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