Language improvements for Lang Packs
This commit is contained in:
parent
89c1c8608c
commit
7b5aceb722
|
@ -1,12 +1,19 @@
|
|||
package org.hl7.fhir.r5.elementmodel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.checkerframework.checker.units.qual.cd;
|
||||
import org.hl7.fhir.r5.context.ContextUtilities;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
|
||||
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionDesignationComponent;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer;
|
||||
|
@ -29,6 +36,12 @@ import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TranslationUnit;
|
|||
*/
|
||||
public class LanguageUtils {
|
||||
|
||||
public static final List<String> TRANSLATION_SUPPLEMENT_RESOURCE_TYPES = Arrays.asList("CodeSystem", "StructureDefinition");
|
||||
|
||||
private static final String ORPHAN_TRANSLATIONS_NAME = "translations.orphans";
|
||||
|
||||
private static final String SUPPLEMENT_NAME = "translations.supplement";
|
||||
|
||||
IWorkerContext context;
|
||||
private List<String> crlist;
|
||||
|
||||
|
@ -185,4 +198,84 @@ public class LanguageUtils {
|
|||
public static boolean langsMatch(String dstLang, String srcLang) {
|
||||
return dstLang == null ? false : dstLang.equals(srcLang);
|
||||
}
|
||||
|
||||
public static void fillSupplement(CodeSystem cs, List<TranslationUnit> list) {
|
||||
cs.setUserData(SUPPLEMENT_NAME, "true");
|
||||
for (TranslationUnit tu : list) {
|
||||
ConceptDefinitionComponent cd = CodeSystemUtilities.getCode(cs, tu.getContext());
|
||||
if (cd != null && cd.hasDisplay() && cd.getDisplay().equals(tu.getSrcText())) {
|
||||
cd.addDesignation().setLanguage(tu.getLanguage()).setValue(tu.getTgtText());
|
||||
} else {
|
||||
addOrphanTranslation(cs, tu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void addOrphanTranslation(CodeSystem cs, TranslationUnit tu) {
|
||||
List<TranslationUnit> list = (List<TranslationUnit>) cs.getUserData(ORPHAN_TRANSLATIONS_NAME);
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
cs.setUserData(ORPHAN_TRANSLATIONS_NAME, list);
|
||||
}
|
||||
list.add(tu);
|
||||
}
|
||||
|
||||
public static String nameForLang(String lang) {
|
||||
// todo: replace with structures from loading languages properly
|
||||
switch (lang) {
|
||||
case "en" : return "English";
|
||||
case "de" : return "German";
|
||||
case "es" : return "Spanish";
|
||||
case "nl" : return "Dutch";
|
||||
}
|
||||
return Utilities.capitalize(lang);
|
||||
}
|
||||
|
||||
public static String titleForLang(String lang) {
|
||||
// todo: replace with structures from loading languages properly
|
||||
switch (lang) {
|
||||
case "en" : return "English";
|
||||
case "de" : return "German";
|
||||
case "es" : return "Spanish";
|
||||
case "nl" : return "Dutch";
|
||||
}
|
||||
return Utilities.capitalize(lang);
|
||||
}
|
||||
|
||||
public static boolean handlesAsResource(Resource resource) {
|
||||
return (resource instanceof CodeSystem && resource.hasUserData(SUPPLEMENT_NAME));
|
||||
}
|
||||
|
||||
public static boolean handlesAsElement(Element element) {
|
||||
return false; // for now...
|
||||
}
|
||||
|
||||
public static List<TranslationUnit> generateTranslations(Resource res, String lang) {
|
||||
List<TranslationUnit> list = new ArrayList<>();
|
||||
CodeSystem cs = (CodeSystem) res;
|
||||
for (ConceptDefinitionComponent cd : cs.getConcept()) {
|
||||
generateTranslations(list, cd, lang);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static void generateTranslations(List<TranslationUnit> list, ConceptDefinitionComponent cd, String lang) {
|
||||
String code = cd.getCode();
|
||||
String display = cd.getDisplay();
|
||||
String target = null;
|
||||
for (ConceptDefinitionDesignationComponent d : cd.getDesignation()) {
|
||||
if (target == null && !d.hasUse() && d.hasLanguage() && lang.equals(d.getLanguage())) {
|
||||
target = d.getValue();
|
||||
}
|
||||
}
|
||||
for (ConceptDefinitionDesignationComponent d : cd.getDesignation()) {
|
||||
if (target == null && d.hasLanguage() && lang.equals(d.getLanguage())) {
|
||||
target = d.getValue();
|
||||
}
|
||||
}
|
||||
list.add(new TranslationUnit(lang, code, display, target));
|
||||
for (ConceptDefinitionComponent cd1 : cd.getConcept()) {
|
||||
generateTranslations(list, cd1, lang);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
|||
import javax.annotation.Nonnull;
|
||||
|
||||
public class QuestionnaireRenderer extends TerminologyRenderer {
|
||||
public static final String EXT_QUESTIONNAIRE_ITEM_TYPE_ORIGINAL = "http://hl7.org/fhir/tools/StructureDefinition/original-item-type";
|
||||
public static final String EXT_QUESTIONNAIRE_ITEM_TYPE_ORIGINAL = "http://hl7.org/fhir/4.0/StructureDefinition/extension-Questionnaire.item.type";
|
||||
|
||||
public QuestionnaireRenderer(RenderingContext context) {
|
||||
super(context);
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
package org.hl7.fhir.utilities.i18n;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TranslationUnit;
|
||||
import org.hl7.fhir.utilities.json.model.JsonObject;
|
||||
import org.hl7.fhir.utilities.json.parser.JsonParser;
|
||||
|
||||
public class JsonLangFileProducer extends LanguageFileProducer {
|
||||
|
||||
public JsonLangFileProducer(String folder) {
|
||||
super(folder);
|
||||
}
|
||||
|
||||
public JsonLangFileProducer() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LanguageProducerSession startSession(String id, String baseLang) throws IOException {
|
||||
return new JsonLangProducerSession(id, baseLang);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
// nothing
|
||||
}
|
||||
|
||||
public class JsonLangProducerSession extends LanguageProducerSession {
|
||||
|
||||
JsonObject json = new JsonObject();
|
||||
|
||||
public JsonLangProducerSession(String id, String baseLang) {
|
||||
super (id, baseLang);
|
||||
json.add("id", id);
|
||||
json.add("baseLang", baseLang);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LanguageProducerLanguageSession forLang(String targetLang) {
|
||||
return new JsonLangLanguageProducerLanguageSession(id, baseLang, targetLang, json);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() throws IOException {
|
||||
JsonParser.compose(json, new FileOutputStream(getFileName(id, baseLang)));
|
||||
}
|
||||
}
|
||||
|
||||
public class JsonLangLanguageProducerLanguageSession extends LanguageProducerLanguageSession {
|
||||
|
||||
|
||||
private JsonObject json;
|
||||
|
||||
public JsonLangLanguageProducerLanguageSession(String id, String baseLang, String targetLang, JsonObject parent) {
|
||||
super(id, baseLang, targetLang);
|
||||
json = new JsonObject();
|
||||
parent.forceArray("languages").add(json);
|
||||
json.add("targetLang", targetLang);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void finish() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void entry(TextUnit unit) {
|
||||
JsonObject entry = new JsonObject();
|
||||
json.forceArray("entries").add(entry);
|
||||
entry.add("context", unit.getContext());
|
||||
entry.add("source", unit.getSrcText());
|
||||
entry.add("target", unit.getTgtText());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<TranslationUnit> loadSource(InputStream source) throws IOException {
|
||||
List<TranslationUnit> list = new ArrayList<>();
|
||||
JsonObject json = JsonParser.parseObject(source);
|
||||
for (JsonObject lang : json.forceArray("languages").asJsonObjects()) {
|
||||
for (JsonObject entry : lang.forceArray("entries").asJsonObjects()) {
|
||||
list.add(new TranslationUnit(lang.asString("targetLang"), entry.asString("context"), entry.asString("source"), entry.asString("target")));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private String getFileName(String id, String baseLang) throws IOException {
|
||||
return Utilities.path(getFolder(), id+"-"+baseLang+".json");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int fileCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void produce(String id, String baseLang, String targetLang, List<TranslationUnit> translations, String filename) throws IOException {
|
||||
|
||||
JsonObject json = new JsonObject();
|
||||
json.add("id", id);
|
||||
json.add("baseLang", baseLang);
|
||||
|
||||
JsonObject lj = new JsonObject();
|
||||
json.forceArray("languages").add(lj);
|
||||
lj.add("targetLang", targetLang);
|
||||
|
||||
for (TranslationUnit tu : translations) {
|
||||
JsonObject entry = new JsonObject();
|
||||
lj.forceArray("entries").add(entry);
|
||||
entry.add("context", tu.getContext());
|
||||
entry.add("source", tu.getSrcText());
|
||||
entry.add("target", tu.getTgtText());
|
||||
}
|
||||
TextFile.stringToFile(JsonParser.compose(json, true), Utilities.path(getFolder(), filename));
|
||||
}
|
||||
|
||||
}
|
|
@ -9,6 +9,7 @@ import java.util.Map;
|
|||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TextUnit;
|
||||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TranslationUnit;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -143,4 +144,6 @@ public abstract class LanguageFileProducer {
|
|||
public abstract List<TranslationUnit> loadSource(InputStream source) throws IOException, ParserConfigurationException, SAXException;
|
||||
|
||||
public abstract int fileCount();
|
||||
|
||||
public abstract void produce(String id, String baseLang, String targetLang, List<TranslationUnit> translations, String filename) throws IOException;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.hl7.fhir.utilities.i18n.XLIFFProducer.XLiffLanguageProducerLanguageSe
|
|||
public class PoGetTextProducer extends LanguageFileProducer {
|
||||
|
||||
private int filecount;
|
||||
private boolean incLangInFilename;
|
||||
|
||||
public PoGetTextProducer(String folder) {
|
||||
super(folder);
|
||||
|
@ -144,8 +145,38 @@ public class PoGetTextProducer extends LanguageFileProducer {
|
|||
}
|
||||
|
||||
private String getFileName(String id, String baseLang, String targetLang) throws IOException {
|
||||
return Utilities.path(getFolder(), id+"-"+baseLang+"-"+targetLang+".po");
|
||||
return Utilities.path(getFolder(), id+(incLangInFilename ? "-"+baseLang+"-"+targetLang+".po" : ""));
|
||||
}
|
||||
|
||||
public boolean isIncLangInFilename() {
|
||||
return incLangInFilename;
|
||||
}
|
||||
|
||||
public void setIncLangInFilename(boolean incLangInFilename) {
|
||||
this.incLangInFilename = incLangInFilename;
|
||||
}
|
||||
|
||||
protected void ln(StringBuilder po, String line) {
|
||||
po.append(line+"\r\n");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void produce(String id, String baseLang, String targetLang, List<TranslationUnit> translations, String filename) throws IOException {
|
||||
StringBuilder po = new StringBuilder();
|
||||
ln(po, "# "+baseLang+" -> "+targetLang);
|
||||
ln(po, "");
|
||||
for (TranslationUnit tu : translations) {
|
||||
ln(po, "#: "+tu.getContext());
|
||||
// if (context != null) {
|
||||
// ln("#. "+context);
|
||||
// }
|
||||
ln(po, "msgid \""+tu.getSrcText()+"\"");
|
||||
ln(po, "msgstr \""+(tu.getTgtText() == null ? "" : tu.getTgtText())+"\"");
|
||||
ln(po, "");
|
||||
}
|
||||
TextFile.stringToFile(po.toString(), Utilities.path(getFolder(), filename));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ import org.hl7.fhir.utilities.TextFile;
|
|||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TextUnit;
|
||||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TranslationUnit;
|
||||
import org.hl7.fhir.utilities.json.model.JsonObject;
|
||||
import org.hl7.fhir.utilities.json.parser.JsonParser;
|
||||
import org.hl7.fhir.utilities.xml.XMLUtil;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
@ -132,4 +134,33 @@ public class XLIFFProducer extends LanguageFileProducer {
|
|||
public int fileCount() {
|
||||
return filecount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected void ln(StringBuilder xml, String line) {
|
||||
xml.append(line+"\r\n");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void produce(String id, String baseLang, String targetLang, List<TranslationUnit> translations, String filename) throws IOException {
|
||||
StringBuilder xml = new StringBuilder();
|
||||
ln(xml, "<?xml version=\"1.0\" ?>\r\n");
|
||||
ln(xml, "<xliff xmlns=\"urn:oasis:names:tc:xliff:document:2.0\" version=\"2.0\">");
|
||||
ln(xml, " <file source-language=\""+baseLang+"\" target-language=\""+targetLang+"\" id=\""+id+"\" original=\"Resource "+id+"\" datatype=\"KEYVALUEJSON\">");
|
||||
ln(xml, " <body>");
|
||||
for (TranslationUnit tu : translations) {
|
||||
ln(xml, " <trans-unit id=\""+id+"\" resname=\""+tu.getContext()+"\">");
|
||||
ln(xml, " <source>"+Utilities.escapeXml(tu.getSrcText())+"</source>");
|
||||
ln(xml, " <target>"+Utilities.escapeXml(tu.getTgtText())+"</target>");
|
||||
ln(xml, " </trans-unit>");
|
||||
}
|
||||
|
||||
ln(xml, " </body>");
|
||||
ln(xml, " </file>");
|
||||
ln(xml, "</xliff>");
|
||||
TextFile.stringToFile(xml.toString(), Utilities.path(getFolder(), filename));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue