ref #7887 Implement term service methods based on DTOs
authorPatrick Plitzner <p.plitzner@bgbm.org>
Fri, 9 Nov 2018 08:18:11 +0000 (09:18 +0100)
committerPatrick Plitzner <p.plitzner@bgbm.org>
Fri, 9 Nov 2018 08:18:11 +0000 (09:18 +0100)
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/common/IDefinedTermDao.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/common/ITermVocabularyDao.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/common/DefinedTermDaoImpl.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/common/TermVocabularyDaoImpl.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dto/AbstractTermDto.java [new file with mode: 0644]
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dto/TermDto.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dto/TermVocabularyDto.java [new file with mode: 0644]
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/ITermService.java
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/IVocabularyService.java
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/TermServiceImpl.java
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/VocabularyServiceImpl.java

index 6ad26ca5b138361b7f3f24a0f117ad9890edfdb7..9e64121e5919f76e7aa33daaae08e87d95ff2928 100644 (file)
@@ -27,6 +27,7 @@ import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
 import eu.etaxonomy.cdm.model.location.NamedAreaType;
 import eu.etaxonomy.cdm.model.media.Media;
 import eu.etaxonomy.cdm.persistence.dao.initializer.IBeanInitializer;
+import eu.etaxonomy.cdm.persistence.dto.TermDto;
 import eu.etaxonomy.cdm.persistence.query.OrderHint;
 
 
@@ -205,4 +206,26 @@ public interface IDefinedTermDao extends IIdentifiableDao<DefinedTermBase>, ITit
      */
     public List<NamedArea> getUuidAndTitleCache(List<TermVocabulary> vocs, Integer limit,
             String pattern);
+
+    /**
+     * Returns the parent term of the given term
+     * @param childTerm the child term
+     * @return the parent term
+     */
+    public TermDto getParentAsDto(TermDto childTerm);
+
+    /**
+     * Returns all terms that are included in the given parent term resp. a part of the given term.
+     * @param parentTerm the parent term
+     * @return a collection of included terms
+     */
+    public Collection<TermDto> getIncludesAsDto(TermDto parentTerm);
+
+    /**
+     * Returns all terms that the given term is a generalization of resp. that are a kind of the given term
+     * @param parentTerm the parent term
+     * @return a collection of included terms
+     */
+    public Collection<TermDto> getKindOfsAsDto(TermDto parentTerm);
+
 }
index 5c9260c3a8e063aec24b60fe9182467d72bc5d5e..53630f5ad70e36753630475be239715382bdd2df 100644 (file)
@@ -10,6 +10,7 @@
 package eu.etaxonomy.cdm.persistence.dao.common;
 
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -18,6 +19,8 @@ import java.util.UUID;
 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
 import eu.etaxonomy.cdm.model.common.TermType;
 import eu.etaxonomy.cdm.model.common.TermVocabulary;
+import eu.etaxonomy.cdm.persistence.dto.TermDto;
+import eu.etaxonomy.cdm.persistence.dto.TermVocabularyDto;
 import eu.etaxonomy.cdm.persistence.query.OrderHint;
 
 
@@ -102,4 +105,19 @@ public interface ITermVocabularyDao extends IIdentifiableDao<TermVocabulary> {
                        Map<UUID, Set<UUID>> uuidsRepsonse,
                        Map<UUID, TermVocabulary<?>> vocabularyResponse);
 
+    /**
+     * Loads all top level terms, i.e. terms that have no parent terms, for the given vocabulary
+     * @param vocabularyUuid the id of the vocabulary
+     * @return a collection of top level terms
+     */
+    public Collection<TermDto> getTopLevelTerms(UUID vocabularyUuid);
+
+    /**
+     * Returns term vocabularies that contain terms of a certain {@link TermType} e.g. Feature, Modifier, State.
+     *
+     * @param termType the {@link TermType} of the terms in the vocabulary and of the vocabulary
+     * @return a list of term vocabularies
+     */
+    public List<TermVocabularyDto> findVocabularyDtoByTermType(TermType termType);
+
 }
index 5a7e9a2698c44921ce00f1e9e26d3a1748892bb5..b3aedfbeec48adc509aa73ddeb291107394f2376 100644 (file)
@@ -63,6 +63,7 @@ import eu.etaxonomy.cdm.model.taxon.SynonymType;
 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
 import eu.etaxonomy.cdm.model.view.AuditEvent;
 import eu.etaxonomy.cdm.persistence.dao.common.IDefinedTermDao;
+import eu.etaxonomy.cdm.persistence.dto.TermDto;
 import eu.etaxonomy.cdm.persistence.query.MatchMode;
 import eu.etaxonomy.cdm.persistence.query.OrderHint;
 
@@ -665,5 +666,52 @@ public class DefinedTermDaoImpl extends IdentifiableDaoBase<DefinedTermBase> imp
         return result;
     }
 
+    @Override
+    public TermDto getParentAsDto(TermDto childTerm) {
+        String queryString = TermDto.getTermDtoSelect()
+                + "where a.uuid = :childUuid";
+
+        Query query =  getSession().createQuery(queryString);
+        query.setParameter("childUuid", childTerm.getUuid());
+
+        @SuppressWarnings("unchecked")
+        List<Object[]> result = query.list();
+
+        List<TermDto> list = TermDto.termDtoListFrom(result);
+        if(list.size()==1){
+            return list.get(0);
+        }
+        return null;
+    }
+
+    @Override
+    public Collection<TermDto> getIncludesAsDto(
+            TermDto parentTerm) {
+        String queryString = TermDto.getTermDtoSelect()
+                + "where a.partOf.uuid = :parentUuid";
+        Query query =  getSession().createQuery(queryString);
+        query.setParameter("parentUuid", parentTerm.getUuid());
+
+        @SuppressWarnings("unchecked")
+        List<Object[]> result = query.list();
+
+        List<TermDto> list = TermDto.termDtoListFrom(result);
+        return list;
+    }
+
+    @Override
+    public Collection<TermDto> getKindOfsAsDto(
+            TermDto parentTerm) {
+        String queryString = TermDto.getTermDtoSelect()
+                + "where a.kindOf.uuid = :parentUuid";
+        Query query =  getSession().createQuery(queryString);
+        query.setParameter("parentUuid", parentTerm.getUuid());
+
+        @SuppressWarnings("unchecked")
+        List<Object[]> result = query.list();
+
+        List<TermDto> list = TermDto.termDtoListFrom(result);
+        return list;
+    }
 
 }
index 74a4ded941e57c164fa397d6860f31576367d7d9..3ad64b67a98ed8342cced7a6bf1c7acf72356b30 100644 (file)
@@ -11,6 +11,7 @@ package eu.etaxonomy.cdm.persistence.dao.hibernate.common;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -26,10 +27,13 @@ import org.springframework.stereotype.Repository;
 
 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
 import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;
+import eu.etaxonomy.cdm.model.common.Representation;
 import eu.etaxonomy.cdm.model.common.TermType;
 import eu.etaxonomy.cdm.model.common.TermVocabulary;
 import eu.etaxonomy.cdm.model.view.AuditEvent;
 import eu.etaxonomy.cdm.persistence.dao.common.ITermVocabularyDao;
+import eu.etaxonomy.cdm.persistence.dto.TermDto;
+import eu.etaxonomy.cdm.persistence.dto.TermVocabularyDto;
 import eu.etaxonomy.cdm.persistence.query.OrderHint;
 
 /**
@@ -106,7 +110,7 @@ public class TermVocabularyDaoImpl extends IdentifiableDaoBase<TermVocabulary> i
                return result;
                } else {
                        @SuppressWarnings("unchecked")
-            AuditQuery query = makeAuditQuery((Class)clazz, auditEvent);
+            AuditQuery query = makeAuditQuery(clazz, auditEvent);
                        query.add(AuditEntity.property("termSourceUri").eq(termSourceUri));
 
                        @SuppressWarnings("unchecked")
@@ -242,4 +246,52 @@ public class TermVocabularyDaoImpl extends IdentifiableDaoBase<TermVocabulary> i
                return;
        }
 
+    @Override
+    public Collection<TermDto> getTopLevelTerms(UUID vocabularyUuid) {
+        String queryString = TermDto.getTermDtoSelect()
+                + "where v.uuid = :vocabularyUuid "
+                + "and a.partOf is null "
+                + "and a.kindOf is null";
+        Query query =  getSession().createQuery(queryString);
+        query.setParameter("vocabularyUuid", vocabularyUuid);
+
+        @SuppressWarnings("unchecked")
+        List<Object[]> result = query.list();
+
+        List<TermDto> list = TermDto.termDtoListFrom(result);
+        return list;
+    }
+
+    @Override
+    public List<TermVocabularyDto> findVocabularyDtoByTermType(TermType termType) {
+        String queryString = ""
+                + "select v.uuid, r "
+                + "from TermVocabulary as v LEFT JOIN v.representations AS r "
+                + "where v.termType = :termType "
+                ;
+        Query query =  getSession().createQuery(queryString);
+        query.setParameter("termType", termType);
+
+        @SuppressWarnings("unchecked")
+        List<Object[]> result = query.list();
+
+        Map<UUID, TermVocabularyDto> dtoMap = new HashMap<>(result.size());
+        for (Object[] elements : result) {
+            UUID uuid = (UUID)elements[0];
+            if(dtoMap.containsKey(uuid)){
+                dtoMap.get(uuid).addRepresentation((Representation)elements[1]);
+            } else {
+                Set<Representation> representations = new HashSet<>();
+                if(elements[1] instanceof Representation) {
+                    representations = new HashSet<Representation>(1);
+                    representations.add((Representation)elements[1]);
+                } else {
+                    representations = (Set<Representation>)elements[1];
+                }
+                dtoMap.put(uuid, new TermVocabularyDto(uuid, representations));
+            }
+        }
+        return new ArrayList<>(dtoMap.values());
+    }
+
 }
diff --git a/cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dto/AbstractTermDto.java b/cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dto/AbstractTermDto.java
new file mode 100644 (file)
index 0000000..1ad379c
--- /dev/null
@@ -0,0 +1,132 @@
+// $Id$
+/**
+* Copyright (C) 2018 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.cdm.persistence.dto;
+
+import java.io.Serializable;
+import java.net.URI;
+import java.util.Set;
+import java.util.UUID;
+
+import eu.etaxonomy.cdm.model.common.Representation;
+import eu.etaxonomy.cdm.model.common.TermType;
+
+/**
+ * @author pplitzner
+ * @date 05.11.2018
+ *
+ */
+public class AbstractTermDto implements Serializable {
+
+    private static final long serialVersionUID = -7160319884811828125L;
+
+    private final UUID uuid;
+    private URI uri;
+    private TermType termType;
+    private final Set<Representation> representations;
+    private String representation_L10n = null;
+    private String representation_L10n_abbreviatedLabel = null;
+
+    public AbstractTermDto(UUID uuid, Set<Representation> representations) {
+        this.representations = representations;
+        this.uuid = uuid;
+    }
+
+    /**
+     *
+     * @param representation_L10n a blank instance of ITermRepresentation_L10n
+     *   created by the  default constructor
+     */
+    public void localize(ITermRepresentation_L10n representation_L10n) {
+
+        representation_L10n.localize(representations);
+        if (representation_L10n.getLabel() != null) {
+            setRepresentation_L10n(representation_L10n.getLabel());
+        }
+        if (representation_L10n.getAbbreviatedLabel() != null) {
+            setRepresentation_L10n_abbreviatedLabel(representation_L10n.getAbbreviatedLabel());
+        }
+    }
+
+    public URI getUri() {
+        return uri;
+    }
+
+    public void setUri(URI uri) {
+        this.uri = uri;
+    }
+
+    public TermType getTermType() {
+        return termType;
+    }
+
+    public void setTermType(TermType termType) {
+        this.termType = termType;
+    }
+
+    public String getRepresentation_L10n() {
+        return representation_L10n;
+    }
+
+    public void setRepresentation_L10n(String representation_L10n) {
+        this.representation_L10n = representation_L10n;
+    }
+
+    public void addRepresentation(Representation representation) {
+        representations.add(representation);
+
+    }
+
+    public String getRepresentation_L10n_abbreviatedLabel() {
+        return representation_L10n_abbreviatedLabel;
+    }
+
+    public void setRepresentation_L10n_abbreviatedLabel(String representation_L10n_abbreviatedLabel) {
+        this.representation_L10n_abbreviatedLabel = representation_L10n_abbreviatedLabel;
+    }
+
+    public UUID getUuid() {
+        return uuid;
+    }
+
+    public Set<Representation> getRepresentations() {
+        return representations;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        AbstractTermDto other = (AbstractTermDto) obj;
+        if (uuid == null) {
+            if (other.uuid != null) {
+                return false;
+            }
+        } else if (!uuid.equals(other.uuid)) {
+            return false;
+        }
+        return true;
+    }
+
+}
index 185447fb2156345fe9a264c8993d1aff7eb3a96d..5e5350315d425a425dca2291d0f1722f40273c25 100644 (file)
@@ -8,6 +8,12 @@
 */
 package eu.etaxonomy.cdm.persistence.dto;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
 
@@ -19,29 +25,34 @@ import eu.etaxonomy.cdm.model.location.NamedArea;
  * @since Mar 25, 2015
  *
  */
-public class TermDto {
+public class TermDto extends AbstractTermDto{
 
+    private static final long serialVersionUID = 5627308906985438034L;
 
-    private final UUID uuid;
+    private UUID kindOfUuid = null;
     private UUID partOfUuid = null;
     private UUID vocabularyUuid = null;
     private Integer orderIndex = null;
-    private final Set<Representation> representations;
-    private String representation_L10n = null;
-    private String representation_L10n_abbreviatedLabel = null;
+    private String idInVocabulary = null;
+    private Collection<TermDto> includes;
+    private Collection<TermDto> generalizationOf;
 
     public TermDto(UUID uuid, Set<Representation> representations, Integer orderIndex) {
-        this.representations = representations;
-        this.uuid = uuid;
+        super(uuid, representations);
         this.setOrderIndex(orderIndex);
     }
 
     public TermDto(UUID uuid, Set<Representation> representations, UUID partOfUuid, UUID vocabularyUuid, Integer orderIndex) {
-        this.representations = representations;
-        this.uuid = uuid;
+        this(uuid, representations, partOfUuid, null, vocabularyUuid, orderIndex, null);
+    }
+
+    public TermDto(UUID uuid, Set<Representation> representations, UUID partOfUuid, UUID kindOfUuid, UUID vocabularyUuid, Integer orderIndex, String idInVocabulary) {
+        super(uuid, representations);
         this.partOfUuid = partOfUuid;
+        this.kindOfUuid = kindOfUuid;
         this.vocabularyUuid = vocabularyUuid;
         this.orderIndex = orderIndex;
+        this.idInVocabulary = idInVocabulary;
     }
 
     static public TermDto fromNamedArea(NamedArea namedArea) {
@@ -49,100 +60,82 @@ public class TermDto {
         return dto;
     }
 
-    /**
-     *
-     * @param representation_L10n a blank instance of ITermRepresentation_L10n
-     *   created by the  default constructor
-     */
-    public void localize(ITermRepresentation_L10n representation_L10n) {
-
-        representation_L10n.localize(representations);
-        if (representation_L10n.getLabel() != null) {
-            setRepresentation_L10n(representation_L10n.getLabel());
-        }
-        if (representation_L10n.getAbbreviatedLabel() != null) {
-            setRepresentation_L10n_abbreviatedLabel(representation_L10n.getAbbreviatedLabel());
-        }
+    public UUID getVocabularyUuid() {
+        return vocabularyUuid;
     }
 
-    /**
-     * @return the uuid
-     */
-    public UUID getUuid() {
-        return uuid;
+    public void setVocabularyUuid(UUID vocabularyUuid) {
+        this.vocabularyUuid = vocabularyUuid;
     }
 
-    /**
-     * @return the representation_L10n
-     */
-    public String getRepresentation_L10n() {
-        return representation_L10n;
+    public UUID getPartOfUuid() {
+        return partOfUuid;
     }
 
-    /**
-     * @param representation_L10n the representation_L10n to set
-     */
-    public void setRepresentation_L10n(String representation_L10n) {
-        this.representation_L10n = representation_L10n;
+    public UUID getKindOfUuid() {
+        return kindOfUuid;
     }
 
-    /**
-     * @param representation_L10n_abbreviatedLabel the representation_L10n_abbreviatedLabel to set
-     */
-    public void setRepresentation_L10n_abbreviatedLabel(String representation_L10n_abbreviatedLabel) {
-        this.representation_L10n_abbreviatedLabel = representation_L10n_abbreviatedLabel;
+    public Integer getOrderIndex() {
+        return orderIndex;
     }
 
-    /**
-     * @return the representation_L10n_abbreviatedLabel
-     */
-    public String getRepresentation_L10n_abbreviatedLabel() {
-        return representation_L10n_abbreviatedLabel;
+    public void setOrderIndex(Integer orderIndex) {
+        this.orderIndex = orderIndex;
     }
 
-    /**
-     * @return the vocabularyUuid
-     */
-    public UUID getVocabularyUuid() {
-        return vocabularyUuid;
+    public String getIdInVocabulary() {
+        return idInVocabulary;
     }
 
-    /**
-     * @param vocabularyUuid the vocabularyUuid to set
-     */
-    public void setVocabularyUuid(UUID vocabularyUuid) {
-        this.vocabularyUuid = vocabularyUuid;
+    public void setIdInVocabulary(String idInVocabulary) {
+        this.idInVocabulary = idInVocabulary;
     }
 
-    /**
-     * @return the partOfUuid
-     */
-    public UUID getPartOfUuid() {
-        return partOfUuid;
+    public Collection<TermDto> getIncludes() {
+        return includes;
     }
 
-    /**
-     * @param representation
-     */
-    public void addRepresentation(Representation representation) {
-        representations.add(representation);
-
+    public void setIncludes(Collection<TermDto> includes) {
+        this.includes = includes;
     }
 
-    /**
-     * @return the orderIndex
-     */
-    public Integer getOrderIndex() {
-        return orderIndex;
+    public Collection<TermDto> getGeneralizationOf() {
+        return generalizationOf;
     }
 
-    /**
-     * @param orderIndex the orderIndex to set
-     */
-    public void setOrderIndex(Integer orderIndex) {
-        this.orderIndex = orderIndex;
+    public void setGeneralizationOf(Collection<TermDto> generalizationOf) {
+        this.generalizationOf = generalizationOf;
     }
 
+    public static String getTermDtoSelect(){
+        return ""
+                + "select a.uuid, r, p.uuid, k.uuid, v.uuid, a.orderIndex, a.idInVocabulary "
+                + "from DefinedTermBase as a "
+                + "LEFT JOIN a.partOf as p "
+                + "LEFT JOIN a.kindOf as k "
+                + "LEFT JOIN a.representations AS r "
+                + "LEFT JOIN a.vocabulary as v ";
+    }
 
+    public static List<TermDto> termDtoListFrom(List<Object[]> results) {
+        Map<UUID, TermDto> dtoMap = new HashMap<>(results.size());
+        for (Object[] elements : results) {
+            UUID uuid = (UUID)elements[0];
+            if(dtoMap.containsKey(uuid)){
+                dtoMap.get(uuid).addRepresentation((Representation)elements[1]);
+            } else {
+                Set<Representation> representations = new HashSet<>();
+                if(elements[1] instanceof Representation) {
+                    representations = new HashSet<Representation>(1);
+                    representations.add((Representation)elements[1]);
+                } else {
+                    representations = (Set<Representation>)elements[1];
+                }
+                dtoMap.put(uuid, new TermDto(uuid, representations, (UUID)elements[2], (UUID)elements[3], (UUID)elements[4], (Integer)elements[5], (String)elements[6]));
+            }
+        }
+        return new ArrayList<>(dtoMap.values());
+    }
 
 }
diff --git a/cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dto/TermVocabularyDto.java b/cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dto/TermVocabularyDto.java
new file mode 100644 (file)
index 0000000..3e463cf
--- /dev/null
@@ -0,0 +1,42 @@
+// $Id$
+/**
+* Copyright (C) 2018 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.cdm.persistence.dto;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+
+import eu.etaxonomy.cdm.model.common.Representation;
+
+/**
+ * @author pplitzner
+ * @date 05.11.2018
+ *
+ */
+public class TermVocabularyDto extends AbstractTermDto {
+
+    private static final long serialVersionUID = 6053392236860675874L;
+
+    private Set<TermDto> terms;
+
+    public TermVocabularyDto(UUID uuid, Set<Representation> representations) {
+        super(uuid, representations);
+        terms = new HashSet<>();
+    }
+
+    public Set<TermDto> getTerms() {
+        return terms;
+    }
+
+    public void addTerm(TermDto term){
+        terms.add(term);
+    }
+
+}
index 734b743ccb731f175472a2389f6af9129977a875..42c01149f1d11f956bcc35089ae22c9f8492ae1d 100644 (file)
@@ -18,12 +18,15 @@ import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
 
+import eu.etaxonomy.cdm.api.service.TermServiceImpl.TermMovePosition;
 import eu.etaxonomy.cdm.api.service.config.TermDeletionConfigurator;
 import eu.etaxonomy.cdm.api.service.pager.Pager;
 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
 import eu.etaxonomy.cdm.model.common.Language;
 import eu.etaxonomy.cdm.model.common.LanguageString;
 import eu.etaxonomy.cdm.model.common.LanguageStringBase;
+import eu.etaxonomy.cdm.model.common.OrderedTermBase;
+import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;
 import eu.etaxonomy.cdm.model.common.Representation;
 import eu.etaxonomy.cdm.model.common.TermType;
 import eu.etaxonomy.cdm.model.common.TermVocabulary;
@@ -32,6 +35,7 @@ import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
 import eu.etaxonomy.cdm.model.location.NamedAreaType;
 import eu.etaxonomy.cdm.model.media.Media;
 import eu.etaxonomy.cdm.persistence.dao.initializer.IBeanInitializer;
+import eu.etaxonomy.cdm.persistence.dto.TermDto;
 import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
 import eu.etaxonomy.cdm.persistence.query.OrderHint;
 
@@ -192,4 +196,50 @@ public interface ITermService extends IIdentifiableEntityService<DefinedTermBase
      */
     List<UuidAndTitleCache<NamedArea>> getUuidAndTitleCache(List<TermVocabulary> vocs, Integer limit, String pattern,
             Language lang);
+
+    /**
+     * Returns the parent term of the given term
+     * @param childTerm the child term
+     * @return the parent term
+     */
+    public TermDto getParentAsDto(TermDto childTerm);
+
+    /**
+     * Returns all terms that are included in the given parent term resp. a part of the given term.
+     * @param parentTerm the parent term
+     * @return a collection of included terms
+     */
+    public Collection<TermDto> getIncludesAsDto(TermDto parentTerm);
+
+    /**
+     * Returns all terms that the given term is a generalization of resp. that are a kind of the given term
+     * @param parentTerm the parent term
+     * @return a collection of included terms
+     */
+    public Collection<TermDto> getKindOfsAsDto(TermDto parentTerm);
+
+    /**
+     * Move the given term to the given parent
+     * @param termDto the {@link TermDto} of the term to move
+     * @param parentUuid the {@link UUID} of the new parent term
+     * @param termMovePosition enum to specify the position for {@link OrderedTermBase}s in an {@link OrderedTermVocabulary}
+     */
+    public void moveTerm(TermDto termDto, UUID parentUuid, TermMovePosition termMovePosition);
+
+    /**
+     * Move the given term to the given parent
+     * @param termDto the {@link TermDto} of the term to move
+     * @param parentUuid the {@link UUID} of the new parent term
+     */
+    public void moveTerm(TermDto termDto, UUID parentUuid);
+
+    /**
+     * Creates a new term as a child of the given parent.
+     * @param termType the {@link TermType} of the term to create
+     * @param parentUuid the {@link UUID} of the parent term
+     * @param isKindOf if <code>true</code> the term will be added via a
+     * kindOf relation. Otherwise it will added via a partOf relation
+     */
+    public void addNewTerm(TermType termType, UUID parentUuid, boolean isKindOf);
+
 }
index e875c999f941a32c0ddb585e1f72b048249ba1ca..3281e7ab2d13de127dd9dad06c0741f1ad2fa99f 100644 (file)
@@ -9,13 +9,17 @@
 
 package eu.etaxonomy.cdm.api.service;
 
+import java.util.Collection;
 import java.util.List;
+import java.util.UUID;
 
 import eu.etaxonomy.cdm.api.service.pager.Pager;
 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
 import eu.etaxonomy.cdm.model.common.Language;
 import eu.etaxonomy.cdm.model.common.TermType;
 import eu.etaxonomy.cdm.model.common.TermVocabulary;
+import eu.etaxonomy.cdm.persistence.dto.TermDto;
+import eu.etaxonomy.cdm.persistence.dto.TermVocabularyDto;
 import eu.etaxonomy.cdm.persistence.query.OrderHint;
 
 public interface IVocabularyService extends IIdentifiableEntityService<TermVocabulary> {
@@ -68,4 +72,35 @@ public interface IVocabularyService extends IIdentifiableEntityService<TermVocab
         */
        public <T extends DefinedTermBase> List<TermVocabulary<T>> findByTermType(TermType termType, List<String> propertyPaths);
 
+       /**
+        * Loads all top level terms, i.e. terms that have no parent terms, for the given vocabulary
+        * @param vocabularyUuid the uuid of the vocabulary
+        * @return a collection of top level terms
+        */
+       public Collection<TermDto> getTopLevelTerms(UUID vocabularyUuid);
+
+       /**
+        * Initializes the complete term hierarchy consisting of {@link TermDto}s
+        * for the given vocabulary
+        * @param vocabularyUuid the UUID of the {@link TermVocabulary}
+        * @return a the top level elements for this vocabulary
+        */
+
+       public Collection<TermDto> getCompleteTermHierarchy(UUID vocabularyUuid);
+    /**
+     * Returns term vocabularies that contain terms of a certain {@link TermType} e.g. Feature, Modifier, State.
+     *
+     * @param termType the {@link TermType} of the terms in the vocabulary and of the vocabulary
+     * @return a list of term vocabularies
+     */
+    public List<TermVocabularyDto> findVocabularyDtoByTermType(TermType termType);
+
+    /**
+     * Creates a new term as a direct child of the given vocabulary.
+     * @param termType the {@link TermType} of the term to create
+     * @param vocabularyUUID the {@link UUID} of the vocabulary
+     * kindOf relation. Otherwise it will added via a partOf relation
+     */
+    public void addNewTerm(TermType termType, UUID vocabularyUUID);
+
 }
index f5e9b8a47f4624cf445216c8c9f9ded078faacff..d96ee9c2dee760c3726bc70df1e27308c8d6a889 100644 (file)
@@ -36,11 +36,14 @@ import eu.etaxonomy.cdm.api.service.exception.ReferencedObjectUndeletableExcepti
 import eu.etaxonomy.cdm.api.service.pager.Pager;
 import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;
 import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
+import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
 import eu.etaxonomy.cdm.model.common.CdmBase;
 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
 import eu.etaxonomy.cdm.model.common.Language;
 import eu.etaxonomy.cdm.model.common.LanguageString;
 import eu.etaxonomy.cdm.model.common.LanguageStringBase;
+import eu.etaxonomy.cdm.model.common.OrderedTermBase;
+import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;
 import eu.etaxonomy.cdm.model.common.Representation;
 import eu.etaxonomy.cdm.model.common.TermBase;
 import eu.etaxonomy.cdm.model.common.TermType;
@@ -53,6 +56,7 @@ import eu.etaxonomy.cdm.persistence.dao.common.IDefinedTermDao;
 import eu.etaxonomy.cdm.persistence.dao.common.ILanguageStringBaseDao;
 import eu.etaxonomy.cdm.persistence.dao.common.ILanguageStringDao;
 import eu.etaxonomy.cdm.persistence.dao.common.IRepresentationDao;
+import eu.etaxonomy.cdm.persistence.dto.TermDto;
 import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
 import eu.etaxonomy.cdm.persistence.query.OrderHint;
 import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
@@ -65,6 +69,9 @@ public class TermServiceImpl extends IdentifiableServiceBase<DefinedTermBase,IDe
 
        private ILanguageStringDao languageStringDao;
 
+       @Autowired
+       private IVocabularyService vocabularyService;
+
        @Autowired
        @Qualifier("langStrBaseDao")
        private ILanguageStringBaseDao languageStringBaseDao;
@@ -460,5 +467,115 @@ public class TermServiceImpl extends IdentifiableServiceBase<DefinedTermBase,IDe
         return result;
     }
 
+    @Override
+    public TermDto getParentAsDto(TermDto childTerm) {
+        return dao.getParentAsDto(childTerm);
+    }
+
+    @Override
+    public Collection<TermDto> getIncludesAsDto(
+            TermDto parentTerm) {
+        return dao.getIncludesAsDto(parentTerm);
+    }
+
+    @Override
+    public Collection<TermDto> getKindOfsAsDto(
+            TermDto parentTerm) {
+        return dao.getKindOfsAsDto(parentTerm);
+    }
+
+    @Transactional(readOnly = false)
+    @Override
+    public void moveTerm(TermDto termDto, UUID parentUUID) {
+        moveTerm(termDto, parentUUID, null);
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Transactional(readOnly = false)
+    @Override
+    public void moveTerm(TermDto termDto, UUID parentUuid, TermMovePosition termMovePosition) {
+        boolean isKindOf = termDto.getKindOfUuid()!=null && termDto.getKindOfUuid().equals(parentUuid);
+        TermVocabulary vocabulary = HibernateProxyHelper.deproxy(vocabularyService.load(termDto.getVocabularyUuid()));
+        DefinedTermBase parent = HibernateProxyHelper.deproxy(dao.load(parentUuid));
+        if(parent==null){
+            //new parent is a vocabulary
+            TermVocabulary parentVocabulary = HibernateProxyHelper.deproxy(vocabularyService.load(parentUuid));
+            DefinedTermBase term = HibernateProxyHelper.deproxy(dao.load(termDto.getUuid()));
+            if(parentVocabulary!=null){
+                term.setKindOf(null);
+                term.setPartOf(null);
+
+                vocabulary.removeTerm(term);
+                parentVocabulary.addTerm(term);
+            }
+            vocabularyService.saveOrUpdate(parentVocabulary);
+        }
+        else {
+            DefinedTermBase term = HibernateProxyHelper.deproxy(dao.load(termDto.getUuid()));
+            //new parent is a term
+            if(parent.isInstanceOf(OrderedTermBase.class)
+                    && term.isInstanceOf(OrderedTermBase.class)
+                    && termMovePosition!=null
+                    && HibernateProxyHelper.deproxy(parent, OrderedTermBase.class).getVocabulary().isInstanceOf(OrderedTermVocabulary.class)) {
+                //new parent is an ordered term
+                OrderedTermBase orderedTerm = HibernateProxyHelper.deproxy(term, OrderedTermBase.class);
+                OrderedTermBase targetOrderedDefinedTerm = HibernateProxyHelper.deproxy(parent, OrderedTermBase.class);
+                OrderedTermVocabulary otVoc = HibernateProxyHelper.deproxy(targetOrderedDefinedTerm.getVocabulary(), OrderedTermVocabulary.class);
+                if(termMovePosition.equals(TermMovePosition.BEFORE)) {
+                    orderedTerm.getVocabulary().removeTerm(orderedTerm);
+                    otVoc.addTermAbove(orderedTerm, targetOrderedDefinedTerm);
+                    if (targetOrderedDefinedTerm.getPartOf() != null){
+                        targetOrderedDefinedTerm.getPartOf().addIncludes(orderedTerm);
+                    }
+                }
+                else if(termMovePosition.equals(TermMovePosition.AFTER)) {
+                    orderedTerm.getVocabulary().removeTerm(orderedTerm);
+                    otVoc.addTermBelow(orderedTerm, targetOrderedDefinedTerm);
+                    if (targetOrderedDefinedTerm.getPartOf() != null){
+                        targetOrderedDefinedTerm.getPartOf().addIncludes(orderedTerm);
+                    }
+                }
+                else if(termMovePosition.equals(TermMovePosition.ON)) {
+                    orderedTerm.getVocabulary().removeTerm(orderedTerm);
+                    targetOrderedDefinedTerm.addIncludes(orderedTerm);
+                    targetOrderedDefinedTerm.getVocabulary().addTerm(orderedTerm);
+                }
+            }
+            else{
+                vocabulary.removeTerm(term);
+                if(isKindOf){
+                    parent.addGeneralizationOf(term);
+                }
+                else{
+                    parent.addIncludes(term);
+                }
+                parent.getVocabulary().addTerm(term);
+            }
+            vocabularyService.saveOrUpdate(parent.getVocabulary());
+        }
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Transactional(readOnly = false)
+    @Override
+    public void addNewTerm(TermType termType, UUID parentUUID, boolean isKindOf) {
+        DefinedTermBase term = termType.getEmptyDefinedTermBase();
+        dao.save(term);
+        DefinedTermBase parent = dao.load(parentUUID);
+        if(isKindOf){
+            parent.addGeneralizationOf(term);
+        }
+        else{
+            parent.addIncludes(term);
+        }
+        parent.getVocabulary().addTerm(term);
+        dao.saveOrUpdate(parent);
+    }
+
+    public enum TermMovePosition{
+        BEFORE,
+        AFTER,
+        ON
+    }
 
 }
index cd933ddf97a40b38dd4b2210433c5d949f0737ff..fe93f289f761961ed3d51459ebe5de185aea9edf 100644 (file)
@@ -10,6 +10,7 @@
 package eu.etaxonomy.cdm.api.service;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 import java.util.UUID;
 
@@ -25,6 +26,8 @@ import eu.etaxonomy.cdm.model.common.Language;
 import eu.etaxonomy.cdm.model.common.TermType;
 import eu.etaxonomy.cdm.model.common.TermVocabulary;
 import eu.etaxonomy.cdm.persistence.dao.common.ITermVocabularyDao;
+import eu.etaxonomy.cdm.persistence.dto.TermDto;
+import eu.etaxonomy.cdm.persistence.dto.TermVocabularyDto;
 import eu.etaxonomy.cdm.persistence.query.OrderHint;
 import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
 
@@ -32,6 +35,9 @@ import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
 @Transactional(readOnly = true)
 public class VocabularyServiceImpl extends IdentifiableServiceBase<TermVocabulary,ITermVocabularyDao>  implements IVocabularyService {
 
+    @Autowired
+    private ITermService termService;
+
        @Override
     @Autowired
        protected void setDao(ITermVocabularyDao dao) {
@@ -85,4 +91,46 @@ public class VocabularyServiceImpl extends IdentifiableServiceBase<TermVocabular
                return new DefaultPagerImpl<>(pageNumber, numberOfResults, pageSize, results);
        }
 
+
+    @Override
+    public Collection<TermDto> getTopLevelTerms(UUID vocabularyUuid) {
+        return dao.getTopLevelTerms(vocabularyUuid);
+    }
+
+    @Override
+    public Collection<TermDto> getCompleteTermHierarchy(UUID vocabularyUuid) {
+        Collection<TermDto> topLevelTerms = dao.getTopLevelTerms(vocabularyUuid);
+        for (TermDto termDto : topLevelTerms) {
+            initializeIncludes(termDto);
+            initializeGeneralizationOf(termDto);
+        }
+        return topLevelTerms;
+    }
+
+    private void initializeGeneralizationOf(TermDto parentTerm){
+        Collection<TermDto> generalizationOf = termService.getKindOfsAsDto(parentTerm);
+        parentTerm.setGeneralizationOf(generalizationOf);
+        generalizationOf.forEach(include->initializeGeneralizationOf(include));
+    }
+
+    private void initializeIncludes(TermDto parentTerm){
+        Collection<TermDto> includes = termService.getIncludesAsDto(parentTerm);
+        parentTerm.setIncludes(includes);
+        includes.forEach(include->initializeIncludes(include));
+    }
+
+    @Override
+    public List<TermVocabularyDto> findVocabularyDtoByTermType(TermType termType) {
+        return dao.findVocabularyDtoByTermType(termType);
+    }
+
+    @Transactional(readOnly = false)
+    @Override
+    public void addNewTerm(TermType termType, UUID vocabularyUUID) {
+        DefinedTermBase term = termType.getEmptyDefinedTermBase();
+        termService.save(term);
+        TermVocabulary vocabulary = dao.load(vocabularyUUID);
+        vocabulary.addTerm(term);
+        dao.saveOrUpdate(vocabulary);
+    }
 }