001package org.hl7.fhir.r5.utils;
002
003import java.io.IOException;
004
005import org.hl7.fhir.exceptions.FHIRException;
006import org.hl7.fhir.r5.context.ContextUtilities;
007import org.hl7.fhir.r5.context.IWorkerContext;
008import org.hl7.fhir.r5.elementmodel.Element;
009import org.hl7.fhir.r5.model.Base;
010import org.hl7.fhir.r5.model.ElementDefinition;
011import org.hl7.fhir.r5.model.Extension;
012import org.hl7.fhir.r5.model.Property;
013import org.hl7.fhir.r5.model.Resource;
014import org.hl7.fhir.r5.model.StructureDefinition;
015import org.hl7.fhir.utilities.i18n.LanguageFileProducer;
016
017public class ResourceLanguageFileBuilder {
018
019  
020  private LanguageFileProducer file;
021  private String source;
022  private String target;
023  private IWorkerContext context;
024  StructureDefinition profile = null;
025
026  public void prepare(LanguageFileProducer file, IWorkerContext context, String source, String target) {
027    this.file = file;
028    this.source = source;
029    this.target = target;
030    this.context = context;
031  }
032  
033  
034  public StructureDefinition getProfile() {
035    return profile;
036  }
037
038  public void setProfile(StructureDefinition profile) {
039    this.profile = profile;
040  }
041  
042  public void build(Resource res) throws IOException {
043    String id = res.fhirType();
044    String path = res.fhirType() +"-"+res.getIdBase();
045    
046    if (!source.equals(res.getLanguage())) {
047      throw new FHIRException("Language mismatch: '"+source+"' => '"+target+"' but resource language is '"+res.getLanguage()+"'");
048    }
049
050    if (profile == null) {
051      profile = context.fetchTypeDefinition(res.fhirType());
052      if (profile == null) {
053        throw new FHIRException("profile");
054      }
055    }
056    
057    file.start(path, path, res.getUserString("path"), source, target);
058  
059    for (Property p : res.children()) {
060      process(p, id, path);      
061    }
062    
063    file.finish();
064  }
065  
066  private void process(Property p, String id, String path) throws IOException {
067    if (p.hasValues()) {
068      int i = 0;
069      for (Base b : p.getValues()) {
070        String pid = id+"."+p.getName();
071        String ppath = path+"."+p.getName()+(p.isList() ? "["+i+"]" : "");
072        i++;
073        if (isTranslatable(p, b, pid)) {
074          file.makeEntry(ppath, null, null, b.primitiveValue(), getTranslation(b, target));
075        }
076        for (Property pp : b.children()) {
077          process(pp, pid, ppath);      
078        }
079      }
080    }  
081  }
082
083  private boolean isTranslatable(Property p, Base b, String id) {
084    if (new ContextUtilities(context).isPrimitiveDatatype(b.fhirType())) { // never any translations for non-primitives
085      ElementDefinition ed = null;
086      for (ElementDefinition t : profile.getSnapshot().getElement()) {
087        if (t.getId().equals(id)) {
088          ed = t;
089        }
090      }
091      if (ed != null && ed.hasExtension(ToolingExtensions.EXT_TRANSLATABLE)) {
092        return true;
093      }
094    }
095    return false;
096  }
097
098  private String getTranslation(Base b, String target2) {
099    if (b instanceof  org.hl7.fhir.r5.model.Element) {
100      org.hl7.fhir.r5.model.Element e = (org.hl7.fhir.r5.model.Element) b;
101      for (Extension ext : e.getExtensionsByUrl(ToolingExtensions.EXT_TRANSLATION)) {
102        String lang = ext.hasExtension("lang") ? ext.getExtensionString("lang") : null;
103        if (target.equals(lang)) {
104          return ext.getExtensionString("content");
105        }
106      }      
107    }
108    return null;
109  }
110
111  public void build(Element res) {
112    
113  }
114
115}