update language file handling to handle context properly

This commit is contained in:
Grahame Grieve 2023-06-05 21:16:51 +02:00
parent fe7cd1f39a
commit 01b4219259
6 changed files with 91 additions and 32 deletions

View File

@ -12,6 +12,8 @@ import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.model.CodeSystem; import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionDesignationComponent; import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionDesignationComponent;
import org.hl7.fhir.r5.model.CodeSystem.ConceptPropertyComponent;
import org.hl7.fhir.r5.model.DataType;
import org.hl7.fhir.r5.model.Resource; import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities; import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.TextFile;
@ -36,7 +38,7 @@ import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TranslationUnit;
*/ */
public class LanguageUtils { public class LanguageUtils {
public static final List<String> TRANSLATION_SUPPLEMENT_RESOURCE_TYPES = Arrays.asList("CodeSystem", "StructureDefinition"); public static final List<String> TRANSLATION_SUPPLEMENT_RESOURCE_TYPES = Arrays.asList("CodeSystem", "StructureDefinition", "Questionnaire");
private static final String ORPHAN_TRANSLATIONS_NAME = "translations.orphans"; private static final String ORPHAN_TRANSLATIONS_NAME = "translations.orphans";
@ -64,7 +66,7 @@ public class LanguageUtils {
if (translation == null) { if (translation == null) {
translation = element.getTranslation(langSession.getTargetLang()); translation = element.getTranslation(langSession.getTargetLang());
} }
langSession.entry(new TextUnit(pathForElement(element), base, translation)); langSession.entry(new TextUnit(pathForElement(element), contextForElement(element), base, translation));
} }
} }
for (Element c: element.getChildren()) { for (Element c: element.getChildren()) {
@ -75,6 +77,10 @@ public class LanguageUtils {
} }
private String contextForElement(Element element) {
throw new Error("Not done yet");
}
private String getSpecialTranslation(Element parent, Element element, String targetLang) { private String getSpecialTranslation(Element parent, Element element, String targetLang) {
if (parent == null) { if (parent == null) {
return null; return null;
@ -188,7 +194,7 @@ public class LanguageUtils {
private Set<TranslationUnit> findTranslations(String path, String src, Set<TranslationUnit> translations) { private Set<TranslationUnit> findTranslations(String path, String src, Set<TranslationUnit> translations) {
Set<TranslationUnit> res = new HashSet<>(); Set<TranslationUnit> res = new HashSet<>();
for (TranslationUnit translation : translations) { for (TranslationUnit translation : translations) {
if (path.equals(translation.getContext()) && src.equals(translation.getSrcText())) { if (path.equals(translation.getId()) && src.equals(translation.getSrcText())) {
res.add(translation); res.add(translation);
} }
} }
@ -202,7 +208,7 @@ public class LanguageUtils {
public static void fillSupplement(CodeSystem cs, List<TranslationUnit> list) { public static void fillSupplement(CodeSystem cs, List<TranslationUnit> list) {
cs.setUserData(SUPPLEMENT_NAME, "true"); cs.setUserData(SUPPLEMENT_NAME, "true");
for (TranslationUnit tu : list) { for (TranslationUnit tu : list) {
ConceptDefinitionComponent cd = CodeSystemUtilities.getCode(cs, tu.getContext()); ConceptDefinitionComponent cd = CodeSystemUtilities.getCode(cs, tu.getId());
if (cd != null && cd.hasDisplay() && cd.getDisplay().equals(tu.getSrcText())) { if (cd != null && cd.hasDisplay() && cd.getDisplay().equals(tu.getSrcText())) {
cd.addDesignation().setLanguage(tu.getLanguage()).setValue(tu.getTgtText()); cd.addDesignation().setLanguage(tu.getLanguage()).setValue(tu.getTgtText());
} else { } else {
@ -273,9 +279,18 @@ public class LanguageUtils {
target = d.getValue(); target = d.getValue();
} }
} }
list.add(new TranslationUnit(lang, code, display, target)); list.add(new TranslationUnit(lang, code, getDefinition(cd), display, target));
for (ConceptDefinitionComponent cd1 : cd.getConcept()) { for (ConceptDefinitionComponent cd1 : cd.getConcept()) {
generateTranslations(list, cd1, lang); generateTranslations(list, cd1, lang);
} }
} }
private static String getDefinition(ConceptDefinitionComponent cd) {
ConceptPropertyComponent v = CodeSystemUtilities.getProperty(cd, "translation-context");
if (v != null && v.hasValue()) {
return v.getValue().primitiveValue();
} else {
return cd.getDefinition();
}
}
} }

View File

@ -77,7 +77,7 @@ public class ResourceLanguageFileBuilder {
String ppath = path+"."+p.getName()+(p.isList() ? "["+i+"]" : ""); String ppath = path+"."+p.getName()+(p.isList() ? "["+i+"]" : "");
i++; i++;
if (isTranslatable(p, b, pid)) { if (isTranslatable(p, b, pid)) {
sess.entry(new TextUnit(ppath, b.primitiveValue(), getTranslation(b, target))); sess.entry(new TextUnit(ppath, getContext(), b.primitiveValue(), getTranslation(b, target)));
} }
for (Property pp : b.children()) { for (Property pp : b.children()) {
process(sess, pp, pid, ppath); process(sess, pp, pid, ppath);
@ -86,6 +86,11 @@ public class ResourceLanguageFileBuilder {
} }
} }
private String getContext() {
throw new Error("not done yet");
}
private boolean isTranslatable(Property p, Base b, String id) { private boolean isTranslatable(Property p, Base b, String id) {
if (new ContextUtilities(context).isPrimitiveDatatype(b.fhirType())) { // never any translations for non-primitives if (new ContextUtilities(context).isPrimitiveDatatype(b.fhirType())) { // never any translations for non-primitives
ElementDefinition ed = null; ElementDefinition ed = null;

View File

@ -74,7 +74,10 @@ public class JsonLangFileProducer extends LanguageFileProducer {
public void entry(TextUnit unit) { public void entry(TextUnit unit) {
JsonObject entry = new JsonObject(); JsonObject entry = new JsonObject();
json.forceArray("entries").add(entry); json.forceArray("entries").add(entry);
entry.add("context", unit.getContext()); entry.add("id", unit.getId());
if (unit.getContext1() != null) {
entry.add("context", unit.getContext1());
}
entry.add("source", unit.getSrcText()); entry.add("source", unit.getSrcText());
entry.add("target", unit.getTgtText()); entry.add("target", unit.getTgtText());
} }
@ -88,7 +91,7 @@ public class JsonLangFileProducer extends LanguageFileProducer {
JsonObject json = JsonParser.parseObject(source); JsonObject json = JsonParser.parseObject(source);
for (JsonObject lang : json.forceArray("languages").asJsonObjects()) { for (JsonObject lang : json.forceArray("languages").asJsonObjects()) {
for (JsonObject entry : lang.forceArray("entries").asJsonObjects()) { for (JsonObject entry : lang.forceArray("entries").asJsonObjects()) {
list.add(new TranslationUnit(lang.asString("targetLang"), entry.asString("context"), entry.asString("source"), entry.asString("target"))); list.add(new TranslationUnit(lang.asString("targetLang"), entry.asString("id"), entry.asString("context"), entry.asString("source"), entry.asString("target")));
} }
} }
return list; return list;
@ -118,7 +121,10 @@ public class JsonLangFileProducer extends LanguageFileProducer {
for (TranslationUnit tu : translations) { for (TranslationUnit tu : translations) {
JsonObject entry = new JsonObject(); JsonObject entry = new JsonObject();
lj.forceArray("entries").add(entry); lj.forceArray("entries").add(entry);
entry.add("context", tu.getContext()); entry.add("id", tu.getId());
if (tu.getContext1() != null) {
entry.add("context", tu.getContext1());
}
entry.add("source", tu.getSrcText()); entry.add("source", tu.getSrcText());
entry.add("target", tu.getTgtText()); entry.add("target", tu.getTgtText());
} }

View File

@ -18,35 +18,59 @@ import java.util.HashMap;
public abstract class LanguageFileProducer { public abstract class LanguageFileProducer {
public static class TextUnit { public static class TextUnit {
protected String id;
protected String context; protected String context;
protected String srcText; protected String srcText;
protected String tgtText; protected String tgtText;
public TextUnit(String context, String srcText, String tgtText) { public TextUnit(String id, String context, String srcText, String tgtText) {
super(); super();
this.id = id;
this.context = context; this.context = context;
this.srcText = srcText; this.srcText = srcText;
this.tgtText = tgtText; this.tgtText = tgtText;
} }
public String getContext() { /**
* The identity of the item being translated
*
* @return
*/
public String getId() {
return id;
}
/**
* Additional language that helps establish the context
* @return
*/
public String getContext1() {
return context; return context;
} }
/**
* The language that's being translated from
*
* @return
*/
public String getSrcText() { public String getSrcText() {
return srcText; return srcText;
} }
/**
* The language that's being translated to
*
* @return
*/
public String getTgtText() { public String getTgtText() {
return tgtText; return tgtText;
} }
} }
public static class TranslationUnit extends TextUnit { public static class TranslationUnit extends TextUnit {
private String language; private String language;
public TranslationUnit(String language, String context, String srcText, String tgtText) { public TranslationUnit(String language, String id, String context, String srcText, String tgtText) {
super(context, srcText, tgtText); super(id, context, srcText, tgtText);
this.language = language; this.language = language;
} }

View File

@ -81,10 +81,10 @@ public class PoGetTextProducer extends LanguageFileProducer {
@Override @Override
public void entry(TextUnit unit) { public void entry(TextUnit unit) {
ln("#: "+unit.getContext()); ln("#: "+unit.getId());
// if (context != null) { if (unit.getContext1() != null) {
// ln("#. "+context); ln("#. "+unit.getContext1());
// } }
ln("msgid \""+unit.getSrcText()+"\""); ln("msgid \""+unit.getSrcText()+"\"");
ln("msgstr \""+(unit.getTgtText() == null ? "" : unit.getTgtText())+"\""); ln("msgstr \""+(unit.getTgtText() == null ? "" : unit.getTgtText())+"\"");
ln(""); ln("");
@ -117,7 +117,7 @@ public class PoGetTextProducer extends LanguageFileProducer {
lang = p[1].trim(); lang = p[1].trim();
} }
} else if (s.startsWith("#:")) { } else if (s.startsWith("#:")) {
tu = new TranslationUnit(lang, s.substring(2).trim(), null, null); tu = new TranslationUnit(lang, s.substring(2).trim(), null, null, null);
} else { } else {
throw new IOException("Encountered unexpected line '"+s+"'"); throw new IOException("Encountered unexpected line '"+s+"'");
} }
@ -166,10 +166,10 @@ public class PoGetTextProducer extends LanguageFileProducer {
ln(po, "# "+baseLang+" -> "+targetLang); ln(po, "# "+baseLang+" -> "+targetLang);
ln(po, ""); ln(po, "");
for (TranslationUnit tu : translations) { for (TranslationUnit tu : translations) {
ln(po, "#: "+tu.getContext()); ln(po, "#: "+tu.getId());
// if (context != null) { if (tu.getContext1() != null) {
// ln("#. "+context); ln(po, "#. "+tu.getContext1());
// } }
ln(po, "msgid \""+tu.getSrcText()+"\""); ln(po, "msgid \""+tu.getSrcText()+"\"");
ln(po, "msgstr \""+(tu.getTgtText() == null ? "" : tu.getTgtText())+"\""); ln(po, "msgstr \""+(tu.getTgtText() == null ? "" : tu.getTgtText())+"\"");
ln(po, ""); ln(po, "");

View File

@ -50,12 +50,12 @@ public class XLIFFProducer extends LanguageFileProducer {
@Override @Override
public void entry(TextUnit unit) { public void entry(TextUnit unit) {
i++; i++;
ln(" <trans-unit id=\""+id+"\" resname=\""+unit.getContext()+"\">"); ln(" <trans-unit id=\""+id+"\" resname=\""+unit.getId()+"\">");
// if (context != null) { if (unit.getContext1() != null) {
// ln(" <notes>"); ln(" <notes>");
// ln(" <note id=\"n"+i+"\">"+Utilities.escapeXml(context)+"</note>"); ln(" <note id=\"n"+i+"\">"+Utilities.escapeXml(unit.getContext1())+"</note>");
// ln(" </notes>"); ln(" </notes>");
// } }
ln(" <source>"+Utilities.escapeXml(unit.getSrcText())+"</source>"); ln(" <source>"+Utilities.escapeXml(unit.getSrcText())+"</source>");
ln(" <target>"+Utilities.escapeXml(unit.getTgtText())+"</target>"); ln(" <target>"+Utilities.escapeXml(unit.getTgtText())+"</target>");
ln(" </trans-unit>"); ln(" </trans-unit>");
@ -114,7 +114,9 @@ public class XLIFFProducer extends LanguageFileProducer {
for (Element file : XMLUtil.getNamedChildren(xliff, "file")) { for (Element file : XMLUtil.getNamedChildren(xliff, "file")) {
Element body = XMLUtil.getNamedChild(file, "body"); Element body = XMLUtil.getNamedChild(file, "body");
for (Element transUnit : XMLUtil.getNamedChildren(body, "trans-unit")) { for (Element transUnit : XMLUtil.getNamedChildren(body, "trans-unit")) {
TranslationUnit tu = new TranslationUnit(file.getAttribute("target-language"), transUnit.getAttribute("id"), Element notes = XMLUtil.getNamedChild(transUnit, "notes");
TranslationUnit tu = new TranslationUnit(file.getAttribute("target-language"), transUnit.getAttribute("id"),
notes == null ? null : XMLUtil.getNamedChildText(notes, "note"),
XMLUtil.getNamedChildText(transUnit, "source"), XMLUtil.getNamedChildText(transUnit, "target")); XMLUtil.getNamedChildText(transUnit, "source"), XMLUtil.getNamedChildText(transUnit, "target"));
if (!Utilities.noString(tu.getSrcText()) && !Utilities.noString(tu.getTgtText())) { if (!Utilities.noString(tu.getSrcText()) && !Utilities.noString(tu.getTgtText())) {
list.add(tu); list.add(tu);
@ -149,7 +151,14 @@ public class XLIFFProducer extends LanguageFileProducer {
ln(xml, " <file source-language=\""+baseLang+"\" target-language=\""+targetLang+"\" id=\""+id+"\" original=\"Resource "+id+"\" datatype=\"KEYVALUEJSON\">"); ln(xml, " <file source-language=\""+baseLang+"\" target-language=\""+targetLang+"\" id=\""+id+"\" original=\"Resource "+id+"\" datatype=\"KEYVALUEJSON\">");
ln(xml, " <body>"); ln(xml, " <body>");
for (TranslationUnit tu : translations) { for (TranslationUnit tu : translations) {
ln(xml, " <trans-unit id=\""+id+"\" resname=\""+tu.getContext()+"\">"); int i = 0;
ln(xml, " <trans-unit id=\""+id+"\" resname=\""+tu.getId()+"\">");
if (tu.getContext1() != null) {
i++;
ln(xml, " <notes>");
ln(xml, " <note id=\"n"+i+"\">"+Utilities.escapeXml(tu.getContext1())+"</note>");
ln(xml, " </notes>");
}
ln(xml, " <source>"+Utilities.escapeXml(tu.getSrcText())+"</source>"); ln(xml, " <source>"+Utilities.escapeXml(tu.getSrcText())+"</source>");
ln(xml, " <target>"+Utilities.escapeXml(tu.getTgtText())+"</target>"); ln(xml, " <target>"+Utilities.escapeXml(tu.getTgtText())+"</target>");
ln(xml, " </trans-unit>"); ln(xml, " </trans-unit>");