Merge pull request #1196 from hapifhir/gg-202303-r5-lang-one

Gg 202303 r5 lang one
This commit is contained in:
Grahame Grieve 2023-03-30 10:16:03 +11:00 committed by GitHub
commit d9cee4b221
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 262 additions and 101 deletions

View File

@ -338,9 +338,9 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
}
public void registerResourceFromPackage(CanonicalResourceProxy r, PackageInformation packageInfo) throws FHIRException {
public void registerResourceFromPackage(CanonicalResourceProxy r, PackageInformation packageInfo) throws FHIRException {
PackageHackerR5.fixLoadedResource(r, packageInfo);
synchronized (lock) {
if (packageInfo != null) {
packages.put(packageInfo.getVID(), packageInfo);

View File

@ -57,6 +57,7 @@ import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
import org.hl7.fhir.r5.model.TypeConvertor;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.utilities.ElementDecoration;
import org.hl7.fhir.utilities.ElementDecoration.DecorationType;
import org.hl7.fhir.utilities.SourceLocation;
@ -1424,4 +1425,30 @@ public class Element extends Base {
}
this.webPath = webPath;
}
public String getTranslation(String lang) {
for (Element e : getChildren()) {
if (e.fhirType().equals("Extension")) {
String url = e.getNamedChildValue("url");
if (ToolingExtensions.EXT_TRANSLATION.equals(url)) {
String l = null;
String 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.getNamedChildValue("value");
}
}
}
if (lang.equals(l)) {
return v;
}
}
}
}
return null;
}
}

View File

@ -126,7 +126,9 @@ public abstract class ParserBase {
public Element parseSingle(InputStream stream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
List<NamedElement> res = parse(stream);
if (res.size() == 0) {
if (res == null) {
throw new FHIRException("Parsing FHIR content failed: "+errors.get(0).summary());
} else if (res.size() == 0) {
throw new FHIRException("Parsing FHIR content returned no elements in a context where one element is required");
}
if (res.size() != 1) {

View File

@ -598,5 +598,10 @@ public class Property {
return definition.hasExtension(ToolingExtensions.EXT_JSON_NAME);
}
public boolean isTranslatable() {
return ToolingExtensions.readBoolExtension(definition, ToolingExtensions.EXT_TRANSLATABLE);
}
}

View File

@ -97,7 +97,6 @@ public class TestingUtilities extends BaseTestingUtilities {
System.out.println("Loading Extensions: "+ext.name()+"#"+ext.version());
fcontext.loadFromPackage(ext, new TestPackageLoader(Utilities.strings("CodeSystem", "ValueSet", "StructureDefinition")));
}
R5Hacker.fixR5BrokenResources(fcontext);
return fcontext;
} catch (Exception e) {
e.printStackTrace();

View File

@ -13,18 +13,20 @@ import org.hl7.fhir.r5.model.Property;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.utilities.i18n.LanguageFileProducer;
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerLanguageSession;
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerSession;
public class ResourceLanguageFileBuilder {
private LanguageFileProducer file;
private LanguageFileProducer lp;
private String source;
private String target;
private IWorkerContext context;
StructureDefinition profile = null;
public void prepare(LanguageFileProducer file, IWorkerContext context, String source, String target) {
this.file = file;
public void prepare(LanguageFileProducer lp, IWorkerContext context, String source, String target) {
this.lp = lp;
this.source = source;
this.target = target;
this.context = context;
@ -53,17 +55,19 @@ public class ResourceLanguageFileBuilder {
throw new FHIRException("profile");
}
}
file.start(path, path, res.getWebPath(), source, target);
LanguageProducerSession session = lp.startSession(path,source);
LanguageProducerLanguageSession langSession = session.forLang(target);
for (Property p : res.children()) {
process(p, id, path);
process(langSession, p, id, path);
}
file.finish();
langSession.finish();
session.finish();
}
private void process(Property p, String id, String path) throws IOException {
private void process(LanguageProducerLanguageSession sess, Property p, String id, String path) throws IOException {
if (p.hasValues()) {
int i = 0;
for (Base b : p.getValues()) {
@ -71,10 +75,10 @@ public class ResourceLanguageFileBuilder {
String ppath = path+"."+p.getName()+(p.isList() ? "["+i+"]" : "");
i++;
if (isTranslatable(p, b, pid)) {
file.makeEntry(ppath, null, null, b.primitiveValue(), getTranslation(b, target));
sess.entry(ppath, b.primitiveValue(), getTranslation(b, target));
}
for (Property pp : b.children()) {
process(pp, pid, ppath);
process(sess, pp, pid, ppath);
}
}
}

View File

@ -1,12 +1,12 @@
package org.hl7.fhir.utilities.i18n;
import com.ibm.icu.text.PluralRules;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.Objects;
import java.util.ResourceBundle;
import com.ibm.icu.text.PluralRules;
/**
* Handles the locale, ResourceBundle and String formatting for i18n

View File

@ -4,6 +4,46 @@ import java.io.IOException;
public abstract class LanguageFileProducer {
public abstract class LanguageProducerLanguageSession {
protected String id;
protected String baseLang;
protected String targetLang;
protected LanguageProducerLanguageSession(String id, String baseLang, String targetLang) {
super();
this.id = id;
this.baseLang = baseLang;
this.targetLang = targetLang;
}
public String getTargetLang() {
return targetLang;
}
public String getBaseLang() {
return baseLang;
}
public abstract void finish() throws IOException;
public abstract void entry(String id, String src, String dst);
}
public abstract class LanguageProducerSession {
protected String id;
protected String baseLang;
protected LanguageProducerSession( String id, String baseLang) {
super();
this.id = id;
this.baseLang = baseLang;
}
public abstract LanguageProducerLanguageSession forLang(String lang);
public abstract void finish() throws IOException;
}
private String folder;
public LanguageFileProducer(String folder) {
@ -15,8 +55,7 @@ public abstract class LanguageFileProducer {
return folder;
}
public abstract void start(String fileName, String contextId, String contextDesc, String baseLang, String targetLang) throws IOException;
public abstract void makeEntry(String id, String ref, String context, String source, String dest) throws IOException;
public abstract void finish() throws IOException;
public abstract LanguageProducerSession startSession(String id, String baseLang) throws IOException;
public abstract void finish();
}

View File

@ -3,42 +3,84 @@ package org.hl7.fhir.utilities.i18n;
import java.io.IOException;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerLanguageSession;
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerSession;
import org.hl7.fhir.utilities.i18n.PoGetTextProducer.POGetTextLanguageProducerLanguageSession;
import org.hl7.fhir.utilities.i18n.PoGetTextProducer.POGetTextProducerSession;
import org.hl7.fhir.utilities.i18n.XLIFFProducer.XLiffLanguageProducerLanguageSession;
public class PoGetTextProducer extends LanguageFileProducer {
public PoGetTextProducer(String folder) {
super(folder);
}
private String fileName;
private StringBuilder po;
int i = 0;
@Override
public void start(String fileName, String contextId, String contextDesc, String baseLang, String targetLang) {
this.fileName = fileName;
po = new StringBuilder();
public LanguageProducerSession startSession(String id, String baseLang) throws IOException {
return new POGetTextProducerSession(id, baseLang);
}
@Override
public void makeEntry(String id, String ref, String context, String source, String target) {
ln("#: "+id);
if (context != null) {
ln("#. "+context);
public void finish() {
// nothing
}
public class POGetTextProducerSession extends LanguageProducerSession {
public POGetTextProducerSession(String id, String baseLang) {
super (id, baseLang);
}
ln("msgid \""+source+"\"");
ln("msgstr \""+target+"\"");
ln("");
@Override
public LanguageProducerLanguageSession forLang(String targetLang) {
return new POGetTextLanguageProducerLanguageSession(id, baseLang, targetLang);
}
@Override
public void finish() throws IOException {
// nothing
}
}
@Override
public void finish() throws IOException {
ln("");
TextFile.stringToFile(po.toString(), fileName);
public class POGetTextLanguageProducerLanguageSession extends LanguageProducerLanguageSession {
private StringBuilder po;
public POGetTextLanguageProducerLanguageSession(String id, String baseLang, String targetLang) {
super(id, baseLang, targetLang);
po = new StringBuilder();
ln("<?xml version=\"1.0\" ?>\r\n");
ln("<xliff xmlns=\"urn:oasis:names:tc:xliff:document:2.0\" version=\"2.0\">");
ln(" <file source-language=\""+baseLang+"\" target-language=\""+targetLang+"\" id=\""+id+"\" original=\"Resource "+id+"\" datatype=\"KEYVALUEJSON\">");
ln(" <body>");
}
protected void ln(String line) {
po.append(line+"\r\n");
}
@Override
public void finish() throws IOException {
ln("");
TextFile.stringToFile(po.toString(), Utilities.path(getFolder(), id+"-"+baseLang+"-"+targetLang+".po"));
}
@Override
public void entry(String id, String src, String dst) {
ln("#: "+id);
// if (context != null) {
// ln("#. "+context);
// }
ln("msgid \""+src+"\"");
ln("msgstr \""+dst+"\"");
ln("");
}
}
protected void ln(String line) {
po.append(line+"\r\n");
}
}

View File

@ -7,48 +7,78 @@ import org.hl7.fhir.utilities.Utilities;
public class XLIFFProducer extends LanguageFileProducer {
public class XLiffLanguageProducerLanguageSession extends LanguageProducerLanguageSession {
private StringBuilder xml;
int i = 0;
public XLiffLanguageProducerLanguageSession(String id, String baseLang, String targetLang) {
super(id, baseLang, targetLang);
xml = new StringBuilder();
ln("<?xml version=\"1.0\" ?>\r\n");
ln("<xliff xmlns=\"urn:oasis:names:tc:xliff:document:2.0\" version=\"2.0\">");
ln(" <file source-language=\""+baseLang+"\" target-language=\""+targetLang+"\" id=\""+id+"\" original=\"Resource "+id+"\" datatype=\"KEYVALUEJSON\">");
ln(" <body>");
}
protected void ln(String line) {
xml.append(line+"\r\n");
}
@Override
public void finish() throws IOException {
ln(" </body>");
ln(" </file>");
ln("</xliff>");
TextFile.stringToFile(xml.toString(), Utilities.path(getFolder(), id+".xliff"));
}
@Override
public void entry(String id, String src, String dst) {
i++;
ln(" <trans-unit id=\""+id+"\" resname=\""+this.id+"\">");
// if (context != null) {
// ln(" <notes>");
// ln(" <note id=\"n"+i+"\">"+Utilities.escapeXml(context)+"</note>");
// ln(" </notes>");
// }
ln(" <source>"+Utilities.escapeXml(src)+"</source>");
ln(" <target>"+Utilities.escapeXml(dst)+"</target>");
ln(" </trans-unit>");
}
}
public class XLiffLanguageProducerSession extends LanguageProducerSession {
public XLiffLanguageProducerSession(String id, String baseLang) {
super (id, baseLang);
}
@Override
public LanguageProducerLanguageSession forLang(String targetLang) {
return new XLiffLanguageProducerLanguageSession(id, baseLang, targetLang);
}
@Override
public void finish() throws IOException {
// nothing
}
}
public XLIFFProducer(String folder) {
super(folder);
}
private String fileName;
private StringBuilder xml;
int i = 0;
@Override
public void start(String fileName, String contextId, String contextDesc, String baseLang, String targetLang) {
this.fileName = fileName;
xml = new StringBuilder();
ln("<?xml version=\"1.0\" ?>\r\n");
ln("<xliff xmlns=\"urn:oasis:names:tc:xliff:document:2.0\" version=\"2.0\">");
ln(" <file source-language=\""+baseLang+"\" target-language=\""+targetLang+"\" id=\""+contextId+"\" original=\""+contextDesc+"\" datatype=\"KEYVALUEJSON\">");
ln(" <body>");
public LanguageProducerSession startSession(String id, String baseLang) throws IOException {
return new XLiffLanguageProducerSession(id, baseLang);
}
@Override
public void makeEntry(String id, String ref, String context, String source, String target) {
i++;
ln(" <trans-unit id=\""+id+"\" resname=\""+ref+"\">");
if (context != null) {
ln(" <notes>");
ln(" <note id=\"n"+i+"\">"+Utilities.escapeXml(context)+"</note>");
ln(" </notes>");
}
ln(" <source>"+Utilities.escapeXml(source)+"</source>");
ln(" <target>"+Utilities.escapeXml(target)+"</target>");
ln(" </trans-unit>");
}
@Override
public void finish() throws IOException {
ln(" </body>");
ln(" </file>");
ln("</xliff>");
TextFile.stringToFile(xml.toString(), Utilities.path(getFolder(), fileName+".xliff"));
}
protected void ln(String line) {
xml.append(line+"\r\n");
public void finish() {
// nothing
}
}

View File

@ -11,7 +11,9 @@ import java.io.InputStream;
import java.net.MalformedURLException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@ -21,6 +23,7 @@ import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.NotImplementedException;
import org.hl7.fhir.utilities.*;
import org.hl7.fhir.utilities.tests.CacheVerificationLogger;
import org.hl7.fhir.validation.tests.ValidationTests.TestSorter;
import org.hl7.fhir.validation.tests.utilities.TestUtilities;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_14_50;
@ -93,6 +96,15 @@ import com.google.gson.JsonObject;
@RunWith(Parameterized.class)
public class ValidationTests implements IEvaluationContext, IValidatorResourceFetcher, IValidationPolicyAdvisor {
public class TestSorter implements Comparator<Object> {
@Override
public int compare(Object o1, Object o2) {
return 0;
}
}
public final static boolean PRINT_OUTPUT_TO_CONSOLE = true;
private static final boolean BUILD_NEW = false;
private static final boolean CLONE = true;
@ -105,7 +117,12 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
manifest = (JsonObject) new com.google.gson.JsonParser().parse(contents);
for (JsonElement e : manifest.getAsJsonArray("test-cases")) {
JsonObject o = (JsonObject) e;
examples.put(JsonUtilities.str(o, "name"), o);
String name = JsonUtilities.str(o, "name");
String version = JsonUtilities.str(o, "version");
if (version == null) {
version = "5.0.0";
}
examples.put(VersionUtilities.getNameForVersion(version)+"."+name, o);
}
List<String> names = new ArrayList<String>(examples.size());
@ -124,10 +141,10 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
private String version;
private String name;
private static Map<String, ValidationEngine> ve = new HashMap<>();
private static ValidationEngine vCurr;
private static ValidationEngine currentEngine;
private ValidationEngine vCurr;
private static String currentVersion;
private static IgLoader igLoader;
public ValidationTests(String name, JsonObject content) {
@ -137,7 +154,7 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
@AfterAll
public void cleanup() {
ve = null;
currentEngine = null;
vCurr = null;
igLoader = null;
manifest = null;
@ -165,29 +182,13 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
}
version = VersionUtilities.getMajMin(version);
if (!ve.containsKey(version)) {
if (version.startsWith("5.0"))
ve.put(version, TestUtilities.getValidationEngine("hl7.fhir.r5.core#5.0.0", ValidationEngineTests.DEF_TX, txLog, FhirPublication.R5, true, "5.0.0"));
else if (version.startsWith("4.3"))
ve.put(version, TestUtilities.getValidationEngine("hl7.fhir.r4b.core#4.3.0", ValidationEngineTests.DEF_TX, txLog, FhirPublication.R4B, true, "4.3.0"));
else if (version.startsWith("4.0"))
ve.put(version, TestUtilities.getValidationEngine("hl7.fhir.r4.core#4.0.1", ValidationEngineTests.DEF_TX, txLog, FhirPublication.R4, true, "4.0.1"));
else if (version.startsWith("3.0"))
ve.put(version, TestUtilities.getValidationEngine("hl7.fhir.r3.core#3.0.2", ValidationEngineTests.DEF_TX, txLog, FhirPublication.STU3, true, "3.0.2"));
else if (version.startsWith("1.4"))
ve.put(version, TestUtilities.getValidationEngine("hl7.fhir.r2b.core#1.4.0", ValidationEngineTests.DEF_TX, txLog, FhirPublication.DSTU2016May, true, "1.4.0"));
else if (version.startsWith("1.0"))
ve.put(version, TestUtilities.getValidationEngine("hl7.fhir.r2.core#1.0.2", ValidationEngineTests.DEF_TX, txLog, FhirPublication.DSTU2, true, "1.0.2"));
else
throw new Exception("unknown version " + version);
if (!version.equals(currentVersion)) {
currentEngine = buildVersionEngine(version, txLog);
currentVersion = version;
}
vCurr = CLONE ? new ValidationEngine(ve.get(version)) : ve.get(version);
vCurr = CLONE ? new ValidationEngine(currentEngine) : currentEngine;
vCurr.getContext().getTxClient().setLogger(logger);
igLoader = new IgLoader(vCurr.getPcm(), vCurr.getContext(), vCurr.getVersion(), true);
// if (TestingUtilities.fcontexts == null) {
// TestingUtilities.fcontexts = new HashMap<>();
// }
// TestingUtilities.fcontexts.put(version, vCurr.getContext());
if (content.has("close-up")) {
cleanup();
@ -387,6 +388,18 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
}
private ValidationEngine buildVersionEngine(String ver, String txLog) throws Exception {
switch (ver) {
case "1.0": return TestUtilities.getValidationEngine("hl7.fhir.r2.core#1.0.2", ValidationEngineTests.DEF_TX, txLog, FhirPublication.DSTU2, true, "1.0.2");
case "1.4": return TestUtilities.getValidationEngine("hl7.fhir.r2b.core#1.4.0", ValidationEngineTests.DEF_TX, txLog, FhirPublication.DSTU2016May, true, "1.4.0");
case "3.0": return TestUtilities.getValidationEngine("hl7.fhir.r3.core#3.0.2", ValidationEngineTests.DEF_TX, txLog, FhirPublication.STU3, true, "3.0.2");
case "4.0": return TestUtilities.getValidationEngine("hl7.fhir.r4.core#4.0.1", ValidationEngineTests.DEF_TX, txLog, FhirPublication.R4, true, "4.0.1");
case "4.3": return TestUtilities.getValidationEngine("hl7.fhir.r4b.core#4.3.0", ValidationEngineTests.DEF_TX, txLog, FhirPublication.R4B, true, "4.3.0");
case "5.0": return TestUtilities.getValidationEngine("hl7.fhir.r5.core#5.0.0", ValidationEngineTests.DEF_TX, txLog, FhirPublication.R5, true, "5.0.0");
}
throw new Exception("unknown version " + version);
}
private FhirFormat determineFormat(JsonObject config, byte[] cnt) throws IOException {
String name = JsonUtilities.str(config, "file");
return org.hl7.fhir.validation.ResourceChecker.checkIsResource(vCurr.getContext(), true, cnt, name, !JsonUtilities.bool(config, "guess-format"));