From d829dc4a13e7f44ffcccc608cddfef79423e6875 Mon Sep 17 00:00:00 2001 From: Lars Johansson <lars.johansson@ess.eu> Date: Thu, 24 Feb 2022 14:22:59 +0100 Subject: [PATCH] Added REST API v1 endpoints for names and structures (implementation) --- .../repository/DeviceGroupRepository.java | 319 ++++ .../repository/DeviceTypeRepository.java | 318 ++++ .../repository/DisciplineRepository.java | 315 ++++ .../names/repository/NameRepository.java | 297 +++ .../names/repository/SubsystemRepository.java | 318 ++++ .../repository/SystemGroupRepository.java | 311 ++++ .../names/repository/SystemRepository.java | 319 ++++ .../rest/controller/NamesController.java | 375 ++++ .../rest/controller/StructuresController.java | 504 ++++++ .../openepics/names/service/NamesService.java | 692 +++++++ .../names/service/StructuresService.java | 1601 +++++++++++++++++ .../names/util/EssNamingConvention.java | 173 ++ .../names/util/HolderRepositories.java | 133 ++ .../org/openepics/names/util/LogUtil.java | 158 ++ .../openepics/names/util/NameElementUtil.java | 276 +++ .../names/util/NamingConvention.java | 152 ++ .../names/util/StructureElementUtil.java | 800 ++++++++ .../openepics/names/util/StructureUtil.java | 263 +++ .../openepics/names/util/ValidateUtil.java | 1385 ++++++++++++++ .../names/util/EssNamingConventionTest.java | 988 ++++++++++ .../names/util/NameElementUtilTest.java | 101 ++ .../names/util/StructureElementUtilTest.java | 98 + .../names/util/ValidateUtilTest.java | 407 +++++ 23 files changed, 10303 insertions(+) create mode 100644 src/main/java/org/openepics/names/repository/DeviceGroupRepository.java create mode 100644 src/main/java/org/openepics/names/repository/DeviceTypeRepository.java create mode 100644 src/main/java/org/openepics/names/repository/DisciplineRepository.java create mode 100644 src/main/java/org/openepics/names/repository/NameRepository.java create mode 100644 src/main/java/org/openepics/names/repository/SubsystemRepository.java create mode 100644 src/main/java/org/openepics/names/repository/SystemGroupRepository.java create mode 100644 src/main/java/org/openepics/names/repository/SystemRepository.java create mode 100644 src/main/java/org/openepics/names/rest/controller/NamesController.java create mode 100644 src/main/java/org/openepics/names/rest/controller/StructuresController.java create mode 100644 src/main/java/org/openepics/names/service/NamesService.java create mode 100644 src/main/java/org/openepics/names/service/StructuresService.java create mode 100644 src/main/java/org/openepics/names/util/EssNamingConvention.java create mode 100644 src/main/java/org/openepics/names/util/HolderRepositories.java create mode 100644 src/main/java/org/openepics/names/util/LogUtil.java create mode 100644 src/main/java/org/openepics/names/util/NameElementUtil.java create mode 100644 src/main/java/org/openepics/names/util/NamingConvention.java create mode 100644 src/main/java/org/openepics/names/util/StructureElementUtil.java create mode 100644 src/main/java/org/openepics/names/util/StructureUtil.java create mode 100644 src/main/java/org/openepics/names/util/ValidateUtil.java create mode 100644 src/test/java/org/openepics/names/util/EssNamingConventionTest.java create mode 100644 src/test/java/org/openepics/names/util/NameElementUtilTest.java create mode 100644 src/test/java/org/openepics/names/util/StructureElementUtilTest.java create mode 100644 src/test/java/org/openepics/names/util/ValidateUtilTest.java diff --git a/src/main/java/org/openepics/names/repository/DeviceGroupRepository.java b/src/main/java/org/openepics/names/repository/DeviceGroupRepository.java new file mode 100644 index 0000000..342a06f --- /dev/null +++ b/src/main/java/org/openepics/names/repository/DeviceGroupRepository.java @@ -0,0 +1,319 @@ +/* + * Copyright (C) 2021 European Spallation Source ERIC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.openepics.names.repository; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +import org.apache.commons.lang3.BooleanUtils; +import org.openepics.names.repository.model.DeviceGroup; +import org.openepics.names.rest.beans.FieldStructure; +import org.openepics.names.rest.beans.Status; +import org.springframework.stereotype.Repository; + +/** + * Handle device group information in JPA. + * + * @author Lars Johansson + */ +@Repository +public class DeviceGroupRepository { + + private static final String PERCENT = "%"; + + @PersistenceContext + private EntityManager em; + + /** + * Count device groups. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @return count of device groups + */ + public Long countDeviceGroups( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues) { + return countDeviceGroups(statuses, deleted, queryFields, queryValues, Boolean.FALSE); + } + + /** + * Count device groups. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @return count of device groups + */ + public Long countDeviceGroups( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, Boolean includeHistory) { + + // note + // use of function for mnemonic path + // where + // statuses + // deleted + // queryFields, queryValues + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery<Long> cq = cb.createQuery(Long.class); + Root<DeviceGroup> from = cq.from(DeviceGroup.class); + + cq.where(cb.and(preparePredicatesDeviceGroups(cb, from, statuses, deleted, queryFields, queryValues, includeHistory).toArray(new Predicate[0]))); + cq.select(cb.count(from)); + + return em.createQuery(cq).getSingleResult(); + } + + /** + * Find device groups. + * + * @param status status + * @param deleted deleted + * @param queryField query field + * @param queryValue query value + * @return list of device groups + */ + public List<DeviceGroup> readDeviceGroups( + Status status, Boolean deleted, FieldStructure queryField, String queryValue) { + + return readDeviceGroups( + status != null ? new Status[] {status} : null, + deleted, + queryField != null ? new FieldStructure[] {queryField} : null, + queryValue != null ? new String[] {queryValue} : null, + Boolean.FALSE, + null, null, null, null); + } + + /** + * Find device groups. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param orderBy order by + * @param isAsc is ascending + * @param offset offset + * @param limit limit + * @return list of device groups + */ + public List<DeviceGroup> readDeviceGroups( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + return readDeviceGroups( + statuses, deleted, queryFields, queryValues, Boolean.FALSE, + orderBy, isAsc, offset, limit); + } + + /** + * Find device groups. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @param orderBy order by + * @param isAsc is ascending + * @param offset offset + * @param limit limit + * @return list of device groups + */ + public List<DeviceGroup> readDeviceGroups( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, Boolean includeHistory, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + + // note + // use of function for mnemonic path + // where + // statuses + // deleted + // queryFields, queryValues + // order + // orderBy, isAsc + // paging + // offset, limit + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery<DeviceGroup> cq = cb.createQuery(DeviceGroup.class); + Root<DeviceGroup> from = cq.from(DeviceGroup.class); + + cq.where(cb.and(preparePredicatesDeviceGroups(cb, from, statuses, deleted, queryFields, queryValues, includeHistory).toArray(new Predicate[0]))); + cq.select(from); + + if (orderBy != null) { + if (BooleanUtils.toBoolean(isAsc)) { + if (FieldStructure.NAME.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("name"))); + } else if (FieldStructure.MNEMONIC.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("mnemonic"))); + } else if (FieldStructure.MNEMONICEQUIVALENCE.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("mnemonic_equivalence"))); + } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) { + cq.orderBy(cb.asc(cb.function("get_mnemonic_path_devicegroup", String.class, from.get("uuid")))); + } else if (FieldStructure.DESCRIPTION.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("description"))); + } else { + cq.orderBy(cb.asc(from.get("convention_name"))); + } + } else { + if (FieldStructure.NAME.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("name"))); + } else if (FieldStructure.MNEMONIC.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("mnemonic"))); + } else if (FieldStructure.MNEMONICEQUIVALENCE.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("mnemonic_equivalence"))); + } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) { + cq.orderBy(cb.desc(cb.function("get_mnemonic_path_devicegroup", String.class, from.get("uuid")))); + } else if (FieldStructure.DESCRIPTION.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("description"))); + } else { + cq.orderBy(cb.desc(from.get("name"))); + } + } + } + + TypedQuery<DeviceGroup> query = em.createQuery(cq); + if (offset != null && limit != null) { + query.setFirstResult(offset * limit); + query.setMaxResults(limit); + } + + return query.getResultList(); + } + + /** + * Prepare predicates for device groups. + * + * @param cb criteria builder + * @param from criteria query root + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @return list of predicates + */ + private List<Predicate> preparePredicatesDeviceGroups( + CriteriaBuilder cb, Root<DeviceGroup> from, + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, Boolean includeHistory) { + + List<Predicate> predicates = new ArrayList<>(); + + if (!Boolean.TRUE.equals(includeHistory)) { + // exclude (approved and not latest) + Predicate predicateApproved = cb.equal(from.get("status"), Status.APPROVED); + Predicate predicateNotLatest = cb.equal(from.get("latest"), Boolean.FALSE); + Predicate predicateExclude = cb.not(cb.and(predicateApproved, predicateNotLatest)); + predicates.add(predicateExclude); + + } + + if (statuses != null) { + List<Predicate> predicatesStatus = new ArrayList<>(); + for (Status status : statuses) { + predicatesStatus.add(cb.equal(from.get("status"), status)); + } + predicates.add(cb.or((Predicate[]) predicatesStatus.toArray(new Predicate[0]))); + } + if (deleted != null) { + predicates.add(cb.equal(from.get("deleted"), deleted)); + } + if (queryFields != null) { + for (int i=0; i<queryFields.length; i++) { + String queryValue = queryValues[i]; + + // jpa query characters % and _ + // remove excess % characters + if (queryValue.startsWith(PERCENT)) { + while (queryValue.startsWith(PERCENT)) { + queryValue = queryValue.substring(1); + } + queryValue = PERCENT + queryValue; + } + if (queryValue.endsWith(PERCENT)) { + while (queryValue.endsWith(PERCENT)) { + queryValue = queryValue.substring(0, queryValue.length()-1); + } + queryValue = queryValue + PERCENT; + } + + switch (queryFields[i]) { + case UUID: + predicates.add(cb.and(cb.equal(from.get("uuid"), queryValue))); + break; + case PARENT: + predicates.add(cb.and(cb.equal(from.get("parent_uuid"), queryValue))); + break; + case NAME: + predicates.add(cb.and(cb.like(from.get("name"), queryValue))); + break; + case MNEMONIC: + predicates.add(cb.and(cb.like(from.get("mnemonic"), queryValue))); + break; + case MNEMONICEQUIVALENCE: + predicates.add(cb.and(cb.like(from.get("mnemonic_equivalence"), queryValue))); + break; + case MNEMONICPATH: + predicates.add(cb.and(cb.like(cb.function("get_mnemonic_path_devicegroup", String.class, from.get("uuid")), queryValue))); + break; + case DESCRIPTION: + predicates.add(cb.and(cb.like(from.get("description"), queryValue))); + break; + default: + continue; + } + } + } + + return predicates; + } + + /** + * Persist device group into persistence context. + * + * @param deviceGroup device group + */ + public void createDeviceGroup(DeviceGroup deviceGroup) { + em.persist(deviceGroup); + } + + /** + * Merge device group into persistence context. + * + * @param deviceGroup device group + */ + public void updateDeviceGroup(DeviceGroup deviceGroup) { + em.merge(deviceGroup); + } + +} diff --git a/src/main/java/org/openepics/names/repository/DeviceTypeRepository.java b/src/main/java/org/openepics/names/repository/DeviceTypeRepository.java new file mode 100644 index 0000000..f06a8e1 --- /dev/null +++ b/src/main/java/org/openepics/names/repository/DeviceTypeRepository.java @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2021 European Spallation Source ERIC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.openepics.names.repository; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +import org.apache.commons.lang3.BooleanUtils; +import org.openepics.names.repository.model.DeviceType; +import org.openepics.names.rest.beans.FieldStructure; +import org.openepics.names.rest.beans.Status; +import org.springframework.stereotype.Repository; + +/** + * Handle device type information in JPA. + * + * @author Lars Johansson + */ +@Repository +public class DeviceTypeRepository { + + private static final String PERCENT = "%"; + + @PersistenceContext + private EntityManager em; + + /** + * Count device types. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @return count of device types + */ + public Long countDeviceTypes( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues) { + return countDeviceTypes(statuses, deleted, queryFields, queryValues, Boolean.FALSE); + } + + /** + * Count device types. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @return count of device types + */ + public Long countDeviceTypes( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, Boolean includeHistory) { + + // note + // use of function for mnemonic path + // where + // statuses + // deleted + // queryFields, queryValues + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery<Long> cq = cb.createQuery(Long.class); + Root<DeviceType> from = cq.from(DeviceType.class); + + cq.where(cb.and(preparePredicatesDeviceTypes(cb, from, statuses, deleted, queryFields, queryValues, includeHistory).toArray(new Predicate[0]))); + cq.select(cb.count(from)); + + return em.createQuery(cq).getSingleResult(); + } + + /** + * Find device types. + * + * @param status status + * @param deleted deleted + * @param queryField query field + * @param queryValue query value + * @return list of device types + */ + public List<DeviceType> readDeviceTypes( + Status status, Boolean deleted, FieldStructure queryField, String queryValue) { + + return readDeviceTypes( + status != null ? new Status[] {status} : null, + deleted, + queryField != null ? new FieldStructure[] {queryField} : null, + queryValue != null ? new String[] {queryValue} : null, + Boolean.FALSE, + null, null, null, null); + } + + /** + * Find device types. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param orderBy order by + * @param isAsc is ascending + * @param offset offset + * @param limit limit + * @return list of device types + */ + public List<DeviceType> readDeviceTypes( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + return readDeviceTypes( + statuses, deleted, queryFields, queryValues, Boolean.FALSE, + orderBy, isAsc, offset, limit); + } + + /** + * Find device types. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @param orderBy order by + * @param isAsc is ascending + * @param offset offset + * @param limit limit + * @return list of device types + */ + public List<DeviceType> readDeviceTypes( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, Boolean includeHistory, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + + // note + // use of function for mnemonic path + // where + // statuses + // deleted + // queryFields, queryValues + // order + // orderBy, isAsc + // paging + // offset, limit + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery<DeviceType> cq = cb.createQuery(DeviceType.class); + Root<DeviceType> from = cq.from(DeviceType.class); + + cq.where(cb.and(preparePredicatesDeviceTypes(cb, from, statuses, deleted, queryFields, queryValues, includeHistory).toArray(new Predicate[0]))); + cq.select(from); + + if (orderBy != null) { + if (BooleanUtils.toBoolean(isAsc)) { + if (FieldStructure.NAME.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("name"))); + } else if (FieldStructure.MNEMONIC.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("mnemonic"))); + } else if (FieldStructure.MNEMONICEQUIVALENCE.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("mnemonic_equivalence"))); + } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) { + cq.orderBy(cb.asc(cb.function("get_mnemonic_path_devicetype", String.class, from.get("uuid")))); + } else if (FieldStructure.DESCRIPTION.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("description"))); + } else { + cq.orderBy(cb.asc(from.get("convention_name"))); + } + } else { + if (FieldStructure.NAME.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("name"))); + } else if (FieldStructure.MNEMONIC.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("mnemonic"))); + } else if (FieldStructure.MNEMONICEQUIVALENCE.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("mnemonic_equivalence"))); + } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) { + cq.orderBy(cb.desc(cb.function("get_mnemonic_path_devicetype", String.class, from.get("uuid")))); + } else if (FieldStructure.DESCRIPTION.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("description"))); + } else { + cq.orderBy(cb.desc(from.get("name"))); + } + } + } + + TypedQuery<DeviceType> query = em.createQuery(cq); + if (offset != null && limit != null) { + query.setFirstResult(offset * limit); + query.setMaxResults(limit); + } + + return query.getResultList(); + } + + /** + * Prepare predicates for device types. + * + * @param cb criteria builder + * @param from criteria query root + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @return list of predicates + */ + private List<Predicate> preparePredicatesDeviceTypes( + CriteriaBuilder cb, Root<DeviceType> from, + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, Boolean includeHistory) { + + List<Predicate> predicates = new ArrayList<>(); + + if (!Boolean.TRUE.equals(includeHistory)) { + // exclude (approved and not latest) + Predicate predicateApproved = cb.equal(from.get("status"), Status.APPROVED); + Predicate predicateNotLatest = cb.equal(from.get("latest"), Boolean.FALSE); + Predicate predicateExclude = cb.not(cb.and(predicateApproved, predicateNotLatest)); + predicates.add(predicateExclude); + } + + if (statuses != null) { + List<Predicate> predicatesStatus = new ArrayList<>(); + for (Status status : statuses) { + predicatesStatus.add(cb.equal(from.get("status"), status)); + } + predicates.add(cb.or((Predicate[]) predicatesStatus.toArray(new Predicate[0]))); + } + if (deleted != null) { + predicates.add(cb.equal(from.get("deleted"), deleted)); + } + if (queryFields != null) { + for (int i=0; i<queryFields.length; i++) { + String queryValue = queryValues[i]; + + // jpa query characters % and _ + // remove excess % characters + if (queryValue.startsWith(PERCENT)) { + while (queryValue.startsWith(PERCENT)) { + queryValue = queryValue.substring(1); + } + queryValue = PERCENT + queryValue; + } + if (queryValue.endsWith(PERCENT)) { + while (queryValue.endsWith(PERCENT)) { + queryValue = queryValue.substring(0, queryValue.length()-1); + } + queryValue = queryValue + PERCENT; + } + + switch (queryFields[i]) { + case UUID: + predicates.add(cb.and(cb.equal(from.get("uuid"), queryValue))); + break; + case PARENT: + predicates.add(cb.and(cb.equal(from.get("parent_uuid"), queryValue))); + break; + case NAME: + predicates.add(cb.and(cb.like(from.get("name"), queryValue))); + break; + case MNEMONIC: + predicates.add(cb.and(cb.like(from.get("mnemonic"), queryValue))); + break; + case MNEMONICEQUIVALENCE: + predicates.add(cb.and(cb.like(from.get("mnemonic_equivalence"), queryValue))); + break; + case MNEMONICPATH: + predicates.add(cb.and(cb.like(cb.function("get_mnemonic_path_devicetype", String.class, from.get("uuid")), queryValue))); + break; + case DESCRIPTION: + predicates.add(cb.and(cb.like(from.get("description"), queryValue))); + break; + default: + continue; + } + } + } + + return predicates; + } + + /** + * Persist device type into persistence context. + * + * @param deviceType device type + */ + public void createDeviceType(DeviceType deviceType) { + em.persist(deviceType); + } + + /** + * Merge device type into persistence context. + * + * @param deviceType device type + */ + public void updateDeviceType(DeviceType deviceType) { + em.merge(deviceType); + } + +} diff --git a/src/main/java/org/openepics/names/repository/DisciplineRepository.java b/src/main/java/org/openepics/names/repository/DisciplineRepository.java new file mode 100644 index 0000000..77faa2e --- /dev/null +++ b/src/main/java/org/openepics/names/repository/DisciplineRepository.java @@ -0,0 +1,315 @@ +/* + * Copyright (C) 2021 European Spallation Source ERIC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.openepics.names.repository; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +import org.apache.commons.lang3.BooleanUtils; +import org.openepics.names.repository.model.Discipline; +import org.openepics.names.rest.beans.FieldStructure; +import org.openepics.names.rest.beans.Status; +import org.springframework.stereotype.Repository; + +/** + * Handle discipline information in JPA. + * + * @author Lars Johansson + */ +@Repository +public class DisciplineRepository { + + private static final String PERCENT = "%"; + + @PersistenceContext + private EntityManager em; + + /** + * Count disciplines. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @return count of disciplines + */ + public Long countDisciplines( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues) { + return countDisciplines(statuses, deleted, queryFields, queryValues, Boolean.FALSE); + } + + /** + * Count disciplines. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @return count of disciplines + */ + public Long countDisciplines( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, Boolean includeHistory) { + + // note + // use of function for mnemonic path + // where + // statuses + // deleted + // queryFields, queryValues + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery<Long> cq = cb.createQuery(Long.class); + Root<Discipline> from = cq.from(Discipline.class); + + cq.where(cb.and(preparePredicatesDisciplines(cb, from, statuses, deleted, queryFields, queryValues, includeHistory).toArray(new Predicate[0]))); + cq.select(cb.count(from)); + + return em.createQuery(cq).getSingleResult(); + } + + /** + *Find disciplines. + * + * @param status status + * @param deleted deleted + * @param queryField query field + * @param queryValue query value + * @return list of disciplines + */ + public List<Discipline> readDisciplines( + Status status, Boolean deleted, FieldStructure queryField, String queryValue) { + + return readDisciplines( + status != null ? new Status[] {status} : null, + deleted, + queryField != null ? new FieldStructure[] {queryField} : null, + queryValue != null ? new String[] {queryValue} : null, + Boolean.FALSE, + null, null, null, null); + } + + /** + * Find disciplines. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param orderBy order by + * @param isAsc is ascending + * @param offset offset + * @param limit limit + * @return list of disciplines + */ + public List<Discipline> readDisciplines( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + return readDisciplines( + statuses, deleted, queryFields, queryValues, Boolean.FALSE, + orderBy, isAsc, offset, limit); + } + + /** + * Find disciplines. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @param orderBy order by + * @param isAsc is ascending + * @param offset offset + * @param limit limit + * @return list of disciplines + */ + public List<Discipline> readDisciplines( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, Boolean includeHistory, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + + // note + // use of function for mnemonic path + // where + // statuses + // latest, deleted + // queryFields, queryValues + // order + // orderBy, isAsc + // paging + // offset, limit + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery<Discipline> cq = cb.createQuery(Discipline.class); + Root<Discipline> from = cq.from(Discipline.class); + + cq.where(cb.and(preparePredicatesDisciplines(cb, from, statuses, deleted, queryFields, queryValues, includeHistory).toArray(new Predicate[0]))); + cq.select(from); + + if (orderBy != null) { + if (BooleanUtils.toBoolean(isAsc)) { + if (FieldStructure.NAME.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("name"))); + } else if (FieldStructure.MNEMONIC.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("mnemonic"))); + } else if (FieldStructure.MNEMONICEQUIVALENCE.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("mnemonic_equivalence"))); + } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("mnemonic"))); + } else if (FieldStructure.DESCRIPTION.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("description"))); + } else { + cq.orderBy(cb.asc(from.get("convention_name"))); + } + } else { + if (FieldStructure.NAME.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("name"))); + } else if (FieldStructure.MNEMONIC.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("mnemonic"))); + } else if (FieldStructure.MNEMONICEQUIVALENCE.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("mnemonic_equivalence"))); + } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("mnemonic"))); + } else if (FieldStructure.DESCRIPTION.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("description"))); + } else { + cq.orderBy(cb.desc(from.get("name"))); + } + } + } + + TypedQuery<Discipline> query = em.createQuery(cq); + if (offset != null && limit != null) { + query.setFirstResult(offset * limit); + query.setMaxResults(limit); + } + + return query.getResultList(); + } + + /** + * Prepare predicates for disciplines. + * + * @param cb criteria builder + * @param from criteria query root + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @return list of predicates + */ + private List<Predicate> preparePredicatesDisciplines( + CriteriaBuilder cb, Root<Discipline> from, + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, Boolean includeHistory) { + + List<Predicate> predicates = new ArrayList<>(); + + if (!Boolean.TRUE.equals(includeHistory)) { + // exclude (approved and not latest) + Predicate predicateApproved = cb.equal(from.get("status"), Status.APPROVED); + Predicate predicateNotLatest = cb.equal(from.get("latest"), Boolean.FALSE); + Predicate predicateExclude = cb.not(cb.and(predicateApproved, predicateNotLatest)); + predicates.add(predicateExclude); + } + + if (statuses != null) { + List<Predicate> predicatesStatus = new ArrayList<>(); + for (Status status : statuses) { + predicatesStatus.add(cb.equal(from.get("status"), status)); + } + predicates.add(cb.or((Predicate[]) predicatesStatus.toArray(new Predicate[0]))); + } + if (deleted != null) { + predicates.add(cb.equal(from.get("deleted"), deleted)); + } + if (queryFields != null) { + for (int i=0; i<queryFields.length; i++) { + String queryValue = queryValues[i]; + + // jpa query characters % and _ + // remove excess % characters + if (queryValue.startsWith(PERCENT)) { + while (queryValue.startsWith(PERCENT)) { + queryValue = queryValue.substring(1); + } + queryValue = PERCENT + queryValue; + } + if (queryValue.endsWith(PERCENT)) { + while (queryValue.endsWith(PERCENT)) { + queryValue = queryValue.substring(0, queryValue.length()-1); + } + queryValue = queryValue + PERCENT; + } + + switch (queryFields[i]) { + case UUID: + predicates.add(cb.and(cb.equal(from.get("uuid"), queryValue))); + break; + case NAME: + predicates.add(cb.and(cb.like(from.get("name"), queryValue))); + break; + case MNEMONIC: + predicates.add(cb.and(cb.like(from.get("mnemonic"), queryValue))); + break; + case MNEMONICEQUIVALENCE: + predicates.add(cb.and(cb.like(from.get("mnemonic_equivalence"), queryValue))); + break; + case MNEMONICPATH: + predicates.add(cb.and(cb.like(from.get("mnemonic"), queryValue))); + break; + case DESCRIPTION: + predicates.add(cb.and(cb.like(from.get("description"), queryValue))); + break; + default: + continue; + } + } + } + + return predicates; + } + + /** + * Persist discipline into persistence context. + * + * @param discipline discipline + */ + public void createDiscipline(Discipline discipline) { + em.persist(discipline); + } + + /** + * Merge discipline into persistence context. + * + * @param discipline discipline + */ + public void updateDiscipline(Discipline discipline) { + em.merge(discipline); + } + +} diff --git a/src/main/java/org/openepics/names/repository/NameRepository.java b/src/main/java/org/openepics/names/repository/NameRepository.java new file mode 100644 index 0000000..4226d7a --- /dev/null +++ b/src/main/java/org/openepics/names/repository/NameRepository.java @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2021 European Spallation Source ERIC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.openepics.names.repository; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +import org.apache.commons.lang3.BooleanUtils; +import org.openepics.names.repository.model.Name; +import org.openepics.names.rest.beans.FieldName; +import org.springframework.stereotype.Repository; + +/** + * Handle name information in JPA. + * + * @author Lars Johansson + */ +@Repository +public class NameRepository { + + private static final String PERCENT = "%"; + + @PersistenceContext + private EntityManager em; + + /** + * Count names. + * + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @return count of names + */ + public Long countNames( + Boolean deleted, FieldName[] queryFields, String[] queryValues) { + return countNames(deleted, queryFields, queryValues, Boolean.FALSE); + } + + /** + * Count names. + * + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @return count of names + */ + public Long countNames( + Boolean deleted, FieldName[] queryFields, String[] queryValues, Boolean includeHistory) { + + // note + // use of function for mnemonic path + // where + // latest, deleted + // queryFields, queryValues + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery<Long> cq = cb.createQuery(Long.class); + Root<Name> from = cq.from(Name.class); + + cq.where(cb.and(preparePredicatesNames(cb, from, deleted, queryFields, queryValues, includeHistory).toArray(new Predicate[0]))); + cq.select(cb.count(from)); + + return em.createQuery(cq).getSingleResult(); + } + + /** + * Find names. + * + * @param deleted deleted + * @param queryField query field + * @param queryValue query value + * @return list of names + */ + public List<Name> readNames( + Boolean deleted, FieldName queryField, String queryValue) { + + return readNames( + deleted, + queryField != null ? new FieldName[] {queryField} : null, + queryValue != null ? new String[] {queryValue} : null, + Boolean.FALSE, + null, null, null, null); + } + + /** + * Find names. + * + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param orderBy order by + * @param isAsc is ascending + * @param offset offset + * @param limit limit + * @return list of names + */ + public List<Name> readNames( + Boolean deleted, FieldName[] queryFields, String[] queryValues, + FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { + return readNames( + deleted, queryFields, queryValues, Boolean.FALSE, + orderBy, isAsc, offset, limit); + } + + /** + * Find names. + * + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @param orderBy order by + * @param isAsc is ascending + * @param offset offset + * @param limit limit + * @return list of names + */ + public List<Name> readNames( + Boolean deleted, FieldName[] queryFields, String[] queryValues, Boolean includeHistory, + FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { + + // note + // use of function for mnemonic path + // where + // latest, deleted + // queryFields, queryValues + // order + // orderBy, isAsc + // paging + // offset, limit + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery<Name> cq = cb.createQuery(Name.class); + Root<Name> from = cq.from(Name.class); + + cq.where(cb.and(preparePredicatesNames(cb, from, deleted, queryFields, queryValues, includeHistory).toArray(new Predicate[0]))); + cq.select(from); + + if (orderBy != null) { + if (BooleanUtils.toBoolean(isAsc)) { + if (FieldName.NAME.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("convention_name"))); + } else if (FieldName.NAMEEQUIVALENCE.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("convention_name_equivalence"))); + } else if (FieldName.SYSTEMSTRUCTURE.equals(orderBy)) { + cq.orderBy(cb.asc(cb.function("get_mnemonic_path_system_structure", String.class, from.get("convention_name")))); + } else if (FieldName.DEVICESTRUCTURE.equals(orderBy)) { + cq.orderBy(cb.asc(cb.function("get_mnemonic_path_device_structure", String.class, from.get("convention_name")))); + } else if (FieldName.DESCRIPTION.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("description"))); + } else { + cq.orderBy(cb.asc(from.get("convention_name"))); + } + } else { + if (FieldName.NAME.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("convention_name"))); + } else if (FieldName.NAMEEQUIVALENCE.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("convention_name_equivalence"))); + } else if (FieldName.SYSTEMSTRUCTURE.equals(orderBy)) { + cq.orderBy(cb.desc(cb.function("get_mnemonic_path_system_structure", String.class, from.get("convention_name")))); + } else if (FieldName.DEVICESTRUCTURE.equals(orderBy)) { + cq.orderBy(cb.desc(cb.function("get_mnemonic_path_device_structure", String.class, from.get("convention_name")))); + } else if (FieldName.DESCRIPTION.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("description"))); + } else { + cq.orderBy(cb.desc(from.get("convention_name"))); + } + } + } + + TypedQuery<Name> query = em.createQuery(cq); + if (offset != null && limit != null) { + query.setFirstResult(offset * limit); + query.setMaxResults(limit); + } + + return query.getResultList(); + } + + /** + * Prepare predicates for names. + * + * @param cb criteria builder + * @param from criteria query root + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @return list of predicates + */ + private List<Predicate> preparePredicatesNames( + CriteriaBuilder cb, Root<Name> from, + Boolean deleted, FieldName[] queryFields, String[] queryValues, Boolean includeHistory) { + + List<Predicate> predicates = new ArrayList<>(); + + if (!Boolean.TRUE.equals(includeHistory)) { + // exclude (not latest) + Predicate predicateNotLatest = cb.equal(from.get("latest"), Boolean.FALSE); + Predicate predicateExclude = cb.not(cb.and(predicateNotLatest)); + predicates.add(predicateExclude); + } + + if (deleted != null) { + predicates.add(cb.equal(from.get("deleted"), deleted)); + } + if (queryFields != null) { + for (int i=0; i<queryFields.length; i++) { + String queryValue = queryValues[i]; + + // jpa query characters % and _ + // remove excess % characters + if (queryValue.startsWith(PERCENT)) { + while (queryValue.startsWith(PERCENT)) { + queryValue = queryValue.substring(1); + } + queryValue = PERCENT + queryValue; + } + if (queryValue.endsWith(PERCENT)) { + while (queryValue.endsWith(PERCENT)) { + queryValue = queryValue.substring(0, queryValue.length()-1); + } + queryValue = queryValue + PERCENT; + } + + switch (queryFields[i]) { + case UUID: + predicates.add(cb.and(cb.equal(from.get("uuid"), queryValue))); + break; + case NAME: + predicates.add(cb.and(cb.like(from.get("convention_name"), queryValue))); + break; + case NAMEEQUIVALENCE: + predicates.add(cb.and(cb.like(from.get("convention_name_equivalence"), queryValue))); + break; + case SYSTEMSTRUCTURE: + predicates.add(cb.and(cb.like(cb.function("get_mnemonic_path_system_structure", String.class, from.get("convention_name")), queryValue))); + break; + case DEVICESTRUCTURE: + predicates.add(cb.and(cb.like(cb.function("get_mnemonic_path_device_structure", String.class, from.get("convention_name")), queryValue))); + break; + case DESCRIPTION: + predicates.add(cb.and(cb.like(from.get("description"), queryValue))); + break; + default: + continue; + } + } + } + + return predicates; + } + + /** + * Persist name into persistence context. + * + * @param name name + */ + public void createName(Name name) { + em.persist(name); + } + + /** + * Merge name into persistence context. + * + * @param name name + */ + public void updateName(Name name) { + em.merge(name); + } + +} diff --git a/src/main/java/org/openepics/names/repository/SubsystemRepository.java b/src/main/java/org/openepics/names/repository/SubsystemRepository.java new file mode 100644 index 0000000..461ab13 --- /dev/null +++ b/src/main/java/org/openepics/names/repository/SubsystemRepository.java @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2021 European Spallation Source ERIC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.openepics.names.repository; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +import org.apache.commons.lang3.BooleanUtils; +import org.openepics.names.repository.model.Subsystem; +import org.openepics.names.rest.beans.FieldStructure; +import org.openepics.names.rest.beans.Status; +import org.springframework.stereotype.Repository; + +/** + * Handle subsystem information in JPA. + * + * @author Lars Johansson + */ +@Repository +public class SubsystemRepository { + + private static final String PERCENT = "%"; + + @PersistenceContext + private EntityManager em; + + /** + * Count subsystems. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @return count of subsystems + */ + public Long countSubsystems( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues) { + return countSubsystems(statuses, deleted, queryFields, queryValues, Boolean.FALSE); + } + + /** + * Count subsystems. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @return count of subsystems + */ + public Long countSubsystems( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, Boolean includeHistory) { + + // note + // use of function for mnemonic path + // where + // statuses + // deleted + // queryFields, queryValues + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery<Long> cq = cb.createQuery(Long.class); + Root<Subsystem> from = cq.from(Subsystem.class); + + cq.where(cb.and(preparePredicatesSubsystems(cb, from, statuses, deleted, queryFields, queryValues, includeHistory).toArray(new Predicate[0]))); + cq.select(cb.count(from)); + + return em.createQuery(cq).getSingleResult(); + } + + /** + * Find subsystems. + * + * @param status status + * @param deleted deleted + * @param queryField query field + * @param queryValue query value + * @return list of subsystems + */ + public List<Subsystem> readSubsystems( + Status status, Boolean deleted, FieldStructure queryField, String queryValue) { + + return readSubsystems( + status != null ? new Status[] {status} : null, + deleted, + queryField != null ? new FieldStructure[] {queryField} : null, + queryValue != null ? new String[] {queryValue} : null, + Boolean.FALSE, + null, null, null, null); + } + + /** + * Find subsystems. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param orderBy order by + * @param isAsc is ascending + * @param offset offset + * @param limit limit + * @return list of subsystems + */ + public List<Subsystem> readSubsystems( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + return readSubsystems( + statuses, deleted, queryFields, queryValues, Boolean.FALSE, + orderBy, isAsc, offset, limit); + } + + /** + * Find subsystems. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @param orderBy order by + * @param isAsc is ascending + * @param offset offset + * @param limit limit + * @return list of subsystems + */ + public List<Subsystem> readSubsystems( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, Boolean includeHistory, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + + // note + // use of function for mnemonic path + // where + // statuses + // deleted + // queryFields, queryValues + // order + // orderBy, isAsc + // paging + // offset, limit + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery<Subsystem> cq = cb.createQuery(Subsystem.class); + Root<Subsystem> from = cq.from(Subsystem.class); + + cq.where(cb.and(preparePredicatesSubsystems(cb, from, statuses, deleted, queryFields, queryValues, includeHistory).toArray(new Predicate[0]))); + cq.select(from); + + if (orderBy != null) { + if (BooleanUtils.toBoolean(isAsc)) { + if (FieldStructure.NAME.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("name"))); + } else if (FieldStructure.MNEMONIC.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("mnemonic"))); + } else if (FieldStructure.MNEMONICEQUIVALENCE.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("mnemonic_equivalence"))); + } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) { + cq.orderBy(cb.asc(cb.function("get_mnemonic_path_subsystem", String.class, from.get("uuid")))); + } else if (FieldStructure.DESCRIPTION.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("description"))); + } else { + cq.orderBy(cb.asc(from.get("convention_name"))); + } + } else { + if (FieldStructure.NAME.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("name"))); + } else if (FieldStructure.MNEMONIC.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("mnemonic"))); + } else if (FieldStructure.MNEMONICEQUIVALENCE.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("mnemonic_equivalence"))); + } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) { + cq.orderBy(cb.desc(cb.function("get_mnemonic_path_subsystem", String.class, from.get("uuid")))); + } else if (FieldStructure.DESCRIPTION.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("description"))); + } else { + cq.orderBy(cb.desc(from.get("name"))); + } + } + } + + TypedQuery<Subsystem> query = em.createQuery(cq); + if (offset != null && limit != null) { + query.setFirstResult(offset * limit); + query.setMaxResults(limit); + } + + return query.getResultList(); + } + + /** + * Prepare predicates for subsystems. + * + * @param cb criteria builder + * @param from criteria query root + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @return list of predicates + */ + private List<Predicate> preparePredicatesSubsystems( + CriteriaBuilder cb, Root<Subsystem> from, + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, Boolean includeHistory) { + + List<Predicate> predicates = new ArrayList<>(); + + if (!Boolean.TRUE.equals(includeHistory)) { + // exclude (approved and not latest) + Predicate predicateApproved = cb.equal(from.get("status"), Status.APPROVED); + Predicate predicateNotLatest = cb.equal(from.get("latest"), Boolean.FALSE); + Predicate predicateExclude = cb.not(cb.and(predicateApproved, predicateNotLatest)); + predicates.add(predicateExclude); + } + + if (statuses != null) { + List<Predicate> predicatesStatus = new ArrayList<>(); + for (Status status : statuses) { + predicatesStatus.add(cb.equal(from.get("status"), status)); + } + predicates.add(cb.or((Predicate[]) predicatesStatus.toArray(new Predicate[0]))); + } + if (deleted != null) { + predicates.add(cb.equal(from.get("deleted"), deleted)); + } + if (queryFields != null) { + for (int i=0; i<queryFields.length; i++) { + String queryValue = queryValues[i]; + + // jpa query characters % and _ + // remove excess % characters + if (queryValue.startsWith(PERCENT)) { + while (queryValue.startsWith(PERCENT)) { + queryValue = queryValue.substring(1); + } + queryValue = PERCENT + queryValue; + } + if (queryValue.endsWith(PERCENT)) { + while (queryValue.endsWith(PERCENT)) { + queryValue = queryValue.substring(0, queryValue.length()-1); + } + queryValue = queryValue + PERCENT; + } + + switch (queryFields[i]) { + case UUID: + predicates.add(cb.and(cb.equal(from.get("uuid"), queryValue))); + break; + case PARENT: + predicates.add(cb.and(cb.equal(from.get("parent_uuid"), queryValue))); + break; + case NAME: + predicates.add(cb.and(cb.like(from.get("name"), queryValue))); + break; + case MNEMONIC: + predicates.add(cb.and(cb.like(from.get("mnemonic"), queryValue))); + break; + case MNEMONICEQUIVALENCE: + predicates.add(cb.and(cb.like(from.get("mnemonic_equivalence"), queryValue))); + break; + case MNEMONICPATH: + predicates.add(cb.and(cb.like(cb.function("get_mnemonic_path_subsystem", String.class, from.get("uuid")), queryValue))); + break; + case DESCRIPTION: + predicates.add(cb.and(cb.like(from.get("description"), queryValue))); + break; + default: + continue; + } + } + } + + return predicates; + } + + /** + * Persist subsystem into persistence context. + * + * @param subsystem subsystem + */ + public void createSubsystem(Subsystem subsystem) { + em.persist(subsystem); + } + + /** + * Merge subsystem into persistence context. + * + * @param subsystem subsystem + */ + public void updateSubsystem(Subsystem subsystem) { + em.merge(subsystem); + } + +} diff --git a/src/main/java/org/openepics/names/repository/SystemGroupRepository.java b/src/main/java/org/openepics/names/repository/SystemGroupRepository.java new file mode 100644 index 0000000..a87a7c3 --- /dev/null +++ b/src/main/java/org/openepics/names/repository/SystemGroupRepository.java @@ -0,0 +1,311 @@ +/* + * Copyright (C) 2021 European Spallation Source ERIC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.openepics.names.repository; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +import org.apache.commons.lang3.BooleanUtils; +import org.openepics.names.repository.model.SystemGroup; +import org.openepics.names.rest.beans.FieldStructure; +import org.openepics.names.rest.beans.Status; +import org.springframework.stereotype.Repository; + +/** + * Handle system group information in JPA. + * + * @author Lars Johansson + */ +@Repository +public class SystemGroupRepository { + + private static final String PERCENT = "%"; + + @PersistenceContext + private EntityManager em; + + /** + * Count system groups. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @return count of system groups + */ + public Long countSystemGroups( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues) { + return countSystemGroups(statuses, deleted, queryFields, queryValues, Boolean.FALSE); + } + + /** + * Count system groups. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @return count of system groups + */ + public Long countSystemGroups( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, Boolean includeHistory) { + + // where + // statuses + // deleted + // queryFields, queryValues + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery<Long> cq = cb.createQuery(Long.class); + Root<SystemGroup> from = cq.from(SystemGroup.class); + + cq.where(cb.and(preparePredicatesSystemGroups(cb, from, statuses, deleted, queryFields, queryValues, includeHistory).toArray(new Predicate[0]))); + cq.select(cb.count(from)); + + return em.createQuery(cq).getSingleResult(); + } + + /** + * Find system groups. + * + * @param status status + * @param deleted deleted + * @param queryField query field + * @param queryValue query value + * @return list of system groups + */ + public List<SystemGroup> readSystemGroups( + Status status, Boolean deleted, FieldStructure queryField, String queryValue) { + + return readSystemGroups( + status != null ? new Status[] {status} : null, + deleted, + queryField != null ? new FieldStructure[] {queryField} : null, + queryValue != null ? new String[] {queryValue} : null, + Boolean.FALSE, + null, null, null, null); + } + + /** + * Find system groups. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param orderBy order by + * @param isAsc is ascending + * @param offset offset + * @param limit limit + * @return list of system groups + */ + public List<SystemGroup> readSystemGroups( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + return readSystemGroups( + statuses, deleted, queryFields, queryValues, Boolean.FALSE, + orderBy, isAsc, offset, limit); + } + + /** + * Find system groups. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @param orderBy order by + * @param isAsc is ascending + * @param offset offset + * @param limit limit + * @return list of system groups + */ + public List<SystemGroup> readSystemGroups( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, Boolean includeHistory, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + + // where + // statuses, + // deleted + // queryFields, queryValues + // order + // orderBy, isAsc + // paging + // offset, limit + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery<SystemGroup> cq = cb.createQuery(SystemGroup.class); + Root<SystemGroup> from = cq.from(SystemGroup.class); + + cq.where(cb.and(preparePredicatesSystemGroups(cb, from, statuses, deleted, queryFields, queryValues, includeHistory).toArray(new Predicate[0]))); + cq.select(from); + + if (orderBy != null) { + if (BooleanUtils.toBoolean(isAsc)) { + if (FieldStructure.NAME.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("name"))); + } else if (FieldStructure.MNEMONIC.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("mnemonic"))); + } else if (FieldStructure.MNEMONICEQUIVALENCE.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("mnemonic_equivalence"))); + } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("mnemonic"))); + } else if (FieldStructure.DESCRIPTION.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("description"))); + } else { + cq.orderBy(cb.asc(from.get("convention_name"))); + } + } else { + if (FieldStructure.NAME.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("name"))); + } else if (FieldStructure.MNEMONIC.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("mnemonic"))); + } else if (FieldStructure.MNEMONICEQUIVALENCE.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("mnemonic_equivalence"))); + } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("mnemonic"))); + } else if (FieldStructure.DESCRIPTION.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("description"))); + } else { + cq.orderBy(cb.desc(from.get("name"))); + } + } + } + + TypedQuery<SystemGroup> query = em.createQuery(cq); + if (offset != null && limit != null) { + query.setFirstResult(offset * limit); + query.setMaxResults(limit); + } + + return query.getResultList(); + } + + /** + * Prepare predicates for system groups. + * + * @param cb criteria builder + * @param from criteria query root + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @return list of predicates + */ + private List<Predicate> preparePredicatesSystemGroups( + CriteriaBuilder cb, Root<SystemGroup> from, + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, Boolean includeHistory) { + + List<Predicate> predicates = new ArrayList<>(); + + if (!Boolean.TRUE.equals(includeHistory)) { + // exclude (approved and not latest) + Predicate predicateApproved = cb.equal(from.get("status"), Status.APPROVED); + Predicate predicateNotLatest = cb.equal(from.get("latest"), Boolean.FALSE); + Predicate predicateExclude = cb.not(cb.and(predicateApproved, predicateNotLatest)); + predicates.add(predicateExclude); + } + + if (statuses != null) { + List<Predicate> predicatesStatus = new ArrayList<>(); + for (Status status : statuses) { + predicatesStatus.add(cb.equal(from.get("status"), status)); + } + predicates.add(cb.or((Predicate[]) predicatesStatus.toArray(new Predicate[0]))); + } + if (deleted != null) { + predicates.add(cb.equal(from.get("deleted"), deleted)); + } + if (queryFields != null) { + for (int i=0; i<queryFields.length; i++) { + String queryValue = queryValues[i]; + + // jpa query characters % and _ + // remove excess % characters + if (queryValue.startsWith(PERCENT)) { + while (queryValue.startsWith(PERCENT)) { + queryValue = queryValue.substring(1); + } + queryValue = PERCENT + queryValue; + } + if (queryValue.endsWith(PERCENT)) { + while (queryValue.endsWith(PERCENT)) { + queryValue = queryValue.substring(0, queryValue.length()-1); + } + queryValue = queryValue + PERCENT; + } + + switch (queryFields[i]) { + case UUID: + predicates.add(cb.and(cb.equal(from.get("uuid"), queryValue))); + break; + case NAME: + predicates.add(cb.and(cb.like(from.get("name"), queryValue))); + break; + case MNEMONIC: + predicates.add(cb.and(cb.like(from.get("mnemonic"), queryValue))); + break; + case MNEMONICEQUIVALENCE: + predicates.add(cb.and(cb.like(from.get("mnemonic_equivalence"), queryValue))); + break; + case MNEMONICPATH: + predicates.add(cb.and(cb.like(from.get("mnemonic"), queryValue))); + break; + case DESCRIPTION: + predicates.add(cb.and(cb.like(from.get("description"), queryValue))); + break; + default: + continue; + } + } + } + + return predicates; + } + + /** + * Persist system group into persistence context. + * + * @param systemGroup system group + */ + public void createSystemGroup(SystemGroup systemGroup) { + em.persist(systemGroup); + } + + /** + * Merge system group into persistence context. + * + * @param systemGroup system group + */ + public void updateSystemGroup(SystemGroup systemGroup) { + em.merge(systemGroup); + } + +} diff --git a/src/main/java/org/openepics/names/repository/SystemRepository.java b/src/main/java/org/openepics/names/repository/SystemRepository.java new file mode 100644 index 0000000..de838d4 --- /dev/null +++ b/src/main/java/org/openepics/names/repository/SystemRepository.java @@ -0,0 +1,319 @@ +/* + * Copyright (C) 2021 European Spallation Source ERIC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.openepics.names.repository; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +import org.apache.commons.lang3.BooleanUtils; +import org.openepics.names.repository.model.System; +import org.openepics.names.rest.beans.FieldStructure; +import org.openepics.names.rest.beans.Status; +import org.springframework.stereotype.Repository; + +/** + * Handle system information in JPA. + * + * @author Lars Johansson + */ +@Repository +public class SystemRepository { + + private static final String PERCENT = "%"; + + @PersistenceContext + private EntityManager em; + + /** + * Count systems. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @return count of systems + */ + public Long countSystems( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues) { + return countSystems(statuses, deleted, queryFields, queryValues, Boolean.FALSE); + } + + /** + * Count systems. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @return count of systems + */ + public Long countSystems( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, Boolean includeHistory) { + + // note + // use of function for mnemonic path + // where + // statuses + // deleted + // queryFields, queryValues + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery<Long> cq = cb.createQuery(Long.class); + Root<System> from = cq.from(System.class); + + cq.where(cb.and(preparePredicatesSystems(cb, from, statuses, deleted, queryFields, queryValues, includeHistory).toArray(new Predicate[0]))); + cq.select(cb.count(from)); + + return em.createQuery(cq).getSingleResult(); + } + + /** + * Find systems. + * + * @param status status + * @param deleted deleted + * @param queryField query field + * @param queryValue query value + * @return list of systems + */ + public List<System> readSystems( + Status status, Boolean deleted, FieldStructure queryField, String queryValue) { + + return readSystems( + status != null ? new Status[] {status} : null, + deleted, + queryField != null ? new FieldStructure[] {queryField} : null, + queryValue != null ? new String[] {queryValue} : null, + Boolean.FALSE, + null, null, null, null); + } + + /** + * Find systems. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param orderBy order by + * @param isAsc is ascending + * @param offset offset + * @param limit limit + * @return list of systems + */ + public List<System> readSystems( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + return readSystems( + statuses, deleted, queryFields, queryValues, Boolean.FALSE, + orderBy, isAsc, offset, limit); + } + + /** + * Find systems. + * + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @param orderBy order by + * @param isAsc is ascending + * @param offset offset + * @param limit limit + * @return list of systems + */ + public List<System> readSystems( + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, Boolean includeHistory, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + + // note + // use of function for mnemonic path + // where + // statuses + // deleted + // queryFields, queryValues + // order + // orderBy, isAsc + // paging + // offset, limit + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery<System> cq = cb.createQuery(System.class); + Root<System> from = cq.from(System.class); + + cq.where(cb.and(preparePredicatesSystems(cb, from, statuses, deleted, queryFields, queryValues, includeHistory).toArray(new Predicate[0]))); + cq.select(from); + + if (orderBy != null) { + if (BooleanUtils.toBoolean(isAsc)) { + if (FieldStructure.NAME.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("name"))); + } else if (FieldStructure.MNEMONIC.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("mnemonic"))); + } else if (FieldStructure.MNEMONICEQUIVALENCE.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("mnemonic_equivalence"))); + } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) { + cq.orderBy(cb.asc(cb.function("get_mnemonic_path_system", String.class, from.get("uuid")))); + } else if (FieldStructure.DESCRIPTION.equals(orderBy)) { + cq.orderBy(cb.asc(from.get("description"))); + } else { + cq.orderBy(cb.asc(from.get("convention_name"))); + } + } else { + if (FieldStructure.NAME.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("name"))); + } else if (FieldStructure.MNEMONIC.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("mnemonic"))); + } else if (FieldStructure.MNEMONICEQUIVALENCE.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("mnemonic_equivalence"))); + } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) { + cq.orderBy(cb.desc(cb.function("get_mnemonic_path_system", String.class, from.get("uuid")))); + } else if (FieldStructure.DESCRIPTION.equals(orderBy)) { + cq.orderBy(cb.desc(from.get("description"))); + } else { + cq.orderBy(cb.desc(from.get("name"))); + } + } + } + + TypedQuery<System> query = em.createQuery(cq); + if (offset != null && limit != null) { + query.setFirstResult(offset * limit); + query.setMaxResults(limit); + } + + return query.getResultList(); + } + + /** + * Prepare predicates for systems. + * + * @param cb criteria builder + * @param from criteria query root + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @return list of predicates + */ + private List<Predicate> preparePredicatesSystems( + CriteriaBuilder cb, Root<System> from, + Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, Boolean includeHistory) { + + List<Predicate> predicates = new ArrayList<>(); + + if (!Boolean.TRUE.equals(includeHistory)) { + // exclude (approved and not latest) + Predicate predicateApproved = cb.equal(from.get("status"), Status.APPROVED); + Predicate predicateNotLatest = cb.equal(from.get("latest"), Boolean.FALSE); + Predicate predicateExclude = cb.not(cb.and(predicateApproved, predicateNotLatest)); + predicates.add(predicateExclude); + + } + + if (statuses != null) { + List<Predicate> predicatesStatus = new ArrayList<>(); + for (Status status : statuses) { + predicatesStatus.add(cb.equal(from.get("status"), status)); + } + predicates.add(cb.or((Predicate[]) predicatesStatus.toArray(new Predicate[0]))); + } + if (deleted != null) { + predicates.add(cb.equal(from.get("deleted"), deleted)); + } + if (queryFields != null) { + for (int i=0; i<queryFields.length; i++) { + String queryValue = queryValues[i]; + + // jpa query characters % and _ + // remove excess % characters + if (queryValue.startsWith(PERCENT)) { + while (queryValue.startsWith(PERCENT)) { + queryValue = queryValue.substring(1); + } + queryValue = PERCENT + queryValue; + } + if (queryValue.endsWith(PERCENT)) { + while (queryValue.endsWith(PERCENT)) { + queryValue = queryValue.substring(0, queryValue.length()-1); + } + queryValue = queryValue + PERCENT; + } + + switch (queryFields[i]) { + case UUID: + predicates.add(cb.and(cb.equal(from.get("uuid"), queryValue))); + break; + case PARENT: + predicates.add(cb.and(cb.equal(from.get("parent_uuid"), queryValue))); + break; + case NAME: + predicates.add(cb.and(cb.like(from.get("name"), queryValue))); + break; + case MNEMONIC: + predicates.add(cb.and(cb.like(from.get("mnemonic"), queryValue))); + break; + case MNEMONICEQUIVALENCE: + predicates.add(cb.and(cb.like(from.get("mnemonic_equivalence"), queryValue))); + break; + case MNEMONICPATH: + predicates.add(cb.and(cb.like(cb.function("get_mnemonic_path_system", String.class, from.get("uuid")), queryValue))); + break; + case DESCRIPTION: + predicates.add(cb.and(cb.like(from.get("description"), queryValue))); + break; + default: + continue; + } + } + } + + return predicates; + } + + /** + * Persist system into persistence context. + * + * @param system system + */ + public void createSystem(System system) { + em.persist(system); + } + + /** + * Merge system into persistence context. + * + * @param system system + */ + public void updateSystem(System system) { + em.merge(system); + } + +} diff --git a/src/main/java/org/openepics/names/rest/controller/NamesController.java b/src/main/java/org/openepics/names/rest/controller/NamesController.java new file mode 100644 index 0000000..f8cd417 --- /dev/null +++ b/src/main/java/org/openepics/names/rest/controller/NamesController.java @@ -0,0 +1,375 @@ +/* + * Copyright (C) 2021 European Spallation Source ERIC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.openepics.names.rest.controller; + +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.openepics.names.rest.api.v1.INames; +import org.openepics.names.rest.beans.FieldName; +import org.openepics.names.rest.beans.NameElement; +import org.openepics.names.service.NamesService; +import org.openepics.names.util.ExceptionUtil; +import org.openepics.names.util.LogUtil; +import org.openepics.names.util.ServiceHttpStatusException; +import org.openepics.names.util.response.Response; +import org.openepics.names.util.response.ResponseBoolean; +import org.openepics.names.util.response.ResponseBooleanList; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RestController; + +import com.google.common.collect.Lists; + +/** + * This part of REST API provides name data for Naming application. + * + * @author Lars Johansson + */ +@RestController +@EnableAutoConfiguration +public class NamesController implements INames { + + // note + // global exception handler available + + private static final Logger LOGGER = Logger.getLogger(NamesController.class.getName()); + + private NamesService namesService; + + @Autowired + public NamesController( + NamesService namesService) { + this.namesService = namesService; + } + + @Override + public List<NameElement> createNames(List<NameElement> nameElements) { + // validate authority + // naming user & admin + // validate + // do + + try { + namesService.validateNamesCreate(nameElements); + return namesService.createNames(nameElements); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + + // ---------------------------------------------------------------------------------------------------- + + @Override + public List<NameElement> readNames( + Boolean deleted, FieldName[] queryFields, String[] queryValues, + FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { + try { + return namesService.readNames( + deleted, queryFields, queryValues, + orderBy, isAsc, offset, limit); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + + @Override + public List<NameElement> readNames( + String name, + FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { + try { + return namesService.readNames(name, orderBy, isAsc, offset, limit); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + + @Override + public List<NameElement> readNamesSystemStructure( + String mnemonicpath, + FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { + try { + return namesService.readNamesSystemStructure(mnemonicpath, orderBy, isAsc, offset, limit); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + + @Override + public List<NameElement> readNamesDeviceStructure( + String mnemonicpath, + FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { + try { + return namesService.readNamesDeviceStructure(mnemonicpath, orderBy, isAsc, offset, limit); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + + @Override + public List<NameElement> readNamesHistory( + String uuid, + FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { + try { + return namesService.readNamesHistory(uuid, orderBy, isAsc, offset, limit); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + + // ---------------------------------------------------------------------------------------------------- + + @Override + public String equivalenceName(String name) { + try { + return namesService.equivalenceName(name); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + + @Override + public ResponseEntity<ResponseBoolean> existsName(String name) { + try { + return new ResponseEntity<>(new ResponseBoolean(namesService.existsName(name)), Response.HEADER_JSON, HttpStatus.OK); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails()), Response.HEADER_JSON, HttpStatus.OK); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED), Response.HEADER_JSON, HttpStatus.OK); + } + } + + @Override + public ResponseEntity<ResponseBoolean> isLegacyName(String name) { + try { + return new ResponseEntity<>(new ResponseBoolean(namesService.isLegacyName(name)), Response.HEADER_JSON, HttpStatus.OK); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails()), Response.HEADER_JSON, HttpStatus.OK); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED), Response.HEADER_JSON, HttpStatus.OK); + } + } + + @Override + public ResponseEntity<ResponseBoolean> isValidToCreateName(String name) { + try { + return new ResponseEntity<>(new ResponseBoolean(namesService.isValidToCreateName(name)), Response.HEADER_JSON, HttpStatus.OK); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails()), Response.HEADER_JSON, HttpStatus.OK); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED), Response.HEADER_JSON, HttpStatus.OK); + } + } + + // ---------------------------------------------------------------------------------------------------- + + @Override + public ResponseEntity<ResponseBooleanList> validateNamesCreate(List<NameElement> nameElements) { + boolean response = true; + String reason = ""; + List<ResponseBoolean> responses = Lists.newArrayList(); + for (NameElement nameElement : nameElements) { + try { + namesService.validateNamesCreate(nameElement); + responses.add(new ResponseBoolean(Boolean.TRUE)); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + if (response) { + response = false; + reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; + } + responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails())); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + if (response) { + response = false; + reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; + } + responses.add(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED)); + } + } + return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.HEADER_JSON, HttpStatus.OK); + } + + @Override + public ResponseEntity<ResponseBooleanList> validateNamesUpdate(List<NameElement> nameElements) { + boolean response = true; + String reason = ""; + List<ResponseBoolean> responses = Lists.newArrayList(); + for (NameElement nameElement : nameElements) { + try { + namesService.validateNamesUpdate(nameElement); + responses.add(new ResponseBoolean(Boolean.TRUE)); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + if (response) { + response = false; + reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; + } + responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails())); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + if (response) { + response = false; + reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; + } + responses.add(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED)); + } + } + return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.HEADER_JSON, HttpStatus.OK); + } + + @Override + public ResponseEntity<ResponseBooleanList> validateNamesDelete(List<NameElement> nameElements) { + boolean response = true; + String reason = ""; + List<ResponseBoolean> responses = Lists.newArrayList(); + for (NameElement nameElement : nameElements) { + try { + namesService.validateNamesDelete(nameElement); + responses.add(new ResponseBoolean(Boolean.TRUE)); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + if (response) { + response = false; + reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; + } + responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails())); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + if (response) { + response = false; + reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; + } + responses.add(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED)); + } + } + return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.HEADER_JSON, HttpStatus.OK); + } + + // ---------------------------------------------------------------------------------------------------- + + @Override + public List<NameElement> updateNames(List<NameElement> nameElements) { + // validate authority + // naming user & admin + // validate + // do + + try { + namesService.validateNamesUpdate(nameElements); + return namesService.updateNames(nameElements); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + + // ---------------------------------------------------------------------------------------------------- + + @Override + public List<NameElement> deleteNames(List<NameElement> nameElements) { + // validate authority + // naming user & admin + // validate + // do + + try { + namesService.validateNamesDelete(nameElements); + return namesService.deleteNames(nameElements); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + +} \ No newline at end of file diff --git a/src/main/java/org/openepics/names/rest/controller/StructuresController.java b/src/main/java/org/openepics/names/rest/controller/StructuresController.java new file mode 100644 index 0000000..9599570 --- /dev/null +++ b/src/main/java/org/openepics/names/rest/controller/StructuresController.java @@ -0,0 +1,504 @@ +/* + * Copyright (C) 2021 European Spallation Source ERIC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.openepics.names.rest.controller; + +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.openepics.names.rest.api.v1.IStructures; +import org.openepics.names.rest.beans.FieldStructure; +import org.openepics.names.rest.beans.Status; +import org.openepics.names.rest.beans.StructureElement; +import org.openepics.names.rest.beans.Type; +import org.openepics.names.service.StructuresService; +import org.openepics.names.util.ExceptionUtil; +import org.openepics.names.util.LogUtil; +import org.openepics.names.util.ServiceHttpStatusException; +import org.openepics.names.util.response.Response; +import org.openepics.names.util.response.ResponseBoolean; +import org.openepics.names.util.response.ResponseBooleanList; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RestController; + +import com.google.common.collect.Lists; + +/** + * This part of REST API provides structures data for Naming application. + * + * @author Lars Johansson + */ +@RestController +@EnableAutoConfiguration +public class StructuresController implements IStructures { + + // note + // global exception handler available + + // TODO validate authority + // either + // no or + // naming user + // naming admin + // naming user & admin + + private static final Logger LOGGER = Logger.getLogger(StructuresController.class.getName()); + + private StructuresService structuresService; + + @Autowired + public StructuresController( + StructuresService structuresService) { + this.structuresService = structuresService; + } + + @Override + public List<StructureElement> createStructures(List<StructureElement> structureElements) { + // validate authority + // naming user & admin + // validate + // do + + try { + structuresService.validateStructuresCreate(structureElements); + return structuresService.createStructures(structureElements); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + + // ---------------------------------------------------------------------------------------------------- + + @Override + public List<StructureElement> readStructures( + Type type, Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + try { + return structuresService.readStructures( + type, statuses, deleted, queryFields, queryValues, + orderBy, isAsc, offset, limit); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + + @Override + public List<StructureElement> readStructuresChildren( + Type type, String uuid, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + try { + return structuresService.readStructuresChildren( + type, uuid, + orderBy, isAsc, offset, limit); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + + @Override + public List<StructureElement> readStructuresMnemonic( + String mnemonic, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + try { + return structuresService.readStructuresMnemonic(mnemonic, orderBy, isAsc, offset, limit); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + + @Override + public List<StructureElement> readStructuresMnemonicpath( + String mnemonicpath, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + try { + return structuresService.readStructuresMnemonicpath(mnemonicpath, orderBy, isAsc, offset, limit); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + + @Override + public List<StructureElement> readStructuresHistory( + String uuid, Type type, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + try { + return structuresService.readStructuresHistory( + uuid, type, + orderBy, isAsc, offset, limit); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + + // ---------------------------------------------------------------------------------------------------- + + @Override + public String equivalenceMnemonic(String mnemonic) { + try { + return structuresService.equivalenceMnemonic(mnemonic); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + + @Override + public ResponseEntity<ResponseBoolean> existsStructure(Type type, String mnemonic) { + try { + return new ResponseEntity<>(new ResponseBoolean(structuresService.existsStructure(type, mnemonic)), Response.HEADER_JSON, HttpStatus.OK); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails()), Response.HEADER_JSON, HttpStatus.OK); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED), Response.HEADER_JSON, HttpStatus.OK); + } + } + + @Override + public ResponseEntity<ResponseBoolean> isValidToCreateStructure(Type type, String mnemonicpath) { + try { + return new ResponseEntity<>(new ResponseBoolean(structuresService.isValidToCreateStructure(type, mnemonicpath)), Response.HEADER_JSON, HttpStatus.OK); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails()), Response.HEADER_JSON, HttpStatus.OK); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + return new ResponseEntity<>(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED), Response.HEADER_JSON, HttpStatus.OK); + } + } + + // ---------------------------------------------------------------------------------------------------- + + @Override + public ResponseEntity<ResponseBooleanList> validateStructuresCreate(List<StructureElement> structureElements) { + boolean response = true; + String reason = ""; + List<ResponseBoolean> responses = Lists.newArrayList(); + for (StructureElement structureElement : structureElements) { + try { + structuresService.validateStructuresCreate(structureElement); + responses.add(new ResponseBoolean(Boolean.TRUE)); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + if (response) { + response = false; + reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; + } + responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails())); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + if (response) { + response = false; + reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; + } + responses.add(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED)); + } + } + return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.HEADER_JSON, HttpStatus.OK); + } + + @Override + public ResponseEntity<ResponseBooleanList> validateStructuresUpdate(List<StructureElement> structureElements) { + boolean response = true; + String reason = ""; + List<ResponseBoolean> responses = Lists.newArrayList(); + for (StructureElement structureElement : structureElements) { + try { + structuresService.validateStructuresUpdate(structureElement); + responses.add(new ResponseBoolean(Boolean.TRUE)); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + if (response) { + response = false; + reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; + } + responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails())); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + if (response) { + response = false; + reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; + } + responses.add(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED)); + } + } + return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.HEADER_JSON, HttpStatus.OK); + } + + @Override + public ResponseEntity<ResponseBooleanList> validateStructuresDelete(List<StructureElement> structureElements) { + boolean response = true; + String reason = ""; + List<ResponseBoolean> responses = Lists.newArrayList(); + for (StructureElement structureElement : structureElements) { + try { + structuresService.validateStructuresDelete(structureElement); + responses.add(new ResponseBoolean(Boolean.TRUE)); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + if (response) { + response = false; + reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; + } + responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails())); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + if (response) { + response = false; + reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; + } + responses.add(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED)); + } + } + return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.HEADER_JSON, HttpStatus.OK); + } + + @Override + public ResponseEntity<ResponseBooleanList> validateStructuresApprove(List<StructureElement> structureElements) { + boolean response = true; + String reason = ""; + List<ResponseBoolean> responses = Lists.newArrayList(); + for (StructureElement structureElement : structureElements) { + try { + structuresService.validateStructuresApprove(structureElement); + responses.add(new ResponseBoolean(Boolean.TRUE)); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + if (response) { + response = false; + reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; + } + responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails())); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + if (response) { + response = false; + reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; + } + responses.add(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED)); + } + } + return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.HEADER_JSON, HttpStatus.OK); + } + + @Override + public ResponseEntity<ResponseBooleanList> validateStructuresCancel(List<StructureElement> structureElements) { + boolean response = true; + String reason = ""; + List<ResponseBoolean> responses = Lists.newArrayList(); + for (StructureElement structureElement : structureElements) { + try { + structuresService.validateStructuresCancel(structureElement); + responses.add(new ResponseBoolean(Boolean.TRUE)); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + if (response) { + response = false; + reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; + } + responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails())); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + if (response) { + response = false; + reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; + } + responses.add(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED)); + } + } + return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.HEADER_JSON, HttpStatus.OK); + } + + @Override + public ResponseEntity<ResponseBooleanList> validateStructuresReject(List<StructureElement> structureElements) { + boolean response = true; + String reason = ""; + List<ResponseBoolean> responses = Lists.newArrayList(); + for (StructureElement structureElement : structureElements) { + try { + structuresService.validateStructuresReject(structureElement); + responses.add(new ResponseBoolean(Boolean.TRUE)); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + if (response) { + response = false; + reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; + } + responses.add(new ResponseBoolean(Boolean.FALSE, e.getMessage(), e.getDetails())); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + if (response) { + response = false; + reason = ExceptionUtil.ONE_OR_MORE_ELEMENTS_ARE_NOT_CORRECT; + } + responses.add(new ResponseBoolean(Boolean.FALSE, ExceptionUtil.OPERATION_COULD_NOT_BE_PERFORMED)); + } + } + return new ResponseEntity<>(new ResponseBooleanList(responses, Boolean.valueOf(response), reason), Response.HEADER_JSON, HttpStatus.OK); + } + + // ---------------------------------------------------------------------------------------------------- + + @Override + public List<StructureElement> updateStructures(List<StructureElement> structureElements) { + try { + structuresService.validateStructuresUpdate(structureElements); + return structuresService.updateStructures(structureElements); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + + + // ---------------------------------------------------------------------------------------------------- + + @Override + public List<StructureElement> deleteStructures(List<StructureElement> structureElements) { + try { + structuresService.validateStructuresDelete(structureElements); + return structuresService.deleteStructures(structureElements); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + + // ---------------------------------------------------------------------------------------------------- + + @Override + public List<StructureElement> approveStructures(List<StructureElement> structureElements) { + try { + structuresService.validateStructuresApprove(structureElements); + return structuresService.approveStructures(structureElements); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + + @Override + public List<StructureElement> cancelStructures(List<StructureElement> structureElements) { + try { + structuresService.validateStructuresCancel(structureElements); + return structuresService.cancelStructures(structureElements); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + + @Override + public List<StructureElement> rejectStructures(List<StructureElement> structureElements) { + try { + structuresService.validateStructuresReject(structureElements); + return structuresService.rejectStructures(structureElements); + } catch (ServiceHttpStatusException e) { + LogUtil.logServiceHttpStatusException(LOGGER, Level.SEVERE, e); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + LogUtil.logStackTraceElements(LOGGER, Level.SEVERE, e); + throw e; + } + } + +} diff --git a/src/main/java/org/openepics/names/service/NamesService.java b/src/main/java/org/openepics/names/service/NamesService.java new file mode 100644 index 0000000..0c16cee --- /dev/null +++ b/src/main/java/org/openepics/names/service/NamesService.java @@ -0,0 +1,692 @@ +/* + * Copyright (C) 2021 European Spallation Source ERIC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.openepics.names.service; + +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.openepics.names.repository.IDeviceGroupRepository; +import org.openepics.names.repository.IDeviceTypeRepository; +import org.openepics.names.repository.IDisciplineRepository; +import org.openepics.names.repository.INameRepository; +import org.openepics.names.repository.ISubsystemRepository; +import org.openepics.names.repository.ISystemGroupRepository; +import org.openepics.names.repository.ISystemRepository; +import org.openepics.names.repository.NameRepository; +import org.openepics.names.repository.model.DeviceGroup; +import org.openepics.names.repository.model.DeviceType; +import org.openepics.names.repository.model.Discipline; +import org.openepics.names.repository.model.Name; +import org.openepics.names.repository.model.Subsystem; +import org.openepics.names.repository.model.SystemGroup; +import org.openepics.names.rest.beans.FieldName; +import org.openepics.names.rest.beans.NameElement; +import org.openepics.names.rest.beans.Status; +import org.openepics.names.util.EssNamingConvention; +import org.openepics.names.util.HolderIRepositories; +import org.openepics.names.util.HolderSystemDeviceStructure; +import org.openepics.names.util.NameElementUtil; +import org.openepics.names.util.ValidateUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.google.common.collect.Lists; + +/** + * This class provides names services. + * + * @author Lars Johansson + */ +@Service +public class NamesService { + + // HolderIRepositories and HolderSystemDeviceStructure may or may not be used for preparation of what to return + + // for each method + // document what values come from NameElement and what values come from persistence layer + // somehow provide this information to user + + private static final Logger LOGGER = Logger.getLogger(NamesService.class.getName()); + + private EssNamingConvention namingConvention; + + private HolderIRepositories holderIRepositories; + private NameRepository nameRepository; + + @Autowired + public NamesService( + INameRepository iNameRepository, + ISystemGroupRepository iSystemGroupRepository, + ISystemRepository iSystemRepository, + ISubsystemRepository iSubsystemRepository, + IDisciplineRepository iDisciplineRepository, + IDeviceGroupRepository iDeviceGroupRepository, + IDeviceTypeRepository iDeviceTypeRepository, + NameRepository nameRepository) { + + this.namingConvention = new EssNamingConvention(); + this.holderIRepositories = new HolderIRepositories( + iNameRepository, + iSystemGroupRepository, + iSystemRepository, + iSubsystemRepository, + iDisciplineRepository, + iDeviceGroupRepository, + iDeviceTypeRepository); + this.nameRepository = nameRepository; + } + + @Transactional + public List<NameElement> createNames(List<NameElement> nameElements) { + // validate + // outside of @Transactional + // transaction + // do + // for each name element + // create name, latest, with data + // add name element for created + // return + // name elements for created names + + LOGGER.log(Level.INFO, "createNames, nameElements.size: " + String.valueOf(nameElements != null ? nameElements.size() : "null")); + + // do + String requestedBy = "test who"; + final List<NameElement> createdNameElements = Lists.newArrayList(); + for (NameElement nameElement : nameElements) { + // create + Name name = new Name(); + setAttributes(name, + UUID.randomUUID(), + nameElement.getSystemgroup(), nameElement.getSystem(), nameElement.getSubsystem(), nameElement.getDevicetype(), + nameElement.getIndex(), nameElement.getName(), namingConvention.equivalenceClassRepresentative(nameElement.getName()), + nameElement.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.FALSE, + new Date(), requestedBy, nameElement.getComment()); + + nameRepository.createName(name); + + // possibly validate that created + // approved, latest, not deleted, uuid + + // add + createdNameElements.add(NameElementUtil.getNameElement(name)); + } + + LOGGER.log(Level.INFO, "createNames, createdNameElements.size: " + createdNameElements.size()); + return createdNameElements; + } + + // ---------------------------------------------------------------------------------------------------- + + public List<NameElement> readNames( + Boolean deleted, FieldName[] queryFields, String[] queryValues, + FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { + return readNames(deleted, queryFields, queryValues, Boolean.FALSE, orderBy, isAsc, offset, limit); + } + + public List<NameElement> readNames( + Boolean deleted, FieldName[] queryFields, String[] queryValues, Boolean includeHistory, + FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { + + LOGGER.log(Level.INFO, "readNames, deleted: " + deleted); + LOGGER.log(Level.INFO, "readNames, queryFields.length: " + String.valueOf(queryFields != null ? queryFields.length : "null")); + LOGGER.log(Level.INFO, "readNames, queryValues.length: " + String.valueOf(queryValues != null ? queryValues.length : "null")); + LOGGER.log(Level.INFO, "readNames, includeHistory: " + includeHistory); + LOGGER.log(Level.INFO, "readNames, orderBy: " + orderBy); + LOGGER.log(Level.INFO, "readNames, isAsc: " + isAsc); + LOGGER.log(Level.INFO, "readNames, offset: " + offset); + LOGGER.log(Level.INFO, "readNames, limit: " + limit); + if (queryFields != null && queryFields.length > 0) { + for (FieldName queryField : queryFields) { + LOGGER.log(Level.INFO, "readNames, queryField: " + queryField); + } + } + if (queryValues != null && queryValues.length > 0) { + for (String queryValue : queryValues) { + LOGGER.log(Level.INFO, "readNames, queryValue: " + queryValue); + } + } + + // validate input + // queryFields and queryValues + // uuid + // do + // read names + // return + // name elements for names + + // validate input + ValidateUtil.validateNamesInputRead( + deleted, queryFields, queryValues, + includeHistory, + orderBy, isAsc, + offset, limit); + + // do + List<Name> names = nameRepository.readNames(deleted, queryFields, queryValues, includeHistory, orderBy, isAsc, offset, limit); + + final List<NameElement> nameElements = Lists.newArrayList(); + for (Name name : names) { + nameElements.add(NameElementUtil.getNameElement(name)); + } + + LOGGER.log(Level.INFO, "readNames, nameElements.size: " + nameElements.size()); + return nameElements; + } + + public List<NameElement> readNames( + String name, + FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { + + LOGGER.log(Level.INFO, "readNames, name: " + name); + + // validate input + // name or uuid + // to work with both uuid and name + // do + // name or uuid + // return + // name elements + + // validate input + ValidateUtil.validateInputName(name); + + // do + final List<NameElement> nameElements = Lists.newArrayList(); + try { + UUID.fromString(name); + Name latestByUuid = holderIRepositories.getNameRepository().findLatestByUuid(name); + if (latestByUuid != null) { + nameElements.add(NameElementUtil.getNameElement(latestByUuid)); + } + } catch (IllegalArgumentException e) { + nameElements.addAll(readNames(false, new FieldName[] {FieldName.NAME}, new String[] {name}, orderBy, isAsc, offset, limit)); + } + + LOGGER.log(Level.INFO, "readNames, nameElements.size: " + nameElements.size()); + return nameElements; + } + + public List<NameElement> readNamesSystemStructure( + String mnemonicpath, + FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { + + LOGGER.log(Level.INFO, "readNamesSystemStructure, mnemonicpath: " + mnemonicpath); + + // validate input + // mnemonic path + // do + // mnemonic path + // return + // name elements + + // validate input + ValidateUtil.validateInputMnemonicpath(mnemonicpath); + + // do + return readNames(false, new FieldName[] {FieldName.SYSTEMSTRUCTURE}, new String[] {mnemonicpath}, orderBy, isAsc, offset, limit); + } + + public List<NameElement> readNamesDeviceStructure( + String mnemonicpath, + FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { + + LOGGER.log(Level.INFO, "readNamesDeviceStructure, mnemonicpath: " + mnemonicpath); + + // validate input + // mnemonic path + // do + // mnemonic path + // return + // name elements + + // validate input + ValidateUtil.validateInputMnemonicpath(mnemonicpath); + + // do + return readNames(false, new FieldName[] {FieldName.DEVICESTRUCTURE}, new String[] {mnemonicpath}, orderBy, isAsc, offset, limit); + } + + public List<NameElement> readNamesHistory( + String uuid, + FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) { + LOGGER.log(Level.INFO, "readNamesHistory, uuid: " + uuid); + + // note + // HolderIRepositories and HolderSystemDeviceStructure may or may not be used for preparation of what to return + // validate input + // uuid + // do + // read history for name + // return + // name elements for names + + // validate input + ValidateUtil.validateInputUuid(uuid); + + // do + List<NameElement> nameElements = readNames(null, new FieldName[] {FieldName.UUID}, new String[] {uuid}, Boolean.TRUE, orderBy, isAsc, offset, limit); + + Collections.sort(nameElements, new Comparator<NameElement>() { + @Override + public int compare(NameElement e1, NameElement e2) { + return e1.getWhen().compareTo(e2.getWhen()); + } + }); + + LOGGER.log(Level.INFO, "readNamesHistory, nameElements.size: " + nameElements.size()); + + return nameElements; + } + + // ---------------------------------------------------------------------------------------------------- + + public String equivalenceName(String name) { + LOGGER.log(Level.INFO, "equivalenceName, name: " + name); + + // validate input + // do + // exists + + // validate input + ValidateUtil.validateInputName(name); + + // do + return namingConvention.equivalenceClassRepresentative(name); + } + + public Boolean existsName(String name) { + LOGGER.log(Level.INFO, "existsName, name: " + name); + + // validate input + // do + // exists + + // validate input + ValidateUtil.validateInputName(name); + + // do + List<Name> names = nameRepository.readNames(false, FieldName.NAME, name); + return !names.isEmpty(); + } + + public Boolean isLegacyName(String name) { + LOGGER.log(Level.INFO, "isLegacyName, name: " + name); + + // validate input + // do + // exists + + // validate input + ValidateUtil.validateInputName(name); + + // do + List<Name> names = nameRepository.readNames(false, FieldName.NAME, name); + ValidateUtil.validateCondition(names != null && names.size() == 1, HttpStatus.BAD_REQUEST, "name not available", name); + + Name toBeChecked = names.get(0); + + // system structure + if (toBeChecked.getSystemgroupUuid() != null) { + SystemGroup systemGroup = holderIRepositories.getSystemGroupRepository().findLatestNotDeletedByUuid(toBeChecked.getSystemgroupUuid().toString()); + ValidateUtil.validateCondition(systemGroup != null, HttpStatus.BAD_REQUEST, "system group not available", name); + + if (systemGroup.isDeleted()) { + return Boolean.TRUE; + } + } else if (toBeChecked.getSystemUuid() != null) { + org.openepics.names.repository.model.System system = holderIRepositories.getSystemRepository().findLatestNotDeletedByUuid(toBeChecked.getSystemUuid().toString()); + ValidateUtil.validateCondition(system != null, HttpStatus.BAD_REQUEST, "system not available", name); + + if (system.isDeleted()) { + return Boolean.TRUE; + } + + SystemGroup systemGroup = holderIRepositories.getSystemGroupRepository().findLatestNotDeletedByUuid(system.getParentUuid().toString()); + ValidateUtil.validateCondition(systemGroup != null, HttpStatus.BAD_REQUEST, "system group not available", name); + + if (systemGroup.isDeleted()) { + return Boolean.TRUE; + } + } else if (toBeChecked.getSubsystemUuid() != null) { + Subsystem subsystem = holderIRepositories.getSubsystemRepository().findLatestNotDeletedByUuid(toBeChecked.getSubsystemUuid().toString()); + ValidateUtil.validateCondition(subsystem != null, HttpStatus.BAD_REQUEST, "subsystem not available", name); + + if (subsystem.isDeleted()) { + return Boolean.TRUE; + } + + org.openepics.names.repository.model.System system = holderIRepositories.getSystemRepository().findLatestNotDeletedByUuid(subsystem.getParentUuid().toString()); + ValidateUtil.validateCondition(system != null, HttpStatus.BAD_REQUEST, "system not available", name); + + if (system.isDeleted()) { + return Boolean.TRUE; + } + + SystemGroup systemGroup = holderIRepositories.getSystemGroupRepository().findLatestNotDeletedByUuid(system.getParentUuid().toString()); + ValidateUtil.validateCondition(systemGroup != null, HttpStatus.BAD_REQUEST, "system group not available", name); + + if (systemGroup.isDeleted()) { + return Boolean.TRUE; + } + } + // device structure + if (toBeChecked.getDevicetypeUuid() != null) { + DeviceType deviceType = holderIRepositories.getDeviceTypeRepository().findLatestNotDeletedByUuid(toBeChecked.getDevicetypeUuid().toString()); + ValidateUtil.validateCondition(deviceType != null, HttpStatus.BAD_REQUEST, "device type not available", name); + + if (deviceType.isDeleted()) { + return Boolean.TRUE; + } + + DeviceGroup deviceGroup = holderIRepositories.getDeviceGroupRepository().findLatestNotDeletedByUuid(deviceType.getParentUuid().toString()); + ValidateUtil.validateCondition(deviceGroup != null, HttpStatus.BAD_REQUEST, "device group not available", name); + + if (deviceGroup.isDeleted()) { + return Boolean.TRUE; + } + + Discipline discipline = holderIRepositories.getDisciplineRepository().findLatestNotDeletedByUuid(deviceType.getParentUuid().toString()); + ValidateUtil.validateCondition(discipline != null, HttpStatus.BAD_REQUEST, "device group not available", name); + + if (discipline.isDeleted()) { + return Boolean.TRUE; + } + } + + return Boolean.FALSE; + } + + public Boolean isValidToCreateName(String name) { + LOGGER.log(Level.INFO, "isValidToCreateName, name: " + name); + + // validate input + // validate data + // not exists + + // validate input + ValidateUtil.validateInputName(name); + + // initiate holder of containers for system and device structure content, for performance reasons + // note false to not include deleted entries + HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories, false); + + // validate data + ValidateUtil.validateNameDataCreate(name, namingConvention, holderIRepositories, nameRepository, holder); + + return Boolean.TRUE; + } + + // ---------------------------------------------------------------------------------------------------- + + public void validateNamesCreate(NameElement nameElement) { + validateNamesCreate(nameElement, new HolderSystemDeviceStructure(holderIRepositories)); + } + public void validateNamesCreate(NameElement nameElement, HolderSystemDeviceStructure holder) { + // validate authority + // elsewhere + // naming user & admin + // validate input + // name element + // validate input itself + // validate data + // name element + // validate towards repository + + // validate input + ValidateUtil.validateNameElementInputCreate(nameElement); + + // validate data + ValidateUtil.validateNameElementDataCreate(nameElement, namingConvention, holderIRepositories, nameRepository, holder); + } + public void validateNamesCreate(List<NameElement> nameElements) { + // initiate holder of containers for system and device structure content, for performance reasons + HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); + + for (NameElement nameElement : nameElements) { + validateNamesCreate(nameElement, holder); + } + } + + public void validateNamesUpdate(NameElement nameElement) { + validateNamesUpdate(nameElement, new HolderSystemDeviceStructure(holderIRepositories)); + } + public void validateNamesUpdate(NameElement nameElement, HolderSystemDeviceStructure holder) { + // validate authority + // elsewhere + // naming user & admin + // validate input + // name element + // validate input itself + // validate data + // name element + // validate towards repository + + // validate input + ValidateUtil.validateNameElementInputUpdate(nameElement); + + // validate data + ValidateUtil.validateNameElementDataUpdate(nameElement, namingConvention, holderIRepositories, nameRepository, holder); + } + public void validateNamesUpdate(List<NameElement> nameElements) { + // initiate holder of containers for system and device structure content, for performance reasons + HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); + + for (NameElement nameElement : nameElements) { + validateNamesUpdate(nameElement, holder); + } + } + + public void validateNamesDelete(NameElement nameElement) { + validateNamesDelete(nameElement, new HolderSystemDeviceStructure(holderIRepositories)); + } + public void validateNamesDelete(NameElement nameElement, HolderSystemDeviceStructure holder) { + // validate authority + // elsewhere + // naming user & admin + // validate input + // uuid + // validate data + // retrieve name (uuid, latest, not deleted) + + // validate input + ValidateUtil.validateNameElementInputDelete(nameElement); + + // validate data + ValidateUtil.validateNameElementDataDelete(nameElement, namingConvention, holderIRepositories, nameRepository, holder); + } + public void validateNamesDelete(List<NameElement> nameElements) { + // validate authority + // elsewhere + // naming user & admin + // validate input + // name element + // validate input itself + // validate data + // name element + // validate towards repository + + // initiate holder of containers for system and device structure content, for performance reasons + HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); + + for (NameElement nameElement : nameElements) { + validateNamesDelete(nameElement, holder); + } + } + + // ---------------------------------------------------------------------------------------------------- + + @Transactional + public List<NameElement> updateNames(List<NameElement> nameElements) { + // validate + // outside of @Transactional + // transaction + // do + // for each name element + // update name to not latest + // insert name to latest, not deleted, with data + // read + // return + // name elements for updated names + + LOGGER.log(Level.INFO, "updateNames, nameElements.size: " + String.valueOf(nameElements != null ? nameElements.size() : "null")); + + // do + String requestedBy = "test who"; + final List<NameElement> updatedNameElements = Lists.newArrayList(); + for (NameElement nameElement : nameElements) { + // update not latest, not deleted + // create latest, not deleted + + Name name = holderIRepositories.getNameRepository().findLatestByUuid(nameElement.getUuid().toString()); + if (name == null) { + continue; + } + + // skip if name element has same content as name + // proceed without fail + if (NameElementUtil.hasSameContent(nameElement, name)) { + continue; + } + + // update + name.setLatest(Boolean.FALSE); + nameRepository.updateName(name); + + // create + name = new Name(); + setAttributes(name, + nameElement.getUuid(), + nameElement.getSystemgroup(), nameElement.getSystem(), nameElement.getSubsystem(), nameElement.getDevicetype(), + nameElement.getIndex(), nameElement.getName(), namingConvention.equivalenceClassRepresentative(nameElement.getName()), + nameElement.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.FALSE, + new Date(), requestedBy, nameElement.getComment()); + + nameRepository.createName(name); + + // possibly validate that updated + + // add + updatedNameElements.add(NameElementUtil.getNameElement(name)); + } + + LOGGER.log(Level.INFO, "updateNames, updatedNameElements.size: " + updatedNameElements.size()); + return updatedNameElements; + } + + // ---------------------------------------------------------------------------------------------------- + + @Transactional + public List<NameElement> deleteNames(List<NameElement> nameElements) { + // validate + // outside of @Transactional + // transaction + // do + // update name to not latest + // insert name to latest, deleted + // read + // return + // name element for deleted name + + LOGGER.log(Level.INFO, "deleteNames, nameElements.size: " + String.valueOf(nameElements != null ? nameElements.size() : "null")); + + // do + String requestedBy = "test who"; + final List<NameElement> deletedNameElements = Lists.newArrayList(); + for (NameElement nameElement : nameElements) { + Name name = holderIRepositories.getNameRepository().findLatestByUuid(nameElement.getUuid().toString()); + if (name == null) { + continue; + } + + name.setLatest(Boolean.FALSE); + nameRepository.updateName(name); + + name = new Name(); + setAttributes(name, + nameElement.getUuid(), + nameElement.getSystemgroup(), nameElement.getSystem(), nameElement.getSubsystem(), nameElement.getDevicetype(), + nameElement.getIndex(), nameElement.getName(), namingConvention.equivalenceClassRepresentative(nameElement.getName()), + nameElement.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.TRUE, + new Date(), requestedBy, nameElement.getComment()); + + nameRepository.createName(name); + + // possibly validate that deleted + + // add + deletedNameElements.add(NameElementUtil.getNameElement(name)); + } + + LOGGER.log(Level.INFO, "deleteNames, deletedNameElements.size: " + deletedNameElements.size()); + return deletedNameElements; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * Utility method to help set attributes for Name class. + * + * @param name name + * @param uuid uuid + * @param systemgroupUuid system group uuid + * @param systemUuid system uuid + * @param subsystemUuid subsystem uuid + * @param devicetypeUuid device type uuid + * @param index index + * @param conventionName convention name + * @param conventionNameEquivalence convention name equivalence + * @param description description + * @param status status + * @param latest latest + * @param deleted deleted + * @param requested requested + * @param requestedBy requested by + * @param requestedComment requested comment + */ + private void setAttributes(Name name, + UUID uuid, UUID systemgroupUuid, UUID systemUuid, UUID subsystemUuid, UUID devicetypeUuid, + String index, String conventionName, String conventionNameEquivalence, + String description, Status status, Boolean latest, Boolean deleted, + Date requested, String requestedBy, String requestedComment) { + name.setUuid(uuid); + name.setSystemgroupUuid(systemgroupUuid); + name.setSystemUuid(systemUuid); + name.setSubsystemUuid(subsystemUuid); + name.setDevicetypeUuid(devicetypeUuid); + name.setInstanceIndex(index); + name.setConventionName(conventionName); + name.setConventionNameEquivalence(conventionNameEquivalence); + name.setDescription(description); + name.setStatus(Status.APPROVED); + name.setLatest(latest); + name.setDeleted(deleted); + name.setRequested(requested); + name.setRequestedBy(requestedBy); + name.setRequestedComment(requestedComment); + + } +} diff --git a/src/main/java/org/openepics/names/service/StructuresService.java b/src/main/java/org/openepics/names/service/StructuresService.java new file mode 100644 index 0000000..d598c13 --- /dev/null +++ b/src/main/java/org/openepics/names/service/StructuresService.java @@ -0,0 +1,1601 @@ +/* + * Copyright (C) 2021 European Spallation Source ERIC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.openepics.names.service; + +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.commons.lang3.StringUtils; +import org.openepics.names.repository.DeviceGroupRepository; +import org.openepics.names.repository.DeviceTypeRepository; +import org.openepics.names.repository.DisciplineRepository; +import org.openepics.names.repository.IDeviceGroupRepository; +import org.openepics.names.repository.IDeviceTypeRepository; +import org.openepics.names.repository.IDisciplineRepository; +import org.openepics.names.repository.INameRepository; +import org.openepics.names.repository.ISubsystemRepository; +import org.openepics.names.repository.ISystemGroupRepository; +import org.openepics.names.repository.ISystemRepository; +import org.openepics.names.repository.NameRepository; +import org.openepics.names.repository.SubsystemRepository; +import org.openepics.names.repository.SystemGroupRepository; +import org.openepics.names.repository.SystemRepository; +import org.openepics.names.repository.model.DeviceGroup; +import org.openepics.names.repository.model.DeviceType; +import org.openepics.names.repository.model.Discipline; +import org.openepics.names.repository.model.Structure; +import org.openepics.names.repository.model.Subsystem; +import org.openepics.names.repository.model.System; +import org.openepics.names.repository.model.SystemGroup; +import org.openepics.names.rest.beans.FieldStructure; +import org.openepics.names.rest.beans.Status; +import org.openepics.names.rest.beans.StructureElement; +import org.openepics.names.rest.beans.Type; +import org.openepics.names.util.EssNamingConvention; +import org.openepics.names.util.HolderIRepositories; +import org.openepics.names.util.HolderRepositories; +import org.openepics.names.util.HolderSystemDeviceStructure; +import org.openepics.names.util.StructureElementUtil; +import org.openepics.names.util.StructureElementUtil.StructureChoice; +import org.openepics.names.util.ValidateUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.google.common.collect.Lists; + +/** + * This class provides structures services. + * + * @author Lars Johansson + */ +@Service +public class StructuresService { + + // HolderIRepositories and HolderSystemDeviceStructure may or may not be used for preparation of what to return + + // for each method + // document what values come from StructureElement and what values come from persistence layer + // somehow provide this information to user + + // latest + // automatically not show structures that do not come into play + // = automatically exclude (approved and not latest) + // otherwise refer to history + + private static final Logger LOGGER = Logger.getLogger(StructuresService.class.getName()); + + private EssNamingConvention namingConvention; + + private HolderIRepositories holderIRepositories; + private HolderRepositories holderRepositories; + + @Autowired + public StructuresService( + INameRepository iNameRepository, + ISystemGroupRepository iSystemGroupRepository, + ISystemRepository iSystemRepository, + ISubsystemRepository iSubsystemRepository, + IDisciplineRepository iDisciplineRepository, + IDeviceGroupRepository iDeviceGroupRepository, + IDeviceTypeRepository iDeviceTypeRepository, + NameRepository nameRepository, + SystemGroupRepository systemGroupRepository, + SystemRepository systemRepository, + SubsystemRepository subsystemRepository, + DisciplineRepository disciplineRepository, + DeviceGroupRepository deviceGroupRepository, + DeviceTypeRepository deviceTypeRepository) { + + this.namingConvention = new EssNamingConvention(); + this.holderIRepositories = new HolderIRepositories( + iNameRepository, + iSystemGroupRepository, + iSystemRepository, + iSubsystemRepository, + iDisciplineRepository, + iDeviceGroupRepository, + iDeviceTypeRepository); + this.holderRepositories = new HolderRepositories( + nameRepository, + systemGroupRepository, + systemRepository, + subsystemRepository, + disciplineRepository, + deviceGroupRepository, + deviceTypeRepository); + } + + @Transactional + public List<StructureElement> createStructures(List<StructureElement> structureElements) { + // validate + // outside of @Transactional + // transaction + // do + // for each structure element + // create structure to pending, not latest, not deleted, with data + // add structure element for created + // return + // structure elements for created structures + + LOGGER.log(Level.INFO, "createStructures, structureElements.size: " + String.valueOf(structureElements != null ? structureElements.size() : "null")); + + // initiate holder of containers for system and device structure content, for performance reasons + HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); + + // do + String requestedBy = "test who"; + final List<StructureElement> createdStructureElements = Lists.newArrayList(); + for (StructureElement structureElement : structureElements) { + if (Type.SYSTEMGROUP.equals(structureElement.getType())) { + // note rules for mnemonic for system group + String mnemonic = structureElement.getMnemonic(); + mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic; + + // create + SystemGroup systemGroup = new SystemGroup(); + setAttributes(systemGroup, + UUID.randomUUID(), + structureElement.getName(), mnemonic, !StringUtils.isEmpty(mnemonic) ? namingConvention.equivalenceClassRepresentative(mnemonic) : null, + structureElement.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.FALSE, + new Date(), requestedBy, structureElement.getComment()); + + holderRepositories.getSystemGroupRepository().createSystemGroup(systemGroup); + + // possibly validate that created + + // add + createdStructureElements.add(StructureElementUtil.getStructureElementRequested(systemGroup, holder)); + } else if (Type.SYSTEM.equals(structureElement.getType())) { + // create + System system = new System(); + setAttributes(system, + UUID.randomUUID(), structureElement.getParent(), + structureElement.getName(), structureElement.getMnemonic(), namingConvention.equivalenceClassRepresentative(structureElement.getMnemonic()), + structureElement.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.FALSE, + new Date(), requestedBy, structureElement.getComment()); + + holderRepositories.getSystemRepository().createSystem(system); + + // possibly validate that created + + // add + createdStructureElements.add(StructureElementUtil.getStructureElementRequested(system, holder)); + } else if (Type.SUBSYSTEM.equals(structureElement.getType())) { + // create + Subsystem subsystem = new Subsystem(); + setAttributes(subsystem, + UUID.randomUUID(), structureElement.getParent(), + structureElement.getName(), structureElement.getMnemonic(), namingConvention.equivalenceClassRepresentative(structureElement.getMnemonic()), + structureElement.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.FALSE, + new Date(), requestedBy, structureElement.getComment()); + + holderRepositories.getSubsystemRepository().createSubsystem(subsystem); + + // possibly validate that created + + // add + createdStructureElements.add(StructureElementUtil.getStructureElementRequested(subsystem, holder)); + } else if (Type.DISCIPLINE.equals(structureElement.getType())) { + // create + Discipline discipline = new Discipline(); + setAttributes(discipline, + UUID.randomUUID(), + structureElement.getName(), structureElement.getMnemonic(), namingConvention.equivalenceClassRepresentative(structureElement.getMnemonic()), + structureElement.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.FALSE, + new Date(), requestedBy, structureElement.getComment()); + + holderRepositories.getDisciplineRepository().createDiscipline(discipline); + + // possibly validate that created + + // add + createdStructureElements.add(StructureElementUtil.getStructureElementRequested(discipline, holder)); + } else if (Type.DEVICEGROUP.equals(structureElement.getType())) { + // note rules for mnemonic for device group + String mnemonic = structureElement.getMnemonic(); + mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic; + + // create + DeviceGroup deviceGroup = new DeviceGroup(); + setAttributes(deviceGroup, + UUID.randomUUID(), structureElement.getParent(), + structureElement.getName(), mnemonic, !StringUtils.isEmpty(mnemonic) ? namingConvention.equivalenceClassRepresentative(mnemonic) : null, + structureElement.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.FALSE, + new Date(), requestedBy, structureElement.getComment()); + + holderRepositories.getDeviceGroupRepository().createDeviceGroup(deviceGroup); + + // possibly validate that created + + // add + createdStructureElements.add(StructureElementUtil.getStructureElementRequested(deviceGroup, holder)); + } else if (Type.DEVICETYPE.equals(structureElement.getType())) { + // create + DeviceType deviceType = new DeviceType(); + setAttributes(deviceType, + UUID.randomUUID(), structureElement.getParent(), + structureElement.getName(), structureElement.getMnemonic(), namingConvention.equivalenceClassRepresentative(structureElement.getMnemonic()), + structureElement.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.FALSE, + new Date(), requestedBy, structureElement.getComment()); + + holderRepositories.getDeviceTypeRepository().createDeviceType(deviceType); + + // possibly validate that created + + // add + createdStructureElements.add(StructureElementUtil.getStructureElementRequested(deviceType, holder)); + } + } + + LOGGER.log(Level.INFO, "createStructures, createdStructureElements.size: " + createdStructureElements.size()); + return createdStructureElements; + } + + // ---------------------------------------------------------------------------------------------------- + + public List<StructureElement> readStructures( + Type type, Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + return readStructures(type, statuses, deleted, queryFields, queryValues, Boolean.FALSE, orderBy, isAsc, offset, limit, StructureChoice.STRUCTURE); + } + + //need to have public static enum StructureChoice {HISTORY, STRUCTURE}; + public List<StructureElement> readStructures( + Type type, Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, Boolean includeHistory, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit, + StructureChoice structureChoice) { + + LOGGER.log(Level.INFO, "readStructures, type: " + type); + LOGGER.log(Level.INFO, "readStructures, statuses.length: " + String.valueOf(statuses != null ? statuses.length : "null")); + LOGGER.log(Level.INFO, "readStructures, deleted: " + deleted); + LOGGER.log(Level.INFO, "readStructures, queryFields.length: " + String.valueOf(queryFields != null ? queryFields.length : "null")); + LOGGER.log(Level.INFO, "readStructures, queryValues.length: " + String.valueOf(queryValues != null ? queryValues.length : "null")); + LOGGER.log(Level.INFO, "readStructures, includeHistory: " + includeHistory); + LOGGER.log(Level.INFO, "readStructures, orderBy: " + orderBy); + LOGGER.log(Level.INFO, "readStructures, isAsc: " + isAsc); + LOGGER.log(Level.INFO, "readStructures, offset: " + offset); + LOGGER.log(Level.INFO, "readStructures, limit: " + limit); + LOGGER.log(Level.INFO, "readStructures, structureChoice: " + structureChoice); + if (statuses != null && statuses.length > 0) { + for (Status status : statuses) { + LOGGER.log(Level.INFO, "readStructures, status: " + status); + } + } + if (queryFields != null && queryFields.length > 0) { + for (FieldStructure queryField : queryFields) { + LOGGER.log(Level.INFO, "readStructures, queryField: " + queryField); + } + } + if (queryValues != null && queryValues.length > 0) { + for (String queryValue : queryValues) { + LOGGER.log(Level.INFO, "readStructures, queryValue: " + queryValue); + } + } + + // validate input + // type + // queryFields and queryValues + // uuid + // do + // read structures + // return + // structure elements for structures + + // validate input + ValidateUtil.validateStructuresInputRead( + type, statuses, deleted, queryFields, queryValues, + includeHistory, + orderBy, isAsc, + offset, limit); + + // initiate holder of containers for system and device structure content, for performance reasons + HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); + + // do + final List<StructureElement> structureElements = Lists.newArrayList(); + if (Type.SYSTEMGROUP.equals(type)) { + List<SystemGroup> systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups( + statuses, deleted, queryFields, queryValues, + includeHistory, + orderBy, isAsc, + offset, limit); + LOGGER.log(Level.INFO, "readStructures, systemGroups.size: " + systemGroups.size()); + structureElements.addAll(StructureElementUtil.getStructureElementsForSystemGroups(systemGroups, holder, structureChoice)); + } else if (Type.SYSTEM.equals(type)) { + List<System> systems = holderRepositories.getSystemRepository().readSystems( + statuses, deleted, queryFields, queryValues, + includeHistory, + orderBy, isAsc, + offset, limit); + LOGGER.log(Level.INFO, "readStructures, systems.size: " + systems.size()); + structureElements.addAll(StructureElementUtil.getStructureElementsForSystems(systems, holder, structureChoice)); + } else if (Type.SUBSYSTEM.equals(type)) { + List<Subsystem> subsystems = holderRepositories.getSubsystemRepository().readSubsystems( + statuses, deleted, queryFields, queryValues, + includeHistory, + orderBy, isAsc, + offset, limit); + LOGGER.log(Level.INFO, "readStructures, subsystems.size: " + subsystems.size()); + structureElements.addAll(StructureElementUtil.getStructureElementsForSubsystems(subsystems, holder, structureChoice)); + } else if (Type.DISCIPLINE.equals(type)) { + List<Discipline> disciplines = holderRepositories.getDisciplineRepository().readDisciplines( + statuses, deleted, queryFields, queryValues, + includeHistory, + orderBy, isAsc, + offset, limit); + LOGGER.log(Level.INFO, "readStructures, disciplines.size: " + disciplines.size()); + structureElements.addAll(StructureElementUtil.getStructureElementsForDisciplines(disciplines, holder, structureChoice)); + } else if (Type.DEVICEGROUP.equals(type)) { + List<DeviceGroup> deviceGroups = holderRepositories.getDeviceGroupRepository().readDeviceGroups( + statuses, deleted, queryFields, queryValues, + includeHistory, + orderBy, isAsc, + offset, limit); + LOGGER.log(Level.INFO, "readStructures, deviceGroups.size: " + deviceGroups.size()); + structureElements.addAll(StructureElementUtil.getStructureElementsForDeviceGroups(deviceGroups, holder, structureChoice)); + } else if (Type.DEVICETYPE.equals(type)) { + List<DeviceType> deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes( + statuses, deleted, queryFields, queryValues, + includeHistory, + orderBy, isAsc, + offset, limit); + LOGGER.log(Level.INFO, "readStructures, deviceTypes.size: " + deviceTypes.size()); + structureElements.addAll(StructureElementUtil.getStructureElementsForDeviceTypes(deviceTypes, holder, structureChoice)); + } + + LOGGER.log(Level.INFO, "readStructures, structureElements.size: " + structureElements.size()); + return structureElements; + } + + public List<StructureElement> readStructuresChildren( + Type type, String uuid, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + + // validate input + // type, uuid + // do + // read structure latest by uuid for type + // return + // structure elements for structures + + LOGGER.log(Level.INFO, "readStructuresChildren, type: " + type); + LOGGER.log(Level.INFO, "readStructuresChildren, uuid: " + uuid); + + // validate input + ValidateUtil.validateInputType(type); + ValidateUtil.validateInputUuid(uuid); + + // do + List<StructureElement> structureElements = Lists.newArrayList(); + if (Type.SYSTEMGROUP.equals(type)) { + structureElements.addAll(readStructures(Type.SYSTEM, new Status[] {Status.APPROVED}, false, new FieldStructure[] {FieldStructure.PARENT}, new String[] {uuid}, orderBy, isAsc, offset, limit)); + } else if (Type.SYSTEM.equals(type)) { + structureElements.addAll(readStructures(Type.SUBSYSTEM, new Status[] {Status.APPROVED}, false, new FieldStructure[] {FieldStructure.PARENT}, new String[] {uuid}, orderBy, isAsc, offset, limit)); + } else if (Type.SUBSYSTEM.equals(type)) { + // no children in structures + } else if (Type.DISCIPLINE.equals(type)) { + structureElements.addAll(readStructures(Type.DEVICEGROUP, new Status[] {Status.APPROVED}, false, new FieldStructure[] {FieldStructure.PARENT}, new String[] {uuid}, orderBy, isAsc, offset, limit)); + } else if (Type.DEVICEGROUP.equals(type)) { + structureElements.addAll(readStructures(Type.DEVICETYPE, new Status[] {Status.APPROVED}, false, new FieldStructure[] {FieldStructure.PARENT}, new String[] {uuid}, orderBy, isAsc, offset, limit)); + } else if (Type.DEVICETYPE.equals(type)) { + // no children in structures + } + LOGGER.log(Level.INFO, "readStructuresChildren, structureElements.size: " + structureElements.size()); + return structureElements; + } + + public List<StructureElement> readStructuresMnemonic( + String mnemonic, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + + // validate input + // mnemonic + // do + // read structure latest by mnemonic + // return + // structure elements for structures + + // validate input + ValidateUtil.validateInputMnemonic(mnemonic); + + // do + List<StructureElement> structureElements = Lists.newArrayList(); + structureElements.addAll(readStructures(Type.SYSTEMGROUP, new Status[] {Status.APPROVED}, false, new FieldStructure[] {FieldStructure.MNEMONIC}, new String[] {mnemonic}, orderBy, isAsc, offset, limit)); + structureElements.addAll(readStructures(Type.SYSTEM, new Status[] {Status.APPROVED}, false, new FieldStructure[] {FieldStructure.MNEMONIC}, new String[] {mnemonic}, orderBy, isAsc, offset, limit)); + structureElements.addAll(readStructures(Type.SUBSYSTEM, new Status[] {Status.APPROVED}, false, new FieldStructure[] {FieldStructure.MNEMONIC}, new String[] {mnemonic}, orderBy, isAsc, offset, limit)); + structureElements.addAll(readStructures(Type.DISCIPLINE, new Status[] {Status.APPROVED}, false, new FieldStructure[] {FieldStructure.MNEMONIC}, new String[] {mnemonic}, orderBy, isAsc, offset, limit)); + structureElements.addAll(readStructures(Type.DEVICEGROUP, new Status[] {Status.APPROVED}, false, new FieldStructure[] {FieldStructure.MNEMONIC}, new String[] {mnemonic}, orderBy, isAsc, offset, limit)); + structureElements.addAll(readStructures(Type.DEVICETYPE, new Status[] {Status.APPROVED}, false, new FieldStructure[] {FieldStructure.MNEMONIC}, new String[] {mnemonic}, orderBy, isAsc, offset, limit)); + + // TODO handle orderBy, isAsc, offset, limit + + return structureElements; + } + + public List<StructureElement> readStructuresMnemonicpath( + String mnemonicpath, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + + // validate input + // mnemonicpath + // do + // read structure latest by mnemonicpath + // return + // structure elements for structures + + // validate input + ValidateUtil.validateInputMnemonic(mnemonicpath); + + // do + List<StructureElement> structureElements = Lists.newArrayList(); + structureElements.addAll(readStructures(Type.SYSTEMGROUP, new Status[] {Status.APPROVED}, false, new FieldStructure[] {FieldStructure.MNEMONICPATH}, new String[] {mnemonicpath}, orderBy, isAsc, offset, limit)); + structureElements.addAll(readStructures(Type.SYSTEM, new Status[] {Status.APPROVED}, false, new FieldStructure[] {FieldStructure.MNEMONICPATH}, new String[] {mnemonicpath}, orderBy, isAsc, offset, limit)); + structureElements.addAll(readStructures(Type.SUBSYSTEM, new Status[] {Status.APPROVED}, false, new FieldStructure[] {FieldStructure.MNEMONICPATH}, new String[] {mnemonicpath}, orderBy, isAsc, offset, limit)); + structureElements.addAll(readStructures(Type.DISCIPLINE, new Status[] {Status.APPROVED}, false, new FieldStructure[] {FieldStructure.MNEMONICPATH}, new String[] {mnemonicpath}, orderBy, isAsc, offset, limit)); + structureElements.addAll(readStructures(Type.DEVICEGROUP, new Status[] {Status.APPROVED}, false, new FieldStructure[] {FieldStructure.MNEMONICPATH}, new String[] {mnemonicpath}, orderBy, isAsc, offset, limit)); + structureElements.addAll(readStructures(Type.DEVICETYPE, new Status[] {Status.APPROVED}, false, new FieldStructure[] {FieldStructure.MNEMONICPATH}, new String[] {mnemonicpath}, orderBy, isAsc, offset, limit)); + + // TODO handle orderBy, isAsc, offset, limit + + return structureElements; + } + + /** + * Read history for structure by uuid. + * + * @param uuid uuid + * @param type type + * @return list of structure elements + */ + public List<StructureElement> readStructuresHistory( + String uuid, Type type, + FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) { + + // note + // HolderIRepositories and HolderSystemDeviceStructure may or may not be used for preparation of what to return + // type may speed up read + // validate input + // uuid + // do + // read history for structure + // return + // structure elements for structures + + // validate input + ValidateUtil.validateInputUuid(uuid); + + boolean type_systemGroup = type != null && Type.SYSTEMGROUP.equals(type); + boolean type_system = type != null && Type.SYSTEM.equals(type); + boolean type_subsystem = type != null && Type.SUBSYSTEM.equals(type); + boolean type_discipline = type != null && Type.DISCIPLINE.equals(type); + boolean type_deviceGroup = type != null && Type.DEVICEGROUP.equals(type); + boolean type_deviceType = type != null && Type.DEVICETYPE.equals(type); + boolean type_either = type_systemGroup || type_system || type_subsystem || type_discipline || type_deviceGroup || type_deviceType; + + // mnemonic path does not make same sense for history + // (very) tricky to find mnemonic path for uuid at proper time (history) + // therefore empty mnemonic path for history for structure + + // do + final List<StructureElement> structureElements = Lists.newArrayList(); + if (type_either) { + if (type_systemGroup) { + structureElements.addAll(readStructures(Type.SYSTEMGROUP, null, null, new FieldStructure[] {FieldStructure.UUID}, new String[] {uuid}, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY)); + } else if (type_system) { + structureElements.addAll(readStructures(Type.SYSTEM, null, null, new FieldStructure[] {FieldStructure.UUID}, new String[] {uuid}, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY)); + } else if (type_subsystem) { + structureElements.addAll(readStructures(Type.SUBSYSTEM, null, null, new FieldStructure[] {FieldStructure.UUID}, new String[] {uuid}, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY)); + } else if (type_discipline) { + structureElements.addAll(readStructures(Type.DISCIPLINE, null, null, new FieldStructure[] {FieldStructure.UUID}, new String[] {uuid}, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY)); + } else if (type_deviceGroup) { + structureElements.addAll(readStructures(Type.DEVICEGROUP, null, null, new FieldStructure[] {FieldStructure.UUID}, new String[] {uuid}, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY)); + } else if (type_deviceType) { + structureElements.addAll(readStructures(Type.DEVICETYPE, null, null, new FieldStructure[] {FieldStructure.UUID}, new String[] {uuid}, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY)); + } + } else { + // go through all structures and see if / where uuid is found + + structureElements.addAll(readStructures(Type.SYSTEMGROUP, null, null, new FieldStructure[] {FieldStructure.UUID}, new String[] {uuid}, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY)); + structureElements.addAll(readStructures(Type.SYSTEM, null, null, new FieldStructure[] {FieldStructure.UUID}, new String[] {uuid}, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY)); + structureElements.addAll(readStructures(Type.SUBSYSTEM, null, null, new FieldStructure[] {FieldStructure.UUID}, new String[] {uuid}, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY)); + structureElements.addAll(readStructures(Type.DISCIPLINE, null, null, new FieldStructure[] {FieldStructure.UUID}, new String[] {uuid}, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY)); + structureElements.addAll(readStructures(Type.DEVICEGROUP, null, null, new FieldStructure[] {FieldStructure.UUID}, new String[] {uuid}, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY)); + structureElements.addAll(readStructures(Type.DEVICETYPE, null, null, new FieldStructure[] {FieldStructure.UUID}, new String[] {uuid}, Boolean.TRUE, orderBy, isAsc, offset, limit, StructureChoice.HISTORY)); + } + + Collections.sort(structureElements, new Comparator<StructureElement>() { + @Override + public int compare(StructureElement e1, StructureElement e2) { + return e1.getWhen().compareTo(e2.getWhen()); + } + }); + + return structureElements; + } + + // ---------------------------------------------------------------------------------------------------- + + public String equivalenceMnemonic(String mnemonic) { + // validate input + // do + // exists + + // validate input + ValidateUtil.validateInputMnemonic(mnemonic); + + // do + return namingConvention.equivalenceClassRepresentative(mnemonic); + } + + public Boolean existsStructure(Type type, String mnemonic) { + // validate input + // do + // exists + + // validate input + ValidateUtil.validateInputType(type); + ValidateUtil.validateInputMnemonic(mnemonic); + + // do + if (Type.SYSTEMGROUP.equals(type)) { + List<SystemGroup> systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.APPROVED, false, FieldStructure.MNEMONIC, mnemonic); + return !systemGroups.isEmpty(); + } else if (Type.SYSTEM.equals(type)) { + List<System> systems = holderRepositories.getSystemRepository().readSystems(Status.APPROVED, false, FieldStructure.MNEMONIC, mnemonic); + return !systems.isEmpty(); + } else if (Type.SUBSYSTEM.equals(type)) { + List<Subsystem> subsystems = holderRepositories.getSubsystemRepository().readSubsystems(Status.APPROVED, false, FieldStructure.MNEMONIC, mnemonic); + return !subsystems.isEmpty(); + } else if (Type.DISCIPLINE.equals(type)) { + List<Discipline> disciplines = holderRepositories.getDisciplineRepository().readDisciplines(Status.APPROVED, false, FieldStructure.MNEMONIC, mnemonic); + return !disciplines.isEmpty(); + } else if (Type.DEVICEGROUP.equals(type)) { + List<DeviceGroup> deviceGroups = holderRepositories.getDeviceGroupRepository().readDeviceGroups(Status.APPROVED, false, FieldStructure.MNEMONIC, mnemonic); + return !deviceGroups.isEmpty(); + } else if (Type.DEVICETYPE.equals(type)) { + List<DeviceType> deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes(Status.APPROVED, false, FieldStructure.MNEMONIC, mnemonic); + return !deviceTypes.isEmpty(); + } + + return Boolean.FALSE; + } + + public Boolean isValidToCreateStructure(Type type, String mnemonicpath) { + // validate input + // validate data + // not exists + + // validate input + ValidateUtil.validateInputType(type); + ValidateUtil.validateInputMnemonicpath(mnemonicpath); + + // initiate holder of containers for system and device structure content, for performance reasons + // note false to not include deleted entries + HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories, false); + + // validate data + ValidateUtil.validateStructureDataCreate(type, mnemonicpath, namingConvention, holderIRepositories, holder); + + return Boolean.TRUE; + } + + // ---------------------------------------------------------------------------------------------------- + + public void validateStructuresCreate(StructureElement structureElement) { + validateStructuresCreate(structureElement, new HolderSystemDeviceStructure(holderIRepositories)); + } + public void validateStructuresCreate(StructureElement structureElement, HolderSystemDeviceStructure holder) { + // validate input + // type + // structure element + // validate input itself + // validate data + // structure element + // validate data + // itself + // relative other data + + // validate input + ValidateUtil.validateStructureElementInputCreate(structureElement); + + // validate data + ValidateUtil.validateStructureElementDataCreate(structureElement, namingConvention, holderRepositories, holder); + } + public void validateStructuresCreate(List<StructureElement> structureElements) { + // initiate holder of containers for system and device structure content, for performance reasons + HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); + + for (StructureElement structureElement : structureElements) { + validateStructuresCreate(structureElement, holder); + } + } + + public void validateStructuresUpdate(StructureElement structureElement) { + validateStructuresUpdate(structureElement, new HolderSystemDeviceStructure(holderIRepositories)); + } + public void validateStructuresUpdate(StructureElement structureElement, HolderSystemDeviceStructure holder) { + // validate input + // type + // structure element + // validate input itself + // validate data + // structure element + // validate data + // itself + // relative other data + + // validate input + ValidateUtil.validateStructureElementInputUpdate(structureElement); + + // validate data + ValidateUtil.validateStructureElementDataUpdate(structureElement, namingConvention, holderRepositories, holder); + } + public void validateStructuresUpdate(List<StructureElement> structureElements) { + // initiate holder of containers for system and device structure content, for performance reasons + HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); + + for (StructureElement structureElement : structureElements) { + validateStructuresUpdate(structureElement, holder); + } + } + + public void validateStructuresDelete(StructureElement structureElement) { + validateStructuresDelete(structureElement, new HolderSystemDeviceStructure(holderIRepositories)); + } + public void validateStructuresDelete(StructureElement structureElement, HolderSystemDeviceStructure holder) { + // validate input + // type + // structure element + // validate input itself + // validate data + // structure element + // validate data + // itself + // relative other data + + // validate input + ValidateUtil.validateStructureElementInputDelete(structureElement); + + // validate data + ValidateUtil.validateStructureElementDataDelete(structureElement, namingConvention, holderRepositories, holder); + } + public void validateStructuresDelete(List<StructureElement> structureElements) { + // initiate holder of containers for system and device structure content, for performance reasons + HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); + + for (StructureElement structureElement : structureElements) { + validateStructuresDelete(structureElement, holder); + } + } + + public void validateStructuresApprove(StructureElement structureElement) { + validateStructuresApprove(structureElement, new HolderSystemDeviceStructure(holderIRepositories)); + } + public void validateStructuresApprove(StructureElement structureElement, HolderSystemDeviceStructure holder) { + // validate input + // type + // structure element + // validate input itself + // validate data + // structure element + // validate data + // itself + // relative other data + + // validate input + ValidateUtil.validateStructureElementInputApprove(structureElement); + + // validate data + ValidateUtil.validateStructureElementDataApprove(structureElement, namingConvention, holderRepositories, holder); + } + public void validateStructuresApprove(List<StructureElement> structureElements) { + // initiate holder of containers for system and device structure content, for performance reasons + HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); + + for (StructureElement structureElement : structureElements) { + validateStructuresApprove(structureElement, holder); + } + } + + public void validateStructuresCancel(StructureElement structureElement) { + validateStructuresCancel(structureElement, new HolderSystemDeviceStructure(holderIRepositories)); + } + public void validateStructuresCancel(StructureElement structureElement, HolderSystemDeviceStructure holder) { + // validate input + // type + // structure element + // validate input itself + // validate data + // structure element + // validate data + // itself + // relative other data + + // validate input + ValidateUtil.validateStructureElementInputCancel(structureElement); + + // validate data + ValidateUtil.validateStructureElementDataCancel(structureElement, namingConvention, holderRepositories, holder); + } + public void validateStructuresCancel(List<StructureElement> structureElements) { + // initiate holder of containers for system and device structure content, for performance reasons + HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); + + for (StructureElement structureElement : structureElements) { + validateStructuresCancel(structureElement, holder); + } + } + + public void validateStructuresReject(StructureElement structureElement) { + validateStructuresReject(structureElement, new HolderSystemDeviceStructure(holderIRepositories)); + } + public void validateStructuresReject(StructureElement structureElement, HolderSystemDeviceStructure holder) { + // validate input + // type + // structure element + // validate input itself + // validate data + // structure element + // validate data + // itself + // relative other data + + // validate input + ValidateUtil.validateStructureElementInputReject(structureElement); + + // validate data + ValidateUtil.validateStructureElementDataReject(structureElement, namingConvention, holderRepositories, holder); + } + public void validateStructuresReject(List<StructureElement> structureElements) { + // initiate holder of containers for system and device structure content, for performance reasons + HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); + + for (StructureElement structureElement : structureElements) { + validateStructuresReject(structureElement, holder); + } + } + + // ---------------------------------------------------------------------------------------------------- + + @Transactional + public List<StructureElement> updateStructures(List<StructureElement> structureElements) { + // validate + // outside of @Transactional + // transaction + // do + // for each structure element + // create structure to pending, not latest, not deleted, with data + // add structure element for updated + // return + // structure elements for updated structures + + LOGGER.log(Level.INFO, "updateStructures, structureElements.size: " + String.valueOf(structureElements != null ? structureElements.size() : "null")); + + // initiate holder of containers for system and device structure content, for performance reasons + HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); + + // do + String requestedBy = "test who"; + final List<StructureElement> updatedStructureElements = Lists.newArrayList(); + for (StructureElement structureElement : structureElements) { + if (Type.SYSTEMGROUP.equals(structureElement.getType())) { + // note rules for mnemonic for system group + String mnemonic = structureElement.getMnemonic(); + mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic; + + // create + SystemGroup systemGroup = new SystemGroup(); + setAttributes(systemGroup, + structureElement.getUuid(), + structureElement.getName(), mnemonic, !StringUtils.isEmpty(mnemonic) ? namingConvention.equivalenceClassRepresentative(mnemonic) : null, + structureElement.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.FALSE, + new Date(), requestedBy, structureElement.getComment()); + + holderRepositories.getSystemGroupRepository().createSystemGroup(systemGroup); + + // possibly validate that created + + // add + updatedStructureElements.add(StructureElementUtil.getStructureElementRequested(systemGroup, holder)); + } else if (Type.SYSTEM.equals(structureElement.getType())) { + // create + System system = new System(); + setAttributes(system, + structureElement.getUuid(), structureElement.getParent(), + structureElement.getName(), structureElement.getMnemonic(), namingConvention.equivalenceClassRepresentative(structureElement.getMnemonic()), + structureElement.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.FALSE, + new Date(), requestedBy, structureElement.getComment()); + + holderRepositories.getSystemRepository().createSystem(system); + + // possibly validate that created + + // add + updatedStructureElements.add(StructureElementUtil.getStructureElementRequested(system, holder)); + } else if (Type.SUBSYSTEM.equals(structureElement.getType())) { + // create + Subsystem subsystem = new Subsystem(); + setAttributes(subsystem, + structureElement.getUuid(), structureElement.getParent(), + structureElement.getName(), structureElement.getMnemonic(), namingConvention.equivalenceClassRepresentative(structureElement.getMnemonic()), + structureElement.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.FALSE, + new Date(), requestedBy, structureElement.getComment()); + + holderRepositories.getSubsystemRepository().createSubsystem(subsystem); + + // possibly validate that created + + // add + updatedStructureElements.add(StructureElementUtil.getStructureElementRequested(subsystem, holder)); + } else if (Type.DISCIPLINE.equals(structureElement.getType())) { + // create + Discipline discipline = new Discipline(); + setAttributes(discipline, + structureElement.getUuid(), + structureElement.getName(), structureElement.getMnemonic(), namingConvention.equivalenceClassRepresentative(structureElement.getMnemonic()), + structureElement.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.FALSE, + new Date(), requestedBy, structureElement.getComment()); + + holderRepositories.getDisciplineRepository().createDiscipline(discipline); + + // possibly validate that created + + // add + updatedStructureElements.add(StructureElementUtil.getStructureElementRequested(discipline, holder)); + } else if (Type.DEVICEGROUP.equals(structureElement.getType())) { + // note rules for mnemonic for device group + String mnemonic = structureElement.getMnemonic(); + mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic; + + // create + DeviceGroup deviceGroup = new DeviceGroup(); + setAttributes(deviceGroup, + structureElement.getUuid(), structureElement.getParent(), + structureElement.getName(), mnemonic, !StringUtils.isEmpty(mnemonic) ? namingConvention.equivalenceClassRepresentative(mnemonic) : null, + structureElement.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.FALSE, + new Date(), requestedBy, structureElement.getComment()); + + holderRepositories.getDeviceGroupRepository().createDeviceGroup(deviceGroup); + + // possibly validate that created + + // add + updatedStructureElements.add(StructureElementUtil.getStructureElementRequested(deviceGroup, holder)); + } else if (Type.DEVICETYPE.equals(structureElement.getType())) { + // create + DeviceType deviceType = new DeviceType(); + setAttributes(deviceType, + structureElement.getUuid(), structureElement.getParent(), + structureElement.getName(), structureElement.getMnemonic(), namingConvention.equivalenceClassRepresentative(structureElement.getMnemonic()), + structureElement.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.FALSE, + new Date(), requestedBy, structureElement.getComment()); + + holderRepositories.getDeviceTypeRepository().createDeviceType(deviceType); + + // possibly validate that created + + // add + updatedStructureElements.add(StructureElementUtil.getStructureElementRequested(deviceType, holder)); + } + } + + LOGGER.log(Level.INFO, "updateStructures, updatedStructureElements.size: " + updatedStructureElements.size()); + return updatedStructureElements; + } + + // ---------------------------------------------------------------------------------------------------- + + @Transactional + public List<StructureElement> deleteStructures(List<StructureElement> structureElements) { + // validate + // outside of @Transactional + // transaction + // do + // for each structure element + // find + // create structure to pending, not latest, deleted, with data + // add structure element for deleted + // return + // structure elements for deleted structures + // TODO continue ---> validation error + + LOGGER.log(Level.INFO, "deleteStructures, structureElements.size: " + String.valueOf(structureElements != null ? structureElements.size() : "null")); + + // initiate holder of containers for system and device structure content, for performance reasons + HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); + + // do + String requestedBy = "test who"; + final List<StructureElement> deletedStructureElements = Lists.newArrayList(); + for (StructureElement structureElement : structureElements) { + if (Type.SYSTEMGROUP.equals(structureElement.getType())) { + // find + List<SystemGroup> systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.APPROVED, false, FieldStructure.UUID, structureElement.getUuid().toString()); + if (systemGroups == null || systemGroups.size() != 1) { + continue; + } + SystemGroup toBeDeleted = systemGroups.get(0); + + // create + SystemGroup systemGroup = new SystemGroup(); + setAttributes(systemGroup, + toBeDeleted.getUuid(), + toBeDeleted.getName(), toBeDeleted.getMnemonic(), namingConvention.equivalenceClassRepresentative(toBeDeleted.getMnemonic()), + toBeDeleted.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.TRUE, + new Date(), requestedBy, structureElement.getComment()); + + holderRepositories.getSystemGroupRepository().createSystemGroup(systemGroup); + + // possibly validate that created + + // add + deletedStructureElements.add(StructureElementUtil.getStructureElementRequested(systemGroup, holder)); + } else if (Type.SYSTEM.equals(structureElement.getType())) { + // find + List<System> systems = holderRepositories.getSystemRepository().readSystems(Status.APPROVED, false, FieldStructure.UUID, structureElement.getUuid().toString()); + if (systems == null || systems.size() != 1) { + continue; + } + System toBeDeleted = systems.get(0); + + // create + System system = new System(); + setAttributes(system, + toBeDeleted.getUuid(), toBeDeleted.getParentUuid(), + toBeDeleted.getName(), toBeDeleted.getMnemonic(), namingConvention.equivalenceClassRepresentative(toBeDeleted.getMnemonic()), + toBeDeleted.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.TRUE, + new Date(), requestedBy, structureElement.getComment()); + + holderRepositories.getSystemRepository().createSystem(system); + + // possibly validate that created + + // add + deletedStructureElements.add(StructureElementUtil.getStructureElementRequested(system, holder)); + } else if (Type.SUBSYSTEM.equals(structureElement.getType())) { + // find + List<Subsystem> subsystems = holderRepositories.getSubsystemRepository().readSubsystems(Status.APPROVED, false, FieldStructure.UUID, structureElement.getUuid().toString()); + if (subsystems == null || subsystems.size() != 1) { + continue; + } + Subsystem toBeDeleted = subsystems.get(0); + + // create + Subsystem subsystem = new Subsystem(); + setAttributes(subsystem, + toBeDeleted.getUuid(), toBeDeleted.getParentUuid(), + toBeDeleted.getName(), toBeDeleted.getMnemonic(), namingConvention.equivalenceClassRepresentative(toBeDeleted.getMnemonic()), + toBeDeleted.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.TRUE, + new Date(), requestedBy, structureElement.getComment()); + + holderRepositories.getSubsystemRepository().createSubsystem(subsystem); + + // possibly validate that created + + // add + deletedStructureElements.add(StructureElementUtil.getStructureElementRequested(subsystem, holder)); + } else if (Type.DISCIPLINE.equals(structureElement.getType())) { + // find + List<Discipline> disciplines = holderRepositories.getDisciplineRepository().readDisciplines(Status.APPROVED, false, FieldStructure.UUID, structureElement.getUuid().toString()); + if (disciplines == null || disciplines.size() != 1) { + continue; + } + Discipline toBeDeleted = disciplines.get(0); + + // create + Discipline discipline = new Discipline(); + setAttributes(discipline, + toBeDeleted.getUuid(), + toBeDeleted.getName(), toBeDeleted.getMnemonic(), namingConvention.equivalenceClassRepresentative(toBeDeleted.getMnemonic()), + toBeDeleted.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.TRUE, + new Date(), requestedBy, structureElement.getComment()); + + holderRepositories.getDisciplineRepository().createDiscipline(discipline); + + // possibly validate that created + + // add + deletedStructureElements.add(StructureElementUtil.getStructureElementRequested(discipline, holder)); + } else if (Type.DEVICEGROUP.equals(structureElement.getType())) { + // find + List<DeviceGroup> deviceGroups = holderRepositories.getDeviceGroupRepository().readDeviceGroups(Status.APPROVED, false, FieldStructure.UUID, structureElement.getUuid().toString()); + if (deviceGroups == null || deviceGroups.size() != 1) { + continue; + } + DeviceGroup toBeDeleted = deviceGroups.get(0); + + // create + DeviceGroup deviceGroup = new DeviceGroup(); + setAttributes(deviceGroup, + toBeDeleted.getUuid(), toBeDeleted.getParentUuid(), + toBeDeleted.getName(), toBeDeleted.getMnemonic(), namingConvention.equivalenceClassRepresentative(toBeDeleted.getMnemonic()), + toBeDeleted.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.TRUE, + new Date(), requestedBy, structureElement.getComment()); + + holderRepositories.getDeviceGroupRepository().createDeviceGroup(deviceGroup); + + // possibly validate that created + + // add + deletedStructureElements.add(StructureElementUtil.getStructureElementRequested(deviceGroup, holder)); + } else if (Type.DEVICETYPE.equals(structureElement.getType())) { + // find + List<DeviceType> deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes(Status.APPROVED, false, FieldStructure.UUID, structureElement.getUuid().toString()); + if (deviceTypes == null || deviceTypes.size() != 1) { + continue; + } + DeviceType toBeDeleted = deviceTypes.get(0); + + // create + DeviceType deviceType = new DeviceType(); + setAttributes(deviceType, + toBeDeleted.getUuid(), toBeDeleted.getParentUuid(), + toBeDeleted.getName(), toBeDeleted.getMnemonic(), namingConvention.equivalenceClassRepresentative(toBeDeleted.getMnemonic()), + toBeDeleted.getDescription(), Status.PENDING, Boolean.FALSE, Boolean.TRUE, + new Date(), requestedBy, structureElement.getComment()); + + holderRepositories.getDeviceTypeRepository().createDeviceType(deviceType); + + // possibly validate that created + + // add + deletedStructureElements.add(StructureElementUtil.getStructureElementRequested(deviceType, holder)); + } + } + + LOGGER.log(Level.INFO, "deleteStructures, deletedStructureElements.size: " + deletedStructureElements.size()); + return deletedStructureElements; + } + + // ---------------------------------------------------------------------------------------------------- + + @Transactional + public List<StructureElement> approveStructures(List<StructureElement> structureElements) { + // validate + // outside of @Transactional + // transaction + // do + // update structure to status APPROVED + // return + // updated structure element + // TODO continue ---> validation error + + LOGGER.log(Level.INFO, "approveStructures, structureElements.size: " + String.valueOf(structureElements != null ? structureElements.size() : "null")); + + // initiate holder of containers for system and device structure content, for performance reasons + HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); + + // approve + // set not latest for current latest + // set approved, latest for pending + // possibly + // if deleted, names that belong to structure may be deleted, otherwise they are alive but become legacy names - legacy way for now + // TODO if not deleted, rename names that belong to structure if different mnemonic + // if that way, then compare what's about to be approved with what is latest + + // do + // update + // set not latest for current latest + // set approved, latest for pending + String processedBy = "test who"; + String processedComment = "test comment"; + final List<StructureElement> approvedStructureElements = Lists.newArrayList(); + for (StructureElement structureElement : structureElements) { + if (Type.SYSTEMGROUP.equals(structureElement.getType())) { + // find + List<SystemGroup> systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.APPROVED, Boolean.FALSE, FieldStructure.UUID, structureElement.getUuid().toString()); + SystemGroup systemGroup = null; + if (systemGroups != null && systemGroups.size() == 1) { + systemGroup = systemGroups.get(0); + + // update not latest + systemGroup.setLatest(Boolean.FALSE); + holderRepositories.getSystemGroupRepository().updateSystemGroup(systemGroup); + } + + // find + systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + if (systemGroups == null || systemGroups.size() != 1) { + continue; + } + systemGroup = systemGroups.get(0); + + // approve + setAttributesStatusProcessed(systemGroup, Status.APPROVED, new Date(), processedBy, processedComment); + systemGroup.setLatest(Boolean.TRUE); + holderRepositories.getSystemGroupRepository().updateSystemGroup(systemGroup); + + // possibly validate that approved + + // add + approvedStructureElements.add(StructureElementUtil.getStructureElementProcessed(systemGroup, holder)); + } else if (Type.SYSTEM.equals(structureElement.getType())) { + // find + List<System> systems = holderRepositories.getSystemRepository().readSystems(Status.APPROVED, Boolean.FALSE, FieldStructure.UUID, structureElement.getUuid().toString()); + System system = null; + if (systems != null && systems.size() == 1) { + system = systems.get(0); + + // update not latest + system.setLatest(Boolean.FALSE); + holderRepositories.getSystemRepository().updateSystem(system); + } + + // find + systems = holderRepositories.getSystemRepository().readSystems(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + if (systems == null || systems.size() != 1) { + continue; + } + system = systems.get(0); + + // approve + setAttributesStatusProcessed(system, Status.APPROVED, new Date(), processedBy, processedComment); + system.setLatest(Boolean.TRUE); + holderRepositories.getSystemRepository().updateSystem(system); + + // possibly validate that approved + + // add + approvedStructureElements.add(StructureElementUtil.getStructureElementProcessed(system, holder)); + } else if (Type.SUBSYSTEM.equals(structureElement.getType())) { + // find + List<Subsystem> subsystems = holderRepositories.getSubsystemRepository().readSubsystems(Status.APPROVED, Boolean.FALSE, FieldStructure.UUID, structureElement.getUuid().toString()); + Subsystem subsystem = null; + if (subsystems != null && subsystems.size() == 1) { + subsystem = subsystems.get(0); + + // update not latest + subsystem.setLatest(Boolean.FALSE); + holderRepositories.getSubsystemRepository().updateSubsystem(subsystem); + } + + // find + subsystems = holderRepositories.getSubsystemRepository().readSubsystems(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + if (subsystems == null || subsystems.size() != 1) { + continue; + } + subsystem = subsystems.get(0); + + // approve + setAttributesStatusProcessed(subsystem, Status.APPROVED, new Date(), processedBy, processedComment); + subsystem.setLatest(Boolean.TRUE); + holderRepositories.getSubsystemRepository().updateSubsystem(subsystem); + + // possibly validate that approved + + // add + approvedStructureElements.add(StructureElementUtil.getStructureElementProcessed(subsystem, holder)); + } else if (Type.DISCIPLINE.equals(structureElement.getType())) { + List<Discipline> disciplines = holderRepositories.getDisciplineRepository().readDisciplines(Status.APPROVED, Boolean.FALSE, FieldStructure.UUID, structureElement.getUuid().toString()); + Discipline discipline = null; + if (disciplines != null && disciplines.size() == 1) { + discipline = disciplines.get(0); + + // update not latest + discipline.setLatest(Boolean.FALSE); + holderRepositories.getDisciplineRepository().updateDiscipline(discipline); + } + + // find + disciplines = holderRepositories.getDisciplineRepository().readDisciplines(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + if (disciplines == null || disciplines.size() != 1) { + continue; + } + discipline = disciplines.get(0); + + // approve + setAttributesStatusProcessed(discipline, Status.APPROVED, new Date(), processedBy, processedComment); + discipline.setLatest(Boolean.TRUE); + holderRepositories.getDisciplineRepository().updateDiscipline(discipline); + + // possibly validate that approved + + // add + approvedStructureElements.add(StructureElementUtil.getStructureElementProcessed(discipline, holder)); + } else if (Type.DEVICEGROUP.equals(structureElement.getType())) { + // find + List<DeviceGroup> deviceGroups = holderRepositories.getDeviceGroupRepository().readDeviceGroups(Status.APPROVED, Boolean.FALSE, FieldStructure.UUID, structureElement.getUuid().toString()); + DeviceGroup deviceGroup = null; + if (deviceGroups != null && deviceGroups.size() == 1) { + deviceGroup = deviceGroups.get(0); + + // update not latest + deviceGroup.setLatest(Boolean.FALSE); + holderRepositories.getDeviceGroupRepository().updateDeviceGroup(deviceGroup); + } + + // find + deviceGroups = holderRepositories.getDeviceGroupRepository().readDeviceGroups(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + if (deviceGroups == null || deviceGroups.size() != 1) { + continue; + } + deviceGroup = deviceGroups.get(0); + + // approve + setAttributesStatusProcessed(deviceGroup, Status.APPROVED, new Date(), processedBy, processedComment); + deviceGroup.setLatest(Boolean.TRUE); + holderRepositories.getDeviceGroupRepository().updateDeviceGroup(deviceGroup); + + // possibly validate that approved + + // add + approvedStructureElements.add(StructureElementUtil.getStructureElementProcessed(deviceGroup, holder)); + } else if (Type.DEVICETYPE.equals(structureElement.getType())) { + // find + List<DeviceType> deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes(Status.APPROVED, Boolean.FALSE, FieldStructure.UUID, structureElement.getUuid().toString()); + DeviceType deviceType = null; + if (deviceTypes != null && deviceTypes.size() == 1) { + deviceType = deviceTypes.get(0); + + // update not latest + deviceType.setLatest(Boolean.FALSE); + holderRepositories.getDeviceTypeRepository().updateDeviceType(deviceType); + } + + // find + deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + if (deviceTypes == null || deviceTypes.size() != 1) { + continue; + } + deviceType = deviceTypes.get(0); + + // approve + setAttributesStatusProcessed(deviceType, Status.APPROVED, new Date(), processedBy, processedComment); + deviceType.setLatest(Boolean.TRUE); + holderRepositories.getDeviceTypeRepository().updateDeviceType(deviceType); + + // possibly validate that approved + + // add + approvedStructureElements.add(StructureElementUtil.getStructureElementProcessed(deviceType, holder)); + } + } + + LOGGER.log(Level.INFO, "approveStructures, approvedStructureElements.size: " + approvedStructureElements.size()); + return approvedStructureElements; + } + + @Transactional + public List<StructureElement> cancelStructures(List<StructureElement> structureElements) { + // validate + // outside of @Transactional + // transaction + // do + // update structure to status CANCELLED + // return + // updated structure element + // TODO continue ---> validation error + + LOGGER.log(Level.INFO, "cancelStructures, structureElements.size: " + String.valueOf(structureElements != null ? structureElements.size() : "null")); + + // initiate holder of containers for system and device structure content, for performance reasons + HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); + + // do + String processedBy = "test who"; + String processedComment = "test comment"; + final List<StructureElement> cancelledStructureElements = Lists.newArrayList(); + for (StructureElement structureElement : structureElements) { + if (Type.SYSTEMGROUP.equals(structureElement.getType())) { + // find + List<SystemGroup> systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + if (systemGroups == null || systemGroups.size() != 1) { + continue; + } + SystemGroup systemGroup = systemGroups.get(0); + + // cancel + setAttributesStatusProcessed(systemGroup, Status.CANCELLED, new Date(), processedBy, processedComment); + holderRepositories.getSystemGroupRepository().updateSystemGroup(systemGroup); + + // possibly validate that cancelled + + // add + cancelledStructureElements.add(StructureElementUtil.getStructureElementProcessed(systemGroup, holder)); + } else if (Type.SYSTEM.equals(structureElement.getType())) { + // find + List<System> systems = holderRepositories.getSystemRepository().readSystems(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + if (systems == null || systems.size() != 1) { + continue; + } + System system = systems.get(0); + + // cancel + setAttributesStatusProcessed(system, Status.CANCELLED, new Date(), processedBy, processedComment); + holderRepositories.getSystemRepository().updateSystem(system); + + // possibly validate that cancelled + + // add + cancelledStructureElements.add(StructureElementUtil.getStructureElementProcessed(system, holder)); + } else if (Type.SUBSYSTEM.equals(structureElement.getType())) { + // find + List<Subsystem> subsystems = holderRepositories.getSubsystemRepository().readSubsystems(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + if (subsystems == null || subsystems.size() != 1) { + continue; + } + Subsystem subsystem = subsystems.get(0); + + // cancel + setAttributesStatusProcessed(subsystem, Status.CANCELLED, new Date(), processedBy, processedComment); + holderRepositories.getSubsystemRepository().updateSubsystem(subsystem); + + // possibly validate that cancelled + + // add + cancelledStructureElements.add(StructureElementUtil.getStructureElementProcessed(subsystem, holder)); + } else if (Type.DISCIPLINE.equals(structureElement.getType())) { + // find + List<Discipline> disciplines = holderRepositories.getDisciplineRepository().readDisciplines(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + if (disciplines == null || disciplines.size() != 1) { + continue; + } + Discipline discipline = disciplines.get(0); + + // cancel + setAttributesStatusProcessed(discipline, Status.CANCELLED, new Date(), processedBy, processedComment); + holderRepositories.getDisciplineRepository().updateDiscipline(discipline); + + // possibly validate that cancelled + + // add + cancelledStructureElements.add(StructureElementUtil.getStructureElementProcessed(discipline, holder)); + } else if (Type.DEVICEGROUP.equals(structureElement.getType())) { + // find + List<DeviceGroup> deviceGroups = holderRepositories.getDeviceGroupRepository().readDeviceGroups(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + if (deviceGroups == null || deviceGroups.size() != 1) { + continue; + } + DeviceGroup deviceGroup = deviceGroups.get(0); + + // cancel + setAttributesStatusProcessed(deviceGroup, Status.CANCELLED, new Date(), processedBy, processedComment); + holderRepositories.getDeviceGroupRepository().updateDeviceGroup(deviceGroup); + + // possibly validate that cancelled + + // add + cancelledStructureElements.add(StructureElementUtil.getStructureElementProcessed(deviceGroup, holder)); + } else if (Type.DEVICETYPE.equals(structureElement.getType())) { + List<DeviceType> deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + if (deviceTypes == null || deviceTypes.size() != 1) { + continue; + } + DeviceType deviceType = deviceTypes.get(0); + + // cancel + setAttributesStatusProcessed(deviceType, Status.CANCELLED, new Date(), processedBy, processedComment); + holderRepositories.getDeviceTypeRepository().updateDeviceType(deviceType); + + // possibly validate that cancelled + + // add + cancelledStructureElements.add(StructureElementUtil.getStructureElementProcessed(deviceType, holder)); + } + } + + LOGGER.log(Level.INFO, "cancelStructures, cancelledStructureElements.size: " + cancelledStructureElements.size()); + return cancelledStructureElements; + } + + @Transactional + public List<StructureElement> rejectStructures(List<StructureElement> structureElements) { + // validate + // outside of @Transactional + // transaction + // do + // update structure to status REJECTED + // return + // updated structure element + // TODO continue ---> validation error + + LOGGER.log(Level.INFO, "rejectStructures, structureElements.size: " + String.valueOf(structureElements != null ? structureElements.size() : "null")); + + // initiate holder of containers for system and device structure content, for performance reasons + HolderSystemDeviceStructure holder = new HolderSystemDeviceStructure(holderIRepositories); + + // do + String processedBy = "test who"; + String processedComment = "test comment"; + final List<StructureElement> rejectedStructureElements = Lists.newArrayList(); + for (StructureElement structureElement : structureElements) { + if (Type.SYSTEMGROUP.equals(structureElement.getType())) { + // find + List<SystemGroup> systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + if (systemGroups == null || systemGroups.size() != 1) { + continue; + } + SystemGroup systemGroup = systemGroups.get(0); + + // reject + setAttributesStatusProcessed(systemGroup, Status.REJECTED, new Date(), processedBy, processedComment); + holderRepositories.getSystemGroupRepository().updateSystemGroup(systemGroup); + + // possibly validate that rejected + + // add + rejectedStructureElements.add(StructureElementUtil.getStructureElementProcessed(systemGroup, holder)); + } else if (Type.SYSTEM.equals(structureElement.getType())) { + // find + List<System> systems = holderRepositories.getSystemRepository().readSystems(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + if (systems == null || systems.size() != 1) { + continue; + } + System system = systems.get(0); + + // reject + setAttributesStatusProcessed(system, Status.REJECTED, new Date(), processedBy, processedComment); + holderRepositories.getSystemRepository().updateSystem(system); + + // possibly validate that rejected + + // add + rejectedStructureElements.add(StructureElementUtil.getStructureElementProcessed(system, holder)); + } else if (Type.SUBSYSTEM.equals(structureElement.getType())) { + // find + List<Subsystem> subsystems = holderRepositories.getSubsystemRepository().readSubsystems(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + if (subsystems == null || subsystems.size() != 1) { + continue; + } + Subsystem subsystem = subsystems.get(0); + + // reject + setAttributesStatusProcessed(subsystem, Status.REJECTED, new Date(), processedBy, processedComment); + holderRepositories.getSubsystemRepository().updateSubsystem(subsystem); + + // possibly validate that rejected + + // add + rejectedStructureElements.add(StructureElementUtil.getStructureElementProcessed(subsystem, holder)); + } else if (Type.DISCIPLINE.equals(structureElement.getType())) { + // find + List<Discipline> disciplines = holderRepositories.getDisciplineRepository().readDisciplines(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + if (disciplines == null || disciplines.size() != 1) { + continue; + } + Discipline discipline = disciplines.get(0); + + // reject + setAttributesStatusProcessed(discipline, Status.REJECTED, new Date(), processedBy, processedComment); + holderRepositories.getDisciplineRepository().updateDiscipline(discipline); + + // possibly validate that rejected + + // add + rejectedStructureElements.add(StructureElementUtil.getStructureElementProcessed(discipline, holder)); + } else if (Type.DEVICEGROUP.equals(structureElement.getType())) { + // find + List<DeviceGroup> deviceGroups = holderRepositories.getDeviceGroupRepository().readDeviceGroups(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + if (deviceGroups == null || deviceGroups.size() != 1) { + continue; + } + DeviceGroup deviceGroup = deviceGroups.get(0); + + // reject + setAttributesStatusProcessed(deviceGroup, Status.REJECTED, new Date(), processedBy, processedComment); + holderRepositories.getDeviceGroupRepository().updateDeviceGroup(deviceGroup); + + // possibly validate that rejected + + // add + rejectedStructureElements.add(StructureElementUtil.getStructureElementProcessed(deviceGroup, holder)); + } else if (Type.DEVICETYPE.equals(structureElement.getType())) { + List<DeviceType> deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + if (deviceTypes == null || deviceTypes.size() != 1) { + continue; + } + DeviceType deviceType = deviceTypes.get(0); + + // reject + setAttributesStatusProcessed(deviceType, Status.REJECTED, new Date(), processedBy, processedComment); + holderRepositories.getDeviceTypeRepository().updateDeviceType(deviceType); + + // possibly validate that rejected + + // add + rejectedStructureElements.add(StructureElementUtil.getStructureElementProcessed(deviceType, holder)); + } + } + + LOGGER.log(Level.INFO, "rejectStructures, rejectedStructureElements.size: " + rejectedStructureElements.size()); + return rejectedStructureElements; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * Utility method to help set attributes for Structure class, which in practice is either of its sub classes. + * + * @param structure structure + * @param status status + * @param requested requested + * @param requestedBy requested by + * @param requestedComment requested comment + */ + private void setAttributesStatusProcessed(Structure structure, Status status, Date processed, String processedBy, String processedComment) { + structure.setStatus(status); + structure.setProcessed(processed); + structure.setProcessedBy(processedBy); + structure.setProcessedComment(processedComment); + } + + private void setAttributes(SystemGroup systemGroup, UUID uuid, String name, String mnemonic, String mnemonicEquivalence, String description, Status status, Boolean isLatest, Boolean isDeleted, Date requested, String requestedBy, String requestedComment) { + setAttributesStructure(systemGroup, uuid, name, mnemonic, mnemonicEquivalence, description, status, isLatest, isDeleted, requested, requestedBy, requestedComment); + } + private void setAttributes(System system, UUID uuid, UUID parentUuid, String name, String mnemonic, String mnemonicEquivalence, String description, Status status, Boolean isLatest, Boolean isDeleted, Date requested, String requestedBy, String requestedComment) { + system.setParentUuid(parentUuid); + setAttributesStructure(system, uuid, name, mnemonic, mnemonicEquivalence, description, status, isLatest, isDeleted, requested, requestedBy, requestedComment); + } + private void setAttributes(Subsystem subsystem, UUID uuid, UUID parentUuid, String name, String mnemonic, String mnemonicEquivalence, String description, Status status, Boolean isLatest, Boolean isDeleted, Date requested, String requestedBy, String requestedComment) { + subsystem.setParentUuid(parentUuid); + setAttributesStructure(subsystem, uuid, name, mnemonic, mnemonicEquivalence, description, status, isLatest, isDeleted, requested, requestedBy, requestedComment); + } + private void setAttributes(Discipline discipline, UUID uuid, String name, String mnemonic, String mnemonicEquivalence, String description, Status status, Boolean isLatest, Boolean isDeleted, Date requested, String requestedBy, String requestedComment) { + setAttributesStructure(discipline, uuid, name, mnemonic, mnemonicEquivalence, description, status, isLatest, isDeleted, requested, requestedBy, requestedComment); + } + private void setAttributes(DeviceGroup deviceGroup, UUID uuid, UUID parentUuid, String name, String mnemonic, String mnemonicEquivalence, String description, Status status, Boolean isLatest, Boolean isDeleted, Date requested, String requestedBy, String requestedComment) { + deviceGroup.setParentUuid(parentUuid); + setAttributesStructure(deviceGroup, uuid, name, mnemonic, mnemonicEquivalence, description, status, isLatest, isDeleted, requested, requestedBy, requestedComment); + } + private void setAttributes(DeviceType deviceType, UUID uuid, UUID parentUuid, String name, String mnemonic, String mnemonicEquivalence, String description, Status status, Boolean isLatest, Boolean isDeleted, Date requested, String requestedBy, String requestedComment) { + deviceType.setParentUuid(parentUuid); + setAttributesStructure(deviceType, uuid, name, mnemonic, mnemonicEquivalence, description, status, isLatest, isDeleted, requested, requestedBy, requestedComment); + } + + /** + * Utility method to help set attributes for Structure class, which in practice is either of its sub classes. + * + * @param structure structure + * @param uuid uuid + * @param name name + * @param mnemonic mnemonic + * @param mnemonicEquivalence mnemonic equivalence + * @param description description + * @param status status + * @param latest latest + * @param deleted deleted + * @param requested requested + * @param requestedBy requested by + * @param requestedComment requested comment + */ + private void setAttributesStructure(Structure structure, + UUID uuid, + String name, String mnemonic, String mnemonicEquivalence, + String description, Status status, Boolean latest, Boolean deleted, + Date requested, String requestedBy, String requestedComment) { + structure.setUuid(uuid); + structure.setName(name); + structure.setMnemonic(mnemonic); + structure.setMnemonicEquivalence(mnemonicEquivalence); + structure.setDescription(description); + structure.setStatus(status); + structure.setLatest(latest); + structure.setDeleted(deleted); + structure.setRequested(requested); + structure.setRequestedBy(requestedBy); + structure.setRequestedComment(requestedComment); + } + +} diff --git a/src/main/java/org/openepics/names/util/EssNamingConvention.java b/src/main/java/org/openepics/names/util/EssNamingConvention.java new file mode 100644 index 0000000..ffd3906 --- /dev/null +++ b/src/main/java/org/openepics/names/util/EssNamingConvention.java @@ -0,0 +1,173 @@ +/*- + * Copyright (c) 2014 European Spallation Source ERIC. + * Copyright (c) 2014 Cosylab d.d. + * + * This file is part of Naming Service. + * Naming Service is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or any newer 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see https://www.gnu.org/licenses/gpl-2.0.txt + */ + +package org.openepics.names.util; + +import org.apache.commons.lang3.StringUtils; + +/** + * A naming convention definition used by ESS. + * + * @author Marko Kolar + * @author Karin Rathsman + * @author Lars Johansson + * + * @see NamingConvention + * @see NamingConventionUtil + */ +public class EssNamingConvention implements NamingConvention { + + // ---------------------------------------------------------------------------------------------------- + // rules for characters + // empty + // space + // value + // alphanumeric + // letter case + // length + // equivalenceClassRepresentative + // note + // mnemonic can be empty + // system structure - system group + // device structure - device group + // note + // mnemonic for system group may be part of ess name + // mnemonic for instance index may be omitted for ess name + // ---------------------------------------------------------------------------------------------------- + + // Note revision history of file in repository. + + private static final String MNEMONIC_ALPHABETIC_LOWERCASE = "^[a-z]+$"; + private static final String MNEMONIC_ALPHANUMERIC = "^[a-zA-Z0-9]+$"; + private static final String MNEMONIC_NUMERIC = "^[0-9]+$"; + private static final String MNEMONIC_NUMERIC_ZERO = "^[0]+$"; + + @Override + public boolean isInstanceIndexValid(String conventionName) { + // not override ruleset for instanceIndex + return isInstanceIndexValid(conventionName, false); + } + + @Override + public boolean isInstanceIndexValid(String conventionName, boolean overrideRuleset) { + String instanceIndex = NamingConventionUtil.extractInstanceIndex(conventionName); + if (overrideRuleset) { + // previous rules, less restrictions + + if (instanceIndex != null && instanceIndex.length() <= 6) { + return instanceIndex.matches(MNEMONIC_ALPHANUMERIC); + } else { + return false; + } + } else { + // normal path + + // p&id numeric + // p&id + // scientific + + if (NamingConventionUtil.isDisciplinePID(NamingConventionUtil.extractDiscipline(conventionName))) { + if (NamingConventionUtil.isMnemonicPathDeviceStructurePIDNumeric(NamingConventionUtil.extractMnemonicPathDeviceStructure(conventionName))) { + // 3 numeric + return isInstanceIndexValidNumeric(instanceIndex, 3, 3); + } + // 3 numeric & 0-3 alphabetic + return isInstanceIndexValidPID(instanceIndex); + } else { + // 1-4 numeric & non-zero + return isInstanceIndexValidNumeric(instanceIndex, 1, 4); + } + } + } + + /** + * Return if instance index is valid PID index. + * + * @param index instance index + * @return if instance index is valid + */ + private boolean isInstanceIndexValidPID(String index) { + if (index != null && index.length() >= 3 && index.length() <= 6) { + if (index.length() == 3) { + return index.matches(MNEMONIC_NUMERIC) + && !index.matches(MNEMONIC_NUMERIC_ZERO); + } else { + return index.substring(0, 3).matches(MNEMONIC_NUMERIC) + && index.substring(3, index.length()).matches(MNEMONIC_ALPHABETIC_LOWERCASE); + } + } + return false; + } + + /** + * Return if instance index is valid numeric index. + * + * @param index instance index + * @param nMin minimum length + * @param nMax maximum length + * @return if instance index is valid + */ + private boolean isInstanceIndexValidNumeric(String index, int nMin, int nMax) { + if ((index == null || index.length() == 0)) { + return nMin <= 0; + } else { + return (index.length() >= nMin && index.length() <= nMax) + && index.matches(MNEMONIC_NUMERIC) + && !index.matches(MNEMONIC_NUMERIC_ZERO); + } + } + + @Override + public String equivalenceClassRepresentative(String name) { + return name != null + ? name.toUpperCase() + .replaceAll("(?<=[A-Za-z])0+", "") + .replace('I', '1').replace('L', '1').replace('O', '0') + .replaceAll("(?<!\\d)0+(?=\\d)", "") + : null; + } + + @Override + public boolean isMnemonicPathValid(String mnemonicPath) { + // note + // split with help of utility + // valid if + // length 1, 2, 3 + // same mnemonic only once in mnemonic path + if (!StringUtils.isEmpty(mnemonicPath)) { + String[] values = NamingConventionUtil.string2MnemonicPath(mnemonicPath.trim()); + if (values.length < 0 || values.length > 3) { + return false; + } + switch (values.length) { + case 3: + return !StringUtils.equals(values[0], values[1]) + && !StringUtils.equals(values[0], values[2]) + && !StringUtils.equals(values[1], values[2]); + case 2: + return !StringUtils.equals(values[0], values[1]); + case 1: + return true; + default: + return false; + } + } + return false; + } + +} diff --git a/src/main/java/org/openepics/names/util/HolderRepositories.java b/src/main/java/org/openepics/names/util/HolderRepositories.java new file mode 100644 index 0000000..0fcd1df --- /dev/null +++ b/src/main/java/org/openepics/names/util/HolderRepositories.java @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2021 European Spallation Source ERIC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.openepics.names.util; + +import org.openepics.names.repository.DeviceGroupRepository; +import org.openepics.names.repository.DeviceTypeRepository; +import org.openepics.names.repository.DisciplineRepository; +import org.openepics.names.repository.NameRepository; +import org.openepics.names.repository.SubsystemRepository; +import org.openepics.names.repository.SystemGroupRepository; +import org.openepics.names.repository.SystemRepository; + +/** + * Utility class and holder of references to repositories. + * + * @author Lars Johansson + */ +public class HolderRepositories { + + private NameRepository nameRepository; + + private SystemGroupRepository systemGroupRepository; + private SystemRepository systemRepository; + private SubsystemRepository subsystemRepository; + + private DisciplineRepository disciplineRepository; + private DeviceGroupRepository deviceGroupRepository; + private DeviceTypeRepository deviceTypeRepository; + + /** + * Public constructor to populate references to repositories. + * + * @param nameRepository reference to name repository + * @param systemGroupRepository reference to system group repository + * @param systemRepository reference to system repository + * @param subsystemRepository reference to subsystem repository + * @param disciplineRepository reference to discipline repository + * @param deviceGroupRepository reference to device group repository + * @param deviceTypeRepository reference to device type repository + */ + public HolderRepositories( + NameRepository nameRepository, + SystemGroupRepository systemGroupRepository, + SystemRepository systemRepository, + SubsystemRepository subsystemRepository, + DisciplineRepository disciplineRepository, + DeviceGroupRepository deviceGroupRepository, + DeviceTypeRepository deviceTypeRepository) { + this.nameRepository = nameRepository; + this.systemGroupRepository = systemGroupRepository; + this.systemRepository = systemRepository; + this.subsystemRepository = subsystemRepository; + this.disciplineRepository = disciplineRepository; + this.deviceGroupRepository = deviceGroupRepository; + this.deviceTypeRepository = deviceTypeRepository; + } + + /** + * Return reference to name repository. + * + * @return reference to name repository + */ + public NameRepository getNameRepository() { + return nameRepository; + }; + + /** + * Return reference to system group repository. + * + * @return reference to system group repository + */ + public SystemGroupRepository getSystemGroupRepository() { + return systemGroupRepository; + }; + /** + * Return reference to system repository. + * + * @return reference to system repository + */ + public SystemRepository getSystemRepository() { + return systemRepository; + }; + /** + * Return reference to subsystem repository. + * + * @return reference to subsystem repository + */ + public SubsystemRepository getSubsystemRepository() { + return subsystemRepository; + }; + + /** + * Return reference to discipline repository. + * + * @return reference to discipline repository + */ + public DisciplineRepository getDisciplineRepository() { + return disciplineRepository; + }; + /** + * Return reference to device group repository. + * + * @return reference to device group repository + */ + public DeviceGroupRepository getDeviceGroupRepository() { + return deviceGroupRepository; + }; + /** + * Return reference to device type repository. + * + * @return reference to device type repository + */ + public DeviceTypeRepository getDeviceTypeRepository() { + return deviceTypeRepository; + }; + +} diff --git a/src/main/java/org/openepics/names/util/LogUtil.java b/src/main/java/org/openepics/names/util/LogUtil.java new file mode 100644 index 0000000..a088b95 --- /dev/null +++ b/src/main/java/org/openepics/names/util/LogUtil.java @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2022 European Spallation Source ERIC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.openepics.names.util; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.commons.lang3.StringUtils; + +/** + * Utility class to assist in handling of logs. + * + * @author Lars Johansson + */ +public class LogUtil { + + private static final String ORG_OPENEPICS_NAMES = "org.openepics.names"; + private static final String ORG_OPENEPICS_NAMES_UTIL_EXCEPTION_UTIL = "org.openepics.names.util.ExceptionUtil"; + + /** + * This class is not to be instantiated. + */ + private LogUtil() { + throw new IllegalStateException("Utility class"); + } + + /** + * Log service http status exception. + * + * @param logger logger + * @param level log level + * @param e service https status exception + */ + public static void logServiceHttpStatusException(Logger logger, Level level, ServiceHttpStatusException e) { + if (logger == null || level == null || e == null) { + return; + } + + String msg = !StringUtils.isEmpty(e.getMessage()) + ? e.getMessage() + : ""; + String details = !StringUtils.isEmpty(e.getDetails()) + ? " ### " + e.getDetails() + : ""; + String httpStatus = e.getHttpStatus() != null + ? " ### " + e.getHttpStatus().toString() + : ""; + msg = msg + details + httpStatus; + + logger.log(level, msg); + } + + /** + * Log stack trace elements. + * + * @param logger logger + * @param level log level + * @param e service https status exception + */ + public static void logStackTraceElements(Logger logger, Level level, ServiceHttpStatusException e) { + logStackTraceElements(logger, Level.SEVERE, e, 10, ORG_OPENEPICS_NAMES, ORG_OPENEPICS_NAMES_UTIL_EXCEPTION_UTIL); + } + + /** + * Log stack trace elements. + * + * @param logger logger + * @param level log level + * @param e exception + */ + public static void logStackTraceElements(Logger logger, Level level, Exception e) { + logStackTraceElements(logger, Level.SEVERE, e, 10, ORG_OPENEPICS_NAMES, ORG_OPENEPICS_NAMES_UTIL_EXCEPTION_UTIL); + } + + /** + * Log stack trace elements. + * + * @param logger logger + * @param level log level + * @param e service https status exception + * @param maxNumberOfLogs max number of logs + * @param filterInclude filter include + * @param filterExclude filter exclude + */ + public static void logStackTraceElements(Logger logger, Level level, ServiceHttpStatusException e, int maxNumberOfLogs, String filterInclude, String filterExclude) { + if (logger == null || level == null || e == null || maxNumberOfLogs <= 0) { + return; + } + + logStackTraceElements(logger, level, e.getStackTrace(), maxNumberOfLogs, filterInclude, filterExclude); + } + + /** + * Log stack trace elements. + * + * @param logger logger + * @param level log level + * @param e exception + * @param maxNumberOfLogs max number of logs + * @param filterInclude filter include + * @param filterExclude filter exclude + */ + public static void logStackTraceElements(Logger logger, Level level, Exception e, int maxNumberOfLogs, String filterInclude, String filterExclude) { + if (logger == null || level == null || e == null || maxNumberOfLogs <= 0) { + return; + } + + logStackTraceElements(logger, level, e.getStackTrace(), maxNumberOfLogs, filterInclude, filterExclude); + } + + /** + * Log stack trace elements. + * + * @param logger logger + * @param level log level + * @param stackTraceElements stack trace elements + * @param maxNumberOfLogs max number of logs + * @param filterInclude filter include + * @param filterExclude filter exclude + */ + private static void logStackTraceElements(Logger logger, Level level, StackTraceElement[] stackTraceElements, int maxNumberOfLogs, String filterInclude, String filterExclude) { + if (logger == null || level == null || stackTraceElements == null || maxNumberOfLogs <= 0) { + return; + } + + String str; + int count = 0; + for (StackTraceElement stackTraceElement : stackTraceElements) { + str = stackTraceElement.toString(); + + if ((StringUtils.isEmpty(filterInclude) || str.contains(filterInclude)) + && !(!StringUtils.isEmpty(filterExclude) && str.contains(filterExclude))) { + count++; + logger.log(level, str); + if (count == maxNumberOfLogs) { + break; + } + } + } + } + +} diff --git a/src/main/java/org/openepics/names/util/NameElementUtil.java b/src/main/java/org/openepics/names/util/NameElementUtil.java new file mode 100644 index 0000000..6ad6c29 --- /dev/null +++ b/src/main/java/org/openepics/names/util/NameElementUtil.java @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2021 European Spallation Source ERIC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.openepics.names.util; + +import java.util.Date; +import java.util.UUID; + +import org.openepics.names.repository.model.Name; +import org.openepics.names.repository.model.NameStructure; +import org.openepics.names.rest.beans.NameElement; +import org.openepics.names.rest.beans.Status; + +/** + * Utility class to assist in populating name elements based on repository content. + * <br/><br/> + * Different strategies for population of name elements are used in different methods. + * The difference in strategies is for finding out system structure and device structure mnemonic paths. + * + * @author Lars Johansson + */ +public class NameElementUtil { + + /** + * This class is not to be instantiated. + */ + private NameElementUtil() { + throw new IllegalStateException("Utility class"); + } + + /** + * Populate and return name element for name. + * + * @param name name + * @return name element + */ + public static NameElement getNameElement(Name name) { + if (name == null) { + return null; + } + + return getNameElement( + name.getUuid(), + name.getSystemgroupUuid(), name.getSystemUuid(), name.getSubsystemUuid(), name.getDevicetypeUuid(), + NamingConventionUtil.extractMnemonicPathSystemStructure(name.getConventionName()), + NamingConventionUtil.extractMnemonicPathDeviceStructure(name.getConventionName()), + name.getInstanceIndex(), name.getConventionName(), + name.getDescription(), Status.APPROVED, name.isLatest(), name.isDeleted(), + name.getRequested(), name.getRequestedBy(), name.getRequestedComment()); + } + + /** + * Populate and return name element. + * + * @param uuid uuid + * @param systemgroup system group + * @param system system + * @param subsystem subsystem + * @param devicetype device type + * @param systemstructure system structure mnemonic path + * @param devicestructure device structure mnemonic path + * @param index instance index + * @param name name + * @param description description + * @param status status + * @param latest latest + * @param deleted deleted + * @param when when + * @param who who + * @param comment comment + * @return name element + */ + protected static NameElement getNameElement( + UUID uuid, + UUID systemgroup, UUID system, UUID subsystem, UUID devicetype, + String systemstructure, String devicestructure, + String index, String name, + String description, Status status, Boolean latest, Boolean deleted, + Date when, String who, String comment) { + + return new NameElement( + uuid, + systemgroup, system, subsystem, devicetype, + systemstructure, devicestructure, + index, name, + description, status, latest, deleted, + when, who, comment); + } + + private static boolean hasSameContent(NameElement nameElement, NameStructure nameStructure) { + /* + NameElement + x uuid + x description + x status + x latest + x deleted + NameStructure + x uuid + x description + x status + x latest + x deleted + */ + + if (nameElement == null && nameStructure == null) + return true; + if (nameElement == null) + return false; + if (nameStructure == null) + return false; + + if (nameElement.getUuid() == null) { + if (nameStructure.getUuid() != null) + return false; + } else if (!nameElement.getUuid().equals(nameStructure.getUuid())) + return false; + if (nameElement.getDescription() == null) { + if (nameStructure.getDescription() != null) + return false; + } else if (!nameElement.getDescription().equals(nameStructure.getDescription())) + return false; + if (nameElement.getStatus() == null) { + if (nameStructure.getStatus() != null) + return false; + } else if (!nameElement.getStatus().equals(nameStructure.getStatus())) + return false; + if (nameElement.isLatest() == null) { + if (nameStructure.isLatest() != null) + return false; + } else if (!nameElement.isLatest().equals(nameStructure.isLatest())) + return false; + if (nameElement.isDeleted() == null) { + if (nameStructure.isDeleted() != null) + return false; + } else if (!nameElement.isDeleted().equals(nameStructure.isDeleted())) + return false; + + return true; + } + + public static boolean hasSameContent(NameElement nameElement, Name name) { + /* + NameElement + x systemgroup + x system + x subsystem + x devicetype + x index + x name + Name + x systemgroup_uuid + x system_uuid + x subsystem_uuid + x devicetype_uuid + x instance_index + x convention_name + */ + + if (!hasSameContent(nameElement, (NameStructure) name)) + return false; + + if (nameElement.getSystemgroup() == null) { + if (name.getSystemgroupUuid() != null) + return false; + } else if (!nameElement.getSystemgroup().equals(name.getSystemgroupUuid())) + return false; + if (nameElement.getSystem() == null) { + if (name.getSystemUuid() != null) + return false; + } else if (!nameElement.getSystem().equals(name.getSystemUuid())) + return false; + if (nameElement.getSubsystem() == null) { + if (name.getSubsystemUuid() != null) + return false; + } else if (!nameElement.getSubsystem().equals(name.getSubsystemUuid())) + return false; + if (nameElement.getDevicetype() == null) { + if (name.getDevicetypeUuid() != null) + return false; + } else if (!nameElement.getDevicetype().equals(name.getDevicetypeUuid())) + return false; + if (nameElement.getIndex() == null) { + if (name.getInstanceIndex() != null) + return false; + } else if (!nameElement.getIndex().equals(name.getInstanceIndex())) + return false; + if (nameElement.getName() == null) { + if (name.getConventionName() != null) + return false; + } else if (!nameElement.getName().equals(name.getConventionName())) + return false; + + return true; + } + +// /** +// * Populate and return name element for name. +// * +// * @param name name +// * @param holderSystemDeviceStructure holder of containers for system and device structure content +// * @return name element +// */ +// public static NameElement getNameElement(Name name, HolderSystemDeviceStructure holderSystemDeviceStructure) { +// if (name == null) { +// return null; +// } +// +// // find out how to populate return element for system structure, device structure +// // levelSystemStructure -1 ---> error +// // levelDeviceStructure -1 ---> error +// +// return new NameElement( +// name.getUuid(), +// name.getSystemgroupUuid(), name.getSystemUuid(), name.getSubsystemUuid(), name.getDevicetypeUuid(), +// getMnemonicPathSystemStructure( +// name, +// StructureUtil.getLevelSystemStructure(name), +// holderSystemDeviceStructure), +// getMnemonicPathDeviceStructure( +// name, +// StructureUtil.getLevelDeviceStructure(name), +// holderSystemDeviceStructure), +// name.getInstanceIndex(), name.getConventionName(), +// name.getDescription(), Status.APPROVED, name.isLatest(), name.isDeleted(), +// name.getRequested(), name.getRequestedBy(), name.getRequestedComment()); +// } +// +// /** +// * Populate and return name element for name. +// * +// * @param name name +// * @param holderIRepositories holder of references to repositories +// * @return name element +// */ +// public static NameElement getNameElement(Name name, HolderIRepositories holderIRepositories) { +// if (name == null) { +// return null; +// } +// +// // find out how to populate return element for system structure, device structure +// // levelSystemStructure -1 ---> error +// // levelDeviceStructure -1 ---> error +// +// return new NameElement( +// name.getUuid(), +// name.getSystemgroupUuid(), name.getSystemUuid(), name.getSubsystemUuid(), name.getDevicetypeUuid(), +// getMnemonicPathSystemStructure( +// name, +// StructureUtil.getLevelSystemStructure(name), +// holderIRepositories), +// getMnemonicPathDeviceStructure( +// name, +// StructureUtil.getLevelDeviceStructure(name), +// holderIRepositories), +// name.getInstanceIndex(), name.getConventionName(), +// name.getDescription(), Status.APPROVED, name.isLatest(), name.isDeleted(), +// name.getRequested(), name.getRequestedBy(), name.getRequestedComment()); +// } + +} diff --git a/src/main/java/org/openepics/names/util/NamingConvention.java b/src/main/java/org/openepics/names/util/NamingConvention.java new file mode 100644 index 0000000..b99c15e --- /dev/null +++ b/src/main/java/org/openepics/names/util/NamingConvention.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2014 European Spallation Source ERIC. + * Copyright (c) 2014 Cosylab d.d. + * + * This file is part of Naming Service. + * Naming Service is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or any newer 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see https://www.gnu.org/licenses/gpl-2.0.txt + */ + +package org.openepics.names.util; + +/** + * An interface defining the naming convention to be used by the Naming application. + * It includes: + * <ul> + * <li> name validation rules + * <li> name uniqueness rules + * <li> form of composite names + * </ul> + * + * <p> + * The used naming convention is configured through beans.xml using the CDI alternatives mechanism. + * + * <p> + * A device name consists of elements having general structure + * <ul> + * <li> <pre>Sys-Sub:Dis-Dev-Idx</pre> + * <li> <pre>Sup-Sys-Sub:Dis-Dev-Idx</pre> + * </ul> + * It consists of of <br/><br/> + * <ul> + * <li> System structure + * <ul> + * <li> System group (Sup)(optional) + * <li> System (Sys) + * <li> Subsystem (Sub) + * </ul> + * <li> Device structure + * <ul> + * <li> Discipline (Dis) + * <li> Device type (Dev) + * </ul> + * <li> Device + * <ul> + * <li> Instance index (Idx) + * </ul> + * </ul> + * + * A device name thus consists of an system structure element, a device structure element and an instance index. + * Together, elements make a device name. In addition, there is intermediate level in device structure + * (device group, between discipline and device type) for grouping purposes.<br/><br/> + * + * <p> + * An element in the name structure is typically handled through its mnemonic path and type. + * <ul> + * <li> mnemonic path is a list of mnemonics starting from the root of the hierarchy to the intended mnemonic + * <li> root of hierarchy is system group (system structure) or discipline (device structure) + * <li> type is structure that mnemonic path belongs, system or device structure + * </ul> + * + * <p> + * Elements consist of full name, mnemonic, description and follow rules, individually and together + * (system structure, device structure, device). Among rules: + * <ul> + * <li> empty + * <li> space + * <li> value + * <li> alphanumeric + * <li> letter case + * <li> length + * <li> equivalence class representative + * </ul> + * + * <p> + * Key concepts + * <ul> + * <li> mnemonic required or not + * <li> mnemonic valid or not + * <li> if mnemonic can coexist with other mnemonic + * <li> equivalence, uniqueness of names when treating similar looking names + * </ul> + * + * <p> + * Note + * <ul> + * <li> system structure is logical structure + * <li> depth of system and device structures is 3 + * <li> names typically handled and referred to through mnemonics + * <li> naming convention also referred to as convention + * </ul> + * + * @author Marko Kolar + * @author Karin Rathsman + * @author Lars Johansson + * + * @see <a href="https://confluence.esss.lu.se/display/NC/ESS+Naming+Convention"/> + * https://confluence.esss.lu.se/display/NC/ESS+Naming+Convention</a> + * @see <a href="https://chess.esss.lu.se/enovia/tvc-action/showObject/dmg_TechnicalSpecification/ESS-0000757/valid"> + * https://chess.esss.lu.se/enovia/tvc-action/showObject/dmg_TechnicalSpecification/ESS-0000757/valid</a> + * + * @see NamingConventionUtil + */ +public interface NamingConvention { + + /** + * Return if the convention name's instance index is valid according to convention rules, + * in the context of system structure and device structure. + * + * @param conventionName convention name + * @return <tt>true</tt> if the convention name's instance index is valid according to convention rules, + * in the context of system structure and device structure + */ + boolean isInstanceIndexValid(String conventionName); + + /** + * Return if the convention name's instance index is valid according to convention rules, + * in the context of system structure and device structure. + * + * @param conventionName convention name + * @param overrideRuleset if ruleset for instance index is to be overridden, e.g. for super user + * @return <tt>true</tt> if the convention name's instance index is valid according to convention rules, + * in the context of system structure and device structure + */ + boolean isInstanceIndexValid(String conventionName, boolean overrideRuleset); + + /** + * Return equivalence class representative for given name. This is used to ensure uniqueness of names + * when treating similar looking names, e.g. 0 vs. O, 1 vs. l treated as as equal. + * + * @param name name of which to determine the equivalence class representative + * @return equivalence class representative for given name + */ + String equivalenceClassRepresentative(String name); + + /** + * Return if mnemonic path is valid within the application according to the convention rules. + * + * @param mnemonicPath list of mnemonics starting from the root of the hierarchy to the mnemonic to be tested + * @return <tt>true</tt> if mnemonic path is valid within the application according to the convention rules + */ + boolean isMnemonicPathValid(String mnemonicPath); + +} diff --git a/src/main/java/org/openepics/names/util/StructureElementUtil.java b/src/main/java/org/openepics/names/util/StructureElementUtil.java new file mode 100644 index 0000000..1a40fbb --- /dev/null +++ b/src/main/java/org/openepics/names/util/StructureElementUtil.java @@ -0,0 +1,800 @@ +/* + * Copyright (C) 2021 European Spallation Source ERIC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.openepics.names.util; + +import java.util.Date; +import java.util.List; +import java.util.UUID; + +import org.apache.commons.lang3.StringUtils; +import org.openepics.names.repository.model.DeviceGroup; +import org.openepics.names.repository.model.DeviceType; +import org.openepics.names.repository.model.Discipline; +import org.openepics.names.repository.model.NameStructure; +import org.openepics.names.repository.model.Structure; +import org.openepics.names.repository.model.Subsystem; +import org.openepics.names.repository.model.System; +import org.openepics.names.repository.model.SystemGroup; +import org.openepics.names.rest.beans.Status; +import org.openepics.names.rest.beans.StructureElement; +import org.openepics.names.rest.beans.Type; + +import com.google.common.collect.Lists; + +/** + * Utility class to assist in populating structure elements based on repository content. + * + * @author Lars Johansson + */ +public class StructureElementUtil { + + public static enum StructureChoice {HISTORY, STRUCTURE}; + + private static final long THOUSAND_MILLISECONDS = 1000; + + /** + * This class is not to be instantiated. + */ + private StructureElementUtil() { + throw new IllegalStateException("Utility class"); + } + + /** + * Populate and return list of structure elements for system groups. + * + * @param systemGroups system groups + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @param structureChoice whether to consider content from structure perspective or history perspective. + * Structure perspective gives one StructureElement object (processed). + * History perspective gives two StructureElement objects (processed, requested). + * If choice not given then default as structure perspective (processed). + * @return list of structure elements + */ + public static List<StructureElement> getStructureElementsForSystemGroups(List<SystemGroup> systemGroups, HolderSystemDeviceStructure holderSystemDeviceStructure, StructureChoice structureChoice) { + List<StructureElement> structureElements = Lists.newArrayList(); + for (SystemGroup systemGroup : systemGroups) { + // one or two return elements + // processed != null and processed != requested (> 1s difference) --> two entries (processed, requested) + // processed != null and processed == requested (<= 1s difference) --> one entry (processed initial) + // processed == null --> one entry (requested) + + if (StructureChoice.HISTORY.equals(structureChoice)) { + if (systemGroup.getProcessed() != null && ((systemGroup.getProcessed().getTime() - systemGroup.getRequested().getTime()) > THOUSAND_MILLISECONDS)) { + structureElements.add(getStructureElementProcessed(systemGroup, holderSystemDeviceStructure)); + structureElements.add(getStructureElementRequested(systemGroup, holderSystemDeviceStructure)); + } else if (systemGroup.getProcessed() != null && ((systemGroup.getProcessed().getTime() - systemGroup.getRequested().getTime()) <= THOUSAND_MILLISECONDS)) { + structureElements.add(getStructureElementProcessed(systemGroup, holderSystemDeviceStructure)); + } else { + structureElements.add(getStructureElementRequested(systemGroup, holderSystemDeviceStructure)); + } + } else { + if (Status.PENDING.equals(systemGroup.getStatus())) { + structureElements.add(getStructureElementRequested(systemGroup, holderSystemDeviceStructure)); + } else { + structureElements.add(getStructureElementProcessed(systemGroup, holderSystemDeviceStructure)); + } + } + } + return structureElements; + } + /** + * Populate and return list of structure elements for systems. + * + * @param systems systems + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return list of structure elements + */ + public static List<StructureElement> getStructureElementsForSystems(List<System> systems, HolderSystemDeviceStructure holderSystemDeviceStructure, StructureChoice structureChoice) { + List<StructureElement> structureElements = Lists.newArrayList(); + for (System system : systems) { + // one or two return elements + // processed != null and processed != requested (> 1s difference) --> two entries (processed, requested) + // processed != null and processed == requested (<= 1s difference) --> one entry (processed initial) + // processed == null --> one entry (requested) + + if (StructureChoice.HISTORY.equals(structureChoice)) { + if (system.getProcessed() != null && ((system.getProcessed().getTime() - system.getRequested().getTime()) > THOUSAND_MILLISECONDS)) { + structureElements.add(getStructureElementProcessed(system, holderSystemDeviceStructure)); + structureElements.add(getStructureElementRequested(system, holderSystemDeviceStructure)); + } else if (system.getProcessed() != null && ((system.getProcessed().getTime() - system.getRequested().getTime()) <= THOUSAND_MILLISECONDS)) { + structureElements.add(getStructureElementProcessed(system, holderSystemDeviceStructure)); + } else { + structureElements.add(getStructureElementRequested(system, holderSystemDeviceStructure)); + } + } else { + if (Status.PENDING.equals(system.getStatus())) { + structureElements.add(getStructureElementRequested(system, holderSystemDeviceStructure)); + } else { + structureElements.add(getStructureElementProcessed(system, holderSystemDeviceStructure)); + } + } + } + return structureElements; + } + /** + * Populate and return list of structure elements for subsystems. + * + * @param subsystems subsystems + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return list of structure elements + */ + public static List<StructureElement> getStructureElementsForSubsystems(List<Subsystem> subsystems, HolderSystemDeviceStructure holderSystemDeviceStructure, StructureChoice structureChoice) { + List<StructureElement> structureElements = Lists.newArrayList(); + for (Subsystem subsystem : subsystems) { + // one or two return elements + // processed != null and processed != requested (> 1s difference) --> two entries (processed, requested) + // processed != null and processed == requested (<= 1s difference) --> one entry (processed initial) + // processed == null --> one entry (requested) + + if (StructureChoice.HISTORY.equals(structureChoice)) { + if (subsystem.getProcessed() != null && ((subsystem.getProcessed().getTime() - subsystem.getRequested().getTime()) > THOUSAND_MILLISECONDS)) { + structureElements.add(getStructureElementProcessed(subsystem, holderSystemDeviceStructure)); + structureElements.add(getStructureElementRequested(subsystem, holderSystemDeviceStructure)); + } else if (subsystem.getProcessed() != null && ((subsystem.getProcessed().getTime() - subsystem.getRequested().getTime()) <= THOUSAND_MILLISECONDS)) { + structureElements.add(getStructureElementProcessed(subsystem, holderSystemDeviceStructure)); + } else { + structureElements.add(getStructureElementRequested(subsystem, holderSystemDeviceStructure)); + } + } else { + if (Status.PENDING.equals(subsystem.getStatus())) { + structureElements.add(getStructureElementRequested(subsystem, holderSystemDeviceStructure)); + } else { + structureElements.add(getStructureElementProcessed(subsystem, holderSystemDeviceStructure)); + } + } + } + return structureElements; + } + + /** + * Populate and return list of structure elements for disciplines. + * + * @param disciplines disciplines + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return list of structure elements + */ + public static List<StructureElement> getStructureElementsForDisciplines(List<Discipline> disciplines, HolderSystemDeviceStructure holderSystemDeviceStructure, StructureChoice structureChoice) { + List<StructureElement> structureElements = Lists.newArrayList(); + for (Discipline discipline : disciplines) { + // one or two return elements + // processed != null and processed != requested (> 1s difference) --> two entries (processed, requested) + // processed != null and processed == requested (<= 1s difference) --> one entry (processed initial) + // processed == null --> one entry (requested) + + if (StructureChoice.HISTORY.equals(structureChoice)) { + if (discipline.getProcessed() != null && ((discipline.getProcessed().getTime() - discipline.getRequested().getTime()) > THOUSAND_MILLISECONDS)) { + structureElements.add(getStructureElementProcessed(discipline, holderSystemDeviceStructure)); + structureElements.add(getStructureElementRequested(discipline, holderSystemDeviceStructure)); + } else if (discipline.getProcessed() != null && ((discipline.getProcessed().getTime() - discipline.getRequested().getTime()) <= THOUSAND_MILLISECONDS)) { + structureElements.add(getStructureElementProcessed(discipline, holderSystemDeviceStructure)); + } else { + structureElements.add(getStructureElementRequested(discipline, holderSystemDeviceStructure)); + } + } else { + if (Status.PENDING.equals(discipline.getStatus())) { + structureElements.add(getStructureElementRequested(discipline, holderSystemDeviceStructure)); + } else { + structureElements.add(getStructureElementProcessed(discipline, holderSystemDeviceStructure)); + } + } + } + return structureElements; + } + /** + * Populate and return list of structure elements for device groups. + * + * @param deviceGroups device groups + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return list of structure elements + */ + public static List<StructureElement> getStructureElementsForDeviceGroups(List<DeviceGroup> deviceGroups, HolderSystemDeviceStructure holderSystemDeviceStructure, StructureChoice structureChoice) { + List<StructureElement> structureElements = Lists.newArrayList(); + for (DeviceGroup deviceGroup : deviceGroups) { + // one or two return elements + // processed != null and processed != requested (> 1s difference) --> two entries (processed, requested) + // processed != null and processed == requested (<= 1s difference) --> one entry (processed initial) + // processed == null --> one entry (requested) + + if (StructureChoice.HISTORY.equals(structureChoice)) { + if (deviceGroup.getProcessed() != null && ((deviceGroup.getProcessed().getTime() - deviceGroup.getRequested().getTime()) > THOUSAND_MILLISECONDS)) { + structureElements.add(getStructureElementProcessed(deviceGroup, holderSystemDeviceStructure)); + structureElements.add(getStructureElementRequested(deviceGroup, holderSystemDeviceStructure)); + } else if (deviceGroup.getProcessed() != null && ((deviceGroup.getProcessed().getTime() - deviceGroup.getRequested().getTime()) <= THOUSAND_MILLISECONDS)) { + structureElements.add(getStructureElementProcessed(deviceGroup, holderSystemDeviceStructure)); + } else { + structureElements.add(getStructureElementRequested(deviceGroup, holderSystemDeviceStructure)); + } + } else { + if (Status.PENDING.equals(deviceGroup.getStatus())) { + structureElements.add(getStructureElementRequested(deviceGroup, holderSystemDeviceStructure)); + } else { + structureElements.add(getStructureElementProcessed(deviceGroup, holderSystemDeviceStructure)); + } + } + } + return structureElements; + } + /** + * Populate and return list of structure elements for device types. + * + * @param deviceTypes device types + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return list of structure elements + */ + public static List<StructureElement> getStructureElementsForDeviceTypes(List<DeviceType> deviceTypes, HolderSystemDeviceStructure holderSystemDeviceStructure, StructureChoice structureChoice) { + List<StructureElement> structureElements = Lists.newArrayList(); + for (DeviceType deviceType : deviceTypes) { + // one or two return elements + // processed != null and processed != requested (> 1s difference) --> two entries (processed, requested) + // processed != null and processed == requested (<= 1s difference) --> one entry (processed initial) + // processed == null --> one entry (requested) + + if (StructureChoice.HISTORY.equals(structureChoice)) { + if (deviceType.getProcessed() != null && ((deviceType.getProcessed().getTime() - deviceType.getRequested().getTime()) > THOUSAND_MILLISECONDS)) { + structureElements.add(getStructureElementProcessed(deviceType, holderSystemDeviceStructure)); + structureElements.add(getStructureElementRequested(deviceType, holderSystemDeviceStructure)); + } else if (deviceType.getProcessed() != null && ((deviceType.getProcessed().getTime() - deviceType.getRequested().getTime()) <= THOUSAND_MILLISECONDS)) { + structureElements.add(getStructureElementProcessed(deviceType, holderSystemDeviceStructure)); + } else { + structureElements.add(getStructureElementRequested(deviceType, holderSystemDeviceStructure)); + } + } else { + if (Status.PENDING.equals(deviceType.getStatus())) { + structureElements.add(getStructureElementRequested(deviceType, holderSystemDeviceStructure)); + } else { + structureElements.add(getStructureElementProcessed(deviceType, holderSystemDeviceStructure)); + } + } + } + return structureElements; + } + + /** + * Populate and return structure element for system group with focus on processed. + * + * @param systemGroup system group + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return structure element + */ + public static StructureElement getStructureElementProcessed(SystemGroup systemGroup, HolderSystemDeviceStructure holderSystemDeviceStructure) { + if (systemGroup == null) { + return null; + } + +// String mnemonicpath = holderSystemDeviceStructure != null +// ? systemGroup.getMnemonic() +// : null; + String mnemonicpath = !StringUtils.isEmpty(systemGroup.getMnemonic()) + ? systemGroup.getMnemonic() + : null; + + return getStructureElement( + Type.SYSTEMGROUP, + systemGroup.getUuid(), + null, + systemGroup.getName(), systemGroup.getMnemonic(), mnemonicpath, 1, + systemGroup.getDescription(), systemGroup.getStatus(), systemGroup.isLatest(), systemGroup.isDeleted(), + systemGroup.getProcessed(), systemGroup.getProcessedBy(), systemGroup.getProcessedComment()); + } + /** + * Populate and return structure element for system group with focus on requested. + * + * @param systemGroup system group + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return structure element + */ + public static StructureElement getStructureElementRequested(SystemGroup systemGroup, HolderSystemDeviceStructure holderSystemDeviceStructure) { + if (systemGroup == null) { + return null; + } + +// String mnemonicpath = holderSystemDeviceStructure != null +// ? systemGroup.getMnemonic() +// : null; + String mnemonicpath = !StringUtils.isEmpty(systemGroup.getMnemonic()) + ? systemGroup.getMnemonic() + : null; + + return getStructureElement( + Type.SYSTEMGROUP, + systemGroup.getUuid(), + null, + systemGroup.getName(), systemGroup.getMnemonic(), mnemonicpath, 1, + systemGroup.getDescription(), Status.PENDING, systemGroup.isLatest(), systemGroup.isDeleted(), + systemGroup.getRequested(), systemGroup.getRequestedBy(), systemGroup.getRequestedComment()); + } + /** + * Populate and return structure element for system with focus on processed. + * + * @param system system + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return structure element + */ + public static StructureElement getStructureElementProcessed(System system, HolderSystemDeviceStructure holderSystemDeviceStructure) { + if (system == null) { + return null; + } + + String mnemonicpath = StructureUtil.getMnemonicPath(system, holderSystemDeviceStructure); + + return getStructureElement( + Type.SYSTEM, + system.getUuid(), + system.getParentUuid(), + system.getName(), system.getMnemonic(), mnemonicpath, 2, + system.getDescription(), system.getStatus(), system.isLatest(), system.isDeleted(), + system.getProcessed(), system.getProcessedBy(), system.getProcessedComment()); + } + /** + * Populate and return structure element for system group with focus on requested. + * + * @param system system + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return structure element + */ + public static StructureElement getStructureElementRequested(System system, HolderSystemDeviceStructure holderSystemDeviceStructure) { + if (system == null) { + return null; + } + + String mnemonicpath = StructureUtil.getMnemonicPath(system, holderSystemDeviceStructure); + + return getStructureElement( + Type.SYSTEM, + system.getUuid(), + system.getParentUuid(), + system.getName(), system.getMnemonic(), mnemonicpath, 2, + system.getDescription(), Status.PENDING, system.isLatest(), system.isDeleted(), + system.getRequested(), system.getRequestedBy(), system.getRequestedComment()); + } + /** + * Populate and return structure element for subsystem with focus on processed. + * + * @param subsystem subsystem + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return structure element + */ + public static StructureElement getStructureElementProcessed(Subsystem subsystem, HolderSystemDeviceStructure holderSystemDeviceStructure) { + if (subsystem == null) { + return null; + } + + String mnemonicpath = StructureUtil.getMnemonicPath(subsystem, holderSystemDeviceStructure); + + return getStructureElement( + Type.SUBSYSTEM, + subsystem.getUuid(), + subsystem.getParentUuid(), + subsystem.getName(), subsystem.getMnemonic(), mnemonicpath, 3, + subsystem.getDescription(), subsystem.getStatus(), subsystem.isLatest(), subsystem.isDeleted(), + subsystem.getProcessed(), subsystem.getProcessedBy(), subsystem.getProcessedComment()); + } + /** + * Populate and return structure element for subsystem with focus on requested. + * + * @param subsystem subsystem + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return structure element + */ + public static StructureElement getStructureElementRequested(Subsystem subsystem, HolderSystemDeviceStructure holderSystemDeviceStructure) { + if (subsystem == null) { + return null; + } + + String mnemonicpath = StructureUtil.getMnemonicPath(subsystem, holderSystemDeviceStructure); + + return getStructureElement( + Type.SUBSYSTEM, + subsystem.getUuid(), + subsystem.getParentUuid(), + subsystem.getName(), subsystem.getMnemonic(), mnemonicpath, 3, + subsystem.getDescription(), Status.PENDING, subsystem.isLatest(), subsystem.isDeleted(), + subsystem.getRequested(), subsystem.getRequestedBy(), subsystem.getRequestedComment()); + } + + /** + * Populate and return structure element for discipline with focus on processed. + * + * @param discipline discipline + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return structure element + */ + public static StructureElement getStructureElementProcessed(Discipline discipline, HolderSystemDeviceStructure holderSystemDeviceStructure) { + if (discipline == null) { + return null; + } + +// String mnemonicpath = holderSystemDeviceStructure != null +// ? discipline.getMnemonic() +// : null; + String mnemonicpath = !StringUtils.isEmpty(discipline.getMnemonic()) + ? discipline.getMnemonic() + : null; + + return getStructureElement( + Type.DISCIPLINE, + discipline.getUuid(), + null, + discipline.getName(), discipline.getMnemonic(), mnemonicpath, 1, + discipline.getDescription(), discipline.getStatus(), discipline.isLatest(), discipline.isDeleted(), + discipline.getProcessed(), discipline.getProcessedBy(), discipline.getProcessedComment()); + } + /** + * Populate and return structure element for discipline with focus on requested. + * + * @param discipline discipline + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return structure element + */ + public static StructureElement getStructureElementRequested(Discipline discipline, HolderSystemDeviceStructure holderSystemDeviceStructure) { + if (discipline == null) { + return null; + } + +// String mnemonicpath = holderSystemDeviceStructure != null +// ? discipline.getMnemonic() +// : null; + String mnemonicpath = !StringUtils.isEmpty(discipline.getMnemonic()) + ? discipline.getMnemonic() + : null; + + return getStructureElement( + Type.DISCIPLINE, + discipline.getUuid(), + null, + discipline.getName(), discipline.getMnemonic(), mnemonicpath, 1, + discipline.getDescription(), Status.PENDING, discipline.isLatest(), discipline.isDeleted(), + discipline.getRequested(), discipline.getRequestedBy(), discipline.getRequestedComment()); + } + /** + * Populate and return structure element for device group with focus on processed. + * + * @param deviceGroup device group + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return structure element + */ + public static StructureElement getStructureElementProcessed(DeviceGroup deviceGroup, HolderSystemDeviceStructure holderSystemDeviceStructure) { + if (deviceGroup == null) { + return null; + } + + String mnemonicpath = StructureUtil.getMnemonicPath(deviceGroup, holderSystemDeviceStructure); + + return getStructureElement( + Type.DEVICEGROUP, + deviceGroup.getUuid(), + deviceGroup.getParentUuid(), + deviceGroup.getName(), deviceGroup.getMnemonic(), mnemonicpath, 2, + deviceGroup.getDescription(), deviceGroup.getStatus(), deviceGroup.isLatest(), deviceGroup.isDeleted(), + deviceGroup.getProcessed(), deviceGroup.getProcessedBy(), deviceGroup.getProcessedComment()); + } + /** + * Populate and return structure element for device group with focus on requested. + * + * @param deviceGroup device group + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return structure element + */ + public static StructureElement getStructureElementRequested(DeviceGroup deviceGroup, HolderSystemDeviceStructure holderSystemDeviceStructure) { + if (deviceGroup == null) { + return null; + } + + String mnemonicpath = StructureUtil.getMnemonicPath(deviceGroup, holderSystemDeviceStructure); + + return getStructureElement( + Type.DEVICEGROUP, + deviceGroup.getUuid(), + deviceGroup.getParentUuid(), + deviceGroup.getName(), deviceGroup.getMnemonic(), mnemonicpath, 2, + deviceGroup.getDescription(), Status.PENDING, deviceGroup.isLatest(), deviceGroup.isDeleted(), + deviceGroup.getRequested(), deviceGroup.getRequestedBy(), deviceGroup.getRequestedComment()); + } + /** + * Populate and return structure element for device type with focus on processed. + * + * @param deviceType device type + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return structure element + */ + public static StructureElement getStructureElementProcessed(DeviceType deviceType, HolderSystemDeviceStructure holderSystemDeviceStructure) { + if (deviceType == null) { + return null; + } + + String mnemonicpath = StructureUtil.getMnemonicPath(deviceType, holderSystemDeviceStructure); + + return getStructureElement( + Type.DEVICETYPE, + deviceType.getUuid(), + deviceType.getParentUuid(), + deviceType.getName(), deviceType.getMnemonic(), mnemonicpath, 3, + deviceType.getDescription(), deviceType.getStatus(), deviceType.isLatest(), deviceType.isDeleted(), + deviceType.getProcessed(), deviceType.getProcessedBy(), deviceType.getProcessedComment()); + } + /** + * Populate and return structure element for device type with focus on requested. + * + * @param deviceType device type + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return structure element + */ + public static StructureElement getStructureElementRequested(DeviceType deviceType, HolderSystemDeviceStructure holderSystemDeviceStructure) { + if (deviceType == null) { + return null; + } + + String mnemonicpath = StructureUtil.getMnemonicPath(deviceType, holderSystemDeviceStructure); + + return getStructureElement( + Type.DEVICETYPE, + deviceType.getUuid(), + deviceType.getParentUuid(), + deviceType.getName(), deviceType.getMnemonic(), mnemonicpath, 3, + deviceType.getDescription(), Status.PENDING, deviceType.isLatest(), deviceType.isDeleted(), + deviceType.getRequested(), deviceType.getRequestedBy(), deviceType.getRequestedComment()); + } + + /** + * Populate and return structure element. + * + * @param type type + * @param uuid uuid + * @param parent parent uuid + * @param name name + * @param mnemonic mnemonic + * @param mnemonicpath mnemonic path + * @param level level + * @param description description + * @param status status + * @param latest latest + * @param deleted deleted + * @param when when + * @param who who + * @param comment comment + * @return structure element + */ + protected static StructureElement getStructureElement( + Type type, + UUID uuid, + UUID parent, + String name, String mnemonic, String mnemonicpath, Integer level, + String description, Status status, Boolean latest, Boolean deleted, + Date when, String who, String comment) { + + return new StructureElement( + type, + uuid, + parent, + name, mnemonic, mnemonicpath, level, + description, status, latest, deleted, + when, who, comment); + } + + + private static boolean hasSameContent(StructureElement structureElement, NameStructure nameStructure) { + /* + StructureElement + x uuid + x description + x status + x latest + x deleted + NameStructure + x uuid + x description + x status + x latest + x deleted + */ + + if (structureElement == null && nameStructure == null) + return true; + if (structureElement == null) + return false; + if (nameStructure == null) + return false; + + if (structureElement.getUuid() == null) { + if (nameStructure.getUuid() != null) + return false; + } else if (!structureElement.getUuid().equals(nameStructure.getUuid())) + return false; + if (structureElement.getDescription() == null) { + if (nameStructure.getDescription() != null) + return false; + } else if (!structureElement.getDescription().equals(nameStructure.getDescription())) + return false; + if (structureElement.getStatus() == null) { + if (nameStructure.getStatus() != null) + return false; + } else if (!structureElement.getStatus().equals(nameStructure.getStatus())) + return false; + if (structureElement.isLatest() == null) { + if (nameStructure.isLatest() != null) + return false; + } else if (!structureElement.isLatest().equals(nameStructure.isLatest())) + return false; + if (structureElement.isDeleted() == null) { + if (nameStructure.isDeleted() != null) + return false; + } else if (!structureElement.isDeleted().equals(nameStructure.isDeleted())) + return false; + + return true; + } + + private static boolean hasSameContent(StructureElement structureElement, Structure structure) { + /* + StructureElement + x name + x mnemonic + Structure + x name + x mnemonic + */ + + if (!hasSameContent(structureElement, (NameStructure) structure)) + return false; + + if (structureElement.getName() == null) { + if (structure.getName() != null) + return false; + } else if (!structureElement.getName().equals(structure.getName())) + return false; + if (structureElement.getMnemonic() == null) { + if (structure.getMnemonic() != null) + return false; + } else if (!structureElement.getMnemonic().equals(structure.getMnemonic())) + return false; + + return true; + } + + public static boolean hasSameContent(StructureElement structureElement, SystemGroup systemGroup) { + /* + StructureElement + x type + SystemGroup + */ + + if (!hasSameContent(structureElement, (Structure) systemGroup)) + return false; + + if (!Type.SYSTEMGROUP.equals(structureElement.getType())) { + return false; + } + + return true; + } + + public static boolean hasSameContent(StructureElement structureElement, System system) { + /* + StructureElement + x type + x parent + System + x parent_uuid + */ + + if (!hasSameContent(structureElement, (Structure) system)) + return false; + + if (!Type.SYSTEMGROUP.equals(structureElement.getType())) { + return false; + } + if (structureElement.getParent() == null) { + if (system.getParentUuid() != null) + return false; + } else if (!structureElement.getParent().equals(system.getParentUuid())) + return false; + + return true; + } + + public static boolean hasSameContent(StructureElement structureElement, Subsystem subsystem) { + /* + StructureElement + x type + x parent + Subsystem + x parent_uuid + */ + + if (!hasSameContent(structureElement, (Structure) subsystem)) + return false; + + if (!Type.SYSTEMGROUP.equals(structureElement.getType())) { + return false; + } + if (structureElement.getParent() == null) { + if (subsystem.getParentUuid() != null) + return false; + } else if (!structureElement.getParent().equals(subsystem.getParentUuid())) + return false; + + return true; + } + + public static boolean hasSameContent(StructureElement structureElement, Discipline discipline) { + /* + StructureElement + x type + Discipline + */ + + if (!hasSameContent(structureElement, (Structure) discipline)) + return false; + + if (!Type.SYSTEMGROUP.equals(structureElement.getType())) { + return false; + } + + return true; + } + + public static boolean hasSameContent(StructureElement structureElement, DeviceGroup deviceGroup) { + /* + StructureElement + x type + x parent + Subsystem + x parent_uuid + */ + + if (!hasSameContent(structureElement, (Structure) deviceGroup)) + return false; + + if (!Type.SYSTEMGROUP.equals(structureElement.getType())) { + return false; + } + if (structureElement.getParent() == null) { + if (deviceGroup.getParentUuid() != null) + return false; + } else if (!structureElement.getParent().equals(deviceGroup.getParentUuid())) + return false; + + return true; + } + + public static boolean hasSameContent(StructureElement structureElement, DeviceType deviceType) { + /* + StructureElement + x type + x parent + DeviceType + x parent_uuid + */ + + if (!hasSameContent(structureElement, (Structure) deviceType)) + return false; + + if (!Type.SYSTEMGROUP.equals(structureElement.getType())) { + return false; + } + if (structureElement.getParent() == null) { + if (deviceType.getParentUuid() != null) + return false; + } else if (!structureElement.getParent().equals(deviceType.getParentUuid())) + return false; + + return true; + } + +} diff --git a/src/main/java/org/openepics/names/util/StructureUtil.java b/src/main/java/org/openepics/names/util/StructureUtil.java new file mode 100644 index 0000000..076900b --- /dev/null +++ b/src/main/java/org/openepics/names/util/StructureUtil.java @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2021 European Spallation Source ERIC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.openepics.names.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; +import java.util.UUID; + +import org.apache.commons.lang3.StringUtils; +import org.openepics.names.repository.model.DeviceGroup; +import org.openepics.names.repository.model.DeviceType; +import org.openepics.names.repository.model.Discipline; +import org.openepics.names.repository.model.Subsystem; +import org.openepics.names.repository.model.System; +import org.openepics.names.repository.model.SystemGroup; + +/** + * Utility class to assist in handling of structure (name part) content. + * + * @author Lars Johansson + */ +public class StructureUtil { + + /** + * This class is not to be instantiated. + */ + private StructureUtil() { + throw new IllegalStateException("Utility class"); + } + + /** + * Return mnemonic path for system. + * + * @param system system + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return mnemonic path + */ + public static String getMnemonicPath(System system, HolderSystemDeviceStructure holderSystemDeviceStructure) { + if (system == null || holderSystemDeviceStructure == null) { + return null; + } + + SystemGroup systemGroup = holderSystemDeviceStructure.findSystemGroupByUuid(system.getParentUuid()); + return systemGroup != null && !StringUtils.isEmpty(systemGroup.getMnemonic()) + ? systemGroup.getMnemonic() + "-" + system.getMnemonic() + : system.getMnemonic(); + } + + /** + * Return mnemonic path for subsystem. + * + * @param subsystem subsystem + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return mnemonic path + */ + public static String getMnemonicPath(Subsystem subsystem, HolderSystemDeviceStructure holderSystemDeviceStructure) { + if (subsystem == null || holderSystemDeviceStructure == null) { + return null; + } + + System system = holderSystemDeviceStructure.findSystemByUuid(subsystem.getParentUuid()); + SystemGroup systemGroup = system != null + ? holderSystemDeviceStructure.findSystemGroupByUuid(system.getParentUuid()) + : null; + return systemGroup != null && !StringUtils.isEmpty(systemGroup.getMnemonic()) && system != null + ? systemGroup.getMnemonic() + "-" + system.getMnemonic() + "-" + subsystem.getMnemonic() + : system != null + ? system.getMnemonic() + "-" + subsystem.getMnemonic() + : subsystem.getMnemonic(); + + } + + /** + * Return mnemonic path for device group. + * + * @param deviceGroup device group + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return mnemonic path + */ + public static String getMnemonicPath(DeviceGroup deviceGroup, HolderSystemDeviceStructure holderSystemDeviceStructure) { + if (deviceGroup == null || holderSystemDeviceStructure == null) { + return null; + } + + Discipline discipline = holderSystemDeviceStructure.findDisciplineByUuid(deviceGroup.getParentUuid()); + return discipline != null + ? discipline.getMnemonic() + : null; + } + + /** + * Return mnemonic path for device type. + * + * @param deviceType device type + * @param holderSystemDeviceStructure holder of containers for system and device structure content + * @return mnemonic path + */ + public static String getMnemonicPath(DeviceType deviceType, HolderSystemDeviceStructure holderSystemDeviceStructure) { + if (deviceType == null || holderSystemDeviceStructure == null) { + return null; + } + + DeviceGroup deviceGroup = holderSystemDeviceStructure.findDeviceGroupByUuid(deviceType.getParentUuid()); + Discipline discipline = deviceGroup != null + ? holderSystemDeviceStructure.findDisciplineByUuid(deviceGroup.getParentUuid()) + : null; + return discipline != null && deviceGroup != null + ? discipline.getMnemonic() + "-" + deviceType.getMnemonic() + : deviceType.getMnemonic(); + } + + // --------------------------------------------------- + + /** + * Return a list of mnemonic paths for system groups. + * + * @param holder holder of containers for system and device structure content + * @param mnemonicEquivalence use mnemonic equivalence instead of mnemonic + * @param namingConvention naming convention + * @return a list of mnemonic paths for system groups + */ + public static List<String> getMnemonicPathsSystemGroup(HolderSystemDeviceStructure holder, boolean mnemonicEquivalence, EssNamingConvention namingConvention) { + List<String> mnemonicPaths = new ArrayList<>(); + String value = null; + for (Entry<UUID, SystemGroup> entry : holder.getUuidSystemGroups().entrySet()) { + if (!StringUtils.isEmpty(entry.getValue().getMnemonic())) { + value = entry.getValue().getMnemonic(); + } + + if (mnemonicEquivalence) { + mnemonicPaths.add(namingConvention.equivalenceClassRepresentative(value)); + } else { + mnemonicPaths.add(value); + } + } + return mnemonicPaths; + } + + /** + * Return a list of mnemonic paths for systems. + * + * @param holder holder of containers for system and device structure content + * @param mnemonicEquivalence use mnemonic equivalence instead of mnemonic + * @param namingConvention naming convention + * @return a list of mnemonic paths for systems + */ + public static List<String> getMnemonicPathsSystem(HolderSystemDeviceStructure holder, boolean mnemonicEquivalence, EssNamingConvention namingConvention) { + List<String> mnemonicPaths = new ArrayList<>(); + String value = null; + for (Entry<UUID, System> entry : holder.getUuidSystems().entrySet()) { + SystemGroup systemGroup = holder.findSystemGroupByUuid(entry.getValue().getParentUuid()); + if (!StringUtils.isEmpty(systemGroup.getMnemonic())) { + value = systemGroup.getMnemonic() + "-" + entry.getValue().getMnemonic(); + } else { + value = entry.getValue().getMnemonic(); + } + + if (mnemonicEquivalence) { + mnemonicPaths.add(namingConvention.equivalenceClassRepresentative(value)); + } else { + mnemonicPaths.add(value); + } + } + return mnemonicPaths; + } + + /** + * Return a list of mnemonic paths for subsystems. + * + * @param holder holder of containers for system and device structure content + * @param mnemonicEquivalence use mnemonic equivalence instead of mnemonic + * @param namingConvention naming convention + * @return a list of mnemonic paths for subsystems + */ + public static List<String> getMnemonicPathsSubsystem(HolderSystemDeviceStructure holder, boolean mnemonicEquivalence, EssNamingConvention namingConvention) { + List<String> mnemonicPaths = new ArrayList<>(); + String value = null; + for (Entry<UUID, Subsystem> entry : holder.getUuidSubsystems().entrySet()) { + System system = holder.findSystemByUuid(entry.getValue().getParentUuid()); + SystemGroup systemGroup = holder.findSystemGroupByUuid(system.getParentUuid()); + if (!StringUtils.isEmpty(systemGroup.getMnemonic())) { + value = systemGroup.getMnemonic() + "-" + system.getMnemonic() + "-" + entry.getValue().getMnemonic(); + } else { + value = system.getMnemonic() + "-" + entry.getValue().getMnemonic(); + } + + if (mnemonicEquivalence) { + mnemonicPaths.add(namingConvention.equivalenceClassRepresentative(value)); + } else { + mnemonicPaths.add(value); + } + } + return mnemonicPaths; + } + + /** + * Return a list of mnemonic paths for disciplines. + * + * @param holder holder of containers for system and device structure content + * @param mnemonicEquivalence use mnemonic equivalence instead of mnemonic + * @param namingConvention naming convention + * @return a list of mnemonic paths for disciplines + */ + public static List<String> getMnemonicPathsDiscipline(HolderSystemDeviceStructure holder, boolean mnemonicEquivalence, EssNamingConvention namingConvention) { + List<String> mnemonicPaths = new ArrayList<>(); + String value = null; + for (Entry<UUID, Discipline> entry : holder.getUuidDisciplines().entrySet()) { + if (!StringUtils.isEmpty(entry.getValue().getMnemonic())) { + value = entry.getValue().getMnemonic(); + } + + if (mnemonicEquivalence) { + mnemonicPaths.add(namingConvention.equivalenceClassRepresentative(value)); + } else { + mnemonicPaths.add(value); + } + } + return mnemonicPaths; + } + + /** + * Return a list of mnemonic paths for device types. + * + * @param holder holder of containers for system and device structure content + * @param mnemonicEquivalence use mnemonic equivalence instead of mnemonic + * @param namingConvention naming convention + * @return a list of mnemonic paths for device types + */ + public static List<String> getMnemonicPathsDeviceType(HolderSystemDeviceStructure holder, boolean mnemonicEquivalence, EssNamingConvention namingConvention) { + List<String> mnemonicPaths = new ArrayList<>(); + String value = null; + for (Entry<UUID, DeviceType> entry : holder.getUuidDeviceTypes().entrySet()) { + DeviceGroup deviceGroup = holder.findDeviceGroupByUuid(entry.getValue().getParentUuid()); + Discipline discipline = holder.findDisciplineByUuid(deviceGroup.getParentUuid()); + value = discipline.getMnemonic() + "-" + entry.getValue().getMnemonic(); + + if (mnemonicEquivalence) { + mnemonicPaths.add(namingConvention.equivalenceClassRepresentative(value)); + } else { + mnemonicPaths.add(value); + } + } + return mnemonicPaths; + } + +} diff --git a/src/main/java/org/openepics/names/util/ValidateUtil.java b/src/main/java/org/openepics/names/util/ValidateUtil.java new file mode 100644 index 0000000..3ecc043 --- /dev/null +++ b/src/main/java/org/openepics/names/util/ValidateUtil.java @@ -0,0 +1,1385 @@ +/* + * Copyright (C) 2021 European Spallation Source ERIC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.openepics.names.util; + +import java.util.List; +import java.util.UUID; + +import org.apache.commons.lang3.StringUtils; +import org.openepics.names.repository.NameRepository; +import org.openepics.names.repository.model.DeviceGroup; +import org.openepics.names.repository.model.DeviceType; +import org.openepics.names.repository.model.Discipline; +import org.openepics.names.repository.model.Name; +import org.openepics.names.repository.model.Subsystem; +import org.openepics.names.repository.model.System; +import org.openepics.names.repository.model.SystemGroup; +import org.openepics.names.rest.beans.FieldName; +import org.openepics.names.rest.beans.FieldStructure; +import org.openepics.names.rest.beans.NameElement; +import org.openepics.names.rest.beans.Status; +import org.openepics.names.rest.beans.StructureElement; +import org.openepics.names.rest.beans.Type; +import org.springframework.http.HttpStatus; + +/** + * Utility class to assist in handling of validation. + * + * @author Lars Johansson + */ +public class ValidateUtil { + + private static enum NameChoice {CREATE, UPDATE, DELETE}; + private static enum StructureChoice {CREATE, UPDATE, DELETE, APPROVE, REJECT, CANCEL}; + + public static final String STRUCTURE = "structure"; + public static final String NAME = "name"; + public static final String SYSTEMGROUP = "system group"; + public static final String SYSTEM = "system"; + public static final String SUBSYSTEM = "subsystem"; + public static final String DISCIPLINE = "discipline"; + public static final String DEVICEGROUP = "device group"; + public static final String DEVICETYPE = "device type"; + + public static final String SPACE = " "; + + public static final String ARE_NOT_CORRECT = "are not correct"; + public static final String EXISTS = "exists"; + public static final String IS_DELETED = "is deleted"; + public static final String IS_NOT_AVAILABLE = "is not available"; + public static final String IS_NOT_CORRECT = "is not correct"; + public static final String IS_NOT_DELETED = "is not deleted"; + public static final String IS_NOT_VALID = "is not valid"; + public static final String WAS_NOT_UPDATED = "was not updated"; + + // NameElement + // uuid, + // systemgroup, system, subsystem, devicetype, systemstructure, devicestructure, + // index, name, + // description, status, latest, deleted, when, who, comment + // StructureElement + // type, uuid, parent uuid, + // name, mnemonic, mnemonic path, level, + // description, status, latest, deleted, when, who, comment + + /** + * This class is not to be instantiated. + */ + private ValidateUtil() { + throw new IllegalStateException("Utility class"); + } + + /** + * Validate comment. + * + * @param comment comment + */ + public static void validateInputComment(String comment) { + // available + validateCondition(!StringUtils.isEmpty(comment), HttpStatus.BAD_REQUEST, + "comment " + ValidateUtil.IS_NOT_AVAILABLE, comment); + } + + /** + * Validate description. + * + * @param description description + */ + public static void validateInputDescription(String description) { + // available + validateCondition(!StringUtils.isEmpty(description), HttpStatus.BAD_REQUEST, + "description " + ValidateUtil.IS_NOT_AVAILABLE, description); + } + + /** + * Validate mnemonic. + * + * @param mnemonic mnemonic + */ + public static void validateInputMnemonic(String mnemonic) { + // available + validateCondition(!StringUtils.isEmpty(mnemonic), HttpStatus.BAD_REQUEST, + "mnemonic " + ValidateUtil.IS_NOT_AVAILABLE, mnemonic); + } + + /** + * Validate mnemonic path. + * + * @param mnemonicpath mnemonic path + */ + public static void validateInputMnemonicpath(String mnemonicpath) { + // available + validateCondition(!StringUtils.isEmpty(mnemonicpath), HttpStatus.BAD_REQUEST, + "mnemonicpath " + ValidateUtil.IS_NOT_AVAILABLE, mnemonicpath); + } + + /** + * Validate name. + * + * @param name name + */ + public static void validateInputName(String name) { + // available + validateCondition(!StringUtils.isEmpty(name), HttpStatus.BAD_REQUEST, + "name " + ValidateUtil.IS_NOT_AVAILABLE, name); + } + + /** + * Validate status. + * + * @param status status + */ + public static void validateInputStatus(Status status) { + validateInputStatus(status, null); + } + + /** + * Validate status. + * + * @param status status + * @param expected expected status + */ + public static void validateInputStatus(Status status, Status expected) { + // available + validateCondition(status != null, HttpStatus.BAD_REQUEST, + "status " + ValidateUtil.IS_NOT_AVAILABLE, null); + // expected status + if (expected != null) { + validateCondition(expected.equals(status), HttpStatus.BAD_REQUEST, + "status " + ValidateUtil.IS_NOT_CORRECT, status.toString()); + } + } + + /** + * Validate type. + * + * @param type type + */ + public static void validateInputType(Type type) { + validateInputType(type, null); + } + + /** + * Validate type. + * + * @param type type + * @param expected expected type + */ + public static void validateInputType(Type type, Type expected) { + // available + validateCondition(type != null, HttpStatus.BAD_REQUEST, + "type " + ValidateUtil.IS_NOT_AVAILABLE, null); + // expected type + if (expected != null) { + validateCondition(expected.equals(type), HttpStatus.BAD_REQUEST, + "type " + ValidateUtil.IS_NOT_CORRECT, type.toString()); + } + } + + /** + * Validate uuid. + * + * @param uuid uuid + */ + public static void validateInputUuid(String uuid) { + // available + // correct + validateCondition(!StringUtils.isEmpty(uuid), HttpStatus.BAD_REQUEST, + "uuid " + ValidateUtil.IS_NOT_AVAILABLE, uuid); + try { + UUID.fromString(uuid); + } catch (IllegalArgumentException e) { + throw ExceptionUtil.createServiceHttpStatusExceptionBadRequest( + "uuid " + ValidateUtil.IS_NOT_CORRECT, uuid, null); + } + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * Validate parameters for read names. + * + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @param orderBy order by + * @param isAsc is ascending + * @param offset offset + * @param limit limit + */ + public static void validateNamesInputRead( + Boolean deleted, FieldName[] queryFields, String[] queryValues, + Boolean includeHistory, + FieldName orderBy, Boolean isAsc, + Integer offset, Integer limit) { + + // validate input + // queryFields and queryValues + // either + // both null + // both non-null, same length, non-empty + // uuid + + boolean condition = ((queryFields == null && queryValues == null) + || (queryFields != null && queryValues != null && queryFields.length == queryValues.length && queryFields.length > 0)); + ValidateUtil.validateCondition(condition, HttpStatus.BAD_REQUEST, + "url and parameters " + ValidateUtil.ARE_NOT_CORRECT, "queryFields, queryValues with different lengths or empty"); + if (queryFields != null) { + for (int i=0; i<queryFields.length; i++) { + if (FieldName.UUID.equals(queryFields[i])) { + ValidateUtil.validateInputUuid(queryValues[i]); + } + } + } + } + + /** + * Validate name element parameters (input) for create. + * + * @param nameElement name element + */ + public static void validateNameElementInputCreate(NameElement nameElement) { + validateNameElementInput(nameElement, NameChoice.CREATE); + } + + /** + * Validate name element parameters (input) for update. + * + * @param nameElement name element + */ + public static void validateNameElementInputUpdate(NameElement nameElement) { + validateNameElementInput(nameElement, NameChoice.UPDATE); + } + + /** + * Validate name element parameters (input) for delete. + * + * @param nameElement name element + */ + public static void validateNameElementInputDelete(NameElement nameElement) { + validateNameElementInput(nameElement, NameChoice.DELETE); + } + + /** + * Validate name element parameters (input). + * + * @param nameElement name element + * @param nameChoice name choice + */ + private static void validateNameElementInput(NameElement nameElement, NameChoice nameChoice) { + // attributes + // not check + // uuid - n.a set server side + // systemstructure - n.a system structure mnemonic path + // devicestructure - n.a device structure mnemonic path + // devicetype - possibly validate uuid also validate data + // index - possibly also validate data + // name - possibly also validate data + // status - n.a. set server side + // latest - n.a. set server side + // deleted - n.a. set server side + // when - n.a. set server side + // who - n.a. set server side + // check + // systemgroup - 1 either 1,2,3 possibly validate uuid also validate data + // system - 2 either 1,2,3 possibly validate uuid also validate data + // subsystem - 3 either 1,2,3 possibly validate uuid also validate data + // description - required + // comment - required + + if (nameElement == null || nameChoice == null) { + return; + } + + if (!NameChoice.CREATE.equals(nameChoice)) { + validateInputUuid(nameElement.getUuid() != null ? nameElement.getUuid().toString() : null); + } + + validateInputDescription(nameElement.getDescription()); + validateInputComment(nameElement.getComment()); + + // uuid vs string + int count = 0; + if (nameElement.getSystemgroup() != null) { + count++; + }; + if (nameElement.getSystem() != null) { + count++; + } + if (nameElement.getSubsystem() != null) { + count++; + } + // correct + ValidateUtil.validateCondition(count == 1, HttpStatus.BAD_REQUEST, + "system structure uuid " + ValidateUtil.IS_NOT_CORRECT, nameElement.toString()); + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * Validate name element data for create. + * + * @param nameElement name element + * @param namingConvention naming convention + * @param holderIRepositories holder repositories + * @param nameRepository name repository + * @param holder holder + */ + public static void validateNameElementDataCreate(NameElement nameElement, EssNamingConvention namingConvention, HolderIRepositories holderIRepositories, NameRepository nameRepository, HolderSystemDeviceStructure holder) { + validateNameElementData(nameElement, namingConvention, holderIRepositories, nameRepository, holder, NameChoice.CREATE); + } + + /** + * Validate name element data for update. + * + * @param nameElement name element + * @param namingConvention naming convention + * @param holderIRepositories holder repositories + * @param nameRepository name repositories + * @param holder holder + */ + public static void validateNameElementDataUpdate(NameElement nameElement, EssNamingConvention namingConvention, HolderIRepositories holderIRepositories, NameRepository nameRepository, HolderSystemDeviceStructure holder) { + validateNameElementData(nameElement, namingConvention, holderIRepositories, nameRepository, holder, NameChoice.UPDATE); + } + + /** + * Validate name element data for delete. + * + * @param nameElement name element + * @param namingConvention naming convention + * @param holderIRepositories holder repositories + * @param nameRepository name repositories + * @param holder holder + */ + public static void validateNameElementDataDelete(NameElement nameElement, EssNamingConvention namingConvention, HolderIRepositories holderIRepositories, NameRepository nameRepository, HolderSystemDeviceStructure holder) { + validateNameElementData(nameElement, namingConvention, holderIRepositories, nameRepository, holder, NameChoice.DELETE); + } + + /** + * Validate name element data. + * + * @param nameElement name element + * @param namingConvention naming convention + * @param holderIRepositories holder repositories + * @param nameRepository name repository + * @param holder holder + * @param nameChoice name choice + */ + private static void validateNameElementData(NameElement nameElement, EssNamingConvention namingConvention, HolderIRepositories holderIRepositories, NameRepository nameRepository, HolderSystemDeviceStructure holder, NameChoice nameChoice) { + // attributes + // not check + // uuid + // systemstructure + // devicestructure + // description + // status + // latest + // deleted + // when + // who + // comment + // check + // systemgroup, system, subsystem - in repository + // found + // not deleted + // devicetype - possibly, in repository + // found + // not deleted + // index - possibly, naming convention rules + // index to match name index + // valid + // name - naming convention rules + // mnemonic paths for system structure uuid to match name mnemonic paths + // mnemonic paths for device structure uuid to match name mnemonic paths + // name not exists + // name equivalence not exists + + if (nameElement == null || namingConvention == null || holderIRepositories == null || nameRepository == null || holder == null || nameChoice == null) { + return; + } + + // name + // create or update? same or not? + // update --> retrieve name and check + Name name = null; + if (NameChoice.UPDATE.equals(nameChoice) || NameChoice.DELETE.equals(nameChoice)) { + List<Name> names = nameRepository.readNames(false, FieldName.UUID, nameElement.getUuid().toString()); + validateCondition(names != null && names.size() == 1, HttpStatus.BAD_REQUEST, + ValidateUtil.NAME + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT, nameElement.toString()); + + name = names.get(0); + } + + SystemGroup systemGroup = null; + System system = null; + Subsystem subsystem = null; + DeviceType deviceType = null; + + String mnemonicPathSystemStructure = null; + String mnemonicPathDeviceStructure = null; + + boolean condition = true; + + if (NameChoice.CREATE.equals(nameChoice) || NameChoice.UPDATE.equals(nameChoice)) { + // system structure + if (nameElement.getSystemgroup() != null) { + systemGroup = holderIRepositories.getSystemGroupRepository().findLatestByUuid(nameElement.getSystemgroup().toString()); + ValidateUtil.validateCondition(systemGroup != null, HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEMGROUP + ValidateUtil.SPACE + ValidateUtil.IS_NOT_AVAILABLE, nameElement.toString()); + ValidateUtil.validateCondition(!systemGroup.isDeleted(), HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEMGROUP + ValidateUtil.SPACE + ValidateUtil.IS_DELETED, nameElement.toString()); + mnemonicPathSystemStructure = systemGroup.getMnemonic(); + } else if (nameElement.getSystem() != null) { + system = holderIRepositories.getSystemRepository().findLatestByUuid(nameElement.getSystem().toString()); + ValidateUtil.validateCondition(system != null, HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_NOT_AVAILABLE, nameElement.toString()); + ValidateUtil.validateCondition(!system.isDeleted(), HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_DELETED, nameElement.toString()); + mnemonicPathSystemStructure = StructureUtil.getMnemonicPath(system, holder); + String[] mnemonicpath = NamingConventionUtil.string2MnemonicPath(mnemonicPathSystemStructure); + mnemonicPathSystemStructure = mnemonicpath != null && mnemonicpath.length == 2 + ? mnemonicpath[1] + : null; + } else if (nameElement.getSubsystem() != null) { + subsystem = holderIRepositories.getSubsystemRepository().findLatestByUuid(nameElement.getSubsystem().toString()); + ValidateUtil.validateCondition(subsystem != null, HttpStatus.BAD_REQUEST, ValidateUtil.SUBSYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_NOT_AVAILABLE, nameElement.toString()); + ValidateUtil.validateCondition(!subsystem.isDeleted(), HttpStatus.BAD_REQUEST, ValidateUtil.SUBSYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_DELETED, nameElement.toString()); + mnemonicPathSystemStructure = StructureUtil.getMnemonicPath(subsystem, holder); + String[] mnemonicpath = NamingConventionUtil.string2MnemonicPath(mnemonicPathSystemStructure); + mnemonicPathSystemStructure = mnemonicpath != null && mnemonicpath.length == 3 + ? mnemonicpath[1] + "-" + mnemonicpath[2] + : mnemonicpath != null && mnemonicpath.length == 2 + ? mnemonicpath[0] + "-" + mnemonicpath[1] + : null; + } else { + throw ExceptionUtil.createServiceHttpStatusExceptionBadRequest("system structure uuid " + IS_NOT_CORRECT, nameElement.toString(), null); + } + // mnemonicPathSystemStructure = NamingConventionUtil.mnemonicPathSystemStructure4Name(mnemonicPathSystemStructure); + + // device structure + if (nameElement.getDevicetype() != null) { + deviceType = holderIRepositories.getDeviceTypeRepository().findLatestByUuid(nameElement.getDevicetype().toString()); + ValidateUtil.validateCondition(deviceType != null, HttpStatus.BAD_REQUEST, ValidateUtil.DEVICETYPE + ValidateUtil.SPACE + ValidateUtil.IS_NOT_AVAILABLE, nameElement.toString()); + ValidateUtil.validateCondition(!deviceType.isDeleted(), HttpStatus.BAD_REQUEST, ValidateUtil.DEVICETYPE + ValidateUtil.SPACE + ValidateUtil.IS_DELETED, nameElement.toString()); + mnemonicPathDeviceStructure = StructureUtil.getMnemonicPath(deviceType, holder); + } + + // index + String extractedInstanceIndex = NamingConventionUtil.extractInstanceIndex(nameElement.getName()); + + if (!StringUtils.isEmpty(nameElement.getIndex()) && StringUtils.isEmpty(extractedInstanceIndex)) { + throw ExceptionUtil.createServiceHttpStatusExceptionBadRequest("convention name " + IS_NOT_CORRECT, nameElement.toString(), null); + } else if (StringUtils.isEmpty(nameElement.getIndex()) && !StringUtils.isEmpty(extractedInstanceIndex)) { + throw ExceptionUtil.createServiceHttpStatusExceptionBadRequest("instance index " + IS_NOT_CORRECT, nameElement.toString(), null); + } + + if (!StringUtils.isEmpty(nameElement.getIndex())) { + condition = StringUtils.equals(nameElement.getIndex(), NamingConventionUtil.extractInstanceIndex(nameElement.getName())); + validateCondition(condition, HttpStatus.BAD_REQUEST, "instance index " + ValidateUtil.IS_NOT_CORRECT, nameElement.toString()); + + // TODO overrideRuleset depend on user authority + condition = namingConvention.isInstanceIndexValid(nameElement.getName(), false); + validateCondition(condition, HttpStatus.BAD_REQUEST, "instance index " + ValidateUtil.IS_NOT_VALID, nameElement.toString()); + } + + // name + // system structure + // device structure + if (!StringUtils.isEmpty(nameElement.getName())) { + condition = StringUtils.equals(mnemonicPathSystemStructure, NamingConventionUtil.extractMnemonicPathSystemStructure(nameElement.getName())); + validateCondition(condition, HttpStatus.BAD_REQUEST, "convention name " + ValidateUtil.IS_NOT_CORRECT, nameElement.toString()); + condition = StringUtils.equals(mnemonicPathDeviceStructure, NamingConventionUtil.extractMnemonicPathDeviceStructure(nameElement.getName())); + validateCondition(condition, HttpStatus.BAD_REQUEST, "convention name " + ValidateUtil.IS_NOT_CORRECT, nameElement.toString()); + } else { + // if no name, then no index, we're left with system structure, possibly also device structure + if (!StringUtils.isEmpty(mnemonicPathSystemStructure) && !StringUtils.isEmpty(mnemonicPathDeviceStructure)) { + nameElement.setName(mnemonicPathSystemStructure + ":" + mnemonicPathDeviceStructure); + } else if (!StringUtils.isEmpty(mnemonicPathSystemStructure)) { + nameElement.setName(mnemonicPathSystemStructure); + } + } + + // name + // name equivalence + // check if (create || update && name not same) + // may also trace & trace, and check name through its parents and index, should result in same name as in nameelement + if (NameChoice.CREATE.equals(nameChoice) || (NameChoice.UPDATE.equals(nameChoice) && !StringUtils.equals(nameElement.getName(), name.getConventionName()))) { + List<Name> names = nameRepository.readNames(false, FieldName.NAME, nameElement.getName()); + condition = names == null || names.isEmpty(); + validateCondition(condition, HttpStatus.BAD_REQUEST, "convention name " + ValidateUtil.EXISTS, nameElement.toString()); + + names = nameRepository.readNames(false, FieldName.NAMEEQUIVALENCE, namingConvention.equivalenceClassRepresentative(nameElement.getName())); + condition = names == null || names.isEmpty(); + validateCondition(condition, HttpStatus.BAD_REQUEST, "convention name equivalence " + ValidateUtil.EXISTS, nameElement.toString()); + } + } + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * Validate name data. + * This method corresponds to name element data for create, albeit in a different way. + * + * @param name name + * @param namingConvention naming convention + * @param holderIRepositories holder repositories + * @param nameRepository name repository + * @param holder holder + * + * @see ValidateUtil#validateNameDataCreate(NameElement, EssNamingConvention, HolderIRepositories, NameRepository, HolderSystemDeviceStructure) + */ + public static void validateNameDataCreate(String name, EssNamingConvention namingConvention, HolderIRepositories holderIRepositories, NameRepository nameRepository, HolderSystemDeviceStructure holder) { + if (name == null || namingConvention == null || holderIRepositories == null || nameRepository == null || holder == null) { + return; + } + + // find out system group, system, subsystem + check if valid + // find out discipline, device group, device type + check if valid + // find out instance index + check if valid + // check name equivalence + + String sg = NamingConventionUtil.extractSystemGroup(name); + String sys = NamingConventionUtil.extractSystem(name); + String sub = NamingConventionUtil.extractSubsystem(name); + String dt = NamingConventionUtil.extractDeviceType(name); + String idx = NamingConventionUtil.extractInstanceIndex(name); + + int count = 0; + if (sg != null) { + count++; + }; + if (sys != null) { + count++; + } + if (sub != null) { + count++; + } + if (count > 2 || count < 1) { + throw ExceptionUtil.createServiceHttpStatusExceptionBadRequest( + "system structure " + ValidateUtil.IS_NOT_CORRECT, name, null); + } else if ( (!StringUtils.isEmpty(sg) && !StringUtils.isEmpty(sys)) + || (!StringUtils.isEmpty(sg) && !StringUtils.isEmpty(sub))) { + throw ExceptionUtil.createServiceHttpStatusExceptionBadRequest( + "system structure " + ValidateUtil.IS_NOT_CORRECT, name, null); + } + + SystemGroup systemGroup = null; + System system = null; + Subsystem subsystem = null; + DeviceType deviceType = null; + + String mnemonicPathSystemStructure = null; + String mnemonicPathDeviceStructure = null; + + boolean condition = true; + + // ensure that system structure parents and device structure parents are available, latest and not deleted + // if (system group) { + // } else { + // if (system) { + // } else { + // (if not system then error) + // } + // if (subsystem) { + // } + // } + // if (device type) { + // } + + // system structure + if (!StringUtils.isEmpty(sg)) { + systemGroup = holderIRepositories.getSystemGroupRepository().findLatestNotDeletedByMnemonic(sg); + ValidateUtil.validateCondition(systemGroup != null, HttpStatus.BAD_REQUEST, + ValidateUtil.SYSTEMGROUP + ValidateUtil.SPACE + ValidateUtil.IS_NOT_AVAILABLE, name); + mnemonicPathSystemStructure = systemGroup.getMnemonic(); + } else { + if (!StringUtils.isEmpty(sys)) { + system = holderIRepositories.getSystemRepository().findLatestNotDeletedByMnemonic(sys); + ValidateUtil.validateCondition(system != null, HttpStatus.BAD_REQUEST, + ValidateUtil.SYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_NOT_AVAILABLE, name); + mnemonicPathSystemStructure = StructureUtil.getMnemonicPath(system, holder); + } else { + throw ExceptionUtil.createServiceHttpStatusExceptionBadRequest( + ValidateUtil.SYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_NOT_AVAILABLE, name, null); + } + // TODO is this condition correct? + ValidateUtil.validateCondition(system != null, HttpStatus.BAD_REQUEST, + ValidateUtil.SYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_NOT_AVAILABLE, name); + if (!StringUtils.isEmpty(sub)) { + subsystem = holderIRepositories.getSubsystemRepository().findLatestNotDeletedByParentAndMnemonic(system.getUuid().toString(), sub); + ValidateUtil.validateCondition(subsystem != null, HttpStatus.BAD_REQUEST, + ValidateUtil.SUBSYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_NOT_AVAILABLE, name); + mnemonicPathSystemStructure = StructureUtil.getMnemonicPath(subsystem, holder); + } + } + + // device structure + if (!StringUtils.isEmpty(dt)) { + deviceType = holderIRepositories.getDeviceTypeRepository().findLatestNotDeletedByMnemonic(dt); + ValidateUtil.validateCondition(deviceType != null, HttpStatus.BAD_REQUEST, + ValidateUtil.DEVICETYPE + ValidateUtil.SPACE + ValidateUtil.IS_NOT_AVAILABLE, name); + mnemonicPathDeviceStructure = StructureUtil.getMnemonicPath(deviceType, holder); + } + + // index + if (!StringUtils.isEmpty(idx)) { + // TODO overrideRuleset depend on user authority + condition = namingConvention.isInstanceIndexValid(name, false); + validateCondition(condition, HttpStatus.BAD_REQUEST, + "instance index " + ValidateUtil.IS_NOT_VALID, name); + } + + // name + // mnemonic paths for found system structure to end with extracted mnemonic path for system structure + // mnemonic paths for found device structure to end with extracted mnemonic path for device structure + // convention name not exists + // convention name equivalence not exists + condition = StringUtils.endsWith(mnemonicPathSystemStructure, NamingConventionUtil.extractMnemonicPathSystemStructure(name)); + validateCondition(condition, HttpStatus.BAD_REQUEST, + "convention name " + ValidateUtil.IS_NOT_CORRECT, name); + + condition = StringUtils.endsWith(mnemonicPathDeviceStructure, NamingConventionUtil.extractMnemonicPathDeviceStructure(name)); + validateCondition(condition, HttpStatus.BAD_REQUEST, + "convention name " + ValidateUtil.IS_NOT_CORRECT, name); + + List<Name> names = nameRepository.readNames(false, FieldName.NAME, name); + condition = names == null || names.isEmpty(); + validateCondition(condition, HttpStatus.BAD_REQUEST, + "convention name " + ValidateUtil.EXISTS, name); + + names = nameRepository.readNames(false, FieldName.NAMEEQUIVALENCE, namingConvention.equivalenceClassRepresentative(name)); + condition = names == null || names.isEmpty(); + validateCondition(condition, HttpStatus.BAD_REQUEST, + "convention name equivalence " + ValidateUtil.EXISTS, name); + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * Validate parameters for read structures. + * + * @param type type + * @param statuses statuses + * @param deleted deleted + * @param queryFields query fields + * @param queryValues query values + * @param includeHistory include history + * @param orderBy order by + * @param isAsc is ascending + * @param offset offset + * @param limit limit + */ + public static void validateStructuresInputRead( + Type type, Status[] statuses, Boolean deleted, FieldStructure[] queryFields, String[] queryValues, + Boolean includeHistory, + FieldStructure orderBy, Boolean isAsc, + Integer offset, Integer limit) { + + // validate input + // type + // queryFields and queryValues + // either + // both null + // both non-null, same length, non-empty + // uuid + + ValidateUtil.validateInputType(type); + boolean condition = ((queryFields == null && queryValues == null) + || (queryFields != null && queryValues != null && queryFields.length == queryValues.length && queryFields.length > 0)); + ValidateUtil.validateCondition(condition, HttpStatus.BAD_REQUEST, + "url and parameters " + ValidateUtil.ARE_NOT_CORRECT, "queryFields, queryValues with different lengths or empty"); + if (queryFields != null) { + for (int i=0; i<queryFields.length; i++) { + if (FieldStructure.UUID.equals(queryFields[i])) { + ValidateUtil.validateInputUuid(queryValues[i]); + } + } + + } + } + + /** + * Validate structure element parameters (input) for create. + * + * @param structureElement structure element + */ + public static void validateStructureElementInputCreate(StructureElement structureElement) { + validateStructureElementInput(structureElement, StructureChoice.CREATE); + } + + /** + * Validate structure element parameters (input) for update. + * + * @param structureElement structure element + */ + public static void validateStructureElementInputUpdate(StructureElement structureElement) { + validateStructureElementInput(structureElement, StructureChoice.UPDATE); + } + + /** + * Validate structure element parameters (input) for delete. + * + * @param structureElement structure element + */ + public static void validateStructureElementInputDelete(StructureElement structureElement) { + validateStructureElementInput(structureElement, StructureChoice.DELETE); + } + + /** + * Validate structure element parameters (input) for approve. + * + * @param structureElement structure element + */ + public static void validateStructureElementInputApprove(StructureElement structureElement) { + validateStructureElementInput(structureElement, StructureChoice.APPROVE); + } + + /** + * Validate structure element parameters (input) for cancel. + * + * @param structureElement structure element + */ + public static void validateStructureElementInputCancel(StructureElement structureElement) { + validateStructureElementInput(structureElement, StructureChoice.CANCEL); + } + + /** + * Validate structure element parameters (input) for reject. + * + * @param structureElement structure element + */ + public static void validateStructureElementInputReject(StructureElement structureElement) { + validateStructureElementInput(structureElement, StructureChoice.REJECT); + } + + /** + * Validate structure element parameters (input). + * + * @param structureElement structure element + * @param structureChoice structure choice + */ + private static void validateStructureElementInput(StructureElement structureElement, StructureChoice structureChoice) { + // check structure element input + // parent uuid - also validate data, parent uuid available if type is system, subsystem, device group, device type + // name - required + // mnemonic - required except for device group + // description - required + // comment - required + + if (structureElement == null || structureChoice == null) { + return; + } + + if (!StructureChoice.CREATE.equals(structureChoice)) { + validateInputUuid(structureElement.getUuid() != null ? structureElement.getUuid().toString() : null); + } + + validateInputType(structureElement.getType()); + + if (Type.SYSTEM.equals(structureElement.getType())) { + validateCondition(structureElement.getParent() != null, HttpStatus.BAD_REQUEST, "parent uuid " + ValidateUtil.IS_NOT_AVAILABLE, structureElement.toString()); + ValidateUtil.validateInputUuid(structureElement.getParent().toString()); + } else if (Type.SUBSYSTEM.equals(structureElement.getType())) { + validateCondition(structureElement.getParent() != null, HttpStatus.BAD_REQUEST, "parent uuid " + ValidateUtil.IS_NOT_AVAILABLE, structureElement.toString()); + ValidateUtil.validateInputUuid(structureElement.getParent().toString()); + } else if (Type.DEVICEGROUP.equals(structureElement.getType())) { + validateCondition(structureElement.getParent() != null, HttpStatus.BAD_REQUEST, "parent uuid " + ValidateUtil.IS_NOT_AVAILABLE, structureElement.toString()); + ValidateUtil.validateInputUuid(structureElement.getParent().toString()); + } else if (Type.DEVICETYPE.equals(structureElement.getType())) { + validateCondition(structureElement.getParent() != null, HttpStatus.BAD_REQUEST, "parent uuid " + ValidateUtil.IS_NOT_AVAILABLE, structureElement.toString()); + ValidateUtil.validateInputUuid(structureElement.getParent().toString()); + } + + validateInputName(structureElement.getName()); + if (Type.DEVICEGROUP.equals(structureElement.getType())) { + validateCondition(StringUtils.isEmpty(structureElement.getMnemonic()), HttpStatus.BAD_REQUEST, "mnemonic " + ValidateUtil.IS_NOT_CORRECT, structureElement.getMnemonic()); + } else if (!Type.SYSTEMGROUP.equals(structureElement.getType())) { + validateInputMnemonic(structureElement.getMnemonic()); + } + validateInputDescription(structureElement.getDescription()); + validateInputComment(structureElement.getComment()); + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * Validate structure element data for create. + * + * @param structureElement structure element + * @param namingConvention naming convention + * @param holderRepositories holder repositories + * @param holder holder + */ + public static void validateStructureElementDataCreate(StructureElement structureElement, EssNamingConvention namingConvention, HolderRepositories holderRepositories, HolderSystemDeviceStructure holder) { + validateStructureElementDataInItself(structureElement, namingConvention, holderRepositories, holder, StructureChoice.CREATE); + validateStructureElementDataRelativeOtherData(structureElement, namingConvention, holderRepositories, holder, StructureChoice.CREATE); + } + + /** + * Validate structure element data for update. + * + * @param structureElement structure element + * @param namingConvention naming convention + * @param holderRepositories holder repositories + * @param holder holder + */ + public static void validateStructureElementDataUpdate(StructureElement structureElement, EssNamingConvention namingConvention, HolderRepositories holderRepositories, HolderSystemDeviceStructure holder) { + validateStructureElementDataInItself(structureElement, namingConvention, holderRepositories, holder, StructureChoice.UPDATE); + validateStructureElementDataRelativeOtherData(structureElement, namingConvention, holderRepositories, holder, StructureChoice.UPDATE); + } + + /** + * Validate structure element data for delete. + * + * @param structureElement structure element + * @param namingConvention naming convention + * @param holderRepositories holder repositories + * @param holder holder + */ + public static void validateStructureElementDataDelete(StructureElement structureElement, EssNamingConvention namingConvention, HolderRepositories holderRepositories, HolderSystemDeviceStructure holder) { + validateStructureElementDataInItself(structureElement, namingConvention, holderRepositories, holder, StructureChoice.DELETE); + validateStructureElementDataRelativeOtherData(structureElement, namingConvention, holderRepositories, holder, StructureChoice.DELETE); + } + + /** + * Validate structure element data for approve. + * + * @param structureElement structure element + * @param namingConvention naming convention + * @param holderRepositories holder repositories + * @param holder holder + */ + public static void validateStructureElementDataApprove(StructureElement structureElement, EssNamingConvention namingConvention, HolderRepositories holderRepositories, HolderSystemDeviceStructure holder) { + validateStructureElementDataInItself(structureElement, namingConvention, holderRepositories, holder, StructureChoice.APPROVE); + validateStructureElementDataRelativeOtherData(structureElement, namingConvention, holderRepositories, holder, StructureChoice.APPROVE); + } + + /** + * Validate structure element data for cancel. + * + * @param structureElement structure element + * @param namingConvention naming convention + * @param holderRepositories holder repositories + * @param holder holder + */ + public static void validateStructureElementDataCancel(StructureElement structureElement, EssNamingConvention namingConvention, HolderRepositories holderRepositories, HolderSystemDeviceStructure holder) { + validateStructureElementDataInItself(structureElement, namingConvention, holderRepositories, holder, StructureChoice.CANCEL); + validateStructureElementDataRelativeOtherData(structureElement, namingConvention, holderRepositories, holder, StructureChoice.CANCEL); + } + + /** + * Validate structure element data for reject. + * + * @param structureElement structure element + * @param namingConvention naming convention + * @param holderRepositories holder repositories + * @param holder holder + */ + public static void validateStructureElementDataReject(StructureElement structureElement, EssNamingConvention namingConvention, HolderRepositories holderRepositories, HolderSystemDeviceStructure holder) { + validateStructureElementDataInItself(structureElement, namingConvention, holderRepositories, holder, StructureChoice.REJECT); + validateStructureElementDataRelativeOtherData(structureElement, namingConvention, holderRepositories, holder, StructureChoice.REJECT); + } + + /** + * Validate structure element data in itself. + * + * @param structureElement + * @param namingConvention + * @param holderRepositories + * @param holder + * @param structureChoice + */ + public static void validateStructureElementDataInItself(StructureElement structureElement, EssNamingConvention namingConvention, HolderRepositories holderRepositories, HolderSystemDeviceStructure holder, StructureChoice structureChoice) { + // check structure element data in itself + // update, delete + // uuid - approved, latest, not deleted - list size 1 + // possibly + // no pending entry waiting to be approved, cancelled, rejected (pending with higher id than currently approved) + // approve, reject, cancel + // uuid - pending, latest, not deleted - list size 1 + + if (structureElement == null || namingConvention == null || holderRepositories == null || holder == null || structureChoice == null) { + return; + } + + if (StructureChoice.UPDATE.equals(structureChoice) || StructureChoice.DELETE.equals(structureChoice)) { + if (Type.SYSTEMGROUP.equals(structureElement.getType())) { + List<SystemGroup> systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.APPROVED, false, FieldStructure.UUID, structureElement.getUuid().toString()); + ValidateUtil.validateCondition(systemGroups != null && systemGroups.size() == 1, HttpStatus.BAD_REQUEST, + ValidateUtil.SYSTEMGROUP + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT, structureElement.toString()); + } else if (Type.SYSTEM.equals(structureElement.getType())) { + List<System> systems = holderRepositories.getSystemRepository().readSystems(Status.APPROVED, false, FieldStructure.UUID, structureElement.getUuid().toString()); + ValidateUtil.validateCondition(systems != null && systems.size() == 1, HttpStatus.BAD_REQUEST, + ValidateUtil.SYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT, structureElement.toString()); + } else if (Type.SUBSYSTEM.equals(structureElement.getType())) { + List<Subsystem> subsystems = holderRepositories.getSubsystemRepository().readSubsystems(Status.APPROVED, false, FieldStructure.UUID, structureElement.getUuid().toString()); + ValidateUtil.validateCondition(subsystems != null && subsystems.size() == 1, HttpStatus.BAD_REQUEST, + ValidateUtil.SUBSYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT, structureElement.toString()); + } else if (Type.DISCIPLINE.equals(structureElement.getType())) { + List<Discipline> disciplines = holderRepositories.getDisciplineRepository().readDisciplines(Status.APPROVED, false, FieldStructure.UUID, structureElement.getUuid().toString()); + ValidateUtil.validateCondition(disciplines != null && disciplines.size() == 1, HttpStatus.BAD_REQUEST, + ValidateUtil.DISCIPLINE + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT, structureElement.toString()); + } else if (Type.DEVICEGROUP.equals(structureElement.getType())) { + List<DeviceGroup> deviceGroups = holderRepositories.getDeviceGroupRepository().readDeviceGroups(Status.APPROVED, false, FieldStructure.UUID, structureElement.getUuid().toString()); + ValidateUtil.validateCondition(deviceGroups != null && deviceGroups.size() == 1, HttpStatus.BAD_REQUEST, + ValidateUtil.DEVICEGROUP + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT, structureElement.toString()); + } else if (Type.DEVICETYPE.equals(structureElement.getType())) { + List<DeviceType> deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes(Status.APPROVED, false, FieldStructure.UUID, structureElement.getUuid().toString()); + ValidateUtil.validateCondition(deviceTypes != null && deviceTypes.size() == 1, HttpStatus.BAD_REQUEST, + ValidateUtil.DEVICETYPE + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT, structureElement.toString()); + } + } else if (StructureChoice.APPROVE.equals(structureChoice) || StructureChoice.CANCEL.equals(structureChoice) || StructureChoice.REJECT.equals(structureChoice)) { + if (Type.SYSTEMGROUP.equals(structureElement.getType())) { + List<SystemGroup> systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + ValidateUtil.validateCondition(systemGroups != null && systemGroups.size() == 1, HttpStatus.BAD_REQUEST, + ValidateUtil.SYSTEMGROUP + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT, structureElement.toString()); + } else if (Type.SYSTEM.equals(structureElement.getType())) { + List<System> systems = holderRepositories.getSystemRepository().readSystems(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + ValidateUtil.validateCondition(systems != null && systems.size() == 1, HttpStatus.BAD_REQUEST, + ValidateUtil.SYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT, structureElement.toString()); + } else if (Type.SUBSYSTEM.equals(structureElement.getType())) { + List<Subsystem> subsystems = holderRepositories.getSubsystemRepository().readSubsystems(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + ValidateUtil.validateCondition(subsystems != null && subsystems.size() == 1, HttpStatus.BAD_REQUEST, + ValidateUtil.SUBSYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT, structureElement.toString()); + } else if (Type.DISCIPLINE.equals(structureElement.getType())) { + List<Discipline> disciplines = holderRepositories.getDisciplineRepository().readDisciplines(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + ValidateUtil.validateCondition(disciplines != null && disciplines.size() == 1, HttpStatus.BAD_REQUEST, + ValidateUtil.DISCIPLINE + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT, structureElement.toString()); + } else if (Type.DEVICEGROUP.equals(structureElement.getType())) { + List<DeviceGroup> deviceGroups = holderRepositories.getDeviceGroupRepository().readDeviceGroups(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + ValidateUtil.validateCondition(deviceGroups != null && deviceGroups.size() == 1, HttpStatus.BAD_REQUEST, + ValidateUtil.DEVICEGROUP + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT, structureElement.toString()); + } else if (Type.DEVICETYPE.equals(structureElement.getType())) { + List<DeviceType> deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + ValidateUtil.validateCondition(deviceTypes != null && deviceTypes.size() == 1, HttpStatus.BAD_REQUEST, + ValidateUtil.DEVICETYPE + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT, structureElement.toString()); + } + } + } + + /** + * Validate structure element data relative other data. + * + * @param structureElement structure element + * @param namingConvention naming convention + * @param holderRepositories holder repositories + * @param holder holder + * @param structureChoice structure choice + */ + public static void validateStructureElementDataRelativeOtherData(StructureElement structureElement, EssNamingConvention namingConvention, HolderRepositories holderRepositories, HolderSystemDeviceStructure holder, StructureChoice structureChoice) { + // check structure element data in relation to other data + // create, update + // parent uuid - (if applicable) approved, latest, not deleted + // mnemonic - (if not same) not exists + // mnemonic equivalence - (if not same) equivalence not exists + // approve + // uuid - pending, not latest, deleted + // no or less checks if entry to be deleted - approve (delete) + // more or same checks as above if entry is not be deleted - approve (create), approve (update) + // need checks as content may have changed from time of create, update, delete to time of approve + // checks on mnemonic, mnemonic equivalence are to ensure can coexist, can move + // possibly + // additional checks if names are affected + // comment not same as previous comment + + if (structureElement == null || namingConvention == null || holderRepositories == null || holder == null || structureChoice == null) { + return; + } + + String details = structureElement.toString(); + if (StructureChoice.CREATE.equals(structureChoice) || StructureChoice.UPDATE.equals(structureChoice)) { + if (Type.SYSTEMGROUP.equals(structureElement.getType())) { + // note rules for mnemonic for system group + if (!StringUtils.isEmpty(structureElement.getMnemonic())) { + // mnemonic + String message = ValidateUtil.SYSTEMGROUP + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<SystemGroup> systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.APPROVED, false, FieldStructure.MNEMONIC, structureElement.getMnemonic()); + validateConditionIfStructureChoice(StructureChoice.CREATE, structureChoice, systemGroups == null || systemGroups.isEmpty(), HttpStatus.BAD_REQUEST, message, details); + validateConditionIfStructureChoice(StructureChoice.UPDATE, structureChoice, systemGroups == null || systemGroups.isEmpty() || systemGroups.size() == 1 && systemGroups.get(0).getUuid().equals(structureElement.getUuid()), HttpStatus.BAD_REQUEST, message, details); + + // mnemonic equivalence + systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.APPROVED, false, FieldStructure.MNEMONICEQUIVALENCE, namingConvention.equivalenceClassRepresentative(structureElement.getMnemonic())); + validateConditionIfStructureChoice(StructureChoice.CREATE, structureChoice, systemGroups == null || systemGroups.isEmpty(), HttpStatus.BAD_REQUEST, message, details); + validateConditionIfStructureChoice(StructureChoice.UPDATE, structureChoice, systemGroups == null || systemGroups.isEmpty() || systemGroups.size() == 1 && systemGroups.get(0).getUuid().equals(structureElement.getUuid()), HttpStatus.BAD_REQUEST, message, details); + } + } else if (Type.SYSTEM.equals(structureElement.getType())) { + // parent uuid + String message = ValidateUtil.SYSTEMGROUP + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<SystemGroup> systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.APPROVED, false, FieldStructure.UUID, structureElement.getParent().toString()); + ValidateUtil.validateCondition(systemGroups != null && systemGroups.size() == 1, HttpStatus.BAD_REQUEST, message, details); + + // mnemonic + message = ValidateUtil.SYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<System> systems = holderRepositories.getSystemRepository().readSystems(Status.APPROVED, false, FieldStructure.MNEMONIC, structureElement.getMnemonic()); + validateConditionIfStructureChoice(StructureChoice.CREATE, structureChoice, systems == null || systems.isEmpty(), HttpStatus.BAD_REQUEST, message, details); + validateConditionIfStructureChoice(StructureChoice.UPDATE, structureChoice, systems == null || systems.isEmpty() || systems.size() == 1 && systems.get(0).getUuid().equals(structureElement.getUuid()), HttpStatus.BAD_REQUEST, message, details); + + // mnemonic equivalence + systems = holderRepositories.getSystemRepository().readSystems(Status.APPROVED, false, FieldStructure.MNEMONICEQUIVALENCE, namingConvention.equivalenceClassRepresentative(structureElement.getMnemonic())); + validateConditionIfStructureChoice(StructureChoice.CREATE, structureChoice, systems == null || systems.isEmpty(), HttpStatus.BAD_REQUEST, message, details); + validateConditionIfStructureChoice(StructureChoice.UPDATE, structureChoice, systems == null || systems.isEmpty() || systems.size() == 1 && systems.get(0).getUuid().equals(structureElement.getUuid()), HttpStatus.BAD_REQUEST, message, details); + } else if (Type.SUBSYSTEM.equals(structureElement.getType())) { + // parent uuid + String message = ValidateUtil.SYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<System> systems = holderRepositories.getSystemRepository().readSystems(Status.APPROVED, false, FieldStructure.UUID, structureElement.getParent().toString()); + ValidateUtil.validateCondition(systems != null && systems.size() == 1, HttpStatus.BAD_REQUEST, message, details); + + // mnemonic + message = ValidateUtil.SUBSYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<Subsystem> subsystems = holderRepositories.getSubsystemRepository().readSubsystems(Status.APPROVED, false, FieldStructure.MNEMONIC, structureElement.getMnemonic()); + validateConditionIfStructureChoice(StructureChoice.CREATE, structureChoice, subsystems == null || subsystems.isEmpty(), HttpStatus.BAD_REQUEST, message, details); + validateConditionIfStructureChoice(StructureChoice.UPDATE, structureChoice, subsystems == null || subsystems.isEmpty() || subsystems.size() == 1 && subsystems.get(0).getUuid().equals(structureElement.getUuid()), HttpStatus.BAD_REQUEST, message, details); + + // mnemonic equivalence + subsystems = holderRepositories.getSubsystemRepository().readSubsystems(Status.APPROVED, false, FieldStructure.MNEMONICEQUIVALENCE, namingConvention.equivalenceClassRepresentative(structureElement.getMnemonic())); + validateConditionIfStructureChoice(StructureChoice.CREATE, structureChoice, subsystems == null || subsystems.isEmpty(), HttpStatus.BAD_REQUEST, message, details); + validateConditionIfStructureChoice(StructureChoice.UPDATE, structureChoice, subsystems == null || subsystems.isEmpty() || subsystems.size() == 1 && subsystems.get(0).getUuid().equals(structureElement.getUuid()), HttpStatus.BAD_REQUEST, message, details); + } else if (Type.DISCIPLINE.equals(structureElement.getType())) { + // mnemonic + String message = ValidateUtil.DISCIPLINE + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<Discipline> disciplines = holderRepositories.getDisciplineRepository().readDisciplines(Status.APPROVED, false, FieldStructure.MNEMONIC, structureElement.getMnemonic()); + validateConditionIfStructureChoice(StructureChoice.CREATE, structureChoice, disciplines == null || disciplines.isEmpty(), HttpStatus.BAD_REQUEST, message, details); + validateConditionIfStructureChoice(StructureChoice.UPDATE, structureChoice, disciplines == null || disciplines.isEmpty() || disciplines.size() == 1 && disciplines.get(0).getUuid().equals(structureElement.getUuid()), HttpStatus.BAD_REQUEST, message, details); + + // mnemonic equivalence + disciplines = holderRepositories.getDisciplineRepository().readDisciplines(Status.APPROVED, false, FieldStructure.MNEMONICEQUIVALENCE, namingConvention.equivalenceClassRepresentative(structureElement.getMnemonic())); + validateConditionIfStructureChoice(StructureChoice.CREATE, structureChoice, disciplines == null || disciplines.isEmpty(), HttpStatus.BAD_REQUEST, message, details); + validateConditionIfStructureChoice(StructureChoice.UPDATE, structureChoice, disciplines == null || disciplines.isEmpty() || disciplines.size() == 1 && disciplines.get(0).getUuid().equals(structureElement.getUuid()), HttpStatus.BAD_REQUEST, message, details); + } else if (Type.DEVICEGROUP.equals(structureElement.getType())) { + // parent uuid + String message = ValidateUtil.DISCIPLINE + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<Discipline> disciplines = holderRepositories.getDisciplineRepository().readDisciplines(Status.APPROVED, false, FieldStructure.UUID, structureElement.getParent().toString()); + ValidateUtil.validateCondition(disciplines != null && disciplines.size() == 1, HttpStatus.BAD_REQUEST, message, details); + + // note rules for mnemonic for device group + + // mnemonic + message = ValidateUtil.DEVICEGROUP + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + ValidateUtil.validateCondition(StringUtils.isEmpty(structureElement.getMnemonic()), HttpStatus.BAD_REQUEST, message, details); + } else if (Type.DEVICETYPE.equals(structureElement.getType())) { + // parent uuid + String message = ValidateUtil.DEVICEGROUP + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<DeviceGroup> deviceGroups = holderRepositories.getDeviceGroupRepository().readDeviceGroups(Status.APPROVED, false, FieldStructure.UUID, structureElement.getParent().toString()); + ValidateUtil.validateCondition(deviceGroups != null && deviceGroups.size() == 1, HttpStatus.BAD_REQUEST, message, details); + + // mnemonic + message = ValidateUtil.DEVICETYPE + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<DeviceType> deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes(Status.APPROVED, false, FieldStructure.MNEMONIC, structureElement.getMnemonic()); + validateConditionIfStructureChoice(StructureChoice.CREATE, structureChoice, deviceTypes == null || deviceTypes.isEmpty(), HttpStatus.BAD_REQUEST, message, details); + validateConditionIfStructureChoice(StructureChoice.UPDATE, structureChoice, deviceTypes == null || deviceTypes.isEmpty() || deviceTypes.size() == 1 && deviceTypes.get(0).getUuid().equals(structureElement.getUuid()), HttpStatus.BAD_REQUEST, message, details); + + // mnemonic equivalence + deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes(Status.APPROVED, false, FieldStructure.MNEMONICEQUIVALENCE, namingConvention.equivalenceClassRepresentative(structureElement.getMnemonic())); + validateConditionIfStructureChoice(StructureChoice.CREATE, structureChoice, deviceTypes == null || deviceTypes.isEmpty(), HttpStatus.BAD_REQUEST, message, details); + validateConditionIfStructureChoice(StructureChoice.UPDATE, structureChoice, deviceTypes == null || deviceTypes.isEmpty() || deviceTypes.size() == 1 && deviceTypes.get(0).getUuid().equals(structureElement.getUuid()), HttpStatus.BAD_REQUEST, message, details); + } + } else if (StructureChoice.APPROVE.equals(structureChoice)) { + // + if (Type.SYSTEMGROUP.equals(structureElement.getType())) { + String message = ValidateUtil.SYSTEMGROUP + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<SystemGroup> toBeApproved = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + ValidateUtil.validateCondition(toBeApproved != null && toBeApproved.size() == 1, HttpStatus.BAD_REQUEST, message, details); + + // mnemonic + List<SystemGroup> systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.APPROVED, false, FieldStructure.MNEMONIC, toBeApproved.get(0).getMnemonic()); + validateConditionIfStructureChoice(StructureChoice.CREATE, structureChoice, systemGroups == null || systemGroups.isEmpty(), HttpStatus.BAD_REQUEST, message, details); + validateConditionIfStructureChoice(StructureChoice.UPDATE, structureChoice, systemGroups == null || systemGroups.isEmpty() || systemGroups.size() == 1 && systemGroups.get(0).getUuid().equals(toBeApproved.get(0).getUuid()), HttpStatus.BAD_REQUEST, message, details); + + // mnemonic equivalence + systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.APPROVED, false, FieldStructure.MNEMONICEQUIVALENCE, toBeApproved.get(0).getMnemonicEquivalence()); + validateConditionIfStructureChoice(StructureChoice.CREATE, structureChoice, systemGroups == null || systemGroups.isEmpty(), HttpStatus.BAD_REQUEST, message, details); + validateConditionIfStructureChoice(StructureChoice.UPDATE, structureChoice, systemGroups == null || systemGroups.isEmpty() || systemGroups.size() == 1 && systemGroups.get(0).getUuid().equals(toBeApproved.get(0).getUuid()), HttpStatus.BAD_REQUEST, message, details); + } else if (Type.SYSTEM.equals(structureElement.getType())) { + String message = ValidateUtil.SYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<System> toBeApproved = holderRepositories.getSystemRepository().readSystems(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + ValidateUtil.validateCondition(toBeApproved != null && toBeApproved.size() == 1, HttpStatus.BAD_REQUEST, message, details); + + // parent uuid + message = ValidateUtil.SYSTEMGROUP + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<SystemGroup> systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(Status.APPROVED, false, FieldStructure.UUID, toBeApproved.get(0).getParentUuid().toString()); + ValidateUtil.validateCondition(systemGroups != null && systemGroups.size() == 1, HttpStatus.BAD_REQUEST, message, details); + + // mnemonic + message = ValidateUtil.SYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<System> systems = holderRepositories.getSystemRepository().readSystems(Status.APPROVED, false, FieldStructure.MNEMONIC, toBeApproved.get(0).getMnemonic()); + validateConditionIfStructureChoice(StructureChoice.CREATE, structureChoice, systems == null || systems.isEmpty(), HttpStatus.BAD_REQUEST, message, details); + validateConditionIfStructureChoice(StructureChoice.UPDATE, structureChoice, systems == null || systems.isEmpty() || systems.size() == 1 && systems.get(0).getUuid().equals(toBeApproved.get(0).getUuid()), HttpStatus.BAD_REQUEST, message, details); + + // mnemonic equivalence + systems = holderRepositories.getSystemRepository().readSystems(Status.APPROVED, false, FieldStructure.MNEMONICEQUIVALENCE, toBeApproved.get(0).getMnemonicEquivalence()); + validateConditionIfStructureChoice(StructureChoice.CREATE, structureChoice, systems == null || systems.isEmpty(), HttpStatus.BAD_REQUEST, message, details); + validateConditionIfStructureChoice(StructureChoice.UPDATE, structureChoice, systems == null || systems.isEmpty() || systems.size() == 1 && systems.get(0).getUuid().equals(toBeApproved.get(0).getUuid()), HttpStatus.BAD_REQUEST, message, details); + } else if (Type.SUBSYSTEM.equals(structureElement.getType())) { + String message = ValidateUtil.SUBSYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<Subsystem> toBeApproved = holderRepositories.getSubsystemRepository().readSubsystems(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + ValidateUtil.validateCondition(toBeApproved != null && toBeApproved.size() == 1, HttpStatus.BAD_REQUEST, message, details); + + // parent uuid + message = ValidateUtil.SYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<System> systems = holderRepositories.getSystemRepository().readSystems(Status.APPROVED, false, FieldStructure.UUID, toBeApproved.get(0).getParentUuid().toString()); + ValidateUtil.validateCondition(systems != null && systems.size() == 1, HttpStatus.BAD_REQUEST, message, details); + + // mnemonic + message = ValidateUtil.SUBSYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<Subsystem> subsystems = holderRepositories.getSubsystemRepository().readSubsystems(Status.APPROVED, false, FieldStructure.MNEMONIC, toBeApproved.get(0).getMnemonic()); + validateConditionIfStructureChoice(StructureChoice.CREATE, structureChoice, subsystems == null || subsystems.isEmpty(), HttpStatus.BAD_REQUEST, message, details); + validateConditionIfStructureChoice(StructureChoice.UPDATE, structureChoice, subsystems == null || subsystems.isEmpty() || subsystems.size() == 1 && subsystems.get(0).getUuid().equals(toBeApproved.get(0).getUuid()), HttpStatus.BAD_REQUEST, message, details); + + // mnemonic equivalence + subsystems = holderRepositories.getSubsystemRepository().readSubsystems(Status.APPROVED, false, FieldStructure.MNEMONICEQUIVALENCE, toBeApproved.get(0).getMnemonicEquivalence()); + validateConditionIfStructureChoice(StructureChoice.CREATE, structureChoice, subsystems == null || subsystems.isEmpty(), HttpStatus.BAD_REQUEST, message, details); + validateConditionIfStructureChoice(StructureChoice.UPDATE, structureChoice, subsystems == null || subsystems.isEmpty() || subsystems.size() == 1 && subsystems.get(0).getUuid().equals(toBeApproved.get(0).getUuid()), HttpStatus.BAD_REQUEST, message, details); + } else if (Type.DISCIPLINE.equals(structureElement.getType())) { + String message = ValidateUtil.DISCIPLINE + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<Discipline> toBeApproved = holderRepositories.getDisciplineRepository().readDisciplines(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + ValidateUtil.validateCondition(toBeApproved != null && toBeApproved.size() == 1, HttpStatus.BAD_REQUEST, message, details); + + // mnemonic + List<Discipline> disciplines = holderRepositories.getDisciplineRepository().readDisciplines(Status.APPROVED, false, FieldStructure.MNEMONIC, toBeApproved.get(0).getMnemonic()); + validateConditionIfStructureChoice(StructureChoice.CREATE, structureChoice, disciplines == null || disciplines.isEmpty(), HttpStatus.BAD_REQUEST, message, details); + validateConditionIfStructureChoice(StructureChoice.UPDATE, structureChoice, disciplines == null || disciplines.isEmpty() || disciplines.size() == 1 && disciplines.get(0).getUuid().equals(toBeApproved.get(0).getUuid()), HttpStatus.BAD_REQUEST, message, details); + + // mnemonic equivalence + disciplines = holderRepositories.getDisciplineRepository().readDisciplines(Status.APPROVED, false, FieldStructure.MNEMONICEQUIVALENCE, toBeApproved.get(0).getMnemonicEquivalence()); + validateConditionIfStructureChoice(StructureChoice.CREATE, structureChoice, disciplines == null || disciplines.isEmpty(), HttpStatus.BAD_REQUEST, message, details); + validateConditionIfStructureChoice(StructureChoice.UPDATE, structureChoice, disciplines == null || disciplines.isEmpty() || disciplines.size() == 1 && disciplines.get(0).getUuid().equals(toBeApproved.get(0).getUuid()), HttpStatus.BAD_REQUEST, message, details); + } else if (Type.DEVICEGROUP.equals(structureElement.getType())) { + String message = ValidateUtil.DEVICEGROUP + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<DeviceGroup> toBeApproved = holderRepositories.getDeviceGroupRepository().readDeviceGroups(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + ValidateUtil.validateCondition(toBeApproved != null && toBeApproved.size() == 1, HttpStatus.BAD_REQUEST, message, details); + + // parent uuid + message = ValidateUtil.DISCIPLINE + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<Discipline> disciplines = holderRepositories.getDisciplineRepository().readDisciplines(Status.APPROVED, false, FieldStructure.UUID, toBeApproved.get(0).getParentUuid().toString()); + ValidateUtil.validateCondition(disciplines != null && disciplines.size() == 1, HttpStatus.BAD_REQUEST, message, details); + + // note rules for mnemonic for device group + + // mnemonic + message = ValidateUtil.DEVICEGROUP + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + ValidateUtil.validateCondition(StringUtils.isEmpty(structureElement.getMnemonic()), HttpStatus.BAD_REQUEST, message, details); + } else if (Type.DEVICETYPE.equals(structureElement.getType())) { + String message = ValidateUtil.DEVICETYPE + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<DeviceType> toBeApproved = holderRepositories.getDeviceTypeRepository().readDeviceTypes(Status.PENDING, null, FieldStructure.UUID, structureElement.getUuid().toString()); + ValidateUtil.validateCondition(toBeApproved != null && toBeApproved.size() == 1, HttpStatus.BAD_REQUEST, message, details); + + // parent uuid + message = ValidateUtil.DEVICEGROUP + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<DeviceGroup> deviceGroups = holderRepositories.getDeviceGroupRepository().readDeviceGroups(Status.APPROVED, false, FieldStructure.UUID, toBeApproved.get(0).getParentUuid().toString()); + ValidateUtil.validateCondition(deviceGroups != null && deviceGroups.size() == 1, HttpStatus.BAD_REQUEST, message, details); + + // mnemonic + message = ValidateUtil.DEVICETYPE + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT; + List<DeviceType> deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes(Status.APPROVED, false, FieldStructure.MNEMONIC, toBeApproved.get(0).getMnemonic()); + validateConditionIfStructureChoice(StructureChoice.CREATE, structureChoice, deviceTypes == null || deviceTypes.isEmpty(), HttpStatus.BAD_REQUEST, message, details); + validateConditionIfStructureChoice(StructureChoice.UPDATE, structureChoice, deviceTypes == null || deviceTypes.isEmpty() || deviceTypes.size() == 1 && deviceTypes.get(0).getUuid().equals(toBeApproved.get(0).getUuid()), HttpStatus.BAD_REQUEST, message, details); + + // mnemonic equivalence + deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes(Status.APPROVED, false, FieldStructure.MNEMONICEQUIVALENCE, toBeApproved.get(0).getMnemonicEquivalence()); + validateConditionIfStructureChoice(StructureChoice.CREATE, structureChoice, deviceTypes == null || deviceTypes.isEmpty(), HttpStatus.BAD_REQUEST, message, details); + validateConditionIfStructureChoice(StructureChoice.UPDATE, structureChoice, deviceTypes == null || deviceTypes.isEmpty() || deviceTypes.size() == 1 && deviceTypes.get(0).getUuid().equals(toBeApproved.get(0).getUuid()), HttpStatus.BAD_REQUEST, message, details); + } + } + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * Validate structure data. + * This method corresponds to structure element data for create, albeit in a different way. + * + * @param type type + * @param mnemonicpath mnemonic path + * @param namingConvention naming convention + * @param holderIRepositories holder repositories + * @param holder holder + */ + public static void validateStructureDataCreate(Type type, String mnemonicpath, EssNamingConvention namingConvention, HolderIRepositories holderIRepositories, HolderSystemDeviceStructure holder) { + if (type == null || mnemonicpath == null || namingConvention == null || holderIRepositories == null || holder == null) { + return; + } + + String[] path = NamingConventionUtil.string2MnemonicPath(mnemonicpath); + validateCondition(path != null && path.length >= 1 && path.length <= 3, + HttpStatus.BAD_REQUEST, ValidateUtil.STRUCTURE + " mnemonic path " + ValidateUtil.IS_NOT_VALID, path + ", " + mnemonicpath); + + if (Type.SYSTEMGROUP.equals(type)) { + validateCondition(path.length == 1, HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEMGROUP + " mnemonic path " + ValidateUtil.IS_NOT_VALID, path.length + ", " + mnemonicpath); + + // system group may have empty path but there will be mnemonicpath in this context + + // mnemonic + SystemGroup sg = holderIRepositories.getSystemGroupRepository().findLatestNotDeletedByMnemonic(path[0]); + ValidateUtil.validateCondition(sg == null, HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEMGROUP + " mnemonic path duplicate", path[0] + ", " + mnemonicpath); + + // mnemonic equivalence + List<SystemGroup> systemGroups = holderIRepositories.getSystemGroupRepository().findLatestNotDeleted(); + for (SystemGroup systemGroup : systemGroups) { + validateCondition(!StringUtils.equals(systemGroup.getMnemonicEquivalence(), namingConvention.equivalenceClassRepresentative(path[0])), HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEMGROUP + " mnemonic path equivalence duplicate", path[0] + ", " + mnemonicpath); + } + } else if (Type.SYSTEM.equals(type)) { + validateCondition(path.length == 1 || path.length == 2, HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEM + " mnemonic path " + ValidateUtil.IS_NOT_VALID, path.length + ", " + mnemonicpath); + + // path with 2 elements - system group and system ---> check both as pair + // path with 1 element - system group or system ---> check both individually + // check mnemonic, mnemonic equivalence + + // mnemonic + if (path.length == 2) { + validateCondition(!StringUtils.equals(path[0], path[1]), HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEM + " mnemonic path duplicate", mnemonicpath); + } + List<String> mnemonicPaths = StructureUtil.getMnemonicPathsSystem(holder, false, namingConvention); + for (String existingPath : mnemonicPaths) { + validateCondition(!StringUtils.equals(mnemonicpath, existingPath), HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEM + " mnemonic path duplicate", mnemonicpath); + } + + // mnemonic equivalence + if (path.length == 2) { + validateCondition(!StringUtils.equals(namingConvention.equivalenceClassRepresentative(path[0]), namingConvention.equivalenceClassRepresentative(path[1])), HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEM + " mnemonic path duplicate", mnemonicpath); + } + String mnemonicpathEquivalence = namingConvention.equivalenceClassRepresentative(mnemonicpath); + mnemonicPaths = StructureUtil.getMnemonicPathsSystem(holder, true, namingConvention); + for (String existingPath : mnemonicPaths) { + validateCondition(!StringUtils.equals(mnemonicpathEquivalence, namingConvention.equivalenceClassRepresentative(existingPath)), HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEM + " mnemonic path equivalence duplicate", mnemonicpath); + } + } else if (Type.SUBSYSTEM.equals(type)) { + validateCondition(path.length == 2 || path.length == 3, HttpStatus.BAD_REQUEST, ValidateUtil.SUBSYSTEM + " mnemonic path " + ValidateUtil.IS_NOT_VALID, path.length + ", " + mnemonicpath); + + // mnemonic + if (path.length == 2) { + validateCondition(!StringUtils.equals(path[0], path[1]), HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEM + " mnemonic path duplicate", mnemonicpath); + } else { + validateCondition(!StringUtils.equals(path[0], path[1]), HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEM + " mnemonic path duplicate", mnemonicpath); + validateCondition(!StringUtils.equals(path[0], path[2]), HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEM + " mnemonic path duplicate", mnemonicpath); + validateCondition(!StringUtils.equals(path[1], path[2]), HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEM + " mnemonic path duplicate", mnemonicpath); + } + List<String> mnemonicPaths = StructureUtil.getMnemonicPathsSubsystem(holder, false, namingConvention); + for (String existingPath : mnemonicPaths) { + validateCondition(!StringUtils.equals(mnemonicpath, existingPath), HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEM + " mnemonic path duplicate", mnemonicpath); + } + + // mnemonic equivalence + if (path.length == 2) { + validateCondition(!StringUtils.equals(namingConvention.equivalenceClassRepresentative(path[0]), namingConvention.equivalenceClassRepresentative(path[1])), HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEM + " mnemonic path duplicate", mnemonicpath); + } else { + validateCondition(!StringUtils.equals(namingConvention.equivalenceClassRepresentative(path[0]), namingConvention.equivalenceClassRepresentative(path[1])), HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEM + " mnemonic path duplicate", mnemonicpath); + validateCondition(!StringUtils.equals(namingConvention.equivalenceClassRepresentative(path[0]), namingConvention.equivalenceClassRepresentative(path[2])), HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEM + " mnemonic path duplicate", mnemonicpath); + validateCondition(!StringUtils.equals(namingConvention.equivalenceClassRepresentative(path[1]), namingConvention.equivalenceClassRepresentative(path[2])), HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEM + " mnemonic path duplicate", mnemonicpath); + } + String mnemonicpathEquivalence = namingConvention.equivalenceClassRepresentative(mnemonicpath); + mnemonicPaths = StructureUtil.getMnemonicPathsSubsystem(holder, true, namingConvention); + for (String existingPath : mnemonicPaths) { + validateCondition(!StringUtils.equals(mnemonicpathEquivalence, namingConvention.equivalenceClassRepresentative(existingPath)), HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEM + " mnemonic path equivalence duplicate", mnemonicpath); + } + } else if (Type.DISCIPLINE.equals(type)) { + validateCondition(path.length == 1, HttpStatus.BAD_REQUEST, ValidateUtil.DISCIPLINE + " mnemonic path " + ValidateUtil.IS_NOT_VALID, path[0] + ", " + mnemonicpath); + + // mnemonic + Discipline di = holderIRepositories.getDisciplineRepository().findLatestNotDeletedByMnemonic(path[0]); + ValidateUtil.validateCondition(di == null, HttpStatus.BAD_REQUEST, ValidateUtil.DISCIPLINE + " mnemonic path duplicate", path[0] + ", " + mnemonicpath); + + // mnemonic equivalence + List<Discipline> disciplines = holderIRepositories.getDisciplineRepository().findLatestNotDeleted(); + for (Discipline discipline : disciplines) { + validateCondition(!StringUtils.equals(discipline.getMnemonicEquivalence(), namingConvention.equivalenceClassRepresentative(path[0])), + HttpStatus.BAD_REQUEST, ValidateUtil.DISCIPLINE + " mnemonic path equivalence duplicate", path[0] + ", " + mnemonicpath); + } + } else if (Type.DEVICEGROUP.equals(type)) { + throw ExceptionUtil.createServiceHttpStatusExceptionBadRequest(ValidateUtil.DEVICEGROUP + " mnemonic path " + ValidateUtil.IS_NOT_VALID, path.length + ", " + mnemonicpath, null); + } else if (Type.DEVICETYPE.equals(type)) { + validateCondition(path.length == 2, HttpStatus.BAD_REQUEST, ValidateUtil.STRUCTURE + " " + ValidateUtil.DEVICETYPE + " mnemonic path " + ValidateUtil.IS_NOT_VALID, path.length + ", " + mnemonicpath); + + // discipline + Discipline discipline = holderIRepositories.getDisciplineRepository().findLatestNotDeletedByMnemonic(path[0]); + ValidateUtil.validateCondition(discipline != null, HttpStatus.BAD_REQUEST, ValidateUtil.DISCIPLINE + " " + ValidateUtil.IS_NOT_VALID, path[0] + ", " + mnemonicpath); + + // mnemonic + if (path.length == 2) { + validateCondition(!StringUtils.equals(path[0], path[1]), HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEM + " mnemonic path duplicate", mnemonicpath); + } + + // mnemonic equivalence + validateCondition(!StringUtils.equals(namingConvention.equivalenceClassRepresentative(path[0]), namingConvention.equivalenceClassRepresentative(path[1])), HttpStatus.BAD_REQUEST, ValidateUtil.SYSTEM + " mnemonic path duplicate", mnemonicpath); + + // since device group is between discipline and device type and device group has no mnemonic, + // it can not be traced to which device group that this device type belongs, + // therefore it can not be known tO which mnemonic line it belongs + // therefore this method considered ok as long as mnemonic not empty and mnemonic not duplicate + // this is ensured by path length 2 + // rest of checks in validatecreate + } + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * Validate condition and throw ServiceHttpStatusException with reason if validation fails. + * + * @param condition condition + * @param status http status + * @param message message + * @param details details + * + * @see ServiceHttpStatusException + */ + public static void validateCondition(boolean condition, HttpStatus status, String message, String details) { + if (!condition) { + switch(status) { + case BAD_REQUEST: + throw ExceptionUtil.createServiceHttpStatusExceptionBadRequest(message, details, null); + default: + throw ExceptionUtil.createServiceHttpStatusExceptionInternalServerError(message, details, null); + } + } + } + + /** + * Validate condition if precondition is fulfilled and throw ServiceHttpStatusException with reason if validation fails. + * + * @param precondition precondition + * @param condition condition + * @param status http status + * @param message message + * @param details details + * + * @see ServiceHttpStatusException + */ + public static void validateConditionIfPrecondition(boolean precondition, boolean condition, HttpStatus status, String message, String details) { + if (precondition) { + validateCondition(condition, status, message, details); + } + } + + /** + * Validate condition if precondition (StructureChoice) is fulfilled and throw ServiceHttpStatusException with reason if validation fails. + * + * @param expected expected structure choice + * @param actual actual structure choice + * @param condition condition + * @param status http status + * @param message message + * @param details details + * + * @see ServiceHttpStatusException + */ + public static void validateConditionIfStructureChoice(StructureChoice expected, StructureChoice actual, boolean condition, HttpStatus status, String message, String details) { + validateConditionIfPrecondition(expected != null && expected.equals(actual), condition, status, message, details); + } + + + +} diff --git a/src/test/java/org/openepics/names/util/EssNamingConventionTest.java b/src/test/java/org/openepics/names/util/EssNamingConventionTest.java new file mode 100644 index 0000000..384d0c7 --- /dev/null +++ b/src/test/java/org/openepics/names/util/EssNamingConventionTest.java @@ -0,0 +1,988 @@ +/* +* Copyright (c) 2014 European Spallation Source +* Copyright (c) 2014 Cosylab d.d. +* +* This file is part of Naming Service. +* Naming Service is free software: you can redistribute it and/or modify it under +* the terms of the GNU General Public License as published by the Free +* Software Foundation, either version 2 of the License, or any newer 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 General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see https://www.gnu.org/licenses/gpl-2.0.txt +*/ +package org.openepics.names.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +/** + * Unit tests for EssNamingConvention class. + * + * @author Karin Rathsman + * @author Lars Johansson + * + * @see NamingConvention + * @see EssNamingConvention + */ +public class EssNamingConventionTest { + + // ---------------------------------------------------------------------------------------------------- + // table of content + // ---------------------------------------------------------------------------------------------------- + // name by itself + // validateMnemonic + // system structure + // device structure + // validateMnemonic (2) + // system structure + // device structure + // isInstanceIndexValid + // device + // isInstanceIndexValid (2) + // device + // equivalenceClassRepresentative + // conventionName + // name in relation to other + // canMnemonicsCoexist + // system structure + // device structure + // system structure & device structure + // canMnemonicsCoexist (2) + // system structure + // device structure + // system structure & device structure + // ---------------------------------------------------------------------------------------------------- + + private static final String EMPTY = ""; + private static final String NULL = null; + private static final String SPACE = " "; + + private static final String A = "A"; + + private static final String SUP = "Sup"; + private static final String SYS = "Sys"; + private static final String SUB = "Sub"; + private static final String DIS = "Dis"; + private static final String DEV = "Dev"; + private static final String IDX = "Idx"; + + private static final String ECAT10 = "ECAT10"; + private static final String IOC = "IOC"; + private static final String TDS = "TDS"; + private static final String TD180 = "TD180"; + + private static final String NUM_0 = "0"; + private static final String NUM_1 = "1"; + private static final String NUM_12 = "12"; + private static final String NUM_123 = "123"; + private static final String NUM_1234 = "1234"; + private static final String NUM_12345 = "12345"; + private static final String NUM_123456 = "123456"; + private static final String NUM_1234567 = "1234567"; + + private static final String ALPHABETIC_NOT_OK = "alphabetic value not allowed"; + private static final String BLANKS_NOT_OK = "value with blanks not allowed"; + private static final String EMPTY_NOT_OK = "empty value not allowed"; + private static final String LENGTH_NOT_OK = "length of value not allowed"; + private static final String LENGTH_OK = "length of value allowed"; + private static final String NON_ALPHANUMERIC_NOT_OK = "non-alphanumeric value not allowed"; + private static final String NUMERIC_OK = "numeric value allowed"; + private static final String NULL_NOT_OK = "null value not allowed"; + private static final String ONLY_ZEROS_NOT_OK = "value with only zeros not allowed"; + + private static EssNamingConvention namingConvention; + + /** + * One-time initialization code. + */ + @BeforeAll + public static void oneTimeSetUp() { + namingConvention = new EssNamingConvention(); + } + + /** + * One-time cleanup code. + */ + @AfterAll + public static void oneTimeTearDown() { + namingConvention = null; + } + + // ---------------------------------------------------------------------------------------------------- + // name by itself + // isInstanceIndexValid + // device + // device override + // device PID + // device PID override + // ---------------------------------------------------------------------------------------------------- + + /** + * Test validity of instance index for device. + */ + @Test + public void isInstanceIndexValid() { + String conventionNameBase = SYS + "-" + SUB + ":" + DIS + "-" + DEV; + + assertFalse(namingConvention.isInstanceIndexValid(NULL), NULL_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase), EMPTY_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + EMPTY), EMPTY_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + SPACE), BLANKS_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + IDX), ALPHABETIC_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "abcdef"), ALPHABETIC_NOT_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_123), NUMERIC_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "0"), ONLY_ZEROS_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "00"), ONLY_ZEROS_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "000"), ONLY_ZEROS_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "0000"), ONLY_ZEROS_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "00000"), ONLY_ZEROS_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "000000"), ONLY_ZEROS_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "0000000"), ONLY_ZEROS_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "abc123"), ALPHABETIC_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "a!"), NON_ALPHANUMERIC_NOT_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "01"), LENGTH_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "001"), LENGTH_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "0001"), LENGTH_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "0110"), LENGTH_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "10"), LENGTH_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "100"), LENGTH_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "1000"), LENGTH_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_1), LENGTH_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_12), LENGTH_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_123), LENGTH_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_1234), LENGTH_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_12345), LENGTH_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_123456), LENGTH_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_1234567), LENGTH_NOT_OK); + + conventionNameBase = SUP + "-" + SYS + "-" + SUB + ":" + DIS + "-" + DEV; + + assertFalse(namingConvention.isInstanceIndexValid(NULL), NULL_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase), EMPTY_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + EMPTY), EMPTY_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + SPACE), BLANKS_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + IDX), ALPHABETIC_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "abcdef"), ALPHABETIC_NOT_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_123), NUMERIC_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "0"), ONLY_ZEROS_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "00"), ONLY_ZEROS_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "000"), ONLY_ZEROS_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "0000"), ONLY_ZEROS_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "00000"), ONLY_ZEROS_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "000000"), ONLY_ZEROS_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "0000000"), ONLY_ZEROS_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "abc123"), ALPHABETIC_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "a!"), NON_ALPHANUMERIC_NOT_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "01"), LENGTH_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "001"), LENGTH_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "0001"), LENGTH_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "0110"), LENGTH_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "10"), LENGTH_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "100"), LENGTH_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "1000"), LENGTH_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_1), LENGTH_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_12), LENGTH_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_123), LENGTH_OK); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_1234), LENGTH_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_12345), LENGTH_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_123456), LENGTH_NOT_OK); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_1234567), LENGTH_NOT_OK); + } + + /** + * Test validity of instance index for device. + */ + @Test + public void isInstanceIndexValidOverride() { + // override - length, characters + + String conventionNameBase = SYS + "-" + SUB + ":" + DIS + "-" + DEV; + + assertFalse(namingConvention.isInstanceIndexValid(NULL, true)); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase, true)); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + EMPTY, true)); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + SPACE, true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + IDX, true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "abcdef", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_123, true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "0", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "00", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "000", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "0000", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "00000", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "000000", true)); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "0000000", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "abc123", true)); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "a!", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "01", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "001", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "0001", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "0110", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "10", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "100", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "1000", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_1, true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_12, true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_123, true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_1234, true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_12345, true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_123456, true)); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_1234567, true)); + + conventionNameBase = SUP + "-" + SYS + "-" + SUB + ":" + DIS + "-" + DEV; + + assertFalse(namingConvention.isInstanceIndexValid(NULL, true)); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase, true)); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + EMPTY, true)); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + SPACE, true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + IDX, true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "abcdef", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_123, true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "0", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "00", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "000", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "0000", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "00000", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "000000", true)); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "0000000", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "abc123", true)); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "a!", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "01", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "001", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "0001", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "0110", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "10", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "100", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + "1000", true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_1, true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_12, true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_123, true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_1234, true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_12345, true)); + assertTrue (namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_123456, true)); + assertFalse(namingConvention.isInstanceIndexValid(conventionNameBase + "-" + NUM_1234567, true)); + } + + /** + * Test validity of instance index, for device. + */ + @Test + public void isInstanceIndexValidPIDNumeric() { + // depend on discipline, device type + + // mnemonic path system structure + final String systemStructure = TDS + "-" + TD180; + + // mnemonic path device structure + final String deviceStructure1 = "Mech" + "-" + IOC; + final String deviceStructure2 = "Cryo" + "-" + IOC; + final String deviceStructure3 = "EMR" + "-" + IOC; + final String deviceStructure4 = "HVAC" + "-" + IOC; + final String deviceStructure5 = "Proc" + "-" + IOC; + final String deviceStructure6 = "SC" + "-" + IOC; + final String deviceStructure7 = "Vac" + "-" + IOC; + final String deviceStructure8 = "WtrC" + "-" + IOC; + + final String _001a = "001a"; + final String _001ab = "001ab"; + final String _001abc = "001abc"; + final String _001abcd = "001abcd"; + final String _001A = "001A"; + final String _001AB = "001AB"; + final String _001ABC = "001ABC"; + final String _001ABCD = "001ABCD"; + + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure1)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure2)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure3)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure4)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure5)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure6)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure7)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure8)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure1 + "-" + "000")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure2 + "-" + "000")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure3 + "-" + "000")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure4 + "-" + "000")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure5 + "-" + "000")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure6 + "-" + "000")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure7 + "-" + "000")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure8 + "-" + "000")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure1 + "-" + "000a")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure2 + "-" + "000a")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure3 + "-" + "000a")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure4 + "-" + "000a")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure5 + "-" + "000a")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure6 + "-" + "000a")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure7 + "-" + "000a")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure8 + "-" + "000a")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure1 + "-" + "000A")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure2 + "-" + "000A")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure3 + "-" + "000A")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure4 + "-" + "000A")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure5 + "-" + "000A")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure6 + "-" + "000A")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure7 + "-" + "000A")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure8 + "-" + "000A")); + + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure1 + "-" + "1")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure2 + "-" + "1")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure3 + "-" + "1")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure4 + "-" + "1")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure5 + "-" + "1")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure6 + "-" + "1")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure7 + "-" + "1")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure8 + "-" + "1")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure1 + "-" + "01")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure2 + "-" + "01")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure3 + "-" + "01")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure4 + "-" + "01")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure5 + "-" + "01")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure6 + "-" + "01")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure7 + "-" + "01")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure8 + "-" + "01")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure1 + "-" + "001")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure2 + "-" + "001")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure3 + "-" + "001")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure4 + "-" + "001")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure5 + "-" + "001")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure6 + "-" + "001")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure7 + "-" + "001")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure8 + "-" + "001")); + + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure1 + "-" + _001a)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure2 + "-" + _001a)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure3 + "-" + _001a)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure4 + "-" + _001a)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure5 + "-" + _001a)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure6 + "-" + _001a)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure7 + "-" + _001a)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure8 + "-" + _001a)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure1 + "-" + _001ab)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure2 + "-" + _001ab)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure3 + "-" + _001ab)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure4 + "-" + _001ab)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure5 + "-" + _001ab)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure6 + "-" + _001ab)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure7 + "-" + _001ab)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure8 + "-" + _001ab)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure1 + "-" + _001abc)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure2 + "-" + _001abc)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure3 + "-" + _001abc)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure4 + "-" + _001abc)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure5 + "-" + _001abc)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure6 + "-" + _001abc)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure7 + "-" + _001abc)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure8 + "-" + _001abc)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure1 + "-" + _001abcd)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure2 + "-" + _001abcd)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure3 + "-" + _001abcd)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure4 + "-" + _001abcd)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure5 + "-" + _001abcd)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure6 + "-" + _001abcd)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure7 + "-" + _001abcd)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure8 + "-" + _001abcd)); + + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure1 + "-" + _001A)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure2 + "-" + _001A)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure3 + "-" + _001A)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure4 + "-" + _001A)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure5 + "-" + _001A)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure6 + "-" + _001A)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure7 + "-" + _001A)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure8 + "-" + _001A)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure1 + "-" + _001AB)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure2 + "-" + _001AB)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure3 + "-" + _001AB)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure4 + "-" + _001AB)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure5 + "-" + _001AB)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure6 + "-" + _001AB)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure7 + "-" + _001AB)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure8 + "-" + _001AB)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure1 + "-" + _001ABC)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure2 + "-" + _001ABC)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure3 + "-" + _001ABC)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure4 + "-" + _001ABC)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure5 + "-" + _001ABC)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure6 + "-" + _001ABC)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure7 + "-" + _001ABC)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure8 + "-" + _001ABC)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure1 + "-" + _001ABCD)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure2 + "-" + _001ABCD)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure3 + "-" + _001ABCD)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure4 + "-" + _001ABCD)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure5 + "-" + _001ABCD)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure6 + "-" + _001ABCD)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure7 + "-" + _001ABCD)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure + ":" + deviceStructure8 + "-" + _001ABCD)); + } + + /** + * Test validity of instance index, for device. + */ + @Test + public void isInstanceIndexValidPID() { + // depend on discipline + + // mnemonic paths system structure and device structure + final String systemStructure1 = A + "-" + A + "-" + A; + final String deviceStructure1 = A + "-" + A; + + // mnemonic paths system structure and device structure + final String systemStructure2 = TDS + "-" + TD180; + final String deviceStructure21 = "Mech" + "-" + TDS; + final String deviceStructure22 = "Cryo" + "-" + TDS; + final String deviceStructure23 = "EMR" + "-" + TDS; + final String deviceStructure24 = "HVAC" + "-" + TDS; + final String deviceStructure25 = "Proc" + "-" + TDS; + final String deviceStructure26 = "SC" + "-" + TDS; + final String deviceStructure27 = "Vac" + "-" + TDS; + final String deviceStructure28 = "WtrC" + "-" + TDS; + + final String _001a = "001a"; + final String _001ab = "001ab"; + final String _001abc = "001abc"; + final String _001abcd = "001abcd"; + final String _001A = "001A"; + final String _001AB = "001AB"; + final String _001ABC = "001ABC"; + final String _001ABCD = "001ABCD"; + + assertFalse(namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "0")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "00")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "000")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "0000")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "1")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "01")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "001")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "001")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "0001")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "1001")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "10001")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "abc")); + + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + "000")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + "000")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + "000")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + "000")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + "000")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + "000")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + "000")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + "000")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + "000a")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + "000a")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + "000a")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + "000a")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + "000a")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + "000a")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + "000a")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + "000a")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + "000A")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + "000A")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + "000A")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + "000A")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + "000A")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + "000A")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + "000A")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + "000A")); + + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + "1")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + "1")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + "1")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + "1")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + "1")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + "1")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + "1")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + "1")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + "01")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + "01")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + "01")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + "01")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + "01")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + "01")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + "01")); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + "01")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + "001")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + "001")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + "001")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + "001")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + "001")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + "001")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + "001")); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + "001")); + + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + _001a)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + _001a)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + _001a)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + _001a)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + _001a)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + _001a)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + _001a)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + _001a)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + _001ab)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + _001ab)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + _001ab)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + _001ab)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + _001ab)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + _001ab)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + _001ab)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + _001ab)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + _001abc)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + _001abc)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + _001abc)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + _001abc)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + _001abc)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + _001abc)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + _001abc)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + _001abc)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + _001abcd)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + _001abcd)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + _001abcd)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + _001abcd)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + _001abcd)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + _001abcd)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + _001abcd)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + _001abcd)); + + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + _001A)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + _001A)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + _001A)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + _001A)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + _001A)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + _001A)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + _001A)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + _001A)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + _001AB)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + _001AB)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + _001AB)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + _001AB)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + _001AB)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + _001AB)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + _001AB)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + _001AB)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + _001ABC)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + _001ABC)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + _001ABC)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + _001ABC)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + _001ABC)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + _001ABC)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + _001ABC)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + _001ABC)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + _001ABCD)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + _001ABCD)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + _001ABCD)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + _001ABCD)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + _001ABCD)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + _001ABCD)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + _001ABCD)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + _001ABCD)); + } + + /** + * Test validity of instance index, for device. + */ + @Test + public void isInstanceIndexValidPIDOverride() { + // depend on discipline + // override - length, characters + + // mnemonic paths system structure and device structure + final String systemStructure1 = A + "-" + A + "-" + A; + final String deviceStructure1 = A + "-" + A; + + // mnemonic paths system structure and device structure + final String systemStructure2 = TDS + "-" + TD180; + final String deviceStructure21 = "Mech" + "-" + TDS; + final String deviceStructure22 = "Cryo" + "-" + TDS; + final String deviceStructure23 = "EMR" + "-" + TDS; + final String deviceStructure24 = "HVAC" + "-" + TDS; + final String deviceStructure25 = "Proc" + "-" + TDS; + final String deviceStructure26 = "SC" + "-" + TDS; + final String deviceStructure27 = "Vac" + "-" + TDS; + final String deviceStructure28 = "WtrC" + "-" + TDS; + + final String _001a = "001a"; + final String _001ab = "001ab"; + final String _001abc = "001abc"; + final String _001abcd = "001abcd"; + final String _001A = "001A"; + final String _001AB = "001AB"; + final String _001ABC = "001ABC"; + final String _001ABCD = "001ABCD"; + + assertFalse(namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "0", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "00", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "000", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "0000", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "1", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "01", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "001", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "001", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "0001", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "1001", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "10001", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure1 + ":" + deviceStructure1 + "-" + "abc", true)); + + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + "000", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + "000", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + "000", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + "000", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + "000", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + "000", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + "000", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + "000", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + "000a", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + "000a", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + "000a", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + "000a", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + "000a", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + "000a", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + "000a", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + "000a", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + "000A", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + "000A", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + "000A", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + "000A", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + "000A", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + "000A", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + "000A", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + "000A", true)); + + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + "1", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + "1", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + "1", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + "1", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + "1", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + "1", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + "1", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + "1", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + "01", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + "01", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + "01", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + "01", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + "01", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + "01", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + "01", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + "01", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + "001", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + "001", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + "001", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + "001", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + "001", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + "001", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + "001", true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + "001", true)); + + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + _001a, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + _001a, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + _001a, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + _001a, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + _001a, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + _001a, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + _001a, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + _001a, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + _001ab, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + _001ab, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + _001ab, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + _001ab, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + _001ab, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + _001ab, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + _001ab, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + _001ab, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + _001abc, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + _001abc, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + _001abc, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + _001abc, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + _001abc, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + _001abc, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + _001abc, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + _001abc, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + _001abcd, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + _001abcd, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + _001abcd, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + _001abcd, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + _001abcd, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + _001abcd, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + _001abcd, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + _001abcd, true)); + + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + _001A, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + _001A, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + _001A, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + _001A, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + _001A, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + _001A, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + _001A, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + _001A, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + _001AB, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + _001AB, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + _001AB, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + _001AB, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + _001AB, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + _001AB, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + _001AB, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + _001AB, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + _001ABC, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + _001ABC, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + _001ABC, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + _001ABC, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + _001ABC, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + _001ABC, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + _001ABC, true)); + assertTrue (namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + _001ABC, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure21 + "-" + _001ABCD, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure22 + "-" + _001ABCD, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure23 + "-" + _001ABCD, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure24 + "-" + _001ABCD, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure25 + "-" + _001ABCD, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure26 + "-" + _001ABCD, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure27 + "-" + _001ABCD, true)); + assertFalse(namingConvention.isInstanceIndexValid(systemStructure2 + ":" + deviceStructure28 + "-" + _001ABCD, true)); + } + + // ---------------------------------------------------------------------------------------------------- + // name by itself + // equivalenceClassRepresentative + // ---------------------------------------------------------------------------------------------------- + + /** + * Test of equivalence class representative method. + */ + @Test + public void equivalenceClassRepresentative() { + assertEquals("RFQ-10:EMR-TT-1", namingConvention.equivalenceClassRepresentative("RFQ-010:EMR-TT-001")); + assertEquals("RFQ-10:EMR-TT-10", namingConvention.equivalenceClassRepresentative("RFQ-010:EMR-TT-010")); + assertEquals("RFQ-10:EMR-TT-11", namingConvention.equivalenceClassRepresentative("RFQ-010:EMR-TT-011")); + assertEquals("RFQ-10:EMR-TT-12", namingConvention.equivalenceClassRepresentative("RFQ-010:EMR-TT-012")); + assertEquals("RFQ-10:EMR-TT-13", namingConvention.equivalenceClassRepresentative("RFQ-010:EMR-TT-013")); + assertEquals("RFQ-10:EMR-TT-14", namingConvention.equivalenceClassRepresentative("RFQ-010:EMR-TT-014")); + assertEquals("RFQ-10:EMR-TT-15", namingConvention.equivalenceClassRepresentative("RFQ-010:EMR-TT-015")); + assertEquals("RFQ-10:EMR-TT-16", namingConvention.equivalenceClassRepresentative("RFQ-010:EMR-TT-016")); + assertEquals("RFQ-10:EMR-TT-17", namingConvention.equivalenceClassRepresentative("RFQ-010:EMR-TT-017")); + assertEquals("RFQ-10:EMR-TT-18", namingConvention.equivalenceClassRepresentative("RFQ-010:EMR-TT-018")); + assertEquals("RFQ-10:EMR-TT-19", namingConvention.equivalenceClassRepresentative("RFQ-010:EMR-TT-019")); + + assertEquals( + "PB1-FPM1:CTR1-ECAT-100", + namingConvention.equivalenceClassRepresentative("PBI-FPM01:Ctrl-ECAT-100")); + assertEquals( + "PB1-FPM1:CTR1-ECATC-101", + namingConvention.equivalenceClassRepresentative("PBI-FPM01:Ctrl-ECATC-101")); + assertEquals( + "PB1-FPM1:CTR1-ECATE-101", + namingConvention.equivalenceClassRepresentative("PBI-FPM01:Ctrl-ECATE-101")); + assertEquals( + "PB1-FPM1:CTR1-ECAT10-101", + namingConvention.equivalenceClassRepresentative("PBI-FPM01:Ctrl-ECATIO-101")); + assertEquals( + "PB1-FPM1:CTR1-ECAT10-102", + namingConvention.equivalenceClassRepresentative("PBI-FPM01:Ctrl-ECATIO-102")); + assertEquals( + "PB1-FPM1:CTR1-ECAT10-103", + namingConvention.equivalenceClassRepresentative("PBI-FPM01:Ctrl-ECATIO-103")); + assertEquals( + "PB1-FPM1:CTR1-ECAT10-104", + namingConvention.equivalenceClassRepresentative("PBI-FPM01:Ctrl-ECATIO-104")); + assertEquals( + "PB1-FPM1:CTR1-EVR-101", + namingConvention.equivalenceClassRepresentative("PBI-FPM01:Ctrl-EVR-101")); + assertEquals( + "PB1-FPM1:CTR1-EVR-201", + namingConvention.equivalenceClassRepresentative("PBI-FPM01:Ctrl-EVR-201")); + assertEquals( + "PB1-FPM1:CTR1-1PC-100", + namingConvention.equivalenceClassRepresentative("PBI-FPM01:Ctrl-IPC-100")); + assertEquals( + "PB1-FPM1:CTR1-1PC-200", + namingConvention.equivalenceClassRepresentative("PBI-FPM01:Ctrl-IPC-200")); + } + + /** + * Test of equivalence class representative method for similarity to <tt>1</tt>. + */ + @Test + public void equivalenceClassRepresentativeSimilarTo1() { + assertEquals( + namingConvention.equivalenceClassRepresentative(NUM_1), + namingConvention.equivalenceClassRepresentative(NUM_1)); + assertEquals( + namingConvention.equivalenceClassRepresentative(NUM_1), + namingConvention.equivalenceClassRepresentative("I")); + assertEquals( + namingConvention.equivalenceClassRepresentative(NUM_1), + namingConvention.equivalenceClassRepresentative("l")); + assertEquals( + namingConvention.equivalenceClassRepresentative(NUM_1), + namingConvention.equivalenceClassRepresentative("L")); + assertEquals( + namingConvention.equivalenceClassRepresentative(NUM_1), + namingConvention.equivalenceClassRepresentative("i")); + assertFalse( + namingConvention.equivalenceClassRepresentative(NUM_1).equals( + namingConvention.equivalenceClassRepresentative("b"))); + } + + /** + * Test of equivalence class representative method for similarity to <tt>0</tt>. + */ + @Test + public void equivalenceClassRepresentativeSimilarTo0() { + assertEquals( + namingConvention.equivalenceClassRepresentative(NUM_0), + namingConvention.equivalenceClassRepresentative("o")); + assertEquals( + namingConvention.equivalenceClassRepresentative(NUM_0), + namingConvention.equivalenceClassRepresentative("O")); + assertEquals( + namingConvention.equivalenceClassRepresentative(NUM_0), + namingConvention.equivalenceClassRepresentative(NUM_0)); + assertFalse( + namingConvention.equivalenceClassRepresentative(NUM_0).equals( + namingConvention.equivalenceClassRepresentative("b"))); + } + + /** + * Test of equivalence class representative method for similarity to <tt>V</tt>. + */ + @Test + public void equivalenceClassRepresentativeSimilarToV() { + assertEquals( + namingConvention.equivalenceClassRepresentative("V"), + namingConvention.equivalenceClassRepresentative("v")); + assertEquals( + namingConvention.equivalenceClassRepresentative("V"), + namingConvention.equivalenceClassRepresentative("V")); + assertFalse( + namingConvention.equivalenceClassRepresentative("V1").equals( + namingConvention.equivalenceClassRepresentative("w1"))); + assertFalse( + namingConvention.equivalenceClassRepresentative("V1").equals( + namingConvention.equivalenceClassRepresentative("W1"))); + assertFalse( + namingConvention.equivalenceClassRepresentative("V").equals( + namingConvention.equivalenceClassRepresentative("w"))); + assertFalse( + namingConvention.equivalenceClassRepresentative("V").equals( + namingConvention.equivalenceClassRepresentative("W"))); + assertFalse( + namingConvention.equivalenceClassRepresentative("V").equals( + namingConvention.equivalenceClassRepresentative("b"))); + } + + /** + * Test of equivalence class representative method for lower and upper case characters. + */ + @Test + public void equivalenceClassRepresentativeLowerAndUpperCaseCharacters() { + assertEquals( + namingConvention.equivalenceClassRepresentative("tEsTS"), + namingConvention.equivalenceClassRepresentative("TeSts")); + } + + /** + * Test of equivalence class representative method for zero prefixed number. + */ + @Test + public void equivalenceClassRepresentativeZeroPrefixedNumber() { + assertEquals( + namingConvention.equivalenceClassRepresentative("01"), + namingConvention.equivalenceClassRepresentative("001")); + assertEquals( + namingConvention.equivalenceClassRepresentative("zero01"), + namingConvention.equivalenceClassRepresentative("zero1")); + assertEquals( + namingConvention.equivalenceClassRepresentative("ze01ro"), + namingConvention.equivalenceClassRepresentative("ze1ro")); + } + + /** + * Test of equivalence class representative method for zero after alpha character. + */ + @Test + public void equivalenceClassRepresentativeZeroAfterAlphaCharacter() { + assertEquals( + namingConvention.equivalenceClassRepresentative("Sub0001"), + namingConvention.equivalenceClassRepresentative("Sub1")); + assertEquals( + namingConvention.equivalenceClassRepresentative("01Sub001"), + namingConvention.equivalenceClassRepresentative("01Sub1")); + } + + /** + * Test of equivalence class representative method for chained calls to get equivalence class. + */ + @Test + public void equivalenceClassRepresentativeTwiceEquivalence() { + // note that of 2 chained calls to equivalenceClassRepresentative, 2nd call may modify + // <==> 2nd output not same as 1st output + assertEquals( + "CRS-T1CP:CRY0-XZ-XXXXX1", + namingConvention.equivalenceClassRepresentative("CrS-TICP:Cryo-XZ-XXXXX1")); + assertEquals( + "CRS-T1CP:CRY-XZ-XXXXX1", + namingConvention.equivalenceClassRepresentative("CRS-T1CP:CRY0-XZ-XXXXX1")); + assertEquals("CRY0", namingConvention.equivalenceClassRepresentative("Cryo")); + assertEquals("CRY", namingConvention.equivalenceClassRepresentative("CRY0")); + } + + /** + * Test of equivalence class representative method for device type. + */ + @Test + public void equivalenceClassRepresentativeDeviceType() { + // note handling of trailing zeroes + assertEquals(ECAT10, namingConvention.equivalenceClassRepresentative("ECATIO")); + assertEquals("ECAT1", namingConvention.equivalenceClassRepresentative("ECATI0")); + assertEquals(ECAT10, namingConvention.equivalenceClassRepresentative(ECAT10)); + } + + /** + * Test validity of mnemonic path. + */ + @Test + public void isMnemonicPathValid() { + assertFalse(namingConvention.isMnemonicPathValid(NULL)); + assertFalse(namingConvention.isMnemonicPathValid(EMPTY)); + assertFalse(namingConvention.isMnemonicPathValid(SPACE)); + + assertTrue (namingConvention.isMnemonicPathValid("A")); + assertTrue (namingConvention.isMnemonicPathValid("A-B")); + assertTrue (namingConvention.isMnemonicPathValid("A-B-C")); + assertFalse(namingConvention.isMnemonicPathValid("A-B-C-D")); + + assertFalse(namingConvention.isMnemonicPathValid("A-A")); + assertFalse(namingConvention.isMnemonicPathValid("A-A-A")); + assertFalse(namingConvention.isMnemonicPathValid("A-A-B")); + assertFalse(namingConvention.isMnemonicPathValid("A-B-A")); + assertFalse(namingConvention.isMnemonicPathValid("B-A-A")); + } + +} diff --git a/src/test/java/org/openepics/names/util/NameElementUtilTest.java b/src/test/java/org/openepics/names/util/NameElementUtilTest.java new file mode 100644 index 0000000..569d3e0 --- /dev/null +++ b/src/test/java/org/openepics/names/util/NameElementUtilTest.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2021 European Spallation Source ERIC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.openepics.names.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +import org.junit.jupiter.api.Test; +import org.openepics.names.repository.model.Name; +import org.openepics.names.rest.beans.NameElement; +import org.openepics.names.rest.beans.Status; + +/** + * Unit tests for NameElementUtil class. + * + * @author Lars Johansson + * + * @see NameElementUtil + */ +public class NameElementUtilTest { + + /** + * Test of get name element for name. + */ + @Test + public void getNameElement() { + NameElement nameElement = NameElementUtil.getNameElement(null); + assertNull(nameElement); + + Name name = new Name(); + nameElement = NameElementUtil.getNameElement(name); + + assertNotNull(nameElement); + assertEquals(null, nameElement.getUuid()); + assertEquals(null, nameElement.getSystemgroup()); + assertEquals(null, nameElement.getSystem()); + assertEquals(null, nameElement.getSubsystem()); + assertEquals(null, nameElement.getDevicetype()); + assertEquals(null, nameElement.getSystemstructure()); + assertEquals(null, nameElement.getDevicestructure()); + assertEquals(null, nameElement.getIndex()); + assertEquals(null, nameElement.getName()); + assertEquals(null, nameElement.getDescription()); + assertEquals(Status.APPROVED, nameElement.getStatus()); + assertEquals(null, nameElement.isLatest()); + assertEquals(null, nameElement.isDeleted()); + assertEquals(null, nameElement.getWhen()); + assertEquals(null, nameElement.getWho()); + assertEquals(null, nameElement.getComment()); + } + + /** + * Test of get name element for content. + */ + @Test + public void getNameElementContent() { + NameElement nameElement = NameElementUtil.getNameElement( + null, + null, null, null, null, + null, null, + null, null, + null, null, null, null, + null, null, null); + + assertNotNull(nameElement); + assertEquals(null, nameElement.getUuid()); + assertEquals(null, nameElement.getSystemgroup()); + assertEquals(null, nameElement.getSystem()); + assertEquals(null, nameElement.getSubsystem()); + assertEquals(null, nameElement.getDevicetype()); + assertEquals(null, nameElement.getSystemstructure()); + assertEquals(null, nameElement.getDevicestructure()); + assertEquals(null, nameElement.getIndex()); + assertEquals(null, nameElement.getName()); + assertEquals(null, nameElement.getDescription()); + assertEquals(null, nameElement.getStatus()); + assertEquals(null, nameElement.isLatest()); + assertEquals(null, nameElement.isDeleted()); + assertEquals(null, nameElement.getWhen()); + assertEquals(null, nameElement.getWho()); + assertEquals(null, nameElement.getComment()); + } + +} diff --git a/src/test/java/org/openepics/names/util/StructureElementUtilTest.java b/src/test/java/org/openepics/names/util/StructureElementUtilTest.java new file mode 100644 index 0000000..b0fca7e --- /dev/null +++ b/src/test/java/org/openepics/names/util/StructureElementUtilTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2021 European Spallation Source ERIC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.openepics.names.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.openepics.names.rest.beans.StructureElement; + +/** + * Unit tests for StructureElementUtil class. + * + * @author Lars Johansson + * + * @see StructureElementUtil + */ +public class StructureElementUtilTest { + + /** + * Test of get structure element for content. + */ + @Test + public void getStructureElementContent() { + StructureElement structureElement = StructureElementUtil.getStructureElement( + null, + null, + null, + null, null, null, null, + null, null, null, null, + null, null, null); + + assertNotNull(structureElement); + assertEquals(null, structureElement.getType()); + assertEquals(null, structureElement.getUuid()); + assertEquals(null, structureElement.getParent()); + assertEquals(null, structureElement.getName()); + assertEquals(null, structureElement.getMnemonic()); + assertEquals(null, structureElement.getMnemonicpath()); + assertEquals(null, structureElement.getLevel()); + assertEquals(null, structureElement.getDescription()); + assertEquals(null, structureElement.getStatus()); + assertEquals(null, structureElement.isLatest()); + assertEquals(null, structureElement.isDeleted()); + assertEquals(null, structureElement.getWhen()); + assertEquals(null, structureElement.getWho()); + assertEquals(null, structureElement.getComment()); + } + + @Test + public void equals() { + StructureElement se1 = new StructureElement(); + StructureElement se2 = new StructureElement(); + + // Field[] fields = se1.getClass().getFields(); + // Field[] declaredFields = se1.getClass().getDeclaredFields(); + // + // Field[] superclass_fields = se1.getClass().getSuperclass().getFields(); + // Field[] superclass_declaredFields = se1.getClass().getSuperclass().getDeclaredFields(); + // + // for (Field field : fields) { + // System.out.println("fields.field.getName: " + field.getName()); + // } + // System.out.println("-----------------------------------------"); + // for (Field field : declaredFields) { + // System.out.println("declaredFields.field.getName: " + field.getName()); + // } + // System.out.println("-----------------------------------------"); + // for (Field field : superclass_fields) { + // System.out.println("superclass_fields.field.getName: " + field.getName()); + // } + // // LOGGER.log(Level.INFO, "-----------------------------------------"); + // System.out.println("-----------------------------------------"); + // for (Field field : superclass_declaredFields) { + // System.out.println("superclass_declaredFields.field.getName: " + field.getName()); + // } + + assertTrue(se1.equals(se2)); + } + +} diff --git a/src/test/java/org/openepics/names/util/ValidateUtilTest.java b/src/test/java/org/openepics/names/util/ValidateUtilTest.java new file mode 100644 index 0000000..cf32a4a --- /dev/null +++ b/src/test/java/org/openepics/names/util/ValidateUtilTest.java @@ -0,0 +1,407 @@ +/* + * Copyright (c) 2021 European Spallation Source ERIC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.openepics.names.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +import java.util.List; +import java.util.UUID; + +import org.junit.jupiter.api.Test; +import org.openepics.names.repository.model.Subsystem; +import org.openepics.names.rest.beans.Type; +import org.springframework.http.HttpStatus; + +import com.google.common.collect.Lists; + +/** + * Unit tests for ValidateUtil class. + * + * @author Lars Johansson + * + * @see ValidateUtil + */ +public class ValidateUtilTest { + + /** + * Test of validate input comment. + */ + @Test + public void validateInputCommentNull() { + try { + ValidateUtil.validateInputComment(null); + fail(); + } catch (ServiceHttpStatusException e) { + assertEquals(HttpStatus.BAD_REQUEST, e.getHttpStatus()); + assertEquals("comment is not available", e.getMessage()); + assertEquals(null, e.getCause()); + } + } + /** + * Test of validate input comment. + */ + @Test + public void validateInputCommentEmpty() { + try { + ValidateUtil.validateInputComment(""); + fail(); + } catch (ServiceHttpStatusException e) { + assertEquals(HttpStatus.BAD_REQUEST, e.getHttpStatus()); + assertEquals("comment is not available", e.getMessage()); + assertEquals(null, e.getCause()); + } + } + /** + * Test of validate input comment. + */ + @Test + public void validateInputComment() { + ValidateUtil.validateInputComment("asdf"); + } + + /** + * Test of validate input description. + */ + @Test + public void validateInputDescriptionNull() { + try { + ValidateUtil.validateInputDescription(null); + fail(); + } catch (ServiceHttpStatusException e) { + assertEquals(HttpStatus.BAD_REQUEST, e.getHttpStatus()); + assertEquals("description is not available", e.getMessage()); + assertEquals(null, e.getCause()); + } + } + /** + * Test of validate input description. + */ + @Test + public void validateInputDescriptionEmpty() { + try { + ValidateUtil.validateInputDescription(""); + fail(); + } catch (ServiceHttpStatusException e) { + assertEquals(HttpStatus.BAD_REQUEST, e.getHttpStatus()); + assertEquals("description is not available", e.getMessage()); + assertEquals(null, e.getCause()); + } + } + /** + * Test of validate input description. + */ + @Test + public void validateInputDescription() { + ValidateUtil.validateInputDescription("asdf"); + } + + /** + * Test of validate input mnemonic. + */ + @Test + public void validateInputMnemonicNull() { + try { + ValidateUtil.validateInputMnemonic(null); + fail(); + } catch (ServiceHttpStatusException e) { + assertEquals(HttpStatus.BAD_REQUEST, e.getHttpStatus()); + assertEquals("mnemonic is not available", e.getMessage()); + assertEquals(null, e.getCause()); + } + } + /** + * Test of validate input mnemonic. + */ + @Test + public void validateInputMnemonicEmpty() { + try { + ValidateUtil.validateInputMnemonic(""); + fail(); + } catch (ServiceHttpStatusException e) { + assertEquals(HttpStatus.BAD_REQUEST, e.getHttpStatus()); + assertEquals("mnemonic is not available", e.getMessage()); + assertEquals(null, e.getCause()); + } + } + /** + * Test of validate input mnemonic. + */ + @Test + public void validateInputMnemonic() { + ValidateUtil.validateInputMnemonic("asdf"); + } + + /** + * Test of validate input name. + */ + @Test + public void validateInputNameNull() { + try { + ValidateUtil.validateInputName(null); + fail(); + } catch (ServiceHttpStatusException e) { + assertEquals(HttpStatus.BAD_REQUEST, e.getHttpStatus()); + assertEquals("name is not available", e.getMessage()); + assertEquals(null, e.getCause()); + } + } + /** + * Test of validate input name. + */ + @Test + public void validateInputNameEmpty() { + try { + ValidateUtil.validateInputName(""); + fail(); + } catch (ServiceHttpStatusException e) { + assertEquals(HttpStatus.BAD_REQUEST, e.getHttpStatus()); + assertEquals("name is not available", e.getMessage()); + assertEquals(null, e.getCause()); + } + } + /** + * Test of validate input name. + */ + @Test + public void validateInputName() { + ValidateUtil.validateInputName("asdf"); + } + + /** + * Test of validate input type. + */ + @Test + public void validateInputTypeNull() { + try { + ValidateUtil.validateInputType(null); + fail(); + } catch (ServiceHttpStatusException e) { + assertEquals(HttpStatus.BAD_REQUEST, e.getHttpStatus()); + assertEquals("type is not available", e.getMessage()); + assertEquals(null, e.getCause()); + } + } + /** + * Test of validate input type. + */ + @Test + public void validateInputType() { + ValidateUtil.validateInputType(Type.SYSTEMGROUP); + ValidateUtil.validateInputType(Type.SYSTEM); + ValidateUtil.validateInputType(Type.SUBSYSTEM); + ValidateUtil.validateInputType(Type.DISCIPLINE); + ValidateUtil.validateInputType(Type.DEVICEGROUP); + ValidateUtil.validateInputType(Type.DEVICETYPE); + } + + /** + * Test of validate input uuid. + */ + @Test + public void validateInputUuidNull() { + try { + ValidateUtil.validateInputUuid(null); + fail(); + } catch (ServiceHttpStatusException e) { + assertEquals(HttpStatus.BAD_REQUEST, e.getHttpStatus()); + assertEquals("uuid is not available", e.getMessage()); + assertEquals(null, e.getCause()); + } + } + /** + * Test of validate input uuid. + */ + @Test + public void validateInputUuidEmpty() { + try { + ValidateUtil.validateInputUuid(""); + fail(); + } catch (ServiceHttpStatusException e) { + assertEquals(HttpStatus.BAD_REQUEST, e.getHttpStatus()); + assertEquals("uuid is not available", e.getMessage()); + assertEquals(null, e.getCause()); + } + } + /** + * Test of validate input uuid. + */ + @Test + public void validateInputUuid() { + ValidateUtil.validateInputUuid(UUID.randomUUID().toString()); + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * Test of validate input read names. + */ + @Test + public void validateInputReadNames() { + ValidateUtil.validateNamesInputRead( + null, null, null, + null, + null, null, + null, null); + } + + /** + * Test of validate input create name element. + */ + @Test + public void validateInputCreateNameElement() { + ValidateUtil.validateNameElementInputCreate(null); + } + + /** + * Test of validate data create name element. + */ + @Test + public void validateDataCreateNameElement() { + ValidateUtil.validateNameElementDataCreate(null, null, null, null, null); + } + + /** + * Test of validate data create name. + */ + @Test + public void validateDataCreateName() { + ValidateUtil.validateNameDataCreate(null, null, null, null, null); + } + /** + * Test of validate input update name element. + */ + @Test + public void validateInputUpdateNameElement() { + ValidateUtil.validateNameElementInputUpdate(null); + } + + /** + * Test of validate data update name element. + */ + @Test + public void validateDataUpdateNameElement() { + ValidateUtil.validateNameElementDataUpdate(null, null, null, null, null); + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * Test of validate input read structures. + */ + @Test + public void validateInputReadStructuresTypeNull() { + try { + ValidateUtil.validateStructuresInputRead( + null, null, null, null, null, + null, + null, null, + null, null); + fail(); + } catch (ServiceHttpStatusException e) { + assertEquals(HttpStatus.BAD_REQUEST, e.getHttpStatus()); + assertEquals("type is not available", e.getMessage()); + assertEquals(null, e.getCause()); + } + } + + /** + * Test of validate input read structures. + */ + @Test + public void validateInputReadStructures() { + ValidateUtil.validateStructuresInputRead( + Type.SYSTEMGROUP, null, null, null, null, + null, + null, null, + null, null); + ValidateUtil.validateStructuresInputRead( + Type.SYSTEM, null, null, null, null, + null, + null, null, + null, null); + ValidateUtil.validateStructuresInputRead( + Type.SUBSYSTEM, null, null, null, null, + null, + null, null, + null, null); + ValidateUtil.validateStructuresInputRead( + Type.DISCIPLINE, null, null, null, null, + null, + null, null, + null, null); + ValidateUtil.validateStructuresInputRead( + Type.DEVICEGROUP, null, null, null, null, + null, + null, null, + null, null); + ValidateUtil.validateStructuresInputRead( + Type.DEVICETYPE, null, null, null, null, + null, + null, null, + null, null); + } + + /** + * Test of validate data create structure element. + */ + @Test + public void validateDataCreateStructureElement() { + ValidateUtil.validateStructureElementDataCreate(null, null, null, null); + } + + /** + * Test of validate data create structure. + */ + @Test + public void validateDataCreateStructuret() { + ValidateUtil.validateStructureDataCreate(null, null, null, null, null); + } + + /** + * Test of validate input update structure element. + */ + @Test + public void validateInputUpdateStructureElement() { + ValidateUtil.validateStructureElementInputUpdate(null); + } + + /** + * Test of validate data update structure element. + */ + @Test + public void validateDataUpdateStructureElement() { + ValidateUtil.validateStructureElementDataUpdate(null, null, null, null); + } + + @Test + public void validateDummy() { + final List<Subsystem> subsystems = Lists.newArrayList(); + try { + ValidateUtil.validateCondition(subsystems != null && subsystems.size() == 1, HttpStatus.INTERNAL_SERVER_ERROR, + ValidateUtil.SUBSYSTEM + ValidateUtil.SPACE + ValidateUtil.IS_NOT_CORRECT, null); + fail(); + } catch (ServiceHttpStatusException e) { + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, e.getHttpStatus()); + assertEquals("subsystem is not correct", e.getMessage()); + assertEquals(null, e.getCause()); + } + } + +} -- GitLab