language translations support in validator
This commit is contained in:
parent
b6b4fbcd0c
commit
3ed7813973
|
@ -45,6 +45,7 @@ import org.apache.commons.lang3.Validate;
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
||||||
import org.hl7.fhir.r5.context.ContextUtilities;
|
import org.hl7.fhir.r5.context.ContextUtilities;
|
||||||
|
import org.hl7.fhir.r5.extensions.ExtensionsUtils;
|
||||||
import org.hl7.fhir.r5.model.Base;
|
import org.hl7.fhir.r5.model.Base;
|
||||||
import org.hl7.fhir.r5.model.DataType;
|
import org.hl7.fhir.r5.model.DataType;
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||||
|
@ -1443,7 +1444,7 @@ public class Element extends Base {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (lang.equals(l)) {
|
if (LanguageUtils.langsMatch(lang, l)) {
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1451,4 +1452,58 @@ public class Element extends Base {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getBasePath() {
|
||||||
|
if (property.getStructure().hasExtension(ToolingExtensions.EXT_RESOURCE_IMPLEMENTS)) {
|
||||||
|
StructureDefinition sd = property.getContext().fetchResource(StructureDefinition.class, ExtensionsUtils.getExtensionString(property.getStructure(), ToolingExtensions.EXT_RESOURCE_IMPLEMENTS));
|
||||||
|
if (sd != null) {
|
||||||
|
ElementDefinition ed = sd.getSnapshot().getElementByPath(property.getDefinition().getPath().replace(property.getStructure().getType(), sd.getType()));
|
||||||
|
if (ed != null) {
|
||||||
|
return ed.getBase().getPath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return property.getDefinition().getBase().getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTranslation(String lang, String translation) {
|
||||||
|
for (Element e : getChildren()) {
|
||||||
|
if (e.fhirType().equals("Extension")) {
|
||||||
|
String url = e.getNamedChildValue("url");
|
||||||
|
if (ToolingExtensions.EXT_TRANSLATION.equals(url)) {
|
||||||
|
String l = null;
|
||||||
|
Element v = null;
|
||||||
|
for (Element g : e.getChildren()) {
|
||||||
|
if (g.fhirType().equals("Extension")) {
|
||||||
|
String u = g.getNamedChildValue("url");
|
||||||
|
if ("lang".equals(u)) {
|
||||||
|
l = g.getNamedChildValue("value");
|
||||||
|
} else if ("value".equals(u)) {
|
||||||
|
v = g.getNamedChild("value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (LanguageUtils.langsMatch(lang, l)) {
|
||||||
|
if (v == null) {
|
||||||
|
Element ext = e.addElement("extension");
|
||||||
|
ext.addElement("url").setValue("value");
|
||||||
|
ext.addElement("valueString").setValue(translation);
|
||||||
|
} else {
|
||||||
|
v.setValue(translation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Element t = addElement("extension");
|
||||||
|
t.addElement("url").setValue(ToolingExtensions.EXT_TRANSLATION);
|
||||||
|
|
||||||
|
Element ext = t.addElement("extension");
|
||||||
|
ext.addElement("url").setValue("lang");
|
||||||
|
ext.addElement("valueCode").setValue(lang);
|
||||||
|
|
||||||
|
ext = t.addElement("extension");
|
||||||
|
ext.addElement("url").setValue("value");
|
||||||
|
ext.addElement("valueString").setValue(translation);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,9 +1,18 @@
|
||||||
package org.hl7.fhir.r5.elementmodel;
|
package org.hl7.fhir.r5.elementmodel;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.hl7.fhir.r5.context.ContextUtilities;
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
|
import org.hl7.fhir.utilities.TextFile;
|
||||||
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer;
|
import org.hl7.fhir.utilities.i18n.LanguageFileProducer;
|
||||||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerLanguageSession;
|
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerLanguageSession;
|
||||||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TextUnit;
|
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TextUnit;
|
||||||
|
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TranslationUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* in here:
|
* in here:
|
||||||
|
@ -21,6 +30,7 @@ import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TextUnit;
|
||||||
public class LanguageUtils {
|
public class LanguageUtils {
|
||||||
|
|
||||||
IWorkerContext context;
|
IWorkerContext context;
|
||||||
|
private List<String> crlist;
|
||||||
|
|
||||||
|
|
||||||
public LanguageUtils(IWorkerContext context) {
|
public LanguageUtils(IWorkerContext context) {
|
||||||
|
@ -29,27 +39,150 @@ public class LanguageUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateTranslations(Element resource, LanguageProducerLanguageSession session) {
|
public void generateTranslations(Element resource, LanguageProducerLanguageSession session) {
|
||||||
translate(resource, session);
|
translate(null, resource, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void translate(Element element, LanguageProducerLanguageSession langSession) {
|
|
||||||
|
private void translate(Element parent, Element element, LanguageProducerLanguageSession langSession) {
|
||||||
if (element.isPrimitive() && isTranslatable(element)) {
|
if (element.isPrimitive() && isTranslatable(element)) {
|
||||||
String base = element.primitiveValue();
|
String base = element.primitiveValue();
|
||||||
if (base != null) {
|
if (base != null) {
|
||||||
String translation = element.getTranslation(langSession.getTargetLang());
|
String translation = getSpecialTranslation(parent, element, langSession.getTargetLang());
|
||||||
langSession.entry(new TextUnit(element.getPath(), base, translation));
|
if (translation == null) {
|
||||||
|
translation = element.getTranslation(langSession.getTargetLang());
|
||||||
|
}
|
||||||
|
langSession.entry(new TextUnit(pathForElement(element), base, translation));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Element c: element.getChildren()) {
|
for (Element c: element.getChildren()) {
|
||||||
translate(c, langSession);
|
if (!c.getName().equals("designation")) {
|
||||||
|
translate(element, c, langSession);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isTranslatable(Element element) {
|
|
||||||
return element.getProperty().isTranslatable();
|
private String getSpecialTranslation(Element parent, Element element, String targetLang) {
|
||||||
|
if (parent == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (Utilities.existsInList(pathForElement(parent), "CodeSystem.concept", "CodeSystem.concept.concept") && "CodeSystem.concept.display".equals(pathForElement(element))) {
|
||||||
|
return getDesignationTranslation(parent, targetLang);
|
||||||
|
}
|
||||||
|
if (Utilities.existsInList(pathForElement(parent), "ValueSet.compose.include.concept") && "ValueSet.compose.include.concept.display".equals(pathForElement(element))) {
|
||||||
|
return getDesignationTranslation(parent, targetLang);
|
||||||
|
}
|
||||||
|
if (Utilities.existsInList(pathForElement(parent), "ValueSet.expansion.contains", "ValueSet.expansion.contains.contains") && "ValueSet.expansion.contains.display".equals(pathForElement(element))) {
|
||||||
|
return getDesignationTranslation(parent, targetLang);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean matches(String dstLang, String srcLang) {
|
private String getDesignationTranslation(Element parent, String targetLang) {
|
||||||
|
for (Element e : parent.getChildren("designation")) {
|
||||||
|
String lang = e.getNamedChildValue("language");
|
||||||
|
if (langsMatch(targetLang, lang)) {
|
||||||
|
return e.getNamedChildValue("value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isTranslatable(Element element) {
|
||||||
|
return element.getProperty().isTranslatable() && !Utilities.existsInList(pathForElement(element), "CanonicalResource.version");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String pathForElement(Element element) {
|
||||||
|
// special case support for metadata elements prior to R5:
|
||||||
|
if (crlist == null) {
|
||||||
|
crlist = new ContextUtilities(context).getCanonicalResourceNames();
|
||||||
|
}
|
||||||
|
String bp = element.getBasePath();
|
||||||
|
if (crlist.contains(element.getProperty().getStructure().getType())) {
|
||||||
|
String fp = bp.replace(element.getProperty().getStructure().getType()+".", "CanonicalResource.");
|
||||||
|
if (Utilities.existsInList(fp,
|
||||||
|
"CanonicalResource.url", "CanonicalResource.identifier", "CanonicalResource.version", "CanonicalResource.name",
|
||||||
|
"CanonicalResource.title", "CanonicalResource.status", "CanonicalResource.experimental", "CanonicalResource.date",
|
||||||
|
"CanonicalResource.publisher", "CanonicalResource.contact", "CanonicalResource.description", "CanonicalResource.useContext",
|
||||||
|
"CanonicalResource.jurisdiction")) {
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int importFromTranslations(Element resource, Set<TranslationUnit> translations) {
|
||||||
|
return importFromTranslations(null, resource, translations);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int importFromTranslations(Element parent, Element element, Set<TranslationUnit> translations) {
|
||||||
|
int t = 0;
|
||||||
|
if (element.isPrimitive() && isTranslatable(element)) {
|
||||||
|
String base = element.primitiveValue();
|
||||||
|
if (base != null) {
|
||||||
|
Set<TranslationUnit> tlist = findTranslations(pathForElement(element), base, translations);
|
||||||
|
for (TranslationUnit translation : tlist) {
|
||||||
|
t++;
|
||||||
|
if (!handleAsSpecial(parent, element, translation)) {
|
||||||
|
element.setTranslation(translation.getLanguage(), translation.getTgtText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Element c: element.getChildren()) {
|
||||||
|
if (!c.getName().equals("designation")) {
|
||||||
|
t = t + importFromTranslations(element, c, translations);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean handleAsSpecial(Element parent, Element element, TranslationUnit translation) {
|
||||||
|
if (parent == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Utilities.existsInList(pathForElement(parent), "CodeSystem.concept", "CodeSystem.concept.concept") && "CodeSystem.concept.display".equals(pathForElement(element))) {
|
||||||
|
return setDesignationTranslation(parent, translation.getLanguage(), translation.getTgtText());
|
||||||
|
}
|
||||||
|
if (Utilities.existsInList(pathForElement(parent), "ValueSet.compose.include.concept") && "ValueSet.compose.include.concept.display".equals(pathForElement(element))) {
|
||||||
|
return setDesignationTranslation(parent, translation.getLanguage(), translation.getTgtText());
|
||||||
|
}
|
||||||
|
if (Utilities.existsInList(pathForElement(parent), "ValueSet.expansion.contains", "ValueSet.expansion.contains.contains") && "ValueSet.expansion.contains.display".equals(pathForElement(element))) {
|
||||||
|
return setDesignationTranslation(parent, translation.getLanguage(), translation.getTgtText());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean setDesignationTranslation(Element parent, String targetLang, String translation) {
|
||||||
|
for (Element e : parent.getChildren("designation")) {
|
||||||
|
String lang = e.getNamedChildValue("language");
|
||||||
|
if (langsMatch(targetLang, lang)) {
|
||||||
|
Element value = e.getNamedChild("value");
|
||||||
|
if (value != null) {
|
||||||
|
value.setValue(translation);
|
||||||
|
} else {
|
||||||
|
e.addElement("value").setValue(translation);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Element d = parent.addElement("designation");
|
||||||
|
d.addElement("language").setValue(targetLang);
|
||||||
|
d.addElement("value").setValue(translation);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<TranslationUnit> findTranslations(String path, String src, Set<TranslationUnit> translations) {
|
||||||
|
Set<TranslationUnit> res = new HashSet<>();
|
||||||
|
for (TranslationUnit translation : translations) {
|
||||||
|
if (path.equals(translation.getContext()) && src.equals(translation.getSrcText())) {
|
||||||
|
res.add(translation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean langsMatch(String dstLang, String srcLang) {
|
||||||
return dstLang == null ? false : dstLang.equals(srcLang);
|
return dstLang == null ? false : dstLang.equals(srcLang);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
package org.hl7.fhir.utilities.i18n;
|
package org.hl7.fhir.utilities.i18n;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TextUnit;
|
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TextUnit;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
@ -12,9 +17,9 @@ import java.util.HashMap;
|
||||||
public abstract class LanguageFileProducer {
|
public abstract class LanguageFileProducer {
|
||||||
|
|
||||||
public static class TextUnit {
|
public static class TextUnit {
|
||||||
private String context;
|
protected String context;
|
||||||
private String srcText;
|
protected String srcText;
|
||||||
private String tgtText;
|
protected String tgtText;
|
||||||
public TextUnit(String context, String srcText, String tgtText) {
|
public TextUnit(String context, String srcText, String tgtText) {
|
||||||
super();
|
super();
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
@ -32,8 +37,34 @@ public abstract class LanguageFileProducer {
|
||||||
public String getTgtText() {
|
public String getTgtText() {
|
||||||
return tgtText;
|
return tgtText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class TranslationUnit extends TextUnit {
|
||||||
|
private String language;
|
||||||
|
|
||||||
|
public TranslationUnit(String language, String context, String srcText, String tgtText) {
|
||||||
|
super(context, srcText, tgtText);
|
||||||
|
this.language = language;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLanguage() {
|
||||||
|
return language;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContext(String context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSrcText(String srcText) {
|
||||||
|
this.srcText = srcText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTgtText(String tgtText) {
|
||||||
|
this.tgtText = tgtText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class Translations {
|
public class Translations {
|
||||||
private String id;
|
private String id;
|
||||||
|
@ -98,6 +129,10 @@ public abstract class LanguageFileProducer {
|
||||||
this.folder = folder;
|
this.folder = folder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LanguageFileProducer() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
public String getFolder() {
|
public String getFolder() {
|
||||||
return folder;
|
return folder;
|
||||||
}
|
}
|
||||||
|
@ -105,7 +140,7 @@ public abstract class LanguageFileProducer {
|
||||||
public abstract LanguageProducerSession startSession(String id, String baseLang) throws IOException;
|
public abstract LanguageProducerSession startSession(String id, String baseLang) throws IOException;
|
||||||
public abstract void finish();
|
public abstract void finish();
|
||||||
|
|
||||||
public abstract List<TextUnit> loadTranslations(String id, String baseLang, String targetLang) throws IOException;
|
public abstract List<TranslationUnit> loadSource(InputStream source) throws IOException, ParserConfigurationException, SAXException;
|
||||||
|
|
||||||
public abstract int fileCount();
|
public abstract int fileCount();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package org.hl7.fhir.utilities.i18n;
|
package org.hl7.fhir.utilities.i18n;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
@ -9,6 +12,7 @@ import org.hl7.fhir.utilities.TextFile;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerLanguageSession;
|
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerLanguageSession;
|
||||||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerSession;
|
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerSession;
|
||||||
|
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TranslationUnit;
|
||||||
import org.hl7.fhir.utilities.i18n.PoGetTextProducer.POGetTextLanguageProducerLanguageSession;
|
import org.hl7.fhir.utilities.i18n.PoGetTextProducer.POGetTextLanguageProducerLanguageSession;
|
||||||
import org.hl7.fhir.utilities.i18n.PoGetTextProducer.POGetTextProducerSession;
|
import org.hl7.fhir.utilities.i18n.PoGetTextProducer.POGetTextProducerSession;
|
||||||
import org.hl7.fhir.utilities.i18n.XLIFFProducer.XLiffLanguageProducerLanguageSession;
|
import org.hl7.fhir.utilities.i18n.XLIFFProducer.XLiffLanguageProducerLanguageSession;
|
||||||
|
@ -21,6 +25,10 @@ public class PoGetTextProducer extends LanguageFileProducer {
|
||||||
super(folder);
|
super(folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PoGetTextProducer() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LanguageProducerSession startSession(String id, String baseLang) throws IOException {
|
public LanguageProducerSession startSession(String id, String baseLang) throws IOException {
|
||||||
return new POGetTextProducerSession(id, baseLang);
|
return new POGetTextProducerSession(id, baseLang);
|
||||||
|
@ -90,13 +98,49 @@ public class PoGetTextProducer extends LanguageFileProducer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<TextUnit> loadTranslations(String id, String baseLang, String targetLang) throws IOException {
|
public List<TranslationUnit> loadSource(InputStream source) throws IOException {
|
||||||
List<TextUnit> res = new ArrayList<>();
|
List<TranslationUnit> list = new ArrayList<>();
|
||||||
File f = new File(getFileName(id, baseLang, targetLang));
|
InputStreamReader r = new InputStreamReader(source, "UTF-8"); // leave charset out for default
|
||||||
if (f.exists()) {
|
BufferedReader br = new BufferedReader(r);
|
||||||
|
String lang = null;
|
||||||
|
String s;
|
||||||
|
TranslationUnit tu = null;
|
||||||
|
while ((s = Utilities.stripBOM(br.readLine())) != null) {
|
||||||
|
if (!Utilities.noString(s)) {
|
||||||
|
if (s.trim().startsWith("#")) {
|
||||||
|
if (lang == null) {
|
||||||
|
String[] p = s.substring(1).trim().split("\\-\\>");
|
||||||
|
if (p.length != 2) {
|
||||||
|
throw new IOException("Encountered unexpected starting line '"+s+"'");
|
||||||
|
} else {
|
||||||
|
lang = p[1].trim();
|
||||||
|
}
|
||||||
|
} else if (s.startsWith("#:")) {
|
||||||
|
tu = new TranslationUnit(lang, s.substring(2).trim(), null, null);
|
||||||
|
} else {
|
||||||
|
throw new IOException("Encountered unexpected line '"+s+"'");
|
||||||
|
}
|
||||||
|
} else if (tu != null && s.startsWith("msgid ")) {
|
||||||
|
tu.setSrcText(stripQuotes(s.substring(5).trim()));
|
||||||
|
} else if (tu != null && s.startsWith("msgstr ")) {
|
||||||
|
tu.setTgtText(stripQuotes(s.substring(6).trim()));
|
||||||
|
if (tu.getTgtText() != null) {
|
||||||
|
list.add(tu);
|
||||||
|
}
|
||||||
|
tu = null;
|
||||||
|
} else {
|
||||||
|
throw new IOException("Encountered unexpected line '"+s+"'");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String stripQuotes(String s) {
|
||||||
|
if (s.length() <= 2) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return s.substring(1, s.length()-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getFileName(String id, String baseLang, String targetLang) throws IOException {
|
private String getFileName(String id, String baseLang, String targetLang) throws IOException {
|
||||||
|
|
|
@ -1,11 +1,20 @@
|
||||||
package org.hl7.fhir.utilities.i18n;
|
package org.hl7.fhir.utilities.i18n;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
import org.hl7.fhir.utilities.TextFile;
|
import org.hl7.fhir.utilities.TextFile;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TextUnit;
|
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TextUnit;
|
||||||
|
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TranslationUnit;
|
||||||
|
import org.hl7.fhir.utilities.xml.XMLUtil;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
public class XLIFFProducer extends LanguageFileProducer {
|
public class XLIFFProducer extends LanguageFileProducer {
|
||||||
|
|
||||||
|
@ -77,6 +86,10 @@ public class XLIFFProducer extends LanguageFileProducer {
|
||||||
super(folder);
|
super(folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public XLIFFProducer() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LanguageProducerSession startSession(String id, String baseLang) throws IOException {
|
public LanguageProducerSession startSession(String id, String baseLang) throws IOException {
|
||||||
return new XLiffLanguageProducerSession(id, baseLang);
|
return new XLiffLanguageProducerSession(id, baseLang);
|
||||||
|
@ -88,8 +101,31 @@ public class XLIFFProducer extends LanguageFileProducer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<TextUnit> loadTranslations(String id, String baseLang, String tgtLang) {
|
public List<TranslationUnit> loadSource(InputStream source) throws IOException, ParserConfigurationException, SAXException {
|
||||||
return null;
|
List<TranslationUnit> list = new ArrayList<>();
|
||||||
|
Document dom = XMLUtil.parseToDom(TextFile.streamToBytes(source));
|
||||||
|
Element xliff = dom.getDocumentElement();
|
||||||
|
if (!xliff.getNodeName().equals("xliff")) {
|
||||||
|
throw new IOException("Not an XLIFF document");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Element file : XMLUtil.getNamedChildren(xliff, "file")) {
|
||||||
|
Element body = XMLUtil.getNamedChild(file, "body");
|
||||||
|
for (Element transUnit : XMLUtil.getNamedChildren(body, "trans-unit")) {
|
||||||
|
TranslationUnit tu = new TranslationUnit(file.getAttribute("target-language"), transUnit.getAttribute("id"),
|
||||||
|
XMLUtil.getNamedChildText(transUnit, "source"), XMLUtil.getNamedChildText(transUnit, "target"));
|
||||||
|
if (!Utilities.noString(tu.getSrcText()) && !Utilities.noString(tu.getTgtText())) {
|
||||||
|
list.add(tu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void check(String string, boolean equals) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -94,6 +94,8 @@ public class CliContext {
|
||||||
private List<String> profiles = new ArrayList<String>();
|
private List<String> profiles = new ArrayList<String>();
|
||||||
@JsonProperty("sources")
|
@JsonProperty("sources")
|
||||||
private List<String> sources = new ArrayList<String>();
|
private List<String> sources = new ArrayList<String>();
|
||||||
|
@JsonProperty("inputs")
|
||||||
|
private List<String> inputs = new ArrayList<String>();
|
||||||
|
|
||||||
@JsonProperty("mode")
|
@JsonProperty("mode")
|
||||||
private EngineMode mode = EngineMode.VALIDATION;
|
private EngineMode mode = EngineMode.VALIDATION;
|
||||||
|
@ -389,6 +391,11 @@ public class CliContext {
|
||||||
return sources;
|
return sources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonProperty("inputs")
|
||||||
|
public List<String> getInputs() {
|
||||||
|
return inputs;
|
||||||
|
}
|
||||||
|
|
||||||
@JsonProperty("sources")
|
@JsonProperty("sources")
|
||||||
public CliContext setSources(List<String> sources) {
|
public CliContext setSources(List<String> sources) {
|
||||||
this.sources = sources;
|
this.sources = sources;
|
||||||
|
@ -721,7 +728,7 @@ public class CliContext {
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(doNative, extensions, hintAboutNonMustSupport, recursive, doDebug, assumeValidRestReferences, canDoNative, noInternalCaching,
|
return Objects.hash(doNative, extensions, hintAboutNonMustSupport, recursive, doDebug, assumeValidRestReferences, canDoNative, noInternalCaching,
|
||||||
noExtensibleBindingMessages, noInvariants, wantInvariantsInMessages, map, output, outputSuffix, htmlOutput, txServer, sv, txLog, txCache, mapLog, lang, srcLang, tgtLang, fhirpath, snomedCT,
|
noExtensibleBindingMessages, noInvariants, wantInvariantsInMessages, map, output, outputSuffix, htmlOutput, txServer, sv, txLog, txCache, mapLog, lang, srcLang, tgtLang, fhirpath, snomedCT,
|
||||||
targetVer, igs, questionnaireMode, level, profiles, sources, mode, locale, locations, crumbTrails, forPublication, showTimes, allowExampleUrls, outputStyle, jurisdiction, noUnicodeBiDiControlChars);
|
targetVer, igs, questionnaireMode, level, profiles, sources, inputs, mode, locale, locations, crumbTrails, forPublication, showTimes, allowExampleUrls, outputStyle, jurisdiction, noUnicodeBiDiControlChars);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -759,6 +766,7 @@ public class CliContext {
|
||||||
", level=" + level +
|
", level=" + level +
|
||||||
", profiles=" + profiles +
|
", profiles=" + profiles +
|
||||||
", sources=" + sources +
|
", sources=" + sources +
|
||||||
|
", inputs=" + inputs +
|
||||||
", mode=" + mode +
|
", mode=" + mode +
|
||||||
", securityChecks=" + securityChecks +
|
", securityChecks=" + securityChecks +
|
||||||
", crumbTrails=" + crumbTrails +
|
", crumbTrails=" + crumbTrails +
|
||||||
|
|
|
@ -12,10 +12,13 @@ import java.net.URISyntaxException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
|
import org.hl7.fhir.r4b.model.AdministrableProductDefinition;
|
||||||
import org.hl7.fhir.r5.conformance.R5ExtensionsLoader;
|
import org.hl7.fhir.r5.conformance.R5ExtensionsLoader;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
||||||
import org.hl7.fhir.r5.context.ContextUtilities;
|
import org.hl7.fhir.r5.context.ContextUtilities;
|
||||||
|
@ -27,6 +30,7 @@ import org.hl7.fhir.r5.elementmodel.LanguageUtils;
|
||||||
import org.hl7.fhir.r5.elementmodel.Manager;
|
import org.hl7.fhir.r5.elementmodel.Manager;
|
||||||
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
|
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
|
||||||
import org.hl7.fhir.r5.formats.IParser;
|
import org.hl7.fhir.r5.formats.IParser;
|
||||||
|
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||||
import org.hl7.fhir.r5.model.Bundle;
|
import org.hl7.fhir.r5.model.Bundle;
|
||||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||||
import org.hl7.fhir.r5.model.CodeSystem;
|
import org.hl7.fhir.r5.model.CodeSystem;
|
||||||
|
@ -50,6 +54,7 @@ import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.VersionUtilities;
|
import org.hl7.fhir.utilities.VersionUtilities;
|
||||||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerLanguageSession;
|
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerLanguageSession;
|
||||||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerSession;
|
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerSession;
|
||||||
|
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TranslationUnit;
|
||||||
import org.hl7.fhir.utilities.i18n.PoGetTextProducer;
|
import org.hl7.fhir.utilities.i18n.PoGetTextProducer;
|
||||||
import org.hl7.fhir.utilities.i18n.XLIFFProducer;
|
import org.hl7.fhir.utilities.i18n.XLIFFProducer;
|
||||||
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
||||||
|
@ -530,6 +535,9 @@ public class ValidationService {
|
||||||
case "extract":
|
case "extract":
|
||||||
transformLangExtract(cliContext, validator);
|
transformLangExtract(cliContext, validator);
|
||||||
break;
|
break;
|
||||||
|
case "inject":
|
||||||
|
transformLangInject(cliContext, validator);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
System.out.println(" ...Unknown lang transform mode "+cliContext.getLangTransform());
|
System.out.println(" ...Unknown lang transform mode "+cliContext.getLangTransform());
|
||||||
}
|
}
|
||||||
|
@ -560,86 +568,67 @@ public class ValidationService {
|
||||||
}
|
}
|
||||||
System.out.println("Done - produced "+(po.fileCount()+xliff.fileCount()) + " files in "+dst);
|
System.out.println("Done - produced "+(po.fileCount()+xliff.fileCount()) + " files in "+dst);
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// try {
|
private void transformLangInject(CliContext cliContext, ValidationEngine validator) throws IOException {
|
||||||
// OperationOutcome outcome = validate(ref, cnt.focus, cnt.cntType, profiles, record);
|
String dst = cliContext.getOutput();
|
||||||
// ToolingExtensions.addStringExtension(outcome, ToolingExtensions.EXT_OO_FILE, ref);
|
Utilities.createDirectory(dst);
|
||||||
// System.out.println(" " + context.clock().milestone());
|
|
||||||
// results.addEntry().setResource(outcome);
|
Set<TranslationUnit> translations = new HashSet<>();
|
||||||
// tts.end();
|
for (String input : cliContext.getInputs()) {
|
||||||
// } catch (Exception e) {
|
loadTranslationSource(translations, input);
|
||||||
// System.out.println("Validation Infrastructure fail validating " + ref + ": " + e.getMessage());
|
}
|
||||||
// tts.end();
|
|
||||||
// throw new FHIRException(e);
|
List<String> refs = new ArrayList<String>();
|
||||||
// }
|
ValidatorUtils.parseSources(cliContext.getSources(), refs, validator.getContext());
|
||||||
// }
|
int t = 0;
|
||||||
// if (asBundle)
|
for (String ref : refs) {
|
||||||
// return results;
|
System.out.println(" Inject Translations into " + ref);
|
||||||
// else
|
org.hl7.fhir.validation.Content cnt = validator.getIgLoader().loadContent(ref, "translate", false);
|
||||||
// return results.getEntryFirstRep().getResource();
|
Element e = Manager.parseSingle(validator.getContext(), new ByteArrayInputStream(cnt.getFocus()), cnt.getCntType());
|
||||||
//
|
t = t + new LanguageUtils(validator.getContext()).importFromTranslations(e, translations);
|
||||||
// List<ValidationRecord> records = new ArrayList<>();
|
Manager.compose(validator.getContext(), e, new FileOutputStream(Utilities.path(dst, new File(ref).getName())), cnt.getCntType(),
|
||||||
// Resource r = validator.validate(cliContext.getSources(), cliContext.getProfiles(), records);
|
OutputStyle.PRETTY, null);
|
||||||
// MemoryMXBean mbean = ManagementFactory.getMemoryMXBean();
|
}
|
||||||
// System.out.println("Done. " + validator.getContext().clock().report()+". Memory = "+Utilities.describeSize(mbean.getHeapMemoryUsage().getUsed()+mbean.getNonHeapMemoryUsage().getUsed()));
|
System.out.println("Done - imported "+t+" translations into "+refs.size()+ " in "+dst);
|
||||||
// System.out.println();
|
}
|
||||||
//
|
|
||||||
// PrintStream dst = null;
|
private void loadTranslationSource(Set<TranslationUnit> translations, String input) {
|
||||||
// ValidationOutputRenderer renderer = makeValidationOutputRenderer(cliContext);
|
File f = new File(input);
|
||||||
// renderer.setCrumbTrails(validator.isCrumbTrails());
|
if (f.exists()) {
|
||||||
// renderer.setRunDate(runDate);
|
if (f.isDirectory()) {
|
||||||
// if (renderer.isSingleFile()) {
|
for (File fd : f.listFiles()) {
|
||||||
// if (cliContext.getOutput() == null) {
|
loadTranslationSource(translations, fd.getAbsolutePath());
|
||||||
// dst = System.out;
|
}
|
||||||
// } else {
|
} else {
|
||||||
// dst = new PrintStream(new FileOutputStream(cliContext.getOutput()));
|
if (f.getName().endsWith(".po")) {
|
||||||
// }
|
try {
|
||||||
// renderer.setOutput(dst);
|
translations.addAll(new PoGetTextProducer().loadSource(new FileInputStream(f)));
|
||||||
// } else {
|
} catch (Exception e) {
|
||||||
// File dir = new File(cliContext.getOutput());
|
System.out.println("Error reading PO File "+f.getAbsolutePath()+": "+e.getMessage());
|
||||||
// if (!dir.isDirectory()) {
|
}
|
||||||
// throw new Error("The output location "+dir.getAbsolutePath()+" must be an existing directory for the output style "+renderer.getStyleCode());
|
} else if (f.getName().endsWith(".xliff")) {
|
||||||
// }
|
try {
|
||||||
// renderer.setFolder(dir);
|
translations.addAll(new XLIFFProducer().loadSource(new FileInputStream(f)));
|
||||||
// }
|
} catch (Exception e) {
|
||||||
//
|
System.out.println("Error reading XLIFF File "+f.getAbsolutePath()+": "+e.getMessage());
|
||||||
// int ec = 0;
|
}
|
||||||
//
|
} else {
|
||||||
// if (r instanceof Bundle) {
|
try {
|
||||||
// if (renderer.handlesBundleDirectly()) {
|
translations.addAll(new PoGetTextProducer().loadSource(new FileInputStream(f)));
|
||||||
// renderer.render((Bundle) r);
|
} catch (Exception e) {
|
||||||
// } else {
|
try {
|
||||||
// renderer.start(((Bundle) r).getEntry().size() > 1);
|
translations.addAll(new XLIFFProducer().loadSource(new FileInputStream(f)));
|
||||||
// for (Bundle.BundleEntryComponent e : ((Bundle) r).getEntry()) {
|
} catch (Exception e2) {
|
||||||
// OperationOutcome op = (OperationOutcome) e.getResource();
|
System.out.println("Error reading File "+f.getAbsolutePath()+" as XLIFF: "+e2.getMessage());
|
||||||
// ec = ec + countErrors(op);
|
System.out.println("Error reading File "+f.getAbsolutePath()+" as PO: "+e.getMessage());
|
||||||
// renderer.render(op);
|
}
|
||||||
// }
|
}
|
||||||
// renderer.finish();
|
}
|
||||||
// }
|
}
|
||||||
// } else if (r == null) {
|
} else {
|
||||||
// ec = ec + 1;
|
System.out.println("Input not found: "+input);
|
||||||
// System.out.println("No output from validation - nothing to validate");
|
}
|
||||||
// } else {
|
}
|
||||||
// renderer.start(false);
|
|
||||||
// OperationOutcome op = (OperationOutcome) r;
|
|
||||||
// ec = countErrors(op);
|
|
||||||
// renderer.render((OperationOutcome) r);
|
|
||||||
// renderer.finish();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (cliContext.getOutput() != null && dst != null) {
|
|
||||||
// dst.close();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (cliContext.getHtmlOutput() != null) {
|
|
||||||
// String html = new HTMLOutputGenerator(records).generate(System.currentTimeMillis() - start);
|
|
||||||
// TextFile.stringToFile(html, cliContext.getHtmlOutput());
|
|
||||||
// System.out.println("HTML Summary in " + cliContext.getHtmlOutput());
|
|
||||||
// }
|
|
||||||
// System.exit(ec > 0 ? 1 : 0);
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
private int cp;
|
private int cp;
|
||||||
private int cs;
|
private int cs;
|
||||||
|
|
|
@ -92,6 +92,7 @@ public class Params {
|
||||||
public static final String SPECIAL = "-special";
|
public static final String SPECIAL = "-special";
|
||||||
public static final String TARGET = "-target";
|
public static final String TARGET = "-target";
|
||||||
public static final String SOURCE = "-source";
|
public static final String SOURCE = "-source";
|
||||||
|
public static final String INPUT = "-input";
|
||||||
public static final String FILTER = "-filter";
|
public static final String FILTER = "-filter";
|
||||||
private static final String FHIR_SETTINGS_PARAM = "-fhir-settings";
|
private static final String FHIR_SETTINGS_PARAM = "-fhir-settings";
|
||||||
|
|
||||||
|
@ -158,8 +159,7 @@ public class Params {
|
||||||
i++;
|
i++;
|
||||||
} else if (args[i].equals(HTTPS_PROXY)) {
|
} else if (args[i].equals(HTTPS_PROXY)) {
|
||||||
i++;
|
i++;
|
||||||
}
|
} else if (args[i].equals(PROFILE)) {
|
||||||
else if (args[i].equals(PROFILE)) {
|
|
||||||
String p = null;
|
String p = null;
|
||||||
if (i + 1 == args.length) {
|
if (i + 1 == args.length) {
|
||||||
throw new Error("Specified -profile without indicating profile source");
|
throw new Error("Specified -profile without indicating profile source");
|
||||||
|
@ -195,6 +195,13 @@ public class Params {
|
||||||
String q = args[++i];
|
String q = args[++i];
|
||||||
cliContext.setLevel(ValidationLevel.fromCode(q));
|
cliContext.setLevel(ValidationLevel.fromCode(q));
|
||||||
}
|
}
|
||||||
|
} else if (args[i].equals(INPUT)) {
|
||||||
|
if (i + 1 == args.length)
|
||||||
|
throw new Error("Specified -input without providing value");
|
||||||
|
else {
|
||||||
|
String inp = args[++i];
|
||||||
|
cliContext.getInputs().add(inp);
|
||||||
|
}
|
||||||
} else if (args[i].equals(NATIVE)) {
|
} else if (args[i].equals(NATIVE)) {
|
||||||
cliContext.setDoNative(true);
|
cliContext.setDoNative(true);
|
||||||
} else if (args[i].equals(ASSUME_VALID_REST_REF)) {
|
} else if (args[i].equals(ASSUME_VALID_REST_REF)) {
|
||||||
|
|
Loading…
Reference in New Issue