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