gt:       return jsonArray.length() > 0;
context: /*
   * Copyright (c) 2018 OBiBa. All rights reserved.
   *
   * This program and the accompanying materials
   * are made available under the terms of the GNU Public License v3.0.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  package org.obiba.mica.core.upgrade;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  import java.util.Objects;
  import java.util.Optional;
  import java.util.stream.StreamSupport;
  
  import javax.inject.Inject;
  
  import org.json.JSONArray;
  import org.json.JSONException;
  import org.json.JSONObject;
  import org.obiba.git.CommitInfo;
  import org.obiba.mica.core.domain.AbstractGitPersistable;
  import org.obiba.mica.core.domain.EntityState;
  import org.obiba.mica.micaConfig.service.TaxonomyConfigService;
  import org.obiba.mica.spi.search.TaxonomyTarget;
  import org.obiba.mica.study.domain.BaseStudy;
  import org.obiba.mica.study.domain.DataCollectionEvent;
  import org.obiba.mica.study.domain.Population;
  import org.obiba.mica.study.domain.Study;
  import org.obiba.mica.study.service.IndividualStudyService;
  import org.obiba.opal.core.domain.taxonomy.Taxonomy;
  import org.obiba.opal.core.domain.taxonomy.Vocabulary;
  import org.obiba.runtime.Version;
  import org.obiba.runtime.upgrade.UpgradeStep;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.springframework.data.mongodb.core.MongoTemplate;
  import org.springframework.stereotype.Component;
  
  import com.google.common.collect.ImmutableList;
  
  import static java.util.stream.Collectors.toList;
  
  @Component
  public class Mica310Upgrade implements UpgradeStep {
  
    @Inject
    private MongoTemplate mongoTemplate;
  
    @Inject
    private IndividualStudyService individualStudyService;
  
    @Inject
    private TaxonomyConfigService taxonomyConfigService;
  
    private static final Logger logger = LoggerFactory.getLogger(Mica310Upgrade.class);
  
    @Override
    public String getDescription() {
      return "Migrate data to mica 3.1.0";
    }
  
    @Override
    public Version getAppliesTo() {
      return new Version(3, 1, 0);
    }
  
    @Override
    public void execute(Version version) {
      logger.info("Executing Mica upgrade to version 3.1.0");
  
      try {
        republishStudiesWithInvalidContent();
      } catch(Exception e) {
        logger.error("Failed republishStudiesWithInvalidContent", e);
      }
  
      try {
        addDefaultFacets();
      } catch(Exception e) {
        logger.error("Failed addDefaultFacets", e);
      }
  
    }
  
    private void addDefaultFacets() {
  
      logger.info("Add default facets in study taxonomy");
      ImmutableList<String> vocabulariesWithFacet = ImmutableList.<String>builder()
        .add("methods-design")
        .add("start")
        .add("end")
        .add("populations-selectionCriteria-countriesIso")
        .add("populations-selectionCriteria-ageMin")
        .add("populations-selectionCriteria-ageMax")
        .add("populations-selectionCriteria-gender")
        .add("populations-selectionCriteria-pregnantWomen")
        .add("populations-selectionCriteria-newborn")
        .add("populations-selectionCriteria-twins")
        .add("numberOfParticipants-participant-number")
        .add("numberOfParticipants-sample-number")
        .add("methods-recruitments")
        .add("populations-recruitment-dataSources")
        .add("populations-dataCollectionEvents-dataSources")
        .add("populations-dataCollectionEvents-bioSamples")
        .add("access", "19")
        .build();
  
      Taxonomy studyTaxonomy = taxonomyConfigService.findByTarget(TaxonomyTarget.STUDY);
      for (Vocabulary vocabulary : studyTaxonomy.getVocabularies()) {
        if(vocabulariesWithFacet.contains(vocabulary.getName())) {
          vocabulary.addAttribute("facet", "true");
          vocabulary.addAttribute("facetPosition", "0");
          vocabulary.addAttribute("facetExpanded", "false");
        }
      }
  
      taxonomyConfigService.update(TaxonomyTarget.STUDY, studyTaxonomy);
    }
  
    private void republishStudiesWithInvalidContent() {
  
      List<Study> publishedStudies = individualStudyService.findAllPublishedStudies();
  
      for (Study publishedStudy : publishedStudies) {
  
        publishedStudy = transformToValidStudy(publishedStudy);
        setDefaultWeightForStudyPopulations(publishedStudy);
  
        EntityState studyState = individualStudyService.getEntityState(publishedStudy.getId());
        if (studyState.getRevisionsAhead() == 0) {
          individualStudyService.save(publishedStudy);
          individualStudyService.publish(publishedStudy.getId(), true);
        } else {
          Study draftStudy = individualStudyService.findStudy(publishedStudy.getId());
          draftStudy = transformToValidStudy(draftStudy);
          individualStudyService.save(publishedStudy);
          individualStudyService.publish(publishedStudy.getId(), true);
          setDefaultWeightForStudyPopulations(draftStudy);
          individualStudyService.save(draftStudy);
        }
      }
  
      List<String> publishedStudiesIds = publishedStudies.stream().map(AbstractGitPersistable::getId).collect(toList());
      individualStudyService.findAllDraftStudies().stream()
        .filter(unknownStateStudy -> !publishedStudiesIds.contains(unknownStateStudy.getId()))
        .filter(this::canGetCommitInfoOnStudyRepository)
        .filter(this::containsInvalidData)
        .map(this::transformToValidStudy)
        .forEach(individualStudyService::save);
  
      removeTaxonomyTaxonomyFromMongo();
    }
  
    boolean canGetCommitInfoOnStudyRepository(Study study) {
      try {
        return individualStudyService.getCommitInfos(study) != null;
      } catch(Exception e) {
        logger.error("Failed to get commit info for Study \"{}\" {}", study.getId(), e.getMessage());
        return false;
      }
    }
  
    void removeTaxonomyTaxonomyFromMongo() {
      try {
        logger.info("Remove Taxonomy of Taxonomies from DB since it is no longer persisted.");
        mongoTemplate.execute(db -> db.eval("db.taxonomyEntityWrapper.deleteOne({_id: 'taxonomy'});"));
      } catch (RuntimeException e) {
        logger.error("Error occurred when trying to removeTaxonomyTaxonomyFromMongo().", e);
      }
  
    }
  
    private boolean containsInvalidData(Study study) {
      return containsInvalidMethodsDesign(study)
        || containsInvalidExistingStudies(study)
        || !containsValidMethods(study, "recruitments")
        || !containsValidMethods(study, "otherDesign")
        || !containsValidMethods(study, "followUpInfo")
        || !containsValidMethods(study, "otherRecruitment")
        || !containsValidMethods(study, "info");
    }
  
    private boolean containsInvalidMethodsDesign(Study study) {
      try {
        Map<String, Object> methods = getModelMethods(study);
        if (methods.containsKey("designs") && !methods.containsKey("design"))
          return true;
      } catch (RuntimeException ignore) {
      }
      return false;
    }
  
    private boolean containsValidMethods(Study study, String methodsAttribute) {
      try {
        return (getModelMethods(study)).get(methodsAttribute) != null;
      } catch (RuntimeException ignore) {
        return false;
      }
    }
  
    private boolean containsRecruitment(JSONObject json) {
      try {
        JSONArray jsonArray = json.getJSONObject("methods").getJSONArray("recruitments");
  