001package org.hl7.fhir.r4.elementmodel; 002 003/*- 004 * #%L 005 * org.hl7.fhir.r4 006 * %% 007 * Copyright (C) 2014 - 2019 Health Level 7 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022import java.io.ByteArrayInputStream; 023import java.io.ByteArrayOutputStream; 024import java.io.IOException; 025import java.util.ArrayList; 026import java.util.List; 027 028import org.hl7.fhir.exceptions.FHIRException; 029import org.hl7.fhir.r4.conformance.ProfileUtilities; 030import org.hl7.fhir.r4.context.IWorkerContext; 031import org.hl7.fhir.r4.formats.IParser.OutputStyle; 032import org.hl7.fhir.r4.model.Base; 033import org.hl7.fhir.r4.model.CodeableConcept; 034import org.hl7.fhir.r4.model.Coding; 035import org.hl7.fhir.r4.model.ElementDefinition; 036import org.hl7.fhir.r4.model.Factory; 037import org.hl7.fhir.r4.model.Identifier; 038import org.hl7.fhir.r4.model.PrimitiveType; 039import org.hl7.fhir.r4.model.Reference; 040import org.hl7.fhir.r4.model.Resource; 041import org.hl7.fhir.r4.model.StructureDefinition; 042import org.hl7.fhir.r4.model.StructureDefinition.StructureDefinitionKind; 043import org.hl7.fhir.r4.model.Type; 044 045 046public class ObjectConverter { 047 048 private IWorkerContext context; 049 050 public ObjectConverter(IWorkerContext context) { 051 this.context = context; 052 } 053 054 public Element convert(Resource ig) throws IOException, FHIRException { 055 if (ig == null) 056 return null; 057 ByteArrayOutputStream bs = new ByteArrayOutputStream(); 058 org.hl7.fhir.r4.formats.JsonParser jp = new org.hl7.fhir.r4.formats.JsonParser(); 059 jp.compose(bs, ig); 060 ByteArrayInputStream bi = new ByteArrayInputStream(bs.toByteArray()); 061 return new JsonParser(context).parse(bi); 062 } 063 064 public Element convert(Property property, Type type) throws FHIRException { 065 return convertElement(property, type); 066 } 067 068 private Element convertElement(Property property, Base base) throws FHIRException { 069 if (base == null) 070 return null; 071 String tn = base.fhirType(); 072 StructureDefinition sd = context.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(tn, context.getOverrideVersionNs())); 073 if (sd == null) 074 throw new FHIRException("Unable to find definition for type "+tn); 075 Element res = new Element(property.getName(), property); 076 if (sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE) 077 res.setValue(((PrimitiveType) base).asStringValue()); 078 079 List<ElementDefinition> children = ProfileUtilities.getChildMap(sd, sd.getSnapshot().getElementFirstRep()); 080 for (ElementDefinition child : children) { 081 String n = tail(child.getPath()); 082 if (sd.getKind() != StructureDefinitionKind.PRIMITIVETYPE || !"value".equals(n)) { 083 Base[] values = base.getProperty(n.hashCode(), n, false); 084 if (values != null) 085 for (Base value : values) { 086 res.getChildren().add(convertElement(new Property(context, child, sd), value)); 087 } 088 } 089 } 090 return res; 091 } 092 093 private String tail(String path) { 094 if (path.contains(".")) 095 return path.substring(path.lastIndexOf('.')+1); 096 else 097 return path; 098 } 099 100 public Type convertToType(Element element) throws FHIRException { 101 Type b = new Factory().create(element.fhirType()); 102 if (b instanceof PrimitiveType) { 103 ((PrimitiveType) b).setValueAsString(element.primitiveValue()); 104 } else { 105 for (Element child : element.getChildren()) { 106 b.setProperty(child.getName(), convertToType(child)); 107 } 108 } 109 return b; 110 } 111 112 public Resource convert(Element element) throws FHIRException { 113 ByteArrayOutputStream bo = new ByteArrayOutputStream(); 114 try { 115 new JsonParser(context).compose(element, bo, OutputStyle.NORMAL, null); 116// TextFile.bytesToFile(bo.toByteArray(), "c:\\temp\\json.json"); 117 return new org.hl7.fhir.r4.formats.JsonParser().parse(bo.toByteArray()); 118 } catch (IOException e) { 119 // won't happen 120 throw new FHIRException(e); 121 } 122 123 } 124 125 public static CodeableConcept readAsCodeableConcept(Element element) { 126 CodeableConcept cc = new CodeableConcept(); 127 List<Element> list = new ArrayList<Element>(); 128 element.getNamedChildren("coding", list); 129 for (Element item : list) 130 cc.addCoding(readAsCoding(item)); 131 cc.setText(element.getNamedChildValue("text")); 132 return cc; 133 } 134 135 public static Coding readAsCoding(Element item) { 136 Coding c = new Coding(); 137 c.setSystem(item.getNamedChildValue("system")); 138 c.setVersion(item.getNamedChildValue("version")); 139 c.setCode(item.getNamedChildValue("code")); 140 c.setDisplay(item.getNamedChildValue("display")); 141 return c; 142 } 143 144 public static Identifier readAsIdentifier(Element item) { 145 Identifier r = new Identifier(); 146 r.setSystem(item.getNamedChildValue("system")); 147 r.setValue(item.getNamedChildValue("value")); 148 return r; 149 } 150 151 public static Reference readAsReference(Element item) { 152 Reference r = new Reference(); 153 r.setDisplay(item.getNamedChildValue("display")); 154 r.setReference(item.getNamedChildValue("reference")); 155 r.setType(item.getNamedChildValue("type")); 156 List<Element> identifier = item.getChildrenByName("identifier"); 157 if (identifier.isEmpty() == false) { 158 r.setIdentifier(readAsIdentifier(identifier.get(0))); 159 } 160 return r; 161 } 162 163}