001package org.hl7.fhir.convertors.misc; 002 003import java.io.FileOutputStream; 004import java.io.IOException; 005import java.util.Arrays; 006import java.util.List; 007 008import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_50; 009import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_50; 010import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50; 011import org.hl7.fhir.convertors.loaders.loaderR5.NullLoaderKnowledgeProviderR5; 012import org.hl7.fhir.convertors.loaders.loaderR5.R2ToR5Loader; 013import org.hl7.fhir.convertors.loaders.loaderR5.R3ToR5Loader; 014import org.hl7.fhir.convertors.loaders.loaderR5.R4ToR5Loader; 015import org.hl7.fhir.convertors.loaders.loaderR5.R5ToR5Loader; 016import org.hl7.fhir.exceptions.FHIRException; 017import org.hl7.fhir.r5.context.IWorkerContext.IContextResourceLoader; 018import org.hl7.fhir.r5.context.SimpleWorkerContext; 019import org.hl7.fhir.r5.context.SimpleWorkerContext.SimpleWorkerContextBuilder; 020import org.hl7.fhir.r5.model.CapabilityStatement; 021import org.hl7.fhir.r5.model.Resource; 022import org.hl7.fhir.r5.utils.ResourceDependencyWalker; 023import org.hl7.fhir.r5.utils.ResourceDependencyWalker.IResourceDependencyNotifier; 024import org.hl7.fhir.r5.utils.ResourceMinifier; 025import org.hl7.fhir.utilities.VersionUtilities; 026import org.hl7.fhir.utilities.json.JsonException; 027import org.hl7.fhir.utilities.json.parser.JsonParser; 028import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager; 029import org.hl7.fhir.utilities.npm.NpmPackage; 030 031public class ResourceDependencyPackageBuilder { 032 033 private static final List<String> LOADED_TYPES = 034 Arrays.asList("StructureDefinition", "CodeSystem", "ValueSet", "CapabilityStatement", "ConceptMap", "NamingSystem", "OperationDefinition", "SearchParameter", "Questionnaire"); 035 036 public static void main(String[] args) throws IOException { 037 038 FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager(true); 039 System.out.println("Load Core"); 040 NpmPackage src = pcm.loadPackage(VersionUtilities.packageForVersion(args[0])); 041 SimpleWorkerContext ctxt = new SimpleWorkerContextBuilder().withAllowLoadingDuplicates(true).fromPackage(src); 042 loadFromPackage(args[0], ctxt, pcm, args[1]); 043 044 NpmResourceDependencyCollector pckBuilder = new NpmResourceDependencyCollector(); 045 pckBuilder.npm = makeNpm(args[3], ctxt.getVersion()); 046 pckBuilder.minify = "true".equals(args[5]); 047 048 new ResourceDependencyWalker(ctxt, pckBuilder).walk(ctxt.fetchResource(CapabilityStatement.class, args[2])); 049 050 pckBuilder.npm.save(new FileOutputStream(args[4])); 051 } 052 053 private static NpmPackage makeNpm(String vid, String version) throws JsonException, IOException { 054 NpmPackage res = NpmPackage.empty(); 055 String name = vid.substring(0, vid.indexOf('#')); 056 String ver = vid.substring(vid.indexOf("#")+1); 057 res.setNpm(JsonParser.parseObject("{\"name\": \""+name+"\", \"version\": \""+ver+"\",\"fhirVersions\": [\""+version+"\"],\"type\": \"fhir.ig\",\"tools-version\": 3}")); 058 return res; 059 } 060 061 062 public static class NpmResourceDependencyCollector implements IResourceDependencyNotifier { 063 064 private NpmPackage npm; 065 private boolean minify; 066 067 private byte[] toBytes(Resource resource) throws IOException { 068 if (VersionUtilities.isR5Ver(npm.fhirVersion())) { 069 return new org.hl7.fhir.r5.formats.JsonParser().composeBytes(resource); 070 } 071 if (VersionUtilities.isR4Plus(npm.fhirVersion())) { 072 org.hl7.fhir.r4.model.Resource r4 = VersionConvertorFactory_40_50.convertResource(resource); 073 return new org.hl7.fhir.r4.formats.JsonParser().composeBytes(r4); 074 } 075 if (VersionUtilities.isR3Ver(npm.fhirVersion())) { 076 org.hl7.fhir.dstu3.model.Resource r3 = VersionConvertorFactory_30_50.convertResource(resource); 077 return new org.hl7.fhir.dstu3.formats.JsonParser().composeBytes(r3); 078 } 079 if (VersionUtilities.isR2Ver(npm.fhirVersion())) { 080 org.hl7.fhir.dstu2.model.Resource r2 = VersionConvertorFactory_10_50.convertResource(resource); 081 return new org.hl7.fhir.dstu2.formats.JsonParser().composeBytes(r2); 082 } 083 throw new Error("Unsupported version"); 084 } 085 086 @Override 087 public void seeResource(Resource resource, String summaryId) { 088 if (minify) { 089 ResourceMinifier min = new ResourceMinifier(); 090 if (min.isMinified(resource.fhirType())) { 091 resource = resource.copy(); 092 if (!min.minify(resource)) { 093 return; 094 } 095 } else { 096 return; 097 } 098 } 099 try { 100 npm.addFile("package", resource.fhirType()+"-"+resource.getIdPart()+".json", toBytes(resource), null); 101 } catch (IOException e) { 102 e.printStackTrace(); 103 } 104 } 105 106 @Override 107 public void brokenLink(String link) { 108 System.err.println("Broken Link: " +link); 109 } 110 } 111 112 private static void loadFromPackage(String version, SimpleWorkerContext ctxt, FilesystemPackageCacheManager pcm, String pid) throws FHIRException, IOException { 113 NpmPackage npm = pcm.loadPackage(pid); 114 for (String dep : npm.dependencies()) { 115 if (!VersionUtilities.isCorePackage(dep)) { 116 loadFromPackage(version, ctxt, pcm, dep); 117 } 118 } 119 System.out.println("Load "+pid); 120 ctxt.loadFromPackage(npm, getLoader(version)); 121 } 122 123 private static IContextResourceLoader getLoader(String version) { 124 if (VersionUtilities.isR2Ver(version)) { 125 return new R2ToR5Loader(LOADED_TYPES, new NullLoaderKnowledgeProviderR5()); 126 } 127 if (VersionUtilities.isR3Ver(version)) { 128 return new R3ToR5Loader(LOADED_TYPES, new NullLoaderKnowledgeProviderR5()); 129 } 130 if (VersionUtilities.isR4Ver(version)) { 131 return new R4ToR5Loader(LOADED_TYPES, new NullLoaderKnowledgeProviderR5(), version); 132 } 133 if (VersionUtilities.isR5Ver(version)) { 134 return new R5ToR5Loader(LOADED_TYPES, new NullLoaderKnowledgeProviderR5()); 135 } 136 return null; 137 } 138 139 140}