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

io.github.linuxforhealth.hl7.resource.HL7DataBasedResourceModel Maven / Gradle / Ivy

Go to download

FHIR converter is a Java based library that enables converting Hl7v2 messages to FHIR resources

There is a newer version: 1.0.19
Show newest version
/*
 * (C) Copyright IBM Corp. 2020
 *
 * SPDX-License-Identifier: Apache-2.0
 */
package io.github.linuxforhealth.hl7.resource;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.google.common.collect.ImmutableMap;
import io.github.linuxforhealth.api.EvaluationResult;
import io.github.linuxforhealth.api.Expression;
import io.github.linuxforhealth.api.InputDataExtractor;
import io.github.linuxforhealth.api.ResourceModel;
import io.github.linuxforhealth.api.ResourceValue;
import io.github.linuxforhealth.core.Constants;
import io.github.linuxforhealth.core.exception.DataExtractionException;
import io.github.linuxforhealth.core.exception.RequiredConstraintFailureException;
import io.github.linuxforhealth.core.resource.ResourceResult;
import io.github.linuxforhealth.core.resource.SimpleResourceValue;
import io.github.linuxforhealth.hl7.expression.Hl7Expression;
import io.github.linuxforhealth.hl7.expression.JELXExpression;
import io.github.linuxforhealth.hl7.expression.ReferenceExpression;
import io.github.linuxforhealth.hl7.expression.ResourceExpression;
import io.github.linuxforhealth.hl7.expression.SimpleExpression;
import io.github.linuxforhealth.hl7.expression.ValueExtractionGeneralExpression;
import io.github.linuxforhealth.hl7.resource.deserializer.HL7DataBasedResourceDeserializer;


@JsonDeserialize(using = HL7DataBasedResourceDeserializer.class)
public class HL7DataBasedResourceModel implements ResourceModel {

  private static final String EVALUATING = "Evaluating {} {}";


  private static final Logger LOGGER = LoggerFactory.getLogger(HL7DataBasedResourceModel.class);


  private Map expressions;
  private String spec;

  private String name;
  private String group;

  public HL7DataBasedResourceModel(String name, Map expressions,
      String hl7spec) {
    this(name, expressions, hl7spec, null);


  }

  public HL7DataBasedResourceModel(String name, Map expressions, String hl7spec,
      String group) {
    this.expressions = new HashMap<>();
    this.expressions.putAll(expressions);
    this.spec = hl7spec;

    this.name = name;
    this.group = group;

  }



  public HL7DataBasedResourceModel(String name, Map expressions) {
    this(name, expressions, null);
  }

  public Map getExpressions() {
    return expressions;
  }



  @Override
  public ResourceResult evaluate(InputDataExtractor dataSource, Map variables,
      EvaluationResult baseValue) {
    ResourceResult resources = null;

    try {

      LOGGER.info("Started Evaluating resource {}", this.name);
      Map localContext = new HashMap<>(variables);


      Map expressionMap = this.getExpressions();


      Map defaultExp =
          expressionMap.entrySet().stream().filter(e -> (e.getValue() instanceof SimpleExpression))
              .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));


      Map resourceExp = expressionMap.entrySet().stream()
          .filter(e -> (e.getValue() instanceof ResourceExpression))
          .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

      Map refResourceExp = expressionMap.entrySet().stream()
          .filter(e -> (e.getValue() instanceof ReferenceExpression))
          .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));


      Map hl7Exps =
          expressionMap.entrySet().stream().filter(e -> (e.getValue() instanceof Hl7Expression))
              .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));



      Map valueExtractionExp = expressionMap.entrySet().stream()
          .filter(e -> (e.getValue() instanceof ValueExtractionGeneralExpression))
          .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));


      Map jexlExp =
          expressionMap.entrySet().stream().filter(e -> (e.getValue() instanceof JELXExpression))
              .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

      // initialize the map and list to collect values
      List additionalResolveValues = new ArrayList<>();
      Map resolveValues = new HashMap<>();

      evaluateResourceExpression(dataSource, localContext, resourceExp, additionalResolveValues,
          resolveValues, baseValue);

      evaluateReferenceExpression(dataSource, localContext, refResourceExp, additionalResolveValues,
          resolveValues, baseValue);


      executeExpression(dataSource, localContext, resolveValues, hl7Exps, baseValue);
      executeExpression(dataSource, localContext, resolveValues, valueExtractionExp, baseValue);

      executeExpression(dataSource, localContext, resolveValues, defaultExp, baseValue);

      executeExpression(dataSource, localContext, resolveValues, jexlExp, baseValue);


      resolveValues.values().removeIf(Objects::isNull);
      if (!resolveValues.isEmpty()) {
        String groupId = getGroupId(localContext);
        resources =
            new ResourceResult(new SimpleResourceValue(resolveValues, this.name),
                additionalResolveValues, groupId);

      }


    } catch (RequiredConstraintFailureException e) {
      LOGGER.error("RequiredConstraintFailureException during  resource {} evaluation", this.name,
          e);
      return null;

    } catch (IllegalArgumentException | IllegalStateException | DataExtractionException e) {
      LOGGER.error("Exception during  resource {} evaluation", this.name, e);
      return null;

    }
    return resources;
  }

  private static String getGroupId(Map localContext) {
    EvaluationResult result = localContext.get(Constants.GROUP_ID);
    if (result != null && result.getValue() instanceof String) {
      return result.getValue();
    }
    return null;
  }

  private static void evaluateReferenceExpression(InputDataExtractor dataSource,
      Map localContext, Map refResourceExp,
      List additionalResolveValues, Map resolveValues,
      EvaluationResult baseValue) {
    for (Entry entry : refResourceExp.entrySet()) {

      ReferenceExpression exp = (ReferenceExpression) entry.getValue();
      LOGGER.debug(EVALUATING, exp.getType(), entry.getKey());
      LOGGER.debug("Extracting reference resource  {} {} reference {}", exp.getType(),
          entry.getKey(), exp.getReference());
      if (exp.getData() != null) {

        EvaluationResult obj =
            exp.evaluate(dataSource, ImmutableMap.copyOf(localContext), baseValue);
        LOGGER.debug("Extracted object from reference resource  {} {} reference {}  value {}",
            exp.getType(), entry.getKey(), exp.getReference(), obj);
        if (obj != null && !obj.isEmpty()) {
          resolveValues.put(getKeyName(entry.getKey()), obj.getValue());
          if (obj.getAdditionalResources() != null && !obj.getAdditionalResources().isEmpty()) {
            additionalResolveValues.addAll(obj.getAdditionalResources());
          }
        }
      }
    }

  }

  private static void evaluateResourceExpression(InputDataExtractor dataSource,
      Map localContext, Map resourceExp,
      List additionalResolveValues, Map resolveValues,
      EvaluationResult baseValue) {
    for (Entry entry : resourceExp.entrySet()) {

      ResourceExpression exp = (ResourceExpression) entry.getValue();
      LOGGER.debug(EVALUATING, exp.getType(), entry.getKey());
      LOGGER.debug("Extracted resource  {} {} reference {}", exp.getType(),
          entry.getKey(), exp.getResourceName());
      if (exp.getData() != null) {

        EvaluationResult obj =
            exp.evaluate(dataSource, ImmutableMap.copyOf(localContext), baseValue);
        LOGGER.debug("Extracted object from reference resource  {} {} reference {}  value {}",
            exp.getType(), entry.getKey(), exp.getResourceName(), obj);
        if (obj != null && !obj.isEmpty()) {
          resolveValues.put(getKeyName(entry.getKey()), obj.getValue());
          if (obj.getAdditionalResources() != null && !obj.getAdditionalResources().isEmpty()) {
            additionalResolveValues.addAll(obj.getAdditionalResources());
          }
        }
      }
    }
  }

  private static String getKeyName(String key) {
    return StringUtils.split(key, "_")[0];
  }

  private static void executeExpression(InputDataExtractor dataSource,
      Map localContext, Map resolveValues,
      Map hl7Exps, EvaluationResult baseValue) {
    for (Entry entry : hl7Exps.entrySet()) {
      Expression exp = entry.getValue();
      LOGGER.debug(EVALUATING, entry.getKey(), entry.getValue());
      EvaluationResult obj = exp.evaluate(dataSource, localContext, baseValue);
      LOGGER.debug("Evaluated {} {} value returned {} ", entry.getKey(), entry.getValue(), obj);

      if (obj != null && !obj.isEmpty()) {

        resolveValues.put(getKeyName(entry.getKey()), obj.getValue());
      } else if (exp.getDefaultValue() != null) {
        resolveValues.put(entry.getKey(), exp.getDefaultValue());
      }
    }
  }


  public String getSpec() {
    return spec;
  }


  public void setName(String name) {
    this.name = name;
  }

  @Override
  public String getName() {
    return this.name;
  }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy