merge conflicts + rework rendering + gather all HTTP access to SimpleHTTPClient + add TerminologyCacheManager

This commit is contained in:
Grahame Grieve 2021-11-09 16:24:21 +11:00
commit 5a33d5c15a
85 changed files with 3810 additions and 1077 deletions

View File

@ -37,9 +37,9 @@ import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_14_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.convertors.loaders.R2016MayToR4Loader;
import org.hl7.fhir.convertors.loaders.R2ToR4Loader;
import org.hl7.fhir.convertors.loaders.R3ToR4Loader;
import org.hl7.fhir.convertors.loaders.loaderR4.R2016MayToR4Loader;
import org.hl7.fhir.convertors.loaders.loaderR4.R2ToR4Loader;
import org.hl7.fhir.convertors.loaders.loaderR4.R3ToR4Loader;
import org.hl7.fhir.convertors.misc.IGR2ConvertorAdvisor;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r4.conformance.ProfileUtilities;

View File

@ -29,7 +29,7 @@ package org.hl7.fhir.convertors;
*/
import org.hl7.fhir.convertors.loaders.R2ToR3Loader;
import org.hl7.fhir.convertors.loaders.loaderR3.R2ToR3Loader;
import org.hl7.fhir.dstu3.context.SimpleWorkerContext;
import org.hl7.fhir.dstu3.elementmodel.Manager;
import org.hl7.fhir.dstu3.elementmodel.Manager.FhirFormat;

View File

@ -1,74 +0,0 @@
package org.hl7.fhir.convertors.loaders;
import org.hl7.fhir.dstu3.context.SimpleWorkerContext.IContextResourceLoader;
import org.hl7.fhir.dstu3.model.Resource;
public abstract class BaseLoaderR3 implements IContextResourceLoader {
protected final String URL_BASE = "http://hl7.org/fhir/";
protected final String URL_DSTU2 = "http://hl7.org/fhir/1.0/";
protected final String URL_DSTU2016MAY = "http://hl7.org/fhir/1.4/";
protected final String URL_DSTU3 = "http://hl7.org/fhir/3.0/";
protected final String URL_R4 = "http://hl7.org/fhir/4.0/";
protected final String URL_ELEMENT_DEF_NAMESPACE = "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace";
private final String[] types;
private final ILoaderKnowledgeProvider lkp;
protected boolean patchUrls;
protected boolean killPrimitives;
public BaseLoaderR3(String[] types, ILoaderKnowledgeProvider lkp) {
super();
this.types = types;
this.lkp = lkp;
}
public String[] getTypes() {
return types;
}
public boolean isPatchUrls() {
return patchUrls;
}
public BaseLoaderR3 setPatchUrls(boolean patchUrls) {
this.patchUrls = patchUrls;
return this;
}
public boolean isKillPrimitives() {
return killPrimitives;
}
public BaseLoaderR3 setKillPrimitives(boolean killPrimitives) {
this.killPrimitives = killPrimitives;
return this;
}
public String getResourcePath(Resource resource) {
return lkp.getResourcePath(resource);
}
public void setPath(Resource r) {
String path = lkp.getResourcePath(r);
if (path != null) {
r.setUserData("path", path);
}
}
public interface ILoaderKnowledgeProvider {
/**
* get the path for references to this resource.
*
* @param resource
* @return null if not tracking paths
*/
String getResourcePath(Resource resource);
}
public static class NullLoaderKnowledgeProvider implements ILoaderKnowledgeProvider {
@Override
public String getResourcePath(Resource resource) {
return null;
}
}
}

View File

@ -1,74 +0,0 @@
package org.hl7.fhir.convertors.loaders;
import org.hl7.fhir.r4.context.SimpleWorkerContext.IContextResourceLoader;
import org.hl7.fhir.r4.model.Resource;
public abstract class BaseLoaderR4 implements IContextResourceLoader {
protected final String URL_BASE = "http://hl7.org/fhir/";
protected final String URL_DSTU2 = "http://hl7.org/fhir/1.0/";
protected final String URL_DSTU2016MAY = "http://hl7.org/fhir/1.4/";
protected final String URL_DSTU3 = "http://hl7.org/fhir/3.0/";
protected final String URL_R4 = "http://hl7.org/fhir/4.0/";
protected final String URL_ELEMENT_DEF_NAMESPACE = "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace";
private final String[] types;
private final ILoaderKnowledgeProvider lkp;
protected boolean patchUrls;
protected boolean killPrimitives;
public BaseLoaderR4(String[] types, ILoaderKnowledgeProvider lkp) {
super();
this.types = types;
this.lkp = lkp;
}
public String[] getTypes() {
return types;
}
public boolean isPatchUrls() {
return patchUrls;
}
public BaseLoaderR4 setPatchUrls(boolean patchUrls) {
this.patchUrls = patchUrls;
return this;
}
public boolean isKillPrimitives() {
return killPrimitives;
}
public BaseLoaderR4 setKillPrimitives(boolean killPrimitives) {
this.killPrimitives = killPrimitives;
return this;
}
public String getResourcePath(Resource resource) {
return lkp.getResourcePath(resource);
}
public void setPath(Resource r) {
String path = lkp.getResourcePath(r);
if (path != null) {
r.setUserData("path", path);
}
}
public interface ILoaderKnowledgeProvider {
/**
* get the path for references to this resource.
*
* @param resource
* @return null if not tracking paths
*/
String getResourcePath(Resource resource);
}
public static class NullLoaderKnowledgeProvider implements ILoaderKnowledgeProvider {
@Override
public String getResourcePath(Resource resource) {
return null;
}
}
}

View File

@ -0,0 +1,43 @@
package org.hl7.fhir.convertors.loaders.loaderR3;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.hl7.fhir.dstu3.context.SimpleWorkerContext.IContextResourceLoader;
import org.hl7.fhir.dstu3.model.Resource;
import javax.annotation.Nonnull;
@Accessors(chain = true)
public abstract class BaseLoaderR3 implements IContextResourceLoader {
protected final String URL_BASE = "http://hl7.org/fhir/";
protected final String URL_DSTU2 = "http://hl7.org/fhir/1.0/";
protected final String URL_DSTU2016MAY = "http://hl7.org/fhir/1.4/";
protected final String URL_DSTU3 = "http://hl7.org/fhir/3.0/";
protected final String URL_R4 = "http://hl7.org/fhir/4.0/";
protected final String URL_ELEMENT_DEF_NAMESPACE = "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace";
@Getter private final String[] types;
private final ILoaderKnowledgeProviderR3 lkp;
@Getter @Setter protected boolean patchUrls;
@Getter @Setter protected boolean killPrimitives;
public BaseLoaderR3(@Nonnull String[] types, @Nonnull ILoaderKnowledgeProviderR3 lkp) {
super();
this.types = types;
this.lkp = lkp;
}
public String getResourcePath(Resource resource) {
return lkp.getResourcePath(resource);
}
public void setPath(Resource r) {
String path = lkp.getResourcePath(r);
if (path != null) {
r.setUserData("path", path);
}
}
}

View File

@ -0,0 +1,13 @@
package org.hl7.fhir.convertors.loaders.loaderR3;
import org.hl7.fhir.dstu3.model.Resource;
public interface ILoaderKnowledgeProviderR3 {
/**
* get the path for references to this resource.
*
* @param resource
* @return null if not tracking paths
*/
String getResourcePath(Resource resource);
}

View File

@ -0,0 +1,10 @@
package org.hl7.fhir.convertors.loaders.loaderR3;
import org.hl7.fhir.dstu3.model.Resource;
public class NullLoaderKnowledgeProviderR3 implements ILoaderKnowledgeProviderR3 {
@Override
public String getResourcePath(Resource resource) {
return null;
}
}

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors.loaders;
package org.hl7.fhir.convertors.loaders.loaderR3;
/*
Copyright (c) 2011+, HL7, Inc.
@ -55,7 +55,7 @@ public class R2ToR3Loader extends BaseLoaderR3 {
private final BaseAdvisor_10_30 advisor_10_30 = new BaseAdvisor_10_30();
public R2ToR3Loader() {
super(new String[0], new NullLoaderKnowledgeProvider());
super(new String[0], new NullLoaderKnowledgeProviderR3());
}
@Override

View File

@ -0,0 +1,42 @@
package org.hl7.fhir.convertors.loaders.loaderR4;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.hl7.fhir.r4.context.SimpleWorkerContext.IContextResourceLoader;
import org.hl7.fhir.r4.model.Resource;
import javax.annotation.Nonnull;
@Accessors(chain = true)
public abstract class BaseLoaderR4 implements IContextResourceLoader {
protected final String URL_BASE = "http://hl7.org/fhir/";
protected final String URL_DSTU2 = "http://hl7.org/fhir/1.0/";
protected final String URL_DSTU2016MAY = "http://hl7.org/fhir/1.4/";
protected final String URL_DSTU3 = "http://hl7.org/fhir/3.0/";
protected final String URL_R4 = "http://hl7.org/fhir/4.0/";
protected final String URL_ELEMENT_DEF_NAMESPACE = "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace";
@Getter private final String[] types;
private final ILoaderKnowledgeProviderR4 lkp;
@Getter @Setter protected boolean patchUrls;
@Getter @Setter protected boolean killPrimitives;
public BaseLoaderR4(@Nonnull String[] types, @Nonnull ILoaderKnowledgeProviderR4 lkp) {
super();
this.types = types;
this.lkp = lkp;
}
public String getResourcePath(Resource resource) {
return lkp.getResourcePath(resource);
}
public void setPath(Resource r) {
String path = lkp.getResourcePath(r);
if (path != null) {
r.setUserData("path", path);
}
}
}

View File

@ -0,0 +1,13 @@
package org.hl7.fhir.convertors.loaders.loaderR4;
import org.hl7.fhir.r4.model.Resource;
public interface ILoaderKnowledgeProviderR4 {
/**
* get the path for references to this resource.
*
* @param resource
* @return null if not tracking paths
*/
String getResourcePath(Resource resource);
}

View File

@ -0,0 +1,10 @@
package org.hl7.fhir.convertors.loaders.loaderR4;
import org.hl7.fhir.r4.model.Resource;
public class NullLoaderKnowledgeProviderR4 implements ILoaderKnowledgeProviderR4 {
@Override
public String getResourcePath(Resource resource) {
return null;
}
}

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors.loaders;
package org.hl7.fhir.convertors.loaders.loaderR4;
/*
Copyright (c) 2011+, HL7, Inc.

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors.loaders;
package org.hl7.fhir.convertors.loaders.loaderR4;
/*
Copyright (c) 2011+, HL7, Inc.
@ -55,7 +55,7 @@ public class R2ToR4Loader extends BaseLoaderR4 {
private final BaseAdvisor_10_40 advisor = new BaseAdvisor_10_40();
public R2ToR4Loader() {
super(new String[0], new NullLoaderKnowledgeProvider());
super(new String[0], new NullLoaderKnowledgeProviderR4());
}
@Override

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors.loaders;
package org.hl7.fhir.convertors.loaders.loaderR4;
/*
Copyright (c) 2011+, HL7, Inc.
@ -54,7 +54,7 @@ public class R3ToR4Loader extends BaseLoaderR4 implements IContextResourceLoader
private final BaseAdvisor_30_40 advisor = new BaseAdvisor_30_40();
public R3ToR4Loader() {
super(new String[0], new NullLoaderKnowledgeProvider());
super(new String[0], new NullLoaderKnowledgeProviderR4());
}
@Override

View File

@ -1,6 +1,9 @@
package org.hl7.fhir.convertors.loaders;
package org.hl7.fhir.convertors.loaders.loaderR5;
import com.google.gson.JsonSyntaxException;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.context.IWorkerContext.IContextResourceLoader;
import org.hl7.fhir.r5.model.Resource;
@ -9,6 +12,7 @@ import org.hl7.fhir.utilities.npm.NpmPackage;
import java.io.IOException;
@Accessors(chain = true)
public abstract class BaseLoaderR5 implements IContextResourceLoader {
protected final String URL_BASE = "http://hl7.org/fhir/";
@ -17,39 +21,17 @@ public abstract class BaseLoaderR5 implements IContextResourceLoader {
protected final String URL_DSTU3 = "http://hl7.org/fhir/3.0/";
protected final String URL_R4 = "http://hl7.org/fhir/4.0/";
protected final String URL_ELEMENT_DEF_NAMESPACE = "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace";
protected boolean patchUrls;
protected boolean killPrimitives;
protected String[] types;
protected ILoaderKnowledgeProvider lkp;
@Getter @Setter protected boolean patchUrls;
@Getter @Setter protected boolean killPrimitives;
@Getter protected String[] types;
protected ILoaderKnowledgeProviderR5 lkp;
public BaseLoaderR5(String[] types, ILoaderKnowledgeProvider lkp) {
public BaseLoaderR5(String[] types, ILoaderKnowledgeProviderR5 lkp) {
super();
this.types = types;
this.lkp = lkp;
}
public String[] getTypes() {
return types;
}
public boolean isPatchUrls() {
return patchUrls;
}
public BaseLoaderR5 setPatchUrls(boolean patchUrls) {
this.patchUrls = patchUrls;
return this;
}
public boolean isKillPrimitives() {
return killPrimitives;
}
public BaseLoaderR5 setKillPrimitives(boolean killPrimitives) {
this.killPrimitives = killPrimitives;
return this;
}
public String getResourcePath(Resource resource) {
return lkp.getResourcePath(resource);
}
@ -84,27 +66,4 @@ public abstract class BaseLoaderR5 implements IContextResourceLoader {
}
}
public interface ILoaderKnowledgeProvider {
/**
* get the path for references to this resource.
*
* @param resource
* @return null if not tracking paths
*/
String getResourcePath(Resource resource);
ILoaderKnowledgeProvider forNewPackage(NpmPackage npm) throws JsonSyntaxException, IOException;
}
public static class NullLoaderKnowledgeProvider implements ILoaderKnowledgeProvider {
@Override
public String getResourcePath(Resource resource) {
return null;
}
@Override
public ILoaderKnowledgeProvider forNewPackage(NpmPackage npm) {
return this;
}
}
}

View File

@ -0,0 +1,19 @@
package org.hl7.fhir.convertors.loaders.loaderR5;
import com.google.gson.JsonSyntaxException;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.utilities.npm.NpmPackage;
import java.io.IOException;
public interface ILoaderKnowledgeProviderR5 {
/**
* get the path for references to this resource.
*
* @param resource
* @return null if not tracking paths
*/
String getResourcePath(Resource resource);
ILoaderKnowledgeProviderR5 forNewPackage(NpmPackage npm) throws JsonSyntaxException, IOException;
}

View File

@ -0,0 +1,16 @@
package org.hl7.fhir.convertors.loaders.loaderR5;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.utilities.npm.NpmPackage;
public class NullLoaderKnowledgeProviderR5 implements ILoaderKnowledgeProviderR5 {
@Override
public String getResourcePath(Resource resource) {
return null;
}
@Override
public ILoaderKnowledgeProviderR5 forNewPackage(NpmPackage npm) {
return this;
}
}

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors.loaders;
package org.hl7.fhir.convertors.loaders.loaderR5;
/*
Copyright (c) 2011+, HL7, Inc.
@ -53,7 +53,7 @@ public class R2016MayToR5Loader extends BaseLoaderR5 {
private final BaseAdvisor_14_50 advisor = new BaseAdvisor_14_50();
public R2016MayToR5Loader(String[] types, ILoaderKnowledgeProvider lkp) {
public R2016MayToR5Loader(String[] types, ILoaderKnowledgeProviderR5 lkp) {
super(types, lkp);
}

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors.loaders;
package org.hl7.fhir.convertors.loaders.loaderR5;
/*
Copyright (c) 2011+, HL7, Inc.
@ -53,7 +53,7 @@ public class R2ToR5Loader extends BaseLoaderR5 implements IContextResourceLoader
private final BaseAdvisor_10_50 advisor = new BaseAdvisor_10_50();
public R2ToR5Loader(String[] types, ILoaderKnowledgeProvider lkp) {
public R2ToR5Loader(String[] types, ILoaderKnowledgeProviderR5 lkp) {
super(types, lkp);
}

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors.loaders;
package org.hl7.fhir.convertors.loaders.loaderR5;
/*
Copyright (c) 2011+, HL7, Inc.
@ -53,7 +53,7 @@ public class R3ToR5Loader extends BaseLoaderR5 implements IContextResourceLoader
private final BaseAdvisor_30_50 advisor = new BaseAdvisor_30_50();
public R3ToR5Loader(String[] types, ILoaderKnowledgeProvider lkp) {
public R3ToR5Loader(String[] types, ILoaderKnowledgeProviderR5 lkp) {
super(types, lkp);
}

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors.loaders;
package org.hl7.fhir.convertors.loaders.loaderR5;
/*
Copyright (c) 2011+, HL7, Inc.
@ -53,7 +53,7 @@ public class R4ToR5Loader extends BaseLoaderR5 implements IContextResourceLoader
private final BaseAdvisor_40_50 advisor = new BaseAdvisor_40_50();
public R4ToR5Loader(String[] types, ILoaderKnowledgeProvider lkp) {
public R4ToR5Loader(String[] types, ILoaderKnowledgeProviderR5 lkp) {
super(types, lkp);
}

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors.loaders;
package org.hl7.fhir.convertors.loaders.loaderR5;
/*
Copyright (c) 2011+, HL7, Inc.
@ -50,7 +50,7 @@ public class R5ToR5Loader extends BaseLoaderR5 {
// TODO Grahame, will this ever be populated? No conversion is being done?
private final List<CodeSystem> cslist = new ArrayList<>();
public R5ToR5Loader(String[] types, ILoaderKnowledgeProvider lkp) {
public R5ToR5Loader(String[] types, ILoaderKnowledgeProviderR5 lkp) {
super(types, lkp);
}

View File

@ -33,6 +33,7 @@ import org.hl7.fhir.utilities.SimpleHTTPClient.HTTPResult;
*/
import org.hl7.fhir.convertors.misc.adl.ADLImporter;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.xml.XMLUtil;

View File

@ -34,6 +34,7 @@ package org.hl7.fhir.convertors.misc;
*/
import org.fhir.ucum.UcumEssenceService;
import org.hl7.fhir.convertors.misc.ccda.CCDAConverter;
import org.hl7.fhir.dstu3.context.SimpleWorkerContext;
import org.hl7.fhir.dstu3.formats.IParser;
import org.hl7.fhir.dstu3.formats.IParser.OutputStyle;

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors.misc;
package org.hl7.fhir.convertors.misc.adl;
/*
Copyright (c) 2011+, HL7, Inc.
@ -133,20 +133,20 @@ public class ADLImporter {
// load data and protocol
Element definition = XMLUtil.getNamedChild(adl, "definition");
NodeTreeEntry root = new NodeTreeEntry();
root.typeName = XMLUtil.getNamedChild(definition, "rm_type_name").getTextContent();
root.atCode = XMLUtil.getNamedChild(definition, "node_id").getTextContent();
root.name = generateToken(root.atCode, true);
sd.setName(root.name);
root.cardinality = readCardinality("root", XMLUtil.getNamedChild(definition, "occurrences"));
root.setTypeName(XMLUtil.getNamedChild(definition, "rm_type_name").getTextContent());
root.setAtCode(XMLUtil.getNamedChild(definition, "node_id").getTextContent());
root.setName(generateToken(root.getAtCode(), true));
sd.setName(root.getName());
root.setCardinality(readCardinality("root", XMLUtil.getNamedChild(definition, "occurrences")));
set.clear();
XMLUtil.getNamedChildren(definition, "attributes", set);
for (Element item : set) {
// we're actually skipping this level - we don't care about data protocol etc.
Element attributes = item; // XMLUtil.getNamedChild(XMLUtil.getNamedChild(item, "children"), "attributes");
loadChildren(root.atCode, root, attributes);
loadChildren(root.getAtCode(), root, attributes);
}
dumpChildren("", root);
genElements(sd, root.name, root);
genElements(sd, root.getName(), root);
// save
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(dest), sd);
@ -156,20 +156,20 @@ public class ADLImporter {
private void genElements(StructureDefinition sd, String path, NodeTreeEntry item) throws Exception {
ElementDefinition ed = sd.getSnapshot().addElement();
ed.setPath(path);
ed.setMax(item.cardinality.max);
ed.setMin(Integer.parseInt(item.cardinality.min));
ed.setShort(texts.get(item.atCode).text);
ed.setDefinition(texts.get(item.atCode).description);
ed.setComment(texts.get(item.atCode).comment);
Element te = findTypeElement(item.typeName);
ed.setMax(item.getCardinality().getMax());
ed.setMin(Integer.parseInt(item.getCardinality().getMin()));
ed.setShort(texts.get(item.getAtCode()).getText());
ed.setDefinition(texts.get(item.getAtCode()).getDescription());
ed.setComment(texts.get(item.getAtCode()).getComment());
Element te = findTypeElement(item.getTypeName());
if (te.hasAttribute("profile"))
ed.addType().setCode(te.getAttribute("fhir")).setProfile(te.getAttribute("profile"));
else
ed.addType().setCode(te.getAttribute("fhir"));
ed.getBase().setPath(ed.getPath()).setMin(ed.getMin()).setMax(ed.getMax());
for (NodeTreeEntry child : item.children) {
genElements(sd, path + "." + child.name, child);
for (NodeTreeEntry child : item.getChildren()) {
genElements(sd, path + "." + child.getName(), child);
}
}
@ -185,13 +185,13 @@ public class ADLImporter {
}
private void dumpChildren(String prefix, NodeTreeEntry item) throws Exception {
Element te = findTypeElement(item.typeName);
Element te = findTypeElement(item.getTypeName());
if (te.hasAttribute("profile"))
System.out.println(prefix + item.atCode + " [" + item.cardinality.min + ".." + item.cardinality.max + "]:" + te.getAttribute("fhir") + "{" + te.getAttribute("profile") + "} // " + item.name + " = " + texts.get(item.atCode).text);
System.out.println(prefix + item.getAtCode() + " [" + item.getCardinality().getMin() + ".." + item.getCardinality().getMax() + "]:" + te.getAttribute("fhir") + "{" + te.getAttribute("profile") + "} // " + item.getName() + " = " + texts.get(item.getAtCode()).getText());
else
System.out.println(prefix + item.atCode + " [" + item.cardinality.min + ".." + item.cardinality.max + "]:" + te.getAttribute("fhir") + " // " + item.name + " = " + texts.get(item.atCode).text);
System.out.println(prefix + item.getAtCode() + " [" + item.getCardinality().getMin() + ".." + item.getCardinality().getMax() + "]:" + te.getAttribute("fhir") + " // " + item.getName() + " = " + texts.get(item.getAtCode()).getText());
for (NodeTreeEntry child : item.children)
for (NodeTreeEntry child : item.getChildren())
dumpChildren(prefix + " ", child);
}
@ -200,22 +200,22 @@ public class ADLImporter {
XMLUtil.getNamedChildren(attributes, "children", set);
for (Element e : set) {
NodeTreeEntry item = new NodeTreeEntry();
item.typeName = XMLUtil.getNamedChild(e, "rm_type_name").getTextContent();
item.atCode = XMLUtil.getNamedChild(e, "node_id").getTextContent();
item.name = generateToken(item.atCode, false);
item.cardinality = readCardinality(path + "/" + item.atCode, XMLUtil.getNamedChild(e, "occurrences"));
parent.children.add(item);
item.setTypeName(XMLUtil.getNamedChild(e, "rm_type_name").getTextContent());
item.setAtCode(XMLUtil.getNamedChild(e, "node_id").getTextContent());
item.setName(generateToken(item.getAtCode(), false));
item.setCardinality(readCardinality(path + "/" + item.getAtCode(), XMLUtil.getNamedChild(e, "occurrences")));
parent.getChildren().add(item);
Element attr = XMLUtil.getNamedChild(e, "attributes");
String type = attr.getAttribute("xsi:type");
if ("C_SINGLE_ATTRIBUTE".equals(type)) {
check(path, item.typeName, "ELEMENT", "type for simple element: " + item.typeName);
check(path, item.getTypeName(), "ELEMENT", "type for simple element: " + item.getTypeName());
checkCardSingle(path, XMLUtil.getNamedChild(attr, "existence"));
Element c = XMLUtil.getNamedChild(attr, "children");
checkCardSingle(path, XMLUtil.getNamedChild(c, "occurrences"));
item.typeName = XMLUtil.getNamedChild(c, "rm_type_name").getTextContent();
item.setTypeName(XMLUtil.getNamedChild(c, "rm_type_name").getTextContent());
} else {
check(path, item.typeName, "CLUSTER", "type for complex element");
loadChildren(path + "/" + item.atCode, item, attr);
check(path, item.getTypeName(), "CLUSTER", "type for complex element");
loadChildren(path + "/" + item.getAtCode(), item, attr);
}
}
}
@ -261,11 +261,11 @@ public class ADLImporter {
check(path, XMLUtil.getNamedChild(element, "upper_included").getTextContent(), "true", "Cardinality check");
check(path, XMLUtil.getNamedChild(element, "lower_unbounded").getTextContent(), "false", "Cardinality check");
Cardinality card = new Cardinality();
card.min = XMLUtil.getNamedChild(element, "lower").getTextContent();
card.setMin(XMLUtil.getNamedChild(element, "lower").getTextContent());
if ("true".equals(XMLUtil.getNamedChild(element, "upper_unbounded").getTextContent()))
card.max = "*";
card.setMax("*");
else
card.max = XMLUtil.getNamedChild(element, "upper").getTextContent();
card.setMax(XMLUtil.getNamedChild(element, "upper").getTextContent());
return card;
}
@ -293,50 +293,4 @@ public class ADLImporter {
throw new Exception(message + ". Expected '" + expected + "' but found '" + found.trim() + "', at " + path);
}
public class Cardinality {
private String min;
private String max;
}
public class TextSet {
private String text;
private String description;
private String comment;
public String getText() {
return text;
}
public void setText(String value) {
this.text = value;
}
public String getDescription() {
return description;
}
public void setDescription(String value) {
this.description = value;
}
public String getComment() {
return comment;
}
public void setComment(String value) {
this.comment = value;
}
}
public class NodeTreeEntry {
private final List<NodeTreeEntry> children = new ArrayList<NodeTreeEntry>();
private String name;
private String atCode;
private String typeName;
private Cardinality cardinality;
}
}

View File

@ -0,0 +1,9 @@
package org.hl7.fhir.convertors.misc.adl;
import lombok.Data;
@Data
public class Cardinality {
private String min;
private String max;
}

View File

@ -0,0 +1,15 @@
package org.hl7.fhir.convertors.misc.adl;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class NodeTreeEntry {
private final List<NodeTreeEntry> children = new ArrayList<NodeTreeEntry>();
private String name;
private String atCode;
private String typeName;
private Cardinality cardinality;
}

View File

@ -0,0 +1,11 @@
package org.hl7.fhir.convertors.misc.adl;
import lombok.Data;
@Data
public class TextSet {
private String text;
private String description;
private String comment;
}

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors.misc;
package org.hl7.fhir.convertors.misc.argonaut;
/*
Copyright (c) 2011+, HL7, Inc.
@ -33,6 +33,10 @@ package org.hl7.fhir.convertors.misc;
import org.apache.commons.io.IOUtils;
import org.fhir.ucum.UcumEssenceService;
import org.fhir.ucum.UcumService;
import org.hl7.fhir.convertors.misc.CDAUtilities;
import org.hl7.fhir.convertors.misc.ccda.CcdaExtensions;
import org.hl7.fhir.convertors.misc.Convert;
import org.hl7.fhir.convertors.misc.ConverterBase;
import org.hl7.fhir.dstu3.context.SimpleWorkerContext;
import org.hl7.fhir.dstu3.formats.IParser.OutputStyle;
import org.hl7.fhir.dstu3.formats.JsonParser;
@ -84,18 +88,18 @@ public class ArgonautConverter extends ConverterBase {
private final UcumService ucumSvc;
// private ValidationEngine validator;
private final SimpleWorkerContext context;
private final Map<String, Map<String, Integer>> sections = new HashMap<String, Map<String, Integer>>();
private final Map<String, Practitioner> practitionerCache = new HashMap<String, Practitioner>();
private final Set<String> oids = new HashSet<String>();
private final Map<String, ZipGenerator> zipsX = new HashMap<String, ZipGenerator>();
private final Map<String, ZipGenerator> zipsJ = new HashMap<String, ZipGenerator>();
private final Map<String, Stats> stats = new HashMap<String, Stats>();
private final Map<String, Map<String, Integer>> sections = new HashMap<>();
private final Map<String, Practitioner> practitionerCache = new HashMap<>();
private final Set<String> oids = new HashSet<>();
private final Map<String, ZipGenerator> zipsX = new HashMap<>();
private final Map<String, ZipGenerator> zipsJ = new HashMap<>();
private final Map<String, Stats> stats = new HashMap<>();
public int perfCount;
int errors = 0;
int warnings = 0;
Map<String, Integer> procCodes = new HashMap<String, Integer>();
Map<String, Integer> condCodes = new HashMap<String, Integer>();
Map<String, Integer> allergyCodes = new HashMap<String, Integer>();
Map<String, Integer> procCodes = new HashMap<>();
Map<String, Integer> condCodes = new HashMap<>();
Map<String, Integer> allergyCodes = new HashMap<>();
private String destFolder;
private ZipGenerator zipJ;
private ZipGenerator zipX;
@ -150,7 +154,7 @@ public class ArgonautConverter extends ConverterBase {
System.out.println("Statistics:");
for (String n : sorted(stats.keySet())) {
Stats s = stats.get(n);
System.out.println(" " + n + ": generated " + s.instances + ", errors " + s.errors + ", warnings " + s.warnings);
System.out.println(" " + n + ": generated " + s.getInstances() + ", errors " + s.getErrors() + ", warnings " + s.getWarnings());
}
System.out.println("OIDs:");
@ -169,7 +173,7 @@ public class ArgonautConverter extends ConverterBase {
}
private List<String> sorted(Set<String> keys) {
List<String> names = new ArrayList<String>();
List<String> names = new ArrayList<>();
names.addAll(keys);
Collections.sort(names);
return names;
@ -189,17 +193,17 @@ public class ArgonautConverter extends ConverterBase {
Convert convert = new Convert(cda, ucumSvc, "-0400");
convert.setGenerateMissingExtensions(true);
Context context = new Context();
context.baseId = Utilities.changeFileExt(filename, "");
context.encClass = clss;
makeSubject(cda, convert, doc, context, context.baseId + "-patient");
makeAuthor(cda, convert, doc, context, context.baseId + "-author");
makeEncounter(cda, convert, doc, context, context.baseId + "-encounter");
context.setBaseId(Utilities.changeFileExt(filename, ""));
context.setEncClass(clss);
makeSubject(cda, convert, doc, context, context.getBaseId() + "-patient");
makeAuthor(cda, convert, doc, context, context.getBaseId() + "-author");
makeEncounter(cda, convert, doc, context, context.getBaseId() + "-encounter");
Element body = cda.getDescendent(doc, "component/structuredBody");
for (Element c : cda.getChildren(body, "component")) {
processSection(cda, convert, context, cda.getChild(c, "section"));
}
oids.addAll(convert.getOids());
saveResource(context.encounter);
saveResource(context.getEncounter());
makeBinary(sourceFolder, filename, context);
makeDocumentReference(cda, convert, doc, context);
zipJ.close();
@ -249,7 +253,7 @@ public class ArgonautConverter extends ConverterBase {
if (sections.containsKey(name))
section = sections.get(name);
else {
section = new HashMap<String, Integer>();
section = new HashMap<>();
sections.put(name, section);
}
iterateChildren(section, "/", child);
@ -340,7 +344,7 @@ public class ArgonautConverter extends ConverterBase {
zipsJ.get(rn).addBytes(resource.getId() + ".json", srcJ, false);
zipsX.get(rn).addBytes(resource.getId() + ".xml", srcX, false);
Stats ss = stats.get(rn);
ss.instances++;
ss.setInstances(ss.getInstances() + 1);
String profile = resource.getUserString("profile");
validate(srcX, profile, resource, ss);
@ -370,11 +374,11 @@ public class ArgonautConverter extends ConverterBase {
}
System.out.println(" " + m.getLevel().toCode() + ": " + m.getMessage() + " @ " + m.getLocation());
if (m.getLevel() == IssueSeverity.WARNING) {
stats.warnings++;
stats.setWarnings(stats.getWarnings() + 1);
warnings++;
}
if (m.getLevel() == IssueSeverity.ERROR || m.getLevel() == IssueSeverity.FATAL) {
stats.errors++;
stats.setErrors(stats.getErrors() + 1);
errors++;
}
}
@ -464,15 +468,15 @@ public class ArgonautConverter extends ConverterBase {
if (prv != null)
pat.setManagingOrganization(new Reference().setReference("Organization/" + processOrganization(prv, cda, convert, context).getId()));
context.subjectRef = new Reference().setDisplay(b.toString()).setReference("Patient/" + pat.getId());
context.setSubjectRef(new Reference().setDisplay(b.toString()).setReference("Patient/" + pat.getId()));
saveResource(pat);
}
private Organization processOrganization(Element oo, CDAUtilities cda, Convert convert, Context context) throws Exception {
Organization org = new Organization();
org.setId(context.baseId + "-organization-" + context.orgId);
org.setId(context.getBaseId() + "-organization-" + context.getOrgId());
org.setUserData("profile", "http://hl7.org/fhir/StructureDefinition/org-daf-daforganization");
context.orgId++;
context.setOrgId(context.getOrgId() + 1);
for (Element e : cda.getChildren(oo, "id"))
org.getIdentifier().add(convert.makeIdentifierFromII(e));
for (Element e : cda.getChildren(oo, "addr"))
@ -523,7 +527,7 @@ public class ArgonautConverter extends ConverterBase {
Element a = cda.getChild(doc, "author");
scanSection("Author", a);
Practitioner author = processPerformer(cda, convert, context, a, "assignedAuthor", "assignedPerson");
context.authorRef = new Reference().setDisplay(author.getUserString("display")).setReference("Practitioner/" + author.getId());
context.setAuthorRef(new Reference().setDisplay(author.getUserString("display")).setReference("Practitioner/" + author.getId()));
return author;
}
@ -585,8 +589,8 @@ public class ArgonautConverter extends ConverterBase {
Encounter enc = new Encounter();
enc.setId(id);
enc.setUserData("profile", "http://hl7.org/fhir/StructureDefinition/encounter-daf-dafencounter");
context.encounter = enc;
enc.setSubject(context.subjectRef);
context.setEncounter(enc);
enc.setSubject(context.getSubjectRef());
for (Element e : cda.getChildren(ee, "id"))
enc.getIdentifier().add(convert.makeIdentifierFromII(e));
@ -601,7 +605,7 @@ public class ArgonautConverter extends ConverterBase {
enc.setStatus(EncounterStatus.FINISHED);
else
enc.setStatus(EncounterStatus.INPROGRESS);
enc.setClass_(context.encClass);
enc.setClass_(context.getEncClass());
Element dd = cda.getChild(ee, "dischargeDispositionCode");
if (dd != null) {
@ -656,26 +660,26 @@ public class ArgonautConverter extends ConverterBase {
private void processProcedureSection(CDAUtilities cda, Convert convert, Element sect, Context context) throws Exception {
scanSection("Procedures", sect);
ListResource list = new ListResource();
list.setId(context.baseId + "-list-procedures");
list.setId(context.getBaseId() + "-list-procedures");
// list.setUserData("profile", "") none?
list.setSubject(context.subjectRef);
list.setSubject(context.getSubjectRef());
list.setCode(inspectCode(convert.makeCodeableConceptFromCD(cda.getChild(sect, "code")), null));
list.setTitle(cda.getChild(sect, "title").getTextContent());
list.setStatus(ListStatus.CURRENT);
list.setMode(ListMode.SNAPSHOT);
list.setDateElement(context.now);
list.setSource(context.authorRef);
list.setDateElement(context.getNow());
list.setSource(context.getAuthorRef());
buildNarrative(list, cda.getChild(sect, "text"));
int i = 0;
for (Element c : cda.getChildren(sect, "entry")) {
Element p = cda.getChild(c, "procedure");
Procedure proc = new Procedure();
proc.setId(context.baseId + "-procedure-" + i);
proc.setId(context.getBaseId() + "-procedure-" + i);
proc.setUserData("profile", "http://hl7.org/fhir/StructureDefinition/procedure-daf-dafprocedure");
i++;
proc.setSubject(context.subjectRef);
proc.setContext(new Reference().setReference("Encounter/" + context.encounter.getId()));
proc.setSubject(context.getSubjectRef());
proc.setContext(new Reference().setReference("Encounter/" + context.getEncounter().getId()));
list.addEntry().setItem(new Reference().setReference("Procedure/" + proc.getId()));
proc.setCode(inspectCode(convert.makeCodeableConceptFromCD(cda.getChild(p, "code")), null));
recordProcedureCode(proc.getCode());
@ -725,32 +729,32 @@ public class ArgonautConverter extends ConverterBase {
private void processReasonForEncounter(CDAUtilities cda, Convert convert, Element sect, Context context) throws Exception {
scanSection("Reason", sect);
context.encounter.addReason().setText(cda.getChild(sect, "text").getTextContent());
context.getEncounter().addReason().setText(cda.getChild(sect, "text").getTextContent());
}
private void processProblemsSection(CDAUtilities cda, Convert convert, Element sect, Context context) throws Exception {
scanSection("Problems", sect);
ListResource list = new ListResource();
list.setId(context.baseId + "-list-problems");
list.setId(context.getBaseId() + "-list-problems");
list.setUserData("profile", "http://hl7.org/fhir/StructureDefinition/list-daf-dafproblemlist");
list.setSubject(context.subjectRef);
list.setSubject(context.getSubjectRef());
list.setCode(inspectCode(convert.makeCodeableConceptFromCD(cda.getChild(sect, "code")), null));
list.setTitle(cda.getChild(sect, "title").getTextContent());
list.setStatus(ListStatus.CURRENT);
list.setMode(ListMode.SNAPSHOT);
list.setDateElement(context.now);
list.setSource(context.authorRef);
list.setDateElement(context.getNow());
list.setSource(context.getAuthorRef());
buildNarrative(list, cda.getChild(sect, "text"));
int i = 0;
for (Element c : cda.getChildren(sect, "entry")) {
Element pca = cda.getChild(c, "act"); // problem concern act
Condition cond = new Condition();
cond.setId(context.baseId + "-problem-" + i);
cond.setId(context.getBaseId() + "-problem-" + i);
cond.setUserData("profile", "http://hl7.org/fhir/StructureDefinition/condition-daf-dafcondition");
i++;
cond.setSubject(context.subjectRef);
cond.setContext(new Reference().setReference("Encounter/" + context.encounter.getId()));
cond.setSubject(context.getSubjectRef());
cond.setContext(new Reference().setReference("Encounter/" + context.getEncounter().getId()));
cond.setVerificationStatus(getVerificationStatusFromAct(cda.getChild(pca, "statusCode")));
cond.setAssertedDateElement(convert.makeDateTimeFromTS(cda.getChild(cda.getChild(pca, "effectiveTime"), "low")));
@ -795,14 +799,14 @@ public class ArgonautConverter extends ConverterBase {
private void processAllergiesSection(CDAUtilities cda, Convert convert, Element section, Context context) throws Exception {
scanSection("Allergies", section);
ListResource list = new ListResource();
list.setId(context.baseId + "-list-allergies");
list.setId(context.getBaseId() + "-list-allergies");
list.setUserData("profile", "http://hl7.org/fhir/StructureDefinition/list-daf-dafallergylist");
list.setSubject(context.subjectRef);
list.setSubject(context.getSubjectRef());
list.setCode(inspectCode(convert.makeCodeableConceptFromCD(cda.getChild(section, "code")), null));
list.setTitle(cda.getChild(section, "title").getTextContent());
list.setStatus(ListStatus.CURRENT);
list.setDateElement(context.now);
list.setSource(context.authorRef);
list.setDateElement(context.getNow());
list.setSource(context.getAuthorRef());
list.setMode(ListMode.SNAPSHOT);
buildNarrative(list, cda.getChild(section, "text"));
@ -810,10 +814,10 @@ public class ArgonautConverter extends ConverterBase {
for (Element c : cda.getChildren(section, "entry")) {
Element apa = cda.getChild(c, "act"); // allergy problem act
AllergyIntolerance ai = new AllergyIntolerance();
ai.setId(context.baseId + "-allergy-" + i);
ai.setId(context.getBaseId() + "-allergy-" + i);
ai.setUserData("profile", "http://hl7.org/fhir/StructureDefinition/allergyintolerance-daf-dafallergyintolerance");
i++;
ai.setPatient(context.subjectRef);
ai.setPatient(context.getSubjectRef());
ai.setAssertedDateElement(convert.makeDateTimeFromTS(cda.getChild(cda.getChild(apa, "effectiveTime"), "low")));
boolean found = false;
@ -859,15 +863,15 @@ public class ArgonautConverter extends ConverterBase {
private void processVitalSignsSection(CDAUtilities cda, Convert convert, Element section, Context context) throws Exception {
scanSection("Vital Signs", section);
ListResource list = new ListResource();
list.setId(context.baseId + "-list-vitalsigns");
list.setId(context.getBaseId() + "-list-vitalsigns");
//. list.setUserData("profile", "http://hl7.org/fhir/StructureDefinition/list-daf-dafproblemlist"); no list
list.setSubject(context.subjectRef);
list.setSubject(context.getSubjectRef());
list.setCode(inspectCode(convert.makeCodeableConceptFromCD(cda.getChild(section, "code")), null));
list.setTitle(cda.getChild(section, "title").getTextContent());
list.setStatus(ListStatus.CURRENT);
list.setMode(ListMode.SNAPSHOT);
list.setDateElement(context.now);
list.setSource(context.authorRef);
list.setDateElement(context.getNow());
list.setSource(context.getAuthorRef());
buildNarrative(list, cda.getChild(section, "text"));
int i = 0;
@ -876,11 +880,11 @@ public class ArgonautConverter extends ConverterBase {
for (Element oc : cda.getChildren(org, "component")) {
Element o = cda.getChild(oc, "observation"); // problem concern act
Observation obs = new Observation();
obs.setId(context.baseId + "-vitals-" + i);
obs.setId(context.getBaseId() + "-vitals-" + i);
obs.setUserData("profile", "http://hl7.org/fhir/StructureDefinition/observation-daf-vitalsigns-dafvitalsigns");
i++;
obs.setSubject(context.subjectRef);
obs.setContext(new Reference().setReference("Encounter/" + context.encounter.getId()));
obs.setSubject(context.getSubjectRef());
obs.setContext(new Reference().setReference("Encounter/" + context.getEncounter().getId()));
obs.setCode(inspectCode(convert.makeCodeableConceptFromCD(cda.getChild(o, "code")), null));
boolean found = false;
@ -909,27 +913,27 @@ public class ArgonautConverter extends ConverterBase {
scanSection("Results", section);
ListResource list = new ListResource();
list.setId(context.baseId + "-list-results");
list.setId(context.getBaseId() + "-list-results");
list.setUserData("profile", "http://hl7.org/fhir/StructureDefinition/list-daf-dafresultlist");
list.setSubject(context.subjectRef);
list.setSubject(context.getSubjectRef());
list.setCode(inspectCode(convert.makeCodeableConceptFromCD(cda.getChild(section, "code")), null));
list.setTitle(cda.getChild(section, "title").getTextContent());
list.setStatus(ListStatus.CURRENT);
list.setMode(ListMode.SNAPSHOT);
list.setDateElement(context.now);
list.setSource(context.authorRef);
list.setDateElement(context.getNow());
list.setSource(context.getAuthorRef());
buildNarrative(list, cda.getChild(section, "text"));
context.obsId = 0;
context.setObsId(0);
for (Element c : cda.getChildren(section, "entry")) {
Element org = cda.getChild(c, "organizer");
if (org != null) {
Observation panel = new Observation();
panel.setId(context.baseId + "-results-" + context.obsId);
panel.setId(context.getBaseId() + "-results-" + context.getObsId());
panel.setUserData("profile", "http://hl7.org/fhir/StructureDefinition/observation-daf-results-dafresultobspanel");
context.obsId++;
panel.setSubject(context.subjectRef);
panel.setContext(new Reference().setReference("Encounter/" + context.encounter.getId()));
context.setObsId(context.getObsId() + 1);
panel.setSubject(context.getSubjectRef());
panel.setContext(new Reference().setReference("Encounter/" + context.getEncounter().getId()));
panel.setStatus(ObservationStatus.FINAL);
boolean found = false;
for (Element e : cda.getChildren(org, "id")) {
@ -971,10 +975,10 @@ public class ArgonautConverter extends ConverterBase {
private Observation processObservation(CDAUtilities cda, Convert convert, Context context, Element o) throws Exception {
Observation obs = new Observation();
obs.setId(context.baseId + "-results-" + context.obsId);
context.obsId++;
obs.setSubject(context.subjectRef);
obs.setContext(new Reference().setReference("Encounter/" + context.encounter.getId()));
obs.setId(context.getBaseId() + "-results-" + context.getObsId());
context.setObsId(context.getObsId() + 1);
obs.setSubject(context.getSubjectRef());
obs.setContext(new Reference().setReference("Encounter/" + context.getEncounter().getId()));
obs.setStatus(ObservationStatus.FINAL);
obs.setEffective(convert.makeDateTimeFromTS(cda.getChild(o, "effectiveTime")));
obs.setCode(inspectCode(convert.makeCodeableConceptFromCD(cda.getChild(o, "code")), null));
@ -1015,11 +1019,11 @@ public class ArgonautConverter extends ConverterBase {
for (Element c : cda.getChildren(section, "entry")) {
Element o = cda.getChild(c, "observation");
Observation obs = new Observation();
obs.setId(context.baseId + "-smoking-" + (i == 0 ? "" : Integer.toString(i)));
obs.setId(context.getBaseId() + "-smoking-" + (i == 0 ? "" : Integer.toString(i)));
obs.setUserData("profile", "http://hl7.org/fhir/StructureDefinition/observation-daf-smokingstatus-dafsmokingstatus");
i++;
obs.setSubject(context.subjectRef);
obs.setContext(new Reference().setReference("Encounter/" + context.encounter.getId()));
obs.setSubject(context.getSubjectRef());
obs.setContext(new Reference().setReference("Encounter/" + context.getEncounter().getId()));
obs.setCode(inspectCode(convert.makeCodeableConceptFromCD(cda.getChild(o, "code")), new Coding().setSystem("http://loinc.org").setCode("72166-2")));
boolean found = false;
@ -1039,25 +1043,25 @@ public class ArgonautConverter extends ConverterBase {
private void processMedicationsSection(CDAUtilities cda, Convert convert, Element section, Context context) throws Exception {
scanSection("Medications", section);
ListResource list = new ListResource();
list.setId(context.baseId + "-list-medications");
list.setId(context.getBaseId() + "-list-medications");
list.setUserData("profile", "http://hl7.org/fhir/StructureDefinition/list-daf-dafmedicationlist");
list.setSubject(context.subjectRef);
list.setSubject(context.getSubjectRef());
list.setCode(inspectCode(convert.makeCodeableConceptFromCD(cda.getChild(section, "code")), null));
list.setTitle(cda.getChild(section, "title").getTextContent());
list.setStatus(ListStatus.CURRENT);
list.setMode(ListMode.SNAPSHOT);
list.setDateElement(context.now);
list.setSource(context.authorRef);
list.setDateElement(context.getNow());
list.setSource(context.getAuthorRef());
buildNarrative(list, cda.getChild(section, "text"));
int i = 0;
for (Element c : cda.getChildren(section, "entry")) {
Element sa = cda.getChild(c, "substanceAdministration"); // allergy problem act
MedicationStatement ms = new MedicationStatement();
ms.setId(context.baseId + "-medication-" + i);
ms.setId(context.getBaseId() + "-medication-" + i);
ms.setUserData("profile", "http://hl7.org/fhir/StructureDefinition/medicationstatement-daf-dafmedicationstatement");
i++;
ms.setSubject(context.subjectRef);
ms.setSubject(context.getSubjectRef());
boolean found = false;
for (Element e : cda.getChildren(sa, "id")) {
@ -1084,7 +1088,7 @@ public class ArgonautConverter extends ConverterBase {
dosage.setDose(convert.makeQuantityFromPQ(qty));
}
} catch (Exception e) {
System.out.println(" invalid dose quantity '" + qty.getAttribute("value") + " " + qty.getAttribute("unit") + "' (" + e.getClass().getName() + ") in " + context.baseId);
System.out.println(" invalid dose quantity '" + qty.getAttribute("value") + " " + qty.getAttribute("unit") + "' (" + e.getClass().getName() + ") in " + context.getBaseId());
}
dosage.setRoute(inspectCode(convert.makeCodeableConceptFromCD(cda.getChild(sa, "routeCode")), null));
Type t = convert.makeSomethingFromGTS(cda.getChildren(sa, "effectiveTime"));
@ -1114,25 +1118,25 @@ public class ArgonautConverter extends ConverterBase {
private void processEncountersSection(CDAUtilities cda, Convert convert, Element section, Context context) throws Exception {
scanSection("Encounters", section);
ListResource list = new ListResource();
list.setId(context.baseId + "-list-encounters");
list.setId(context.getBaseId() + "-list-encounters");
list.setUserData("profile", "http://hl7.org/fhir/StructureDefinition/list-daf-dafencounterlist");
list.setSubject(context.subjectRef);
list.setSubject(context.getSubjectRef());
list.setCode(inspectCode(convert.makeCodeableConceptFromCD(cda.getChild(section, "code")), null));
list.setTitle(cda.getChild(section, "title").getTextContent());
list.setStatus(ListStatus.CURRENT);
list.setMode(ListMode.SNAPSHOT);
list.setDateElement(context.now);
list.setSource(context.authorRef);
list.setDateElement(context.getNow());
list.setSource(context.getAuthorRef());
buildNarrative(list, cda.getChild(section, "text"));
int i = 0;
for (Element c : cda.getChildren(section, "entry")) {
Element ee = cda.getChild(c, "encounter"); // allergy problem act
Encounter enc = new Encounter();
enc.setId(context.baseId + "-encounter-" + i);
enc.setId(context.getBaseId() + "-encounter-" + i);
enc.setUserData("profile", "http://hl7.org/fhir/StructureDefinition/encounter-daf-dafencounter");
i++;
enc.setSubject(context.subjectRef);
enc.setSubject(context.getSubjectRef());
list.addEntry().setItem(new Reference().setReference("Encounter/" + enc.getId()));
for (Element e : cda.getChildren(ee, "id"))
@ -1187,26 +1191,26 @@ public class ArgonautConverter extends ConverterBase {
private void processImmunizationsSection(CDAUtilities cda, Convert convert, Element section, Context context) throws Exception {
scanSection("Immunizations", section);
ListResource list = new ListResource();
list.setId(context.baseId + "-list-immunizations");
list.setId(context.getBaseId() + "-list-immunizations");
list.setUserData("profile", "http://hl7.org/fhir/StructureDefinition/list-daf-dafimmunizationlist");
list.setSubject(context.subjectRef);
list.setSubject(context.getSubjectRef());
list.setCode(inspectCode(convert.makeCodeableConceptFromCD(cda.getChild(section, "code")), null));
list.setTitle(cda.getChild(section, "title").getTextContent());
list.setStatus(ListStatus.CURRENT);
list.setMode(ListMode.SNAPSHOT);
list.setDateElement(context.now);
list.setSource(context.authorRef);
list.setDateElement(context.getNow());
list.setSource(context.getAuthorRef());
buildNarrative(list, cda.getChild(section, "text"));
int i = 0;
for (Element c : cda.getChildren(section, "entry")) {
Element sa = cda.getChild(c, "substanceAdministration"); // allergy problem act
Immunization imm = new Immunization();
imm.setId(context.baseId + "-immunization-" + i);
imm.setId(context.getBaseId() + "-immunization-" + i);
imm.setUserData("profile", "http://hl7.org/fhir/StructureDefinition/immunization-daf-dafimmunization");
i++;
imm.setPatient(context.subjectRef);
imm.setEncounter(new Reference().setReference("Encounter/" + context.encounter.getId()));
imm.setPatient(context.getSubjectRef());
imm.setEncounter(new Reference().setReference("Encounter/" + context.getEncounter().getId()));
imm.setNotGiven("true".equals(sa.getAttribute("negationInd")));
imm.setStatus(convertImmunizationStatus(cda.getChild(sa, "statusCode")));
boolean found = false;
@ -1273,7 +1277,7 @@ public class ArgonautConverter extends ConverterBase {
private void makeBinary(String sourceFolder, String filename, Context context) throws Exception {
Binary binary = new Binary();
binary.setId(context.baseId + "-binary");
binary.setId(context.getBaseId() + "-binary");
binary.setContentType("application/hl7-v3+xml");
binary.setContent(IOUtils.toByteArray(new FileInputStream(Utilities.path(sourceFolder, filename))));
saveResource(binary);
@ -1282,22 +1286,22 @@ public class ArgonautConverter extends ConverterBase {
private void makeDocumentReference(CDAUtilities cda, Convert convert, Element doc, Context context) throws Exception {
scanSection("document", doc);
DocumentReference ref = new DocumentReference();
ref.setId(context.baseId + "-document");
ref.setId(context.getBaseId() + "-document");
ref.setMasterIdentifier(convert.makeIdentifierFromII(cda.getChild(doc, "id")));
ref.setSubject(context.subjectRef);
ref.setSubject(context.getSubjectRef());
ref.setType(inspectCode(convert.makeCodeableConceptFromCD(cda.getChild(doc, "code")), null));
ref.addAuthor(context.authorRef);
ref.addAuthor(context.getAuthorRef());
ref.setCreatedElement(convert.makeDateTimeFromTS(cda.getChild(doc, "effectiveTime")));
ref.setIndexedElement(InstantType.now());
ref.setStatus(DocumentReferenceStatus.CURRENT);
ref.addSecurityLabel(inspectCode(convert.makeCodeableConceptFromCD(cda.getChild(doc, "confidentialityCode")), null));
DocumentReferenceContentComponent cnt = ref.addContent();
cnt.getAttachment().setContentType("application/hl7-v3+xml").setUrl("Binary/" + context.baseId).setLanguage(convertLanguage(cda.getChild(doc, "language")));
cnt.getAttachment().setContentType("application/hl7-v3+xml").setUrl("Binary/" + context.getBaseId()).setLanguage(convertLanguage(cda.getChild(doc, "language")));
// for (Element ti : cda.getChildren(doc, "templateId"))
// cnt.addFormat().setSystem("urn:oid:1.3.6.1.4.1.19376.1.2.3").setCode(value)("urn:oid:"+ti.getAttribute("root"));
ref.setContext(new DocumentReferenceContextComponent());
ref.getContext().setPeriod(convert.makePeriodFromIVL(cda.getChild(cda.getChild(doc, "serviceEvent"), "effectiveTime")));
for (CodeableConcept cc : context.encounter.getType())
for (CodeableConcept cc : context.getEncounter().getType())
ref.getContext().addEvent(cc);
ref.setDescription(cda.getChild(doc, "title").getTextContent());
ref.setCustodian(new Reference().setReference("Organization/" + processOrganization(cda.getDescendent(doc, "custodian/assignedCustodian/representedCustodianOrganization"), cda, convert, context).getId()));
@ -1371,23 +1375,4 @@ public class ArgonautConverter extends ConverterBase {
System.out.println();
}
public class Context {
public String baseId;
public Reference authorRef;
public Encounter encounter;
public Coding encClass;
public int obsId;
public DateTimeType now = DateTimeType.now();
public int orgId;
public Reference subjectRef;
}
public class Stats {
public int instances;
public int errors;
public int warnings;
}
}

View File

@ -0,0 +1,19 @@
package org.hl7.fhir.convertors.misc.argonaut;
import lombok.Data;
import org.hl7.fhir.dstu3.model.Coding;
import org.hl7.fhir.dstu3.model.DateTimeType;
import org.hl7.fhir.dstu3.model.Encounter;
import org.hl7.fhir.dstu3.model.Reference;
@Data
public class Context {
private String baseId;
private Reference authorRef;
private Encounter encounter;
private Coding encClass;
private int obsId;
private DateTimeType now = DateTimeType.now();
private int orgId;
private Reference subjectRef;
}

View File

@ -0,0 +1,10 @@
package org.hl7.fhir.convertors.misc.argonaut;
import lombok.Data;
@Data
public class Stats {
private int instances;
private int errors;
private int warnings;
}

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors.misc;
package org.hl7.fhir.convertors.misc.ccda;
@ -35,6 +35,8 @@ package org.hl7.fhir.convertors.misc;
import org.fhir.ucum.UcumService;
import org.hl7.fhir.convertors.misc.CDAUtilities;
import org.hl7.fhir.convertors.misc.Convert;
import org.hl7.fhir.dstu3.context.IWorkerContext;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.AllergyIntolerance.*;

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors.misc;
package org.hl7.fhir.convertors.misc.ccda;
/*
Copyright (c) 2011+, HL7, Inc.

View File

@ -0,0 +1,15 @@
package org.hl7.fhir.convertors.misc.iso21090;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
class DataType {
private final List<Property> properties = new ArrayList<>();
private boolean isAbstract;
private String name;
private String doco;
private String parent;
}

View File

@ -0,0 +1,17 @@
package org.hl7.fhir.convertors.misc.iso21090;
import lombok.Data;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Data
public class EnumValueSet {
private final List<String> codes = new ArrayList<>();
private final Map<String, String> members = new HashMap<>();
private String name;
private String template;
private String system;
}

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors.misc;
package org.hl7.fhir.convertors.misc.iso21090;
/*
Copyright (c) 2011+, HL7, Inc.
@ -62,8 +62,8 @@ import java.util.*;
public class ISO21090Importer {
private final Map<String, EnumValueSet> bindings = new HashMap<String, EnumValueSet>();
private final Map<String, DataType> types = new HashMap<String, DataType>();
private final Map<String, EnumValueSet> bindings = new HashMap<>();
private final Map<String, DataType> types = new HashMap<>();
private IWorkerContext ctxt;
private Element schema;
@ -92,64 +92,64 @@ public class ISO21090Importer {
private void generateType(DataType dt) throws Exception {
StructureDefinition sd = new StructureDefinition();
sd.setId(dt.name);
sd.setId(dt.getName());
sd.setUrl("http://hl7.org/fhir/iso21090/StructureDefinition/" + sd.getId());
sd.setName(dt.name + " data type");
sd.setName(dt.getName() + " data type");
sd.setStatus(PublicationStatus.ACTIVE);
sd.setExperimental(false);
sd.setPublisher("HL7 / ISO");
sd.setDate(new Date());
sd.setDescription(dt.doco);
sd.setDescription(dt.getDoco());
sd.setKind(StructureDefinitionKind.LOGICAL);
sd.setAbstract(Utilities.existsInList(dt.name, "HXIT", "QTY"));
sd.setAbstract(Utilities.existsInList(dt.getName(), "HXIT", "QTY"));
sd.setType("Element");
if (dt.parent == null)
if (dt.getParent() == null)
sd.setBaseDefinition("http://hl7.org/fhir/StructureDefinition/Element");
else
sd.setBaseDefinition("http://hl7.org/fhir/iso21090/StructureDefinition/" + dt.parent);
sd.setBaseDefinition("http://hl7.org/fhir/iso21090/StructureDefinition/" + dt.getParent());
sd.setDerivation(TypeDerivationRule.SPECIALIZATION);
ElementDefinition ed = sd.getDifferential().addElement();
ed.setPath(dt.name);
produceProperties(sd.getDifferential().getElement(), dt.name, dt.properties, true, false);
produceProperties(sd.getDifferential().getElement(), dt.name, dt.properties, false, false);
ed.setPath(dt.getName());
produceProperties(sd.getDifferential().getElement(), dt.getName(), dt.getProperties(), true, false);
produceProperties(sd.getDifferential().getElement(), dt.getName(), dt.getProperties(), false, false);
ed = sd.getSnapshot().addElement();
ed.setPath(dt.name);
if (dt.parent != null)
addParentProperties(sd.getSnapshot().getElement(), dt.name, dt.parent, true, true);
produceProperties(sd.getSnapshot().getElement(), dt.name, dt.properties, true, true);
if (dt.parent != null)
addParentProperties(sd.getSnapshot().getElement(), dt.name, dt.parent, false, true);
produceProperties(sd.getSnapshot().getElement(), dt.name, dt.properties, false, true);
ed.setPath(dt.getName());
if (dt.getParent() != null)
addParentProperties(sd.getSnapshot().getElement(), dt.getName(), dt.getParent(), true, true);
produceProperties(sd.getSnapshot().getElement(), dt.getName(), dt.getProperties(), true, true);
if (dt.getParent() != null)
addParentProperties(sd.getSnapshot().getElement(), dt.getName(), dt.getParent(), false, true);
produceProperties(sd.getSnapshot().getElement(), dt.getName(), dt.getProperties(), false, true);
ed.getBase().setPath(ed.getPath()).setMin(ed.getMin()).setMax(ed.getMax());
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream("c:\\temp\\iso21090\\StructureDefinition-" + dt.name + ".xml"), sd);
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream("c:\\temp\\iso21090\\StructureDefinition-" + dt.getName() + ".xml"), sd);
}
private void addParentProperties(List<ElementDefinition> elements, String name, String parent, boolean attrMode, boolean snapshot) throws FHIRFormatError {
DataType dt = types.get(parent);
if (dt == null)
throw new Error("No find " + parent);
if (dt.parent != null)
addParentProperties(elements, name, dt.parent, attrMode, snapshot);
produceProperties(elements, name, dt.properties, attrMode, snapshot);
if (dt.getParent() != null)
addParentProperties(elements, name, dt.getParent(), attrMode, snapshot);
produceProperties(elements, name, dt.getProperties(), attrMode, snapshot);
}
private void produceProperties(List<ElementDefinition> elements, String name, List<Property> properties, boolean attrMode, boolean snapshot) throws FHIRFormatError {
for (Property p : properties) {
if (p.isattr == attrMode) {
if (p.isIsattr() == attrMode) {
ElementDefinition ed = new ElementDefinition();
elements.add(ed);
ed.setPath(name + "." + p.name);
if (p.type.startsWith("xsd:"))
ToolingExtensions.addStringExtension(ed.addType(), ToolingExtensions.EXT_XML_TYPE, p.type);
ed.setPath(name + "." + p.getName());
if (p.getType().startsWith("xsd:"))
ToolingExtensions.addStringExtension(ed.addType(), ToolingExtensions.EXT_XML_TYPE, p.getType());
else
ed.addType().setCode(p.type);
ed.setMin(p.min);
ed.setMax(p.max == Integer.MAX_VALUE ? "*" : Integer.toString(p.max));
ed.setDefinition(p.doco);
if (p.isattr)
ed.addType().setCode(p.getType());
ed.setMin(p.getMin());
ed.setMax(p.getMax() == Integer.MAX_VALUE ? "*" : Integer.toString(p.getMax()));
ed.setDefinition(p.getDoco());
if (p.isIsattr())
ed.addRepresentation(PropertyRepresentation.XMLATTR);
if (p.binding != null)
ed.getBinding().setStrength(BindingStrength.REQUIRED).setValueSet(new UriType("http://hl7.org/fhir/iso21090/ValueSet/" + p.binding));
if (p.getBinding() != null)
ed.getBinding().setStrength(BindingStrength.REQUIRED).setValueSet(new UriType("http://hl7.org/fhir/iso21090/ValueSet/" + p.getBinding()));
if (snapshot)
ed.getBase().setPath(ed.getPath()).setMin(ed.getMin()).setMax(ed.getMax());
}
@ -157,22 +157,22 @@ public class ISO21090Importer {
}
private void generateValueSet(EnumValueSet evs) throws Exception {
ValueSet bvs = ctxt.fetchResource(ValueSet.class, evs.template);
ValueSet bvs = ctxt.fetchResource(ValueSet.class, evs.getTemplate());
if (bvs == null)
throw new Exception("Did not find template value set " + evs.template);
throw new Exception("Did not find template value set " + evs.getTemplate());
ValueSet vs = bvs.copy();
vs.getCompose().getInclude().clear();
vs.getIdentifier().clear();
vs.setName("ISO 20190 " + evs.name + " Enumeration");
vs.setId(evs.name);
vs.setName("ISO 20190 " + evs.getName() + " Enumeration");
vs.setId(evs.getName());
vs.setUrl("http://hl7.org/fhir/iso21090/ValueSet/" + vs.getId());
vs.setDate(new Date());
vs.setExperimental(false);
ConceptSetComponent inc = vs.getCompose().addInclude().setSystem(evs.system);
for (String code : evs.codes) {
ConceptSetComponent inc = vs.getCompose().addInclude().setSystem(evs.getSystem());
for (String code : evs.getCodes()) {
inc.addConcept().setCode(code);
}
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream("c:\\temp\\iso21090\\ValueSet-" + evs.name + ".xml"), vs);
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream("c:\\temp\\iso21090\\ValueSet-" + evs.getName() + ".xml"), vs);
}
private void processDataTypes() {
@ -190,19 +190,19 @@ public class ISO21090Importer {
private void processDataType(String n, Element type) {
DataType dt = new DataType();
types.put(n, dt);
dt.name = n;
dt.doco = getDoco(type);
dt.setName(n);
dt.setDoco(getDoco(type));
Element cnt;
Element ext = XMLUtil.getNamedChild(XMLUtil.getNamedChild(type, "xsd:complexContent"), "xsd:extension");
if (ext != null) {
dt.parent = ext.getAttribute("base");
dt.setParent(ext.getAttribute("base"));
cnt = XMLUtil.getFirstChild(ext);
} else {
cnt = XMLUtil.getFirstChild(type);
}
if (cnt.getTagName().equals("xsd:annotation"))
cnt = XMLUtil.getNextSibling(cnt);
System.out.println(n + " (" + dt.parent + ")");
System.out.println(n + " (" + dt.getParent() + ")");
while (cnt != null) {
if (cnt.getTagName().equals("xsd:attribute")) {
processAttribute(dt, cnt);
@ -224,44 +224,44 @@ public class ISO21090Importer {
private void processElement(DataType dt, Element elem) {
Property prop = new Property();
prop.name = elem.getAttribute("name");
prop.min = Integer.parseInt(elem.getAttribute("minOccurs"));
prop.max = "unbounded".equals(elem.getAttribute("maxOccurs")) ? Integer.MAX_VALUE : Integer.parseInt(elem.getAttribute("maxOccurs"));
prop.type = elem.getAttribute("type");
prop.doco = getDoco(elem);
dt.properties.add(prop);
System.out.println(" " + prop.name + " : " + prop.type + " [" + prop.min + ".." + prop.max + "]");
prop.setName(elem.getAttribute("name"));
prop.setMin(Integer.parseInt(elem.getAttribute("minOccurs")));
prop.setMax("unbounded".equals(elem.getAttribute("maxOccurs")) ? Integer.MAX_VALUE : Integer.parseInt(elem.getAttribute("maxOccurs")));
prop.setType(elem.getAttribute("type"));
prop.setDoco(getDoco(elem));
dt.getProperties().add(prop);
System.out.println(" " + prop.getName() + " : " + prop.getType() + " [" + prop.getMin() + ".." + prop.getMax() + "]");
}
private void processAttribute(DataType dt, Element attr) {
Property prop = new Property();
prop.name = attr.getAttribute("name");
prop.type = attr.getAttribute("type");
if (!prop.type.startsWith("xsd:")) {
if (Utilities.noString(prop.type))
prop.type = "xsd:string";
else if (bindings.containsKey(prop.type)) {
prop.binding = prop.type;
prop.type = "xsd:string";
} else if (prop.type.startsWith("set_") && bindings.containsKey(prop.type.substring(4))) {
prop.binding = prop.type.substring(4);
prop.type = "xsd:string";
prop.max = Integer.MAX_VALUE;
} else if ("Uid".equals(prop.type))
prop.type = "xsd:string";
else if ("Code".equals(prop.type))
prop.type = "xsd:token";
else if ("Decimal".equals(prop.type))
prop.type = "xsd:decimal";
prop.setName(attr.getAttribute("name"));
prop.setType(attr.getAttribute("type"));
if (!prop.getType().startsWith("xsd:")) {
if (Utilities.noString(prop.getType()))
prop.setType("xsd:string");
else if (bindings.containsKey(prop.getType())) {
prop.setBinding(prop.getType());
prop.setType("xsd:string");
} else if (prop.getType().startsWith("set_") && bindings.containsKey(prop.getType().substring(4))) {
prop.setBinding(prop.getType().substring(4));
prop.setType("xsd:string");
prop.setMax(Integer.MAX_VALUE);
} else if ("Uid".equals(prop.getType()))
prop.setType("xsd:string");
else if ("Code".equals(prop.getType()))
prop.setType("xsd:token");
else if ("Decimal".equals(prop.getType()))
prop.setType("xsd:decimal");
else
throw new Error("Unknown type " + prop.type + " on " + dt.name + "." + prop.name);
throw new Error("Unknown type " + prop.getType() + " on " + dt.getName() + "." + prop.getName());
}
prop.min = "optional".equals(attr.getAttribute("use")) ? 0 : 1;
prop.max = 1;
prop.doco = getDoco(attr);
prop.isattr = true;
dt.properties.add(prop);
System.out.println(" " + prop.name + " : " + prop.type + " [" + prop.min + ".." + prop.max + "]");
prop.setMin("optional".equals(attr.getAttribute("use")) ? 0 : 1);
prop.setMax(1);
prop.setDoco(getDoco(attr));
prop.setIsattr(true);
dt.getProperties().add(prop);
System.out.println(" " + prop.getName() + " : " + prop.getType() + " [" + prop.getMin() + ".." + prop.getMax() + "]");
}
private void processEnums() {
@ -280,7 +280,7 @@ public class ISO21090Importer {
private void processEnum(String n, Element en) {
EnumValueSet vs = new EnumValueSet();
bindings.put(n, vs);
vs.name = n;
vs.setName(n);
String v3n;
if (n.contains("EntityName"))
v3n = n + "R2";
@ -296,12 +296,12 @@ public class ISO21090Importer {
v3n = "TelecommunicationCapabilities";
else
v3n = n;
vs.system = "http://hl7.org/fhir/v3-" + v3n;
vs.template = "http://hl7.org/fhir/ValueSet/v3-" + v3n;
System.out.println("Enum: " + n + " == " + vs.system);
vs.setSystem("http://hl7.org/fhir/v3-" + v3n);
vs.setTemplate("http://hl7.org/fhir/ValueSet/v3-" + v3n);
System.out.println("Enum: " + n + " == " + vs.getSystem());
while (en != null) {
vs.codes.add(en.getAttribute("value"));
vs.members.put(en.getAttribute("value"), getDoco(en));
vs.getCodes().add(en.getAttribute("value"));
vs.getMembers().put(en.getAttribute("value"), getDoco(en));
en = XMLUtil.getNextSibling(en);
}
}
@ -319,30 +319,4 @@ public class ISO21090Importer {
schema = doc.getDocumentElement();
}
private class Property {
private boolean isattr;
private String name;
private int min;
private int max;
private String type;
private String doco;
private String binding;
}
private class DataType {
private final List<Property> properties = new ArrayList<Property>();
private boolean isAbstract;
private String name;
private String doco;
private String parent;
}
public class EnumValueSet {
private final List<String> codes = new ArrayList<String>();
private final Map<String, String> members = new HashMap<String, String>();
private String name;
private String template;
private String system;
}
}

View File

@ -0,0 +1,14 @@
package org.hl7.fhir.convertors.misc.iso21090;
import lombok.Data;
@Data
class Property {
private boolean isattr;
private String name;
private int min;
private int max;
private String type;
private String doco;
private String binding;
}

View File

@ -0,0 +1,24 @@
package org.hl7.fhir.convertors.misc.searchparam;
import lombok.Data;
@Data
public class SPRelationship {
private final String r4;
private final String r3;
private final String r2b;
private final String r2;
public String getByCode(String code) {
if ("R4".equals(code))
return r4;
if ("R3".equals(code))
return r3;
if ("R2b".equals(code))
return r2b;
if ("R2".equals(code))
return getR2();
return null;
}
}

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors.misc;
package org.hl7.fhir.convertors.misc.searchparam;
/*
Copyright (c) 2011+, HL7, Inc.
@ -135,17 +135,17 @@ public class SearchParameterProcessor {
for (String s : list4) {
boolean ok = false;
for (SPRelationship t : list) {
if (s.equals(t.r4))
if (s.equals(t.getR4()))
ok = true;
}
if (!ok)
System.out.println("R4 missing : " + s);
}
for (SPRelationship sp : list) {
if (!Utilities.noString(sp.r4)) {
boolean ok = list4.contains(sp.r4);
if (!Utilities.noString(sp.getR4())) {
boolean ok = list4.contains(sp.getR4());
if (!ok)
System.out.println("R4 extra : " + sp.r4);
System.out.println("R4 extra : " + sp.getR4());
}
}
}
@ -154,17 +154,17 @@ public class SearchParameterProcessor {
for (String s : list3) {
boolean ok = false;
for (SPRelationship t : list) {
if (s.equals(t.r3))
if (s.equals(t.getR3()))
ok = true;
}
if (!ok)
System.out.println("R3 : " + s);
}
for (SPRelationship sp : list) {
if (!Utilities.noString(sp.r3)) {
boolean ok = list3.contains(sp.r3);
if (!Utilities.noString(sp.getR3())) {
boolean ok = list3.contains(sp.getR3());
if (!ok)
System.out.println("R3 extra : " + sp.r3);
System.out.println("R3 extra : " + sp.getR3());
}
}
}
@ -173,17 +173,17 @@ public class SearchParameterProcessor {
for (String s : list2b) {
boolean ok = false;
for (SPRelationship t : list) {
if (s.equals(t.r2b))
if (s.equals(t.getR2b()))
ok = true;
}
if (!ok)
System.out.println("R2b : " + s);
}
for (SPRelationship sp : list) {
if (!Utilities.noString(sp.r2b)) {
boolean ok = list2b.contains(sp.r2b);
if (!Utilities.noString(sp.getR2b())) {
boolean ok = list2b.contains(sp.getR2b());
if (!ok)
System.out.println("R2b extra : " + sp.r2b);
System.out.println("R2b extra : " + sp.getR2b());
}
}
}
@ -192,17 +192,17 @@ public class SearchParameterProcessor {
for (String s : list2) {
boolean ok = false;
for (SPRelationship t : list) {
if (s.equals(t.r2))
if (s.equals(t.getR2()))
ok = true;
}
if (!ok)
System.out.println("R2 : " + s);
}
for (SPRelationship sp : list) {
if (!Utilities.noString(sp.r2)) {
boolean ok = list2.contains(sp.r2);
if (!Utilities.noString(sp.getR2())) {
boolean ok = list2.contains(sp.getR2());
if (!ok)
System.out.println("R2 extra : " + sp.r2);
System.out.println("R2 extra : " + sp.getR2());
}
}
}
@ -278,49 +278,5 @@ public class SearchParameterProcessor {
System.out.println("Map loaded - " + list.size() + " entries");
}
public class SPRelationship {
private final String r4;
private final String r3;
private final String r2b;
private final String r2;
public SPRelationship(String r4, String r3, String r2b, String r2) {
super();
this.r4 = r4;
this.r3 = r3;
this.r2b = r2b;
this.r2 = r2;
}
public String getR4() {
return r4;
}
public String getR3() {
return r3;
}
public String getR2b() {
return r2b;
}
public String getR2() {
return r2;
}
public String getByCode(String code) {
if ("R4".equals(code))
return r4;
if ("R3".equals(code))
return r3;
if ("R2b".equals(code))
return r2b;
if ("R2".equals(code))
return r2;
return null;
}
}
}

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors.misc;
package org.hl7.fhir.convertors.misc.utg;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_50;

View File

@ -1,33 +1,33 @@
package org.hl7.fhir.r4.context;
/*
Copyright (c) 2011+, HL7, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Copyright (c) 2011+, HL7, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/

View File

@ -276,15 +276,9 @@ public class FHIRToolingClient {
URI url = resourceAddress.resolveOperationURLFromClass(resourceClass, name, ps);
if (complex) {
byte[] body = ByteUtils.resourceToByteArray(params, false, isJson(getPreferredResourceFormat()));
if (client.getLogger() != null) {
client.getLogger().logRequest("POST", url.toString(), null, body);
}
result = client.issuePostRequest(url, body, getPreferredResourceFormat(), generateHeaders(),
"POST " + resourceClass.getName() + "/$" + name, TIMEOUT_OPERATION_LONG);
} else {
if (client.getLogger() != null) {
client.getLogger().logRequest("GET", url.toString(), null, null);
}
result = client.issueGetResourceRequest(url, getPreferredResourceFormat(), generateHeaders(), "GET " + resourceClass.getName() + "/$" + name, TIMEOUT_OPERATION_LONG);
}
if (result.isUnsuccessfulRequest()) {

View File

@ -19,6 +19,7 @@ public class Client {
public static final String DEFAULT_CHARSET = "UTF-8";
private static final long DEFAULT_TIMEOUT = 5000;
private ToolingClientLogger logger;
private FhirLoggingInterceptor fhirLoggingInterceptor;
private int retryCount;
private long timeout = DEFAULT_TIMEOUT;
@ -28,6 +29,7 @@ public class Client {
public void setLogger(ToolingClientLogger logger) {
this.logger = logger;
this.fhirLoggingInterceptor = new FhirLoggingInterceptor(logger);
}
public int getRetryCount() {
@ -167,7 +169,7 @@ public class Client {
int retryCount,
long timeout) throws IOException {
return new FhirRequestBuilder(request)
.withLogger(logger)
.withLogger(fhirLoggingInterceptor)
.withResourceFormat(resourceFormat)
.withRetryCount(retryCount)
.withMessage(message)
@ -183,7 +185,7 @@ public class Client {
int retryCount,
long timeout) throws IOException {
return new FhirRequestBuilder(request)
.withLogger(logger)
.withLogger(fhirLoggingInterceptor)
.withResourceFormat(resourceFormat)
.withRetryCount(retryCount)
.withMessage(message)

View File

@ -0,0 +1,55 @@
package org.hl7.fhir.r4.utils.client.network;
import okhttp3.*;
import org.hl7.fhir.utilities.ToolingClientLogger;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class FhirLoggingInterceptor implements Interceptor {
private ToolingClientLogger logger;
public FhirLoggingInterceptor(ToolingClientLogger logger) {
this.logger = logger;
}
public FhirLoggingInterceptor setLogger(ToolingClientLogger logger) {
this.logger = logger;
return this;
}
@NotNull
@Override
public Response intercept(@NotNull Interceptor.Chain chain) throws IOException {
// Log Request
Request request = chain.request();
logger.logRequest(request.method(), request.url().toString(), new ArrayList<>(request.headers().names()),
request.body() != null ? request.body().toString().getBytes() : null);
// Log Response
Response response = null;
response = chain.proceed(chain.request());
MediaType contentType = null;
byte[] bodyBytes = null;
if (response.body() != null) {
contentType = response.body().contentType();
bodyBytes = response.body().bytes();
}
// Get Headers as List
List<String> headerList = new ArrayList<>();
Map<String, List<String>> headerMap = response.headers().toMultimap();
headerMap.keySet().forEach(key -> headerMap.get(key).forEach(value -> headerList.add(key + ":" + value)));
logger.logResponse(Integer.toString(response.code()), headerList, bodyBytes);
// Reading byte[] clears body. Need to recreate.
ResponseBody body = ResponseBody.create(bodyBytes, contentType);
return response.newBuilder().body(body).build();
}
}

View File

@ -45,10 +45,11 @@ public class FhirRequestBuilder {
* Time unit for {@link FhirRequestBuilder#timeout}.
*/
private TimeUnit timeoutUnit = TimeUnit.MILLISECONDS;
/**
* {@link ToolingClientLogger} for log output.
* {@link FhirLoggingInterceptor} for log output.
*/
private ToolingClientLogger logger = null;
private FhirLoggingInterceptor logger = null;
public FhirRequestBuilder(Request.Builder httpRequest) {
this.httpRequest = httpRequest;
@ -160,7 +161,11 @@ public class FhirRequestBuilder {
.build();
};
return okHttpClient.newBuilder()
OkHttpClient.Builder builder = okHttpClient.newBuilder();
if (logger != null) builder.addInterceptor(logger);
builder.addInterceptor(new RetryInterceptor(retryCount));
return builder.connectTimeout(timeout, timeoutUnit)
.addInterceptor(new RetryInterceptor(retryCount))
.connectTimeout(timeout, timeoutUnit)
.writeTimeout(timeout, timeoutUnit)
@ -189,7 +194,7 @@ public class FhirRequestBuilder {
return this;
}
public FhirRequestBuilder withLogger(ToolingClientLogger logger) {
public FhirRequestBuilder withLogger(FhirLoggingInterceptor logger) {
this.logger = logger;
return this;
}
@ -228,7 +233,6 @@ public class FhirRequestBuilder {
if (response.body() != null) {
try {
byte[] body = response.body().bytes();
log(response.code(), response.headers(), body);
resource = (T) getParser(format).parse(body);
if (resource instanceof OperationOutcome && hasError((OperationOutcome) resource)) {
error = (OperationOutcome) resource;
@ -255,7 +259,6 @@ public class FhirRequestBuilder {
OperationOutcome error = null;
try {
byte[] body = response.body().bytes();
log(response.code(), response.headers(), body);
String contentType = response.header("Content-Type");
if (body != null) {
if (contentType.contains(ResourceFormat.RESOURCE_XML.getHeader()) || contentType.contains("text/xml+fhir")) {
@ -301,30 +304,4 @@ public class FhirRequestBuilder {
throw new EFhirClientException("Invalid format: " + format);
}
}
/**
* Logs the given {@link Response}, using the current {@link ToolingClientLogger}. If the current
* {@link FhirRequestBuilder#logger} is null, no action is taken.
*
* @param responseCode HTTP response code
* @param responseHeaders {@link Headers} from response
* @param responseBody Byte array response
*/
protected void log(int responseCode, Headers responseHeaders, byte[] responseBody) {
if (logger != null) {
List<String> headerList = new ArrayList<>(Collections.emptyList());
Map<String, List<String>> headerMap = responseHeaders.toMultimap();
headerMap.keySet().forEach(key -> headerMap.get(key).forEach(value -> headerList.add(key + ":" + value)));
try {
logger.logResponse(Integer.toString(responseCode), headerList, responseBody);
} catch (Exception e) {
System.out.println("Error parsing response body passed in to logger ->\n" + e.getLocalizedMessage());
}
}
// else { // TODO fix logs
// System.out.println("Call to log HTTP response with null ToolingClientLogger set... are you forgetting to " +
// "initialize your logger?");
// }
}
}

View File

@ -107,6 +107,12 @@
<version>4.9.0</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>logging-interceptor</artifactId>
<version>4.9.0</version>
<optional>true</optional>
</dependency>
<!-- Test dependencies -->
<dependency>

View File

@ -1,33 +1,33 @@
package org.hl7.fhir.r5.context;
/*
Copyright (c) 2011+, HL7, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Copyright (c) 2011+, HL7, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
@ -42,7 +42,7 @@ import org.hl7.fhir.utilities.Utilities;
public class HTMLClientLogger extends BaseLogger implements ToolingClientLogger {
private static final boolean DEBUG = false;
private static final boolean DEBUG = true;
private boolean req = false;
private PrintStream file;

View File

@ -97,7 +97,7 @@ public class SHCParser extends ParserBase {
return res;
}
map = jwt.map;
JsonTrackingParser.write(jwt.payload, "c:\\temp\\payload.json");
checkNamedProperties(jwt.getPayload(), prefix+"payload", "iss", "nbf", "vc");
checkProperty(jwt.getPayload(), prefix+"payload", "iss", true, "String");
logError(1, 1, prefix+"JWT", IssueType.INFORMATIONAL, "The FHIR Validator does not check the JWT signature "+
@ -105,43 +105,43 @@ public class SHCParser extends ParserBase {
checkProperty(jwt.getPayload(), prefix+"payload", "nbf", true, "Number");
JsonObject vc = jwt.getPayload().getAsJsonObject("vc");
if (vc == null) {
logError(1, 1, "JWT", IssueType.STRUCTURE, "Unable to find property 'vc' in the payload", IssueSeverity.ERROR);
logError(1, 1, "JWT", IssueType.STRUCTURE, "Unable to find property 'vc' in the payload", IssueSeverity.ERROR);
return res;
}
String path = prefix+"payload.vc";
checkNamedProperties(vc, path, "type", "credentialSubject");
if (!checkProperty(vc, path, "type", true, "Array")) {
return res;
if (!checkProperty(vc, path, "type", true, "Array")) {
return res;
}
JsonArray type = vc.getAsJsonArray("type");
int i = 0;
for (JsonElement e : type) {
if (!(e instanceof JsonPrimitive)) {
logError(line(e), col(e), path+".type["+i+"]", IssueType.STRUCTURE, "Wrong Property Type in JSON Payload. Expected : String but found "+JSONUtil.type(e), IssueSeverity.ERROR);
logError(line(e), col(e), path+".type["+i+"]", IssueType.STRUCTURE, "Wrong Property Type in JSON Payload. Expected : String but found "+JSONUtil.type(e), IssueSeverity.ERROR);
} else {
types.add(e.getAsString());
}
i++;
}
if (!types.contains("https://smarthealth.cards#health-card")) {
logError(line(vc), col(vc), path, IssueType.STRUCTURE, "Card does not claim to be of type https://smarthealth.cards#health-card, cannot validate", IssueSeverity.ERROR);
logError(line(vc), col(vc), path, IssueType.STRUCTURE, "Card does not claim to be of type https://smarthealth.cards#health-card, cannot validate", IssueSeverity.ERROR);
return res;
}
if (!checkProperty(vc, path, "credentialSubject", true, "Object")) {
return res;
if (!checkProperty(vc, path, "credentialSubject", true, "Object")) {
return res;
}
JsonObject cs = vc.getAsJsonObject("credentialSubject");
path = path+".credentialSubject";
if (!checkProperty(cs, path, "fhirVersion", true, "String")) {
return res;
if (!checkProperty(cs, path, "fhirVersion", true, "String")) {
return res;
}
JsonElement fv = cs.get("fhirVersion");
if (!VersionUtilities.versionsCompatible(context.getVersion(), fv.getAsString())) {
logError(line(fv), col(fv), path+".fhirVersion", IssueType.STRUCTURE, "Card claims to be of version "+fv.getAsString()+", cannot be validated against version "+context.getVersion(), IssueSeverity.ERROR);
return res;
}
if (!checkProperty(cs, path, "fhirBundle", true, "Object")) {
return res;
logError(line(fv), col(fv), path+".fhirVersion", IssueType.STRUCTURE, "Card claims to be of version "+fv.getAsString()+", cannot be validated against version "+context.getVersion(), IssueSeverity.ERROR);
return res;
}
if (!checkProperty(cs, path, "fhirBundle", true, "Object")) {
return res;
}
// ok. all checks passed, we can now validate the bundle
Element e = jsonParser.parse(cs.getAsJsonObject("fhirBundle"), map);

View File

@ -63,6 +63,8 @@ import org.hl7.fhir.utilities.validation.ValidationOptions;
import org.hl7.fhir.utilities.xhtml.NodeType;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import org.hl7.fhir.utilities.xhtml.XhtmlParser;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Piece;
public class DataRenderer extends Renderer {
@ -129,6 +131,56 @@ public class DataRenderer extends Renderer {
// -- 3. General Purpose Terminology Support -----------------------------------------
private static String month(String m) {
switch (m) {
case "1" : return "Jan";
case "2" : return "Feb";
case "3" : return "Mar";
case "4" : return "Apr";
case "5" : return "May";
case "6" : return "Jun";
case "7" : return "Jul";
case "8" : return "Aug";
case "9" : return "Sep";
case "10" : return "Oct";
case "11" : return "Nov";
case "12" : return "Dec";
default: return null;
}
}
public static String describeVersion(String version) {
if (version.startsWith("http://snomed.info/sct")) {
String[] p = version.split("\\/");
String ed = null;
String dt = "";
if (p[p.length-2].equals("version")) {
ed = p[p.length-3];
String y = p[p.length-3].substring(4, 8);
String m = p[p.length-3].substring(2, 4);
dt = " rel. "+month(m)+" "+y;
} else {
ed = p[p.length-1];
}
switch (ed) {
case "900000000000207008": return "Intl"+dt;
case "731000124108": return "US"+dt;
case "32506021000036107": return "AU"+dt;
case "449081005": return "ES"+dt;
case "554471000005108": return "DK"+dt;
case "11000146104": return "NL"+dt;
case "45991000052106": return "SE"+dt;
case "999000041000000102": return "UK"+dt;
case "20611000087101": return "CA"+dt;
case "11000172109": return "BE"+dt;
default: return "??"+dt;
}
} else {
return version;
}
}
public static String describeSystem(String system) {
if (system == null)
return "[not stated]";
@ -282,7 +334,7 @@ public class DataRenderer extends Renderer {
// -- 5. Data type Rendering ----------------------------------------------
public static String display(IWorkerContext context, DataType type) {
return new DataRenderer(new RenderingContext(context, null, null, "http://hl7.org/fhir/R4", "", null, ResourceRendererMode.RESOURCE)).display(type);
return new DataRenderer(new RenderingContext(context, null, null, "http://hl7.org/fhir/R4", "", null, ResourceRendererMode.END_USER)).display(type);
}
public String displayBase(Base b) {
@ -412,6 +464,13 @@ public class DataRenderer extends Renderer {
}
}
public void renderDateTime(XhtmlNode x, String s) {
if (s != null) {
DateTimeType dt = new DateTimeType(s);
x.addText(dt.toHumanDisplay());
}
}
protected void renderUri(XhtmlNode x, UriType uri) {
if (uri.getValue().startsWith("mailto:")) {
x.ah(uri.getValue()).addText(uri.getValue().substring(7));
@ -481,15 +540,53 @@ public class DataRenderer extends Renderer {
public String displayCoding(Coding c) {
String s = "";
if (context.isTechnicalMode()) {
s = c.getDisplay();
if (Utilities.noString(s)) {
s = lookupCode(c.getSystem(), c.getVersion(), c.getCode());
}
if (Utilities.noString(s)) {
s = displayCodeTriple(c.getSystem(), c.getVersion(), c.getCode());
} else if (c.hasSystem()) {
s = s + " ("+displayCodeTriple(c.getSystem(), c.getVersion(), c.getCode())+")";
} else if (c.hasCode()) {
s = s + " ("+c.getCode()+")";
}
} else {
if (c.hasDisplayElement())
return c.getDisplay();
if (Utilities.noString(s))
s = lookupCode(c.getSystem(), c.getVersion(), c.getCode());
if (Utilities.noString(s))
s = c.getCode();
}
return s;
}
private String displayCodeSource(String system, String version) {
String s = displaySystem(system);
if (version != null) {
s = s + "["+describeVersion(version)+"]";
}
return s;
}
private String displayCodeTriple(String system, String version, String code) {
if (system == null) {
if (code == null) {
return "";
} else {
return "#"+code;
}
} else {
String s = displayCodeSource(system, version);
if (code != null) {
s = s + "#"+code;
}
return s;
}
}
public String displayCoding(List<Coding> list) {
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
for (Coding c : list) {
@ -502,6 +599,48 @@ public class DataRenderer extends Renderer {
renderCoding(x, c, false);
}
protected void renderCoding(HierarchicalTableGenerator gen, List<Piece> pieces, Coding c) {
if (c.isEmpty()) {
return;
}
String url = getLinkForSystem(c.getSystem(), c.getVersion());
String name = displayCodeSource(c.getSystem(), c.getVersion());
if (!Utilities.noString(url)) {
pieces.add(gen.new Piece(url, name, c.getSystem()+(c.hasVersion() ? "#"+c.getVersion() : "")));
} else {
pieces.add(gen.new Piece(null, name, c.getSystem()+(c.hasVersion() ? "#"+c.getVersion() : "")));
}
pieces.add(gen.new Piece(null, "#"+c.getCode(), null));
String s = c.getDisplay();
if (Utilities.noString(s)) {
s = lookupCode(c.getSystem(), c.getVersion(), c.getCode());
}
if (!Utilities.noString(s)) {
pieces.add(gen.new Piece(null, " \""+s+"\"", null));
}
}
private String getLinkForSystem(String system, String version) {
if ("http://snomed.info/sct".equals(system)) {
return "https://browser.ihtsdotools.org/";
} else if ("http://loinc.org".equals(system)) {
return "https://loinc.org/";
} else if ("http://unitsofmeasure.org".equals(system)) {
return "http://ucum.org";
} else {
String url = system;
if (version != null) {
url = url + "|"+version;
}
CodeSystem cs = context.getWorker().fetchCodeSystem(url);
if (cs != null && cs.hasUserData("path")) {
return cs.getUserString("path");
}
return null;
}
}
protected void renderCodingWithDetails(XhtmlNode x, Coding c) {
String s = "";
if (c.hasDisplayElement())
@ -512,7 +651,11 @@ public class DataRenderer extends Renderer {
String sn = describeSystem(c.getSystem());
if ("http://snomed.info/sct".equals(c.getSystem())) {
x.ah("https://browser.ihtsdotools.org/").tx(sn);
if (c.hasCode()) {
x.ah("http://snomed.info/id/"+c.getCode()).tx(sn);
} else {
x.ah("https://browser.ihtsdotools.org/").tx(sn);
}
} else if ("http://loinc.org".equals(c.getSystem())) {
x.ah("https://loinc.org/").tx(sn);
} else {
@ -627,16 +770,27 @@ public class DataRenderer extends Renderer {
if (showCodeDetails) {
x.addText(s+" ");
XhtmlNode sp = x.span("background: LightGoldenRodYellow", null);
sp.tx("(Details ");
XhtmlNode sp = x.span("background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki", null);
sp.tx(" (");
boolean first = true;
for (Coding c : cc.getCoding()) {
if (first) {
sp.tx(": ");
first = false;
} else
} else {
sp.tx("; ");
sp.tx("{"+TerminologyRenderer.describeSystem(c.getSystem())+" code '"+c.getCode()+"' = '"+lookupCode(c.getSystem(), c.getVersion(), c.getCode())+(c.hasDisplay() ? "', given as '"+c.getDisplay()+"'}" : ""));
}
String url = getLinkForSystem(c.getSystem(), c.getVersion());
if (url != null) {
sp.ah(url).tx(displayCodeSource(c.getSystem(), c.getVersion()));
} else {
sp.tx(displayCodeSource(c.getSystem(), c.getVersion()));
}
if (c.hasCode()) {
sp.tx("#"+c.getCode());
}
if (c.hasDisplay() && !s.equals(c.getDisplay())) {
sp.tx(" \""+c.getDisplay()+"\"");
}
}
sp.tx(")");
} else {

View File

@ -104,6 +104,9 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
if (context.isAddGeneratedNarrativeHeader()) {
x.para().b().tx("Generated Narrative");
}
if (context.isTechnicalMode()) {
renderResourceHeader(r, x);
}
try {
StructureDefinition sd = r.getDefinition();
if (sd == null) {
@ -112,7 +115,7 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
ElementDefinition ed = sd.getSnapshot().getElement().get(0);
containedIds.clear();
hasExtensions = false;
generateByProfile(r, sd, r.root(), sd.getSnapshot().getElement(), ed, context.getProfileUtilities().getChildList(sd, ed), x, r.fhirType(), false, 0);
generateByProfile(r, sd, r.root(), sd.getSnapshot().getElement(), ed, context.getProfileUtilities().getChildList(sd, ed), x, r.fhirType(), context.isTechnicalMode(), 0);
}
} catch (Exception e) {
e.printStackTrace();
@ -121,6 +124,7 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
return hasExtensions;
}
@Override
public String display(Resource r) throws UnsupportedEncodingException, IOException {
return "todo";
@ -212,7 +216,7 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
//
public void generateResourceSummary(XhtmlNode x, ResourceWrapper res, boolean textAlready, boolean showCodeDetails) throws FHIRException, UnsupportedEncodingException, IOException {
public void generateResourceSummary(XhtmlNode x, ResourceWrapper res, boolean textAlready, boolean showCodeDetails, boolean canLink) throws FHIRException, UnsupportedEncodingException, IOException {
if (!textAlready) {
XhtmlNode div = res.getNarrative();
if (div != null) {
@ -231,9 +235,9 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
boolean firstElement = true;
boolean last = false;
for (PropertyWrapper p : res.children()) {
if (!ignoreProperty(p)) {
if (!ignoreProperty(p) && !p.getElementDefinition().getBase().getPath().startsWith("Resource.")) {
ElementDefinition child = getElementDefinition(profile.getSnapshot().getElement(), path+"."+p.getName(), p);
if (p.getValues().size() > 0 && p.getValues().get(0) != null && child != null && isPrimitive(child) && includeInSummary(child)) {
if (p.getValues().size() > 0 && p.getValues().get(0) != null && child != null && isPrimitive(child) && includeInSummary(child, p.getValues())) {
if (firstElement)
firstElement = false;
else if (last)
@ -245,7 +249,7 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
first = false;
else if (last)
x.tx(", ");
last = displayLeaf(res, v, child, x, p.getName(), showCodeDetails, false) || last;
last = displayLeaf(res, v, child, x, p.getName(), showCodeDetails, canLink) || last;
}
}
}
@ -258,7 +262,10 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
return Utilities.existsInList(p.getName(), "contained");
}
private boolean includeInSummary(ElementDefinition child) {
private boolean includeInSummary(ElementDefinition child, List<BaseWrapper> list) throws UnsupportedEncodingException, FHIRException, IOException {
if (child.getName().endsWith("active") && list != null && list.size() > 0 && "true".equals(list.get(0).getBase().primitiveValue())) {
return false;
}
if (child.getIsModifier())
return true;
if (child.getMustSupport())
@ -432,7 +439,12 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
x.addText(name+": "+((IdType) e).getValue());
return true;
} else if (e instanceof UriType) {
x.addText(name+": "+((UriType) e).getValue());
if (Utilities.isAbsoluteUrlLinkable(((UriType) e).getValue()) && allowLinks) {
x.tx(name+": ");
x.ah(((UriType) e).getValue()).addText(((UriType) e).getValue());
} else {
x.addText(name+": "+((UriType) e).getValue());
}
return true;
} else if (e instanceof DateTimeType) {
x.addText(name+": "+((DateTimeType) e).toHumanDisplay());

View File

@ -325,7 +325,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
if (v.getValue().isPrimitive()) {
defn.getPieces().add(gen.new Piece(null, v.getValue().primitiveValue(), null));
} else {
defn.getPieces().add(gen.new Piece(null, "{todo}", null));
renderCoding(gen, defn.getPieces(), v.getValueCoding());
}
}
}
@ -499,7 +499,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
if (v.getValue().isPrimitive()) {
defn.getPieces().add(gen.new Piece(null, v.getValue().primitiveValue(), null));
} else {
defn.getPieces().add(gen.new Piece(null, "{todo}", null));
renderCoding(gen, defn.getPieces(), v.getValueCoding());
}
}
}
@ -730,7 +730,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
if (v.getValue().isPrimitive()) {
vi.tx(v.getValue().primitiveValue());
} else {
vi.tx("{todo}");
renderCoding(vi, v.getValueCoding(), true);
}
}
}

View File

@ -33,7 +33,7 @@ public class Renderer {
}
public Renderer(IWorkerContext worker) {
this.context = new RenderingContext(worker, new MarkDownProcessor(Dialect.COMMON_MARK), ValidationOptions.defaults(), "http://hl7.org/fhir/R5", "", null, ResourceRendererMode.RESOURCE);
this.context = new RenderingContext(worker, new MarkDownProcessor(Dialect.COMMON_MARK), ValidationOptions.defaults(), "http://hl7.org/fhir/R5", "", null, ResourceRendererMode.END_USER);
}

View File

@ -11,6 +11,7 @@ import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.Enumerations.PublicationStatus;
import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.model.CodeSystem;
@ -31,6 +32,7 @@ import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
import org.hl7.fhir.r5.utils.EOperationOutcome;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.xhtml.NodeType;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
@ -195,22 +197,37 @@ public abstract class ResourceRenderer extends DataRenderer {
} else {
c = x.span(null, null);
}
// what to display: if text is provided, then that. if the reference was resolved, then show the generated narrative
if (r.hasDisplayElement()) {
c.addText(r.getDisplay());
if (tr != null && tr.getResource() != null) {
c.tx(". Generated Summary: ");
new ProfileDrivenRenderer(context).generateResourceSummary(c, tr.getResource(), true, r.getReference().startsWith("#"));
if (tr != null && tr.getReference() != null && tr.getReference().startsWith("#")) {
c.tx("See above (");
}
// what to display: if text is provided, then that. if the reference was resolved, then show the name, or the generated narrative
String display = r.hasDisplayElement() ? r.getDisplay() : null;
String name = tr != null && tr.getResource() != null ? tr.getResource().getNameFromResource() : null;
if (display == null && (tr == null || tr.getResource() == null)) {
c.addText(r.getReference());
} else if (context.isTechnicalMode()) {
c.addText(r.getReference());
if (display != null) {
c.addText(": "+display);
}
} else if (tr != null && tr.getResource() != null) {
if (tr.getReference().startsWith("#")) {
// we already rendered this in this page
c.tx("See above ("+tr.getResource().fhirType()+"/"+tr.getResource().getId()+")");
} else {
new ProfileDrivenRenderer(context).generateResourceSummary(c, tr.getResource(), r.getReference().startsWith("#"), r.getReference().startsWith("#"));
if ((tr == null || !tr.getReference().startsWith("#")) && name != null) {
x.addText(" \""+name+"\"");
}
} else {
c.addText(r.getReference());
if (display != null) {
c.addText(display);
} else if (name != null) {
c.addText(name);
} else {
c.tx(". Generated Summary: ");
if (tr != null) {
new ProfileDrivenRenderer(context).generateResourceSummary(c, tr.getResource(), true, r.getReference().startsWith("#"), true);
}
}
}
if (tr != null && tr.getReference() != null && tr.getReference().startsWith("#")) {
c.tx(")");
}
}
@ -236,10 +253,10 @@ public abstract class ResourceRenderer extends DataRenderer {
c.addText(r.get("display").primitiveValue());
if (tr != null && tr.getResource() != null) {
c.tx(". Generated Summary: ");
new ProfileDrivenRenderer(context).generateResourceSummary(c, tr.getResource(), true, v.startsWith("#"));
new ProfileDrivenRenderer(context).generateResourceSummary(c, tr.getResource(), true, v.startsWith("#"), false);
}
} else if (tr != null && tr.getResource() != null) {
new ProfileDrivenRenderer(context).generateResourceSummary(c, tr.getResource(), v.startsWith("#"), v.startsWith("#"));
new ProfileDrivenRenderer(context).generateResourceSummary(c, tr.getResource(), v.startsWith("#"), v.startsWith("#"), false);
} else {
c.addText(v);
}
@ -371,4 +388,94 @@ public abstract class ResourceRenderer extends DataRenderer {
return true;
}
protected void renderResourceHeader(ResourceWrapper r, XhtmlNode x) throws UnsupportedEncodingException, FHIRException, IOException {
XhtmlNode div = x.div().style("display: inline-block").style("background-color: #d9e0e7").style("padding: 6px").style("margin: 4px").style("border: 1px solid #8da1b4")
.style("border-radius: 5px").style("line-height: 60%");
String id = getPrimitiveValue(r, "id");
String lang = getPrimitiveValue(r, "language");
String ir = getPrimitiveValue(r, "implicitRules");
BaseWrapper meta = r.getChildByName("meta").hasValues() ? r.getChildByName("meta").getValues().get(0) : null;
String versionId = getPrimitiveValue(meta, "versionId");
String lastUpdated = getPrimitiveValue(meta, "lastUpdated");
String source = getPrimitiveValue(meta, "source");
if (id != null || lang != null || versionId != null || lastUpdated != null) {
XhtmlNode p = plateStyle(div.para());
p.tx("Resource ");
if (id != null) {
p.tx("\""+id+"\" ");
}
if (versionId != null) {
p.tx("Version \""+versionId+"\" ");
}
if (lastUpdated != null) {
p.tx("Updated \"");
renderDateTime(p, lastUpdated);
p.tx("\" ");
}
if (lang != null) {
p.tx(" (Language \""+lang+"\") ");
}
}
if (ir != null) {
plateStyle(div.para()).b().tx("Special rules apply: "+ir+"!");
}
if (source != null) {
plateStyle(div.para()).tx("Information Source: "+source+"!");
}
if (meta != null) {
PropertyWrapper pl = meta.getChildByName("profile");
if (pl.hasValues()) {
XhtmlNode p = plateStyle(div.para());
p.tx(Utilities.pluralize("Profile", pl.getValues().size())+": ");
boolean first = true;
for (BaseWrapper bw : pl.getValues()) {
if (first) first = false; else p.tx(", ");
renderCanonical(r, p, bw.getBase().primitiveValue());
}
}
PropertyWrapper tl = meta.getChildByName("tag");
if (tl.hasValues()) {
XhtmlNode p = plateStyle(div.para());
p.tx(Utilities.pluralize("Tag", tl.getValues().size())+": ");
boolean first = true;
for (BaseWrapper bw : tl.getValues()) {
if (first) first = false; else p.tx(", ");
String system = getPrimitiveValue(bw, "system");
String version = getPrimitiveValue(bw, "version");
String code = getPrimitiveValue(bw, "system");
String display = getPrimitiveValue(bw, "system");
renderCoding(p, new Coding(system, version, code, display));
}
}
PropertyWrapper sl = meta.getChildByName("security");
if (sl.hasValues()) {
XhtmlNode p = plateStyle(div.para());
p.tx(Utilities.pluralize("Security Label", tl.getValues().size())+": ");
boolean first = true;
for (BaseWrapper bw : sl.getValues()) {
if (first) first = false; else p.tx(", ");
String system = getPrimitiveValue(bw, "system");
String version = getPrimitiveValue(bw, "version");
String code = getPrimitiveValue(bw, "system");
String display = getPrimitiveValue(bw, "system");
renderCoding(p, new Coding(system, version, code, display));
}
}
}
}
private XhtmlNode plateStyle(XhtmlNode para) {
return para.style("margin-bottom: 0px");
}
private String getPrimitiveValue(BaseWrapper b, String name) throws UnsupportedEncodingException, FHIRException, IOException {
return b != null && b.getChildByName(name).hasValues() ? b.getChildByName(name).getValues().get(0).getBase().primitiveValue() : null;
}
private String getPrimitiveValue(ResourceWrapper r, String name) throws UnsupportedEncodingException, FHIRException, IOException {
return r.getChildByName(name).hasValues() ? r.getChildByName(name).getValues().get(0).getBase().primitiveValue() : null;
}
}

View File

@ -712,7 +712,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
public String sctLink(String code) {
// if (snomedEdition != null)
// http://browser.ihtsdotools.org/?perspective=full&conceptId1=428041000124106&edition=us-edition&release=v20180301&server=https://prod-browser-exten.ihtsdotools.org/api/snomed&langRefset=900000000000509007
return "http://browser.ihtsdotools.org/?perspective=full&conceptId1="+code;
return "http://snomed.info/id/"+code;
}
private void addRefToCode(XhtmlNode td, String target, String vslink, String code) {

View File

@ -55,6 +55,7 @@ public class BaseWrappers {
public PropertyWrapper getChildByName(String tail);
public StructureDefinition getDefinition();
public boolean hasNarrative();
public String getNameFromResource();
}
public interface BaseWrapper extends WrapperBase {

View File

@ -10,6 +10,7 @@ import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.formats.FormatUtilities;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.ElementDefinition;
import org.hl7.fhir.r5.model.Property;
import org.hl7.fhir.r5.model.Narrative.NarrativeStatus;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
@ -267,6 +268,29 @@ public class DOMWrappers {
return wrapped.getNodeName();
}
@Override
public String getNameFromResource() {
Element e = XMLUtil.getNamedChild(wrapped, "name");
if (e != null) {
if (e.hasAttribute("value")) {
return e.getAttribute("value");
}
if (XMLUtil.hasNamedChild(e, "text")) {
return XMLUtil.getNamedChildValue(e, "text");
}
if (XMLUtil.hasNamedChild(e, "family") || XMLUtil.hasNamedChild(e, "given")) {
Element family = XMLUtil.getNamedChild(e, "family");
Element given = XMLUtil.getNamedChild(e, "given");
String s = given != null && given.hasAttribute("value") ? given.getAttribute("value") : "";
if (family != null && family.hasAttribute("value"))
s = s + " " + family.getAttribute("value").toUpperCase();
return s;
}
return null;
}
return null;
}
@Override
public List<PropertyWrapper> children() {
if (list2 == null) {

View File

@ -208,6 +208,28 @@ public class DirectWrappers {
return wrapped.getResourceType().toString();
}
@Override
public String getNameFromResource() {
Property name = wrapped.getChildByName("name");
if (name != null && name.hasValues()) {
Base b = name.getValues().get(0);
if (b.isPrimitive()) {
return b.primitiveValue();
} else if (b.fhirType().equals("HumanName")) {
Property family = b.getChildByName("family");
Property given = wrapped.getChildByName("given");
String s = given != null && given.hasValues() ? given.getValues().get(0).primitiveValue() : "";
if (family != null && family.hasValues())
s = s + " " + family.getValues().get(0).primitiveValue().toUpperCase();
return s;
} else {
// it might be a human name?
throw new Error("What to do?");
}
}
return null;
}
@Override
public List<PropertyWrapper> children() {
List<PropertyWrapper> list = new ArrayList<PropertyWrapper>();

View File

@ -16,6 +16,7 @@ import org.hl7.fhir.r5.elementmodel.XmlParser;
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.ElementDefinition;
import org.hl7.fhir.r5.model.Property;
import org.hl7.fhir.r5.model.Narrative.NarrativeStatus;
import org.hl7.fhir.r5.model.StringType;
import org.hl7.fhir.r5.model.StructureDefinition;
@ -157,6 +158,27 @@ public class ElementWrappers {
return wrapped.getName();
}
@Override
public String getNameFromResource() {
Property name = wrapped.getChildByName("name");
if (name != null && name.hasValues()) {
Base b = name.getValues().get(0);
if (b.isPrimitive()) {
return b.primitiveValue();
} else if (b.fhirType().equals("HumanName")) {
Property family = b.getChildByName("family");
Property given = wrapped.getChildByName("given");
String s = given != null && given.hasValues() ? given.getValues().get(0).primitiveValue() : "";
if (family != null && family.hasValues())
s = s + " " + family.getValues().get(0).primitiveValue().toUpperCase();
return s;
} else {
throw new Error("Now what? ("+b.fhirType()+")");
}
}
return null;
}
@Override
public List<PropertyWrapper> children() {
if (list2 == null) {

View File

@ -23,20 +23,38 @@ import org.hl7.fhir.utilities.validation.ValidationOptions;
public class RenderingContext {
// provides liquid templates, if they are available for the content
public interface ILiquidTemplateProvider {
String findTemplate(RenderingContext rcontext, DomainResource r);
String findTemplate(RenderingContext rcontext, String resourceName);
}
// parses xml to an XML instance. Whatever codes provides this needs to provide something that parses the right version
public interface ITypeParser {
Base parseType(String xml, String type) throws FHIRFormatError, IOException, FHIRException ;
}
public enum ResourceRendererMode{
RESOURCE, IG
/**
* What kind of user the renderer is targeting - end users, or technical users
*
* This affects the way codes and references are rendered
*
* @author graha
*
*/
public enum ResourceRendererMode {
/**
* The user has no interest in the contents of the FHIR resource, and just wants to see the data
*
*/
END_USER,
/**
* The user wants to see the resource, but a technical view so they can see what's going on with the content
*/
TECHNICAL
}
public enum QuestionnaireRendererMode {
/**
* A visual presentation of the questionnaire, with a set of property panes that can be toggled on and off.
@ -405,4 +423,8 @@ public class RenderingContext {
this.targetVersion = targetVersion;
}
public boolean isTechnicalMode() {
return mode == ResourceRendererMode.TECHNICAL;
}
}

View File

@ -0,0 +1,165 @@
package org.hl7.fhir.r5.terminologies;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import org.hl7.fhir.utilities.SimpleHTTPClient;
import org.hl7.fhir.utilities.SimpleHTTPClient.HTTPResult;
import org.hl7.fhir.utilities.IniFile;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtilities;
public class TerminologyCacheManager {
// if either the CACHE_VERSION of the stated maj/min server versions change, the
// cache will be blown. Note that the stated terminology server version is
// the CapabilityStatement.software.version
private static final String CACHE_VERSION = "1";
private String cacheFolder;
private String version;
private String ghOrg;
private String ghRepo;
private String ghBranch;
public TerminologyCacheManager(String serverVersion, String rootDir, String ghOrg, String ghRepo, String ghBranch) throws IOException {
super();
// this.rootDir = rootDir;
this.ghOrg = ghOrg;
this.ghRepo = ghRepo;
this.ghBranch = ghBranch;
version = CACHE_VERSION+"/"+VersionUtilities.getMajMin(serverVersion);
if (Utilities.noString(ghOrg) || Utilities.noString(ghRepo) || Utilities.noString(ghBranch)) {
cacheFolder = Utilities.path(rootDir, "temp", "tx-cache");
} else {
cacheFolder = Utilities.path(System.getProperty("user.home"), ".fhir", "tx-cache", ghOrg, ghRepo, ghBranch);
}
}
public void initialize() throws IOException {
File f = new File(cacheFolder);
if (!f.exists()) {
Utilities.createDirectory(cacheFolder);
}
if (!version.equals(getCacheVersion())) {
clearCache();
fillCache("http://tx.fhir.org/tx-cache/"+ghOrg+"/"+ghRepo+"/"+ghBranch+".zip");
}
if (!version.equals(getCacheVersion())) {
clearCache();
fillCache("http://tx.fhir.org/tx-cache/"+ghOrg+"/"+ghRepo+"/default.zip");
}
if (!version.equals(getCacheVersion())) {
clearCache();
}
IniFile ini = new IniFile(Utilities.path(cacheFolder, "cache.ini"));
ini.setStringProperty("version", "version", version, null);
ini.save();
}
private void fillCache(String source) throws IOException {
try {
System.out.println("Initialise terminology cache from "+source);
SimpleHTTPClient http = new SimpleHTTPClient();
HTTPResult res = http.get(source+"?nocache=" + System.currentTimeMillis());
res.checkThrowException();
unzip(new ByteArrayInputStream(res.getContent()), cacheFolder);
} catch (Exception e) {
System.out.println("No - can't initialise cache from "+source+": "+e.getMessage());
}
}
public static void unzip(InputStream is, String targetDir) throws IOException {
try (ZipInputStream zipIn = new ZipInputStream(is)) {
for (ZipEntry ze; (ze = zipIn.getNextEntry()) != null; ) {
String path = Utilities.path(targetDir, ze.getName());
if (!path.startsWith(targetDir)) {
// see: https://snyk.io/research/zip-slip-vulnerability
throw new RuntimeException("Entry with an illegal path: " + ze.getName());
}
if (ze.isDirectory()) {
Utilities.createDirectory(path);
} else {
Utilities.createDirectory(Utilities.getDirectoryForFile(path));
TextFile.streamToFile(zipIn, path);
}
}
}
}
private void clearCache() throws IOException {
Utilities.clearDirectory(cacheFolder);
}
private String getCacheVersion() throws IOException {
IniFile ini = new IniFile(Utilities.path(cacheFolder, "cache.ini"));
return ini.getStringProperty("version", "version");
}
public String getFolder() {
return cacheFolder;
}
private void zipDirectory(OutputStream outputStream) throws IOException {
try (ZipOutputStream zs = new ZipOutputStream(outputStream)) {
Path pp = Paths.get(cacheFolder);
Files.walk(pp)
.forEach(path -> {
try {
if (Files.isDirectory(path)) {
zs.putNextEntry(new ZipEntry(pp.relativize(path).toString() + "/"));
} else {
ZipEntry zipEntry = new ZipEntry(pp.relativize(path).toString());
zs.putNextEntry(zipEntry);
Files.copy(path, zs);
zs.closeEntry();
}
} catch (IOException e) {
System.err.println(e);
}
});
}
}
public void commit(String token) throws IOException {
// create a zip of all the files
ByteArrayOutputStream bs = new ByteArrayOutputStream();
zipDirectory(bs);
// post it to
String url = "https://tx.fhir.org/post/tx-cache/"+ghOrg+"/"+ghRepo+"/"+ghBranch+".zip";
System.out.println("Sending tx-cache to "+url+" ("+Utilities.describeSize(bs.toByteArray().length)+")");
SimpleHTTPClient http = new SimpleHTTPClient();
HTTPResult res = http.put(url, "application/zip", bs.toByteArray(), null); // accept doesn't matter
if (res.getCode() >= 300) {
System.out.println("sending cache failed: "+res.getCode());
} else {
System.out.println("Sent cache");
}
}
}

View File

@ -308,15 +308,9 @@ public class FHIRToolingClient {
URI url = resourceAddress.resolveOperationURLFromClass(resourceClass, name, ps);
if (complex) {
byte[] body = ByteUtils.resourceToByteArray(params, false, isJson(getPreferredResourceFormat()));
if (client.getLogger() != null) {
client.getLogger().logRequest("POST", url.toString(), null, body);
}
result = client.issuePostRequest(url, body, getPreferredResourceFormat(), generateHeaders(),
"POST " + resourceClass.getName() + "/$" + name, TIMEOUT_OPERATION_LONG);
} else {
if (client.getLogger() != null) {
client.getLogger().logRequest("GET", url.toString(), null, null);
}
result = client.issueGetResourceRequest(url, getPreferredResourceFormat(), generateHeaders(), "GET " + resourceClass.getName() + "/$" + name, TIMEOUT_OPERATION_LONG);
}
if (result.isUnsuccessfulRequest()) {

View File

@ -4,6 +4,7 @@ import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.logging.HttpLoggingInterceptor;
import org.hl7.fhir.r5.model.Bundle;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.utils.client.EFhirClientException;
@ -19,6 +20,7 @@ public class Client {
public static final String DEFAULT_CHARSET = "UTF-8";
private static final long DEFAULT_TIMEOUT = 5000;
private ToolingClientLogger logger;
private FhirLoggingInterceptor fhirLoggingInterceptor;
private int retryCount;
private long timeout = DEFAULT_TIMEOUT;
private byte[] payload;
@ -29,6 +31,7 @@ public class Client {
public void setLogger(ToolingClientLogger logger) {
this.logger = logger;
this.fhirLoggingInterceptor = new FhirLoggingInterceptor(logger);
}
public int getRetryCount() {
@ -173,13 +176,13 @@ public class Client {
int retryCount,
long timeout) throws IOException {
return new FhirRequestBuilder(request)
.withLogger(logger)
.withLogger(fhirLoggingInterceptor)
.withResourceFormat(resourceFormat)
.withRetryCount(retryCount)
.withMessage(message)
.withHeaders(headers == null ? new Headers.Builder().build() : headers)
.withTimeout(timeout, TimeUnit.MILLISECONDS)
.executeAsBatch(payload);
.executeAsBatch();
}
public <T extends Resource> ResourceRequest<T> executeFhirRequest(Request.Builder request,
@ -189,12 +192,12 @@ public class Client {
int retryCount,
long timeout) throws IOException {
return new FhirRequestBuilder(request)
.withLogger(logger)
.withLogger(fhirLoggingInterceptor)
.withResourceFormat(resourceFormat)
.withRetryCount(retryCount)
.withMessage(message)
.withHeaders(headers == null ? new Headers.Builder().build() : headers)
.withTimeout(timeout, TimeUnit.MILLISECONDS)
.execute(payload);
.execute();
}
}

View File

@ -0,0 +1,55 @@
package org.hl7.fhir.r5.utils.client.network;
import okhttp3.*;
import org.hl7.fhir.utilities.ToolingClientLogger;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class FhirLoggingInterceptor implements Interceptor {
private ToolingClientLogger logger;
public FhirLoggingInterceptor(ToolingClientLogger logger) {
this.logger = logger;
}
public FhirLoggingInterceptor setLogger(ToolingClientLogger logger) {
this.logger = logger;
return this;
}
@NotNull
@Override
public Response intercept(@NotNull Interceptor.Chain chain) throws IOException {
// Log Request
Request request = chain.request();
logger.logRequest(request.method(), request.url().toString(), new ArrayList<>(request.headers().names()),
request.body() != null ? request.body().toString().getBytes() : null);
// Log Response
Response response = null;
response = chain.proceed(chain.request());
MediaType contentType = null;
byte[] bodyBytes = null;
if (response.body() != null) {
contentType = response.body().contentType();
bodyBytes = response.body().bytes();
}
// Get Headers as List
List<String> headerList = new ArrayList<>();
Map<String, List<String>> headerMap = response.headers().toMultimap();
headerMap.keySet().forEach(key -> headerMap.get(key).forEach(value -> headerList.add(key + ":" + value)));
logger.logResponse(Integer.toString(response.code()), headerList, bodyBytes);
// Reading byte[] clears body. Need to recreate.
ResponseBody body = ResponseBody.create(bodyBytes, contentType);
return response.newBuilder().body(body).build();
}
}

View File

@ -1,8 +1,6 @@
package org.hl7.fhir.r5.utils.client.network;
import okhttp3.*;
import okio.RealBufferedSink;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.r5.formats.IParser;
import org.hl7.fhir.r5.formats.JsonParser;
@ -47,10 +45,11 @@ public class FhirRequestBuilder {
* Time unit for {@link FhirRequestBuilder#timeout}.
*/
private TimeUnit timeoutUnit = TimeUnit.MILLISECONDS;
/**
* {@link ToolingClientLogger} for log output.
* {@link FhirLoggingInterceptor} for log output.
*/
private ToolingClientLogger logger = null;
private FhirLoggingInterceptor logger = null;
public FhirRequestBuilder(Request.Builder httpRequest) {
this.httpRequest = httpRequest;
@ -162,9 +161,11 @@ public class FhirRequestBuilder {
.build();
};
return okHttpClient.newBuilder()
.addInterceptor(new RetryInterceptor(retryCount))
.connectTimeout(timeout, timeoutUnit)
OkHttpClient.Builder builder = okHttpClient.newBuilder();
if (logger != null) builder.addInterceptor(logger);
builder.addInterceptor(new RetryInterceptor(retryCount));
return builder.connectTimeout(timeout, timeoutUnit)
.writeTimeout(timeout, timeoutUnit)
.readTimeout(timeout, timeoutUnit)
.proxyAuthenticator(proxyAuthenticator)
@ -191,7 +192,7 @@ public class FhirRequestBuilder {
return this;
}
public FhirRequestBuilder withLogger(ToolingClientLogger logger) {
public FhirRequestBuilder withLogger(FhirLoggingInterceptor logger) {
this.logger = logger;
return this;
}
@ -203,30 +204,18 @@ public class FhirRequestBuilder {
}
protected Request buildRequest() {
Request req = httpRequest.build();
return req;
return httpRequest.build();
}
public <T extends Resource> ResourceRequest<T> execute(byte[] payload) throws IOException {
public <T extends Resource> ResourceRequest<T> execute() throws IOException {
formatHeaders(httpRequest, resourceFormat, headers);
logRequest(payload);
Response response = getHttpClient().newCall(httpRequest.build()).execute();
T resource = unmarshalReference(response, resourceFormat);
return new ResourceRequest<T>(resource, response.code(), getLocationHeader(response.headers()));
}
public void logRequest(byte[] payload) {
if (logger != null) {
List<String> headerList = new ArrayList<>(Collections.emptyList());
Map<String, List<String>> headerMap = headers.toMultimap();
headerMap.keySet().forEach(key -> headerMap.get(key).forEach(value -> headerList.add(key + ":" + value)));
logger.logRequest(httpRequest.getMethod$okhttp().toString(), httpRequest.getUrl$okhttp().toString(), headerList, payload);
}
}
public Bundle executeAsBatch(byte[] payload) throws IOException {
public Bundle executeAsBatch() throws IOException {
formatHeaders(httpRequest, resourceFormat, null);
logRequest(payload);
Response response = getHttpClient().newCall(httpRequest.build()).execute();
return unmarshalFeed(response, resourceFormat);
}
@ -242,7 +231,6 @@ public class FhirRequestBuilder {
if (response.body() != null) {
try {
byte[] body = response.body().bytes();
log(response.code(), response.headers(), body);
resource = (T) getParser(format).parse(body);
if (resource instanceof OperationOutcome && hasError((OperationOutcome) resource)) {
error = (OperationOutcome) resource;
@ -269,7 +257,6 @@ public class FhirRequestBuilder {
OperationOutcome error = null;
try {
byte[] body = response.body().bytes();
log(response.code(), response.headers(), body);
String contentType = response.header("Content-Type");
if (body != null) {
if (contentType.contains(ResourceFormat.RESOURCE_XML.getHeader()) || contentType.contains("text/xml+fhir")) {
@ -315,31 +302,4 @@ public class FhirRequestBuilder {
throw new EFhirClientException("Invalid format: " + format);
}
}
/**
* Logs the given {@link Response}, using the current {@link ToolingClientLogger}. If the current
* {@link FhirRequestBuilder#logger} is null, no action is taken.
*
* @param responseCode HTTP response code
* @param responseHeaders {@link Headers} from response
* @param responseBody Byte array response
*/
protected void log(int responseCode, Headers responseHeaders, byte[] responseBody) {
if (logger != null) {
List<String> headerList = new ArrayList<>(Collections.emptyList());
Map<String, List<String>> headerMap = responseHeaders.toMultimap();
headerMap.keySet().forEach(key -> headerMap.get(key).forEach(value -> headerList.add(key + ":" + value)));
try {
logger.logResponse(Integer.toString(responseCode), headerList, responseBody);
} catch (Exception e) {
System.out.println("Error parsing response body passed in to logger ->\n" + e.getLocalizedMessage());
}
}
// else { // TODO fix logs
// System.out.println("Call to log HTTP response with null ToolingClientLogger set... are you forgetting to " +
// "initialize your logger?");
// }
}
}

View File

@ -127,7 +127,7 @@ public class NarrativeGenerationTests {
@ParameterizedTest(name = "{index}: file {0}")
@MethodSource("data")
public void test(String id, TestDetails test) throws Exception {
RenderingContext rc = new RenderingContext(context, null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.RESOURCE);
RenderingContext rc = new RenderingContext(context, null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.END_USER);
rc.setDestDir("");
rc.setHeader(test.isHeader());
rc.setDefinitionsTarget("test.html");

View File

@ -24,7 +24,7 @@ public class NarrativeGeneratorTests {
@BeforeAll
public static void setUp() throws FHIRException {
rc = new RenderingContext(TestingUtilities.context(), null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.RESOURCE);
rc = new RenderingContext(TestingUtilities.context(), null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.END_USER);
}
@Test

View File

@ -35,7 +35,7 @@ public class ResourceRoundTripTests {
@Test
public void test() throws IOException, FHIRException, EOperationOutcome {
DomainResource res = (DomainResource) new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", "unicode.xml"));
RenderingContext rc = new RenderingContext(TestingUtilities.context(), null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.RESOURCE);
RenderingContext rc = new RenderingContext(TestingUtilities.context(), null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.END_USER);
RendererFactory.factory(res, rc).render(res);
IOUtils.copy(TestingUtilities.loadTestResourceStream("r5", "unicode.xml"), new FileOutputStream(TestingUtilities.tempFile("gen", "unicode.xml")));
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(TestingUtilities.tempFile("gen", "unicode.out.xml")), res);

View File

@ -42,6 +42,7 @@ import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.npm.CommonPackages;
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
import org.hl7.fhir.utilities.npm.NpmPackage;
import org.hl7.fhir.utilities.npm.ToolsVersion;
@ -546,8 +547,8 @@ public class SnapShotGenerationTests {
pu.setThrowException(false);
pu.setDebug(test.isDebug());
pu.setIds(test.getSource(), false);
if (!TestingUtilities.context().hasPackage("hl7.fhir.xver-extensions", "0.0.4")) {
NpmPackage npm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION).loadPackage("hl7.fhir.xver-extensions", "0.0.4");
if (!TestingUtilities.context().hasPackage(CommonPackages.ID_XVER, CommonPackages.VER_XVER)) {
NpmPackage npm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION).loadPackage(CommonPackages.ID_XVER, CommonPackages.VER_XVER);
TestingUtilities.context().loadFromPackage(npm, new TestLoader(new String[]{"StructureDefinition"}), new String[]{"StructureDefinition"});
}
pu.setXver(new XVerExtensionManager(TestingUtilities.context()));
@ -575,7 +576,7 @@ public class SnapShotGenerationTests {
throw e;
}
if (output.getDifferential().hasElement()) {
RenderingContext rc = new RenderingContext(TestingUtilities.context(), null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.RESOURCE);
RenderingContext rc = new RenderingContext(TestingUtilities.context(), null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.END_USER);
rc.setDestDir(Utilities.path("[tmp]", "snapshot"));
rc.setProfileUtilities(new ProfileUtilities(TestingUtilities.context(), null, new TestPKP()));
RendererFactory.factory(output, rc).render(output);

View File

@ -4,9 +4,11 @@ import okhttp3.HttpUrl;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import org.hl7.fhir.r5.context.HTMLClientLogger;
import org.hl7.fhir.r5.formats.JsonParser;
import org.hl7.fhir.r5.model.*;
import org.junit.jupiter.api.*;
import org.mockito.Mockito;
import java.io.IOException;
import java.net.URI;
@ -143,4 +145,24 @@ class ClientTest {
Assertions.assertArrayEquals(payload, recordedRequest.getBody().readByteArray(),
"POST request payload does not match send data.");
}
@Test
@DisplayName("Testing the logger works.")
void test_logger() throws IOException, URISyntaxException, InterruptedException {
byte[] payload = ByteUtils.resourceToByteArray(patient, true, false);
server.enqueue(
new MockResponse()
.setResponseCode(200)
.setBody(new String(payload))
);
HTMLClientLogger mockLogger = Mockito.mock(HTMLClientLogger.class);
client.setLogger(mockLogger);
client.issuePostRequest(new URI(serverUrl.toString()), payload,
"xml", null, TIMEOUT);
server.takeRequest();
Mockito.verify(mockLogger, Mockito.times(1))
.logRequest(Mockito.anyString(), Mockito.anyString(), Mockito.anyList(), Mockito.any());
Mockito.verify(mockLogger, Mockito.times(1))
.logResponse(Mockito.anyString(), Mockito.anyList(), Mockito.any());
}
}

View File

@ -86,6 +86,14 @@
<version>${validator_test_case_version}</version>
<scope>test</scope>
</dependency>
<!--
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>logging-interceptor</artifactId>
<version>4.9.0</version>
<scope>compile</scope>
</dependency>
-->
</dependencies>
<build>

View File

@ -1,5 +1,5 @@
package org.hl7.fhir.utilities;
package org.hl7.fhir.utilities;
/*
Copyright (c) 2011+, HL7, Inc.
All rights reserved.
@ -28,17 +28,16 @@ package org.hl7.fhir.utilities;
POSSIBILITY OF SUCH DAMAGE.
*/
import java.util.List;
public interface ToolingClientLogger {
public void logRequest(String method, String url, List<String> headers, byte[] body);
public void logResponse(String outcome, List<String> headers, byte[] body);
public String getLastId();
public void clearLastId();
import java.util.List;
public interface ToolingClientLogger {
void logRequest(String method, String url, List<String> headers, byte[] body);
void logResponse(String outcome, List<String> headers, byte[] body);
String getLastId();
void clearLastId();
}

View File

@ -1501,5 +1501,14 @@ public class Utilities {
return oid.matches(OID_REGEX);
}
public static int findinList(String[] list, String val) {
for (int i = 0; i < list.length; i++) {
if (val.equals(list[i])) {
return i;
}
}
return -1;
}
}

View File

@ -653,6 +653,7 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
http.trustAllhosts();
HTTPResult res = http.get("https://build.fhir.org/ig/qas.json?nocache=" + System.currentTimeMillis());
res.checkThrowException();
TextFile.bytesToFile(res.getContent(), "c:\\temp\\qa.json");
buildInfo = (JsonArray) new com.google.gson.JsonParser().parse(TextFile.bytesToString(res.getContent()));
List<BuildRecord> builds = new ArrayList<>();

View File

@ -727,16 +727,19 @@ public class NpmPackage {
if ("hl7.fhir.core".equals(JSONUtil.str(npm, "name")))
return JSONUtil.str(npm, "version");
else if (JSONUtil.str(npm, "name").startsWith("hl7.fhir.r2.") || JSONUtil.str(npm, "name").startsWith("hl7.fhir.r2b.") || JSONUtil.str(npm, "name").startsWith("hl7.fhir.r3.") ||
JSONUtil.str(npm, "name").startsWith("hl7.fhir.r4.") || JSONUtil.str(npm, "name").startsWith("hl7.fhir.r4b.") || JSONUtil.str(npm, "name").startsWith("hl7.fhir.r5."))
JSONUtil.str(npm, "name").startsWith("hl7.fhir.r4.") || JSONUtil.str(npm, "name").startsWith("hl7.fhir.r4b.") || JSONUtil.str(npm, "name").startsWith("hl7.fhir.r5."))
return JSONUtil.str(npm, "version");
else {
JsonObject dep = npm.getAsJsonObject("dependencies");
if (dep != null) {
for (Entry<String, JsonElement> e : dep.entrySet()) {
if (Utilities.existsInList(e.getKey(), "hl7.fhir.r2.core", "hl7.fhir.r2b.core", "hl7.fhir.r3.core", "hl7.fhir.r4.core"))
return e.getValue().getAsString();
if (Utilities.existsInList(e.getKey(), "hl7.fhir.core")) // while all packages are updated
return e.getValue().getAsString();
else {
JsonObject dep = null;
if (npm.has("dependencies") && npm.get("dependencies").isJsonObject()) {
dep = npm.getAsJsonObject("dependencies");
if (dep != null) {
for (Entry<String, JsonElement> e : dep.entrySet()) {
if (Utilities.existsInList(e.getKey(), "hl7.fhir.r2.core", "hl7.fhir.r2b.core", "hl7.fhir.r3.core", "hl7.fhir.r4.core"))
return e.getValue().getAsString();
if (Utilities.existsInList(e.getKey(), "hl7.fhir.core")) // while all packages are updated
return e.getValue().getAsString();
}
}
}
if (npm.has("fhirVersions")) {
@ -955,8 +958,13 @@ public class NpmPackage {
public String fhirVersionList() {
if (npm.has("fhirVersions")) {
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
for (JsonElement n : npm.getAsJsonArray("fhirVersions")) {
b.append(n.getAsString());
if (npm.get("fhirVersions").isJsonArray()) {
for (JsonElement n : npm.getAsJsonArray("fhirVersions")) {
b.append(n.getAsString());
}
}
if (npm.get("fhirVersions").isJsonPrimitive()) {
b.append(npm.get("fhirVersions").getAsString());
}
return b.toString();
} else

View File

@ -1,6 +1,7 @@
package org.hl7.fhir.utilities.tests;
import org.hl7.fhir.utilities.npm.CachingPackageClient;
import org.hl7.fhir.utilities.npm.CommonPackages;
import org.hl7.fhir.utilities.npm.PackageInfo;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@ -70,7 +71,7 @@ public class CachingPackageClientTests {
Assertions.assertTrue(client.exists("hl7.fhir.r4.core", "4.0.1"));
Assertions.assertTrue(!client.exists("hl7.fhir.r4.core", "1.0.2"));
Assertions.assertTrue(!client.exists("hl7.fhir.nothing", "1.0.1"));
Assertions.assertTrue(client.exists("hl7.fhir.pubpack", "0.0.9"));
Assertions.assertTrue(client.exists(CommonPackages.ID_PUBPACK, CommonPackages.VER_PUBPACK));
}
@Test

View File

@ -1,6 +1,7 @@
package org.hl7.fhir.utilities.tests;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.npm.CommonPackages;
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
import org.hl7.fhir.utilities.npm.NpmPackage;
import org.hl7.fhir.utilities.npm.ToolsVersion;
@ -22,7 +23,7 @@ public class PackageCacheTests {
System.out.println("remaining packages: "+list.toString());
}
Assertions.assertTrue(list.isEmpty(), "List should be true but is "+list.toString());
NpmPackage npm = cache.loadPackage("hl7.fhir.pubpack", "0.0.9");
NpmPackage npm = cache.loadPackage(CommonPackages.ID_PUBPACK, CommonPackages.VER_PUBPACK);
npm.loadAllFiles();
Assertions.assertNotNull(npm);
File dir = new File(Utilities.path("[tmp]", "cache"));
@ -32,7 +33,7 @@ public class PackageCacheTests {
Utilities.createDirectory(dir.getAbsolutePath());
}
npm.save(dir);
NpmPackage npm2 = cache.loadPackage("hl7.fhir.pubpack", "file:" + dir.getAbsolutePath());
NpmPackage npm2 = cache.loadPackage(CommonPackages.ID_PUBPACK, "file:" + dir.getAbsolutePath());
Assertions.assertNotNull(npm2);
list = cache.listPackages();
Assertions.assertFalse(list.isEmpty());
@ -60,7 +61,7 @@ public class PackageCacheTests {
public void testLastReleasedVersion() throws IOException {
FilesystemPackageCacheManager cache = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
cache.clear();
Assertions.assertEquals("0.0.8", cache.loadPackage("hl7.fhir.pubpack", "0.0.8").version());
Assertions.assertEquals("0.0.9", cache.loadPackage("hl7.fhir.pubpack").version());
Assertions.assertEquals("0.0.8", cache.loadPackage(CommonPackages.ID_PUBPACK, "0.0.8").version());
Assertions.assertEquals(CommonPackages.VER_PUBPACK, cache.loadPackage(CommonPackages.ID_PUBPACK).version());
}
}

View File

@ -107,6 +107,11 @@ public class XhtmlNodeTest {
Assertions.assertThrows(FHIRException.class, () -> new XhtmlParser().parse(BaseTestingUtilities.loadTestResource("xhtml", "bad-link.html"), "div"));
}
@Test
public void testParseEntities() throws FHIRFormatError, IOException {
XhtmlNode x = new XhtmlParser().parse(BaseTestingUtilities.loadTestResource("xhtml", "entities.html"), "div");
}
}

View File

@ -11,6 +11,8 @@ import org.hl7.fhir.r5.renderers.RendererFactory;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.utils.EOperationOutcome;
import org.hl7.fhir.r5.utils.FHIRPathEngine;
import org.hl7.fhir.utilities.SimpleHTTPClient;
import org.hl7.fhir.utilities.SimpleHTTPClient.HTTPResult;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.validation.ValidationMessage;
@ -19,8 +21,6 @@ import org.hl7.fhir.validation.cli.model.ScanOutputItem;
import org.hl7.fhir.validation.instance.InstanceValidator;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
@ -240,7 +240,7 @@ public class Scanner {
}
protected void genScanOutputItem(ScanOutputItem item, String filename) throws IOException, FHIRException, EOperationOutcome {
RenderingContext rc = new RenderingContext(getContext(), null, null, "http://hl7.org/fhir", "", null, RenderingContext.ResourceRendererMode.RESOURCE);
RenderingContext rc = new RenderingContext(getContext(), null, null, "http://hl7.org/fhir", "", null, RenderingContext.ResourceRendererMode.END_USER);
rc.setNoSlowLookup(true);
RendererFactory.factory(item.getOutcome(), rc).render(item.getOutcome());
String s = new XhtmlComposer(XhtmlComposer.HTML).compose(item.getOutcome().getText().getDiv());
@ -294,18 +294,16 @@ public class Scanner {
protected OperationOutcome exceptionToOutcome(Exception ex) throws IOException, FHIRException, EOperationOutcome {
OperationOutcome op = new OperationOutcome();
op.addIssue().setCode(OperationOutcome.IssueType.EXCEPTION).setSeverity(OperationOutcome.IssueSeverity.FATAL).getDetails().setText(ex.getMessage());
RenderingContext rc = new RenderingContext(getContext(), null, null, "http://hl7.org/fhir", "", null, RenderingContext.ResourceRendererMode.RESOURCE);
RenderingContext rc = new RenderingContext(getContext(), null, null, "http://hl7.org/fhir", "", null, RenderingContext.ResourceRendererMode.END_USER);
RendererFactory.factory(op, rc).render(op);
return op;
}
protected void download(String address, String filename) throws IOException {
URL url = new URL(address);
URLConnection c = url.openConnection();
InputStream s = c.getInputStream();
FileOutputStream f = new FileOutputStream(filename);
transfer(s, f, 1024);
f.close();
SimpleHTTPClient http = new SimpleHTTPClient();
HTTPResult res = http.get(address);
res.checkThrowException();
TextFile.bytesToFile(res.getContent(), filename);
}
protected void transfer(InputStream in, OutputStream out, int buffer) throws IOException {

View File

@ -41,6 +41,8 @@ import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.structuremap.StructureMapUtilities;
import org.hl7.fhir.utilities.TimeTracker;
import org.hl7.fhir.utilities.*;
import org.hl7.fhir.utilities.SimpleHTTPClient.HTTPResult;
import org.hl7.fhir.utilities.npm.CommonPackages;
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
import org.hl7.fhir.utilities.npm.NpmPackage;
import org.hl7.fhir.utilities.npm.ToolsVersion;
@ -54,10 +56,8 @@ import org.hl7.fhir.validation.instance.utils.ValidatorHostContext;
import org.xml.sax.SAXException;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
/*
@ -238,7 +238,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst
if (tt != null) {
context.setClock(tt);
}
NpmPackage npmX = getPcm().loadPackage("hl7.fhir.xver-extensions", "0.0.4");
NpmPackage npmX = getPcm().loadPackage(CommonPackages.ID_XVER, CommonPackages.VER_XVER);
context.loadFromPackage(npmX, null);
this.fhirPathEngine = new FHIRPathEngine(context);
@ -435,7 +435,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst
public Resource generate(String source, String version) throws FHIRException, IOException, EOperationOutcome {
Content cnt = igLoader.loadContent(source, "validate", false);
Resource res = igLoader.loadResourceByVersion(version, cnt.focus, source);
RenderingContext rc = new RenderingContext(context, null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.RESOURCE);
RenderingContext rc = new RenderingContext(context, null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.END_USER);
genResource(res, rc);
return (Resource) res;
}
@ -554,19 +554,9 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst
if (output.startsWith("http://")) {
ByteArrayOutputStream bs = new ByteArrayOutputStream();
handleOutputToStream(r, output, bs, version);
URL url = new URL(output);
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setDoOutput(true);
c.setDoInput(true);
c.setRequestMethod("POST");
c.setRequestProperty("Content-type", "application/fhir+xml");
c.setRequestProperty("Accept", "application/fhir+xml");
c.getOutputStream().write(bs.toByteArray());
c.getOutputStream().close();
if (c.getResponseCode() >= 300) {
throw new IOException("Unable to PUT to " + output + ": " + c.getResponseMessage());
}
SimpleHTTPClient http = new SimpleHTTPClient();
HTTPResult res = http.post(output, "application/fhir+xml", bs.toByteArray(), "application/fhir+xml");
res.checkThrowException();
} else {
FileOutputStream s = new FileOutputStream(output);
handleOutputToStream(r, output, s, version);
@ -711,9 +701,10 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst
@Override
public byte[] fetchRaw(IResourceValidator validator, String source) throws IOException {
URL url = new URL(source);
URLConnection c = url.openConnection();
return TextFile.streamToBytes(c.getInputStream());
SimpleHTTPClient http = new SimpleHTTPClient();
HTTPResult res = http.get(source);
res.checkThrowException();
return res.getContent();
}
@Override

View File

@ -1,6 +1,6 @@
package org.hl7.fhir.validation;
import org.hl7.fhir.convertors.loaders.*;
import org.hl7.fhir.convertors.loaders.loaderR5.*;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.context.SimpleWorkerContext;
@ -42,15 +42,15 @@ public class ValidatorUtils {
if (Utilities.noString(version))
return null;
if (version.startsWith("1.0"))
return new R2ToR5Loader(new String[]{"Conformance", "StructureDefinition", "ValueSet", "SearchParameter", "OperationDefinition", "Questionnaire", "ConceptMap", "StructureMap", "NamingSystem"}, new BaseLoaderR5.NullLoaderKnowledgeProvider());
return new R2ToR5Loader(new String[]{"Conformance", "StructureDefinition", "ValueSet", "SearchParameter", "OperationDefinition", "Questionnaire", "ConceptMap", "StructureMap", "NamingSystem"}, new NullLoaderKnowledgeProviderR5());
if (version.startsWith("1.4"))
return new R2016MayToR5Loader(new String[]{"Conformance", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire", "ConceptMap", "StructureMap", "NamingSystem"}, new BaseLoaderR5.NullLoaderKnowledgeProvider()); // special case
return new R2016MayToR5Loader(new String[]{"Conformance", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire", "ConceptMap", "StructureMap", "NamingSystem"}, new NullLoaderKnowledgeProviderR5()); // special case
if (version.startsWith("3.0"))
return new R3ToR5Loader(new String[]{"CapabilityStatement", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire", "ConceptMap", "StructureMap", "NamingSystem"}, new BaseLoaderR5.NullLoaderKnowledgeProvider());
return new R3ToR5Loader(new String[]{"CapabilityStatement", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire", "ConceptMap", "StructureMap", "NamingSystem"}, new NullLoaderKnowledgeProviderR5());
if (version.startsWith("4.0"))
return new R4ToR5Loader(new String[]{"CapabilityStatement", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire", "ConceptMap", "StructureMap", "NamingSystem"}, new BaseLoaderR5.NullLoaderKnowledgeProvider());
return new R4ToR5Loader(new String[]{"CapabilityStatement", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire", "ConceptMap", "StructureMap", "NamingSystem"}, new NullLoaderKnowledgeProviderR5());
if (version.startsWith("5.0"))
return new R5ToR5Loader(new String[]{"CapabilityStatement", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire", "ConceptMap", "StructureMap", "NamingSystem"}, new BaseLoaderR5.NullLoaderKnowledgeProvider());
return new R5ToR5Loader(new String[]{"CapabilityStatement", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire", "ConceptMap", "StructureMap", "NamingSystem"}, new NullLoaderKnowledgeProviderR5());
return null;
}
@ -91,7 +91,7 @@ public class ValidatorUtils {
if (!op.hasIssue()) {
op.addIssue().setSeverity(OperationOutcome.IssueSeverity.INFORMATION).setCode(OperationOutcome.IssueType.INFORMATIONAL).getDetails().setText(context.formatMessage(I18nConstants.ALL_OK));
}
RenderingContext rc = new RenderingContext(context, null, null, "http://hl7.org/fhir", "", null, RenderingContext.ResourceRendererMode.RESOURCE);
RenderingContext rc = new RenderingContext(context, null, null, "http://hl7.org/fhir", "", null, RenderingContext.ResourceRendererMode.END_USER);
RendererFactory.factory(op, rc).render(op);
return op;
}

View File

@ -14,15 +14,12 @@ import java.util.Map.Entry;
import java.util.stream.Stream;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.convertors.conv10_50.VersionConvertor_10_50;
import org.hl7.fhir.convertors.conv14_50.VersionConvertor_14_50;
import org.hl7.fhir.convertors.conv30_50.VersionConvertor_30_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_14_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.convertors.loaders.BaseLoaderR5.NullLoaderKnowledgeProvider;
import org.hl7.fhir.convertors.loaders.R4ToR5Loader;
import org.hl7.fhir.convertors.loaders.loaderR5.NullLoaderKnowledgeProviderR5;
import org.hl7.fhir.convertors.loaders.loaderR5.R4ToR5Loader;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
@ -117,7 +114,7 @@ public class ComparisonTests {
BaseWorkerContext bc = (BaseWorkerContext) context;
boolean dupl = bc.isAllowLoadingDuplicates();
bc.setAllowLoadingDuplicates(true);
context.loadFromPackage(npm, new R4ToR5Loader(new String[] { "CapabilityStatement", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire","ConceptMap","StructureMap", "NamingSystem"}, new NullLoaderKnowledgeProvider()));
context.loadFromPackage(npm, new R4ToR5Loader(new String[] { "CapabilityStatement", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire","ConceptMap","StructureMap", "NamingSystem"}, new NullLoaderKnowledgeProviderR5()));
bc.setAllowLoadingDuplicates(dupl);
}

View File

@ -17,7 +17,7 @@ import java.util.zip.ZipInputStream;
import javax.xml.parsers.ParserConfigurationException;
import org.hl7.fhir.convertors.loaders.R3ToR4Loader;
import org.hl7.fhir.convertors.loaders.loaderR4.R3ToR4Loader;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;

View File

@ -524,7 +524,7 @@ public class SnapShotGenerationXTests {
throw e;
}
if (output.getDifferential().hasElement()) {
RenderingContext rc = new RenderingContext(TestingUtilities.context(), null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.RESOURCE);
RenderingContext rc = new RenderingContext(TestingUtilities.context(), null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.END_USER);
rc.setDestDir(makeTempDir());
rc.setProfileUtilities(new ProfileUtilities(TestingUtilities.context(), null, new TestPKP()));
RendererFactory.factory(output, rc).render(output);

View File

@ -46,11 +46,11 @@ import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.fhir.ucum.UcumEssenceService;
import org.hl7.fhir.convertors.loaders.BaseLoaderR5.NullLoaderKnowledgeProvider;
import org.hl7.fhir.convertors.loaders.R2016MayToR5Loader;
import org.hl7.fhir.convertors.loaders.R2ToR5Loader;
import org.hl7.fhir.convertors.loaders.R3ToR5Loader;
import org.hl7.fhir.convertors.loaders.R4ToR5Loader;
import org.hl7.fhir.convertors.loaders.loaderR5.NullLoaderKnowledgeProviderR5;
import org.hl7.fhir.convertors.loaders.loaderR5.R2016MayToR5Loader;
import org.hl7.fhir.convertors.loaders.loaderR5.R2ToR5Loader;
import org.hl7.fhir.convertors.loaders.loaderR5.R3ToR5Loader;
import org.hl7.fhir.convertors.loaders.loaderR5.R4ToR5Loader;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.context.IWorkerContext.IContextResourceLoader;
import org.hl7.fhir.r5.context.SimpleWorkerContext;
@ -101,13 +101,13 @@ public class UtilitiesXTests {
if (Utilities.noString(version))
return null;
if (version.startsWith("1.0"))
return new R2ToR5Loader(new String[] { "Conformance", "StructureDefinition", "ValueSet", "SearchParameter", "OperationDefinition", "Questionnaire","ConceptMap","StructureMap", "NamingSystem"}, new NullLoaderKnowledgeProvider());
return new R2ToR5Loader(new String[] { "Conformance", "StructureDefinition", "ValueSet", "SearchParameter", "OperationDefinition", "Questionnaire","ConceptMap","StructureMap", "NamingSystem"}, new NullLoaderKnowledgeProviderR5());
if (version.startsWith("1.4"))
return new R2016MayToR5Loader(new String[] { "Conformance", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire","ConceptMap","StructureMap", "NamingSystem"}, new NullLoaderKnowledgeProvider()); // special case
return new R2016MayToR5Loader(new String[] { "Conformance", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire","ConceptMap","StructureMap", "NamingSystem"}, new NullLoaderKnowledgeProviderR5()); // special case
if (version.startsWith("3.0"))
return new R3ToR5Loader(new String[] { "CapabilityStatement", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire","ConceptMap","StructureMap", "NamingSystem"}, new NullLoaderKnowledgeProvider());
return new R3ToR5Loader(new String[] { "CapabilityStatement", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire","ConceptMap","StructureMap", "NamingSystem"}, new NullLoaderKnowledgeProviderR5());
if (version.startsWith("4.0"))
return new R4ToR5Loader(new String[] { "CapabilityStatement", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire","ConceptMap","StructureMap", "NamingSystem"}, new NullLoaderKnowledgeProvider());
return new R4ToR5Loader(new String[] { "CapabilityStatement", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire","ConceptMap","StructureMap", "NamingSystem"}, new NullLoaderKnowledgeProviderR5());
return null;
}