language translations support in validator

This commit is contained in:
Grahame Grieve 2023-04-25 21:51:31 +10:00
parent b6b4fbcd0c
commit 3ed7813973
8 changed files with 411 additions and 104 deletions

View File

@ -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);
}
} }

View File

@ -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);
} }
} }

View File

@ -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();
} }

View File

@ -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 {

View File

@ -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

View File

@ -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 +

View File

@ -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;

View File

@ -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)) {