Merge branch 'master' of https://github.com/hapifhir/org.hl7.fhir.core into converting-medication-request
This commit is contained in:
commit
aedc2205c8
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.1.6-SNAPSHOT</version>
|
||||
<version>5.1.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -69,7 +69,7 @@
|
|||
<dependency>
|
||||
<groupId>org.fhir</groupId>
|
||||
<artifactId>ucum</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
|
|
@ -3150,6 +3150,8 @@ public class VersionConvertor_10_30 {
|
|||
return Medication10_30.convertMedication((org.hl7.fhir.dstu2.model.Medication) src);
|
||||
if (src instanceof org.hl7.fhir.dstu2.model.MedicationDispense)
|
||||
return MedicationDispense10_30.convertMedicationDispense((org.hl7.fhir.dstu2.model.MedicationDispense) src);
|
||||
if (src instanceof org.hl7.fhir.dstu2.model.MedicationOrder)
|
||||
return MedicationRequest10_30.convertMedicationOrder((org.hl7.fhir.dstu2.model.MedicationOrder)src);
|
||||
if (src instanceof org.hl7.fhir.dstu2.model.MedicationStatement)
|
||||
return MedicationStatement10_30.convertMedicationStatement((org.hl7.fhir.dstu2.model.MedicationStatement) src);
|
||||
if (src instanceof org.hl7.fhir.dstu2.model.MessageHeader)
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
package org.hl7.fhir.convertors.conv10_30;
|
||||
|
||||
import org.hl7.fhir.convertors.VersionConvertor_10_30;
|
||||
import org.hl7.fhir.dstu2.model.MedicationOrder;
|
||||
import org.hl7.fhir.dstu3.model.Dosage;
|
||||
import org.hl7.fhir.dstu3.model.MedicationRequest;
|
||||
import org.hl7.fhir.dstu3.model.StringType;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MedicationRequest10_30 {
|
||||
public static org.hl7.fhir.dstu3.model.MedicationRequest convertMedicationOrder(org.hl7.fhir.dstu2.model.MedicationOrder src) throws FHIRException {
|
||||
if (src == null || src.isEmpty())
|
||||
return null;
|
||||
org.hl7.fhir.dstu3.model.MedicationRequest tgt = new org.hl7.fhir.dstu3.model.MedicationRequest();
|
||||
VersionConvertor_10_30.copyDomainResource(src, tgt);
|
||||
tgt.setIntent(MedicationRequest.MedicationRequestIntent.ORDER);
|
||||
for (org.hl7.fhir.dstu2.model.Identifier t : src.getIdentifier()) tgt.addIdentifier(VersionConvertor_10_30.convertIdentifier(t));
|
||||
if (src.hasDateWritten())
|
||||
tgt.setAuthoredOn(src.getDateWritten());
|
||||
if (src.hasStatus())
|
||||
tgt.setStatus(MedicationRequest.MedicationRequestStatus.fromCode(src.getStatus().toCode()));
|
||||
if (src.hasPatient())
|
||||
tgt.setSubject(VersionConvertor_10_30.convertReference(src.getPatient()));
|
||||
if (src.hasPrescriber())
|
||||
tgt.setRequester(medRequestor(src));
|
||||
if (src.hasEncounter())
|
||||
tgt.setContext(VersionConvertor_10_30.convertReference(src.getEncounter()));
|
||||
if (src.hasReasonCodeableConcept())
|
||||
tgt.addReasonCode(VersionConvertor_10_30.convertCodeableConcept(src.getReasonCodeableConcept()));
|
||||
if (src.hasReasonReference())
|
||||
tgt.addReasonReference(VersionConvertor_10_30.convertReference(src.getReasonReference()));
|
||||
if (src.hasNote())
|
||||
tgt.addNote(new org.hl7.fhir.dstu3.model.Annotation(new StringType(src.getNote())));
|
||||
if (src.hasMedication())
|
||||
tgt.setMedication(VersionConvertor_10_30.convertType(src.getMedication()));
|
||||
for (MedicationOrder.MedicationOrderDosageInstructionComponent dosage : src.getDosageInstruction())
|
||||
tgt.addDosageInstruction(medDosageInstruction(dosage));
|
||||
if (src.hasDispenseRequest())
|
||||
tgt.setDispenseRequest(medDispenseRequest(src.getDispenseRequest()));
|
||||
if (src.hasSubstitution())
|
||||
tgt.setSubstitution(medSubstitution(src.getSubstitution()));
|
||||
if (src.hasPriorPrescription())
|
||||
tgt.setPriorPrescription(VersionConvertor_10_30.convertReference(src.getPriorPrescription()));
|
||||
return tgt;
|
||||
}
|
||||
|
||||
private static org.hl7.fhir.dstu3.model.Dosage medDosageInstruction(org.hl7.fhir.dstu2.model.MedicationOrder.MedicationOrderDosageInstructionComponent src) {
|
||||
if (src == null || src.isEmpty())
|
||||
return null;
|
||||
org.hl7.fhir.dstu3.model.Dosage tgt = new org.hl7.fhir.dstu3.model.Dosage();
|
||||
if (src.hasText())
|
||||
tgt.setText(src.getText());
|
||||
if (src.hasAdditionalInstructions())
|
||||
tgt.addAdditionalInstruction(VersionConvertor_10_30.convertCodeableConcept(src.getAdditionalInstructions()));
|
||||
if (src.hasTiming())
|
||||
tgt.setTiming(VersionConvertor_10_30.convertTiming(src.getTiming()));
|
||||
if (src.hasAsNeeded())
|
||||
tgt.setAsNeeded(VersionConvertor_10_30.convertType(src.getAsNeeded()));
|
||||
if (src.hasSiteCodeableConcept())
|
||||
tgt.setSite(VersionConvertor_10_30.convertCodeableConcept(src.getSiteCodeableConcept()));
|
||||
if (src.hasRoute())
|
||||
tgt.setRoute(VersionConvertor_10_30.convertCodeableConcept(src.getRoute()));
|
||||
if (src.hasMethod())
|
||||
tgt.setMethod(VersionConvertor_10_30.convertCodeableConcept(src.getMethod()));
|
||||
if (src.hasDose())
|
||||
tgt.setDose(VersionConvertor_10_30.convertType(src.getDose()));
|
||||
if (src.hasRate())
|
||||
tgt.setRate(VersionConvertor_10_30.convertType(src.getRate()));
|
||||
if (src.hasMaxDosePerPeriod())
|
||||
tgt.setMaxDosePerPeriod(VersionConvertor_10_30.convertRatio(src.getMaxDosePerPeriod()));
|
||||
return tgt;
|
||||
}
|
||||
|
||||
private static org.hl7.fhir.dstu3.model.MedicationRequest.MedicationRequestDispenseRequestComponent medDispenseRequest(org.hl7.fhir.dstu2.model.MedicationOrder.MedicationOrderDispenseRequestComponent src) {
|
||||
if (src == null || src.isEmpty())
|
||||
return null;
|
||||
org.hl7.fhir.dstu3.model.MedicationRequest.MedicationRequestDispenseRequestComponent tgt = new org.hl7.fhir.dstu3.model.MedicationRequest.MedicationRequestDispenseRequestComponent();
|
||||
if (src.hasValidityPeriod())
|
||||
tgt.setValidityPeriod(VersionConvertor_10_30.convertPeriod(src.getValidityPeriod()));
|
||||
if (src.hasNumberOfRepeatsAllowed())
|
||||
tgt.setNumberOfRepeatsAllowed(src.getNumberOfRepeatsAllowed());
|
||||
if (src.hasQuantity())
|
||||
tgt.setQuantity(VersionConvertor_10_30.convertSimpleQuantity(src.getQuantity()));
|
||||
if (src.hasExpectedSupplyDuration())
|
||||
tgt.setExpectedSupplyDuration(VersionConvertor_10_30.convertDuration(src.getExpectedSupplyDuration()));
|
||||
return tgt;
|
||||
}
|
||||
|
||||
private static org.hl7.fhir.dstu3.model.MedicationRequest.MedicationRequestSubstitutionComponent medSubstitution(org.hl7.fhir.dstu2.model.MedicationOrder.MedicationOrderSubstitutionComponent src) {
|
||||
if (src == null || src.isEmpty())
|
||||
return null;
|
||||
org.hl7.fhir.dstu3.model.MedicationRequest.MedicationRequestSubstitutionComponent tgt = new MedicationRequest.MedicationRequestSubstitutionComponent();
|
||||
if (src.hasReason())
|
||||
tgt.setReason(VersionConvertor_10_30.convertCodeableConcept(src.getReason()));
|
||||
return tgt;
|
||||
}
|
||||
|
||||
public static org.hl7.fhir.dstu3.model.MedicationRequest.MedicationRequestRequesterComponent
|
||||
medRequestor(org.hl7.fhir.dstu2.model.MedicationOrder src) {
|
||||
org.hl7.fhir.dstu3.model.MedicationRequest.MedicationRequestRequesterComponent tgt = new org.hl7.fhir.dstu3.model.MedicationRequest.MedicationRequestRequesterComponent();
|
||||
tgt.setAgent(VersionConvertor_10_30.convertReference(src.getPrescriber()));
|
||||
return tgt;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package org.hl7.fhir.convertors.misc;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.context.SimpleWorkerContext;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
|
||||
import org.hl7.fhir.utilities.cache.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.cache.NpmPackage;
|
||||
import org.hl7.fhir.utilities.cache.ToolsVersion;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
public class OIDBasedValueSetImporter {
|
||||
|
||||
protected IWorkerContext context;
|
||||
|
||||
protected void init() throws FileNotFoundException, FHIRException, IOException {
|
||||
FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
||||
NpmPackage npm = pcm.loadPackage("hl7.fhir.r5.core", "current");
|
||||
SimpleWorkerContext ctxt = SimpleWorkerContext.fromPackage(npm);
|
||||
ctxt.setAllowLoadingDuplicates(true);
|
||||
ctxt.loadFromPackage(pcm.loadPackage("hl7.terminology"), null);
|
||||
context = ctxt;
|
||||
}
|
||||
|
||||
protected String fixVersionforSystem(String url, String csver) {
|
||||
if ("http://snomed.info/sct".equals(url)) {
|
||||
return "http://snomed.info/sct/731000124108/version/"+csver;
|
||||
}
|
||||
if ("http://loinc.org".equals(url)) {
|
||||
return csver;
|
||||
}
|
||||
if ("http://www.nlm.nih.gov/research/umls/rxnorm".equals(url)) {
|
||||
if (csver.length() == 8) {
|
||||
return csver.substring(4,6)+csver.substring(6,8)+csver.substring(0,4);
|
||||
} else {
|
||||
return csver;
|
||||
}
|
||||
|
||||
}
|
||||
return csver;
|
||||
}
|
||||
|
||||
|
||||
protected ConceptSetComponent getInclude(ValueSet vs, String url, String csver) {
|
||||
for (ConceptSetComponent t : vs.getCompose().getInclude()) {
|
||||
if (csver == null) {
|
||||
if (t.getSystem().equals(url) && !t.hasVersion()) {
|
||||
return t;
|
||||
}
|
||||
} else {
|
||||
if (t.getSystem().equals(url) && t.hasVersion() && t.getVersion().equals(csver)) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
ConceptSetComponent c = vs.getCompose().addInclude();
|
||||
c.setSystem(url);
|
||||
c.setVersion(csver);
|
||||
return c;
|
||||
}
|
||||
|
||||
protected Document loadXml(InputStream fn) throws Exception {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
||||
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||||
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||||
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||||
factory.setXIncludeAware(false);
|
||||
factory.setExpandEntityReferences(false);
|
||||
|
||||
factory.setNamespaceAware(true);
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
return builder.parse(fn);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -23,28 +23,18 @@ import org.hl7.fhir.utilities.cache.FilesystemPackageCacheManager;
|
|||
import org.hl7.fhir.utilities.cache.NpmPackage;
|
||||
import org.hl7.fhir.utilities.cache.ToolsVersion;
|
||||
|
||||
public class PhinVadsImporter {
|
||||
public class PhinVadsImporter extends OIDBasedValueSetImporter {
|
||||
|
||||
public static void main(String[] args) throws FileNotFoundException, FHIRException, IOException, ParseException {
|
||||
// new PhinVadsImporter().importValueSet(TextFile.fileToBytes("C:\\work\\org.hl7.fhir\\packages\\us.cdc.phinvads-source\\source\\PHVS_BirthDefectsLateralityatDiagnosis_HL7_V1.txt"));
|
||||
PhinVadsImporter self = new PhinVadsImporter();
|
||||
self.init();
|
||||
self.process(args[0], args[1]);
|
||||
}
|
||||
|
||||
private IWorkerContext context;
|
||||
|
||||
public PhinVadsImporter() {
|
||||
public PhinVadsImporter() throws FileNotFoundException, FHIRException, IOException {
|
||||
super();
|
||||
}
|
||||
|
||||
private void init() throws FileNotFoundException, FHIRException, IOException {
|
||||
FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
||||
NpmPackage npm = pcm.loadPackage("hl7.fhir.r5.core", "current");
|
||||
SimpleWorkerContext ctxt = SimpleWorkerContext.fromPackage(npm);
|
||||
ctxt.setAllowLoadingDuplicates(true);
|
||||
ctxt.loadFromPackage(pcm.loadPackage("hl7.terminology"), null);
|
||||
context = ctxt;
|
||||
init();
|
||||
}
|
||||
|
||||
private void process(String source, String dest) {
|
||||
|
@ -84,6 +74,8 @@ public class PhinVadsImporter {
|
|||
vs.setDescription(rdr.cell("Value Set Definition"));
|
||||
if ("Published".equals(rdr.cell("Value Set Status"))) {
|
||||
vs.setStatus(PublicationStatus.ACTIVE);
|
||||
} else {
|
||||
vs.setStatus(PublicationStatus.DRAFT);
|
||||
}
|
||||
if (rdr.has("VS Last Updated Date")) {
|
||||
vs.setDate(new SimpleDateFormat("mm/dd/yyyy").parse(rdr.cell("VS Last Updated Date")));
|
||||
|
@ -109,40 +101,5 @@ public class PhinVadsImporter {
|
|||
return vs;
|
||||
}
|
||||
|
||||
private String fixVersionforSystem(String url, String csver) {
|
||||
if ("http://snomed.info/sct".equals(url)) {
|
||||
return "http://snomed.info/sct|http://snomed.info/sct/731000124108/"+csver;
|
||||
}
|
||||
if ("http://loinc.org".equals(url)) {
|
||||
return csver;
|
||||
}
|
||||
if ("http://www.nlm.nih.gov/research/umls/rxnorm".equals(url)) {
|
||||
if (csver.length() == 8) {
|
||||
return csver.substring(4,6)+csver.substring(6,8)+csver.substring(0,4);
|
||||
} else {
|
||||
return csver;
|
||||
}
|
||||
|
||||
}
|
||||
return csver;
|
||||
}
|
||||
|
||||
private ConceptSetComponent getInclude(ValueSet vs, String url, String csver) {
|
||||
for (ConceptSetComponent t : vs.getCompose().getInclude()) {
|
||||
if (csver == null) {
|
||||
if (t.getSystem().equals(url) && !t.hasVersion()) {
|
||||
return t;
|
||||
}
|
||||
} else {
|
||||
if (t.getSystem().equals(url) && t.hasVersion() && t.getVersion().equals(csver)) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
ConceptSetComponent c = vs.getCompose().addInclude();
|
||||
c.setSystem(url);
|
||||
c.setVersion(csver);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
package org.hl7.fhir.convertors.misc;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.context.SimpleWorkerContext;
|
||||
import org.hl7.fhir.r5.formats.JsonParser;
|
||||
import org.hl7.fhir.r5.model.Enumerations.PublicationStatus;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
|
||||
import org.hl7.fhir.utilities.CSVReader;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.cache.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.cache.NpmPackage;
|
||||
import org.hl7.fhir.utilities.cache.ToolsVersion;
|
||||
import org.hl7.fhir.utilities.xml.XMLUtil;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
public class VSACImporter extends OIDBasedValueSetImporter {
|
||||
|
||||
public static void main(String[] args) throws FileNotFoundException, FHIRException, IOException, ParseException {
|
||||
// new PhinVadsImporter().importValueSet(TextFile.fileToBytes("C:\\work\\org.hl7.fhir\\packages\\us.cdc.phinvads-source\\source\\PHVS_BirthDefectsLateralityatDiagnosis_HL7_V1.txt"));
|
||||
VSACImporter self = new VSACImporter();
|
||||
self.process(args[0], args[1]);
|
||||
}
|
||||
|
||||
public VSACImporter() throws FileNotFoundException, FHIRException, IOException {
|
||||
super();
|
||||
init();
|
||||
}
|
||||
|
||||
private void process(String source, String dest) {
|
||||
for (File f : new File(source).listFiles()) {
|
||||
try {
|
||||
System.out.println("Process "+f.getName());
|
||||
List<ValueSet> vsl = importValueSet(TextFile.fileToBytes(f));
|
||||
for (ValueSet vs : vsl) {
|
||||
if (vs.getId() != null) {
|
||||
new JsonParser().compose(new FileOutputStream(Utilities.path(dest, "ValueSet-"+vs.getId()+".json")), vs);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<ValueSet> importValueSet(byte[] source) throws Exception {
|
||||
List<ValueSet> res = new ArrayList<ValueSet>();
|
||||
Element x = loadXml(new ByteArrayInputStream(source)).getDocumentElement();
|
||||
List<Element> vl = XMLUtil.getNamedChildren(x, "DescribedValueSet");
|
||||
for (Element v : vl) {
|
||||
ValueSet vs = new ValueSet();
|
||||
vs.setId(v.getAttribute("ID"));
|
||||
vs.setUrl("http://vsac.nlm.nih.gov/fhir/ValueSet/"+vs.getId());
|
||||
vs.getMeta().setSource("https://vsac.nlm.nih.gov/valueset/"+vs.getId()+"/expansion");
|
||||
vs.setVersion(v.getAttribute("version"));
|
||||
vs.setTitle(v.getAttribute("displayName"));
|
||||
vs.setName(Utilities.titleize(vs.getTitle()).replace(" ", ""));
|
||||
Element d = XMLUtil.getNamedChild(v, "Purpose");
|
||||
if (d != null) {
|
||||
vs.setDescription(d.getTextContent());
|
||||
}
|
||||
Element s = XMLUtil.getNamedChild(v, "Status");
|
||||
if (s != null && "Active".equals(s.getTextContent())) {
|
||||
vs.setStatus(PublicationStatus.ACTIVE);
|
||||
} else {
|
||||
vs.setStatus(PublicationStatus.DRAFT);
|
||||
}
|
||||
Element dt = XMLUtil.getNamedChild(v, "RevisionDate");
|
||||
if (dt != null) {
|
||||
vs.getDateElement().setValueAsString(dt.getTextContent());
|
||||
}
|
||||
|
||||
Element cl = XMLUtil.getNamedChild(v, "ConceptList");
|
||||
Element cc = XMLUtil.getFirstChild(cl);
|
||||
|
||||
while (cc != null) {
|
||||
String code = cc.getAttribute("code");
|
||||
String display = cc.getAttribute("displayName");
|
||||
String csoid = cc.getAttribute("codeSystem");
|
||||
String csver = cc.getAttribute("codeSystemVersion");
|
||||
String url = context.oid2Uri(csoid);
|
||||
if (url == null) {
|
||||
url = "urn:oid:"+csoid;
|
||||
}
|
||||
csver = fixVersionforSystem(url, csver);
|
||||
ConceptSetComponent inc = getInclude(vs, url, csver);
|
||||
inc.addConcept().setCode(code).setDisplay(display);
|
||||
cc = XMLUtil.getNextSibling(cc);
|
||||
}
|
||||
|
||||
res.add(vs);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.1.6-SNAPSHOT</version>
|
||||
<version>5.1.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
|||
<dependency>
|
||||
<groupId>org.fhir</groupId>
|
||||
<artifactId>ucum</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.1.6-SNAPSHOT</version>
|
||||
<version>5.1.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
|||
<dependency>
|
||||
<groupId>org.fhir</groupId>
|
||||
<artifactId>ucum</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3</version>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
|
|
|
@ -214,7 +214,6 @@ public class ClientUtils {
|
|||
|
||||
/**
|
||||
* @param resourceFormat
|
||||
* @param options
|
||||
* @return
|
||||
*/
|
||||
protected <T extends Resource> ResourceRequest<T> issueResourceRequest(String resourceFormat, HttpUriRequest request, byte[] payload, int timeoutLoading) {
|
||||
|
@ -223,7 +222,6 @@ public class ClientUtils {
|
|||
|
||||
/**
|
||||
* @param resourceFormat
|
||||
* @param options
|
||||
* @return
|
||||
*/
|
||||
protected <T extends Resource> ResourceRequest<T> issueResourceRequest(String resourceFormat, HttpUriRequest request, byte[] payload, List<Header> headers, int timeoutLoading) {
|
||||
|
@ -314,9 +312,7 @@ public class ClientUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param request
|
||||
* @param payload
|
||||
* @return
|
||||
*/
|
||||
protected HttpResponse sendRequest(HttpUriRequest request) {
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.hl7.fhir.dstu2016may.test;
|
|||
|
||||
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
||||
import org.hl7.fhir.dstu2016may.model.DateType;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -11,8 +12,6 @@ import java.util.Calendar;
|
|||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class BaseDateTimeTypeTest {
|
||||
private SimpleDateFormat myDateInstantParser;
|
||||
|
||||
|
@ -34,7 +33,7 @@ public class BaseDateTimeTypeTest {
|
|||
|
||||
DateType date = new DateType();
|
||||
date.setValue(time, TemporalPrecisionEnum.DAY);
|
||||
assertEquals("2012-01-02", date.getValueAsString());
|
||||
Assertions.assertEquals("2012-01-02", date.getValueAsString());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -50,6 +49,6 @@ public class BaseDateTimeTypeTest {
|
|||
|
||||
DateType date = new DateType();
|
||||
date.setValue(time);
|
||||
assertEquals("2012-01-02", date.getValueAsString());
|
||||
Assertions.assertEquals("2012-01-02", date.getValueAsString());
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package org.hl7.fhir.dstu2016may.test;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
public class ClientUtilsTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass() {
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownAfterClass() {
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.1.6-SNAPSHOT</version>
|
||||
<version>5.1.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
|||
<dependency>
|
||||
<groupId>org.fhir</groupId>
|
||||
<artifactId>ucum</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.1.6-SNAPSHOT</version>
|
||||
<version>5.1.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
|||
<dependency>
|
||||
<groupId>org.fhir</groupId>
|
||||
<artifactId>ucum</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.hl7.fhir.utilities.graphql.IGraphQLStorageServices;
|
|||
import org.hl7.fhir.utilities.graphql.NameValue;
|
||||
import org.hl7.fhir.utilities.graphql.Parser;
|
||||
import org.hl7.fhir.utilities.xml.XMLUtil;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
|
@ -36,8 +37,6 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@Disabled
|
||||
public class GraphQLEngineTests implements IGraphQLStorageServices {
|
||||
|
||||
|
@ -86,15 +85,15 @@ public class GraphQLEngineTests implements IGraphQLStorageServices {
|
|||
msg = e.getMessage();
|
||||
}
|
||||
if (ok) {
|
||||
assertTrue("Expected to fail, but didn't", !output.equals("$error"));
|
||||
Assertions.assertTrue(!output.equals("$error"), "Expected to fail, but didn't");
|
||||
StringBuilder str = new StringBuilder();
|
||||
gql.getOutput().setWriteWrapper(false);
|
||||
gql.getOutput().write(str, 0);
|
||||
TextFile.stringToFile(str.toString(), TestingUtilities.resourceNameToFile("graphql", output + ".out"));
|
||||
msg = TestingUtilities.checkJsonIsSame(TestingUtilities.resourceNameToFile("graphql", output + ".out"), TestingUtilities.resourceNameToFile("graphql", output));
|
||||
assertTrue(msg, Utilities.noString(msg));
|
||||
Assertions.assertTrue(Utilities.noString(msg), msg);
|
||||
} else
|
||||
assertTrue("Error, but proper output was expected (" + msg + ")", output.equals("$error"));
|
||||
Assertions.assertTrue(output.equals("$error"), "Error, but proper output was expected (" + msg + ")");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,6 +7,7 @@ import org.hl7.fhir.utilities.graphql.EGraphEngine;
|
|||
import org.hl7.fhir.utilities.graphql.EGraphQLException;
|
||||
import org.hl7.fhir.utilities.graphql.Package;
|
||||
import org.hl7.fhir.utilities.graphql.Parser;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
|
@ -18,8 +19,6 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@Disabled
|
||||
public class GraphQLParserTests {
|
||||
|
||||
|
@ -40,7 +39,7 @@ public class GraphQLParserTests {
|
|||
@MethodSource("data")
|
||||
public void test(String name, String test) throws IOException, EGraphQLException, EGraphEngine {
|
||||
Package doc = Parser.parse(test);
|
||||
assertTrue(doc != null);
|
||||
Assertions.assertTrue(doc != null);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import org.hl7.fhir.r4.model.Resource;
|
|||
import org.hl7.fhir.r4.test.utils.TestingUtilities;
|
||||
import org.hl7.fhir.r4.utils.EOperationOutcome;
|
||||
import org.hl7.fhir.r4.utils.NarrativeGenerator;
|
||||
import org.junit.Before;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -20,7 +20,7 @@ import java.io.*;
|
|||
|
||||
public class ResourceRoundTripTests {
|
||||
|
||||
@Before
|
||||
@BeforeAll
|
||||
public void setUp() throws Exception {
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,9 @@ package org.hl7.fhir.r4.test;
|
|||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r4.utils.SnomedExpressions;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
public class SnomedExpressionsTests {
|
||||
|
||||
@Test
|
||||
|
@ -47,7 +46,7 @@ public class SnomedExpressionsTests {
|
|||
}
|
||||
|
||||
private void p(String expression) throws FHIRException {
|
||||
assertNotNull("must be present", SnomedExpressions.parse(expression));
|
||||
Assertions.assertNotNull(SnomedExpressions.parse(expression), "must be present");
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.1.6-SNAPSHOT</version>
|
||||
<version>5.1.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
|||
<dependency>
|
||||
<groupId>org.fhir</groupId>
|
||||
<artifactId>ucum</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
|
|
@ -420,9 +420,11 @@ public class CodeSystemComparer extends CanonicalResourceComparer {
|
|||
c = comp.getPropMap().get(c);
|
||||
}
|
||||
ConceptPropertyComponent cp = null;
|
||||
for (ConceptPropertyComponent t : cd.getProperty()) {
|
||||
if (t.getCode().equals(c)) {
|
||||
cp = t;
|
||||
if (cd != null) {
|
||||
for (ConceptPropertyComponent t : cd.getProperty()) {
|
||||
if (t.getCode().equals(c)) {
|
||||
cp = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cp;
|
||||
|
|
|
@ -942,12 +942,12 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
nc = utilsRight.genElementNameCell(gen, combined.getRight(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used , ref, sName);
|
||||
}
|
||||
if (combined.hasLeft()) {
|
||||
frame(utilsRight.genElementCells(gen, combined.getLeft(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used , ref, sName, nc), leftColor);
|
||||
frame(utilsRight.genElementCells(gen, combined.getLeft(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used , ref, sName, nc, false), leftColor);
|
||||
} else {
|
||||
frame(spacers(row, 4, gen), leftColor);
|
||||
}
|
||||
if (combined.hasRight()) {
|
||||
frame(utilsRight.genElementCells(gen, combined.getRight(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used, ref, sName, nc), rightColor);
|
||||
frame(utilsRight.genElementCells(gen, combined.getRight(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used, ref, sName, nc, false), rightColor);
|
||||
} else {
|
||||
frame(spacers(row, 4, gen), rightColor);
|
||||
}
|
||||
|
|
|
@ -234,7 +234,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
ElementDefinition ed = defn.getSnapshot().getElement().get(i);
|
||||
if (ed.getPath().equals(element.getPath()))
|
||||
return null;
|
||||
if (ed.getPath().startsWith(element.getPath()+".value"))
|
||||
if (ed.getPath().startsWith(element.getPath()+".value") && !ed.hasSlicing())
|
||||
return ed;
|
||||
i++;
|
||||
}
|
||||
|
@ -2992,7 +2992,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (!child.getPath().endsWith(".id")) {
|
||||
List<StructureDefinition> sdl = new ArrayList<>();
|
||||
sdl.add(ed);
|
||||
genElement(defFile == null ? "" : defFile+"-definitions.html#extension.", gen, r.getSubRows(), child, ed.getSnapshot().getElement(), sdl, true, defFile, true, full, corePath, imagePath, true, false, false, false, null);
|
||||
genElement(defFile == null ? "" : defFile+"-definitions.html#extension.", gen, r.getSubRows(), child, ed.getSnapshot().getElement(), sdl, true, defFile, true, full, corePath, imagePath, true, false, false, false, null, false);
|
||||
}
|
||||
} else if (deep) {
|
||||
List<ElementDefinition> children = new ArrayList<ElementDefinition>();
|
||||
|
@ -3371,7 +3371,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
|
||||
public XhtmlNode generateTable(String defFile, StructureDefinition profile, boolean diff, String imageFolder, boolean inlineGraphics, String profileBaseFileName, boolean snapshot, String corePath, String imagePath,
|
||||
boolean logicalModel, boolean allInvariants, Set<String> outputTracker, boolean active) throws IOException, FHIRException {
|
||||
boolean logicalModel, boolean allInvariants, Set<String> outputTracker, boolean active, boolean mustSupport) throws IOException, FHIRException {
|
||||
assert(diff != snapshot);// check it's ok to get rid of one of these
|
||||
HierarchicalTableGenerator gen = new HierarchicalTableGenerator(imageFolder, inlineGraphics, true);
|
||||
gen.setTranslator(getTranslator());
|
||||
|
@ -3397,7 +3397,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (diff) {
|
||||
insertMissingSparseElements(list);
|
||||
}
|
||||
genElement(defFile == null ? null : defFile+"#", gen, model.getRows(), list.get(0), list, profiles, diff, profileBaseFileName, null, snapshot, corePath, imagePath, true, logicalModel, profile.getDerivation() == TypeDerivationRule.CONSTRAINT && usesMustSupport(list), allInvariants, null);
|
||||
genElement(defFile == null ? null : defFile+"#", gen, model.getRows(), list.get(0), list, profiles, diff, profileBaseFileName, null, snapshot, corePath, imagePath, true, logicalModel, profile.getDerivation() == TypeDerivationRule.CONSTRAINT && usesMustSupport(list), allInvariants, null, mustSupport);
|
||||
try {
|
||||
return gen.generate(model, imagePath, 0, outputTracker);
|
||||
} catch (org.hl7.fhir.exceptions.FHIRException e) {
|
||||
|
@ -3492,7 +3492,8 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
|
||||
|
||||
private Row genElement(String defPath, HierarchicalTableGenerator gen, List<Row> rows, ElementDefinition element, List<ElementDefinition> all, List<StructureDefinition> profiles, boolean showMissing, String profileBaseFileName, Boolean extensions, boolean snapshot, String corePath, String imagePath, boolean root, boolean logicalModel, boolean isConstraintMode, boolean allInvariants, Row slicingRow) throws IOException, FHIRException {
|
||||
private Row genElement(String defPath, HierarchicalTableGenerator gen, List<Row> rows, ElementDefinition element, List<ElementDefinition> all, List<StructureDefinition> profiles, boolean showMissing, String profileBaseFileName, Boolean extensions,
|
||||
boolean snapshot, String corePath, String imagePath, boolean root, boolean logicalModel, boolean isConstraintMode, boolean allInvariants, Row slicingRow, boolean mustSupport) throws IOException, FHIRException {
|
||||
Row originalRow = slicingRow;
|
||||
StructureDefinition profile = profiles == null ? null : profiles.get(profiles.size()-1);
|
||||
Row typesRow = null;
|
||||
|
@ -3562,7 +3563,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (logicalModel && element.hasRepresentation(PropertyRepresentation.XMLATTR))
|
||||
sName = "@"+sName;
|
||||
Cell nc = genElementNameCell(gen, element, profileBaseFileName, snapshot, corePath, imagePath, root, logicalModel, allInvariants, profile, typesRow, row, hasDef, ext, used, ref, sName);
|
||||
genElementCells(gen, element, profileBaseFileName, snapshot, corePath, imagePath, root, logicalModel, allInvariants, profile, typesRow, row, hasDef, ext, used, ref, sName, nc);
|
||||
genElementCells(gen, element, profileBaseFileName, snapshot, corePath, imagePath, root, logicalModel, allInvariants, profile, typesRow, row, hasDef, ext, used, ref, sName, nc, mustSupport);
|
||||
if (element.hasSlicing()) {
|
||||
if (standardExtensionSlicing(element)) {
|
||||
used.used = true; // doesn't matter whether we have a type, we're used if we're setting up slicing ... element.hasType() && element.getType().get(0).hasProfile();
|
||||
|
@ -3624,7 +3625,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (!child.hasSliceName())
|
||||
currRow = row;
|
||||
if (logicalModel || !child.getPath().endsWith(".id") || (child.getPath().endsWith(".id") && (profile != null) && (profile.getDerivation() == TypeDerivationRule.CONSTRAINT)))
|
||||
currRow = genElement(defPath, gen, currRow.getSubRows(), child, all, profiles, showMissing, profileBaseFileName, isExtension, snapshot, corePath, imagePath, false, logicalModel, isConstraintMode, allInvariants, currRow);
|
||||
currRow = genElement(defPath, gen, currRow.getSubRows(), child, all, profiles, showMissing, profileBaseFileName, isExtension, snapshot, corePath, imagePath, false, logicalModel, isConstraintMode, allInvariants, currRow, mustSupport);
|
||||
}
|
||||
// if (!snapshot && (extensions == null || !extensions))
|
||||
// for (ElementDefinition child : children)
|
||||
|
@ -3654,7 +3655,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
|
||||
public List<Cell> genElementCells(HierarchicalTableGenerator gen, ElementDefinition element, String profileBaseFileName, boolean snapshot, String corePath,
|
||||
String imagePath, boolean root, boolean logicalModel, boolean allInvariants, StructureDefinition profile, Row typesRow, Row row, boolean hasDef,
|
||||
boolean ext, UnusedTracker used, String ref, String sName, Cell nameCell) throws IOException {
|
||||
boolean ext, UnusedTracker used, String ref, String sName, Cell nameCell, boolean mustSupport) throws IOException {
|
||||
List<Cell> res = new ArrayList<>();
|
||||
Cell gc = gen.new Cell();
|
||||
row.getCells().add(gc);
|
||||
|
@ -3680,7 +3681,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (extDefn == null) {
|
||||
res.add(genCardinality(gen, element, row, hasDef, used, null));
|
||||
res.add(addCell(row, gen.new Cell(null, null, "?gen-e1? "+element.getType().get(0).getProfile(), null, null)));
|
||||
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, profile.getUrl(), eurl, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot));
|
||||
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, profile.getUrl(), eurl, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport));
|
||||
} else {
|
||||
String name = urltail(eurl);
|
||||
nameCell.getPieces().get(0).setText(name);
|
||||
|
@ -3693,7 +3694,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
else // if it's complex, we just call it nothing
|
||||
// genTypes(gen, row, extDefn.getSnapshot().getElement().get(0), profileBaseFileName, profile);
|
||||
res.add(addCell(row, gen.new Cell(null, null, "("+translate("sd.table", "Complex")+")", null, null)));
|
||||
res.add(generateDescription(gen, row, element, extDefn.getElement(), used.used, null, extDefn.getUrl(), profile, corePath, imagePath, root, logicalModel, allInvariants, valueDefn, snapshot));
|
||||
res.add(generateDescription(gen, row, element, extDefn.getElement(), used.used, null, extDefn.getUrl(), profile, corePath, imagePath, root, logicalModel, allInvariants, valueDefn, snapshot, mustSupport));
|
||||
}
|
||||
} else {
|
||||
res.add(genCardinality(gen, element, row, hasDef, used, null));
|
||||
|
@ -3701,7 +3702,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
res.add(addCell(row, gen.new Cell()));
|
||||
else
|
||||
res.add(genTypes(gen, row, element, profileBaseFileName, profile, corePath, imagePath, root));
|
||||
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot));
|
||||
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport));
|
||||
}
|
||||
} else {
|
||||
res.add(genCardinality(gen, element, row, hasDef, used, null));
|
||||
|
@ -3711,7 +3712,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
res.add(genTypes(gen, row, element, profileBaseFileName, profile, corePath, imagePath, root));
|
||||
else
|
||||
res.add(addCell(row, gen.new Cell()));
|
||||
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot));
|
||||
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -3963,11 +3964,11 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
&& element.getSlicing().getRules() != SlicingRules.CLOSED && element.getSlicing().getDiscriminator().size() == 1 && element.getSlicing().getDiscriminator().get(0).getPath().equals("url") && element.getSlicing().getDiscriminator().get(0).getType().equals(DiscriminatorType.VALUE);
|
||||
}
|
||||
|
||||
private Cell generateDescription(HierarchicalTableGenerator gen, Row row, ElementDefinition definition, ElementDefinition fallback, boolean used, String baseURL, String url, StructureDefinition profile, String corePath, String imagePath, boolean root, boolean logicalModel, boolean allInvariants, boolean snapshot) throws IOException, FHIRException {
|
||||
return generateDescription(gen, row, definition, fallback, used, baseURL, url, profile, corePath, imagePath, root, logicalModel, allInvariants, null, snapshot);
|
||||
private Cell generateDescription(HierarchicalTableGenerator gen, Row row, ElementDefinition definition, ElementDefinition fallback, boolean used, String baseURL, String url, StructureDefinition profile, String corePath, String imagePath, boolean root, boolean logicalModel, boolean allInvariants, boolean snapshot, boolean mustSupportOnly) throws IOException, FHIRException {
|
||||
return generateDescription(gen, row, definition, fallback, used, baseURL, url, profile, corePath, imagePath, root, logicalModel, allInvariants, null, snapshot, mustSupportOnly);
|
||||
}
|
||||
|
||||
private Cell generateDescription(HierarchicalTableGenerator gen, Row row, ElementDefinition definition, ElementDefinition fallback, boolean used, String baseURL, String url, StructureDefinition profile, String corePath, String imagePath, boolean root, boolean logicalModel, boolean allInvariants, ElementDefinition valueDefn, boolean snapshot) throws IOException, FHIRException {
|
||||
private Cell generateDescription(HierarchicalTableGenerator gen, Row row, ElementDefinition definition, ElementDefinition fallback, boolean used, String baseURL, String url, StructureDefinition profile, String corePath, String imagePath, boolean root, boolean logicalModel, boolean allInvariants, ElementDefinition valueDefn, boolean snapshot, boolean mustSupportOnly) throws IOException, FHIRException {
|
||||
Cell c = gen.new Cell();
|
||||
row.getCells().add(c);
|
||||
|
||||
|
@ -4104,7 +4105,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(link, s, null).addStyle("color: darkgreen")));
|
||||
} else {
|
||||
c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(null, "As shown", null).addStyle("color: darkgreen")));
|
||||
genFixedValue(gen, row, definition.getFixed(), snapshot, false, corePath);
|
||||
genFixedValue(gen, row, definition.getFixed(), snapshot, false, corePath, mustSupportOnly);
|
||||
}
|
||||
if (isCoded(definition.getFixed()) && !hasDescription(definition.getFixed())) {
|
||||
Piece p = describeCoded(gen, definition.getFixed());
|
||||
|
@ -4118,7 +4119,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, buildJson(definition.getPattern()), null).addStyle("color: darkgreen")));
|
||||
else {
|
||||
c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, "At least the following", null).addStyle("color: darkgreen")));
|
||||
genFixedValue(gen, row, definition.getPattern(), snapshot, true, corePath);
|
||||
genFixedValue(gen, row, definition.getPattern(), snapshot, true, corePath, false);
|
||||
}
|
||||
} else if (definition.hasExample()) {
|
||||
for (ElementDefinitionExampleComponent ex : definition.getExample()) {
|
||||
|
@ -4154,7 +4155,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
return c;
|
||||
}
|
||||
|
||||
private void genFixedValue(HierarchicalTableGenerator gen, Row erow, DataType value, boolean snapshot, boolean pattern, String corePath) {
|
||||
private void genFixedValue(HierarchicalTableGenerator gen, Row erow, DataType value, boolean snapshot, boolean pattern, String corePath, boolean skipnoValue) {
|
||||
String ref = pkp.getLinkFor(corePath, value.fhirType());
|
||||
if (ref != null) {
|
||||
ref = ref.substring(0, ref.indexOf(".html"))+"-definitions.html#";
|
||||
|
@ -4167,47 +4168,49 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (t.getValues().size() > 0 || snapshot) {
|
||||
ElementDefinition ed = findElementDefinition(sd, t.getName());
|
||||
if (t.getValues().size() == 0 || (t.getValues().size() == 1 && t.getValues().get(0).isEmpty())) {
|
||||
Row row = gen.new Row();
|
||||
erow.getSubRows().add(row);
|
||||
Cell c = gen.new Cell();
|
||||
row.getCells().add(c);
|
||||
c.addPiece(gen.new Piece((ed.getBase().getPath().equals(ed.getPath()) ? ref+ed.getPath() : corePath+(VersionUtilities.isThisOrLater("4.1", context.getVersion()) ? "types-definitions.html#"+ed.getBase().getPath() : "element-definitions.html#"+ed.getBase().getPath())), t.getName(), null));
|
||||
c = gen.new Cell();
|
||||
row.getCells().add(c);
|
||||
c.addPiece(gen.new Piece(null, null, null));
|
||||
c = gen.new Cell();
|
||||
row.getCells().add(c);
|
||||
if (!pattern) {
|
||||
c.addPiece(gen.new Piece(null, "0..0", null));
|
||||
row.setIcon("icon_fixed.gif", "Fixed Value" /*HierarchicalTableGenerator.TEXT_ICON_FIXED*/);
|
||||
} else if (isPrimitive(t.getTypeCode())) {
|
||||
row.setIcon("icon_primitive.png", HierarchicalTableGenerator.TEXT_ICON_PRIMITIVE);
|
||||
c.addPiece(gen.new Piece(null, "0.."+(t.getMaxCardinality() == 2147483647 ? "*": Integer.toString(t.getMaxCardinality())), null));
|
||||
} else if (isReference(t.getTypeCode())) {
|
||||
row.setIcon("icon_reference.png", HierarchicalTableGenerator.TEXT_ICON_REFERENCE);
|
||||
c.addPiece(gen.new Piece(null, "0.."+(t.getMaxCardinality() == 2147483647 ? "*": Integer.toString(t.getMaxCardinality())), null));
|
||||
} else {
|
||||
row.setIcon("icon_datatype.gif", HierarchicalTableGenerator.TEXT_ICON_DATATYPE);
|
||||
c.addPiece(gen.new Piece(null, "0.."+(t.getMaxCardinality() == 2147483647 ? "*": Integer.toString(t.getMaxCardinality())), null));
|
||||
}
|
||||
c = gen.new Cell();
|
||||
row.getCells().add(c);
|
||||
if (t.getTypeCode().contains("(")) {
|
||||
String tc = t.getTypeCode();
|
||||
String tn = tc.substring(0, tc.indexOf("("));
|
||||
c.addPiece(gen.new Piece(pkp.getLinkFor(corePath, tn), tn, null));
|
||||
c.addPiece(gen.new Piece(null, "(", null));
|
||||
String[] p = tc.substring(tc.indexOf("(")+1, tc.indexOf(")")).split("\\|");
|
||||
for (String s : p) {
|
||||
c.addPiece(gen.new Piece(pkp.getLinkFor(corePath, s), s, null));
|
||||
if (!skipnoValue) {
|
||||
Row row = gen.new Row();
|
||||
erow.getSubRows().add(row);
|
||||
Cell c = gen.new Cell();
|
||||
row.getCells().add(c);
|
||||
c.addPiece(gen.new Piece((ed.getBase().getPath().equals(ed.getPath()) ? ref+ed.getPath() : corePath+(VersionUtilities.isThisOrLater("4.1", context.getVersion()) ? "types-definitions.html#"+ed.getBase().getPath() : "element-definitions.html#"+ed.getBase().getPath())), t.getName(), null));
|
||||
c = gen.new Cell();
|
||||
row.getCells().add(c);
|
||||
c.addPiece(gen.new Piece(null, null, null));
|
||||
c = gen.new Cell();
|
||||
row.getCells().add(c);
|
||||
if (!pattern) {
|
||||
c.addPiece(gen.new Piece(null, "0..0", null));
|
||||
row.setIcon("icon_fixed.gif", "Fixed Value" /*HierarchicalTableGenerator.TEXT_ICON_FIXED*/);
|
||||
} else if (isPrimitive(t.getTypeCode())) {
|
||||
row.setIcon("icon_primitive.png", HierarchicalTableGenerator.TEXT_ICON_PRIMITIVE);
|
||||
c.addPiece(gen.new Piece(null, "0.."+(t.getMaxCardinality() == 2147483647 ? "*": Integer.toString(t.getMaxCardinality())), null));
|
||||
} else if (isReference(t.getTypeCode())) {
|
||||
row.setIcon("icon_reference.png", HierarchicalTableGenerator.TEXT_ICON_REFERENCE);
|
||||
c.addPiece(gen.new Piece(null, "0.."+(t.getMaxCardinality() == 2147483647 ? "*": Integer.toString(t.getMaxCardinality())), null));
|
||||
} else {
|
||||
row.setIcon("icon_datatype.gif", HierarchicalTableGenerator.TEXT_ICON_DATATYPE);
|
||||
c.addPiece(gen.new Piece(null, "0.."+(t.getMaxCardinality() == 2147483647 ? "*": Integer.toString(t.getMaxCardinality())), null));
|
||||
}
|
||||
c.addPiece(gen.new Piece(null, ")", null));
|
||||
} else {
|
||||
c.addPiece(gen.new Piece(pkp.getLinkFor(corePath, t.getTypeCode()), t.getTypeCode(), null));
|
||||
c = gen.new Cell();
|
||||
row.getCells().add(c);
|
||||
if (t.getTypeCode().contains("(")) {
|
||||
String tc = t.getTypeCode();
|
||||
String tn = tc.substring(0, tc.indexOf("("));
|
||||
c.addPiece(gen.new Piece(pkp.getLinkFor(corePath, tn), tn, null));
|
||||
c.addPiece(gen.new Piece(null, "(", null));
|
||||
String[] p = tc.substring(tc.indexOf("(")+1, tc.indexOf(")")).split("\\|");
|
||||
for (String s : p) {
|
||||
c.addPiece(gen.new Piece(pkp.getLinkFor(corePath, s), s, null));
|
||||
}
|
||||
c.addPiece(gen.new Piece(null, ")", null));
|
||||
} else {
|
||||
c.addPiece(gen.new Piece(pkp.getLinkFor(corePath, t.getTypeCode()), t.getTypeCode(), null));
|
||||
}
|
||||
c = gen.new Cell();
|
||||
c.addPiece(gen.new Piece(null, ed.getShort(), null));
|
||||
row.getCells().add(c);
|
||||
}
|
||||
c = gen.new Cell();
|
||||
c.addPiece(gen.new Piece(null, ed.getShort(), null));
|
||||
row.getCells().add(c);
|
||||
} else {
|
||||
for (Base b : t.getValues()) {
|
||||
Row row = gen.new Row();
|
||||
|
@ -4264,7 +4267,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
c.addPiece(gen.new Piece("br"));
|
||||
c.getPieces().add(gen.new Piece(null, "Fixed Value: ", null).addStyle("font-weight: bold"));
|
||||
c.getPieces().add(gen.new Piece(null, "(complex)", null).addStyle("color: darkgreen"));
|
||||
genFixedValue(gen, row, (DataType) b, snapshot, pattern, corePath);
|
||||
genFixedValue(gen, row, (DataType) b, snapshot, pattern, corePath, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.apache.commons.lang3.Validate;
|
|||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.apache.commons.lang3.time.FastDateFormat;
|
||||
import org.hl7.fhir.utilities.DateTimeUtil;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
@ -283,6 +284,13 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
return getFieldValue(Calendar.MONTH);
|
||||
}
|
||||
|
||||
public float getSecondsMilli() {
|
||||
int sec = getSecond();
|
||||
int milli = getMillis();
|
||||
String s = Integer.toString(sec)+"."+Utilities.padLeft(Integer.toString(milli), '0', 3);
|
||||
return Float.parseFloat(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nanoseconds within the current second
|
||||
* <p>
|
||||
|
@ -855,43 +863,80 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
* Caveat: this implementation assumes local timezone for unspecified timezones
|
||||
*/
|
||||
public Boolean equalsUsingFhirPathRules(BaseDateTimeType theOther) {
|
||||
TemporalPrecisionEnum mp = this.myPrecision == TemporalPrecisionEnum.MILLI ? TemporalPrecisionEnum.SECOND : this.myPrecision;
|
||||
TemporalPrecisionEnum op = theOther.myPrecision == TemporalPrecisionEnum.MILLI ? TemporalPrecisionEnum.SECOND : theOther.myPrecision;
|
||||
TemporalPrecisionEnum cp = (mp.compareTo(op) < 0) ? mp : op;
|
||||
FastDateFormat df = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSS");
|
||||
String ms = df.format(this.getValue());
|
||||
String os = df.format(theOther.getValue());
|
||||
if (!sub(ms, cp.stringLength()).equals(sub(os, cp.stringLength()))) {
|
||||
if (hasTimezone() != theOther.hasTimezone()) {
|
||||
if (!couldBeTheSameTime(this, theOther)) {
|
||||
return false;
|
||||
} else if (getPrecision() != theOther.getPrecision()) {
|
||||
return false;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
BaseDateTimeType left = (BaseDateTimeType) this.copy();
|
||||
BaseDateTimeType right = (BaseDateTimeType) theOther.copy();
|
||||
if (left.hasTimezone() && left.getPrecision().ordinal() > TemporalPrecisionEnum.DAY.ordinal()) {
|
||||
left.setTimeZoneZulu(true);
|
||||
}
|
||||
if (right.hasTimezone() && right.getPrecision().ordinal() > TemporalPrecisionEnum.DAY.ordinal()) {
|
||||
right.setTimeZoneZulu(true);
|
||||
}
|
||||
Integer i = compareTimes(left, right, null);
|
||||
return i == null ? null : i == 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private boolean couldBeTheSameTime(BaseDateTimeType theArg1, BaseDateTimeType theArg2) {
|
||||
long lowLeft = theArg1.getValue().getTime();
|
||||
long highLeft = theArg1.getHighEdge().getValue().getTime();
|
||||
if (!theArg1.hasTimezone()) {
|
||||
lowLeft = lowLeft - (14 * DateUtils.MILLIS_PER_HOUR);
|
||||
highLeft = highLeft + (14 * DateUtils.MILLIS_PER_HOUR);
|
||||
}
|
||||
long lowRight = theArg2.getValue().getTime();
|
||||
long highRight = theArg2.getHighEdge().getValue().getTime();
|
||||
if (!theArg2.hasTimezone()) {
|
||||
lowRight = lowRight - (14 * DateUtils.MILLIS_PER_HOUR);
|
||||
highRight = highRight + (14 * DateUtils.MILLIS_PER_HOUR);
|
||||
}
|
||||
System.out.print("["+((lowLeft / 1000) - 130000000)+"-"+((highLeft / 1000) - 130000000)+"] vs ["+((lowRight / 1000) - 130000000)+"-"+((highRight / 1000) - 130000000)+"] = ");
|
||||
if (highRight < lowLeft) {
|
||||
System.out.println("false");
|
||||
return false;
|
||||
}
|
||||
if (mp != op) {
|
||||
return null;
|
||||
}
|
||||
if (this.myPrecision == TemporalPrecisionEnum.MILLI || theOther.myPrecision == TemporalPrecisionEnum.MILLI) {
|
||||
float mf = Float.parseFloat(ms.substring(17));
|
||||
float of = Float.parseFloat(os.substring(17));
|
||||
if (mf != of) {
|
||||
return false;
|
||||
}
|
||||
if (highLeft < lowRight) {
|
||||
System.out.println("false");
|
||||
return false;
|
||||
}
|
||||
System.out.println("true");
|
||||
return true;
|
||||
}
|
||||
|
||||
private String sub(String ms, int i) {
|
||||
return ms.length() < i ? ms : ms.substring(0, i);
|
||||
}
|
||||
|
||||
private boolean couldBeTheSameTime(BaseDateTimeType theArg1, BaseDateTimeType theArg2) {
|
||||
boolean theCouldBeTheSameTime = false;
|
||||
if (theArg1.getTimeZone() == null && theArg2.getTimeZone() != null) {
|
||||
long lowLeft = new DateTimeType(theArg1.getValueAsString()+"Z").getValue().getTime() - (14 * DateUtils.MILLIS_PER_HOUR);
|
||||
long highLeft = new DateTimeType(theArg1.getValueAsString()+"Z").getValue().getTime() + (14 * DateUtils.MILLIS_PER_HOUR);
|
||||
long right = theArg2.getValue().getTime();
|
||||
if (right >= lowLeft && right <= highLeft) {
|
||||
theCouldBeTheSameTime = true;
|
||||
}
|
||||
}
|
||||
return theCouldBeTheSameTime;
|
||||
private BaseDateTimeType getHighEdge() {
|
||||
BaseDateTimeType result = (BaseDateTimeType) copy();
|
||||
switch (getPrecision()) {
|
||||
case DAY:
|
||||
result.add(Calendar.DATE, 1);
|
||||
break;
|
||||
case MILLI:
|
||||
break;
|
||||
case MINUTE:
|
||||
result.add(Calendar.MINUTE, 1);
|
||||
break;
|
||||
case MONTH:
|
||||
result.add(Calendar.MONTH, 1);
|
||||
break;
|
||||
case SECOND:
|
||||
result.add(Calendar.SECOND, 1);
|
||||
break;
|
||||
case YEAR:
|
||||
result.add(Calendar.YEAR, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
boolean hasTimezoneIfRequired() {
|
||||
|
@ -904,4 +949,65 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
return getTimeZone() != null;
|
||||
}
|
||||
|
||||
public static Integer compareTimes(BaseDateTimeType left, BaseDateTimeType right, Integer def) {
|
||||
if (left.getYear() < right.getYear()) {
|
||||
return -1;
|
||||
} else if (left.getYear() > right.getYear()) {
|
||||
return 1;
|
||||
} else if (left.getPrecision() == TemporalPrecisionEnum.YEAR && right.getPrecision() == TemporalPrecisionEnum.YEAR) {
|
||||
return 0;
|
||||
} else if (left.getPrecision() == TemporalPrecisionEnum.YEAR || right.getPrecision() == TemporalPrecisionEnum.YEAR) {
|
||||
return def;
|
||||
}
|
||||
|
||||
if (left.getMonth() < right.getMonth()) {
|
||||
return -1;
|
||||
} else if (left.getMonth() > right.getMonth()) {
|
||||
return 1;
|
||||
} else if (left.getPrecision() == TemporalPrecisionEnum.MONTH && right.getPrecision() == TemporalPrecisionEnum.MONTH) {
|
||||
return 0;
|
||||
} else if (left.getPrecision() == TemporalPrecisionEnum.MONTH || right.getPrecision() == TemporalPrecisionEnum.MONTH) {
|
||||
return def;
|
||||
}
|
||||
|
||||
if (left.getDay() < right.getDay()) {
|
||||
return -1;
|
||||
} else if (left.getDay() > right.getDay()) {
|
||||
return 1;
|
||||
} else if (left.getPrecision() == TemporalPrecisionEnum.DAY && right.getPrecision() == TemporalPrecisionEnum.DAY) {
|
||||
return 0;
|
||||
} else if (left.getPrecision() == TemporalPrecisionEnum.DAY || right.getPrecision() == TemporalPrecisionEnum.DAY) {
|
||||
return def;
|
||||
}
|
||||
|
||||
if (left.getHour() < right.getHour()) {
|
||||
return -1;
|
||||
} else if (left.getHour() > right.getHour()) {
|
||||
return 1;
|
||||
// hour is not a valid precision
|
||||
// } else if (dateLeft.getPrecision() == TemporalPrecisionEnum.YEAR && dateRight.getPrecision() == TemporalPrecisionEnum.YEAR) {
|
||||
// return 0;
|
||||
// } else if (dateLeft.getPrecision() == TemporalPrecisionEnum.HOUR || dateRight.getPrecision() == TemporalPrecisionEnum.HOUR) {
|
||||
// return null;
|
||||
}
|
||||
|
||||
if (left.getMinute() < right.getMinute()) {
|
||||
return -1;
|
||||
} else if (left.getMinute() > right.getMinute()) {
|
||||
return 1;
|
||||
} else if (left.getPrecision() == TemporalPrecisionEnum.MINUTE && right.getPrecision() == TemporalPrecisionEnum.MINUTE) {
|
||||
return 0;
|
||||
} else if (left.getPrecision() == TemporalPrecisionEnum.MINUTE || right.getPrecision() == TemporalPrecisionEnum.MINUTE) {
|
||||
return def;
|
||||
}
|
||||
|
||||
if (left.getSecondsMilli() < right.getSecondsMilli()) {
|
||||
return -1;
|
||||
} else if (left.getSecondsMilli() > right.getSecondsMilli()) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -72,7 +72,9 @@ public class ExpressionNode {
|
|||
Empty, Not, Exists, SubsetOf, SupersetOf, IsDistinct, Distinct, Count, Where, Select, All, Repeat, Aggregate, Item /*implicit from name[]*/, As, Is, Single,
|
||||
First, Last, Tail, Skip, Take, Union, Combine, Intersect, Exclude, Iif, Upper, Lower, ToChars, IndexOf, Substring, StartsWith, EndsWith, Matches, ReplaceMatches, Contains, Replace, Length,
|
||||
Children, Descendants, MemberOf, Trace, Check, Today, Now, Resolve, Extension, AllFalse, AnyFalse, AllTrue, AnyTrue,
|
||||
HasValue, OfType, Type, ConvertsToBoolean, ConvertsToInteger, ConvertsToString, ConvertsToDecimal, ConvertsToQuantity, ConvertsToDateTime, ConvertsToTime, ToBoolean, ToInteger, ToString, ToDecimal, ToQuantity, ToDateTime, ToTime, ConformsTo,
|
||||
HasValue, OfType, Type, ConvertsToBoolean, ConvertsToInteger, ConvertsToString, ConvertsToDecimal, ConvertsToQuantity, ConvertsToDateTime, ConvertsToDate, ConvertsToTime, ToBoolean, ToInteger, ToString, ToDecimal, ToQuantity, ToDateTime, ToTime, ConformsTo,
|
||||
Round, Sqrt, Abs, Ceiling, Exp, Floor, Ln, Log, Power, Truncate,
|
||||
|
||||
// R3 functions
|
||||
Encode, Decode, Escape, Unescape, Trim, Split, Join,
|
||||
// Local extensions to FHIRPath
|
||||
|
@ -159,8 +161,19 @@ public class ExpressionNode {
|
|||
if (name.equals("convertsToQuantity")) return Function.ConvertsToQuantity;
|
||||
if (name.equals("convertsToBoolean")) return Function.ConvertsToBoolean;
|
||||
if (name.equals("convertsToDateTime")) return Function.ConvertsToDateTime;
|
||||
if (name.equals("convertsToDate")) return Function.ConvertsToDate;
|
||||
if (name.equals("convertsToTime")) return Function.ConvertsToTime;
|
||||
if (name.equals("conformsTo")) return Function.ConformsTo;
|
||||
if (name.equals("round")) return Function.Round;
|
||||
if (name.equals("sqrt")) return Function.Sqrt;
|
||||
if (name.equals("abs")) return Function.Abs;
|
||||
if (name.equals("ceiling")) return Function.Ceiling;
|
||||
if (name.equals("exp")) return Function.Exp;
|
||||
if (name.equals("floor")) return Function.Floor;
|
||||
if (name.equals("ln")) return Function.Ln;
|
||||
if (name.equals("log")) return Function.Log;
|
||||
if (name.equals("power")) return Function.Power;
|
||||
if (name.equals("truncate")) return Function.Truncate;
|
||||
return null;
|
||||
}
|
||||
public String toCode() {
|
||||
|
@ -244,8 +257,20 @@ public class ExpressionNode {
|
|||
case ConvertsToBoolean : return "convertsToBoolean";
|
||||
case ConvertsToQuantity : return "convertsToQuantity";
|
||||
case ConvertsToDateTime : return "convertsToDateTime";
|
||||
case ConvertsToDate : return "convertsToDate";
|
||||
case ConvertsToTime : return "isTime";
|
||||
case ConformsTo : return "conformsTo";
|
||||
case Round : return "round";
|
||||
case Sqrt : return "sqrt";
|
||||
case Abs : return "abs";
|
||||
case Ceiling : return "ceiling";
|
||||
case Exp : return "exp";
|
||||
case Floor : return "floor";
|
||||
case Ln : return "ln";
|
||||
case Log : return "log";
|
||||
case Power : return "power";
|
||||
case Truncate: return "truncate";
|
||||
|
||||
default: return "?custom?";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ package org.hl7.fhir.r5.model;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.utilities.MergedList.IMatcher;
|
||||
|
||||
/**
|
||||
* A child element or property defined by the FHIR specification
|
||||
* This class is defined as a helper class when iterating the
|
||||
|
@ -47,7 +49,17 @@ import java.util.List;
|
|||
*/
|
||||
public class Property {
|
||||
|
||||
/**
|
||||
public static class PropertyMatcher implements IMatcher<Property> {
|
||||
|
||||
@Override
|
||||
public boolean match(Property l, Property r) {
|
||||
return l.getName().equals(r.getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The name of the property as found in the FHIR specification
|
||||
*/
|
||||
private String name;
|
||||
|
|
|
@ -624,6 +624,13 @@ public class Quantity extends DataType implements ICompositeType, ICoding {
|
|||
res.setCode(code);
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getValue().toPlainString()+ (hasUnit() || hasCode() ? " '"+(hasUnit() ? getUnit() : getCode())+"'" : "");
|
||||
}
|
||||
|
||||
|
||||
// end addition
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
package org.hl7.fhir.r5.model;
|
||||
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
@ -77,4 +81,67 @@ public class TimeType extends PrimitiveType<String> {
|
|||
return "time";
|
||||
}
|
||||
|
||||
public int getHour() {
|
||||
String v = getValue();
|
||||
if (v.length() < 2) {
|
||||
return 0;
|
||||
}
|
||||
v = v.substring(0, 2);
|
||||
if (!Utilities.isInteger(v)) {
|
||||
return 0;
|
||||
}
|
||||
return Integer.parseInt(v);
|
||||
}
|
||||
|
||||
public int getMinute() {
|
||||
String v = getValue();
|
||||
if (v.length() < 5) {
|
||||
return 0;
|
||||
}
|
||||
v = v.substring(3, 5);
|
||||
if (!Utilities.isInteger(v)) {
|
||||
return 0;
|
||||
}
|
||||
return Integer.parseInt(v);
|
||||
}
|
||||
|
||||
public float getSecond() {
|
||||
String v = getValue();
|
||||
if (v.length() < 8) {
|
||||
return 0;
|
||||
}
|
||||
v = v.substring(6);
|
||||
if (!Utilities.isDecimal(v, false, true)) {
|
||||
return 0;
|
||||
}
|
||||
return Float.parseFloat(v);
|
||||
}
|
||||
|
||||
public TemporalPrecisionEnum getPrecision() {
|
||||
String v = getValue();
|
||||
// if (v.length() == 2) {
|
||||
// return TemporalPrecisionEnum.HOUR;
|
||||
// }
|
||||
if (v.length() == 5) {
|
||||
return TemporalPrecisionEnum.MINUTE;
|
||||
}
|
||||
if (v.length() == 8) {
|
||||
return TemporalPrecisionEnum.SECOND;
|
||||
}
|
||||
if (v.length() > 9) {
|
||||
return TemporalPrecisionEnum.MILLI;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setPrecision(TemporalPrecisionEnum temp) {
|
||||
if (temp == TemporalPrecisionEnum.MINUTE) {
|
||||
setValue(getValue().substring(0, 5));
|
||||
}
|
||||
if (temp == TemporalPrecisionEnum.SECOND) {
|
||||
setValue(getValue().substring(0, 8));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -32,6 +32,7 @@ package org.hl7.fhir.r5.model;
|
|||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
@ -57,6 +58,7 @@ public class TypeDetails {
|
|||
public static final String FP_Time = "http://hl7.org/fhirpath/Time";
|
||||
public static final String FP_SimpleTypeInfo = "http://hl7.org/fhirpath/SimpleTypeInfo";
|
||||
public static final String FP_ClassInfo = "http://hl7.org/fhirpath/ClassInfo";
|
||||
public static final Set<String> FP_NUMBERS = new HashSet<String>(Arrays.asList(FP_Integer, FP_Decimal));
|
||||
|
||||
public static class ProfiledType {
|
||||
private String uri;
|
||||
|
|
|
@ -312,7 +312,11 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
|
|||
} else if (e instanceof Identifier) {
|
||||
renderIdentifier(x, (Identifier) e);
|
||||
} else if (e instanceof org.hl7.fhir.r5.model.IntegerType) {
|
||||
x.addText(Integer.toString(((org.hl7.fhir.r5.model.IntegerType) e).getValue()));
|
||||
if (((org.hl7.fhir.r5.model.IntegerType) e).hasValue()) {
|
||||
x.addText(Integer.toString(((org.hl7.fhir.r5.model.IntegerType) e).getValue()));
|
||||
} else {
|
||||
x.addText("??");
|
||||
}
|
||||
} else if (e instanceof org.hl7.fhir.r5.model.DecimalType) {
|
||||
x.addText(((org.hl7.fhir.r5.model.DecimalType) e).getValue().toString());
|
||||
} else if (e instanceof HumanName) {
|
||||
|
|
|
@ -89,18 +89,18 @@ public class ProvenanceRenderer extends ResourceRenderer {
|
|||
hasRole = hasRole || a.hasRole();
|
||||
hasOnBehalfOf = hasOnBehalfOf || a.hasOnBehalfOf();
|
||||
}
|
||||
x.para().tx("Agents");
|
||||
x.para().b().tx("Agents");
|
||||
t = x.table("grid");
|
||||
tr = t.tr();
|
||||
if (hasType) {
|
||||
tr.td().b().tx("type");
|
||||
tr.td().b().tx("Type");
|
||||
}
|
||||
if (hasRole) {
|
||||
tr.td().b().tx("role");
|
||||
tr.td().b().tx("Role");
|
||||
}
|
||||
tr.td().b().tx("who");
|
||||
if (hasOnBehalfOf) {
|
||||
tr.td().b().tx("onBehalfOf");
|
||||
tr.td().b().tx("On Behalf Of");
|
||||
}
|
||||
for (ProvenanceAgentComponent a : prv.getAgent()) {
|
||||
tr = t.tr();
|
||||
|
|
|
@ -28,7 +28,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
|||
}
|
||||
|
||||
public boolean render(XhtmlNode x, StructureDefinition sd) throws FHIRFormatError, DefinitionException, IOException {
|
||||
x.getChildNodes().add(context.getProfileUtilities().generateTable(context.getDefinitionsTarget(), sd, true, context.getDestDir(), false, sd.getId(), false, context.getSpecificationLink(), "", false, false, null, false));
|
||||
x.getChildNodes().add(context.getProfileUtilities().generateTable(context.getDefinitionsTarget(), sd, true, context.getDestDir(), false, sd.getId(), false, context.getSpecificationLink(), "", false, false, null, false, false));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.hl7.fhir.r5.utils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.rmi.server.LoaderHandler;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
|
@ -38,6 +39,7 @@ import org.hl7.fhir.r5.model.ExpressionNode.Function;
|
|||
import org.hl7.fhir.r5.model.ExpressionNode.Kind;
|
||||
import org.hl7.fhir.r5.model.ExpressionNode.Operation;
|
||||
import org.hl7.fhir.r5.model.ExpressionNode.SourceLocation;
|
||||
import org.hl7.fhir.r5.model.Property.PropertyMatcher;
|
||||
import org.hl7.fhir.r5.model.IntegerType;
|
||||
import org.hl7.fhir.r5.model.Property;
|
||||
import org.hl7.fhir.r5.model.Quantity;
|
||||
|
@ -54,6 +56,8 @@ import org.hl7.fhir.r5.model.ValueSet;
|
|||
import org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException;
|
||||
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext.FunctionDetails;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
import org.hl7.fhir.utilities.MergedList;
|
||||
import org.hl7.fhir.utilities.MergedList.MergeNode;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
|
@ -539,30 +543,59 @@ public class FHIRPathEngine {
|
|||
return check(appContext, resourceType, context, parse(expr));
|
||||
}
|
||||
|
||||
private int compareDateTimeElements(Base theL, Base theR, boolean theEquivalenceTest) {
|
||||
String dateLeftString = theL.primitiveValue();
|
||||
DateTimeType dateLeft = new DateTimeType(dateLeftString);
|
||||
|
||||
String dateRightString = theR.primitiveValue();
|
||||
DateTimeType dateRight = new DateTimeType(dateRightString);
|
||||
private Integer compareDateTimeElements(Base theL, Base theR, boolean theEquivalenceTest) {
|
||||
DateTimeType left = theL instanceof DateTimeType ? (DateTimeType) theL : new DateTimeType(theL.primitiveValue());
|
||||
DateTimeType right = theR instanceof DateTimeType ? (DateTimeType) theR : new DateTimeType(theR.primitiveValue());
|
||||
|
||||
if (theEquivalenceTest) {
|
||||
return dateLeft.equalsUsingFhirPathRules(dateRight) == Boolean.TRUE ? 0 : 1;
|
||||
return left.equalsUsingFhirPathRules(right) == Boolean.TRUE ? 0 : 1;
|
||||
}
|
||||
|
||||
if (dateLeft.getPrecision().ordinal() > TemporalPrecisionEnum.DAY.ordinal()) {
|
||||
dateLeft.setTimeZoneZulu(true);
|
||||
if (left.getPrecision().ordinal() > TemporalPrecisionEnum.DAY.ordinal()) {
|
||||
left.setTimeZoneZulu(true);
|
||||
}
|
||||
if (dateRight.getPrecision().ordinal() > TemporalPrecisionEnum.DAY.ordinal()) {
|
||||
dateRight.setTimeZoneZulu(true);
|
||||
if (right.getPrecision().ordinal() > TemporalPrecisionEnum.DAY.ordinal()) {
|
||||
right.setTimeZoneZulu(true);
|
||||
}
|
||||
|
||||
dateLeftString = dateLeft.getValueAsString();
|
||||
dateRightString = dateRight.getValueAsString();
|
||||
|
||||
return dateLeftString.compareTo(dateRightString);
|
||||
return BaseDateTimeType.compareTimes(left, right, null);
|
||||
}
|
||||
|
||||
private Integer compareTimeElements(Base theL, Base theR, boolean theEquivalenceTest) {
|
||||
TimeType left = theL instanceof TimeType ? (TimeType) theL : new TimeType(theL.primitiveValue());
|
||||
TimeType right = theR instanceof TimeType ? (TimeType) theR : new TimeType(theR.primitiveValue());
|
||||
|
||||
if (left.getHour() < right.getHour()) {
|
||||
return -1;
|
||||
} else if (left.getHour() > right.getHour()) {
|
||||
return 1;
|
||||
// hour is not a valid precision
|
||||
// } else if (dateLeft.getPrecision() == TemporalPrecisionEnum.YEAR && dateRight.getPrecision() == TemporalPrecisionEnum.YEAR) {
|
||||
// return 0;
|
||||
// } else if (dateLeft.getPrecision() == TemporalPrecisionEnum.HOUR || dateRight.getPrecision() == TemporalPrecisionEnum.HOUR) {
|
||||
// return null;
|
||||
}
|
||||
|
||||
if (left.getMinute() < right.getMinute()) {
|
||||
return -1;
|
||||
} else if (left.getMinute() > right.getMinute()) {
|
||||
return 1;
|
||||
} else if (left.getPrecision() == TemporalPrecisionEnum.MINUTE && right.getPrecision() == TemporalPrecisionEnum.MINUTE) {
|
||||
return 0;
|
||||
} else if (left.getPrecision() == TemporalPrecisionEnum.MINUTE || right.getPrecision() == TemporalPrecisionEnum.MINUTE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (left.getSecond() < right.getSecond()) {
|
||||
return -1;
|
||||
} else if (left.getSecond() > right.getSecond()) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* evaluate a path and return the matching elements
|
||||
*
|
||||
|
@ -1239,8 +1272,19 @@ public class FHIRPathEngine {
|
|||
case ConvertsToQuantity: return checkParamCount(lexer, location, exp, 0);
|
||||
case ConvertsToBoolean: return checkParamCount(lexer, location, exp, 0);
|
||||
case ConvertsToDateTime: return checkParamCount(lexer, location, exp, 0);
|
||||
case ConvertsToDate: return checkParamCount(lexer, location, exp, 0);
|
||||
case ConvertsToTime: return checkParamCount(lexer, location, exp, 0);
|
||||
case ConformsTo: return checkParamCount(lexer, location, exp, 1);
|
||||
case Round: return checkParamCount(lexer, location, exp, 0, 1);
|
||||
case Sqrt: return checkParamCount(lexer, location, exp, 0);
|
||||
case Abs: return checkParamCount(lexer, location, exp, 0);
|
||||
case Ceiling: return checkParamCount(lexer, location, exp, 0);
|
||||
case Exp: return checkParamCount(lexer, location, exp, 0);
|
||||
case Floor: return checkParamCount(lexer, location, exp, 0);
|
||||
case Ln: return checkParamCount(lexer, location, exp, 0);
|
||||
case Log: return checkParamCount(lexer, location, exp, 1);
|
||||
case Power: return checkParamCount(lexer, location, exp, 1);
|
||||
case Truncate: return checkParamCount(lexer, location, exp, 0);
|
||||
case Custom: return checkParamCount(lexer, location, exp, details.getMinParameters(), details.getMaxParameters());
|
||||
}
|
||||
return false;
|
||||
|
@ -1378,7 +1422,9 @@ public class FHIRPathEngine {
|
|||
result.update(evaluateFunctionType(context, focus, exp));
|
||||
break;
|
||||
case Unary:
|
||||
result.addType("integer");
|
||||
result.addType(TypeDetails.FP_Integer);
|
||||
result.addType(TypeDetails.FP_Decimal);
|
||||
result.addType(TypeDetails.FP_Quantity);
|
||||
break;
|
||||
case Constant:
|
||||
result.update(resolveConstantType(context, exp.getConstant()));
|
||||
|
@ -1426,23 +1472,65 @@ public class FHIRPathEngine {
|
|||
}
|
||||
|
||||
private Base processDateConstant(Object appInfo, String value) throws PathEngineException {
|
||||
if (value.startsWith("T"))
|
||||
return new TimeType(value.substring(1)).noExtensions();
|
||||
String v = value;
|
||||
if (v.length() > 10) {
|
||||
int i = v.substring(10).indexOf("-");
|
||||
if (i == -1) {
|
||||
i = v.substring(10).indexOf("+");
|
||||
String date = null;
|
||||
String time = null;
|
||||
String tz = null;
|
||||
|
||||
TemporalPrecisionEnum temp = null;
|
||||
|
||||
if (value.startsWith("T")) {
|
||||
time = value.substring(1);
|
||||
} else if (!value.contains("T")) {
|
||||
date = value;
|
||||
} else {
|
||||
String[] p = value.split("T");
|
||||
date = p[0];
|
||||
if (p.length > 1) {
|
||||
time = p[1];
|
||||
}
|
||||
if (i == -1) {
|
||||
i = v.substring(10).indexOf("Z");
|
||||
}
|
||||
v = i == -1 ? value : v.substring(0, 10+i);
|
||||
}
|
||||
if (v.length() > 10) {
|
||||
return new DateTimeType(value).noExtensions();
|
||||
|
||||
if (time != null) {
|
||||
int i = time.indexOf("-");
|
||||
if (i == -1) {
|
||||
i = time.indexOf("+");
|
||||
}
|
||||
if (i == -1) {
|
||||
i = time.indexOf("Z");
|
||||
}
|
||||
if (i > -1) {
|
||||
tz = time.substring(i);
|
||||
time = time.substring(0, i);
|
||||
}
|
||||
|
||||
if (time.length() == 2) {
|
||||
time = time+":00:00";
|
||||
temp = TemporalPrecisionEnum.MINUTE;
|
||||
} else if (time.length() == 5) {
|
||||
temp = TemporalPrecisionEnum.MINUTE;
|
||||
time = time+":00";
|
||||
} else if (time.contains(".")) {
|
||||
temp = TemporalPrecisionEnum.MILLI;
|
||||
} else {
|
||||
temp = TemporalPrecisionEnum.SECOND;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (date == null) {
|
||||
if (tz != null) {
|
||||
throw makeException(I18nConstants.FHIRPATH_UNKNOWN_CONTEXT, value);
|
||||
} else {
|
||||
TimeType tt = new TimeType(time);
|
||||
tt.setPrecision(temp);
|
||||
return tt.noExtensions();
|
||||
}
|
||||
} else if (time != null) {
|
||||
DateTimeType dt = new DateTimeType(date+"T"+time+(tz == null ? "" : tz));
|
||||
dt.setPrecision(temp);
|
||||
return dt.noExtensions();
|
||||
} else {
|
||||
return new DateType(value).noExtensions();
|
||||
return new DateType(date).noExtensions();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1655,6 +1743,8 @@ public class FHIRPathEngine {
|
|||
result.addType(TypeDetails.FP_Integer);
|
||||
} else if (left.hasType(worker, "integer", "decimal") && right.hasType(worker, "integer", "decimal")) {
|
||||
result.addType(TypeDetails.FP_Decimal);
|
||||
} else if (left.hasType(worker, "Quantity") && right.hasType(worker, "Quantity")) {
|
||||
result.addType(TypeDetails.FP_Quantity);
|
||||
}
|
||||
return result;
|
||||
case Div:
|
||||
|
@ -1758,7 +1848,7 @@ public class FHIRPathEngine {
|
|||
return left.equals(right);
|
||||
}
|
||||
|
||||
private Boolean compareDates(BaseDateTimeType left, BaseDateTimeType right) {
|
||||
private Boolean datesEqual(BaseDateTimeType left, BaseDateTimeType right) {
|
||||
return left.equalsUsingFhirPathRules(right);
|
||||
}
|
||||
|
||||
|
@ -1766,7 +1856,7 @@ public class FHIRPathEngine {
|
|||
if (left instanceof Quantity && right instanceof Quantity) {
|
||||
return qtyEqual((Quantity) left, (Quantity) right);
|
||||
} else if (left.isDateTime() && right.isDateTime()) {
|
||||
return compareDates(left.dateTimeValue(), right.dateTimeValue());
|
||||
return datesEqual(left.dateTimeValue(), right.dateTimeValue());
|
||||
} else if (left instanceof DecimalType || right instanceof DecimalType) {
|
||||
return decEqual(left.primitiveValue(), right.primitiveValue());
|
||||
} else if (left.isPrimitive() && right.isPrimitive()) {
|
||||
|
@ -1776,7 +1866,6 @@ public class FHIRPathEngine {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean doEquivalent(Base left, Base right) throws PathEngineException {
|
||||
if (left instanceof Quantity && right instanceof Quantity) {
|
||||
return qtyEquivalent((Quantity) left, (Quantity) right);
|
||||
|
@ -1791,13 +1880,44 @@ public class FHIRPathEngine {
|
|||
return Utilities.equivalentNumber(left.primitiveValue(), right.primitiveValue());
|
||||
}
|
||||
if (left.hasType("date", "dateTime", "time", "instant") && right.hasType("date", "dateTime", "time", "instant")) {
|
||||
return compareDateTimeElements(left, right, true) == 0;
|
||||
Integer i = compareDateTimeElements(left, right, true);
|
||||
if (i == null) {
|
||||
i = 0;
|
||||
}
|
||||
return i == 0;
|
||||
}
|
||||
if (left.hasType(FHIR_TYPES_STRING) && right.hasType(FHIR_TYPES_STRING)) {
|
||||
return Utilities.equivalent(convertToString(left), convertToString(right));
|
||||
}
|
||||
|
||||
throw new PathEngineException(String.format("Unable to determine equivalence between %s and %s", left.fhirType(), right.fhirType()));
|
||||
if (left.isPrimitive() && right.isPrimitive()) {
|
||||
return Utilities.equivalent(left.primitiveValue(), right.primitiveValue());
|
||||
}
|
||||
if (!left.isPrimitive() && !right.isPrimitive()) {
|
||||
MergedList<Property> props = new MergedList<Property>(left.children(), right.children(), new PropertyMatcher());
|
||||
for (MergeNode<Property> t : props) {
|
||||
if (t.hasLeft() && t.hasRight()) {
|
||||
if (t.getLeft().hasValues() && t.getRight().hasValues()) {
|
||||
MergedList<Base> values = new MergedList<Base>(t.getLeft().getValues(), t.getRight().getValues());
|
||||
for (MergeNode<Base> v : values) {
|
||||
if (v.hasLeft() && v.hasRight()) {
|
||||
if (!doEquivalent(v.getLeft(), v.getRight())) {
|
||||
return false;
|
||||
}
|
||||
} else if (v.hasLeft() || v.hasRight()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (t.getLeft().hasValues() || t.getRight().hasValues()) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean qtyEqual(Quantity left, Quantity right) {
|
||||
|
@ -1816,7 +1936,7 @@ public class FHIRPathEngine {
|
|||
return null;
|
||||
}
|
||||
try {
|
||||
Pair p = new Pair(new Decimal(q.getValue().toPlainString()), q.getCode());
|
||||
Pair p = new Pair(new Decimal(q.getValue().toPlainString()), q.getCode() == null ? "1" : q.getCode());
|
||||
Pair c = worker.getUcumService().getCanonicalForm(p);
|
||||
return new DecimalType(c.getValue().asDecimal());
|
||||
} catch (UcumException e) {
|
||||
|
@ -1912,9 +2032,19 @@ public class FHIRPathEngine {
|
|||
} else if ((l.hasType("integer") || l.hasType("decimal")) && (r.hasType("integer") || r.hasType("decimal"))) {
|
||||
return makeBoolean(new Double(l.primitiveValue()) < new Double(r.primitiveValue()));
|
||||
} else if ((l.hasType("date", "dateTime", "instant")) && (r.hasType("date", "dateTime", "instant"))) {
|
||||
return makeBoolean(compareDateTimeElements(l, r, false) < 0);
|
||||
Integer i = compareDateTimeElements(l, r, false);
|
||||
if (i == null) {
|
||||
return makeNull();
|
||||
} else {
|
||||
return makeBoolean(i < 0);
|
||||
}
|
||||
} else if ((l.hasType("time")) && (r.hasType("time"))) {
|
||||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) < 0);
|
||||
Integer i = compareTimeElements(l, r, false);
|
||||
if (i == null) {
|
||||
return makeNull();
|
||||
} else {
|
||||
return makeBoolean(i < 0);
|
||||
}
|
||||
} else {
|
||||
throw makeException(I18nConstants.FHIRPATH_CANT_COMPARE, l.fhirType(), r.fhirType());
|
||||
}
|
||||
|
@ -1949,9 +2079,19 @@ public class FHIRPathEngine {
|
|||
} else if ((l.hasType("integer", "decimal", "unsignedInt", "positiveInt")) && (r.hasType("integer", "decimal", "unsignedInt", "positiveInt"))) {
|
||||
return makeBoolean(new Double(l.primitiveValue()) > new Double(r.primitiveValue()));
|
||||
} else if ((l.hasType("date", "dateTime", "instant")) && (r.hasType("date", "dateTime", "instant"))) {
|
||||
return makeBoolean(compareDateTimeElements(l, r, false) > 0);
|
||||
Integer i = compareDateTimeElements(l, r, false);
|
||||
if (i == null) {
|
||||
return makeNull();
|
||||
} else {
|
||||
return makeBoolean(i > 0);
|
||||
}
|
||||
} else if ((l.hasType("time")) && (r.hasType("time"))) {
|
||||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) > 0);
|
||||
Integer i = compareTimeElements(l, r, false);
|
||||
if (i == null) {
|
||||
return makeNull();
|
||||
} else {
|
||||
return makeBoolean(i > 0);
|
||||
}
|
||||
} else {
|
||||
throw makeException(I18nConstants.FHIRPATH_CANT_COMPARE, l.fhirType(), r.fhirType());
|
||||
}
|
||||
|
@ -1987,9 +2127,19 @@ public class FHIRPathEngine {
|
|||
} else if ((l.hasType("integer", "decimal", "unsignedInt", "positiveInt")) && (r.hasType("integer", "decimal", "unsignedInt", "positiveInt"))) {
|
||||
return makeBoolean(new Double(l.primitiveValue()) <= new Double(r.primitiveValue()));
|
||||
} else if ((l.hasType("date", "dateTime", "instant")) && (r.hasType("date", "dateTime", "instant"))) {
|
||||
return makeBoolean(compareDateTimeElements(l, r, false) <= 0);
|
||||
Integer i = compareDateTimeElements(l, r, false);
|
||||
if (i == null) {
|
||||
return makeNull();
|
||||
} else {
|
||||
return makeBoolean(i <= 0);
|
||||
}
|
||||
} else if ((l.hasType("time")) && (r.hasType("time"))) {
|
||||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) <= 0);
|
||||
Integer i = compareTimeElements(l, r, false);
|
||||
if (i == null) {
|
||||
return makeNull();
|
||||
} else {
|
||||
return makeBoolean(i <= 0);
|
||||
}
|
||||
} else {
|
||||
throw makeException(I18nConstants.FHIRPATH_CANT_COMPARE, l.fhirType(), r.fhirType());
|
||||
}
|
||||
|
@ -2027,9 +2177,19 @@ public class FHIRPathEngine {
|
|||
} else if ((l.hasType("integer", "decimal", "unsignedInt", "positiveInt")) && (r.hasType("integer", "decimal", "unsignedInt", "positiveInt"))) {
|
||||
return makeBoolean(new Double(l.primitiveValue()) >= new Double(r.primitiveValue()));
|
||||
} else if ((l.hasType("date", "dateTime", "instant")) && (r.hasType("date", "dateTime", "instant"))) {
|
||||
return makeBoolean(compareDateTimeElements(l, r, false) >= 0);
|
||||
Integer i = compareDateTimeElements(l, r, false);
|
||||
if (i == null) {
|
||||
return makeNull();
|
||||
} else {
|
||||
return makeBoolean(i >= 0);
|
||||
}
|
||||
} else if ((l.hasType("time")) && (r.hasType("time"))) {
|
||||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) >= 0);
|
||||
Integer i = compareTimeElements(l, r, false);
|
||||
if (i == null) {
|
||||
return makeNull();
|
||||
} else {
|
||||
return makeBoolean(i >= 0);
|
||||
}
|
||||
} else {
|
||||
throw makeException(I18nConstants.FHIRPATH_CANT_COMPARE, l.fhirType(), r.fhirType());
|
||||
}
|
||||
|
@ -2336,13 +2496,13 @@ public class FHIRPathEngine {
|
|||
if (left.size() > 1) {
|
||||
throw makeException(I18nConstants.FHIRPATH_LEFT_VALUE_PLURAL, "-");
|
||||
}
|
||||
if (!left.get(0).isPrimitive()) {
|
||||
if (!left.get(0).isPrimitive() && !left.get(0).hasType("Quantity")) {
|
||||
throw makeException(I18nConstants.FHIRPATH_LEFT_VALUE_WRONG_TYPE, "-", left.get(0).fhirType());
|
||||
}
|
||||
if (right.size() > 1) {
|
||||
throw makeException(I18nConstants.FHIRPATH_RIGHT_VALUE_PLURAL, "-");
|
||||
}
|
||||
if (!right.get(0).isPrimitive()) {
|
||||
if (!right.get(0).isPrimitive() && !right.get(0).hasType("Quantity")) {
|
||||
throw makeException(I18nConstants.FHIRPATH_RIGHT_VALUE_WRONG_TYPE, "-", right.get(0).fhirType());
|
||||
}
|
||||
|
||||
|
@ -2354,6 +2514,12 @@ public class FHIRPathEngine {
|
|||
result.add(new IntegerType(Integer.parseInt(l.primitiveValue()) - Integer.parseInt(r.primitiveValue())));
|
||||
} else if (l.hasType("decimal", "integer") && r.hasType("decimal", "integer")) {
|
||||
result.add(new DecimalType(new BigDecimal(l.primitiveValue()).subtract(new BigDecimal(r.primitiveValue()))));
|
||||
} else if (l.hasType("decimal", "integer", "Quantity") && r.hasType("Quantity")) {
|
||||
String s = l.primitiveValue();
|
||||
if ("0".equals(s)) {
|
||||
Quantity qty = (Quantity) r;
|
||||
result.add(qty.copy().setValue(qty.getValue().abs()));
|
||||
}
|
||||
} else {
|
||||
throw makeException(I18nConstants.FHIRPATH_OP_INCOMPATIBLE, "-", left.get(0).fhirType(), right.get(0).fhirType());
|
||||
}
|
||||
|
@ -2388,17 +2554,17 @@ public class FHIRPathEngine {
|
|||
Decimal d2 = new Decimal(r.primitiveValue());
|
||||
result.add(new DecimalType(d1.divide(d2).asDecimal()));
|
||||
} catch (UcumException e) {
|
||||
throw new PathEngineException(e);
|
||||
// just return nothing
|
||||
}
|
||||
} else if (l instanceof Quantity && r instanceof Quantity && worker.getUcumService() != null) {
|
||||
Pair pl = qtyToPair((Quantity) l);
|
||||
Pair pr = qtyToPair((Quantity) r);
|
||||
Pair p;
|
||||
try {
|
||||
p = worker.getUcumService().multiply(pl, pr);
|
||||
p = worker.getUcumService().divideBy(pl, pr);
|
||||
result.add(pairToQty(p));
|
||||
} catch (UcumException e) {
|
||||
throw new PathEngineException(e.getMessage(), e);
|
||||
// just return nothing
|
||||
}
|
||||
} else {
|
||||
throw makeException(I18nConstants.FHIRPATH_OP_INCOMPATIBLE, "/", left.get(0).fhirType(), right.get(0).fhirType());
|
||||
|
@ -2428,7 +2594,10 @@ public class FHIRPathEngine {
|
|||
Base r = right.get(0);
|
||||
|
||||
if (l.hasType("integer") && r.hasType("integer")) {
|
||||
result.add(new IntegerType(Integer.parseInt(l.primitiveValue()) / Integer.parseInt(r.primitiveValue())));
|
||||
int divisor = Integer.parseInt(r.primitiveValue());
|
||||
if (divisor != 0) {
|
||||
result.add(new IntegerType(Integer.parseInt(l.primitiveValue()) / divisor));
|
||||
}
|
||||
} else if (l.hasType("decimal", "integer") && r.hasType("decimal", "integer")) {
|
||||
Decimal d1;
|
||||
try {
|
||||
|
@ -2436,7 +2605,7 @@ public class FHIRPathEngine {
|
|||
Decimal d2 = new Decimal(r.primitiveValue());
|
||||
result.add(new IntegerType(d1.divInt(d2).asDecimal()));
|
||||
} catch (UcumException e) {
|
||||
throw new PathEngineException(e);
|
||||
// just return nothing
|
||||
}
|
||||
} else {
|
||||
throw makeException(I18nConstants.FHIRPATH_OP_INCOMPATIBLE, "div", left.get(0).fhirType(), right.get(0).fhirType());
|
||||
|
@ -2465,7 +2634,10 @@ public class FHIRPathEngine {
|
|||
Base r = right.get(0);
|
||||
|
||||
if (l.hasType("integer") && r.hasType("integer")) {
|
||||
result.add(new IntegerType(Integer.parseInt(l.primitiveValue()) % Integer.parseInt(r.primitiveValue())));
|
||||
int modulus = Integer.parseInt(r.primitiveValue());
|
||||
if (modulus != 0) {
|
||||
result.add(new IntegerType(Integer.parseInt(l.primitiveValue()) % modulus));
|
||||
}
|
||||
} else if (l.hasType("decimal", "integer") && r.hasType("decimal", "integer")) {
|
||||
Decimal d1;
|
||||
try {
|
||||
|
@ -2876,11 +3048,11 @@ public class FHIRPathEngine {
|
|||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
|
||||
}
|
||||
case ToDateTime : {
|
||||
checkContextPrimitive(focus, "toBoolean", false);
|
||||
checkContextPrimitive(focus, "ToDateTime", false);
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_DateTime);
|
||||
}
|
||||
case ToTime : {
|
||||
checkContextPrimitive(focus, "toBoolean", false);
|
||||
checkContextPrimitive(focus, "ToTime", false);
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Time);
|
||||
}
|
||||
case ConvertsToString :
|
||||
|
@ -2891,6 +3063,7 @@ public class FHIRPathEngine {
|
|||
case ConvertsToInteger :
|
||||
case ConvertsToDecimal :
|
||||
case ConvertsToDateTime :
|
||||
case ConvertsToDate :
|
||||
case ConvertsToTime :
|
||||
case ConvertsToBoolean : {
|
||||
checkContextPrimitive(focus, exp.getFunction().toCode(), false);
|
||||
|
@ -2900,6 +3073,42 @@ public class FHIRPathEngine {
|
|||
checkParamTypes(exp.getFunction().toCode(), paramTypes, new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String));
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
|
||||
}
|
||||
case Abs : {
|
||||
checkContextNumerical(focus, "abs");
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, focus.getTypes());
|
||||
}
|
||||
case Truncate :
|
||||
case Floor :
|
||||
case Ceiling : {
|
||||
checkContextDecimal(focus, exp.getFunction().toCode());
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Integer);
|
||||
}
|
||||
|
||||
case Round :{
|
||||
checkContextDecimal(focus, "round");
|
||||
if (paramTypes.size() > 0) {
|
||||
checkParamTypes(exp.getFunction().toCode(), paramTypes, new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Integer));
|
||||
}
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Decimal);
|
||||
}
|
||||
|
||||
case Exp :
|
||||
case Ln :
|
||||
case Sqrt : {
|
||||
checkContextNumerical(focus, exp.getFunction().toCode());
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Decimal);
|
||||
}
|
||||
case Log : {
|
||||
checkContextNumerical(focus, exp.getFunction().toCode());
|
||||
checkParamTypes(exp.getFunction().toCode(), paramTypes, new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_NUMBERS));
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Decimal);
|
||||
}
|
||||
case Power : {
|
||||
checkContextNumerical(focus, exp.getFunction().toCode());
|
||||
checkParamTypes(exp.getFunction().toCode(), paramTypes, new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_NUMBERS));
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, focus.getTypes());
|
||||
}
|
||||
|
||||
case Custom : {
|
||||
return hostServices.checkFunction(context.appInfo, exp.getName(), paramTypes);
|
||||
}
|
||||
|
@ -2962,7 +3171,18 @@ public class FHIRPathEngine {
|
|||
throw makeException(I18nConstants.FHIRPATH_PRIMITIVE_ONLY, name, focus.describe(), primitiveTypes.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkContextNumerical(TypeDetails focus, String name) throws PathEngineException {
|
||||
if (!focus.hasType("integer") && !focus.hasType("decimal") && !focus.hasType("Quantity")) {
|
||||
throw makeException(I18nConstants.FHIRPATH_NUMERICAL_ONLY, name, focus.describe());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkContextDecimal(TypeDetails focus, String name) throws PathEngineException {
|
||||
if (!focus.hasType("decimal") && !focus.hasType("integer")) {
|
||||
throw makeException(I18nConstants.FHIRPATH_DECIMAL_ONLY, name, focus.describe());
|
||||
}
|
||||
}
|
||||
|
||||
private TypeDetails childTypes(TypeDetails focus, String mask) throws PathEngineException, DefinitionException {
|
||||
TypeDetails result = new TypeDetails(CollectionStatus.UNORDERED);
|
||||
|
@ -3061,8 +3281,20 @@ public class FHIRPathEngine {
|
|||
case ConvertsToBoolean : return funcIsBoolean(context, focus, exp);
|
||||
case ConvertsToQuantity : return funcIsQuantity(context, focus, exp);
|
||||
case ConvertsToDateTime : return funcIsDateTime(context, focus, exp);
|
||||
case ConvertsToDate : return funcIsDate(context, focus, exp);
|
||||
case ConvertsToTime : return funcIsTime(context, focus, exp);
|
||||
case ConformsTo : return funcConformsTo(context, focus, exp);
|
||||
case ConformsTo : return funcConformsTo(context, focus, exp);
|
||||
case Round : return funcRound(context, focus, exp);
|
||||
case Sqrt : return funcSqrt(context, focus, exp);
|
||||
case Abs : return funcAbs(context, focus, exp);
|
||||
case Ceiling : return funcCeiling(context, focus, exp);
|
||||
case Exp : return funcExp(context, focus, exp);
|
||||
case Floor : return funcFloor(context, focus, exp);
|
||||
case Ln : return funcLn(context, focus, exp);
|
||||
case Log : return funcLog(context, focus, exp);
|
||||
case Power : return funcPower(context, focus, exp);
|
||||
case Truncate : return funcTruncate(context, focus, exp);
|
||||
|
||||
case Custom: {
|
||||
List<List<Base>> params = new ArrayList<List<Base>>();
|
||||
for (ExpressionNode p : exp.getParameters()) {
|
||||
|
@ -3075,7 +3307,222 @@ public class FHIRPathEngine {
|
|||
}
|
||||
}
|
||||
|
||||
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
|
||||
private List<Base> funcSqrt(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
|
||||
if (focus.size() != 1) {
|
||||
throw makeException(I18nConstants.FHIRPATH_FOCUS_PLURAL, "sqrt", focus.size());
|
||||
}
|
||||
Base base = focus.get(0);
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
if (base.hasType("integer", "decimal", "unsignedInt", "positiveInt")) {
|
||||
Double d = Double.parseDouble(base.primitiveValue());
|
||||
try {
|
||||
result.add(new DecimalType(Math.sqrt(d)));
|
||||
} catch (Exception e) {
|
||||
// just return nothing
|
||||
}
|
||||
} else {
|
||||
makeException(I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "sqrt", "(focus)", base.fhirType(), "integer or decimal");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private List<Base> funcAbs(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
|
||||
if (focus.size() != 1) {
|
||||
throw makeException(I18nConstants.FHIRPATH_FOCUS_PLURAL, "abs", focus.size());
|
||||
}
|
||||
Base base = focus.get(0);
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
if (base.hasType("integer", "decimal", "unsignedInt", "positiveInt")) {
|
||||
Double d = Double.parseDouble(base.primitiveValue());
|
||||
try {
|
||||
result.add(new DecimalType(Math.abs(d)));
|
||||
} catch (Exception e) {
|
||||
// just return nothing
|
||||
}
|
||||
} else if (base.hasType("Quantity")) {
|
||||
Quantity qty = (Quantity) base;
|
||||
result.add(qty.copy().setValue(qty.getValue().abs()));
|
||||
} else {
|
||||
makeException(I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "abs", "(focus)", base.fhirType(), "integer or decimal");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private List<Base> funcCeiling(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
|
||||
if (focus.size() != 1) {
|
||||
throw makeException(I18nConstants.FHIRPATH_FOCUS_PLURAL, "ceiling", focus.size());
|
||||
}
|
||||
Base base = focus.get(0);
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
if (base.hasType("integer", "decimal", "unsignedInt", "positiveInt")) {
|
||||
Double d = Double.parseDouble(base.primitiveValue());
|
||||
try {result.add(new IntegerType((int) Math.ceil(d)));
|
||||
} catch (Exception e) {
|
||||
// just return nothing
|
||||
}
|
||||
} else {
|
||||
makeException(I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "ceiling", "(focus)", base.fhirType(), "integer or decimal");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Base> funcFloor(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
|
||||
if (focus.size() != 1) {
|
||||
throw makeException(I18nConstants.FHIRPATH_FOCUS_PLURAL, "floor", focus.size());
|
||||
}
|
||||
Base base = focus.get(0);
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
if (base.hasType("integer", "decimal", "unsignedInt", "positiveInt")) {
|
||||
Double d = Double.parseDouble(base.primitiveValue());
|
||||
try {
|
||||
result.add(new IntegerType((int) Math.floor(d)));
|
||||
} catch (Exception e) {
|
||||
// just return nothing
|
||||
}
|
||||
} else {
|
||||
makeException(I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "floor", "(focus)", base.fhirType(), "integer or decimal");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private List<Base> funcExp(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
|
||||
if (focus.size() != 1) {
|
||||
throw makeException(I18nConstants.FHIRPATH_FOCUS_PLURAL, "exp", focus.size());
|
||||
}
|
||||
Base base = focus.get(0);
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
if (base.hasType("integer", "decimal", "unsignedInt", "positiveInt")) {
|
||||
Double d = Double.parseDouble(base.primitiveValue());
|
||||
try {
|
||||
result.add(new DecimalType(Math.exp(d)));
|
||||
} catch (Exception e) {
|
||||
// just return nothing
|
||||
}
|
||||
|
||||
} else {
|
||||
makeException(I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "exp", "(focus)", base.fhirType(), "integer or decimal");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private List<Base> funcLn(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
|
||||
if (focus.size() != 1) {
|
||||
throw makeException(I18nConstants.FHIRPATH_FOCUS_PLURAL, "ln", focus.size());
|
||||
}
|
||||
Base base = focus.get(0);
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
if (base.hasType("integer", "decimal", "unsignedInt", "positiveInt")) {
|
||||
Double d = Double.parseDouble(base.primitiveValue());
|
||||
try {
|
||||
result.add(new DecimalType(Math.log(d)));
|
||||
} catch (Exception e) {
|
||||
// just return nothing
|
||||
}
|
||||
} else {
|
||||
makeException(I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "ln", "(focus)", base.fhirType(), "integer or decimal");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private List<Base> funcLog(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
|
||||
if (focus.size() != 1) {
|
||||
throw makeException(I18nConstants.FHIRPATH_FOCUS_PLURAL, "log", focus.size());
|
||||
}
|
||||
Base base = focus.get(0);
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
if (base.hasType("integer", "decimal", "unsignedInt", "positiveInt")) {
|
||||
List<Base> n1 = execute(context, focus, exp.getParameters().get(0), true);
|
||||
if (n1.size() != 1) {
|
||||
throw makeException(I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "log", "0", "Multiple Values", "integer or decimal");
|
||||
}
|
||||
Double e = Double.parseDouble(n1.get(0).primitiveValue());
|
||||
Double d = Double.parseDouble(base.primitiveValue());
|
||||
try {
|
||||
result.add(new DecimalType(customLog(e, d)));
|
||||
} catch (Exception ex) {
|
||||
// just return nothing
|
||||
}
|
||||
} else {
|
||||
makeException(I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "log", "(focus)", base.fhirType(), "integer or decimal");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static double customLog(double base, double logNumber) {
|
||||
return Math.log(logNumber) / Math.log(base);
|
||||
}
|
||||
|
||||
private List<Base> funcPower(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
|
||||
if (focus.size() != 1) {
|
||||
throw makeException(I18nConstants.FHIRPATH_FOCUS_PLURAL, "power", focus.size());
|
||||
}
|
||||
Base base = focus.get(0);
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
if (base.hasType("integer", "decimal", "unsignedInt", "positiveInt")) {
|
||||
List<Base> n1 = execute(context, focus, exp.getParameters().get(0), true);
|
||||
if (n1.size() != 1) {
|
||||
throw makeException(I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "power", "0", "Multiple Values", "integer or decimal");
|
||||
}
|
||||
Double e = Double.parseDouble(n1.get(0).primitiveValue());
|
||||
Double d = Double.parseDouble(base.primitiveValue());
|
||||
try {
|
||||
result.add(new DecimalType(Math.pow(d, e)));
|
||||
} catch (Exception ex) {
|
||||
// just return nothing
|
||||
}
|
||||
} else {
|
||||
makeException(I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "power", "(focus)", base.fhirType(), "integer or decimal");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Base> funcTruncate(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
|
||||
if (focus.size() != 1) {
|
||||
throw makeException(I18nConstants.FHIRPATH_FOCUS_PLURAL, "truncate", focus.size());
|
||||
}
|
||||
Base base = focus.get(0);
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
if (base.hasType("integer", "decimal", "unsignedInt", "positiveInt")) {
|
||||
String s = base.primitiveValue();
|
||||
if (s.contains(".")) {
|
||||
s = s.substring(0, s.indexOf("."));
|
||||
}
|
||||
result.add(new IntegerType(s));
|
||||
} else {
|
||||
makeException(I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "sqrt", "(focus)", base.fhirType(), "integer or decimal");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Base> funcRound(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
|
||||
if (focus.size() != 1) {
|
||||
throw makeException(I18nConstants.FHIRPATH_FOCUS_PLURAL, "round", focus.size());
|
||||
}
|
||||
Base base = focus.get(0);
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
if (base.hasType("integer", "decimal", "unsignedInt", "positiveInt")) {
|
||||
int i = 0;
|
||||
if (exp.getParameters().size() == 1) {
|
||||
List<Base> n1 = execute(context, focus, exp.getParameters().get(0), true);
|
||||
if (n1.size() != 1) {
|
||||
throw makeException(I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "power", "0", "Multiple Values", "integer");
|
||||
}
|
||||
i = Integer.parseInt(n1.get(0).primitiveValue());
|
||||
}
|
||||
BigDecimal d = new BigDecimal (base.primitiveValue());
|
||||
result.add(new DecimalType(d.setScale(i, RoundingMode.HALF_UP)));
|
||||
} else {
|
||||
makeException(I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "round", "(focus)", base.fhirType(), "integer or decimal");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
|
||||
public static String bytesToHex(byte[] bytes) {
|
||||
char[] hexChars = new char[bytes.length * 2];
|
||||
for (int j = 0; j < bytes.length; j++) {
|
||||
|
@ -3633,7 +4080,7 @@ public class FHIRPathEngine {
|
|||
|
||||
private List<Base> funcIs(ExecutionContext context, List<Base> focus, ExpressionNode exp) throws PathEngineException {
|
||||
if (focus.size() == 0 || focus.size() > 1) {
|
||||
return makeBoolean(false);
|
||||
return makeNull();
|
||||
}
|
||||
String ns = null;
|
||||
String n = null;
|
||||
|
@ -3648,7 +4095,7 @@ public class FHIRPathEngine {
|
|||
}
|
||||
ns = texp.getName();
|
||||
n = texp.getInner().getName();
|
||||
} else if (Utilities.existsInList(texp.getName(), "Boolean", "Integer", "Decimal", "String", "DateTime", "Time", "SimpleTypeInfo", "ClassInfo")) {
|
||||
} else if (Utilities.existsInList(texp.getName(), "Boolean", "Integer", "Decimal", "String", "DateTime", "Date", "Time", "SimpleTypeInfo", "ClassInfo")) {
|
||||
ns = "System";
|
||||
n = texp.getName();
|
||||
} else {
|
||||
|
@ -3660,7 +4107,15 @@ public class FHIRPathEngine {
|
|||
return makeBoolean(false);
|
||||
}
|
||||
if (!(focus.get(0) instanceof Element) || ((Element) focus.get(0)).isDisallowExtensions()) {
|
||||
return makeBoolean(n.equals(Utilities.capitalize(focus.get(0).fhirType())));
|
||||
String t = Utilities.capitalize(focus.get(0).fhirType());
|
||||
if (n.equals(t)) {
|
||||
return makeBoolean(true);
|
||||
}
|
||||
if ("Date".equals(t) && n.equals("DateTime")) {
|
||||
return makeBoolean(true);
|
||||
} else {
|
||||
return makeBoolean(false);
|
||||
}
|
||||
} else {
|
||||
return makeBoolean(false);
|
||||
}
|
||||
|
@ -4287,7 +4742,22 @@ public class FHIRPathEngine {
|
|||
result.add(new BooleanType(true).noExtensions());
|
||||
} else if (focus.get(0) instanceof StringType) {
|
||||
result.add(new BooleanType((convertToString(focus.get(0)).matches
|
||||
("([0-9]([0-9]([0-9][1-9]|[1-9]0)|[1-9]00)|[1-9]000)(-(0[1-9]|1[0-2])(-(0[1-9]|[1-2][0-9]|3[0-1])(T([01][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\\.[0-9]+)?(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?)?)?)?"))).noExtensions());
|
||||
("([0-9]([0-9]([0-9][1-9]|[1-9]0)|[1-9]00)|[1-9]000)(-(0[1-9]|1[0-2])(-(0[1-9]|[1-2][0-9]|3[0-1])(T([01][0-9]|2[0-3])(:[0-5][0-9](:([0-5][0-9]|60))?)?(\\.[0-9]+)?(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?)?)?)?"))).noExtensions());
|
||||
} else {
|
||||
result.add(new BooleanType(false).noExtensions());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Base> funcIsDate(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
if (focus.size() != 1) {
|
||||
result.add(new BooleanType(false).noExtensions());
|
||||
} else if (focus.get(0) instanceof DateTimeType || focus.get(0) instanceof DateType) {
|
||||
result.add(new BooleanType(true).noExtensions());
|
||||
} else if (focus.get(0) instanceof StringType) {
|
||||
result.add(new BooleanType((convertToString(focus.get(0)).matches
|
||||
("([0-9]([0-9]([0-9][1-9]|[1-9]0)|[1-9]00)|[1-9]000)(-(0[1-9]|1[0-2])(-(0[1-9]|[1-2][0-9]|3[0-1])(T([01][0-9]|2[0-3])(:[0-5][0-9](:([0-5][0-9]|60))?)?(\\.[0-9]+)?(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?)?)?)?"))).noExtensions());
|
||||
} else {
|
||||
result.add(new BooleanType(false).noExtensions());
|
||||
}
|
||||
|
@ -4316,7 +4786,7 @@ public class FHIRPathEngine {
|
|||
result.add(new BooleanType(true).noExtensions());
|
||||
} else if (focus.get(0) instanceof StringType) {
|
||||
result.add(new BooleanType((convertToString(focus.get(0)).matches
|
||||
("T([01][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\\.[0-9]+)?(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?"))).noExtensions());
|
||||
("(T)?([01][0-9]|2[0-3])(:[0-5][0-9](:([0-5][0-9]|60))?)?(\\.[0-9]+)?(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?"))).noExtensions());
|
||||
} else {
|
||||
result.add(new BooleanType(false).noExtensions());
|
||||
}
|
||||
|
@ -4839,7 +5309,7 @@ public class FHIRPathEngine {
|
|||
while (exsd!=null && !exsd.getBaseDefinition().equals("http://hl7.org/fhir/StructureDefinition/Extension")) {
|
||||
exsd = worker.fetchResource(StructureDefinition.class, exsd.getBaseDefinition());
|
||||
}
|
||||
if (exsd.getUrl().equals(targetUrl)) {
|
||||
if (exsd != null && exsd.getUrl().equals(targetUrl)) {
|
||||
if (profileUtilities.getChildMap(sd, t).isEmpty()) {
|
||||
sd = exsd;
|
||||
}
|
||||
|
|
|
@ -205,6 +205,8 @@ public interface IResourceValidator {
|
|||
public boolean isAllowExamples();
|
||||
public void setAllowExamples(boolean value) ;
|
||||
|
||||
public boolean isNoCheckAggregation();
|
||||
public void setNoCheckAggregation(boolean value);
|
||||
/**
|
||||
* CrumbTrail - whether the validator creates hints to
|
||||
* @return
|
||||
|
|
|
@ -284,7 +284,10 @@ public class StructureMapUtilities {
|
|||
b.append("\" = \"");
|
||||
b.append(Utilities.escapeJson(map.getName()));
|
||||
b.append("\"\r\n\r\n");
|
||||
|
||||
if (map.getDescription()!=null) {
|
||||
renderMultilineDoco(b, map.getDescription(), 0);
|
||||
b.append("\r\n");
|
||||
}
|
||||
renderConceptMaps(b, map);
|
||||
renderUses(b, map);
|
||||
renderImports(b, map);
|
||||
|
@ -392,8 +395,8 @@ public class StructureMapUtilities {
|
|||
}
|
||||
b.append("as ");
|
||||
b.append(s.getMode().toCode());
|
||||
b.append("\r\n");
|
||||
renderDoco(b, s.getDocumentation());
|
||||
b.append("\r\n");
|
||||
}
|
||||
if (map.hasStructure())
|
||||
b.append("\r\n");
|
||||
|
@ -416,6 +419,9 @@ public class StructureMapUtilities {
|
|||
}
|
||||
|
||||
private static void renderGroup(StringBuilder b, StructureMapGroupComponent g) {
|
||||
if (g.hasDocumentation()) {
|
||||
renderMultilineDoco(b, g.getDocumentation(), 0);
|
||||
}
|
||||
b.append("group ");
|
||||
b.append(g.getName());
|
||||
b.append("(");
|
||||
|
@ -464,6 +470,9 @@ public class StructureMapUtilities {
|
|||
}
|
||||
|
||||
private static void renderRule(StringBuilder b, StructureMapGroupRuleComponent r, int indent) {
|
||||
if (r.getDocumentation()!=null) {
|
||||
renderMultilineDoco(b, r.getDocumentation(),indent);
|
||||
}
|
||||
for (int i = 0; i < indent; i++)
|
||||
b.append(' ');
|
||||
boolean canBeAbbreviated = checkisSimple(r);
|
||||
|
@ -499,7 +508,6 @@ public class StructureMapUtilities {
|
|||
}
|
||||
if (r.hasRule()) {
|
||||
b.append(" then {\r\n");
|
||||
renderDoco(b, r.getDocumentation());
|
||||
for (StructureMapGroupRuleComponent ir : r.getRule()) {
|
||||
renderRule(b, ir, indent+2);
|
||||
}
|
||||
|
@ -539,8 +547,7 @@ public class StructureMapUtilities {
|
|||
}
|
||||
}
|
||||
b.append(";");
|
||||
renderDoco(b, r.getDocumentation());
|
||||
b.append("\r\n");
|
||||
b.append("\r\n");
|
||||
}
|
||||
|
||||
private static boolean matchesName(String n, List<StructureMapGroupRuleSourceComponent> source) {
|
||||
|
@ -653,13 +660,13 @@ public class StructureMapUtilities {
|
|||
renderTransformParam(b, rt.getParameter().get(0));
|
||||
} else if (rt.getTransform() == StructureMapTransform.EVALUATE && rt.getParameter().size() == 1) {
|
||||
b.append("(");
|
||||
b.append("\""+((StringType) rt.getParameter().get(0).getValue()).asStringValue()+"\"");
|
||||
b.append(((StringType) rt.getParameter().get(0).getValue()).asStringValue());
|
||||
b.append(")");
|
||||
} else if (rt.getTransform() == StructureMapTransform.EVALUATE && rt.getParameter().size() == 2) {
|
||||
b.append(rt.getTransform().toCode());
|
||||
b.append("(");
|
||||
b.append(((IdType) rt.getParameter().get(0).getValue()).asStringValue());
|
||||
b.append("\""+((StringType) rt.getParameter().get(1).getValue()).asStringValue()+"\"");
|
||||
b.append(((StringType) rt.getParameter().get(1).getValue()).asStringValue());
|
||||
b.append(")");
|
||||
} else {
|
||||
b.append(rt.getTransform().toCode());
|
||||
|
@ -718,9 +725,24 @@ public class StructureMapUtilities {
|
|||
private static void renderDoco(StringBuilder b, String doco) {
|
||||
if (Utilities.noString(doco))
|
||||
return;
|
||||
b.append(" // ");
|
||||
if (b!=null && b.length()>1 && b.charAt(b.length()-1)!='\n' && b.charAt(b.length()-1)!=' ') {
|
||||
b.append(" ");
|
||||
}
|
||||
b.append("// ");
|
||||
b.append(doco.replace("\r\n", " ").replace("\r", " ").replace("\n", " "));
|
||||
}
|
||||
|
||||
private static void renderMultilineDoco(StringBuilder b, String doco, int indent) {
|
||||
if (Utilities.noString(doco))
|
||||
return;
|
||||
String[] lines = doco.split("\\r?\\n");
|
||||
for(String line: lines) {
|
||||
for (int i = 0; i < indent; i++)
|
||||
b.append(' ');
|
||||
renderDoco(b, line);
|
||||
b.append("\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
public StructureMap parse(String text, String srcName) throws FHIRException {
|
||||
FHIRLexer lexer = new FHIRLexer(text, srcName);
|
||||
|
@ -732,8 +754,9 @@ public class StructureMapUtilities {
|
|||
result.setUrl(lexer.readConstant("url"));
|
||||
lexer.token("=");
|
||||
result.setName(lexer.readConstant("name"));
|
||||
lexer.skipComments();
|
||||
|
||||
if (lexer.hasComment()) {
|
||||
result.setDescription(getMultiLineComments(lexer));
|
||||
}
|
||||
while (lexer.hasToken("conceptmap"))
|
||||
parseConceptMap(result, lexer);
|
||||
|
||||
|
@ -801,12 +824,24 @@ public class StructureMapUtilities {
|
|||
tgt.setCode(lexer.take());
|
||||
if (tgt.getCode().startsWith("\""))
|
||||
tgt.setCode(lexer.processConstant(tgt.getCode()));
|
||||
if (lexer.hasComment())
|
||||
tgt.setComment(lexer.take().substring(2).trim());
|
||||
if (lexer.hasComment())
|
||||
tgt.setComment(lexer.take().substring(2).trim());
|
||||
}
|
||||
lexer.token("}");
|
||||
}
|
||||
|
||||
|
||||
private String getMultiLineComments(FHIRLexer lexer) {
|
||||
String comment = null;
|
||||
while (lexer.hasComment()) {
|
||||
String newComment = lexer.take().substring(2).trim();
|
||||
if (comment == null) {
|
||||
comment = newComment;
|
||||
} else {
|
||||
comment += "\r\n"+newComment;
|
||||
}
|
||||
}
|
||||
return comment;
|
||||
}
|
||||
|
||||
private ConceptMapGroupComponent getGroup(ConceptMap map, String srcs, String tgts) {
|
||||
for (ConceptMapGroupComponent grp : map.getGroup()) {
|
||||
|
@ -850,6 +885,7 @@ public class StructureMapUtilities {
|
|||
|
||||
private void parseUses(StructureMap result, FHIRLexer lexer) throws FHIRException {
|
||||
lexer.token("uses");
|
||||
int currentLine = lexer.getCurrentLocation().getLine();
|
||||
StructureMapStructureComponent st = result.addStructure();
|
||||
st.setUrl(lexer.readConstant("url"));
|
||||
if (lexer.hasToken("alias")) {
|
||||
|
@ -859,25 +895,34 @@ public class StructureMapUtilities {
|
|||
lexer.token("as");
|
||||
st.setMode(StructureMapModelMode.fromCode(lexer.take()));
|
||||
lexer.skipToken(";");
|
||||
if (lexer.hasComment()) {
|
||||
if (lexer.hasComment() && currentLine == lexer.getCurrentLocation().getLine()) {
|
||||
st.setDocumentation(lexer.take().substring(2).trim());
|
||||
}
|
||||
lexer.skipComments();
|
||||
}
|
||||
|
||||
private void parseImports(StructureMap result, FHIRLexer lexer) throws FHIRException {
|
||||
lexer.token("imports");
|
||||
int currentLine = lexer.getCurrentLocation().getLine();
|
||||
result.addImport(lexer.readConstant("url"));
|
||||
lexer.skipToken(";");
|
||||
if (lexer.hasComment()) {
|
||||
if (lexer.hasComment() && currentLine == lexer.getCurrentLocation().getLine()) {
|
||||
lexer.next();
|
||||
}
|
||||
lexer.skipComments();
|
||||
}
|
||||
|
||||
private void parseGroup(StructureMap result, FHIRLexer lexer) throws FHIRException {
|
||||
String comment = null;
|
||||
if (lexer.hasComment()) {
|
||||
comment = getMultiLineComments(lexer);
|
||||
if (lexer.done()) {
|
||||
return ;
|
||||
}
|
||||
}
|
||||
lexer.token("group");
|
||||
StructureMapGroupComponent group = result.addGroup();
|
||||
if (comment != null) {
|
||||
group.setDocumentation(comment);
|
||||
}
|
||||
boolean newFmt = false;
|
||||
if (lexer.hasToken("for")) {
|
||||
lexer.token("for");
|
||||
|
@ -923,7 +968,6 @@ public class StructureMapUtilities {
|
|||
}
|
||||
lexer.token("{");
|
||||
}
|
||||
lexer.skipComments();
|
||||
if (newFmt) {
|
||||
while (!lexer.hasToken("}")) {
|
||||
if (lexer.done())
|
||||
|
@ -931,6 +975,7 @@ public class StructureMapUtilities {
|
|||
parseRule(result, group.getRule(), lexer, true);
|
||||
}
|
||||
} else {
|
||||
lexer.skipComments();
|
||||
while (lexer.hasToken("input"))
|
||||
parseInput(group, lexer, false);
|
||||
while (!lexer.hasToken("endgroup")) {
|
||||
|
@ -942,7 +987,6 @@ public class StructureMapUtilities {
|
|||
lexer.next();
|
||||
if (newFmt && lexer.hasToken(";"))
|
||||
lexer.next();
|
||||
lexer.skipComments();
|
||||
}
|
||||
|
||||
private void parseInput(StructureMapGroupComponent group, FHIRLexer lexer, boolean newFmt) throws FHIRException {
|
||||
|
@ -969,12 +1013,19 @@ public class StructureMapUtilities {
|
|||
|
||||
private void parseRule(StructureMap map, List<StructureMapGroupRuleComponent> list, FHIRLexer lexer, boolean newFmt) throws FHIRException {
|
||||
StructureMapGroupRuleComponent rule = new StructureMapGroupRuleComponent();
|
||||
list.add(rule);
|
||||
if (!newFmt) {
|
||||
rule.setName(lexer.takeDottedToken());
|
||||
lexer.token(":");
|
||||
lexer.token("for");
|
||||
} else {
|
||||
if (lexer.hasComment()) {
|
||||
rule.setDocumentation(this.getMultiLineComments(lexer));
|
||||
if (lexer.hasToken("}")) {
|
||||
return ; // catched a comment at the end
|
||||
}
|
||||
}
|
||||
}
|
||||
list.add(rule);
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
parseSource(rule, lexer);
|
||||
|
@ -996,10 +1047,6 @@ public class StructureMapUtilities {
|
|||
lexer.token("then");
|
||||
if (lexer.hasToken("{")) {
|
||||
lexer.token("{");
|
||||
if (lexer.hasComment()) {
|
||||
rule.setDocumentation(lexer.take().substring(2).trim());
|
||||
}
|
||||
lexer.skipComments();
|
||||
while (!lexer.hasToken("}")) {
|
||||
if (lexer.done())
|
||||
throw lexer.error("premature termination expecting '}' in nested group");
|
||||
|
@ -1016,7 +1063,7 @@ public class StructureMapUtilities {
|
|||
}
|
||||
}
|
||||
} else if (lexer.hasComment()) {
|
||||
rule.setDocumentation(lexer.take().substring(2).trim());
|
||||
rule.setDocumentation(getMultiLineComments(lexer));
|
||||
}
|
||||
if (isSimpleSyntax(rule)) {
|
||||
rule.getSourceFirstRep().setVariable(AUTO_VAR_NAME);
|
||||
|
@ -1041,7 +1088,6 @@ public class StructureMapUtilities {
|
|||
}
|
||||
lexer.token(";");
|
||||
}
|
||||
lexer.skipComments();
|
||||
}
|
||||
|
||||
private boolean isSimpleSyntax(StructureMapGroupRuleComponent rule) {
|
||||
|
|
|
@ -55,12 +55,12 @@ public class BaseDateTimeTypeTest {
|
|||
Assertions.assertFalse(compareDateTimes("2001-01-02T11:22:33.445Z", "2001-01-02T11:22:33.444Z"));
|
||||
|
||||
// FHIRPath tests:
|
||||
Assertions.assertNull(compareDateTimes("1974-12-25", "1974-12-25T12:34:00+10:00"));
|
||||
Assertions.assertNull(compareDateTimes("1974-12-25T12:34:00+10:00", "1974-12-25"));
|
||||
Assertions.assertFalse(compareDateTimes("1974-12-25", "1974-12-25T12:34:00+10:00"));
|
||||
Assertions.assertFalse(compareDateTimes("1974-12-25T12:34:00+10:00", "1974-12-25"));
|
||||
Assertions.assertFalse(compareDateTimes("1974-12-25", "1974-12-23T12:34:00+10:00")); // false because they can't be the same date irrespective of precision
|
||||
Assertions.assertFalse(compareDateTimes("1974-12-23T12:34:00+10:00", "1974-12-25"));
|
||||
Assertions.assertNull(compareDateTimes("1974-12-25", "1974-12-25T12:34:00Z"));
|
||||
Assertions.assertNull(compareDateTimes("1974-12-25T12:34:00Z", "1974-12-25"));
|
||||
Assertions.assertFalse(compareDateTimes("1974-12-25", "1974-12-25T12:34:00Z"));
|
||||
Assertions.assertFalse(compareDateTimes("1974-12-25T12:34:00Z", "1974-12-25"));
|
||||
Assertions.assertFalse(compareDateTimes("2012-04-15", "2012-04-16"));
|
||||
Assertions.assertFalse(compareDateTimes("2012-04-16", "2012-04-15"));
|
||||
Assertions.assertFalse(compareDateTimes("2012-04-15T15:00:00", "2012-04-15T10:00:00"));
|
||||
|
@ -70,8 +70,8 @@ public class BaseDateTimeTypeTest {
|
|||
Assertions.assertNull(compareDateTimes("1974-12-25", "1974-12-25T12:34:00"));
|
||||
Assertions.assertNull(compareDateTimes("1974-12-25T12:34:00", "1974-12-25"));
|
||||
Assertions.assertNull(compareDateTimes("2012-04-15T10:00:00", "2012-04-15"));
|
||||
Assertions.assertFalse(compareDateTimes("2012-04-15T15:00:00Z", "2012-04-15T10:00:00"));
|
||||
Assertions.assertFalse(compareDateTimes("2012-04-15T10:00:00", "2012-04-15T15:00:00Z"));
|
||||
Assertions.assertNull(compareDateTimes("2012-04-15T15:00:00Z", "2012-04-15T10:00:00"));
|
||||
Assertions.assertNull(compareDateTimes("2012-04-15T10:00:00", "2012-04-15T15:00:00Z"));
|
||||
Assertions.assertTrue(compareDateTimes("1974-12-25", "1974-12-25"));
|
||||
Assertions.assertTrue(compareDateTimes("2012-04-15", "2012-04-15"));
|
||||
Assertions.assertTrue(compareDateTimes("2012-04-15T15:00:00+02:00", "2012-04-15T16:00:00+03:00"));
|
||||
|
@ -80,7 +80,7 @@ public class BaseDateTimeTypeTest {
|
|||
Assertions.assertTrue(compareDateTimes("2017-11-05T00:30:00.0-05:00", "2017-11-05T01:30:00.0-04:00"));
|
||||
|
||||
Assertions.assertFalse(compareDateTimes("2016-12-02T13:00:00Z", "2016-11-02T10:00:00")); // no timezone, but cannot be the same time
|
||||
Assertions.assertFalse(compareDateTimes("2016-12-02T13:00:00Z", "2016-12-02T10:00:00")); // no timezone, might be the same time
|
||||
Assertions.assertNull(compareDateTimes("2016-12-02T13:00:00Z", "2016-12-02T10:00:00")); // no timezone, might be the same time
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -99,7 +99,6 @@ public class BaseDateTimeTypeTest {
|
|||
|
||||
|
||||
private Boolean compareDateTimes(String theLeft, String theRight) {
|
||||
System.out.println("Compare " + theLeft + " to " + theRight);
|
||||
DateTimeType leftDt = new DateTimeType(theLeft);
|
||||
DateTimeType rightDt = new DateTimeType(theRight);
|
||||
return leftDt.equalsUsingFhirPathRules(rightDt);
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package org.hl7.fhir.r5.test;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -41,7 +39,7 @@ public class CDARoundTripTests {
|
|||
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "cda.xml"), "cda.xml", null);
|
||||
for (StructureDefinition sd : context.getStructures()) {
|
||||
if (!sd.hasSnapshot()) {
|
||||
System.out.println("generate snapshot for " + sd.getUrl());
|
||||
// System.out.println("generate snapshot for " + sd.getUrl());
|
||||
context.generateSnapshot(sd, true);
|
||||
}
|
||||
}
|
||||
|
@ -251,7 +249,7 @@ public class CDARoundTripTests {
|
|||
TestingUtilities.loadTestResourceStream("validator", "cda", "example.xml"), FhirFormat.XML);
|
||||
|
||||
List<Element> title = xml.getChildrenByName("title");
|
||||
assertTrue(title != null && title.size() == 1);
|
||||
Assertions.assertTrue(title != null && title.size() == 1);
|
||||
|
||||
|
||||
Element value = title.get(0).getChildren().get(0);
|
||||
|
@ -261,7 +259,7 @@ public class CDARoundTripTests {
|
|||
ByteArrayOutputStream baosXml = new ByteArrayOutputStream();
|
||||
Manager.compose(TestingUtilities.context(), xml, baosXml, FhirFormat.XML, OutputStyle.PRETTY, null);
|
||||
String cdaSerialised = baosXml.toString("UTF-8");
|
||||
assertTrue(cdaSerialised.indexOf("öé") > 0);
|
||||
Assertions.assertTrue(cdaSerialised.indexOf("öé") > 0);
|
||||
}
|
||||
|
||||
}
|
|
@ -178,8 +178,10 @@ public class FHIRPathTests {
|
|||
outcome.clear();
|
||||
outcome.add(new BooleanType(ok));
|
||||
}
|
||||
if (fp.hasLog())
|
||||
if (fp.hasLog()) {
|
||||
System.out.println(name);
|
||||
System.out.println(fp.takeLog());
|
||||
}
|
||||
|
||||
List<Element> expected = new ArrayList<Element>();
|
||||
XMLUtil.getNamedChildren(test, "output", expected);
|
||||
|
@ -214,6 +216,7 @@ public class FHIRPathTests {
|
|||
} else {
|
||||
Assertions.assertTrue(outcome.get(i) instanceof PrimitiveType, String.format("Outcome %d: Value should be a primitive type but was %s", i, outcome.get(i).fhirType()));
|
||||
if (!(v.equals(((PrimitiveType) outcome.get(i)).asStringValue()))) {
|
||||
System.out.println(name);
|
||||
System.out.println(String.format("Outcome %d: Value should be %s but was %s for expression %s", i, v, outcome.get(i).toString(), expression));
|
||||
}
|
||||
Assertions.assertEquals(v, ((PrimitiveType) outcome.get(i)).asStringValue(), String.format("Outcome %d: Value should be %s but was %s for expression %s", i, v, outcome.get(i).toString(), expression));
|
||||
|
|
|
@ -83,7 +83,7 @@ public class ParsingTests {
|
|||
@ParameterizedTest(name = "{index}: file {0}")
|
||||
@MethodSource("data")
|
||||
public void test(String name) throws Exception {
|
||||
System.out.println(name);
|
||||
// System.out.println(name);
|
||||
byte[] b = TextFile.streamToBytes(npm.load("package", name));
|
||||
String src = new String(b);
|
||||
Resource r = new JsonParser().parse(b);
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package org.hl7.fhir.r5.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -10,23 +8,24 @@ import org.hl7.fhir.r5.context.SimpleWorkerContext;
|
|||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.Coding;
|
||||
import org.hl7.fhir.r5.model.StructureMap;
|
||||
import org.hl7.fhir.r5.model.StructureMap.StructureMapGroupRuleTargetComponent;
|
||||
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||
import org.hl7.fhir.r5.utils.StructureMapUtilities;
|
||||
import org.hl7.fhir.r5.utils.StructureMapUtilities.ITransformerServices;
|
||||
import org.hl7.fhir.utilities.cache.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.cache.ToolsVersion;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@Disabled // org.hl7.fhir.exceptions.FHIRException: Unable to resolve package id hl7.fhir.core#4.0.0
|
||||
public class StructureMapUtilitiesTest implements ITransformerServices {
|
||||
|
||||
static private SimpleWorkerContext context;
|
||||
|
||||
// @BeforeAll
|
||||
|
||||
@BeforeAll
|
||||
static public void setUp() throws Exception {
|
||||
FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
||||
context = SimpleWorkerContext.fromPackage(pcm.loadPackage("hl7.fhir.core", "4.0.0"));
|
||||
context = SimpleWorkerContext.fromPackage(pcm.loadPackage("hl7.fhir.r4.core", "4.0.1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -36,9 +35,45 @@ public class StructureMapUtilitiesTest implements ITransformerServices {
|
|||
StructureMap structureMap = scu.parse(fileMap, "ActivityDefinition3To4");
|
||||
|
||||
// StructureMap/ActivityDefinition3to4: StructureMap.group[3].rule[2].name error id value '"expression"' is not valid
|
||||
assertEquals("expression", structureMap.getGroup().get(2).getRule().get(1).getName());
|
||||
Assertions.assertEquals("expression", structureMap.getGroup().get(2).getRule().get(1).getName());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void assertSerializeDeserialize(StructureMap structureMap) {
|
||||
Assertions.assertEquals("syntax", structureMap.getName());
|
||||
Assertions.assertEquals("Title of this map\r\nAuthor", structureMap.getDescription());
|
||||
Assertions.assertEquals("http://github.com/FHIR/fhir-test-cases/r5/fml/syntax", structureMap.getUrl());
|
||||
Assertions.assertEquals("Patient", structureMap.getStructure().get(0).getAlias());
|
||||
Assertions.assertEquals("http://hl7.org/fhir/StructureDefinition/Patient", structureMap.getStructure().get(0).getUrl());
|
||||
Assertions.assertEquals("Source Documentation", structureMap.getStructure().get(0).getDocumentation());
|
||||
Assertions.assertEquals("http://hl7.org/fhir/StructureDefinition/Patient", structureMap.getStructure().get(0).getUrl());
|
||||
Assertions.assertEquals("http://hl7.org/fhir/StructureDefinition/Basic", structureMap.getStructure().get(1).getUrl());
|
||||
Assertions.assertEquals("Target Documentation", structureMap.getStructure().get(1).getDocumentation());
|
||||
Assertions.assertEquals("Groups\r\nrule for patient group", structureMap.getGroup().get(0).getDocumentation());
|
||||
Assertions.assertEquals("Comment to rule", structureMap.getGroup().get(0).getRule().get(0).getDocumentation());
|
||||
Assertions.assertEquals("Copy identifier short syntax", structureMap.getGroup().get(0).getRule().get(1).getDocumentation());
|
||||
|
||||
StructureMapGroupRuleTargetComponent target = structureMap.getGroup().get(0).getRule().get(2).getTarget().get(1);
|
||||
Assertions.assertEquals("'urn:uuid:' + r.lower()", target.getParameter().get(0).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSyntax() throws IOException, FHIRException {
|
||||
StructureMapUtilities scu = new StructureMapUtilities(context, this);
|
||||
String fileMap = TestingUtilities.loadTestResource("r5", "fml", "syntax.map");
|
||||
System.out.println(fileMap);
|
||||
|
||||
StructureMap structureMap = scu.parse(fileMap, "Syntax");
|
||||
assertSerializeDeserialize(structureMap);
|
||||
|
||||
String renderedMap = StructureMapUtilities.render(structureMap);
|
||||
StructureMap map = scu.parse(renderedMap, "Syntax");
|
||||
System.out.println(map);
|
||||
assertSerializeDeserialize(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String message) {
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package org.hl7.fhir.r5.test;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -15,6 +13,7 @@ import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
|||
import org.hl7.fhir.r5.utils.FHIRPathEngine;
|
||||
import org.hl7.fhir.utilities.cache.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.cache.ToolsVersion;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -59,7 +58,7 @@ public class XmlParserTests {
|
|||
Manager.compose(context, cda, baosXml, FhirFormat.XML, OutputStyle.PRETTY, null);
|
||||
|
||||
String cdaSerialised = baosXml.toString();
|
||||
assertTrue(cdaSerialised.indexOf("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"")>0);
|
||||
assertTrue(cdaSerialised.indexOf("xsi:type=\"CD\"")>0);
|
||||
Assertions.assertTrue(cdaSerialised.indexOf("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"")>0);
|
||||
Assertions.assertTrue(cdaSerialised.indexOf("xsi:type=\"CD\"")>0);
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.1.6-SNAPSHOT</version>
|
||||
<version>5.1.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.1.6-SNAPSHOT</version>
|
||||
<version>5.1.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
package org.hl7.fhir.utilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.utilities.MergedList.MergeNode;
|
||||
|
||||
/**
|
||||
* A list of items that represent
|
||||
* @author graha
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public class MergedList<T> extends ArrayList<MergeNode<T>> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static interface IMatcher<T1> {
|
||||
public boolean match(T1 l, T1 r);
|
||||
}
|
||||
|
||||
public static class MergeNode<T1> {
|
||||
private T1 left;
|
||||
private T1 right;
|
||||
public MergeNode(T1 left, T1 right) {
|
||||
super();
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
public T1 getLeft() {
|
||||
return left;
|
||||
}
|
||||
public T1 getRight() {
|
||||
return right;
|
||||
}
|
||||
|
||||
public boolean hasLeft() {
|
||||
return left != null;
|
||||
}
|
||||
|
||||
public boolean hasRight() {
|
||||
return right != null;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return (hasLeft() ? left.toString() : "null") + " :: "+(hasRight() ? right.toString() : "null");
|
||||
}
|
||||
}
|
||||
|
||||
public MergedList(List<T> left, List<T> right, IMatcher<T> matcher) {
|
||||
super();
|
||||
List<T> m = new ArrayList<>();
|
||||
for (T l : left) {
|
||||
T t = null;
|
||||
for (T r : right) {
|
||||
if (matcher.match(l, r)) {
|
||||
t = r;
|
||||
m.add(r);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.add(new MergeNode<T>(l, t));
|
||||
}
|
||||
for (T r : right) {
|
||||
if (!m.contains(r)) {
|
||||
this.add(new MergeNode<T>(null, r));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MergedList(List<T> left, List<T> right) {
|
||||
super();
|
||||
for (int i = 0; i < Integer.max(left.size(), right.size()); i++) {
|
||||
T l = i < left.size() ? left.get(i) : null;
|
||||
T r = i < right.size() ? right.get(i) : null;
|
||||
this.add(new MergeNode<T>(l, r));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -42,6 +42,8 @@ import java.io.FilenameFilter;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
@ -1103,12 +1105,18 @@ public class Utilities {
|
|||
return true;
|
||||
if (Utilities.noString(l) || Utilities.noString(r))
|
||||
return false;
|
||||
l = l.toLowerCase().trim();
|
||||
r = r.toLowerCase().trim(); // not that this should make any difference
|
||||
return l.startsWith(r) || r.startsWith(l);
|
||||
if (!Utilities.isDecimal(l, true) || !Utilities.isDecimal(r, true))
|
||||
return false;
|
||||
BigDecimal dl = new BigDecimal(l);
|
||||
BigDecimal dr = new BigDecimal(r);
|
||||
if (dl.scale() < dr.scale()) {
|
||||
dr = dr.setScale(dl.scale(), RoundingMode.HALF_UP);
|
||||
} else if (dl.scale() > dr.scale()) {
|
||||
dl = dl.setScale(dr.scale(), RoundingMode.HALF_UP);
|
||||
}
|
||||
return dl.equals(dr);
|
||||
}
|
||||
|
||||
|
||||
public static String getFileExtension(String fn) {
|
||||
return fn.contains(".") ? fn.substring(fn.lastIndexOf(".") + 1) : "";
|
||||
}
|
||||
|
|
|
@ -117,10 +117,12 @@ public class I18nConstants {
|
|||
public static final String EXTENSION_EXT_VERSION_NOCHANGE = "Extension_EXT_Version_NoChange";
|
||||
public static final String EXTENSION_PROF_TYPE = "Extension_PROF_Type";
|
||||
public static final String FHIRPATH_ALIAS_COLLECTION = "FHIRPATH_ALIAS_COLLECTION";
|
||||
public static final String FHIRPATH_BAD_DATE = "FHIRPATH_BAD_DATE";
|
||||
public static final String FHIRPATH_CANNOT_USE = "FHIRPATH_CANNOT_USE";
|
||||
public static final String FHIRPATH_CANT_COMPARE = "FHIRPATH_CANT_COMPARE";
|
||||
public static final String FHIRPATH_CHECK_FAILED = "FHIRPATH_CHECK_FAILED";
|
||||
public static final String FHIRPATH_CODED_ONLY = "FHIRPATH_CODED_ONLY";
|
||||
public static final String FHIRPATH_DECIMAL_ONLY = "FHIRPATH_DECIMAL_ONLY";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_BAD_NAME = "FHIRPATH_DISCRIMINATOR_BAD_NAME";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_BAD_SYNTAX_CONST = "FHIRPATH_DISCRIMINATOR_BAD_SYNTAX_CONST";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_BAD_SYNTAX_GROUP = "FHIRPATH_DISCRIMINATOR_BAD_SYNTAX_GROUP";
|
||||
|
@ -136,6 +138,7 @@ public class I18nConstants {
|
|||
public static final String FHIRPATH_DISCRIMINATOR_THIS_CANNOT_FIND = "FHIRPATH_DISCRIMINATOR_THIS_CANNOT_FIND";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_TYPE_MULTIPLE = "FHIRPATH_DISCRIMINATOR_TYPE_MULTIPLE";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_TYPE_NONE = "FHIRPATH_DISCRIMINATOR_TYPE_NONE";
|
||||
public static final String FHIRPATH_FOCUS_PLURAL = "FHIRPATH_FOCUS_PLURAL";
|
||||
public static final String FHIRPATH_HO_HOST_SERVICES = "FHIRPATH_HO_HOST_SERVICES";
|
||||
public static final String FHIRPATH_LEFT_VALUE_PLURAL = "FHIRPATH_LEFT_VALUE_PLURAL";
|
||||
public static final String FHIRPATH_LEFT_VALUE_WRONG_TYPE = "FHIRPATH_LEFT_VALUE_WRONG_TYPE";
|
||||
|
@ -143,6 +146,7 @@ public class I18nConstants {
|
|||
public static final String FHIRPATH_NOT_IMPLEMENTED = "FHIRPATH_NOT_IMPLEMENTED";
|
||||
public static final String FHIRPATH_NO_COLLECTION = "FHIRPATH_NO_COLLECTION";
|
||||
public static final String FHIRPATH_NO_TYPE = "FHIRPATH_NO_TYPE";
|
||||
public static final String FHIRPATH_NUMERICAL_ONLY = "FHIRPATH_NUMERICAL_ONLY";
|
||||
public static final String FHIRPATH_OP_INCOMPATIBLE = "FHIRPATH_OP_INCOMPATIBLE";
|
||||
public static final String FHIRPATH_ORDERED_ONLY = "FHIRPATH_ORDERED_ONLY";
|
||||
public static final String FHIRPATH_PARAM_WRONG = "FHIRPATH_PARAM_WRONG";
|
||||
|
|
|
@ -102,7 +102,7 @@ Questionnaire_Q_EnableWhen_IsInner = Questions with an enableWhen cannot refer t
|
|||
Questionnaire_Q_EnableWhen_NoLink = Questions with an enableWhen must have a value for the question link
|
||||
Questionnaire_Q_EnableWhen_NoTarget = Unable to find an item with the linkId ''{0}'' which is referenced in the enableWhen for ''{1}''
|
||||
Questionnaire_Q_EnableWhen_Self = Target for this question enableWhen can''t reference itself
|
||||
Reference_REF_Aggregation = Reference is {0} which isn''t supported by the specified aggregation mode(s) for the reference
|
||||
Reference_REF_Aggregation = Reference is {0} which isn''t supported by the specified aggregation mode(s) for the reference ({1})
|
||||
Reference_REF_BadTargetType = Invalid Resource target type. Found {0}, but expected one of ({1})
|
||||
Reference_REF_BadTargetType2 = The type ''{0}'' implied by the reference URL {1} is not a valid Target for this element (must be one of {2})
|
||||
Reference_REF_CantMatchChoice = Unable to find matching profile for {0} among choices: {1}
|
||||
|
@ -600,3 +600,7 @@ BUNDLE_RULE_PROFILE_UNKNOWN = Bundle Rules profile {1} is unknown for {0}
|
|||
UNABLE_TO_CHECK_IF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_ = Unable to determine whether the provided codes are in the value set {0} because the value set or code system is not known to the validator
|
||||
TERMINOLOGY_TX_SYSTEM_WRONG_HTML = The code system reference {0} is wrong - the code system reference cannot be to an HTML page. This may be the correct reference: {1}
|
||||
TERMINOLOGY_TX_SYSTEM_WRONG_BUILD = The code system reference {0} is wrong - the code system reference cannot be a reference to build.fhir.org. This may be the correct reference: {1}
|
||||
FHIRPATH_BAD_DATE = Unable to parse Date {0}
|
||||
FHIRPATH_NUMERICAL_ONLY = Error evaluating FHIRPath expression: The function {0} can only be used on integer, decimal or Quantity but found {1}
|
||||
FHIRPATH_DECIMAL_ONLY = Error evaluating FHIRPath expression: The function {0} can only be used on a decimal but found {1}
|
||||
FHIRPATH_FOCUS_PLURAL = Error evaluating FHIRPath expression: focus for {0} has more than one value
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.1.6-SNAPSHOT</version>
|
||||
<version>5.1.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
|||
<dependency>
|
||||
<groupId>org.fhir</groupId>
|
||||
<artifactId>ucum</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>xpp3</groupId>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.1.6-SNAPSHOT</version>
|
||||
<version>5.1.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -103,7 +103,7 @@
|
|||
<dependency>
|
||||
<groupId>org.fhir</groupId>
|
||||
<artifactId>ucum</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3</version>
|
||||
</dependency>
|
||||
|
||||
<!-- CQL-to-ELM -->
|
||||
|
|
|
@ -7,6 +7,8 @@ import org.hl7.fhir.validation.ValidationEngine;
|
|||
|
||||
public class Common {
|
||||
|
||||
public static final String DEFAULT_TX_SERVER = "http://tx.fhir.org";
|
||||
|
||||
public static String getVersion(String[] args) {
|
||||
String v = Params.getParam(args, "-version");
|
||||
if (v == null) {
|
||||
|
@ -75,9 +77,16 @@ public class Common {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default validation engine will point to "http://tx.fhir.org" terminology server.
|
||||
*/
|
||||
public static ValidationEngine getValidationEngine(String version, String definitions, String txLog) throws Exception {
|
||||
System.out.println("Loading (v = " + version + ", tx server http://tx.fhir.org)");
|
||||
return new ValidationEngine(definitions, "http://tx.fhir.org", txLog, FhirPublication.fromCode(version), version);
|
||||
return getValidationEngine(version, DEFAULT_TX_SERVER, definitions, txLog);
|
||||
}
|
||||
|
||||
public static ValidationEngine getValidationEngine(String version, String txServer, String definitions, String txLog) throws Exception {
|
||||
System.out.println("Loading (v = " + version + ", tx server -> " + txServer + ")");
|
||||
return new ValidationEngine(definitions, txServer, txLog, FhirPublication.fromCode(version), version);
|
||||
}
|
||||
|
||||
}
|
|
@ -333,6 +333,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
private BestPracticeWarningLevel bpWarnings;
|
||||
private String validationLanguage;
|
||||
private boolean baseOnly;
|
||||
private boolean noCheckAggregation;
|
||||
|
||||
private List<ImplementationGuide> igs = new ArrayList<>();
|
||||
private List<String> extensionDomains = new ArrayList<String>();
|
||||
|
@ -2535,9 +2536,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, ok, I18nConstants.REFERENCE_REF_BADTARGETTYPE, ft, types.toString());
|
||||
}
|
||||
if (type.hasAggregation()) {
|
||||
if (type.hasAggregation() && !noCheckAggregation) {
|
||||
boolean modeOk = false;
|
||||
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
|
||||
for (Enumeration<AggregationMode> mode : type.getAggregation()) {
|
||||
b.append(mode.getCode());
|
||||
if (mode.getValue().equals(AggregationMode.CONTAINED) && refType.equals("contained"))
|
||||
modeOk = true;
|
||||
else if (mode.getValue().equals(AggregationMode.BUNDLED) && refType.equals("bundled"))
|
||||
|
@ -2545,7 +2548,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
else if (mode.getValue().equals(AggregationMode.REFERENCED) && (refType.equals("bundled") || refType.equals("remote")))
|
||||
modeOk = true;
|
||||
}
|
||||
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, modeOk, I18nConstants.REFERENCE_REF_AGGREGATION, refType);
|
||||
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, modeOk, I18nConstants.REFERENCE_REF_AGGREGATION, refType, b.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4892,4 +4895,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
this.validateValueSetCodesOnTxServer = value;
|
||||
}
|
||||
|
||||
public boolean isNoCheckAggregation() {
|
||||
return noCheckAggregation;
|
||||
}
|
||||
|
||||
public void setNoCheckAggregation(boolean noCheckAggregation) {
|
||||
this.noCheckAggregation = noCheckAggregation;
|
||||
}
|
||||
|
||||
|
||||
}
|
4
pom.xml
4
pom.xml
|
@ -13,11 +13,11 @@
|
|||
each other. It is fine to bump the point version of this POM without affecting
|
||||
HAPI FHIR.
|
||||
-->
|
||||
<version>5.1.6-SNAPSHOT</version>
|
||||
<version>5.1.7-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<hapi_fhir_version>5.1.0</hapi_fhir_version>
|
||||
<validator_test_case_version>1.1.33</validator_test_case_version>
|
||||
<validator_test_case_version>1.1.34</validator_test_case_version>
|
||||
<junit_jupiter_version>5.6.2</junit_jupiter_version>
|
||||
<maven_surefire_version>3.0.0-M4</maven_surefire_version>
|
||||
<jacoco_version>0.8.5</jacoco_version>
|
||||
|
|
Loading…
Reference in New Issue