All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.molgenis.data.icd10.CollectionsQueryTransformerImpl Maven / Gradle / Ivy

There is a newer version: 8.4.5
Show newest version
package org.molgenis.data.icd10;

import static com.google.common.graph.Traverser.forTree;
import static java.util.Collections.singletonList;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toList;

import com.google.common.collect.Streams;
import com.google.common.graph.Traverser;
import java.util.Collection;
import java.util.List;
import org.molgenis.data.DataService;
import org.molgenis.data.Entity;
import org.molgenis.data.Query;
import org.molgenis.data.QueryRule;
import org.springframework.stereotype.Component;

@Component
public class CollectionsQueryTransformerImpl implements CollectionsQueryTransformer {
  private static final Traverser RULE_TRAVERSER = forTree(QueryRule::getNestedRules);

  private final Icd10ClassExpander icd10ClassExpander;
  private final DataService dataService;

  CollectionsQueryTransformerImpl(Icd10ClassExpander icd10ClassExpander, DataService dataService) {
    this.icd10ClassExpander = requireNonNull(icd10ClassExpander);
    this.dataService = requireNonNull(dataService);
  }

  @Override
  public Query transformQuery(
      Query query, String icd10EntityTypeId, String expandAttribute) {
    if (query != null && query.getRules() != null && !query.getRules().isEmpty()) {
      query
          .getRules()
          .forEach(
              rule ->
                  Streams.stream(RULE_TRAVERSER.depthFirstPreOrder(rule))
                      .filter(nestedRule -> isTransformableRule(nestedRule, expandAttribute))
                      .forEach(nestedRule -> transformQueryRule(nestedRule, icd10EntityTypeId)));
    }

    return query;
  }

  private void transformQueryRule(QueryRule rule, String icd10EntityTypeId) {
    List queryValues;

    switch (rule.getOperator()) {
      case EQUALS:
        queryValues = singletonList(rule.getValue());
        rule.setOperator(QueryRule.Operator.IN);
        break;
      case IN:
        //noinspection unchecked
        queryValues = (List) rule.getValue();
        break;
      default:
        throw new IllegalStateException("Can't expand queries other than IN or EQUALS");
    }

    List diseaseTypes =
        dataService.findAll(icd10EntityTypeId, queryValues.stream()).collect(toList());

    rule.setValue(expandDiseaseTypes(diseaseTypes));
  }

  /**
   * Returns true if a rule is 'IN' or 'EQUALS' on the attribute that should be
   * expanded
   */
  private boolean isTransformableRule(QueryRule nestedRule, String expandAttribute) {
    return nestedRule != null
        && nestedRule.getField() != null
        && nestedRule.getField().equals(expandAttribute)
        && (nestedRule.getOperator() == QueryRule.Operator.IN
            || nestedRule.getOperator() == QueryRule.Operator.EQUALS);
  }

  /** Expand ICD-10 entities with all their children, grandchildren, etc. */
  private Collection expandDiseaseTypes(List diseaseTypes) {
    return icd10ClassExpander.expandClasses(diseaseTypes);
  }
}