Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.github.linuxforhealth.hl7.message.util.SegmentExtractorUtil Maven / Gradle / Ivy
/*
* (C) Copyright IBM Corp. 2020, 2021
*
* SPDX-License-Identifier: Apache-2.0
*/
package io.github.linuxforhealth.hl7.message.util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import ca.uhn.hl7v2.model.Structure;
import io.github.linuxforhealth.hl7.message.HL7Segment;
import io.github.linuxforhealth.hl7.parsing.HL7DataExtractor;
import io.github.linuxforhealth.hl7.parsing.result.ParsingResult;
public class SegmentExtractorUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(SegmentExtractorUtil.class);
private SegmentExtractorUtil() {
}
/**
* Returns list of segments and additional segments without group constraint.
*
* @param segment Segment to be extracted
* @param additionalSegments Additional segments to be tracked
* @param dataExtractor HL7 Data extractor to use
* @return List of {@link SegmentGroup}
*/
public static List extractSegmentNonGroups(String segment,
List additionalSegments, HL7DataExtractor dataExtractor) {
List returnValues = new ArrayList<>();
List segments = getStructures(segment, dataExtractor);
if (segments != null && !segments.isEmpty()) {
Map> additionalSegmentValues = extractAdditionalSegmentValueNonGroup(
additionalSegments, dataExtractor);
returnValues.add(new SegmentGroup(segments, additionalSegmentValues));
}
return returnValues;
}
/**
* Returns list of segments from all the repetitions of the group with a group name included in
* groupId
*
* @param primaryGroup Group the segment is to be extracted from
* @param primarySegment Segment to be extracted
* @param additionalSegments Additional segments to be tracked
* @param dataExtractor HL7 Data extractor to use
* @param parentGroup Parent group
*
* @return List of {@link SegmentGroup}
*/
public static List extractSegmentGroups(List primaryGroup,
String primarySegment, List additionalSegments, HL7DataExtractor dataExtractor,
List parentGroup) {
Preconditions.checkArgument(primaryGroup != null,
"Groups list for segment to be extracted cannot be null");
Preconditions.checkArgument(StringUtils.isNotBlank(primarySegment),
"primarySegment cannot be null or blank.");
if (parentGroup == null || parentGroup.isEmpty()) {
List parentSegments = getChildStructures(primaryGroup, dataExtractor);
return generateSegmentGroup(primarySegment, primaryGroup, additionalSegments, dataExtractor,
parentSegments, primaryGroup);
} else { // if parentGroup is not null then fetch parent group.
List parentSegments = getChildStructures(parentGroup, dataExtractor);
return generateSegmentGroup(primarySegment, primaryGroup, additionalSegments, dataExtractor,
parentSegments, parentGroup);
}
}
private static List generateSegmentGroup(String primarySegment,
List primaryGroup, List additionalSegments,
HL7DataExtractor dataExtractor, List parentSegments,
List parentGroupUsedForParentSegment) {
List returnValues = new ArrayList<>();
List relativePrimaryGroups = null;
relativePrimaryGroups = new ArrayList<>(primaryGroup);
relativePrimaryGroups.removeAll(parentGroupUsedForParentSegment);
for (Structure parent : parentSegments) {
List primarySegments = getChildStructures(parent, relativePrimaryGroups, primarySegment,
dataExtractor);
for (Structure primary : primarySegments) {
// Extract additional structures
Map> additionalSegmentValues = extractAdditionalSegmentValue(primary,
primaryGroup, additionalSegments, dataExtractor);
String groupId = generateGroupId(parent, parentGroupUsedForParentSegment);
if (primarySegments != null && !primarySegments.isEmpty()) {
returnValues
.add(new SegmentGroup(Lists.newArrayList(primary), additionalSegmentValues, groupId));
}
}
}
return returnValues;
}
private static List getChildStructures(Structure s, List groups,
String segment, HL7DataExtractor dataExtractor) {
if (StringUtils.isBlank(segment)) {
return new ArrayList<>();
} else if (groups == null || groups.isEmpty()) {
return getStructures(s, segment, dataExtractor);
} else {
List parents = getChildStructures(s, groups, dataExtractor);
List returnValues = new ArrayList<>();
for (Structure parent : parents) {
returnValues.addAll(getStructures(parent, segment, dataExtractor));
}
return returnValues;
}
}
private static List getChildStructures(List parentGroup,
HL7DataExtractor dataExtractor) {
if (parentGroup.isEmpty()) {
return new ArrayList<>();
} else if (parentGroup.size() == 1) {
return getStructures(parentGroup.get(0), dataExtractor);
} else {
String parent = parentGroup.get(0);
List subParents = parentGroup.subList(1, parentGroup.size());
List segments = getStructures(parent, dataExtractor);
List results = new ArrayList<>();
for (Structure s : segments) {
results.addAll(getChildStructures(s, subParents, dataExtractor));
}
return results;
}
}
private static List getChildStructures(Structure parentStruct,
List parentGroup, HL7DataExtractor dataExtractor) {
if (parentGroup.isEmpty()) {
return Lists.newArrayList(parentStruct);
} else if (parentStruct == null) {
return new ArrayList<>();
} else if (parentGroup.size() == 1) {
return getStructures(parentStruct, parentGroup.get(0), dataExtractor);
} else {
String parent = parentGroup.get(0);
List subParents = parentGroup.subList(1, parentGroup.size());
List segments = getStructures(parentStruct, parent, dataExtractor);
List result = new ArrayList<>();
for (Structure s : segments) {
result.addAll(getChildStructures(s, subParents, dataExtractor));
}
return result;
}
}
private static Map> extractAdditionalSegmentValue(Structure primaryStruct,
List primaryGroups, List additionalSegments,
HL7DataExtractor dataExtractor) {
Map> additionalSegmentValues = new HashMap<>();
for (HL7Segment seg : additionalSegments) {
List values = extractEachAdditionalSegment(primaryStruct, primaryGroups, seg, dataExtractor);
if (values != null && !values.isEmpty()) {
additionalSegmentValues.put(seg.getSegment(), values);
}
}
return additionalSegmentValues;
}
private static List extractEachAdditionalSegment(Structure primaryStruct,
List primaryGroups, HL7Segment seg, HL7DataExtractor dataExtractor) {
List values = null;
List groups = seg.getGroup();
if (groups.isEmpty()) {
values = getStructures(seg.getSegment(), dataExtractor);
} else if (primaryGroups.isEmpty()) {
// extract without parent
List parentSegments = getChildStructures(seg.getGroup(), dataExtractor);
values = new ArrayList<>();
for (Structure par : parentSegments) {
values.addAll(getStructures(par, seg.getSegment(), dataExtractor));
}
} else if (CollectionUtils.containsAll(primaryGroups, groups)) {
String commonParentGroup = getCommonParent(groups, primaryGroups);
Structure commonParent = getParentGroup(primaryStruct, commonParentGroup);
values = getStructures(commonParent, seg.getSegment(), dataExtractor);
} else if (getCommonParent(groups, primaryGroups) != null) {
String commonParentGroup = getCommonParent(groups, primaryGroups);
Structure commonParent = getParentGroup(primaryStruct, commonParentGroup);
List relativeGroupsToCommonParent = new ArrayList<>(groups);
relativeGroupsToCommonParent.removeAll(primaryGroups);
values = getChildStructures(commonParent, relativeGroupsToCommonParent, seg.getSegment(),
dataExtractor);
} else {
//extracts data from segment that is in a group outside of the primary group for that specific resource
List parentSegments = getChildStructures(seg.getGroup(), dataExtractor);
values = new ArrayList<>();
for (Structure par : parentSegments) {
values.addAll(getStructures(par, seg.getSegment(), dataExtractor));
}
}
return values;
}
private static String getCommonParent(List groups, List primaryGroups) {
List common = groups.stream().filter(primaryGroups::contains).collect(Collectors.toList());
if (!common.isEmpty()) {
return common.get(common.size() - 1);
}
return null;
}
private static Map> extractAdditionalSegmentValueNonGroup(
List additionalSegments, HL7DataExtractor dataExtractor) {
Map> additionalSegmentValues = new HashMap<>();
for (HL7Segment seg : additionalSegments) {
List values = null;
if (seg.isFromGroup()) {
throw new IllegalStateException(
"Primary segment is not from a group, so additional segements cannot be from relative group. ");
} else if (!seg.getGroup().isEmpty()) {
//extracts data from segment that is in a group outside of the primary group for that specific resource
List parentSegments = getChildStructures(seg.getGroup(), dataExtractor);
values = new ArrayList<>();
for (Structure par : parentSegments) {
values.addAll(getStructures(par, seg.getSegment(), dataExtractor));
}
} else {
ParsingResult result = dataExtractor.getAllStructures(seg.getSegment());
values = result.getValues();
}
if (values != null) {
additionalSegmentValues.put(seg.getSegment(), values);
}
}
return additionalSegmentValues;
}
// HL7 segments extraction
private static List getStructures(String seg, HL7DataExtractor dataExtractor) {
ParsingResult segments = dataExtractor.getAllStructures(seg);
if (segments == null || segments.isEmpty()) {
return new ArrayList<>();
} else {
return segments.getValues();
}
}
private static List getStructures(Structure parent, String segment,
HL7DataExtractor dataExtractor) {
ParsingResult segments = dataExtractor.getAllStructures(parent, segment);
if (segments == null || segments.isEmpty()) {
return new ArrayList<>();
} else {
return segments.getValues();
}
}
private static String generateGroupId(Structure struct, List groups) {
Structure parent = getParentGroup(struct, groups);
if (parent != null) {
return parent.getName() + "_" + parent.hashCode();
} else {
return null;
}
}
private static Structure getParentGroup(Structure struct, List groups) {
if (groups == null || groups.isEmpty()) {
return null;
}
List reversedGroups = new ArrayList<>(groups);
Collections.reverse(reversedGroups);
Structure parent = struct;
boolean foundParentGroup = false;
int numGroups = reversedGroups.size();
int i = 0;
while (!foundParentGroup && i < numGroups) {
parent = getParentGroup(parent, reversedGroups.get(i));
if (parent != null) {
foundParentGroup = true;
}
i = i + 1;
}
if (parent != null) {
return parent;
} else {
return null;
}
}
private static Structure getParentGroup(Structure struct, String group) {
boolean parentMatchFound = false;
Structure parent = struct;
boolean noMoreParent = false;
while (!parentMatchFound && !noMoreParent) {
if (parent != null && StringUtils.endsWith(parent.getName(), group)) {
parentMatchFound = true;
} else if (parent == null
|| parent.getName().equalsIgnoreCase(parent.getMessage().getName())) {
noMoreParent = true;
} else {
parent = parent.getParent();
}
}
if (parentMatchFound) {
return parent;
} else {
return null;
}
}
}