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.MarkedToMoveToAdjunctPackage;
016import org.hl7.fhir.utilities.i18n.LanguageFileProducer;
017import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerLanguageSession;
018import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerSession;
019import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TextUnit;
020
021
022@MarkedToMoveToAdjunctPackage
023public class ResourceLanguageFileBuilder {
024
025  
026  private LanguageFileProducer lp;
027  private String source;
028  private String target;
029  private IWorkerContext context;
030  StructureDefinition profile = null;
031
032  public void prepare(LanguageFileProducer lp, IWorkerContext context, String source, String target) {
033    this.lp = lp;
034    this.source = source;
035    this.target = target;
036    this.context = context;
037  }
038  
039  
040  public StructureDefinition getProfile() {
041    return profile;
042  }
043
044  public void setProfile(StructureDefinition profile) {
045    this.profile = profile;
046  }
047  
048  public void build(Resource res) throws IOException {
049    String id = res.fhirType();
050    String path = res.fhirType() +"-"+res.getIdBase();
051    
052    if (!source.equals(res.getLanguage())) {
053      throw new FHIRException("Language mismatch: '"+source+"' => '"+target+"' but resource language is '"+res.getLanguage()+"'");
054    }
055
056    if (profile == null) {
057      profile = context.fetchTypeDefinition(res.fhirType());
058      if (profile == null) {
059        throw new FHIRException("profile");
060      }
061    }
062
063    LanguageProducerSession session = lp.startSession(path,source);
064    LanguageProducerLanguageSession langSession = session.forLang(target);
065  
066    for (Property p : res.children()) {
067      process(langSession, p, id, path);      
068    }
069    
070    langSession.finish();
071    session.finish();
072  }
073  
074  private void process(LanguageProducerLanguageSession sess, Property p, String id, String path) throws IOException {
075    if (p.hasValues()) {
076      int i = 0;
077      for (Base b : p.getValues()) {
078        String pid = id+"."+p.getName();
079        String ppath = path+"."+p.getName()+(p.isList() ? "["+i+"]" : "");
080        i++;
081        if (isTranslatable(p, b, pid)) {
082          sess.entry(new TextUnit(ppath, getContext(), b.primitiveValue(), getTranslation(b, target)));
083        }
084        for (Property pp : b.children()) {
085          process(sess, pp, pid, ppath);      
086        }
087      }
088    }  
089  }
090
091  private String getContext() {
092    throw new Error("not done yet"); 
093  }
094
095
096  private boolean isTranslatable(Property p, Base b, String id) {
097    if (context.isPrimitiveType(b.fhirType())) { // never any translations for non-primitives
098      ElementDefinition ed = null;
099      for (ElementDefinition t : profile.getSnapshot().getElement()) {
100        if (t.getId().equals(id)) {
101          ed = t;
102        }
103      }
104      if (ed != null && ed.hasExtension(ToolingExtensions.EXT_TRANSLATABLE)) {
105        return true;
106      }
107    }
108    return false;
109  }
110
111  private String getTranslation(Base b, String target2) {
112    if (b instanceof  org.hl7.fhir.r5.model.Element) {
113      org.hl7.fhir.r5.model.Element e = (org.hl7.fhir.r5.model.Element) b;
114      for (Extension ext : e.getExtensionsByUrl(ToolingExtensions.EXT_TRANSLATION)) {
115        String lang = ext.hasExtension("lang") ? ext.getExtensionString("lang") : null;
116        if (target.equals(lang)) {
117          return ext.getExtensionString("content");
118        }
119      }      
120    }
121    return null;
122  }
123
124  public void build(Element res) {
125    
126  }
127
128}