mirror of
https://github.com/hapifhir/org.hl7.fhir.core.git
synced 2025-02-09 06:14:45 +00:00
add Resource Dependency walker + Resource Minifier functionality
This commit is contained in:
parent
f238d1af14
commit
d4d5b42aa1
@ -0,0 +1,39 @@
|
||||
package org.hl7.fhir.convertors.misc;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.hl7.fhir.r5.formats.JsonParser;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.utils.ResourceMinifier;
|
||||
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage.PackageResourceInformation;
|
||||
|
||||
public class PackageMinifier {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
new PackageMinifier().process(args[0], args[1]);
|
||||
}
|
||||
|
||||
private void process(String source, String target) throws FileNotFoundException, IOException {
|
||||
FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager(true);
|
||||
NpmPackage src = pcm.loadPackage(source);
|
||||
NpmPackage tgt = NpmPackage.empty();
|
||||
tgt.setNpm(src.getNpm().deepCopy());
|
||||
tgt.getNpm().set("name", tgt.getNpm().asString("name")+".min");
|
||||
|
||||
ResourceMinifier min = new ResourceMinifier();
|
||||
for (PackageResourceInformation pri : src.listIndexedResources()) {
|
||||
if (min.isMinified(pri.getResourceType())) {
|
||||
Resource res = new JsonParser().parse(src.load(pri));
|
||||
min.minify(res);
|
||||
tgt.addFile("package", res.fhirType()+"-"+res.getIdPart()+".json", new JsonParser().composeBytes(res), null);
|
||||
}
|
||||
}
|
||||
tgt.save(new FileOutputStream(target));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,140 @@
|
||||
package org.hl7.fhir.convertors.misc;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.convertors.conv40_50.VersionConvertor_40_50;
|
||||
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_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.loaderR5.NullLoaderKnowledgeProviderR5;
|
||||
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.convertors.loaders.loaderR5.R5ToR5Loader;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.IContextResourceLoader;
|
||||
import org.hl7.fhir.r5.context.SimpleWorkerContext;
|
||||
import org.hl7.fhir.r5.context.SimpleWorkerContext.SimpleWorkerContextBuilder;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.test.utils.TestPackageLoader;
|
||||
import org.hl7.fhir.r5.utils.ResourceDependencyWalker;
|
||||
import org.hl7.fhir.r5.utils.ResourceDependencyWalker.IResourceDependencyNotifier;
|
||||
import org.hl7.fhir.r5.utils.ResourceMinifier;
|
||||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.utilities.json.JsonException;
|
||||
import org.hl7.fhir.utilities.json.parser.JsonParser;
|
||||
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
|
||||
public class ResourceDependencyPackageBuilder {
|
||||
|
||||
private static final List<String> LOADED_TYPES =
|
||||
Arrays.asList("StructureDefinition", "CodeSystem", "ValueSet", "CapabilityStatement", "ConceptMap", "NamingSystem", "OperationDefinition", "SearchParameter", "Questionnaire");
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager(true);
|
||||
System.out.println("Load Core");
|
||||
NpmPackage src = pcm.loadPackage(VersionUtilities.packageForVersion(args[0]));
|
||||
SimpleWorkerContext ctxt = new SimpleWorkerContextBuilder().withAllowLoadingDuplicates(true).fromPackage(src);
|
||||
loadFromPackage(args[0], ctxt, pcm, args[1]);
|
||||
|
||||
NpmResourceDependencyCollector pckBuilder = new NpmResourceDependencyCollector();
|
||||
pckBuilder.npm = makeNpm(args[3], ctxt.getVersion());
|
||||
pckBuilder.minify = "true".equals(args[5]);
|
||||
|
||||
new ResourceDependencyWalker(ctxt, pckBuilder).walk(ctxt.fetchResource(CapabilityStatement.class, args[2]));
|
||||
|
||||
pckBuilder.npm.save(new FileOutputStream(args[4]));
|
||||
}
|
||||
|
||||
private static NpmPackage makeNpm(String vid, String version) throws JsonException, IOException {
|
||||
NpmPackage res = NpmPackage.empty();
|
||||
String name = vid.substring(0, vid.indexOf('#'));
|
||||
String ver = vid.substring(vid.indexOf("#")+1);
|
||||
res.setNpm(JsonParser.parseObject("{\"name\": \""+name+"\", \"version\": \""+ver+"\",\"fhirVersions\": [\""+version+"\"],\"type\": \"fhir.ig\",\"tools-version\": 3}"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
public static class NpmResourceDependencyCollector implements IResourceDependencyNotifier {
|
||||
|
||||
private NpmPackage npm;
|
||||
private boolean minify;
|
||||
|
||||
private byte[] toBytes(Resource resource) throws IOException {
|
||||
if (VersionUtilities.isR5Ver(npm.fhirVersion())) {
|
||||
return new org.hl7.fhir.r5.formats.JsonParser().composeBytes(resource);
|
||||
}
|
||||
if (VersionUtilities.isR4Plus(npm.fhirVersion())) {
|
||||
org.hl7.fhir.r4.model.Resource r4 = VersionConvertorFactory_40_50.convertResource(resource);
|
||||
return new org.hl7.fhir.r4.formats.JsonParser().composeBytes(r4);
|
||||
}
|
||||
if (VersionUtilities.isR3Ver(npm.fhirVersion())) {
|
||||
org.hl7.fhir.dstu3.model.Resource r3 = VersionConvertorFactory_30_50.convertResource(resource);
|
||||
return new org.hl7.fhir.dstu3.formats.JsonParser().composeBytes(r3);
|
||||
}
|
||||
if (VersionUtilities.isR2Ver(npm.fhirVersion())) {
|
||||
org.hl7.fhir.dstu2.model.Resource r2 = VersionConvertorFactory_10_50.convertResource(resource);
|
||||
return new org.hl7.fhir.dstu2.formats.JsonParser().composeBytes(r2);
|
||||
}
|
||||
throw new Error("Unsupported version");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seeResource(Resource resource, String summaryId) {
|
||||
if (minify) {
|
||||
ResourceMinifier min = new ResourceMinifier();
|
||||
if (min.isMinified(resource.fhirType())) {
|
||||
resource = resource.copy();
|
||||
min.minify(resource);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
try {
|
||||
npm.addFile("package", resource.fhirType()+"-"+resource.getIdPart()+".json", toBytes(resource), null);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void brokenLink(String link) {
|
||||
System.err.println("Broken Link: " +link);
|
||||
}
|
||||
}
|
||||
|
||||
private static void loadFromPackage(String version, SimpleWorkerContext ctxt, FilesystemPackageCacheManager pcm, String pid) throws FHIRException, IOException {
|
||||
NpmPackage npm = pcm.loadPackage(pid);
|
||||
for (String dep : npm.dependencies()) {
|
||||
if (!VersionUtilities.isCorePackage(dep)) {
|
||||
loadFromPackage(version, ctxt, pcm, dep);
|
||||
}
|
||||
}
|
||||
System.out.println("Load "+pid);
|
||||
ctxt.loadFromPackage(npm, getLoader(version));
|
||||
}
|
||||
|
||||
private static IContextResourceLoader getLoader(String version) {
|
||||
if (VersionUtilities.isR2Ver(version)) {
|
||||
return new R2ToR5Loader(LOADED_TYPES, new NullLoaderKnowledgeProviderR5());
|
||||
}
|
||||
if (VersionUtilities.isR3Ver(version)) {
|
||||
return new R3ToR5Loader(LOADED_TYPES, new NullLoaderKnowledgeProviderR5());
|
||||
}
|
||||
if (VersionUtilities.isR4Ver(version)) {
|
||||
return new R4ToR5Loader(LOADED_TYPES, new NullLoaderKnowledgeProviderR5(), version);
|
||||
}
|
||||
if (VersionUtilities.isR5Ver(version)) {
|
||||
return new R5ToR5Loader(LOADED_TYPES, new NullLoaderKnowledgeProviderR5());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,418 @@
|
||||
package org.hl7.fhir.r5.utils;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||
import org.hl7.fhir.r5.model.CanonicalType;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestComponent;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestResourceComponent;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestResourceOperationComponent;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.CodeSystem.PropertyComponent;
|
||||
import org.hl7.fhir.r5.model.ConceptMap;
|
||||
import org.hl7.fhir.r5.model.ConceptMap.AdditionalAttributeComponent;
|
||||
import org.hl7.fhir.r5.model.ConceptMap.ConceptMapGroupComponent;
|
||||
import org.hl7.fhir.r5.model.ConceptMap.SourceElementComponent;
|
||||
import org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent;
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingAdditionalComponent;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
||||
import org.hl7.fhir.r5.model.NamingSystem;
|
||||
import org.hl7.fhir.r5.model.OperationDefinition;
|
||||
import org.hl7.fhir.r5.model.OperationDefinition.OperationDefinitionParameterComponent;
|
||||
import org.hl7.fhir.r5.model.Questionnaire;
|
||||
import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemAnswerOptionComponent;
|
||||
import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemComponent;
|
||||
import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemEnableWhenComponent;
|
||||
import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemInitialComponent;
|
||||
import org.hl7.fhir.r5.model.Reference;
|
||||
import org.hl7.fhir.r5.model.RelatedArtifact;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.SearchParameter;
|
||||
import org.hl7.fhir.r5.model.SearchParameter.SearchParameterComponentComponent;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.UsageContext;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionPropertyComponent;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
public class ResourceDependencyWalker {
|
||||
|
||||
public interface IResourceDependencyNotifier {
|
||||
public void seeResource(Resource resource, String summaryId);
|
||||
public void brokenLink(String link);
|
||||
}
|
||||
|
||||
public class NullResourceDependencyNotifier implements IResourceDependencyNotifier {
|
||||
|
||||
@Override
|
||||
public void seeResource(Resource resource, String summaryId) {
|
||||
System.out.println(summaryId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void brokenLink(String link) {
|
||||
System.err.println("Broken Link: " +link);
|
||||
}
|
||||
}
|
||||
|
||||
private IResourceDependencyNotifier notifier = new NullResourceDependencyNotifier();
|
||||
private IWorkerContext context;
|
||||
private Set<String> processedLinks = new HashSet<>();
|
||||
private Set<Resource> processedResources = new HashSet<>();
|
||||
|
||||
public ResourceDependencyWalker(IWorkerContext context, IResourceDependencyNotifier notifier) {
|
||||
super();
|
||||
this.notifier = notifier;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public ResourceDependencyWalker(IWorkerContext context) {
|
||||
super();
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
private void notify(Resource resource, String prefix) {
|
||||
String summary = null;
|
||||
if (resource instanceof CanonicalResource) {
|
||||
summary = ((CanonicalResource) resource).getVersionedUrl();
|
||||
} else {
|
||||
summary = resource.fhirType()+"/"+resource.getIdPart();
|
||||
}
|
||||
if (resource.getSourcePackage() != null) {
|
||||
summary = summary + " from "+resource.getSourcePackage();
|
||||
}
|
||||
notifier.seeResource(resource, prefix+summary);
|
||||
}
|
||||
|
||||
public void walk(Resource res) {
|
||||
notify(res, "Find Dependencies for ");
|
||||
processedResources.add(res);
|
||||
doWalk(res);
|
||||
}
|
||||
|
||||
private void walkIntoLink(String value, CanonicalResource source) {
|
||||
if (value != null ) {
|
||||
String key = source.getSourcePackage() == null ? value : value+" from "+source.getSourcePackage().getVID();
|
||||
if (!processedLinks.contains(key)) {
|
||||
processedLinks.add(key);
|
||||
Resource tgt = context.fetchResource(Resource.class, value, source);
|
||||
if (tgt == null && Utilities.charCount(value, '/') == 1) {
|
||||
tgt = context.fetchResourceById(value.substring(0, value.indexOf('/')), value.substring(value.indexOf('/')+1));
|
||||
}
|
||||
if (tgt == null) {
|
||||
notifier.brokenLink(key);
|
||||
} else {
|
||||
if (!processedResources.contains(tgt) && !isCore(tgt)) {
|
||||
processedResources.add(tgt);
|
||||
notify(tgt, "Depends On ");
|
||||
doWalk(tgt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isCore(Resource tgt) {
|
||||
return tgt.hasSourcePackage() && "hl7.fhir.r5.core".equals(tgt.getSourcePackage().getId());
|
||||
}
|
||||
|
||||
private void doWalk(Resource res) {
|
||||
if (res instanceof StructureDefinition) {
|
||||
walkSD((StructureDefinition) res);
|
||||
} else if (res instanceof ValueSet) {
|
||||
walkVS((ValueSet) res);
|
||||
} else if (res instanceof CodeSystem) {
|
||||
walkCS((CodeSystem) res);
|
||||
} else if (res instanceof CapabilityStatement) {
|
||||
walkCS((CapabilityStatement) res);
|
||||
} else if (res instanceof ConceptMap) {
|
||||
walkCM((ConceptMap) res);
|
||||
} else if (res instanceof NamingSystem) {
|
||||
walkNS((NamingSystem) res);
|
||||
} else if (res instanceof OperationDefinition) {
|
||||
walkOD((OperationDefinition) res);
|
||||
} else if (res instanceof SearchParameter) {
|
||||
walkSP((SearchParameter) res);
|
||||
} else if (res instanceof Questionnaire) {
|
||||
walkQ((Questionnaire) res);
|
||||
} else {
|
||||
throw new Error("Resource "+res.fhirType()+" not Processed yet");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void walkSP(SearchParameter sp) {
|
||||
walkCR(sp);
|
||||
walkIntoLink(sp.getDerivedFrom(), sp);
|
||||
for (SearchParameterComponentComponent spc : sp.getComponent()) {
|
||||
walkIntoLink(spc.getDefinition(), sp);
|
||||
}
|
||||
}
|
||||
|
||||
private void walkQ(Questionnaire q) {
|
||||
walkCR(q);
|
||||
walkCT(q.getDerivedFrom(), q);
|
||||
for (QuestionnaireItemComponent item : q.getItem()) {
|
||||
walkQItem(item, q);
|
||||
}
|
||||
}
|
||||
|
||||
private void walkQItem(QuestionnaireItemComponent item, Questionnaire q) {
|
||||
walkIntoLink(item.getDefinition(), q);
|
||||
walkIntoLink(item.getAnswerValueSet(), q);
|
||||
for (QuestionnaireItemEnableWhenComponent ew : item.getEnableWhen()) {
|
||||
if (ew.hasAnswerReference()) {
|
||||
walkIntoLink(ew.getAnswerReference().getReference(), q);
|
||||
}
|
||||
}
|
||||
for (QuestionnaireItemAnswerOptionComponent ao : item.getAnswerOption()) {
|
||||
if (ao.hasValueReference()) {
|
||||
walkIntoLink(ao.getValueReference().getReference(), q);
|
||||
}
|
||||
}
|
||||
for (QuestionnaireItemInitialComponent iv : item.getInitial()) {
|
||||
if (iv.hasValueReference()) {
|
||||
walkIntoLink(iv.getValueReference().getReference(), q);
|
||||
}
|
||||
}
|
||||
walkIntoLink(item.getDefinition(), q);
|
||||
for (QuestionnaireItemComponent child : item.getItem()) {
|
||||
walkQItem(child, q);
|
||||
}
|
||||
}
|
||||
|
||||
private void walkOD(OperationDefinition od) {
|
||||
walkCR(od);
|
||||
walkIntoLink(od.getBase(), od);
|
||||
walkIntoLink(od.getInputProfile(), od);
|
||||
walkIntoLink(od.getOutputProfile(), od);
|
||||
|
||||
for (OperationDefinitionParameterComponent p : od.getParameter()) {
|
||||
walkODP(od, p);
|
||||
}
|
||||
}
|
||||
|
||||
private void walkODP(OperationDefinition od, OperationDefinitionParameterComponent p) {
|
||||
walkCT(p.getTargetProfile(), od);
|
||||
walkIntoLink(p.getBinding().getValueSet(), od);
|
||||
for (OperationDefinitionParameterComponent pp : p.getPart()) {
|
||||
walkODP(od, pp);
|
||||
}
|
||||
}
|
||||
|
||||
private void walkNS(NamingSystem ns) {
|
||||
walkCR(ns);
|
||||
}
|
||||
|
||||
private void walkCM(ConceptMap cm) {
|
||||
walkCR(cm);
|
||||
walkRA(cm.getRelatedArtifact(), cm);
|
||||
|
||||
for (org.hl7.fhir.r5.model.ConceptMap.PropertyComponent prop : cm.getProperty()) {
|
||||
walkIntoLink(prop.getUri(), cm);
|
||||
}
|
||||
for (AdditionalAttributeComponent attr : cm.getAdditionalAttribute()) {
|
||||
walkIntoLink(attr.getUri(), cm);
|
||||
}
|
||||
walkIntoLink(cm.getSourceScope().primitiveValue(), cm);
|
||||
walkIntoLink(cm.getTargetScope().primitiveValue(), cm);
|
||||
|
||||
for (ConceptMapGroupComponent group : cm.getGroup()) {
|
||||
walkIntoLink(group.getSource(), cm);
|
||||
walkIntoLink(group.getTarget(), cm);
|
||||
walkIntoLink(group.getUnmapped().getValueSet(), cm);
|
||||
walkIntoLink(group.getUnmapped().getOtherMap(), cm);
|
||||
for (SourceElementComponent elem : group.getElement()) {
|
||||
walkIntoLink(elem.getValueSet(), cm);
|
||||
for (TargetElementComponent tgt : elem.getTarget()) {
|
||||
walkIntoLink(tgt.getValueSet(), cm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void walkCS(CapabilityStatement cs) {
|
||||
walkCR(cs);
|
||||
walkCT(cs.getInstantiates(), cs);
|
||||
walkCT(cs.getImports(), cs);
|
||||
walkCT(cs.getImplementationGuide(), cs);
|
||||
|
||||
for (CapabilityStatementRestComponent rest : cs.getRest()) {
|
||||
|
||||
for (CapabilityStatementRestResourceComponent res : rest.getResource()) {
|
||||
walkIntoLink(res.getProfile(), cs);
|
||||
walkCT(res.getSupportedProfile(), cs);
|
||||
for (CapabilityStatementRestResourceSearchParamComponent srch : res.getSearchParam()) {
|
||||
walkIntoLink(srch.getDefinition(), cs);
|
||||
}
|
||||
for (CapabilityStatementRestResourceOperationComponent op : res.getOperation()) {
|
||||
walkIntoLink(op.getDefinition(), cs);
|
||||
}
|
||||
}
|
||||
for (CapabilityStatementRestResourceSearchParamComponent srch : rest.getSearchParam()) {
|
||||
walkIntoLink(srch.getDefinition(), cs);
|
||||
}
|
||||
for (CapabilityStatementRestResourceOperationComponent op : rest.getOperation()) {
|
||||
walkIntoLink(op.getDefinition(), cs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void walkCS(CodeSystem cs) {
|
||||
walkCR(cs);
|
||||
walkRA(cs.getRelatedArtifact(), cs);
|
||||
if (cs.hasValueSet()) {
|
||||
walkIntoLink(cs.getValueSet(), cs);
|
||||
}
|
||||
if (cs.hasSupplements()) {
|
||||
walkIntoLink(cs.getSupplements(), cs);
|
||||
}
|
||||
|
||||
for (PropertyComponent p : cs.getProperty()) {
|
||||
if (p.hasUri()) {
|
||||
walkIntoLink(p.getUri(), cs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void walkVS(ValueSet vs) {
|
||||
walkCR(vs);
|
||||
walkRA(vs.getRelatedArtifact(), vs);
|
||||
for (ConceptSetComponent inc : vs.getCompose().getInclude()) {
|
||||
walkVSInc(inc, vs);
|
||||
}
|
||||
for (ConceptSetComponent inc : vs.getCompose().getExclude()) {
|
||||
walkVSInc(inc, vs);
|
||||
}
|
||||
if (vs.hasExpansion()) {
|
||||
ValueSetExpansionComponent exp = vs.getExpansion();
|
||||
for (ValueSetExpansionParameterComponent p : exp.getParameter()) {
|
||||
if (p.hasValueUriType()) {
|
||||
walkIntoLink(p.getValueUriType().primitiveValue(), vs);
|
||||
}
|
||||
}
|
||||
for (ValueSetExpansionPropertyComponent p : exp.getProperty()) {
|
||||
if (p.hasUri()) {
|
||||
walkIntoLink(p.getUri(), vs);
|
||||
}
|
||||
}
|
||||
for (ValueSetExpansionContainsComponent cc : exp.getContains()) {
|
||||
walkCC(cc, vs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void walkCC(ValueSetExpansionContainsComponent cc, ValueSet vs) {
|
||||
walkIntoLink(cc.getSystem(), vs);
|
||||
for (ValueSetExpansionContainsComponent ccc : cc.getContains()) {
|
||||
walkCC(ccc, vs);
|
||||
}
|
||||
}
|
||||
|
||||
private void walkVSInc(ConceptSetComponent inc, ValueSet vs) {
|
||||
walkCT(inc.getValueSet(), vs);
|
||||
walkIntoLink(inc.getSystem(), vs);
|
||||
}
|
||||
|
||||
private void walkCT(List<CanonicalType> list, CanonicalResource source) {
|
||||
for (CanonicalType ct : list) {
|
||||
walkIntoLink(ct.getValue(), source);
|
||||
}
|
||||
}
|
||||
|
||||
private void walkRA(List<RelatedArtifact> list, CanonicalResource source) {
|
||||
for (RelatedArtifact ra : list) {
|
||||
walkRA(ra, source);
|
||||
}
|
||||
}
|
||||
|
||||
private void walkRA(RelatedArtifact ra, CanonicalResource source) {
|
||||
if (ra.hasResource()) {
|
||||
walkIntoLink(ra.getResource(), source);
|
||||
}
|
||||
if (ra.hasResourceReference()) {
|
||||
walkIntoLink(ra.getResourceReference().getReference(), source);
|
||||
}
|
||||
}
|
||||
|
||||
private void walkSD(StructureDefinition sd) {
|
||||
walkCR(sd);
|
||||
walkIntoLink(sd.getBaseDefinition(), sd);
|
||||
for (ElementDefinition ed : sd.getDifferential().getElement()) {
|
||||
walkED(ed, sd);
|
||||
}
|
||||
}
|
||||
|
||||
private void walkED(ElementDefinition ed, StructureDefinition sd) {
|
||||
for (TypeRefComponent type : ed.getType()) {
|
||||
if (Utilities.isAbsoluteUrl(type.getCode())) {
|
||||
walkIntoLink(type.getCode(), sd);
|
||||
}
|
||||
walkCT(type.getProfile(), sd);
|
||||
walkCT(type.getTargetProfile(), sd);
|
||||
}
|
||||
walkCT(ed.getValueAlternatives(), sd);
|
||||
if (ed.hasBinding()) {
|
||||
ElementDefinitionBindingComponent b = ed.getBinding();
|
||||
if (b.hasValueSet()) {
|
||||
walkIntoLink(b.getValueSet(), sd);
|
||||
}
|
||||
for (ElementDefinitionBindingAdditionalComponent ab : b.getAdditional()) {
|
||||
if (ab.hasValueSet()) {
|
||||
walkIntoLink(ab.getValueSet(), sd);
|
||||
}
|
||||
if (ab.hasUsage()) {
|
||||
walkUsage(ab.getUsage(), sd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void walkUsage(List<UsageContext> usageList, CanonicalResource source) {
|
||||
for (UsageContext usage : usageList) {
|
||||
walkUsage(usage, source);
|
||||
}
|
||||
}
|
||||
|
||||
private void walkUsage(UsageContext usage, CanonicalResource source) {
|
||||
if (usage.hasValueReference()) {
|
||||
walkReference(usage.getValueReference(), source);
|
||||
}
|
||||
}
|
||||
|
||||
private void walkReference(Reference ref, CanonicalResource source) {
|
||||
if (ref.hasReference()) {
|
||||
walkIntoLink(ref.getReference(), source);
|
||||
}
|
||||
}
|
||||
|
||||
private void walkCR(CanonicalResource cr) {
|
||||
walkDR(cr);
|
||||
walkUsage(cr.getUseContext(), cr);
|
||||
}
|
||||
|
||||
private void walkDR(DomainResource dr) {
|
||||
walkRes(dr);
|
||||
for (Resource res : dr.getContained()) {
|
||||
walk(res);
|
||||
}
|
||||
}
|
||||
|
||||
private void walkRes(Resource res) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,308 @@
|
||||
package org.hl7.fhir.r5.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestComponent;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestResourceComponent;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestResourceOperationComponent;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement.ResourceInteractionComponent;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement.SystemInteractionComponent;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.CodeSystem.CodeSystemFilterComponent;
|
||||
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
|
||||
import org.hl7.fhir.r5.model.CodeSystem.PropertyComponent;
|
||||
import org.hl7.fhir.r5.model.ConceptMap;
|
||||
import org.hl7.fhir.r5.model.ConceptMap.AdditionalAttributeComponent;
|
||||
import org.hl7.fhir.r5.model.ConceptMap.ConceptMapGroupComponent;
|
||||
import org.hl7.fhir.r5.model.ConceptMap.SourceElementComponent;
|
||||
import org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent;
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingAdditionalComponent;
|
||||
import org.hl7.fhir.r5.model.NamingSystem;
|
||||
import org.hl7.fhir.r5.model.NamingSystem.NamingSystemUniqueIdComponent;
|
||||
import org.hl7.fhir.r5.model.OperationDefinition;
|
||||
import org.hl7.fhir.r5.model.OperationDefinition.OperationDefinitionOverloadComponent;
|
||||
import org.hl7.fhir.r5.model.OperationDefinition.OperationDefinitionParameterComponent;
|
||||
import org.hl7.fhir.r5.model.Questionnaire;
|
||||
import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemComponent;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
public class ResourceMinifier {
|
||||
|
||||
private static final List<String> VALIDATION_EXTENSIONS =
|
||||
Arrays.asList(ToolingExtensions.EXT_OBLIGATION_INHERITS, ToolingExtensions.EXT_OBLIGATION_PROFILE_FLAG);
|
||||
|
||||
public boolean isMinified(String resName) {
|
||||
return Utilities.existsInList(resName, "StructureDefinition", "CodeSystem", "ValueSet", "CapabilityStatement",
|
||||
"ConceptMap", "NamingSystem", "OperationDefinition", "SearchParameter", "Questionnaire");
|
||||
}
|
||||
|
||||
public void minify(Resource res) {
|
||||
if (res instanceof StructureDefinition) {
|
||||
minifySD((StructureDefinition) res);
|
||||
}
|
||||
if (res instanceof ValueSet) {
|
||||
minifyVS((ValueSet) res);
|
||||
}
|
||||
if (res instanceof CodeSystem) {
|
||||
minifyCS((CodeSystem) res);
|
||||
}
|
||||
if (res instanceof CapabilityStatement) {
|
||||
minifyCS((CapabilityStatement) res);
|
||||
}
|
||||
if (res instanceof ConceptMap) {
|
||||
minifyCM((ConceptMap) res);
|
||||
}
|
||||
if (res instanceof NamingSystem) {
|
||||
minifyNS((NamingSystem) res);
|
||||
}
|
||||
|
||||
if (res instanceof OperationDefinition) {
|
||||
minifyOD((OperationDefinition) res);
|
||||
}
|
||||
|
||||
if (res instanceof Questionnaire) {
|
||||
minifyQ((Questionnaire) res);
|
||||
}
|
||||
}
|
||||
|
||||
private void minifyQ(Questionnaire q) {
|
||||
minCR(q);
|
||||
|
||||
q.setApprovalDate(null);
|
||||
q.setLastReviewDate(null);
|
||||
q.setEffectivePeriod(null);
|
||||
q.setCode(null);
|
||||
for (QuestionnaireItemComponent item : q.getItem()) {
|
||||
minifyQItem(item);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void minifyQItem(QuestionnaireItemComponent item) {
|
||||
item.setCode(null);
|
||||
item.setPrefix(null);
|
||||
item.setText(null);
|
||||
for (QuestionnaireItemComponent child : item.getItem()) {
|
||||
minifyQItem(child);
|
||||
}
|
||||
}
|
||||
|
||||
private void minifyOD(OperationDefinition od) {
|
||||
minCR(od);
|
||||
od.setComment(null);
|
||||
for (OperationDefinitionParameterComponent p : od.getParameter()) {
|
||||
minifyODP(p);
|
||||
}
|
||||
for (OperationDefinitionOverloadComponent ol : od.getOverload()) {
|
||||
ol.setComment(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void minifyODP(OperationDefinitionParameterComponent p) {
|
||||
p.setDocumentation(null);
|
||||
for (OperationDefinitionParameterComponent pp : p.getPart()) {
|
||||
minifyODP(pp);
|
||||
}
|
||||
}
|
||||
|
||||
private void minifyNS(NamingSystem ns) {
|
||||
minCR(ns);
|
||||
|
||||
ns.setApprovalDate(null);
|
||||
ns.setLastReviewDate(null);
|
||||
ns.setEffectivePeriod(null);
|
||||
ns.setTopic(null);
|
||||
ns.setAuthor(null);
|
||||
ns.setEditor(null);
|
||||
ns.setReviewer(null);
|
||||
ns.setEndorser(null);
|
||||
ns.setRelatedArtifact(null);
|
||||
|
||||
ns.setUsage(null);
|
||||
for (NamingSystemUniqueIdComponent id : ns.getUniqueId()) {
|
||||
id.setComment(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void minifyCM(ConceptMap cm) {
|
||||
minCR(cm);
|
||||
|
||||
cm.setApprovalDate(null);
|
||||
cm.setLastReviewDate(null);
|
||||
cm.setEffectivePeriod(null);
|
||||
cm.setTopic(null);
|
||||
cm.setAuthor(null);
|
||||
cm.setEditor(null);
|
||||
cm.setReviewer(null);
|
||||
cm.setEndorser(null);
|
||||
cm.setRelatedArtifact(null);
|
||||
|
||||
for (org.hl7.fhir.r5.model.ConceptMap.PropertyComponent prop : cm.getProperty()) {
|
||||
prop.setDescription(null);
|
||||
}
|
||||
for (AdditionalAttributeComponent attr : cm.getAdditionalAttribute()) {
|
||||
attr.setDescription(null);
|
||||
}
|
||||
for (ConceptMapGroupComponent group : cm.getGroup()) {
|
||||
for (SourceElementComponent elem : group.getElement()) {
|
||||
for (TargetElementComponent tgt : elem.getTarget()) {
|
||||
tgt.setComment(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void minifyCS(CapabilityStatement cs) {
|
||||
minCR(cs);
|
||||
|
||||
cs.setSoftware(null);
|
||||
cs.setImplementation(null);
|
||||
for (CapabilityStatementRestComponent rest : cs.getRest()) {
|
||||
rest.setDocumentation(null);
|
||||
rest.setSecurity(null);
|
||||
for (CapabilityStatementRestResourceComponent res : rest.getResource()) {
|
||||
res.setDocumentation(null);
|
||||
for (ResourceInteractionComponent intr : res.getInteraction()) {
|
||||
intr.setDocumentation(null);
|
||||
}
|
||||
for (CapabilityStatementRestResourceSearchParamComponent srch : res.getSearchParam()) {
|
||||
srch.setDocumentation(null);
|
||||
}
|
||||
for (CapabilityStatementRestResourceOperationComponent op : res.getOperation()) {
|
||||
op.setDocumentation(null);
|
||||
}
|
||||
}
|
||||
for (SystemInteractionComponent intr : rest.getInteraction()) {
|
||||
intr.setDocumentation(null);
|
||||
}
|
||||
for (CapabilityStatementRestResourceSearchParamComponent srch : rest.getSearchParam()) {
|
||||
srch.setDocumentation(null);
|
||||
}
|
||||
for (CapabilityStatementRestResourceOperationComponent op : rest.getOperation()) {
|
||||
op.setDocumentation(null);
|
||||
}
|
||||
}
|
||||
cs.setMessaging(null);
|
||||
cs.setDocument(null);
|
||||
}
|
||||
|
||||
private void minifyCS(CodeSystem cs) {
|
||||
minCR(cs);
|
||||
|
||||
cs.setApprovalDate(null);
|
||||
cs.setLastReviewDate(null);
|
||||
cs.setEffectivePeriod(null);
|
||||
cs.setTopic(null);
|
||||
cs.setAuthor(null);
|
||||
cs.setEditor(null);
|
||||
cs.setReviewer(null);
|
||||
cs.setEndorser(null);
|
||||
cs.setRelatedArtifact(null);
|
||||
|
||||
for (CodeSystemFilterComponent filter : cs.getFilter()) {
|
||||
filter.setDescription(null);
|
||||
}
|
||||
for (PropertyComponent prop : cs.getProperty()) {
|
||||
prop.setDescription(null);
|
||||
}
|
||||
for (ConceptDefinitionComponent cc : cs.getConcept()) {
|
||||
minify(cc);
|
||||
}
|
||||
}
|
||||
|
||||
private void minify(ConceptDefinitionComponent cc) {
|
||||
cc.setDefinition(null);
|
||||
for (ConceptDefinitionComponent ccc : cc.getConcept()) {
|
||||
minify(ccc);
|
||||
}
|
||||
}
|
||||
|
||||
private void minifyVS(ValueSet vs) {
|
||||
minCR(vs);
|
||||
|
||||
vs.setApprovalDate(null);
|
||||
vs.setLastReviewDate(null);
|
||||
vs.setEffectivePeriod(null);
|
||||
vs.setTopic(null);
|
||||
vs.setAuthor(null);
|
||||
vs.setEditor(null);
|
||||
vs.setReviewer(null);
|
||||
vs.setEndorser(null);
|
||||
vs.setRelatedArtifact(null);
|
||||
// can't remove anything else
|
||||
}
|
||||
|
||||
private void minifySD(StructureDefinition sd) {
|
||||
minCR(sd);
|
||||
sd.setKeyword(null);
|
||||
sd.setMapping(null);
|
||||
sd.setSnapshot(null);
|
||||
for (ElementDefinition ed : sd.getDifferential().getElement()) {
|
||||
minifyED(ed);
|
||||
}
|
||||
}
|
||||
|
||||
private void minifyED(ElementDefinition ed) {
|
||||
ed.setLabel(null);
|
||||
ed.setCode(null);
|
||||
ed.getSlicing().setDescription(null);
|
||||
ed.setShort(null);
|
||||
ed.setDefinition(null);
|
||||
ed.setComment(null);
|
||||
ed.setRequirements(null);
|
||||
ed.setAlias(null);
|
||||
ed.setDefaultValue(null);
|
||||
ed.setOrderMeaning(null);
|
||||
ed.setMeaningWhenMissing(null);
|
||||
ed.setExample(null);
|
||||
ed.setIsModifierReason(null);
|
||||
ed.getBinding().setDescription(null);
|
||||
for (ElementDefinitionBindingAdditionalComponent abn : ed.getBinding().getAdditional()) {
|
||||
abn.setDocumentation(null);
|
||||
abn.setShortDoco(null);
|
||||
}
|
||||
ed.setMapping(null);
|
||||
}
|
||||
|
||||
private void minCR(CanonicalResource cr) {
|
||||
minDR(cr);
|
||||
cr.setIdentifier(null);
|
||||
cr.setPublisher(null);
|
||||
cr.setContact(null);
|
||||
cr.setDescription(null);
|
||||
cr.setPurpose(null);
|
||||
cr.setCopyright(null);
|
||||
cr.setCopyrightLabel(null);
|
||||
}
|
||||
|
||||
private void minDR(DomainResource dr) {
|
||||
minRes(dr);
|
||||
dr.setText(null);
|
||||
List<Resource> del = new ArrayList<>();
|
||||
for (Resource res : dr.getContained()) {
|
||||
if (isMinified(res.fhirType())) {
|
||||
minify(res);
|
||||
} else {
|
||||
del.add(res);
|
||||
}
|
||||
}
|
||||
dr.getContained().removeAll(del);
|
||||
dr.getExtension().removeIf(ext -> !Utilities.existsInList(ext.getUrl(), VALIDATION_EXTENSIONS));
|
||||
}
|
||||
|
||||
private void minRes(Resource res) {
|
||||
res.setMeta(null);
|
||||
res.setImplicitRules(null);
|
||||
}
|
||||
|
||||
}
|
@ -719,6 +719,15 @@ public class NpmPackage {
|
||||
return npm;
|
||||
}
|
||||
|
||||
/**
|
||||
* should only use this when npm == null
|
||||
*
|
||||
* @param npm
|
||||
*/
|
||||
public void setNpm(JsonObject npm) {
|
||||
this.npm = npm;
|
||||
}
|
||||
|
||||
/**
|
||||
* convenience method for getting the package name
|
||||
* @return
|
||||
|
Loading…
x
Reference in New Issue
Block a user