001package org.hl7.fhir.dstu3.elementmodel; 002 003/*- 004 * #%L 005 * org.hl7.fhir.dstu3 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 */ 022 023 024import java.io.ByteArrayInputStream; 025import java.io.ByteArrayOutputStream; 026import java.io.IOException; 027import java.util.ArrayList; 028import java.util.List; 029 030import org.hl7.fhir.dstu3.conformance.ProfileUtilities; 031import org.hl7.fhir.dstu3.context.IWorkerContext; 032import org.hl7.fhir.dstu3.formats.IParser.OutputStyle; 033import org.hl7.fhir.dstu3.model.Base; 034import org.hl7.fhir.dstu3.model.CodeableConcept; 035import org.hl7.fhir.dstu3.model.Coding; 036import org.hl7.fhir.dstu3.model.ElementDefinition; 037import org.hl7.fhir.dstu3.model.Factory; 038import org.hl7.fhir.dstu3.model.Identifier; 039import org.hl7.fhir.dstu3.model.PrimitiveType; 040import org.hl7.fhir.dstu3.model.Reference; 041import org.hl7.fhir.dstu3.model.Resource; 042import org.hl7.fhir.dstu3.model.StructureDefinition; 043import org.hl7.fhir.dstu3.model.StructureDefinition.StructureDefinitionKind; 044import org.hl7.fhir.dstu3.model.Type; 045import org.hl7.fhir.exceptions.DefinitionException; 046import org.hl7.fhir.exceptions.FHIRException; 047import org.hl7.fhir.exceptions.FHIRFormatError; 048 049 050 051public class ObjectConverter { 052 053 private IWorkerContext context; 054 055 public ObjectConverter(IWorkerContext context) { 056 this.context = context; 057 } 058 059 public Element convert(Resource ig) throws IOException, FHIRFormatError, DefinitionException { 060 if (ig == null) 061 return null; 062 ByteArrayOutputStream bs = new ByteArrayOutputStream(); 063 org.hl7.fhir.dstu3.formats.JsonParser jp = new org.hl7.fhir.dstu3.formats.JsonParser(); 064 jp.compose(bs, ig); 065 ByteArrayInputStream bi = new ByteArrayInputStream(bs.toByteArray()); 066 return new JsonParser(context).parse(bi); 067 } 068 069 public Element convert(Property property, Type type) throws FHIRException { 070 return convertElement(property, type); 071 } 072 073 private Element convertElement(Property property, Base base) throws FHIRException { 074 if (base == null) 075 return null; 076 String tn = base.fhirType(); 077 StructureDefinition sd = context.fetchTypeDefinition(tn); 078 if (sd == null) 079 throw new FHIRException("Unable to find definition for type "+tn); 080 Element res = new Element(property.getName(), property); 081 if (sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE) 082 res.setValue(((PrimitiveType) base).asStringValue()); 083 084 List<ElementDefinition> children = ProfileUtilities.getChildMap(sd, sd.getSnapshot().getElementFirstRep()); 085 for (ElementDefinition child : children) { 086 String n = tail(child.getPath()); 087 if (sd.getKind() != StructureDefinitionKind.PRIMITIVETYPE || !"value".equals(n)) { 088 Base[] values = base.getProperty(n.hashCode(), n, false); 089 if (values != null) 090 for (Base value : values) { 091 res.getChildren().add(convertElement(new Property(context, child, sd), value)); 092 } 093 } 094 } 095 return res; 096 } 097 098 private String tail(String path) { 099 if (path.contains(".")) 100 return path.substring(path.lastIndexOf('.')+1); 101 else 102 return path; 103 } 104 105 public Type convertToType(Element element) throws FHIRException { 106 Type b = new Factory().create(element.fhirType()); 107 if (b instanceof PrimitiveType) { 108 ((PrimitiveType) b).setValueAsString(element.primitiveValue()); 109 } else { 110 for (Element child : element.getChildren()) { 111 b.setProperty(child.getName(), convertToType(child)); 112 } 113 } 114 return b; 115 } 116 117 public Resource convert(Element element) throws FHIRException { 118 ByteArrayOutputStream bo = new ByteArrayOutputStream(); 119 try { 120 new JsonParser(context).compose(element, bo, OutputStyle.NORMAL, null); 121 return new org.hl7.fhir.dstu3.formats.JsonParser().parse(bo.toByteArray()); 122 } catch (IOException e) { 123 // won't happen 124 throw new FHIRException(e); 125 } 126 127 } 128 129 public static CodeableConcept readAsCodeableConcept(Element element) { 130 CodeableConcept cc = new CodeableConcept(); 131 List<Element> list = new ArrayList<Element>(); 132 element.getNamedChildren("coding", list); 133 for (Element item : list) 134 cc.addCoding(readAsCoding(item)); 135 cc.setText(element.getNamedChildValue("text")); 136 return cc; 137 } 138 139 public static Coding readAsCoding(Element item) { 140 Coding c = new Coding(); 141 c.setSystem(item.getNamedChildValue("system")); 142 c.setVersion(item.getNamedChildValue("version")); 143 c.setCode(item.getNamedChildValue("code")); 144 c.setDisplay(item.getNamedChildValue("display")); 145 return c; 146 } 147 148 public static Identifier readAsIdentifier(Element item) { 149 Identifier r = new Identifier(); 150 r.setSystem(item.getNamedChildValue("system")); 151 r.setValue(item.getNamedChildValue("value")); 152 return r; 153 } 154 155 public static Reference readAsReference(Element item) { 156 Reference r = new Reference(); 157 r.setDisplay(item.getNamedChildValue("display")); 158 r.setReference(item.getNamedChildValue("reference")); 159 List<Element> identifier = item.getChildrenByName("identifier"); 160 if (identifier.isEmpty() == false) { 161 r.setIdentifier(readAsIdentifier(identifier.get(0))); 162 } 163 return r; 164 } 165 166}