@Override
 public List<ThesaurusConcept> getConceptsByThesaurusId(
     String excludeConceptId,
     String thesaurusId,
     Boolean searchOrphans,
     Boolean onlyValidatedConcepts) {
   return thesaurusConceptDAO.getConceptsByThesaurusId(
       excludeConceptId, thesaurusId, searchOrphans, onlyValidatedConcepts);
 }
 @Override
 public List<ThesaurusConcept> getRecursiveParentsByConceptId(String conceptId) {
   ThesaurusConcept thesaurusConcept = thesaurusConceptDAO.getById(conceptId);
   if (thesaurusConcept != null) {
     return getRecursiveParentByConceptId(thesaurusConcept, new ArrayList<ThesaurusConcept>());
   } else {
     return new ArrayList<ThesaurusConcept>();
   }
 }
  @Override
  public List<ThesaurusConcept> getAvailableConceptsOfArray(
      String arrayId, String thesaurusId, String like) {
    ThesaurusArray currentArray = new ThesaurusArray();
    List<ThesaurusConcept> returnAvailableConcepts = new ArrayList<ThesaurusConcept>();

    if (StringUtils.isNotEmpty(arrayId)) {
      currentArray = thesaurusArrayDAO.getById(arrayId);
    }

    if (StringUtils.isNotEmpty(arrayId) && currentArray.getSuperOrdinateConcept() != null) {
      // We get all arrays matching our superordinate, excluding our
      // concept from the list
      List<ThesaurusArray> arrayWithSameSuperOrdinate =
          thesaurusArrayDAO.getConceptSuperOrdinateArrays(
              currentArray.getSuperOrdinateConcept().getIdentifier(), currentArray.getIdentifier());
      returnAvailableConcepts =
          thesaurusConceptDAO.getChildrenConcepts(
              currentArray.getSuperOrdinateConcept().getIdentifier(), 0, like);

      for (ThesaurusArray thesaurusArray : arrayWithSameSuperOrdinate) {
        Set<ThesaurusArrayConcept> conceptOfEachArray = thesaurusArray.getConcepts();
        for (ThesaurusArrayConcept thesaurusConcept : conceptOfEachArray) {
          returnAvailableConcepts.remove(thesaurusConcept.getConcepts());
        }
      }
    } else {
      // The array is null or has no superordinate : we get all topterm
      // concepts which are not already in other arrays
      List<ThesaurusArray> arrayWithNoSuperOrdinate =
          thesaurusArrayDAO.getConceptSuperOrdinateArrays(null);
      returnAvailableConcepts =
          thesaurusConceptDAO.getTopTermThesaurusConcept(
              thesaurusDAO.getById(thesaurusId), 0, like);
      for (ThesaurusArray thesaurusArray : arrayWithNoSuperOrdinate) {
        Set<ThesaurusArrayConcept> conceptOfEachArrayWithoutSuperordinate =
            thesaurusArray.getConcepts();
        for (ThesaurusArrayConcept thesaurusConcept : conceptOfEachArrayWithoutSuperordinate) {
          returnAvailableConcepts.remove(thesaurusConcept.getConcepts());
        }
      }
    }
    return returnAvailableConcepts;
  }
  @Transactional(readOnly = false)
  @Override
  public ThesaurusConcept destroyThesaurusConcept(ThesaurusConcept object) {
    if (object.getStatus() == ConceptStatusEnum.CANDIDATE.getStatus()
        || object.getStatus() == ConceptStatusEnum.REJECTED.getStatus()) {
      List<ThesaurusTerm> terms = thesaurusTermDAO.findTermsByConceptId(object.getIdentifier());
      for (ThesaurusTerm term : terms) {
        term.setConcept(null);
        thesaurusTermDAO.update(term);
      }

      List<ThesaurusConcept> childrenConcepts =
          getChildrenByConceptId(object.getIdentifier(), null);
      for (ThesaurusConcept childConcept : childrenConcepts) {
        childConcept.getParentConcepts().remove(object);
        thesaurusConceptDAO.update(childConcept);
      }

      List<ThesaurusConcept> rootChildrenConcepts = thesaurusConceptDAO.getAllRootChildren(object);
      for (ThesaurusConcept rootChild : rootChildrenConcepts) {
        rootChild.getRootConcepts().remove(object);
        thesaurusConceptDAO.update(rootChild);
      }

      List<ThesaurusArray> arrays =
          thesaurusArrayDAO.getConceptSuperOrdinateArrays(object.getIdentifier());
      for (ThesaurusArray array : arrays) {
        thesaurusArrayDAO.delete(array);
      }
      List<Alignment> alignments = alignmentDAO.findByTargetConceptId(object.getIdentifier());
      for (Alignment alignment : alignments) {
        if (alignment.getTargetConcepts().size() <= 1) {
          alignmentDAO.delete(alignment);
        }
      }

      return thesaurusConceptDAO.delete(object);
    } else {
      throw new BusinessException(
          "It's not possible to delete a concept with a status different from candidate or rejected",
          "delete-concept");
    }
  }
 @Override
 public int getStatusByConceptId(String conceptId) {
   ThesaurusConcept thesaurusConcept = thesaurusConceptDAO.getById(conceptId);
   if (thesaurusConcept != null) {
     return thesaurusConcept.getStatus();
   } else {
     throw new BusinessException(
         "Concept with identifier " + conceptId + " does not exist", "concepts-does-not-exist");
   }
 }
 @Override
 public Long getConceptsByThesaurusIdCount(
     String excludeConceptId,
     String thesaurusId,
     Boolean searchOrphans,
     Boolean onlyValidatedConcepts,
     String like) {
   return thesaurusConceptDAO.getConceptsByThesaurusIdCount(
       excludeConceptId, thesaurusId, searchOrphans, onlyValidatedConcepts, like);
 }
  @Override
  public int getConceptsHierarchicalRelations(String firstConceptId, String secondConceptId) {
    ThesaurusConcept firstConcept = thesaurusConceptDAO.getById(firstConceptId);
    ThesaurusConcept secondConcept = thesaurusConceptDAO.getById(secondConceptId);

    if (firstConcept != null && secondConcept != null) {
      if (thesaurusConceptDAO
          .getChildrenConcepts(firstConceptId, 0, null)
          .contains(secondConcept)) {
        return ConceptHierarchicalRelationsEnum.PARENT.getStatus();
      }

      if (thesaurusConceptDAO
          .getChildrenConcepts(secondConceptId, 0, null)
          .contains(firstConcept)) {
        return ConceptHierarchicalRelationsEnum.CHILD.getStatus();
      } else {
        return ConceptHierarchicalRelationsEnum.NORELATIONS.getStatus();
      }
    } else {
      throw new BusinessException("One or both concepts don't exist", "concepts-do-not-exist");
    }
  }
  private List<ThesaurusConcept> getRecursiveChildrenByConceptId(
      String conceptId, String originalParentId, List<ThesaurusConcept> allRecursiveChildren) {
    List<ThesaurusConcept> childrenConcepts =
        thesaurusConceptDAO.getChildrenConcepts(conceptId, 0, null);

    for (ThesaurusConcept concept : childrenConcepts) {
      if (concept.getIdentifier() != originalParentId) {
        if (!allRecursiveChildren.contains(concept)) {
          allRecursiveChildren.add(concept);
        }
        getRecursiveChildrenByConceptId(
            concept.getIdentifier(), originalParentId, allRecursiveChildren);
      }
    }
    return allRecursiveChildren;
  }
 /*
  * (non-Javadoc)
  *
  * @see
  * fr.mcc.ginco.services.IThesaurusConceptService#getThesaurusConceptList
  * (java.util.List)
  */
 @Override
 public Set<ThesaurusConcept> getThesaurusConceptList(List<String> ids) {
   Set<ThesaurusConcept> result = new HashSet<ThesaurusConcept>();
   for (String id : ids) {
     ThesaurusConcept concept = thesaurusConceptDAO.getById(id);
     if (concept == null) {
       throw new BusinessException(
           "The concept " + id + " does not exist!", "concept-does-not-exist");
     } else {
       if (!result.contains(concept)) {
         result.add(concept);
       }
     }
   }
   return result;
 }
 @Override
 public List<ThesaurusConcept> getPaginatedConceptsByThesaurusId(
     Integer startIndex,
     Integer limit,
     String excludeConceptId,
     String thesaurusId,
     Boolean searchOrphans,
     Boolean onlyValidatedConcepts,
     String like) {
   return thesaurusConceptDAO.getPaginatedConceptsByThesaurusId(
       startIndex,
       limit,
       excludeConceptId,
       thesaurusId,
       searchOrphans,
       onlyValidatedConcepts,
       like);
 }
 @Override
 public boolean hasChildren(String conceptId) {
   return (thesaurusConceptDAO.getChildrenConcepts(conceptId, 1, null).size() > 0);
 }
 @Override
 public List<ThesaurusConcept> getOrphanThesaurusConcepts(String thesaurusId, int maxResults) {
   Thesaurus thesaurus = checkThesaurusId(thesaurusId);
   return thesaurusConceptDAO.getOrphansThesaurusConcept(thesaurus, maxResults);
 }
 /*
  * (non-Javadoc)
  *
  * @see
  * fr.mcc.ginco.IThesaurusConceptService#getTopTermThesaurusConcept(java
  * .lang.String)
  */
 @Override
 public List<ThesaurusConcept> getTopTermThesaurusConcepts(String thesaurusId, int maxResults) {
   Thesaurus thesaurus = checkThesaurusId(thesaurusId);
   return thesaurusConceptDAO.getTopTermThesaurusConcept(thesaurus, maxResults, null);
 }
 @Override
 public List<ThesaurusConcept> getAvailableConceptsOfGroup(
     Integer startIndex, Integer limit, String groupId, String thesaurusId, String like) {
   return thesaurusConceptDAO.getPaginatedAvailableConceptsOfGroup(
       startIndex, limit, groupId, thesaurusId, false, like);
 }
 @Override
 public long getTopTermThesaurusConceptsCount(String thesaurusId) {
   Thesaurus thesaurus = checkThesaurusId(thesaurusId);
   return thesaurusConceptDAO.getTopTermThesaurusConceptCount(thesaurus);
 }
 @Override
 public List<ThesaurusConcept> getAllConcepts() {
   return thesaurusConceptDAO.findAll();
 }
 @Override
 public List<ThesaurusConcept> getChildrenByConceptId(
     String conceptId, int maxResults, String like) {
   return thesaurusConceptDAO.getChildrenConcepts(conceptId, maxResults, like);
 }
  @Transactional(readOnly = false)
  @Override
  public ThesaurusConcept updateThesaurusConcept(
      ThesaurusConcept object,
      List<ThesaurusTerm> terms,
      List<AssociativeRelationship> associatedConcepts,
      List<ConceptHierarchicalRelationship> hierarchicalRelationships,
      List<ThesaurusConcept> childrenConceptToDetach,
      List<ThesaurusConcept> childrenConceptToAttach,
      List<Alignment> alignments) {

    thesaurusTermUtils.checkTerms(terms);
    alignmentService.saveExternalThesauruses(alignments);

    if (StringUtils.isNotEmpty(object.getIdentifier())) {
      List<ThesaurusTerm> existingTerms =
          thesaurusTermDAO.findTermsByConceptId(object.getIdentifier());
      for (ThesaurusTerm existingTerm : existingTerms) {
        if (!terms.contains(existingTerm)) {
          ThesaurusTerm term = thesaurusTermDAO.getById(existingTerm.getIdentifier());
          term.setConcept(null);
          thesaurusTermDAO.update(term);
          logger.info("Marking Term with ID " + existingTerm.getIdentifier() + " as SandBoxed.");
        }
      }
    } else {
      object.setIdentifier(generatorService.generate(ThesaurusConcept.class));
      for (ConceptHierarchicalRelationship hierarchicalRelationship : hierarchicalRelationships) {
        hierarchicalRelationship.getIdentifier().setChildconceptid(object.getIdentifier());
      }
      for (AssociativeRelationship relation : associatedConcepts) {
        relation.getIdentifier().setConcept1(object.getIdentifier());
      }
    }
    List<ThesaurusConcept> allRecursiveChild =
        getRecursiveChildrenByConceptId(object.getIdentifier());
    List<ThesaurusConcept> allRecursiveParents =
        getRecursiveParentsByConceptId(object.getIdentifier());

    object =
        conceptHierarchicalRelationshipServiceUtil.saveHierarchicalRelationship(
            object,
            hierarchicalRelationships,
            allRecursiveParents,
            allRecursiveChild,
            childrenConceptToDetach,
            childrenConceptToAttach);

    if (object.getStatus() == ConceptStatusEnum.CANDIDATE.getStatus()) {
      // We can set status = candidate only if concept has not relation
      // (both hierarchical or associative)
      if (!associatedConcepts.isEmpty()
          || !object.getParentConcepts().isEmpty()
          || hasChildren(object.getIdentifier())) {
        throw new BusinessException(
            "A concept must not have a status candidate when it still have relations",
            "concept-status-candidate-relation");
      }
    }

    if (object.getStatus() == ConceptStatusEnum.VALIDATED.getStatus()) {
      // Test if parent concepts are validated
      Set<ThesaurusConcept> parents = object.getParentConcepts();
      for (ThesaurusConcept parent : parents) {
        if (parent.getStatus() != ConceptStatusEnum.VALIDATED.getStatus()) {
          throw new BusinessException(
              "A concept cannot have a parent which status is not validated",
              "concept-parent-not-validated");
        }
      }
    }

    ThesaurusConcept concept = thesaurusConceptDAO.update(object);
    updateConceptTerms(concept, terms);

    alignmentService.saveAlignments(concept, alignments);
    if (!alignments.isEmpty()) {
      alignmentService.deleteExternalThesauruses();
    }
    return thesaurusConceptDAO.update(saveAssociativeRelationship(concept, associatedConcepts));
  }
 @Override
 public Set<String> getConceptWithChildrenIdentifers(String thesaurusId) {
   return new HashSet<String>(
       thesaurusConceptDAO.getIdentifiersOfConceptsWithChildren(thesaurusId));
 }
 /*
  * (non-Javadoc)
  *
  * @see
  * fr.mcc.ginco.IThesaurusConceptService#getThesaurusConceptById(java.lang
  * .String)
  */
 @Override
 public ThesaurusConcept getThesaurusConceptById(String id) {
   return thesaurusConceptDAO.getById(id);
 }