diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/R5ToR5Loader.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/R5ToR5Loader.java new file mode 100644 index 000000000..b369b0375 --- /dev/null +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/R5ToR5Loader.java @@ -0,0 +1,180 @@ +package org.hl7.fhir.convertors; + +/*- + * #%L + * org.hl7.fhir.convertors + * %% + * Copyright (C) 2014 - 2019 Health Level 7 + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.hl7.fhir.exceptions.FHIRException; +import org.hl7.fhir.r5.formats.JsonParser; +import org.hl7.fhir.r5.formats.XmlParser; +import org.hl7.fhir.r5.model.Resource; +import org.hl7.fhir.r5.context.SimpleWorkerContext.IContextResourceLoader; +import org.hl7.fhir.r5.model.Bundle; +import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent; +import org.hl7.fhir.r5.model.Bundle.BundleType; +import org.hl7.fhir.r5.model.CanonicalResource; +import org.hl7.fhir.r5.model.CanonicalType; +import org.hl7.fhir.r5.model.CodeSystem; +import org.hl7.fhir.r5.model.ElementDefinition; +import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent; +import org.hl7.fhir.r5.model.StructureDefinition; +import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind; +import org.hl7.fhir.r5.model.UriType; +import org.hl7.fhir.r5.model.ValueSet; + +/** + * This loader doesn't really do anything, but it's defined for structural consistency + * + * @author graha + * + */ +public class R5ToR5Loader extends BaseLoader implements IContextResourceLoader, VersionConvertorAdvisor50 { + + public R5ToR5Loader(String[] types) { + super(types); + } + + private List cslist = new ArrayList<>(); + private boolean patchUrls; + private boolean killPrimitives;; + + @Override + public Bundle loadBundle(InputStream stream, boolean isJson) throws FHIRException, IOException { + Resource r5 = null; + if (isJson) + r5 = new JsonParser().parse(stream); + else + r5 = new XmlParser().parse(stream); + + Bundle b; + if (r5 instanceof Bundle) + b = (Bundle) r5; + else { + b = new Bundle(); + b.setId(UUID.randomUUID().toString().toLowerCase()); + b.setType(BundleType.COLLECTION); + b.addEntry().setResource(r5).setFullUrl(r5 instanceof CanonicalResource ? ((CanonicalResource) r5).getUrl() : null); + } + for (CodeSystem cs : cslist) { + BundleEntryComponent be = b.addEntry(); + be.setFullUrl(cs.getUrl()); + be.setResource(cs); + } + if (killPrimitives) { + List remove = new ArrayList(); + for (BundleEntryComponent be : b.getEntry()) { + if (be.hasResource() && be.getResource() instanceof StructureDefinition) { + StructureDefinition sd = (StructureDefinition) be.getResource(); + if (sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE) + remove.add(be); + } + } + b.getEntry().removeAll(remove); + } + if (patchUrls) { + for (BundleEntryComponent be : b.getEntry()) { + if (be.hasResource() && be.getResource() instanceof StructureDefinition) { + StructureDefinition sd = (StructureDefinition) be.getResource(); + sd.setUrl(sd.getUrl().replace("http://hl7.org/fhir/", "http://hl7.org/fhir/4.0/")); + sd.addExtension().setUrl("http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace").setValue(new UriType("http://hl7.org/fhir")); + for (ElementDefinition ed : sd.getSnapshot().getElement()) + patchUrl(ed); + for (ElementDefinition ed : sd.getDifferential().getElement()) + patchUrl(ed); + } + } + } + return b; + } + + private void patchUrl(ElementDefinition ed) { + for (TypeRefComponent tr : ed.getType()) { + for (CanonicalType s : tr.getTargetProfile()) { + s.setValue(s.getValue().replace("http://hl7.org/fhir/", "http://hl7.org/fhir/4.0/")); + } + for (CanonicalType s : tr.getProfile()) { + s.setValue(s.getValue().replace("http://hl7.org/fhir/", "http://hl7.org/fhir/4.0/")); + } + } + } + + @Override + public boolean ignoreEntry(BundleEntryComponent src) { + return false; + } + + @Override + public org.hl7.fhir.dstu2.model.Resource convertR2(org.hl7.fhir.r5.model.Resource resource) throws FHIRException { + return null; + } + + @Override + public org.hl7.fhir.dstu2016may.model.Resource convertR2016May(org.hl7.fhir.r5.model.Resource resource) throws FHIRException { + return null; + } + + @Override + public org.hl7.fhir.r4.model.Resource convertR4(org.hl7.fhir.r5.model.Resource resource) throws FHIRException { + return null; + } + + @Override + public void handleCodeSystem(CodeSystem cs, ValueSet vs) { + cs.setId(vs.getId()); + cs.setValueSet(vs.getUrl()); + cslist.add(cs); + + } + + @Override + public CodeSystem getCodeSystem(ValueSet src) { + return null; + } + + public boolean isPatchUrls() { + return patchUrls; + } + + public R5ToR5Loader setPatchUrls(boolean patchUrls) { + this.patchUrls = patchUrls; + return this; + } + + public boolean isKillPrimitives() { + return killPrimitives; + } + + public R5ToR5Loader setKillPrimitives(boolean killPrimitives) { + this.killPrimitives = killPrimitives; + return this; + } + + @Override + public org.hl7.fhir.dstu3.model.Resource convertR3(org.hl7.fhir.r5.model.Resource resource) throws FHIRException { + return null; + } + +} diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv10_50/MedicationDispense10_50.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv10_50/MedicationDispense10_50.java index 79bdd9196..7aafac6f7 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv10_50/MedicationDispense10_50.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv10_50/MedicationDispense10_50.java @@ -4,7 +4,6 @@ import org.hl7.fhir.convertors.VersionConvertor_10_50; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.r5.model.Dosage; import org.hl7.fhir.r5.model.Dosage.DosageDoseAndRateComponent; -import org.hl7.fhir.r5.model.MedicationDispense.MedicationDispenseStatusCodesEnumFactory; public class MedicationDispense10_50 { @@ -128,7 +127,7 @@ public class MedicationDispense10_50 { public static org.hl7.fhir.r5.model.Enumeration convertMedicationDispenseStatus(org.hl7.fhir.dstu2.model.Enumeration src) throws FHIRException { if (src == null) return null; - org.hl7.fhir.r5.model.Enumeration tgt = new org.hl7.fhir.r5.model.Enumeration<>(new MedicationDispenseStatusCodesEnumFactory()); + org.hl7.fhir.r5.model.Enumeration tgt = new org.hl7.fhir.r5.model.Enumeration(); VersionConvertor_10_50.copyElement(src, tgt); switch(src.getValue()) { case COMPLETED: diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv30_50/MedicationAdministration30_50.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv30_50/MedicationAdministration30_50.java index 061b72a28..0637cebce 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv30_50/MedicationAdministration30_50.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv30_50/MedicationAdministration30_50.java @@ -3,7 +3,6 @@ package org.hl7.fhir.convertors.conv30_50; import org.hl7.fhir.convertors.VersionConvertor_30_50; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.r5.model.CodeableReference; -import org.hl7.fhir.r5.model.MedicationAdministration.MedicationAdministrationStatusCodesEnumFactory; public class MedicationAdministration30_50 { @@ -140,7 +139,7 @@ public class MedicationAdministration30_50 { static public org.hl7.fhir.r5.model.Enumeration convertMedicationAdministrationStatus(org.hl7.fhir.dstu3.model.Enumeration src) { if (src == null) return null; - org.hl7.fhir.r5.model.Enumeration tgt = new org.hl7.fhir.r5.model.Enumeration<>(new MedicationAdministrationStatusCodesEnumFactory()); + org.hl7.fhir.r5.model.Enumeration tgt = new org.hl7.fhir.r5.model.Enumeration(); VersionConvertor_30_50.copyElement(src, tgt); tgt.setValue(org.hl7.fhir.r5.model.MedicationAdministration.MedicationAdministrationStatusCodes.fromCode(src.getValueAsString())); return tgt; diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/MedicationAdministration40_50.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/MedicationAdministration40_50.java index f5e09ddd3..eeff0d742 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/MedicationAdministration40_50.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/MedicationAdministration40_50.java @@ -25,7 +25,6 @@ import org.hl7.fhir.r4.model.CodeType; import org.hl7.fhir.r5.model.CodeableReference; import org.hl7.fhir.r5.model.Enumeration; import org.hl7.fhir.r5.model.MedicationAdministration.MedicationAdministrationStatusCodes; -import org.hl7.fhir.r5.model.MedicationAdministration.MedicationAdministrationStatusCodesEnumFactory; /* Copyright (c) 2011+, HL7, Inc. @@ -142,7 +141,7 @@ public class MedicationAdministration40_50 extends VersionConvertor_40_50 { private static Enumeration convertMedicationAdministrationStatus(CodeType src) { if (src == null) return null; - Enumeration tgt = new Enumeration<>(new MedicationAdministrationStatusCodesEnumFactory()); + Enumeration tgt = new Enumeration(); copyElement(src, tgt); tgt.setValue(MedicationAdministrationStatusCodes.fromCode(src.getCode())); return tgt; diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/MedicationDispense40_50.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/MedicationDispense40_50.java index 421bc5b71..1fc91144a 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/MedicationDispense40_50.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/MedicationDispense40_50.java @@ -23,7 +23,6 @@ import org.hl7.fhir.convertors.VersionConvertor_40_50; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.r4.model.CodeType; import org.hl7.fhir.r5.model.MedicationDispense.MedicationDispenseStatusCodes; -import org.hl7.fhir.r5.model.MedicationDispense.MedicationDispenseStatusCodesEnumFactory; /* Copyright (c) 2011+, HL7, Inc. @@ -163,7 +162,7 @@ public class MedicationDispense40_50 extends VersionConvertor_40_50 { private static org.hl7.fhir.r5.model.Enumeration convertMedicationStatus(org.hl7.fhir.r4.model.CodeType src) { if (src == null) return null; - org.hl7.fhir.r5.model.Enumeration tgt = new org.hl7.fhir.r5.model.Enumeration<>(new MedicationDispenseStatusCodesEnumFactory()); + org.hl7.fhir.r5.model.Enumeration tgt = new org.hl7.fhir.r5.model.Enumeration(); copyElement(src, tgt); if (src.hasCode()) tgt.setValue(MedicationDispenseStatusCodes.fromCode(src.getCode())); diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/MedicationKnowledge40_50.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/MedicationKnowledge40_50.java index 56180669c..dd4a089e6 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/MedicationKnowledge40_50.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/MedicationKnowledge40_50.java @@ -24,7 +24,6 @@ import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.r4.model.CodeType; import org.hl7.fhir.r5.model.Enumeration; import org.hl7.fhir.r5.model.MedicationKnowledge.MedicationKnowledgeStatusCodes; -import org.hl7.fhir.r5.model.MedicationKnowledge.MedicationKnowledgeStatusCodesEnumFactory; /* Copyright (c) 2011+, HL7, Inc. @@ -149,7 +148,7 @@ public class MedicationKnowledge40_50 extends VersionConvertor_40_50 { private static Enumeration convertMedicationKnowledgeStatus(CodeType src) { if (src == null) return null; - org.hl7.fhir.r5.model.Enumeration tgt = new org.hl7.fhir.r5.model.Enumeration<>(new MedicationKnowledgeStatusCodesEnumFactory()); + org.hl7.fhir.r5.model.Enumeration tgt = new org.hl7.fhir.r5.model.Enumeration(); copyElement(src, tgt); tgt.setValue(MedicationKnowledgeStatusCodes.fromCode(src.getCode())); return tgt; diff --git a/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/BaseWorkerContext.java b/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/BaseWorkerContext.java index e7a213e0d..59024f9a3 100644 --- a/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/BaseWorkerContext.java +++ b/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/BaseWorkerContext.java @@ -23,15 +23,11 @@ package org.hl7.fhir.dstu2.utils; import java.io.FileNotFoundException; import java.io.IOException; -import java.text.MessageFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Locale; import java.util.Map; -import java.util.Objects; -import java.util.ResourceBundle; import java.util.Set; import org.hl7.fhir.dstu2.model.BooleanType; @@ -77,8 +73,6 @@ public abstract class BaseWorkerContext implements IWorkerContext { // private ValueSetExpansionCache expansionCache; // protected FHIRToolingClient txServer; - private Locale locale; - private ResourceBundle i18Nmessages; @Override public ValueSet fetchCodeSystem(String system) { @@ -408,37 +402,4 @@ public abstract class BaseWorkerContext implements IWorkerContext { return fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/"+typeName); } - @Override - public Locale getLocale() { - if (Objects.nonNull(locale)){ - return locale; - } else { - return Locale.US; - } - } - - @Override - public void setLocale(Locale locale) { - this.locale = locale; - setValidationMessageLanguage(getLocale()); - } - - @Override - public String formatMessage(String theMessage, Object... theMessageArguments) { - String message = theMessage; - if (Objects.nonNull(i18Nmessages) && i18Nmessages.containsKey(theMessage)) { - if (Objects.nonNull(theMessageArguments) && theMessageArguments.length > 0) { - message = MessageFormat.format(i18Nmessages.getString(theMessage), theMessageArguments); - } else { - message = i18Nmessages.getString(theMessage); - } - } - return message; - } - - @Override - public void setValidationMessageLanguage(Locale locale) { - i18Nmessages = ResourceBundle.getBundle("Messages", locale ); - } - } diff --git a/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/IWorkerContext.java b/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/IWorkerContext.java index ddf1dd822..c566a64f8 100644 --- a/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/IWorkerContext.java +++ b/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/IWorkerContext.java @@ -23,7 +23,6 @@ package org.hl7.fhir.dstu2.utils; import java.util.List; -import java.util.Locale; import org.hl7.fhir.dstu2.formats.IParser; import org.hl7.fhir.dstu2.formats.ParserType; import org.hl7.fhir.dstu2.model.CodeableConcept; @@ -209,15 +208,7 @@ public interface IWorkerContext { * @return */ public ValueSetExpansionComponent expandVS(ConceptSetComponent inc); - - Locale getLocale(); - - void setLocale(Locale locale); - - String formatMessage(String theMessage, Object... theMessageArguments); - - void setValidationMessageLanguage(Locale locale); - + public class ValidationResult { private ConceptDefinitionComponent definition; private IssueSeverity severity; diff --git a/org.hl7.fhir.dstu2016may/src/main/java/org/hl7/fhir/dstu2016may/utils/BaseWorkerContext.java b/org.hl7.fhir.dstu2016may/src/main/java/org/hl7/fhir/dstu2016may/utils/BaseWorkerContext.java index 262178207..f56158e9d 100644 --- a/org.hl7.fhir.dstu2016may/src/main/java/org/hl7/fhir/dstu2016may/utils/BaseWorkerContext.java +++ b/org.hl7.fhir.dstu2016may/src/main/java/org/hl7/fhir/dstu2016may/utils/BaseWorkerContext.java @@ -23,15 +23,11 @@ package org.hl7.fhir.dstu2016may.utils; import java.io.FileNotFoundException; import java.io.IOException; -import java.text.MessageFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Locale; import java.util.Map; -import java.util.Objects; -import java.util.ResourceBundle; import java.util.Set; import org.hl7.fhir.dstu2016may.model.BooleanType; @@ -79,8 +75,6 @@ public abstract class BaseWorkerContext implements IWorkerContext { protected FHIRToolingClient txServer; private Bundle bndCodeSystems; - private Locale locale; - private ResourceBundle i18Nmessages; @Override public CodeSystem fetchCodeSystem(String system) { @@ -447,37 +441,5 @@ public abstract class BaseWorkerContext implements IWorkerContext { return fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/"+typeName); } - @Override - public Locale getLocale() { - if (Objects.nonNull(locale)){ - return locale; - } else { - return Locale.US; - } - } - - @Override - public void setLocale(Locale locale) { - this.locale = locale; - setValidationMessageLanguage(getLocale()); - } - - @Override - public String formatMessage(String theMessage, Object... theMessageArguments) { - String message = theMessage; - if (Objects.nonNull(i18Nmessages) && i18Nmessages.containsKey(theMessage)) { - if (Objects.nonNull(theMessageArguments) && theMessageArguments.length > 0) { - message = MessageFormat.format(i18Nmessages.getString(theMessage), theMessageArguments); - } else { - message = i18Nmessages.getString(theMessage); - } - } - return message; - } - - @Override - public void setValidationMessageLanguage(Locale locale) { - i18Nmessages = ResourceBundle.getBundle("Messages", locale ); - } } diff --git a/org.hl7.fhir.dstu2016may/src/main/java/org/hl7/fhir/dstu2016may/utils/IWorkerContext.java b/org.hl7.fhir.dstu2016may/src/main/java/org/hl7/fhir/dstu2016may/utils/IWorkerContext.java index fa96c4915..d9e91b6ee 100644 --- a/org.hl7.fhir.dstu2016may/src/main/java/org/hl7/fhir/dstu2016may/utils/IWorkerContext.java +++ b/org.hl7.fhir.dstu2016may/src/main/java/org/hl7/fhir/dstu2016may/utils/IWorkerContext.java @@ -22,7 +22,6 @@ package org.hl7.fhir.dstu2016may.utils; import java.util.List; -import java.util.Locale; import java.util.Set; import org.hl7.fhir.dstu2016may.formats.IParser; @@ -205,15 +204,7 @@ public interface IWorkerContext { * @return */ public ValueSetExpansionComponent expandVS(ConceptSetComponent inc); - - Locale getLocale(); - - void setLocale(Locale locale); - - String formatMessage(String theMessage, Object... theMessageArguments); - - void setValidationMessageLanguage(Locale locale); - + public class ValidationResult { private ConceptDefinitionComponent definition; private IssueSeverity severity; diff --git a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/context/BaseWorkerContext.java b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/context/BaseWorkerContext.java index 2ba664936..8fbcee29a 100644 --- a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/context/BaseWorkerContext.java +++ b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/context/BaseWorkerContext.java @@ -9,9 +9,9 @@ package org.hl7.fhir.dstu3.context; * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -27,15 +27,11 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; -import java.text.MessageFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Locale; import java.util.Map; -import java.util.Objects; -import java.util.ResourceBundle; import java.util.Set; import ca.uhn.fhir.rest.api.Constants; @@ -110,7 +106,7 @@ public abstract class BaseWorkerContext implements IWorkerContext { protected ValueSetExpanderFactory expansionCache = new ValueSetExpansionCache(this); protected boolean cacheValidation; // if true, do an expansion and cache the expansion private Set failed = new HashSet(); // value sets for which we don't try to do expansion, since the first attempt to get a comprehensive expansion was not successful - protected Map> validationCache = new HashMap>(); + protected Map> validationCache = new HashMap>(); protected String tsServer; protected String validationCachePath; protected String name; @@ -126,8 +122,6 @@ public abstract class BaseWorkerContext implements IWorkerContext { private int expandCodesLimit = 1000; protected ILoggingService logger; protected ExpansionProfile expProfile; - private Locale locale; - private ResourceBundle i18Nmessages; public Map getCodeSystems() { return codeSystems; @@ -162,9 +156,8 @@ public abstract class BaseWorkerContext implements IWorkerContext { } public void seeExtensionDefinition(String url, StructureDefinition ed) throws Exception { - if (extensionDefinitions.get(ed.getUrl()) != null) { + if (extensionDefinitions.get(ed.getUrl()) != null) throw new Exception("duplicate extension definition: " + ed.getUrl()); - } extensionDefinitions.put(ed.getId(), ed); extensionDefinitions.put(url, ed); extensionDefinitions.put(ed.getUrl(), ed); @@ -173,31 +166,27 @@ public abstract class BaseWorkerContext implements IWorkerContext { public void dropExtensionDefinition(String id) { StructureDefinition sd = extensionDefinitions.get(id); extensionDefinitions.remove(id); - if (sd != null) { + if (sd!= null) extensionDefinitions.remove(sd.getUrl()); - } } public void seeQuestionnaire(String url, Questionnaire theQuestionnaire) throws Exception { - if (questionnaires.get(theQuestionnaire.getId()) != null) { - throw new Exception("duplicate extension definition: " + theQuestionnaire.getId()); - } + if (questionnaires.get(theQuestionnaire.getId()) != null) + throw new Exception("duplicate extension definition: "+theQuestionnaire.getId()); questionnaires.put(theQuestionnaire.getId(), theQuestionnaire); questionnaires.put(url, theQuestionnaire); } public void seeOperation(OperationDefinition opd) throws Exception { - if (operations.get(opd.getUrl()) != null) { - throw new Exception("duplicate extension definition: " + opd.getUrl()); - } + if (operations.get(opd.getUrl()) != null) + throw new Exception("duplicate extension definition: "+opd.getUrl()); operations.put(opd.getUrl(), opd); operations.put(opd.getId(), opd); } public void seeValueSet(String url, ValueSet vs) throws Exception { - if (valueSets.containsKey(vs.getUrl()) && !allowLoadingDuplicates) { - throw new Exception("Duplicate value set " + vs.getUrl()); - } + if (valueSets.containsKey(vs.getUrl()) && !allowLoadingDuplicates) + throw new Exception("Duplicate value set "+vs.getUrl()); valueSets.put(vs.getId(), vs); valueSets.put(url, vs); valueSets.put(vs.getUrl(), vs); @@ -206,15 +195,13 @@ public abstract class BaseWorkerContext implements IWorkerContext { public void dropValueSet(String id) { ValueSet vs = valueSets.get(id); valueSets.remove(id); - if (vs != null) { + if (vs != null) valueSets.remove(vs.getUrl()); - } } public void seeCodeSystem(String url, CodeSystem cs) throws FHIRException { - if (codeSystems.containsKey(cs.getUrl()) && !allowLoadingDuplicates) { - throw new FHIRException("Duplicate code system " + cs.getUrl()); - } + if (codeSystems.containsKey(cs.getUrl()) && !allowLoadingDuplicates) + throw new FHIRException("Duplicate code system "+cs.getUrl()); codeSystems.put(cs.getId(), cs); codeSystems.put(url, cs); codeSystems.put(cs.getUrl(), cs); @@ -223,15 +210,13 @@ public abstract class BaseWorkerContext implements IWorkerContext { public void dropCodeSystem(String id) { CodeSystem cs = codeSystems.get(id); codeSystems.remove(id); - if (cs != null) { + if (cs != null) codeSystems.remove(cs.getUrl()); - } } public void seeProfile(String url, StructureDefinition p) throws Exception { - if (profiles.containsKey(p.getUrl())) { - throw new Exception("Duplicate Profile " + p.getUrl()); - } + if (profiles.containsKey(p.getUrl())) + throw new Exception("Duplicate Profile "+p.getUrl()); profiles.put(p.getId(), p); profiles.put(url, p); profiles.put(p.getUrl(), p); @@ -240,43 +225,37 @@ public abstract class BaseWorkerContext implements IWorkerContext { public void dropProfile(String id) { StructureDefinition sd = profiles.get(id); profiles.remove(id); - if (sd != null) { + if (sd!= null) profiles.remove(sd.getUrl()); - } } @Override public CodeSystem fetchCodeSystem(String system) { return codeSystems.get(system); - } + } @Override public boolean supportsSystem(String system) throws TerminologyServiceException { - if (codeSystems.containsKey(system)) { + if (codeSystems.containsKey(system)) return true; - } else if (nonSupportedCodeSystems.contains(system)) { + else if (nonSupportedCodeSystems.contains(system)) return false; - } else if (system.startsWith("http://example.org") || system.startsWith("http://acme.com") - || system.startsWith("http://hl7.org/fhir/valueset-") || system.startsWith("urn:oid:")) { + else if (system.startsWith("http://example.org") || system.startsWith("http://acme.com") || system.startsWith("http://hl7.org/fhir/valueset-") || system.startsWith("urn:oid:")) return false; - } else { - if (noTerminologyServer) { + else { + if (noTerminologyServer) return false; - } if (bndCodeSystems == null) { try { - tlog("Terminology server: Check for supported code systems for " + system); - bndCodeSystems = txServer.fetchFeed(txServer.getAddress() - + "/CodeSystem?content-mode=not-present&_summary=true&_count=1000"); + tlog("Terminology server: Check for supported code systems for "+system); + bndCodeSystems = txServer.fetchFeed(txServer.getAddress()+"/CodeSystem?content-mode=not-present&_summary=true&_count=1000"); } catch (Exception e) { if (canRunWithoutTerminology) { noTerminologyServer = true; - log("==============!! Running without terminology server !!============== (" + e - .getMessage() + ")"); + log("==============!! Running without terminology server !!============== ("+e.getMessage()+")"); return false; - } else { + } else throw new TerminologyServiceException(e); - } } } if (bndCodeSystems != null) { @@ -287,20 +266,18 @@ public abstract class BaseWorkerContext implements IWorkerContext { } } } - if (codeSystems.containsKey(system)) { + if (codeSystems.containsKey(system)) return true; - } } nonSupportedCodeSystems.add(system); return false; } private void log(String message) { - if (logger != null) { + if (logger != null) logger.logMessage(message); - } else { + else System.out.println(message); - } } @Override @@ -311,17 +288,14 @@ public abstract class BaseWorkerContext implements IWorkerContext { } String cacheFn = null; if (cache != null) { - cacheFn = Utilities.path(cache, determineCacheId(vs, heirarchical) + ".json"); - if (new File(cacheFn).exists()) { + cacheFn = Utilities.path(cache, determineCacheId(vs, heirarchical)+".json"); + if (new File(cacheFn).exists()) return loadFromCache(vs.copy(), cacheFn); - } } if (cacheOk && vs.hasUrl()) { - if (expProfile == null) { + if (expProfile == null) throw new Exception("No ExpansionProfile provided"); - } - ValueSetExpansionOutcome vse = expansionCache.getExpander() - .expand(vs, expProfile.setExcludeNested(!heirarchical)); + ValueSetExpansionOutcome vse = expansionCache.getExpander().expand(vs, expProfile.setExcludeNested(!heirarchical)); if (vse.getValueset() != null) { if (cache != null) { FileOutputStream s = new FileOutputStream(cacheFn); @@ -335,7 +309,7 @@ public abstract class BaseWorkerContext implements IWorkerContext { if (cacheFn != null) { if (res.getValueset() != null) { saveToCache(res.getValueset(), cacheFn); - } else { + } else { OperationOutcome oo = new OperationOutcome(); oo.addIssue().getDetails().setText(res.getError()); saveToCache(oo, cacheFn); @@ -344,27 +318,19 @@ public abstract class BaseWorkerContext implements IWorkerContext { return res; } } catch (NoTerminologyServiceException e) { - return new ValueSetExpansionOutcome( - e.getMessage() == null ? e.getClass().getName() : e.getMessage(), - TerminologyServiceErrorClass.NOSERVICE); + return new ValueSetExpansionOutcome(e.getMessage() == null ? e.getClass().getName() : e.getMessage(), TerminologyServiceErrorClass.NOSERVICE); } catch (Exception e) { - return new ValueSetExpansionOutcome( - e.getMessage() == null ? e.getClass().getName() : e.getMessage(), - TerminologyServiceErrorClass.UNKNOWN); + return new ValueSetExpansionOutcome(e.getMessage() == null ? e.getClass().getName() : e.getMessage(), TerminologyServiceErrorClass.UNKNOWN); } } - private ValueSetExpansionOutcome loadFromCache(ValueSet vs, String cacheFn) - throws FileNotFoundException, Exception { + private ValueSetExpansionOutcome loadFromCache(ValueSet vs, String cacheFn) throws FileNotFoundException, Exception { JsonParser parser = new JsonParser(); Resource r = parser.parse(new FileInputStream(cacheFn)); - if (r instanceof OperationOutcome) { - return new ValueSetExpansionOutcome( - ((OperationOutcome) r).getIssue().get(0).getDetails().getText(), - TerminologyServiceErrorClass.UNKNOWN); - } else { - vs.setExpansion(((ValueSet) r) - .getExpansion()); // because what is cached might be from a different value set + if (r instanceof OperationOutcome) + return new ValueSetExpansionOutcome(((OperationOutcome) r).getIssue().get(0).getDetails().getText(), TerminologyServiceErrorClass.UNKNOWN); + else { + vs.setExpansion(((ValueSet) r).getExpansion()); // because what is cached might be from a different value set return new ValueSetExpansionOutcome(vs); } } @@ -380,7 +346,7 @@ public abstract class BaseWorkerContext implements IWorkerContext { vsid.setCompose(vs.getCompose()); JsonParser parser = new JsonParser(); parser.setOutputStyle(OutputStyle.NORMAL); - ByteArrayOutputStream b = new ByteArrayOutputStream(); + ByteArrayOutputStream b = new ByteArrayOutputStream(); parser.compose(b, vsid); b.close(); String s = new String(b.toByteArray(), Constants.CHARSET_UTF8); @@ -392,7 +358,7 @@ public abstract class BaseWorkerContext implements IWorkerContext { s = s + css; } } - s = s + "-" + Boolean.toString(heirarchical); + s = s + "-"+Boolean.toString(heirarchical); String r = Integer.toString(s.hashCode()); // TextFile.stringToFile(s, Utilities.path(cache, r+".id.json")); return r; @@ -405,12 +371,11 @@ public abstract class BaseWorkerContext implements IWorkerContext { csid.setVersion(cs.getVersion()); csid.setContent(cs.getContent()); csid.setHierarchyMeaning(CodeSystemHierarchyMeaning.GROUPEDBY); - for (ConceptDefinitionComponent cc : cs.getConcept()) { + for (ConceptDefinitionComponent cc : cs.getConcept()) csid.getConcept().add(processCSConcept(cc)); - } JsonParser parser = new JsonParser(); parser.setOutputStyle(OutputStyle.NORMAL); - ByteArrayOutputStream b = new ByteArrayOutputStream(); + ByteArrayOutputStream b = new ByteArrayOutputStream(); parser.compose(b, csid); b.close(); return new String(b.toByteArray(), Constants.CHARSET_UTF8); @@ -421,69 +386,56 @@ public abstract class BaseWorkerContext implements IWorkerContext { ConceptDefinitionComponent ccid = new ConceptDefinitionComponent(); ccid.setCode(cc.getCode()); ccid.setDisplay(cc.getDisplay()); - for (ConceptDefinitionComponent cci : cc.getConcept()) { + for (ConceptDefinitionComponent cci : cc.getConcept()) ccid.getConcept().add(processCSConcept(cci)); - } return ccid; } public ValueSetExpansionOutcome expandOnServer(ValueSet vs, String fn) throws Exception { - if (noTerminologyServer) { - return new ValueSetExpansionOutcome( - "Error expanding ValueSet: running without terminology services", - TerminologyServiceErrorClass.NOSERVICE); - } - if (expProfile == null) { + if (noTerminologyServer) + return new ValueSetExpansionOutcome("Error expanding ValueSet: running without terminology services", TerminologyServiceErrorClass.NOSERVICE); + if (expProfile == null) throw new Exception("No ExpansionProfile provided"); - } try { Map params = new HashMap(); - params.put("_limit", Integer.toString(expandCodesLimit)); + params.put("_limit", Integer.toString(expandCodesLimit )); params.put("_incomplete", "true"); - tlog("Terminology Server: $expand on " + getVSSummary(vs)); + tlog("Terminology Server: $expand on "+getVSSummary(vs)); ValueSet result = txServer.expandValueset(vs, expProfile.setIncludeDefinition(false), params); - return new ValueSetExpansionOutcome(result); + return new ValueSetExpansionOutcome(result); } catch (Exception e) { - return new ValueSetExpansionOutcome( - "Error expanding ValueSet \"" + vs.getUrl() + ": " + e.getMessage(), - TerminologyServiceErrorClass.UNKNOWN); + return new ValueSetExpansionOutcome("Error expanding ValueSet \""+vs.getUrl()+": "+e.getMessage(), TerminologyServiceErrorClass.UNKNOWN); } } private String getVSSummary(ValueSet vs) { CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); - for (ConceptSetComponent cc : vs.getCompose().getInclude()) { - b.append("Include " + getIncSummary(cc)); - } - for (ConceptSetComponent cc : vs.getCompose().getExclude()) { - b.append("Exclude " + getIncSummary(cc)); - } + for (ConceptSetComponent cc : vs.getCompose().getInclude()) + b.append("Include "+getIncSummary(cc)); + for (ConceptSetComponent cc : vs.getCompose().getExclude()) + b.append("Exclude "+getIncSummary(cc)); return b.toString(); } private String getIncSummary(ConceptSetComponent cc) { CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); - for (UriType vs : cc.getValueSet()) { + for (UriType vs : cc.getValueSet()) b.append(vs.asStringValue()); - } - String vsd = - b.length() > 0 ? " where the codes are in the value sets (" + b.toString() + ")" : ""; + String vsd = b.length() > 0 ? " where the codes are in the value sets ("+b.toString()+")" : ""; String system = cc.getSystem(); - if (cc.hasConcept()) { - return Integer.toString(cc.getConcept().size()) + " codes from " + system + vsd; - } + if (cc.hasConcept()) + return Integer.toString(cc.getConcept().size())+" codes from "+system+vsd; if (cc.hasFilter()) { String s = ""; for (ConceptSetFilterComponent f : cc.getFilter()) { - if (!Utilities.noString(s)) { + if (!Utilities.noString(s)) s = s + " & "; - } - s = s + f.getProperty() + " " + f.getOp().toCode() + " " + f.getValue(); + s = s + f.getProperty()+" "+f.getOp().toCode()+" "+f.getValue(); } - return "from " + system + " where " + s + vsd; + return "from "+system+" where "+s+vsd; } - return "All codes from " + system + vsd; + return "All codes from "+system+vsd; } private ValidationResult handleByCache(ValueSet vs, Coding coding, boolean tryCache) { @@ -493,18 +445,14 @@ public abstract class BaseWorkerContext implements IWorkerContext { cache = new HashMap(); validationCache.put(vs.getUrl(), cache); } - if (cache.containsKey(cacheId)) { + if (cache.containsKey(cacheId)) return cache.get(cacheId); - } - if (!tryCache) { + if (!tryCache) return null; - } - if (!cacheValidation) { + if (!cacheValidation) return null; - } - if (failed.contains(vs.getUrl())) { + if (failed.contains(vs.getUrl())) return null; - } ValueSetExpansionOutcome vse = expandVS(vs, true, false); if (vse.getValueset() == null || notcomplete(vse.getValueset())) { failed.add(vs.getUrl()); @@ -517,17 +465,12 @@ public abstract class BaseWorkerContext implements IWorkerContext { } private boolean notcomplete(ValueSet vs) { - if (!vs.hasExpansion()) { + if (!vs.hasExpansion()) return true; - } - if (!vs.getExpansion() - .getExtensionsByUrl("http://hl7.org/fhir/StructureDefinition/valueset-unclosed").isEmpty()) { + if (!vs.getExpansion().getExtensionsByUrl("http://hl7.org/fhir/StructureDefinition/valueset-unclosed").isEmpty()) return true; - } - if (!vs.getExpansion() - .getExtensionsByUrl("http://hl7.org/fhir/StructureDefinition/valueset-toocostly").isEmpty()) { + if (!vs.getExpansion().getExtensionsByUrl("http://hl7.org/fhir/StructureDefinition/valueset-toocostly").isEmpty()) return true; - } return false; } @@ -538,23 +481,17 @@ public abstract class BaseWorkerContext implements IWorkerContext { cache = new HashMap(); validationCache.put(vs.getUrl(), cache); } - if (cache.containsKey(cacheId)) { + if (cache.containsKey(cacheId)) return cache.get(cacheId); - } - if (validationCache.containsKey(vs.getUrl()) && validationCache.get(vs.getUrl()) - .containsKey(cacheId)) { + if (validationCache.containsKey(vs.getUrl()) && validationCache.get(vs.getUrl()).containsKey(cacheId)) return validationCache.get(vs.getUrl()).get(cacheId); - } - if (!tryCache) { + if (!tryCache) return null; - } - if (!cacheValidation) { + if (!cacheValidation) return null; - } - if (failed.contains(vs.getUrl())) { + if (failed.contains(vs.getUrl())) return null; - } ValueSetExpansionOutcome vse = expandVS(vs, true, false); if (vse.getValueset() == null || notcomplete(vse.getValueset())) { failed.add(vs.getUrl()); @@ -566,8 +503,7 @@ public abstract class BaseWorkerContext implements IWorkerContext { } private String cacheId(Coding coding) { - return "|" + coding.getSystem() + "|" + coding.getVersion() + "|" + coding.getCode() + "|" - + coding.getDisplay(); + return "|"+coding.getSystem()+"|"+coding.getVersion()+"|"+coding.getCode()+"|"+coding.getDisplay(); } private String cacheId(CodeableConcept cc) { @@ -575,21 +511,18 @@ public abstract class BaseWorkerContext implements IWorkerContext { for (Coding c : cc.getCoding()) { b.append("#"); b.append(cacheId(c)); - } + } return b.toString(); } - private ValidationResult verifyCodeExternal(ValueSet vs, Coding coding, boolean tryCache) - throws Exception { + private ValidationResult verifyCodeExternal(ValueSet vs, Coding coding, boolean tryCache) throws Exception { ValidationResult res = vs == null ? null : handleByCache(vs, coding, tryCache); - if (res != null) { + if (res != null) return res; - } Parameters pin = new Parameters(); pin.addParameter().setName("coding").setValue(coding); - if (vs != null) { + if (vs != null) pin.addParameter().setName("valueSet").setResource(vs); - } res = serverValidateCode(pin, vs == null); if (vs != null) { Map cache = validationCache.get(vs.getUrl()); @@ -598,12 +531,10 @@ public abstract class BaseWorkerContext implements IWorkerContext { return res; } - private ValidationResult verifyCodeExternal(ValueSet vs, CodeableConcept cc, boolean tryCache) - throws Exception { + private ValidationResult verifyCodeExternal(ValueSet vs, CodeableConcept cc, boolean tryCache) throws Exception { ValidationResult res = handleByCache(vs, cc, tryCache); - if (res != null) { + if (res != null) return res; - } Parameters pin = new Parameters(); pin.addParameter().setName("codeableConcept").setValue(cc); pin.addParameter().setName("valueSet").setResource(vs); @@ -614,23 +545,18 @@ public abstract class BaseWorkerContext implements IWorkerContext { } private ValidationResult serverValidateCode(Parameters pin, boolean doCache) throws Exception { - if (noTerminologyServer) { + if (noTerminologyServer) return new ValidationResult(null, null, TerminologyServiceErrorClass.NOSERVICE); - } String cacheName = doCache ? generateCacheName(pin) : null; ValidationResult res = loadFromCache(cacheName); - if (res != null) { + if (res != null) return res; - } - tlog("Terminology Server: $validate-code " + describeValidationParameters(pin)); - for (ParametersParameterComponent pp : pin.getParameter()) { - if (pp.getName().equals("profile")) { + tlog("Terminology Server: $validate-code "+describeValidationParameters(pin)); + for (ParametersParameterComponent pp : pin.getParameter()) + if (pp.getName().equals("profile")) throw new Error("Can only specify profile in the context"); - } - } - if (expProfile == null) { + if (expProfile == null) throw new Exception("No ExpansionProfile provided"); - } pin.addParameter().setName("profile").setResource(expProfile); Parameters pout = txServer.operateType(ValueSet.class, "validate-code", pin); @@ -639,31 +565,29 @@ public abstract class BaseWorkerContext implements IWorkerContext { String display = null; TerminologyServiceErrorClass err = TerminologyServiceErrorClass.UNKNOWN; for (ParametersParameterComponent p : pout.getParameter()) { - if (p.getName().equals("result")) { + if (p.getName().equals("result")) ok = ((BooleanType) p.getValue()).getValue().booleanValue(); - } else if (p.getName().equals("message")) { + else if (p.getName().equals("message")) message = ((StringType) p.getValue()).getValue(); - } else if (p.getName().equals("display")) { + else if (p.getName().equals("display")) display = ((StringType) p.getValue()).getValue(); - } else if (p.getName().equals("cause")) { + else if (p.getName().equals("cause")) { try { IssueType it = IssueType.fromCode(((StringType) p.getValue()).getValue()); - if (it == IssueType.UNKNOWN) { + if (it == IssueType.UNKNOWN) err = TerminologyServiceErrorClass.UNKNOWN; - } else if (it == IssueType.NOTSUPPORTED) { + else if (it == IssueType.NOTSUPPORTED) err = TerminologyServiceErrorClass.VALUESET_UNSUPPORTED; - } } catch (FHIRException e) { } } } - if (!ok) { + if (!ok) res = new ValidationResult(IssueSeverity.ERROR, message, err); - } else if (display != null) { + else if (display != null) res = new ValidationResult(new ConceptDefinitionComponent().setDisplay(display)); - } else { + else res = new ValidationResult(new ConceptDefinitionComponent()); - } saveToCache(res, cacheName); return res; } @@ -678,191 +602,158 @@ public abstract class BaseWorkerContext implements IWorkerContext { CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); for (ParametersParameterComponent p : pin.getParameter()) { if (p.hasValue() && p.getValue() instanceof PrimitiveType) { - b.append(p.getName() + "=" + ((PrimitiveType) p.getValue()).asStringValue()); + b.append(p.getName()+"="+((PrimitiveType) p.getValue()).asStringValue()); } else if (p.hasValue() && p.getValue() instanceof Coding) { - b.append("system=" + ((Coding) p.getValue()).getSystem()); - b.append("code=" + ((Coding) p.getValue()).getCode()); - b.append("display=" + ((Coding) p.getValue()).getDisplay()); + b.append("system="+((Coding) p.getValue()).getSystem()); + b.append("code="+((Coding) p.getValue()).getCode()); + b.append("display="+((Coding) p.getValue()).getDisplay()); } else if (p.hasValue() && p.getValue() instanceof CodeableConcept) { if (((CodeableConcept) p.getValue()).hasCoding()) { Coding c = ((CodeableConcept) p.getValue()).getCodingFirstRep(); - b.append("system=" + c.getSystem()); - b.append("code=" + c.getCode()); - b.append("display=" + c.getDisplay()); + b.append("system="+c.getSystem()); + b.append("code="+c.getCode()); + b.append("display="+c.getDisplay()); } else if (((CodeableConcept) p.getValue()).hasText()) { - b.append("text=" + ((CodeableConcept) p.getValue()).getText()); + b.append("text="+((CodeableConcept) p.getValue()).getText()); } } else if (p.hasResource() && (p.getResource() instanceof ValueSet)) { - b.append("valueset=" + getVSSummary((ValueSet) p.getResource())); - } + b.append("valueset="+getVSSummary((ValueSet) p.getResource())); + } } return b.toString(); } private ValidationResult loadFromCache(String fn) throws FileNotFoundException, IOException { - if (fn == null) { + if (fn == null) return null; - } - if (!(new File(fn).exists())) { + if (!(new File(fn).exists())) return null; - } String cnt = TextFile.fileToString(fn); - if (cnt.startsWith("!error: ")) { + if (cnt.startsWith("!error: ")) return new ValidationResult(IssueSeverity.ERROR, cnt.substring(8)); - } else if (cnt.startsWith("!warning: ")) { + else if (cnt.startsWith("!warning: ")) return new ValidationResult(IssueSeverity.ERROR, cnt.substring(10)); - } else { + else return new ValidationResult(new ConceptDefinitionComponent().setDisplay(cnt)); - } } private void saveToCache(ValidationResult res, String cacheName) throws IOException { - if (cacheName == null) { + if (cacheName == null) return; - } - if (res.getDisplay() != null) { + if (res.getDisplay() != null) TextFile.stringToFile(res.getDisplay(), cacheName); - } else if (res.getMessage() != null) { - if (res.getSeverity() == IssueSeverity.WARNING) { - TextFile.stringToFile("!warning: " + res.getMessage(), cacheName); - } else { - TextFile.stringToFile("!error: " + res.getMessage(), cacheName); - } + else if (res.getMessage() != null) { + if (res.getSeverity() == IssueSeverity.WARNING) + TextFile.stringToFile("!warning: "+res.getMessage(), cacheName); + else + TextFile.stringToFile("!error: "+res.getMessage(), cacheName); } } private String generateCacheName(Parameters pin) throws IOException { - if (cache == null) { + if (cache == null) return null; - } String json = new JsonParser().composeString(pin); - return Utilities.path(cache, "vc" + Integer.toString(json.hashCode()) + ".json"); + return Utilities.path(cache, "vc"+Integer.toString(json.hashCode())+".json"); } @Override - public ValueSetExpansionComponent expandVS(ConceptSetComponent inc, boolean heirachical) - throws TerminologyServiceException { + public ValueSetExpansionComponent expandVS(ConceptSetComponent inc, boolean heirachical) throws TerminologyServiceException { ValueSet vs = new ValueSet(); vs.setCompose(new ValueSetComposeComponent()); vs.getCompose().getInclude().add(inc); ValueSetExpansionOutcome vse = expandVS(vs, true, heirachical); ValueSet valueset = vse.getValueset(); - if (valueset == null) { - throw new TerminologyServiceException("Error Expanding ValueSet: " + vse.getError()); - } + if (valueset == null) + throw new TerminologyServiceException("Error Expanding ValueSet: "+vse.getError()); return valueset.getExpansion(); } @Override public ValidationResult validateCode(String system, String code, String display) { try { - if (codeSystems.containsKey(system) && codeSystems.get(system) != null) { + if (codeSystems.containsKey(system) && codeSystems.get(system) != null) return verifyCodeInCodeSystem(codeSystems.get(system), system, code, display); - } else { - return verifyCodeExternal(null, - new Coding().setSystem(system).setCode(code).setDisplay(display), false); - } + else + return verifyCodeExternal(null, new Coding().setSystem(system).setCode(code).setDisplay(display), false); } catch (Exception e) { - return new ValidationResult(IssueSeverity.FATAL, - "Error validating code \"" + code + "\" in system \"" + system + "\": " + e.getMessage()); + return new ValidationResult(IssueSeverity.FATAL, "Error validating code \""+code+"\" in system \""+system+"\": "+e.getMessage()); } } @Override public ValidationResult validateCode(Coding code, ValueSet vs) { - if (codeSystems.containsKey(code.getSystem()) && codeSystems.get(code.getSystem()) != null) { + if (codeSystems.containsKey(code.getSystem()) && codeSystems.get(code.getSystem()) != null) try { - return verifyCodeInCodeSystem(codeSystems.get(code.getSystem()), code.getSystem(), - code.getCode(), code.getDisplay()); + return verifyCodeInCodeSystem(codeSystems.get(code.getSystem()), code.getSystem(), code.getCode(), code.getDisplay()); } catch (Exception e) { - return new ValidationResult(IssueSeverity.FATAL, - "Error validating code \"" + code + "\" in system \"" + code.getSystem() + "\": " + e - .getMessage()); + return new ValidationResult(IssueSeverity.FATAL, "Error validating code \""+code+"\" in system \""+code.getSystem()+"\": "+e.getMessage()); } - } else if (vs.hasExpansion()) { + else if (vs.hasExpansion()) try { return verifyCodeInternal(vs, code.getSystem(), code.getCode(), code.getDisplay()); } catch (Exception e) { - return new ValidationResult(IssueSeverity.FATAL, - "Error validating code \"" + code + "\" in system \"" + code.getSystem() + "\": " + e - .getMessage()); + return new ValidationResult(IssueSeverity.FATAL, "Error validating code \""+code+"\" in system \""+code.getSystem()+"\": "+e.getMessage()); } - } else { + else try { return verifyCodeExternal(vs, code, true); } catch (Exception e) { - return new ValidationResult(IssueSeverity.WARNING, - "Error validating code \"" + code + "\" in system \"" + code.getSystem() + "\": " + e - .getMessage()); + return new ValidationResult(IssueSeverity.WARNING, "Error validating code \""+code+"\" in system \""+code.getSystem()+"\": "+e.getMessage()); } - } } @Override public ValidationResult validateCode(CodeableConcept code, ValueSet vs) { try { - if (vs.hasExpansion()) { + if (vs.hasExpansion()) return verifyCodeInternal(vs, code); - } else { + else { // we'll try expanding first; if that doesn't work, then we'll just pass it to the server to validate // ... could be a problem if the server doesn't have the code systems we have locally, so we try not to depend on the server try { ValueSetExpansionOutcome vse = expandVS(vs, true, false); - if (vse.getValueset() != null && !hasTooCostlyExpansion(vse.getValueset())) { + if (vse.getValueset() != null && !hasTooCostlyExpansion(vse.getValueset())) return verifyCodeInternal(vse.getValueset(), code); - } } catch (Exception e) { // failed? we'll just try the server - } + } return verifyCodeExternal(vs, code, true); } } catch (Exception e) { - return new ValidationResult(IssueSeverity.FATAL, - "Error validating code \"" + code.toString() + "\": " + e.getMessage(), - TerminologyServiceErrorClass.SERVER_ERROR); + return new ValidationResult(IssueSeverity.FATAL, "Error validating code \""+code.toString()+"\": "+e.getMessage(), TerminologyServiceErrorClass.SERVER_ERROR); } } private boolean hasTooCostlyExpansion(ValueSet valueset) { - return valueset != null && valueset.hasExpansion() && ToolingExtensions - .hasExtension(valueset.getExpansion(), - "http://hl7.org/fhir/StructureDefinition/valueset-toocostly"); + return valueset != null && valueset.hasExpansion() && ToolingExtensions.hasExtension(valueset.getExpansion(), "http://hl7.org/fhir/StructureDefinition/valueset-toocostly"); } @Override public ValidationResult validateCode(String system, String code, String display, ValueSet vs) { try { - if (system == null && display == null) { + if (system == null && display == null) return verifyCodeInternal(vs, code); - } - if ((codeSystems.containsKey(system) && codeSystems.get(system) != null) || vs - .hasExpansion()) { + if ((codeSystems.containsKey(system) && codeSystems.get(system) != null) || vs.hasExpansion()) return verifyCodeInternal(vs, system, code, display); - } else { - return verifyCodeExternal(vs, - new Coding().setSystem(system).setCode(code).setDisplay(display), true); - } + else + return verifyCodeExternal(vs, new Coding().setSystem(system).setCode(code).setDisplay(display), true); } catch (Exception e) { - return new ValidationResult(IssueSeverity.FATAL, - "Error validating code \"" + code + "\" in system \"" + system + "\": " + e.getMessage(), - TerminologyServiceErrorClass.SERVER_ERROR); + return new ValidationResult(IssueSeverity.FATAL, "Error validating code \""+code+"\" in system \""+system+"\": "+e.getMessage(), TerminologyServiceErrorClass.SERVER_ERROR); } } @Override - public ValidationResult validateCode(String system, String code, String display, - ConceptSetComponent vsi) { + public ValidationResult validateCode(String system, String code, String display, ConceptSetComponent vsi) { try { ValueSet vs = new ValueSet(); vs.setUrl(Utilities.makeUuidUrn()); vs.getCompose().addInclude(vsi); - return verifyCodeExternal(vs, - new Coding().setSystem(system).setCode(code).setDisplay(display), true); + return verifyCodeExternal(vs, new Coding().setSystem(system).setCode(code).setDisplay(display), true); } catch (Exception e) { - return new ValidationResult(IssueSeverity.FATAL, - "Error validating code \"" + code + "\" in system \"" + system + "\": " + e.getMessage()); + return new ValidationResult(IssueSeverity.FATAL, "Error validating code \""+code+"\" in system \""+system+"\": "+e.getMessage()); } } @@ -884,158 +775,120 @@ public abstract class BaseWorkerContext implements IWorkerContext { @Override public List findMapsForSource(String url) { List res = new ArrayList(); - for (ConceptMap map : maps.values()) { - if (((Reference) map.getSource()).getReference().equals(url)) { + for (ConceptMap map : maps.values()) + if (((Reference) map.getSource()).getReference().equals(url)) res.add(map); - } - } return res; } private ValidationResult verifyCodeInternal(ValueSet vs, CodeableConcept code) throws Exception { for (Coding c : code.getCoding()) { ValidationResult res = verifyCodeInternal(vs, c.getSystem(), c.getCode(), c.getDisplay()); - if (res.isOk()) { + if (res.isOk()) return res; - } } - if (code.getCoding().isEmpty()) { + if (code.getCoding().isEmpty()) return new ValidationResult(IssueSeverity.ERROR, "None code provided"); - } else { - return new ValidationResult(IssueSeverity.ERROR, - "None of the codes are in the specified value set"); - } + else + return new ValidationResult(IssueSeverity.ERROR, "None of the codes are in the specified value set"); } - private ValidationResult verifyCodeInternal(ValueSet vs, String system, String code, - String display) throws Exception { - if (vs.hasExpansion()) { + private ValidationResult verifyCodeInternal(ValueSet vs, String system, String code, String display) throws Exception { + if (vs.hasExpansion()) return verifyCodeInExpansion(vs, system, code, display); - } else { + else { ValueSetExpansionOutcome vse = expansionCache.getExpander().expand(vs, null); - if (vse.getValueset() != null) { - return verifyCodeExternal(vs, - new Coding().setSystem(system).setCode(code).setDisplay(display), false); - } else { + if (vse.getValueset() != null) + return verifyCodeExternal(vs, new Coding().setSystem(system).setCode(code).setDisplay(display), false); + else return verifyCodeInExpansion(vse.getValueset(), system, code, display); - } } } - private ValidationResult verifyCodeInternal(ValueSet vs, String code) - throws FileNotFoundException, ETooCostly, IOException, FHIRException { - if (vs.hasExpansion()) { + private ValidationResult verifyCodeInternal(ValueSet vs, String code) throws FileNotFoundException, ETooCostly, IOException, FHIRException { + if (vs.hasExpansion()) return verifyCodeInExpansion(vs, code); - } else { + else { ValueSetExpansionOutcome vse = expansionCache.getExpander().expand(vs, null); - if (vse.getValueset() == null) { + if (vse.getValueset() == null) return new ValidationResult(IssueSeverity.ERROR, vse.getError(), vse.getErrorClass()); - } else { + else return verifyCodeInExpansion(vse.getValueset(), code); - } } } - private ValidationResult verifyCodeInCodeSystem(CodeSystem cs, String system, String code, - String display) throws Exception { + private ValidationResult verifyCodeInCodeSystem(CodeSystem cs, String system, String code, String display) throws Exception { ConceptDefinitionComponent cc = findCodeInConcept(cs.getConcept(), code); - if (cc == null) { - if (cs.getContent().equals(CodeSystem.CodeSystemContentMode.COMPLETE)) { - return new ValidationResult(IssueSeverity.ERROR, - "Unknown Code " + code + " in " + cs.getUrl()); - } else if (!cs.getContent().equals(CodeSystem.CodeSystemContentMode.NOTPRESENT)) { - return new ValidationResult(IssueSeverity.WARNING, - "Unknown Code " + code + " in partial code list of " + cs.getUrl()); - } else { - return verifyCodeExternal(null, - new Coding().setSystem(system).setCode(code).setDisplay(display), false); - } - } + if (cc == null) + if (cs.getContent().equals(CodeSystem.CodeSystemContentMode.COMPLETE)) + return new ValidationResult(IssueSeverity.ERROR, "Unknown Code "+code+" in "+cs.getUrl()); + else if (!cs.getContent().equals(CodeSystem.CodeSystemContentMode.NOTPRESENT)) + return new ValidationResult(IssueSeverity.WARNING, "Unknown Code "+code+" in partial code list of "+cs.getUrl()); + else + return verifyCodeExternal(null, new Coding().setSystem(system).setCode(code).setDisplay(display), false); // // return new ValidationResult(IssueSeverity.WARNING, "A definition was found for "+cs.getUrl()+", but it has no codes in the definition"); // return new ValidationResult(IssueSeverity.ERROR, "Unknown Code "+code+" in "+cs.getUrl()); - if (display == null) { + if (display == null) return new ValidationResult(cc); - } CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); if (cc.hasDisplay()) { b.append(cc.getDisplay()); - if (display.equalsIgnoreCase(cc.getDisplay())) { + if (display.equalsIgnoreCase(cc.getDisplay())) return new ValidationResult(cc); - } } for (ConceptDefinitionDesignationComponent ds : cc.getDesignation()) { b.append(ds.getValue()); - if (display.equalsIgnoreCase(ds.getValue())) { + if (display.equalsIgnoreCase(ds.getValue())) return new ValidationResult(cc); - } } - return new ValidationResult(IssueSeverity.WARNING, - "Display Name for " + code + " must be one of '" + b.toString() + "'", cc); + return new ValidationResult(IssueSeverity.WARNING, "Display Name for "+code+" must be one of '"+b.toString()+"'", cc); } - private ValidationResult verifyCodeInExpansion(ValueSet vs, String system, String code, - String display) { + private ValidationResult verifyCodeInExpansion(ValueSet vs, String system,String code, String display) { ValueSetExpansionContainsComponent cc = findCode(vs.getExpansion().getContains(), code); - if (cc == null) { - return new ValidationResult(IssueSeverity.ERROR, - "Unknown Code " + code + " in " + vs.getUrl()); - } - if (display == null) { - return new ValidationResult( - new ConceptDefinitionComponent().setCode(code).setDisplay(cc.getDisplay())); - } + if (cc == null) + return new ValidationResult(IssueSeverity.ERROR, "Unknown Code "+code+" in "+vs.getUrl()); + if (display == null) + return new ValidationResult(new ConceptDefinitionComponent().setCode(code).setDisplay(cc.getDisplay())); if (cc.hasDisplay()) { - if (display.equalsIgnoreCase(cc.getDisplay())) { - return new ValidationResult( - new ConceptDefinitionComponent().setCode(code).setDisplay(cc.getDisplay())); - } - return new ValidationResult(IssueSeverity.WARNING, - "Display Name for " + code + " must be '" + cc.getDisplay() + "'", - new ConceptDefinitionComponent().setCode(code).setDisplay(cc.getDisplay())); + if (display.equalsIgnoreCase(cc.getDisplay())) + return new ValidationResult(new ConceptDefinitionComponent().setCode(code).setDisplay(cc.getDisplay())); + return new ValidationResult(IssueSeverity.WARNING, "Display Name for "+code+" must be '"+cc.getDisplay()+"'", new ConceptDefinitionComponent().setCode(code).setDisplay(cc.getDisplay())); } return null; } private ValidationResult verifyCodeInExpansion(ValueSet vs, String code) throws FHIRException { - if (vs.getExpansion() - .hasExtension("http://hl7.org/fhir/StructureDefinition/valueset-toocostly")) { - throw new FHIRException("Unable to validate core - value set is too costly to expand"); + if (vs.getExpansion().hasExtension("http://hl7.org/fhir/StructureDefinition/valueset-toocostly")) { + throw new FHIRException("Unable to validate core - value set is too costly to expand"); } else { ValueSetExpansionContainsComponent cc = findCode(vs.getExpansion().getContains(), code); - if (cc == null) { - return new ValidationResult(IssueSeverity.ERROR, - "Unknown Code " + code + " in " + vs.getUrl()); - } + if (cc == null) + return new ValidationResult(IssueSeverity.ERROR, "Unknown Code "+code+" in "+vs.getUrl()); return null; } } - private ValueSetExpansionContainsComponent findCode( - List contains, String code) { + private ValueSetExpansionContainsComponent findCode(List contains, String code) { for (ValueSetExpansionContainsComponent cc : contains) { - if (code.equals(cc.getCode())) { + if (code.equals(cc.getCode())) return cc; - } ValueSetExpansionContainsComponent c = findCode(cc.getContains(), code); - if (c != null) { + if (c != null) return c; - } } return null; } - private ConceptDefinitionComponent findCodeInConcept(List concept, - String code) { + private ConceptDefinitionComponent findCodeInConcept(List concept, String code) { for (ConceptDefinitionComponent cc : concept) { - if (code.equals(cc.getCode())) { + if (code.equals(cc.getCode())) return cc; - } ConceptDefinitionComponent c = findCodeInConcept(cc.getConcept(), code); - if (c != null) { + if (c != null) return c; - } } return null; } @@ -1101,29 +954,26 @@ public abstract class BaseWorkerContext implements IWorkerContext { } public void cacheResource(Resource r) throws Exception { - if (r instanceof ValueSet) { + if (r instanceof ValueSet) seeValueSet(((ValueSet) r).getUrl(), (ValueSet) r); - } else if (r instanceof CodeSystem) { + else if (r instanceof CodeSystem) seeCodeSystem(((CodeSystem) r).getUrl(), (CodeSystem) r); - } else if (r instanceof StructureDefinition) { + else if (r instanceof StructureDefinition) { StructureDefinition sd = (StructureDefinition) r; - if ("http://hl7.org/fhir/StructureDefinition/Extension".equals(sd.getBaseDefinition())) { + if ("http://hl7.org/fhir/StructureDefinition/Extension".equals(sd.getBaseDefinition())) seeExtensionDefinition(sd.getUrl(), sd); - } else if (sd.getDerivation() == TypeDerivationRule.CONSTRAINT) { + else if (sd.getDerivation() == TypeDerivationRule.CONSTRAINT) seeProfile(sd.getUrl(), sd); - } } } public void dropResource(String type, String id) throws FHIRException { - if (type.equals("ValueSet")) { - dropValueSet(id); - } - if (type.equals("CodeSystem")) { - dropCodeSystem(id); - } + if (type.equals("ValueSet")) + dropValueSet(id); + if (type.equals("CodeSystem")) + dropCodeSystem(id); if (type.equals("StructureDefinition")) { - dropProfile(id); + dropProfile(id); dropExtensionDefinition(id); } } @@ -1138,41 +988,8 @@ public abstract class BaseWorkerContext implements IWorkerContext { @Override public StructureDefinition fetchTypeDefinition(String typeName) { - return fetchResource(StructureDefinition.class, - "http://hl7.org/fhir/StructureDefinition/" + typeName); + return fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/"+typeName); } - @Override - public Locale getLocale() { - if (Objects.nonNull(locale)) { - return locale; - } else { - return Locale.US; - } - } - - @Override - public void setLocale(Locale locale) { - this.locale = locale; - setValidationMessageLanguage(getLocale()); - } - - @Override - public String formatMessage(String theMessage, Object... theMessageArguments) { - String message = theMessage; - if (Objects.nonNull(i18Nmessages) && i18Nmessages.containsKey(theMessage)) { - if (Objects.nonNull(theMessageArguments) && theMessageArguments.length > 0) { - message = MessageFormat.format(i18Nmessages.getString(theMessage), theMessageArguments); - } else { - message = i18Nmessages.getString(theMessage); - } - } - return message; - } - - @Override - public void setValidationMessageLanguage(Locale locale) { - i18Nmessages = ResourceBundle.getBundle("Messages", locale); - } } diff --git a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/context/IWorkerContext.java b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/context/IWorkerContext.java index bcfc0ef98..f51e69f89 100644 --- a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/context/IWorkerContext.java +++ b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/context/IWorkerContext.java @@ -22,7 +22,6 @@ package org.hl7.fhir.dstu3.context; import java.util.List; -import java.util.Locale; import java.util.Set; import org.hl7.fhir.dstu3.formats.IParser; @@ -237,15 +236,7 @@ public interface IWorkerContext { * @throws FHIRException */ public ValueSetExpansionComponent expandVS(ConceptSetComponent inc, boolean heiarchical) throws TerminologyServiceException; - - Locale getLocale(); - - void setLocale(Locale locale); - - String formatMessage(String theMessage, Object... theMessageArguments); - - void setValidationMessageLanguage(Locale locale); - + public class ValidationResult { private ConceptDefinitionComponent definition; private IssueSeverity severity; diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/context/BaseWorkerContext.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/context/BaseWorkerContext.java index 62d11f7cf..75a4b365a 100644 --- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/context/BaseWorkerContext.java +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/context/BaseWorkerContext.java @@ -21,10 +21,6 @@ package org.hl7.fhir.r4.context; */ import com.google.gson.JsonObject; -import java.text.MessageFormat; -import java.util.Locale; -import java.util.Objects; -import java.util.ResourceBundle; import org.apache.commons.lang3.StringUtils; import org.fhir.ucum.UcumService; import org.hl7.fhir.exceptions.DefinitionException; @@ -103,9 +99,7 @@ public abstract class BaseWorkerContext implements IWorkerContext { protected TerminologyCache txCache; private boolean tlogging = true; - private Locale locale; - private ResourceBundle i18Nmessages; - + public BaseWorkerContext() throws FileNotFoundException, IOException, FHIRException { super(); txCache = new TerminologyCache(lock, null); @@ -1180,37 +1174,5 @@ public abstract class BaseWorkerContext implements IWorkerContext { return null; } - @Override - public Locale getLocale() { - if (Objects.nonNull(locale)){ - return locale; - } else { - return Locale.US; - } - } - - @Override - public void setLocale(Locale locale) { - this.locale = locale; - setValidationMessageLanguage(getLocale()); - } - - @Override - public String formatMessage(String theMessage, Object... theMessageArguments) { - String message = theMessage; - if (Objects.nonNull(i18Nmessages) && i18Nmessages.containsKey(theMessage)) { - if (Objects.nonNull(theMessageArguments) && theMessageArguments.length > 0) { - message = MessageFormat.format(i18Nmessages.getString(theMessage), theMessageArguments); - } else { - message = i18Nmessages.getString(theMessage); - } - } - return message; - } - - @Override - public void setValidationMessageLanguage(Locale locale) { - i18Nmessages = ResourceBundle.getBundle("Messages", locale ); - } } diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/context/IWorkerContext.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/context/IWorkerContext.java index b5ce51f24..765379522 100644 --- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/context/IWorkerContext.java +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/context/IWorkerContext.java @@ -22,7 +22,6 @@ package org.hl7.fhir.r4.context; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Set; @@ -284,15 +283,7 @@ public interface IWorkerContext { * @throws FHIRException */ public ValueSetExpansionOutcome expandVS(ConceptSetComponent inc, boolean heirarchical) throws TerminologyServiceException; - - Locale getLocale(); - - void setLocale(Locale locale); - - String formatMessage(String theMessage, Object... theMessageArguments); - - void setValidationMessageLanguage(Locale locale); - + public class ValidationResult { private ConceptDefinitionComponent definition; private IssueSeverity severity; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java index 10f17881b..7813013a9 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java @@ -9,9 +9,9 @@ package org.hl7.fhir.r5.conformance; * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -31,13 +31,13 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.ResourceBundle; import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.exceptions.DefinitionException; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRFormatError; +import org.hl7.fhir.r5.conformance.ProfileUtilities.BaseTypeSlice; import org.hl7.fhir.r5.conformance.ProfileUtilities.ProfileKnowledgeProvider.BindingResolution; import org.hl7.fhir.r5.context.IWorkerContext; import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult; @@ -95,7 +95,7 @@ import org.hl7.fhir.r5.utils.TranslatingUtilities; import org.hl7.fhir.r5.utils.formats.CSVWriter; import org.hl7.fhir.r5.utils.formats.XLSXWriter; import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; -import org.hl7.fhir.utilities.I18nConstants; +import org.hl7.fhir.utilities.TerminologyServiceOptions; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.validation.ValidationOptions; @@ -266,7 +266,6 @@ public class ProfileUtilities extends TranslatingUtilities { private boolean newSlicingProcessing; private String defWebRoot; private boolean autoFixSliceNames; - private ResourceBundle i18nMessages; public ProfileUtilities(IWorkerContext context, List messages, ProfileKnowledgeProvider pkp) { super(); @@ -274,7 +273,7 @@ public class ProfileUtilities extends TranslatingUtilities { this.messages = messages; this.pkp = pkp; } - + private class UnusedTracker { private boolean used; } @@ -299,20 +298,19 @@ public class ProfileUtilities extends TranslatingUtilities { } public interface ProfileKnowledgeProvider { - class BindingResolution { + public class BindingResolution { public String display; public String url; } - boolean isDatatype(String typeSimple); - boolean isResource(String typeSimple); - boolean hasLinkFor(String typeSimple); - String getLinkFor(String corePath, String typeSimple); - BindingResolution resolveBinding(StructureDefinition def, - ElementDefinitionBindingComponent binding, String path) throws FHIRException; - BindingResolution resolveBinding(StructureDefinition def, String url, String path) throws FHIRException; - String getLinkForProfile(StructureDefinition profile, String url); - boolean prependLinks(); - String getLinkForUrl(String corePath, String s); + public boolean isDatatype(String typeSimple); + public boolean isResource(String typeSimple); + public boolean hasLinkFor(String typeSimple); + public String getLinkFor(String corePath, String typeSimple); + public BindingResolution resolveBinding(StructureDefinition def, ElementDefinitionBindingComponent binding, String path) throws FHIRException; + public BindingResolution resolveBinding(StructureDefinition def, String url, String path) throws FHIRException; + public String getLinkForProfile(StructureDefinition profile, String url); + public boolean prependLinks(); + public String getLinkForUrl(String corePath, String s); } @@ -323,7 +321,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (element.getContentReference().equals("#"+e.getId())) return getChildMap(profile, e); } - throw new DefinitionException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_NAME_REFERENCE__AT_PATH_, element.getContentReference(), element.getPath())); + throw new DefinitionException("Unable to resolve name reference "+element.getContentReference()+" at path "+element.getPath()); } else { List res = new ArrayList(); @@ -345,7 +343,7 @@ public class ProfileUtilities extends TranslatingUtilities { public List getSliceList(StructureDefinition profile, ElementDefinition element) throws DefinitionException { if (!element.hasSlicing()) - throw new Error(context.formatMessage(I18nConstants.GETSLICELIST_SHOULD_ONLY_BE_CALLED_WHEN_THE_ELEMENT_HAS_SLICING)); + throw new Error("getSliceList should only be called when the element has slicing"); List res = new ArrayList(); List elements = profile.getSnapshot().getElement(); @@ -384,9 +382,9 @@ public class ProfileUtilities extends TranslatingUtilities { List list = diff ? profile.getDifferential().getElement() : profile.getSnapshot().getElement(); for (ElementDefinition e : list) { if (e == null) - throw new Error(context.formatMessage(I18nConstants.ELEMENT__NULL_, profile.getUrl())); + throw new Error("element = null: "+profile.getUrl()); if (e.getId() == null) - throw new Error(context.formatMessage(I18nConstants.ELEMENT_ID__NULL__ON_, e.toString(), profile.getUrl())); + throw new Error("element id = null: "+e.toString()+" on "+profile.getUrl()); if (!capturing && id!=null && e.getId().equals(id)) { capturing = true; @@ -427,9 +425,9 @@ public class ProfileUtilities extends TranslatingUtilities { public void updateMaps(StructureDefinition base, StructureDefinition derived) throws DefinitionException { if (base == null) - throw new DefinitionException(context.formatMessage(I18nConstants.NO_BASE_PROFILE_PROVIDED)); + throw new DefinitionException("no base profile provided"); if (derived == null) - throw new DefinitionException(context.formatMessage(I18nConstants.NO_DERIVED_STRUCTURE_PROVIDED)); + throw new DefinitionException("no derived structure provided"); for (StructureDefinitionMappingComponent baseMap : base.getMapping()) { boolean found = false; @@ -460,30 +458,30 @@ public class ProfileUtilities extends TranslatingUtilities { */ public void generateSnapshot(StructureDefinition base, StructureDefinition derived, String url, String webUrl, String profileName) throws DefinitionException, FHIRException { if (base == null) { - throw new DefinitionException(context.formatMessage(I18nConstants.NO_BASE_PROFILE_PROVIDED)); + throw new DefinitionException("no base profile provided"); } if (derived == null) { - throw new DefinitionException(context.formatMessage(I18nConstants.NO_DERIVED_STRUCTURE_PROVIDED)); + throw new DefinitionException("no derived structure provided"); } checkNotGenerating(base, "Base for generating a snapshot for the profile "+derived.getUrl()); checkNotGenerating(derived, "Focus for generating a snapshot"); derived.setUserData("profileutils.snapshot.generating", true); if (!base.hasType()) { - throw new DefinitionException(context.formatMessage(I18nConstants.BASE_PROFILE__HAS_NO_TYPE, base.getUrl())); + throw new DefinitionException("Base profile "+base.getUrl()+" has no type"); } if (!derived.hasType()) { - throw new DefinitionException(context.formatMessage(I18nConstants.DERIVED_PROFILE__HAS_NO_TYPE, derived.getUrl())); + throw new DefinitionException("Derived profile "+derived.getUrl()+" has no type"); } if (!derived.hasDerivation()) { - throw new DefinitionException(context.formatMessage(I18nConstants.DERIVED_PROFILE__HAS_NO_DERIVATION_VALUE_AND_SO_CANT_BE_PROCESSED, derived.getUrl())); + throw new DefinitionException("Derived profile "+derived.getUrl()+" has no derivation value and so can't be processed"); } if (!base.getType().equals(derived.getType()) && derived.getDerivation() == TypeDerivationRule.CONSTRAINT) { - throw new DefinitionException(context.formatMessage(I18nConstants.BASE__DERIVED_PROFILES_HAVE_DIFFERENT_TYPES____VS___, base.getUrl(), base.getType(), derived.getUrl(), derived.getType())); + throw new DefinitionException("Base & Derived profiles have different types ("+base.getUrl()+" = "+base.getType()+" vs "+derived.getUrl()+" = "+derived.getType()+")"); } if (snapshotStack.contains(derived.getUrl())) { - throw new DefinitionException(context.formatMessage(I18nConstants.CIRCULAR_SNAPSHOT_REFERENCES_DETECTED_CANNOT_GENERATE_SNAPSHOT_STACK__, snapshotStack.toString())); + throw new DefinitionException("Circular snapshot references detected; cannot generate snapshot (stack = "+snapshotStack.toString()+")"); } snapshotStack.add(derived.getUrl()); @@ -507,7 +505,7 @@ public class ProfileUtilities extends TranslatingUtilities { int diffCursor = 0; // we need a diff cursor because we can only look ahead, in the bound scoped by longer paths if (derived.hasDifferential() && !derived.getDifferential().getElementFirstRep().getPath().contains(".") && !derived.getDifferential().getElementFirstRep().getType().isEmpty()) - throw new Error(context.formatMessage(I18nConstants.TYPE_ON_FIRST_DIFFERENTIAL_ELEMENT)); + throw new Error("type on first differential element!"); for (ElementDefinition e : derived.getDifferential().getElement()) e.clearUserData(GENERATED_IN_SNAPSHOT); @@ -538,7 +536,7 @@ public class ProfileUtilities extends TranslatingUtilities { } if (!derived.getSnapshot().getElementFirstRep().getType().isEmpty()) - throw new Error(context.formatMessage(I18nConstants.TYPE_ON_FIRST_SNAPSHOT_ELEMENT_FOR__IN__FROM_, derived.getSnapshot().getElementFirstRep().getPath(), derived.getUrl(), base.getUrl())); + throw new Error("type on first snapshot element for "+derived.getSnapshot().getElementFirstRep().getPath()+" in "+derived.getUrl()+" from "+base.getUrl()); updateMaps(base, derived); if (debug) { @@ -555,7 +553,7 @@ public class ProfileUtilities extends TranslatingUtilities { int ce = 0; for (ElementDefinition e : diff.getElement()) { if (!e.hasUserData("diff-source")) - throw new Error(context.formatMessage(I18nConstants.UNXPECTED_INTERNAL_CONDITION__NO_SOURCE_ON_DIFF_ELEMENT)); + throw new Error("Unxpected internal condition - no source on diff element"); else { if (e.hasUserData(DERIVATION_EQUALS)) ((Base) e.getUserData("diff-source")).setUserData(DERIVATION_EQUALS, e.getUserData(DERIVATION_EQUALS)); @@ -601,7 +599,7 @@ public class ProfileUtilities extends TranslatingUtilities { } } } - // last, check for wrong profiles or target profiles + // last, check for wrong profiles or target profiles for (ElementDefinition ed : derived.getSnapshot().getElement()) { for (TypeRefComponent t : ed.getType()) { for (UriType u : t.getProfile()) { @@ -641,14 +639,14 @@ public class ProfileUtilities extends TranslatingUtilities { boolean first = true; for (ElementDefinition ed : elements) { if (!ed.hasPath()) { - throw new FHIRException(context.formatMessage(I18nConstants.NO_PATH_ON_ELEMENT_IN_DIFFERENTIAL_IN_, url)); + throw new FHIRException("No path on element in differential in "+url); } String p = ed.getPath(); if (p == null) { - throw new FHIRException(context.formatMessage(I18nConstants.NO_PATH_VALUE_ON_ELEMENT_IN_DIFFERENTIAL_IN_, url)); + throw new FHIRException("No path value on element in differential in "+url); } if (!((first && type.equals(p)) || p.startsWith(type+"."))) { - throw new FHIRException(context.formatMessage(I18nConstants.ILLEGAL_PATH__IN_DIFFERENTIAL_IN__MUST_START_WITH_, p, url, type, (first ? " (o be '"+type+"')" : ""))); + throw new FHIRException("Illegal path '"+p+"' in differential in "+url+": must start with "+type+"."+(first ? " (o be '"+type+"')" : "")); } if (p.contains(".")) { // Element names (the parts of a path delineated by the '.' character) SHALL NOT contain whitespace (i.e. Unicode characters marked as whitespace) @@ -658,25 +656,25 @@ public class ProfileUtilities extends TranslatingUtilities { String[] pl = p.split("\\."); for (String pp : pl) { if (pp.length() < 1) { - throw new FHIRException(context.formatMessage(I18nConstants.ILLEGAL_PATH__IN_DIFFERENTIAL_IN__NAME_PORTION_MISING_, p, url)); + throw new FHIRException("Illegal path '"+p+"' in differential in "+url+": name portion mising ('..')"); } if (pp.length() > 64) { - throw new FHIRException(context.formatMessage(I18nConstants.ILLEGAL_PATH__IN_DIFFERENTIAL_IN__NAME_PORTION_EXCEEDS_64_CHARS_IN_LENGTH, p, url)); + throw new FHIRException("Illegal path '"+p+"' in differential in "+url+": name portion exceeds 64 chars in length"); } for (char ch : pp.toCharArray()) { if (Character.isWhitespace(ch)) { - throw new FHIRException(context.formatMessage(I18nConstants.ILLEGAL_PATH__IN_DIFFERENTIAL_IN__NO_UNICODE_WHITESPACE, p, url)); + throw new FHIRException("Illegal path '"+p+"' in differential in "+url+": no unicode whitespace"); } if (Utilities.existsInList(ch, ',', ':', ';', '\'', '"', '/', '|', '?', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '{', '}')) { - throw new FHIRException(context.formatMessage(I18nConstants.ILLEGAL_PATH__IN_DIFFERENTIAL_IN__ILLEGAL_CHARACTER_, p, url, ch)); + throw new FHIRException("Illegal path '"+p+"' in differential in "+url+": illegal character '"+ch+"'"); } if (ch < ' ' || ch > 'z') { - throw new FHIRException(context.formatMessage(I18nConstants.ILLEGAL_PATH__IN_DIFFERENTIAL_IN__ILLEGAL_CHARACTER_, p, url, ch)); + throw new FHIRException("Illegal path '"+p+"' in differential in "+url+": illegal character '"+ch+"'"); } } if (pp.contains("[") || pp.contains("]")) { if (!pp.endsWith("[x]") || (pp.substring(0, pp.length()-3).contains("[") || (pp.substring(0, pp.length()-3).contains("]")))) { - throw new FHIRException(context.formatMessage(I18nConstants.ILLEGAL_PATH__IN_DIFFERENTIAL_IN__ILLEGAL_CHARACTERS_, p, url)); + throw new FHIRException("Illegal path '"+p+"' in differential in "+url+": illegal characters []"); } } } @@ -830,7 +828,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (resultPathBase == null) resultPathBase = outcome.getPath(); else if (!outcome.getPath().startsWith(resultPathBase)) - throw new DefinitionException(context.formatMessage(I18nConstants.ADDING_WRONG_PATH__OUTCOMEGETPATH___RESULTPATHBASE__, outcome.getPath(), resultPathBase)); + throw new DefinitionException("Adding wrong path - outcome.getPath() = "+outcome.getPath()+", resultPathBase = "+resultPathBase); result.getElement().add(outcome); if (hasInnerDiffMatches(differential, cpath, diffCursor, diffLimit, base.getElement(), true)) { // well, the profile walks into this, so we need to as well @@ -840,17 +838,17 @@ public class ProfileUtilities extends TranslatingUtilities { baseCursor = indexOfFirstNonChild(base, currentBase, baseCursor+1, baseLimit); } else { if (outcome.getType().size() == 0) { - throw new DefinitionException(context.formatMessage(I18nConstants._HAS_NO_CHILDREN__AND_NO_TYPES_IN_PROFILE_, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), profileName)); + throw new DefinitionException(diffMatches.get(0).getPath()+" has no children ("+differential.getElement().get(diffCursor).getPath()+") and no types in profile "+profileName); } if (outcome.getType().size() > 1) { for (TypeRefComponent t : outcome.getType()) { if (!t.getWorkingCode().equals("Reference")) - throw new DefinitionException(context.formatMessage(I18nConstants._HAS_CHILDREN__AND_MULTIPLE_TYPES__IN_PROFILE_, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName)); + throw new DefinitionException(diffMatches.get(0).getPath()+" has children ("+differential.getElement().get(diffCursor).getPath()+") and multiple types ("+typeCode(outcome.getType())+") in profile "+profileName); } } StructureDefinition dt = getProfileForDataType(outcome.getType().get(0)); if (dt == null) - throw new DefinitionException(context.formatMessage(I18nConstants.UNKNOWN_TYPE__AT_, outcome.getType().get(0), diffMatches.get(0).getPath())); + throw new DefinitionException("Unknown type "+outcome.getType().get(0)+" at "+diffMatches.get(0).getPath()); contextName = dt.getUrl(); int start = diffCursor; while (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), cpath+".")) @@ -870,7 +868,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (!sd.hasSnapshot()) { StructureDefinition sdb = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition()); if (sdb == null) - throw new DefinitionException(context.formatMessage(I18nConstants.UNABLE_TO_FIND_BASE__FOR_, sd.getBaseDefinition(), sd.getUrl())); + throw new DefinitionException("Unable to find base "+sd.getBaseDefinition()+" for "+sd.getUrl()); checkNotGenerating(sdb, "an extension base"); generateSnapshot(sdb, sd, sd.getUrl(), (sdb.hasUserData("path")) ? Utilities.extractBaseUrl(sdb.getUserString("path")) : webUrl, sd.getName()); } @@ -883,7 +881,7 @@ public class ProfileUtilities extends TranslatingUtilities { src = t; } if (src == null) - throw new DefinitionException(context.formatMessage(I18nConstants.UNABLE_TO_FIND_ELEMENT__IN_, eid, p.getValue())); + throw new DefinitionException("Unable to find element "+eid+" in "+p.getValue()); } else src = sd.getSnapshot().getElement().get(0); template = src.copy().setPath(currentBase.getPath()); @@ -916,7 +914,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (resultPathBase == null) resultPathBase = outcome.getPath(); else if (!outcome.getPath().startsWith(resultPathBase)) - throw new DefinitionException(context.formatMessage(I18nConstants.ADDING_WRONG_PATH)); + throw new DefinitionException("Adding wrong path"); result.getElement().add(outcome); baseCursor++; diffCursor = differential.getElement().indexOf(diffMatches.get(0))+1; @@ -943,7 +941,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (ed != diffMatches.get(0) && !ed.getPath().endsWith(".extension")) nonExtension = true; if (nonExtension) - throw new DefinitionException(context.formatMessage(I18nConstants._HAS_CHILDREN__AND_MULTIPLE_TYPES__IN_PROFILE_, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName)); + throw new DefinitionException(diffMatches.get(0).getPath()+" has children ("+differential.getElement().get(diffCursor).getPath()+") and multiple types ("+typeCode(outcome.getType())+") in profile "+profileName); } } } @@ -953,7 +951,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (outcome.hasContentReference()) { ElementDefinition tgt = getElementById(base.getElement(), outcome.getContentReference()); if (tgt == null) - throw new DefinitionException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_REFERENCE_TO_, outcome.getContentReference())); + throw new DefinitionException("Unable to resolve reference to "+outcome.getContentReference()); replaceFromContentReference(outcome, tgt); int nbc = base.getElement().indexOf(tgt)+1; int nbl = nbc; @@ -963,7 +961,7 @@ public class ProfileUtilities extends TranslatingUtilities { } else { StructureDefinition dt = outcome.getType().size() == 1 ? getProfileForDataType(outcome.getType().get(0)) : getProfileForDataType("Element"); if (dt == null) - throw new DefinitionException(context.formatMessage(I18nConstants._HAS_CHILDREN__FOR_TYPE__IN_PROFILE__BUT_CANT_FIND_TYPE, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName)); + throw new DefinitionException(diffMatches.get(0).getPath()+" has children ("+differential.getElement().get(diffCursor).getPath()+") for type "+typeCode(outcome.getType())+" in profile "+profileName+", but can't find type"); contextName = dt.getUrl(); processPaths(indent+" ", result, dt.getSnapshot(), differential, 1 /* starting again on the data type, but skip the root */, start, dt.getSnapshot().getElement().size()-1, diffCursor - 1, url, getWebUrl(dt, webUrl, indent), profileName+pathTail(diffMatches, 0), diffMatches.get(0).getPath(), outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, new ArrayList(), srcSD); @@ -976,9 +974,9 @@ public class ProfileUtilities extends TranslatingUtilities { int ndc = differential.getElement().indexOf(diffMatches.get(0)); ElementDefinition elementToRemove = null; boolean shortCut = !typeList.isEmpty() && typeList.get(0).type != null; - // we come here whether they are sliced in the diff, or whether the short cut is used. + // we come here whether they are sliced in the diff, or whether the short cut is used. if (shortCut) { - // this is the short cut method, we've just dived in and specified a type slice. + // this is the short cut method, we've just dived in and specified a type slice. // in R3 (and unpatched R4, as a workaround right now... if (!FHIRVersion.isR4Plus(context.getVersion()) || !newSlicingProcessing) { // newSlicingProcessing is a work around for editorial loop dependency // we insert a cloned element with the right types at the start of the diffMatches @@ -994,9 +992,9 @@ public class ProfileUtilities extends TranslatingUtilities { differential.getElement().add(ndc, ed); elementToRemove = ed; } else { - // as of R4, this changed; if there's no slice, there's no constraint on the slice types, only one the type. - // so the element we insert specifies no types (= all types) allowed in the base, not just the listed type. - // see also discussion here: https://chat.fhir.org/#narrow/stream/179177-conformance/topic/Slicing.20a.20non-repeating.20element + // as of R4, this changed; if there's no slice, there's no constraint on the slice types, only one the type. + // so the element we insert specifies no types (= all types) allowed in the base, not just the listed type. + // see also discussion here: https://chat.fhir.org/#narrow/stream/179177-conformance/topic/Slicing.20a.20non-repeating.20element ElementDefinition ed = new ElementDefinition(); ed.setPath(determineTypeSlicePath(diffMatches.get(0).getPath(), cpath)); ed.setSlicing(new ElementDefinitionSlicingComponent()); @@ -1013,18 +1011,18 @@ public class ProfileUtilities extends TranslatingUtilities { if (diffMatches.get(0).getSlicing().hasOrdered()) { if (diffMatches.get(0).getSlicing().getOrdered()) { - throw new FHIRException(context.formatMessage(I18nConstants.ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGORDERED__TRUE, cpath, url)); + throw new FHIRException("Error at path "+cpath+" in "+url+": Type slicing with slicing.ordered = true"); } } if (diffMatches.get(0).getSlicing().hasDiscriminator()) { if (diffMatches.get(0).getSlicing().getDiscriminator().size() != 1) { - throw new FHIRException(context.formatMessage(I18nConstants.ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGDISCRIMINATORCOUNT__1, cpath, url)); + throw new FHIRException("Error at path "+cpath+" in "+url+": Type slicing with slicing.discriminator.count() > 1"); } if (diffMatches.get(0).getSlicing().getDiscriminatorFirstRep().getType() != DiscriminatorType.TYPE) { - throw new FHIRException(context.formatMessage(I18nConstants.ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGDISCRIMINATORTYPE__TYPE, cpath, url)); + throw new FHIRException("Error at path "+cpath+" in "+url+": Type slicing with slicing.discriminator.type != 'type'"); } if (!"$this".equals(diffMatches.get(0).getSlicing().getDiscriminatorFirstRep().getPath())) { - throw new FHIRException(context.formatMessage(I18nConstants.ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGDISCRIMINATORPATH__THIS, cpath, url)); + throw new FHIRException("Error at path "+cpath+" in "+url+": Type slicing with slicing.discriminator.path != '$this'"); } } // check the slice names too while we're at it... @@ -1037,28 +1035,28 @@ public class ProfileUtilities extends TranslatingUtilities { if (autoFixSliceNames) { ts.defn.setSliceName(tn); } else { - throw new FHIRException(context.formatMessage(I18nConstants.ERROR_AT_PATH__SLICE_NAME_MUST_BE__BUT_IS_, (!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath), tn, ts.defn.getSliceName())); + throw new FHIRException("Error at path "+(!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath)+": Slice name must be '"+tn+"' but is '"+ts.defn.getSliceName()+"'"); } } if (!ts.defn.hasType()) { ts.defn.addType().setCode(ts.type); } else if (ts.defn.getType().size() > 1) { - throw new FHIRException(context.formatMessage(I18nConstants.ERROR_AT_PATH__SLICE_FOR_TYPE__HAS_MORE_THAN_ONE_TYPE_, (!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath), tn, ts.defn.typeSummary())); + throw new FHIRException("Error at path "+(!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath)+": Slice for type '"+tn+"' has more than one type '"+ts.defn.typeSummary()+"'"); } else if (!ts.defn.getType().get(0).getCode().equals(ts.type)) { - throw new FHIRException(context.formatMessage(I18nConstants.ERROR_AT_PATH__SLICE_FOR_TYPE__HAS_WRONG_TYPE_, (!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath), tn, ts.defn.typeSummary())); + throw new FHIRException("Error at path "+(!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath)+": Slice for type '"+tn+"' has wrong type '"+ts.defn.typeSummary()+"'"); } } } - // ok passed the checks. + // ok passed the checks. // copy the root diff, and then process any children it has ElementDefinition e = processPaths(indent+" ", result, base, differential, baseCursor, ndc, nbl, ndl, url, webUrl, profileName+pathTail(diffMatches, 0), contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, true, null, redirector, srcSD); if (e==null) - throw new FHIRException(context.formatMessage(I18nConstants.DID_NOT_FIND_TYPE_ROOT_, diffMatches.get(0).getPath())); + throw new FHIRException("Did not find type root: " + diffMatches.get(0).getPath()); // now set up slicing on the e (cause it was wiped by what we called. e.setSlicing(new ElementDefinitionSlicingComponent()); e.getSlicing().addDiscriminator().setType(DiscriminatorType.TYPE).setPath("$this"); - e.getSlicing().setRules(SlicingRules.CLOSED); // type slicing is always closed; the differential might call it open, but that just means it's not constraining the slices it doesn't mention + e.getSlicing().setRules(SlicingRules.CLOSED); // type slicing is always closed; the differential might call it open, but that just means it's not constraining the slices it doesn't mention e.getSlicing().setOrdered(false); start++; @@ -1069,7 +1067,7 @@ public class ProfileUtilities extends TranslatingUtilities { // our processing scope for the differential is the item in the list, and all the items before the next one in the list if (diffMatches.get(i).getMin() > 0) { if (diffMatches.size() > i+1) { - throw new FHIRException(context.formatMessage(I18nConstants.INVALID_SLICING__THERE_IS_MORE_THAN_ONE_TYPE_SLICE_AT__BUT_ONE_OF_THEM__HAS_MIN__1_SO_THE_OTHER_SLICES_CANNOT_EXIST, diffMatches.get(i).getPath(), diffMatches.get(i).getSliceName())); + throw new FHIRException("Invalid slicing : there is more than one type slice at "+diffMatches.get(i).getPath()+", but one of them ("+diffMatches.get(i).getSliceName()+") has min = 1, so the other slices cannot exist"); } else { e.setMin(1); } @@ -1101,9 +1099,9 @@ public class ProfileUtilities extends TranslatingUtilities { if (!unbounded(currentBase) && !isSlicedToOneOnly(diffMatches.get(0))) // you can only slice an element that doesn't repeat if the sum total of your slices is limited to 1 // (but you might do that in order to split up constraints by type) - throw new DefinitionException(context.formatMessage(I18nConstants.ATTEMPT_TO_A_SLICE_AN_ELEMENT_THAT_DOES_NOT_REPEAT__FROM__IN_, currentBase.getPath(), currentBase.getPath(), contextName, url)); + throw new DefinitionException("Attempt to a slice an element that does not repeat: "+currentBase.getPath()+"/"+currentBase.getPath()+" from "+contextName+" in "+url); if (!diffMatches.get(0).hasSlicing() && !isExtension(currentBase)) // well, the diff has set up a slice, but hasn't defined it. this is an error - throw new DefinitionException(context.formatMessage(I18nConstants.DIFFERENTIAL_DOES_NOT_HAVE_A_SLICE__B_OF_____IN_PROFILE_, currentBase.getPath(), baseCursor, baseLimit, diffCursor, diffLimit, url)); + throw new DefinitionException("Differential does not have a slice: "+currentBase.getPath()+"/ (b:"+baseCursor+" of "+ baseLimit+" / "+ diffCursor +"/ "+diffLimit+") in profile "+url); // well, if it passed those preconditions then we slice the dest. int start = 0; @@ -1115,7 +1113,7 @@ public class ProfileUtilities extends TranslatingUtilities { ElementDefinition e = processPaths(indent+" ", result, base, differential, baseCursor, ndc, nbl, ndl, url, webUrl, profileName+pathTail(diffMatches, 0), contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, true, null, redirector, srcSD); if (e==null) - throw new FHIRException(context.formatMessage(I18nConstants.DID_NOT_FIND_SINGLE_SLICE_, diffMatches.get(0).getPath())); + throw new FHIRException("Did not find single slice: " + diffMatches.get(0).getPath()); e.setSlicing(diffMatches.get(0).getSlicing()); start++; } else { @@ -1129,7 +1127,7 @@ public class ProfileUtilities extends TranslatingUtilities { else outcome.setSlicing(diffMatches.get(0).getSlicing().copy()); if (!outcome.getPath().startsWith(resultPathBase)) - throw new DefinitionException(context.formatMessage(I18nConstants.ADDING_WRONG_PATH)); + throw new DefinitionException("Adding wrong path"); result.getElement().add(outcome); // differential - if the first one in the list has a name, we'll process it. Else we'll treat it as the base definition of the slice. @@ -1137,7 +1135,7 @@ public class ProfileUtilities extends TranslatingUtilities { updateFromDefinition(outcome, diffMatches.get(0), profileName, trimDifferential, url, srcSD); removeStatusExtensions(outcome); if (!outcome.hasContentReference() && !outcome.hasType()) { - throw new DefinitionException(context.formatMessage(I18nConstants.NOT_DONE_YET)); + throw new DefinitionException("not done yet"); } start++; // result.getElement().remove(result.getElement().size()-1); @@ -1186,7 +1184,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (resultPathBase == null) resultPathBase = outcome.getPath(); else if (!outcome.getPath().startsWith(resultPathBase)) - throw new DefinitionException(context.formatMessage(I18nConstants.ADDING_WRONG_PATH)); + throw new DefinitionException("Adding wrong path"); result.getElement().add(outcome); // the profile walks into this, so we need to as well // did we implicitly step into a new type? @@ -1195,17 +1193,17 @@ public class ProfileUtilities extends TranslatingUtilities { baseCursor = indexOfFirstNonChild(base, currentBase, baseCursor, baseLimit); } else { if (outcome.getType().size() == 0) { - throw new DefinitionException(context.formatMessage(I18nConstants._HAS_NO_CHILDREN__AND_NO_TYPES_IN_PROFILE_, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), profileName)); + throw new DefinitionException(diffMatches.get(0).getPath()+" has no children ("+differential.getElement().get(diffCursor).getPath()+") and no types in profile "+profileName); } if (outcome.getType().size() > 1) { for (TypeRefComponent t : outcome.getType()) { if (!t.getWorkingCode().equals("Reference")) - throw new DefinitionException(context.formatMessage(I18nConstants._HAS_CHILDREN__AND_MULTIPLE_TYPES__IN_PROFILE_, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName)); + throw new DefinitionException(diffMatches.get(0).getPath()+" has children ("+differential.getElement().get(diffCursor).getPath()+") and multiple types ("+typeCode(outcome.getType())+") in profile "+profileName); } } StructureDefinition dt = getProfileForDataType(outcome.getType().get(0)); if (dt == null) - throw new DefinitionException(context.formatMessage(I18nConstants.UNKNOWN_TYPE__AT_, outcome.getType().get(0), diffMatches.get(0).getPath())); + throw new DefinitionException("Unknown type "+outcome.getType().get(0)+" at "+diffMatches.get(0).getPath()); contextName = dt.getUrl(); int start = diffCursor; while (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), cpath+".")) @@ -1221,7 +1219,7 @@ public class ProfileUtilities extends TranslatingUtilities { ElementDefinition outcome = updateURLs(url, webUrl, base.getElement().get(baseCursor).copy()); outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc)); if (!outcome.getPath().startsWith(resultPathBase)) - throw new DefinitionException(context.formatMessage(I18nConstants.ADDING_WRONG_PATH_IN_PROFILE___VS_, profileName, outcome.getPath(), resultPathBase)); + throw new DefinitionException("Adding wrong path in profile " + profileName + ": "+outcome.getPath()+" vs " + resultPathBase); result.getElement().add(outcome); // so we just copy it in baseCursor++; } @@ -1232,9 +1230,9 @@ public class ProfileUtilities extends TranslatingUtilities { int ndc = differential.getElement().indexOf(diffMatches.get(0)); ElementDefinition elementToRemove = null; boolean shortCut = (!typeList.isEmpty() && typeList.get(0).type != null) || (diffMatches.get(0).hasSliceName() && !diffMatches.get(0).hasSlicing()); - // we come here whether they are sliced in the diff, or whether the short cut is used. + // we come here whether they are sliced in the diff, or whether the short cut is used. if (shortCut) { - // this is the short cut method, we've just dived in and specified a type slice. + // this is the short cut method, we've just dived in and specified a type slice. // in R3 (and unpatched R4, as a workaround right now... if (!FHIRVersion.isR4Plus(context.getVersion()) || !newSlicingProcessing) { // newSlicingProcessing is a work around for editorial loop dependency // we insert a cloned element with the right types at the start of the diffMatches @@ -1250,9 +1248,9 @@ public class ProfileUtilities extends TranslatingUtilities { differential.getElement().add(ndc, ed); elementToRemove = ed; } else { - // as of R4, this changed; if there's no slice, there's no constraint on the slice types, only one the type. - // so the element we insert specifies no types (= all types) allowed in the base, not just the listed type. - // see also discussion here: https://chat.fhir.org/#narrow/stream/179177-conformance/topic/Slicing.20a.20non-repeating.20element + // as of R4, this changed; if there's no slice, there's no constraint on the slice types, only one the type. + // so the element we insert specifies no types (= all types) allowed in the base, not just the listed type. + // see also discussion here: https://chat.fhir.org/#narrow/stream/179177-conformance/topic/Slicing.20a.20non-repeating.20element ElementDefinition ed = new ElementDefinition(); ed.setPath(determineTypeSlicePath(diffMatches.get(0).getPath(), cpath)); ed.setSlicing(new ElementDefinitionSlicingComponent()); @@ -1269,18 +1267,18 @@ public class ProfileUtilities extends TranslatingUtilities { if (diffMatches.get(0).getSlicing().hasOrdered()) { if (diffMatches.get(0).getSlicing().getOrdered()) { - throw new FHIRException(context.formatMessage(I18nConstants.ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGORDERED__TRUE, cpath, url)); + throw new FHIRException("Error at path "+cpath+" in "+url+": Type slicing with slicing.ordered = true"); } } if (diffMatches.get(0).getSlicing().hasDiscriminator()) { if (diffMatches.get(0).getSlicing().getDiscriminator().size() != 1) { - throw new FHIRException(context.formatMessage(I18nConstants.ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGDISCRIMINATORCOUNT__1, cpath, url)); + throw new FHIRException("Error at path "+cpath+" in "+url+": Type slicing with slicing.discriminator.count() > 1"); } if (diffMatches.get(0).getSlicing().getDiscriminatorFirstRep().getType() != DiscriminatorType.TYPE) { - throw new FHIRException(context.formatMessage(I18nConstants.ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGDISCRIMINATORTYPE__TYPE, cpath, url)); + throw new FHIRException("Error at path "+cpath+" in "+url+": Type slicing with slicing.discriminator.type != 'type'"); } if (!"$this".equals(diffMatches.get(0).getSlicing().getDiscriminatorFirstRep().getPath())) { - throw new FHIRException(context.formatMessage(I18nConstants.ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGDISCRIMINATORPATH__THIS, cpath, url)); + throw new FHIRException("Error at path "+cpath+" in "+url+": Type slicing with slicing.discriminator.path != '$this'"); } } // check the slice names too while we're at it... @@ -1290,27 +1288,27 @@ public class ProfileUtilities extends TranslatingUtilities { if (!ts.defn.hasSliceName()) { ts.defn.setSliceName(tn); } else if (!ts.defn.getSliceName().equals(tn)) { - throw new FHIRException(context.formatMessage(I18nConstants.ERROR_AT_PATH__SLICE_NAME_MUST_BE__BUT_IS_, (!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath), tn, ts.defn.getSliceName())); + throw new FHIRException("Error at path "+(!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath)+": Slice name must be '"+tn+"' but is '"+ts.defn.getSliceName()+"'"); } if (!ts.defn.hasType()) { ts.defn.addType().setCode(ts.type); } else if (ts.defn.getType().size() > 1) { - throw new FHIRException(context.formatMessage(I18nConstants.ERROR_AT_PATH__SLICE_FOR_TYPE__HAS_MORE_THAN_ONE_TYPE_, (!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath), tn, ts.defn.typeSummary())); + throw new FHIRException("Error at path "+(!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath)+": Slice for type '"+tn+"' has more than one type '"+ts.defn.typeSummary()+"'"); } else if (!ts.defn.getType().get(0).getCode().equals(ts.type)) { - throw new FHIRException(context.formatMessage(I18nConstants.ERROR_AT_PATH__SLICE_FOR_TYPE__HAS_WRONG_TYPE_, (!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath), tn, ts.defn.typeSummary())); + throw new FHIRException("Error at path "+(!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath)+": Slice for type '"+tn+"' has wrong type '"+ts.defn.typeSummary()+"'"); } } } - // ok passed the checks. + // ok passed the checks. // copy the root diff, and then process any children it has ElementDefinition e = processPaths(indent+" ", result, base, differential, baseCursor, ndc, nbl, ndl, url, webUrl, profileName+pathTail(diffMatches, 0), contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, true, cpath, redirector, srcSD); if (e==null) - throw new FHIRException(context.formatMessage(I18nConstants.DID_NOT_FIND_TYPE_ROOT_, diffMatches.get(0).getPath())); + throw new FHIRException("Did not find type root: " + diffMatches.get(0).getPath()); // now set up slicing on the e (cause it was wiped by what we called. e.setSlicing(new ElementDefinitionSlicingComponent()); e.getSlicing().addDiscriminator().setType(DiscriminatorType.TYPE).setPath("$this"); - e.getSlicing().setRules(SlicingRules.CLOSED); // type slicing is always closed; the differential might call it open, but that just means it's not constraining the slices it doesn't mention + e.getSlicing().setRules(SlicingRules.CLOSED); // type slicing is always closed; the differential might call it open, but that just means it's not constraining the slices it doesn't mention e.getSlicing().setOrdered(false); start++; @@ -1323,7 +1321,7 @@ public class ProfileUtilities extends TranslatingUtilities { // our processing scope for the differential is the item in the list, and all the items before the next one in the list if (diffMatches.get(i).getMin() > 0) { if (diffMatches.size() > i+1) { - throw new FHIRException(context.formatMessage(I18nConstants.INVALID_SLICING__THERE_IS_MORE_THAN_ONE_TYPE_SLICE_AT__BUT_ONE_OF_THEM__HAS_MIN__1_SO_THE_OTHER_SLICES_CANNOT_EXIST, diffMatches.get(i).getPath(), diffMatches.get(i).getSliceName())); + throw new FHIRException("Invalid slicing : there is more than one type slice at "+diffMatches.get(i).getPath()+", but one of them ("+diffMatches.get(i).getSliceName()+") has min = 1, so the other slices cannot exist"); } fixedType = type; } @@ -1375,11 +1373,11 @@ public class ProfileUtilities extends TranslatingUtilities { ElementDefinitionSlicingComponent dSlice = diffMatches.get(0).getSlicing(); ElementDefinitionSlicingComponent bSlice = currentBase.getSlicing(); if (dSlice.hasOrderedElement() && bSlice.hasOrderedElement() && !orderMatches(dSlice.getOrderedElement(), bSlice.getOrderedElement())) - throw new DefinitionException(context.formatMessage(I18nConstants.SLICING_RULES_ON_DIFFERENTIAL__DO_NOT_MATCH_THOSE_ON_BASE___ORDER___, summarizeSlicing(dSlice), summarizeSlicing(bSlice), path, contextName)); + throw new DefinitionException("Slicing rules on differential ("+summarizeSlicing(dSlice)+") do not match those on base ("+summarizeSlicing(bSlice)+") - order @ "+path+" ("+contextName+")"); if (!discriminatorMatches(dSlice.getDiscriminator(), bSlice.getDiscriminator())) - throw new DefinitionException(context.formatMessage(I18nConstants.SLICING_RULES_ON_DIFFERENTIAL__DO_NOT_MATCH_THOSE_ON_BASE___DISCIMINATOR___, summarizeSlicing(dSlice), summarizeSlicing(bSlice), path, contextName)); + throw new DefinitionException("Slicing rules on differential ("+summarizeSlicing(dSlice)+") do not match those on base ("+summarizeSlicing(bSlice)+") - disciminator @ "+path+" ("+contextName+")"); if (!currentBase.isChoice() && !ruleMatches(dSlice.getRules(), bSlice.getRules())) - throw new DefinitionException(context.formatMessage(I18nConstants.SLICING_RULES_ON_DIFFERENTIAL__DO_NOT_MATCH_THOSE_ON_BASE___RULE___, summarizeSlicing(dSlice), summarizeSlicing(bSlice), path, contextName)); + throw new DefinitionException("Slicing rules on differential ("+summarizeSlicing(dSlice)+") do not match those on base ("+summarizeSlicing(bSlice)+") - rule @ "+path+" ("+contextName+")"); } ElementDefinition outcome = updateURLs(url, webUrl, currentBase.copy()); outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc)); @@ -1389,7 +1387,7 @@ public class ProfileUtilities extends TranslatingUtilities { updateFromDefinition(outcome, diffMatches.get(0), profileName, closed, url, srcSD); // if there's no slice, we don't want to update the unsliced description removeStatusExtensions(outcome); } else if (!diffMatches.get(0).hasSliceName()) - diffMatches.get(0).setUserData(GENERATED_IN_SNAPSHOT, outcome); // because of updateFromDefinition isn't called + diffMatches.get(0).setUserData(GENERATED_IN_SNAPSHOT, outcome); // because of updateFromDefinition isn't called result.getElement().add(outcome); @@ -1403,11 +1401,11 @@ public class ProfileUtilities extends TranslatingUtilities { int ndl = findEndOfElement(differential, ndx); if (nbl == baseCursor) { if (base.getElement().get(baseCursor).getType().size() != 1) { - throw new Error(context.formatMessage(I18nConstants.DIFFERENTIAL_WALKS_INTO____BUT_THE_BASE_DOES_NOT_AND_THERE_IS_NOT_A_SINGLE_FIXED_TYPE_THE_TYPE_IS__THIS_IS_NOT_HANDLED_YET, cpath, diffMatches.get(0).toString(), base.getElement().get(baseCursor).typeSummary())); + throw new Error("Differential walks into '"+cpath+" (@ "+diffMatches.get(0).toString()+")', but the base does not, and there is not a single fixed type. The type is "+base.getElement().get(baseCursor).typeSummary()+". This is not handled yet"); } StructureDefinition dt = getProfileForDataType(base.getElement().get(baseCursor).getType().get(0)); if (dt == null) { - throw new DefinitionException(context.formatMessage(I18nConstants.UNKNOWN_TYPE__AT_, outcome.getType().get(0), diffMatches.get(0).getPath())); + throw new DefinitionException("Unknown type "+outcome.getType().get(0)+" at "+diffMatches.get(0).getPath()); } contextName = dt.getUrl(); while (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), cpath+".")) @@ -1438,7 +1436,7 @@ public class ProfileUtilities extends TranslatingUtilities { outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc)); outcome.setSlicing(null); if (!outcome.getPath().startsWith(resultPathBase)) - throw new DefinitionException(context.formatMessage(I18nConstants.ADDING_WRONG_PATH)); + throw new DefinitionException("Adding wrong path"); if (diffpos < diffMatches.size() && diffMatches.get(diffpos).hasSliceName() && diffMatches.get(diffpos).getSliceName().equals(outcome.getSliceName())) { // if there's a diff, we update the outcome with diff // no? updateFromDefinition(outcome, diffMatches.get(diffpos), profileName, closed, url); @@ -1460,7 +1458,7 @@ public class ProfileUtilities extends TranslatingUtilities { outcome = updateURLs(url, webUrl, base.getElement().get(baseCursor).copy()); outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc)); if (!outcome.getPath().startsWith(resultPathBase)) - throw new DefinitionException(context.formatMessage(I18nConstants.ADDING_WRONG_PATH)); + throw new DefinitionException("Adding wrong path"); result.getElement().add(outcome); baseCursor++; } @@ -1471,11 +1469,11 @@ public class ProfileUtilities extends TranslatingUtilities { // finally, we process any remaining entries in diff, which are new (and which are only allowed if the base wasn't closed boolean checkImplicitTypes = false; if (closed && diffpos < diffMatches.size()) { - // this is a problem, unless we're on a polymorhpic type and we're going to constrain a slice that actually implicitly exists + // this is a problem, unless we're on a polymorhpic type and we're going to constrain a slice that actually implicitly exists if (currentBase.getPath().endsWith("[x]")) { checkImplicitTypes = true; } else { - throw new DefinitionException(context.formatMessage(I18nConstants.THE_BASE_SNAPSHOT_MARKS_A_SLICING_AS_CLOSED_BUT_THE_DIFFERENTIAL_TRIES_TO_EXTEND_IT_IN__AT__, profileName, path, cpath)); + throw new DefinitionException("The base snapshot marks a slicing as closed, but the differential tries to extend it in "+profileName+" at "+path+" ("+cpath+")"); } } if (diffpos == diffMatches.size()) { @@ -1486,14 +1484,14 @@ public class ProfileUtilities extends TranslatingUtilities { ElementDefinition diffItem = diffMatches.get(diffpos); for (ElementDefinition baseItem : baseMatches) if (baseItem.getSliceName().equals(diffItem.getSliceName())) - throw new DefinitionException(context.formatMessage(I18nConstants.NAMED_ITEMS_ARE_OUT_OF_ORDER_IN_THE_SLICE)); + throw new DefinitionException("Named items are out of order in the slice"); outcome = updateURLs(url, webUrl, currentBase.copy()); // outcome = updateURLs(url, diffItem.copy()); outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc)); updateFromBase(outcome, currentBase); outcome.setSlicing(null); if (!outcome.getPath().startsWith(resultPathBase)) - throw new DefinitionException(context.formatMessage(I18nConstants.ADDING_WRONG_PATH)); + throw new DefinitionException("Adding wrong path"); result.getElement().add(outcome); updateFromDefinition(outcome, diffItem, profileName, trimDifferential, url, srcSD); removeStatusExtensions(outcome); @@ -1505,7 +1503,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (outcome.getType().size() > 1) for (TypeRefComponent t : outcome.getType()) { if (!t.getCode().equals("Reference")) - throw new DefinitionException(context.formatMessage(I18nConstants._HAS_CHILDREN__AND_MULTIPLE_TYPES__IN_PROFILE_, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName)); + throw new DefinitionException(diffMatches.get(0).getPath()+" has children ("+differential.getElement().get(diffCursor).getPath()+") and multiple types ("+typeCode(outcome.getType())+") in profile "+profileName); } TypeRefComponent t = outcome.getType().get(0); if (t.getCode().equals("BackboneElement")) { @@ -1522,10 +1520,10 @@ public class ProfileUtilities extends TranslatingUtilities { } else { StructureDefinition dt = getProfileForDataType(outcome.getType().get(0)); // if (t.getCode().equals("Extension") && t.hasProfile() && !t.getProfile().contains(":")) { - // lloydfix dt = + // lloydfix dt = // } if (dt == null) - throw new DefinitionException(context.formatMessage(I18nConstants._HAS_CHILDREN__FOR_TYPE__IN_PROFILE__BUT_CANT_FIND_TYPE, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName)); + throw new DefinitionException(diffMatches.get(0).getPath()+" has children ("+differential.getElement().get(diffCursor).getPath()+") for type "+typeCode(outcome.getType())+" in profile "+profileName+", but can't find type"); contextName = dt.getUrl(); int start = diffCursor; while (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), diffMatches.get(0).getPath()+".")) @@ -1549,7 +1547,7 @@ public class ProfileUtilities extends TranslatingUtilities { for (ElementDefinition e : result.getElement()) { i++; if (e.hasMinElement() && e.getMinElement().getValue()==null) - throw new Error(context.formatMessage(I18nConstants.NULL_MIN)); + throw new Error("null min"); } return res; } @@ -1557,7 +1555,7 @@ public class ProfileUtilities extends TranslatingUtilities { private void checkNotGenerating(StructureDefinition sd, String role) { if (sd.hasUserData("profileutils.snapshot.generating")) { - throw new FHIRException(context.formatMessage(I18nConstants.ATTEMPT_TO_USE_A_SNAPSHOT_ON_PROFILE__AS__BEFORE_IT_IS_GENERATED, sd.getUrl(), role)); + throw new FHIRException("Attempt to use a snapshot on profile '"+sd.getUrl()+"' as "+role+" before it is generated"); } } @@ -1582,12 +1580,12 @@ public class ProfileUtilities extends TranslatingUtilities { } else if (isPrimitive(Utilities.uncapitalize(t))) { fixedType = Utilities.uncapitalize(t); } else { - throw new FHIRException(context.formatMessage(I18nConstants.UNEXPECTED_CONDITION_IN_DIFFERENTIAL_TYPESLICETYPELISTSIZE__10_AND_IMPLICIT_SLICE_NAME_DOES_NOT_CONTAIN_A_VALID_TYPE__AT_, t, diffMatches.get(i).getPath(), diffMatches.get(i).getSliceName())); + throw new FHIRException("Unexpected condition in differential: type-slice.type-list.size() == 10 and implicit slice name does not contain a valid type ('"+t+"'?) at "+diffMatches.get(i).getPath()+"/"+diffMatches.get(i).getSliceName()); } } else if (diffMatches.get(i).getType().size() == 1) { fixedType = diffMatches.get(i).getType().get(0).getCode(); } else { - throw new FHIRException(context.formatMessage(I18nConstants.UNEXPECTED_CONDITION_IN_DIFFERENTIAL_TYPESLICETYPELISTSIZE__1_AT_, diffMatches.get(i).getPath(), diffMatches.get(i).getSliceName())); + throw new FHIRException("Unexpected condition in differential: type-slice.type-list.size() != 1 at "+diffMatches.get(i).getPath()+"/"+diffMatches.get(i).getSliceName()); } return fixedType; } @@ -2156,14 +2154,14 @@ public class ProfileUtilities extends TranslatingUtilities { for (int j = 0; j < p.length; j++) { ok = ok && sp.length > j && (p[j].equals(sp[j]) || isSameBase(p[j], sp[j])); } -// don't need this debug check - everything is ok -// if (ok != (statedPath.equals(path) || (path.endsWith("[x]") && statedPath.length() > path.length() - 2 && -// statedPath.substring(0, path.length()-3).equals(path.substring(0, path.length()-3)) && +// don't need this debug check - everything is ok +// if (ok != (statedPath.equals(path) || (path.endsWith("[x]") && statedPath.length() > path.length() - 2 && +// statedPath.substring(0, path.length()-3).equals(path.substring(0, path.length()-3)) && // (statedPath.length() < path.length() || !statedPath.substring(path.length()).contains("."))))) { // System.out.println("mismatch in paths: "+statedPath +" vs " +path); // } if (ok) { - /* + /* * Commenting this out because it raises warnings when profiling inherited elements. For example, * Error: unknown element 'Bundle.meta.profile' (or it is out of order) in profile ... (looking for 'Bundle.entry') * Not sure we have enough information here to do the check properly. Might be better done when we're sorting the profile? @@ -2319,7 +2317,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (derived.hasMinElement()) { if (!Base.compareDeep(derived.getMinElement(), base.getMinElement(), false)) { - if (derived.getMin() < base.getMin() && !derived.hasSliceName()) // in a slice, minimum cardinality rules do not apply + if (derived.getMin() < base.getMin() && !derived.hasSliceName()) // in a slice, minimum cardinality rules do not apply messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+source.getPath(), "Element "+base.getPath()+": derived min ("+Integer.toString(derived.getMin())+") cannot be less than base min ("+Integer.toString(base.getMin())+")", ValidationMessage.IssueSeverity.ERROR)); base.setMinElement(derived.getMinElement().copy()); } else if (trimDifferential) @@ -2462,7 +2460,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (derived.hasIsSummaryElement()) { if (!Base.compareDeep(derived.getIsSummaryElement(), base.getIsSummaryElement(), false)) { if (base.hasIsSummary()) - throw new Error(context.formatMessage(I18nConstants.ERROR_IN_PROFILE__AT__BASE_ISSUMMARY___DERIVED_ISSUMMARY__, pn, derived.getPath(), base.getIsSummaryElement().asStringValue(), derived.getIsSummaryElement().asStringValue())); + throw new Error("Error in profile "+pn+" at "+derived.getPath()+": Base isSummary = "+base.getIsSummaryElement().asStringValue()+", derived isSummary = "+derived.getIsSummaryElement().asStringValue()); base.setIsSummaryElement(derived.getIsSummaryElement().copy()); } else if (trimDifferential) derived.setIsSummaryElement(null); @@ -2589,7 +2587,7 @@ public class ProfileUtilities extends TranslatingUtilities { ok = true; } if (ok && ts.hasTargetProfile()) { - // check that any derived target has a reference chain back to one of the base target profiles + // check that any derived target has a reference chain back to one of the base target profiles for (UriType u : ts.getTargetProfile()) { String url = u.getValue(); boolean tgtOk = !td.hasTargetProfile() || td.hasTargetProfile(url); @@ -2608,7 +2606,7 @@ public class ProfileUtilities extends TranslatingUtilities { } if (!tgtOk) { if (messages == null) { - throw new FHIRException(context.formatMessage(I18nConstants.ERROR_AT__THE_TARGET_PROFILE__IS_NOT__VALID_CONSTRAINT_ON_THE_BASE_, purl, derived.getPath(), url, td.getTargetProfile())); + throw new FHIRException("Error at "+purl+"#"+derived.getPath()+": The target profile "+url+" is not valid constraint on the base ("+td.getTargetProfile()+")"); } else { messages.add(new ValidationMessage(Source.InstanceValidator, IssueType.BUSINESSRULE, derived.getPath(), "The target profile "+u.getValue()+" is not a valid constraint on the base ("+td.getTargetProfile()+") at "+derived.getPath(), IssueSeverity.ERROR)); } @@ -2617,7 +2615,7 @@ public class ProfileUtilities extends TranslatingUtilities { } } if (!ok) { - throw new DefinitionException(context.formatMessage(I18nConstants.STRUCTUREDEFINITION__AT__ILLEGAL_CONSTRAINED_TYPE__FROM__IN_, purl, derived.getPath(), t, b.toString(), srcSD.getUrl())); + throw new DefinitionException("StructureDefinition "+purl+" at "+derived.getPath()+": illegal constrained type "+t+" from "+b.toString()+" in "+srcSD.getUrl()); } } @@ -3196,7 +3194,7 @@ public class ProfileUtilities extends TranslatingUtilities { try { return gen.generate(model, imagePath, 0, outputTracker); } catch (org.hl7.fhir.exceptions.FHIRException e) { - throw new FHIRException(context.formatMessage(I18nConstants.ERROR_GENERATING_TABLE_FOR_PROFILE__, profile.getUrl(), e.getMessage()), e); + throw new FHIRException("Error generating table for profile " + profile.getUrl() + ": " + e.getMessage(), e); } } @@ -3206,7 +3204,7 @@ public class ProfileUtilities extends TranslatingUtilities { while (i < list.size()) { String[] pathCurrent = list.get(i).getPath().split("\\."); String[] pathLast = list.get(i-1).getPath().split("\\."); - int firstDiff = 0; // the first entry must be a match + int firstDiff = 0; // the first entry must be a match while (firstDiff < pathCurrent.length && firstDiff < pathLast.length && pathCurrent[firstDiff].equals(pathLast[firstDiff])) { firstDiff++; } @@ -3756,7 +3754,7 @@ public class ProfileUtilities extends TranslatingUtilities { ref = p.startsWith("http:") || igmode ? p : Utilities.pathURL(corePath, p); } fixedUrl = getFixedUrl(ed); - if (fixedUrl != null) {// if its null, we guess that it's not a profiled extension? + if (fixedUrl != null) {// if its null, we guess that it's not a profiled extension? if (fixedUrl.equals(url)) fixedUrl = null; else { @@ -4023,7 +4021,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (ed.getPath().equals(path)) return ed; } - throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_FIND_ELEMENT_, path)); + throw new FHIRException("Unable to find element "+path); } @@ -4292,7 +4290,7 @@ public class ProfileUtilities extends TranslatingUtilities { return sd.getType(); if (Utilities.existsInList(value, "SimpleQuantity", "MoneyQuantity")) return "Quantity"; - throw new Error(context.formatMessage(I18nConstants.INTERNAL_ERROR___TYPE_NOT_KNOWN_, value)); + throw new Error("Internal error - type not known "+value); } @@ -4592,7 +4590,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (ed.getType().isEmpty() || isAbstract(ed.getType().get(0).getWorkingCode()) || ed.getType().get(0).getWorkingCode().equals(ed.getPath())) { if (ed.hasType() && "Resource".equals(ed.getType().get(0).getWorkingCode()) && child.getSelf().getType().get(0).hasProfile()) { if (child.getSelf().getType().get(0).getProfile().size() > 1) { - throw new FHIRException(context.formatMessage(I18nConstants.UNHANDLED_SITUATION_RESOURCE_IS_PROFILED_TO_MORE_THAN_ONE_OPTION__CANNOT_SORT_PROFILE)); + throw new FHIRException("Unhandled situation: resource is profiled to more than one option - cannot sort profile"); } StructureDefinition profile = context.fetchResource(StructureDefinition.class, child.getSelf().getType().get(0).getProfile().get(0).getValue()); while (profile != null && profile.getDerivation() == TypeDerivationRule.CONSTRAINT) { @@ -4615,12 +4613,12 @@ public class ProfileUtilities extends TranslatingUtilities { } else if (ed.getType().size() == 1 && !ed.getType().get(0).getWorkingCode().equals("*")) { StructureDefinition profile = context.fetchResource(StructureDefinition.class, sdNs(ed.getType().get(0).getWorkingCode())); if (profile==null) - throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_PROFILE__IN_ELEMENT_, sdNs(ed.getType().get(0).getWorkingCode()), ed.getPath())); + throw new FHIRException("Unable to resolve profile " + sdNs(ed.getType().get(0).getWorkingCode()) + " in element " + ed.getPath()); ccmp = new ElementDefinitionComparer(false, profile.getSnapshot().getElement(), ed.getType().get(0).getWorkingCode(), child.getSelf().getPath().length(), cmp.name); } else if (child.getSelf().getType().size() == 1) { StructureDefinition profile = context.fetchResource(StructureDefinition.class, sdNs(child.getSelf().getType().get(0).getWorkingCode())); if (profile==null) - throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_PROFILE__IN_ELEMENT_, sdNs(ed.getType().get(0).getWorkingCode()), ed.getPath())); + throw new FHIRException("Unable to resolve profile " + sdNs(ed.getType().get(0).getWorkingCode()) + " in element " + ed.getPath()); ccmp = new ElementDefinitionComparer(false, profile.getSnapshot().getElement(), child.getSelf().getType().get(0).getWorkingCode(), child.getSelf().getPath().length(), cmp.name); } else if (ed.getPath().endsWith("[x]") && !child.getSelf().getPath().endsWith("[x]")) { String edLastNode = ed.getPath().replaceAll("(.*\\.)*(.*)", "$2"); @@ -4630,12 +4628,12 @@ public class ProfileUtilities extends TranslatingUtilities { p = Utilities.uncapitalize(p); StructureDefinition sd = context.fetchResource(StructureDefinition.class, sdNs(p)); if (sd == null) - throw new Error(context.formatMessage(I18nConstants.UNABLE_TO_FIND_PROFILE__AT_, p, ed.getId())); + throw new Error("Unable to find profile '"+p+"' at "+ed.getId()); ccmp = new ElementDefinitionComparer(false, sd.getSnapshot().getElement(), p, child.getSelf().getPath().length(), cmp.name); } else if (child.getSelf().hasType() && child.getSelf().getType().get(0).getWorkingCode().equals("Reference")) { for (TypeRefComponent t: child.getSelf().getType()) { if (!t.getWorkingCode().equals("Reference")) { - throw new Error(context.formatMessage(I18nConstants.CANT_HAVE_CHILDREN_ON_AN_ELEMENT_WITH_A_POLYMORPHIC_TYPE__YOU_MUST_SLICE_AND_CONSTRAIN_THE_TYPES_FIRST_SORTELEMENTS_, ed.getPath(), typeCode(ed.getType()))); + throw new Error("Can't have children on an element with a polymorphic type - you must slice and constrain the types first (sortElements: "+ed.getPath()+":"+typeCode(ed.getType())+")"); } } StructureDefinition profile = context.fetchResource(StructureDefinition.class, sdNs(ed.getType().get(0).getWorkingCode())); @@ -4643,7 +4641,7 @@ public class ProfileUtilities extends TranslatingUtilities { } else if (!child.getSelf().hasType() && ed.getType().get(0).getWorkingCode().equals("Reference")) { for (TypeRefComponent t: ed.getType()) { if (!t.getWorkingCode().equals("Reference")) { - throw new Error(context.formatMessage(I18nConstants.NOT_HANDLED_YET_SORTELEMENTS_, ed.getPath(), typeCode(ed.getType()))); + throw new Error("Not handled yet (sortElements: "+ed.getPath()+":"+typeCode(ed.getType())+")"); } } StructureDefinition profile = context.fetchResource(StructureDefinition.class, sdNs(ed.getType().get(0).getWorkingCode())); @@ -4652,7 +4650,7 @@ public class ProfileUtilities extends TranslatingUtilities { // this is allowed if we only profile the extensions StructureDefinition profile = context.fetchResource(StructureDefinition.class, sdNs("Element")); if (profile==null) - throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_PROFILE__IN_ELEMENT_, sdNs(ed.getType().get(0).getWorkingCode()), ed.getPath())); + throw new FHIRException("Unable to resolve profile " + sdNs(ed.getType().get(0).getWorkingCode()) + " in element " + ed.getPath()); ccmp = new ElementDefinitionComparer(false, profile.getSnapshot().getElement(), "Element", child.getSelf().getPath().length(), cmp.name); // throw new Error("Not handled yet (sortElements: "+ed.getPath()+":"+typeCode(ed.getType())+")"); } @@ -4721,9 +4719,9 @@ public class ProfileUtilities extends TranslatingUtilities { // generate schematrons for the rules in a structure definition public void generateSchematrons(OutputStream dest, StructureDefinition structure) throws IOException, DefinitionException { if (structure.getDerivation() != TypeDerivationRule.CONSTRAINT) - throw new DefinitionException(context.formatMessage(I18nConstants.NOT_THE_RIGHT_KIND_OF_STRUCTURE_TO_GENERATE_SCHEMATRONS_FOR)); + throw new DefinitionException("not the right kind of structure to generate schematrons for"); if (!structure.hasSnapshot()) - throw new DefinitionException(context.formatMessage(I18nConstants.NEEDS_A_SNAPSHOT)); + throw new DefinitionException("needs a snapshot"); StructureDefinition base = context.fetchResource(StructureDefinition.class, structure.getBaseDefinition()); @@ -4739,7 +4737,7 @@ public class ProfileUtilities extends TranslatingUtilities { // generate a CSV representation of the structure definition public void generateCsvs(OutputStream dest, StructureDefinition structure, boolean asXml) throws IOException, DefinitionException, Exception { if (!structure.hasSnapshot()) - throw new DefinitionException(context.formatMessage(I18nConstants.NEEDS_A_SNAPSHOT)); + throw new DefinitionException("needs a snapshot"); CSVWriter csv = new CSVWriter(dest, structure, asXml); @@ -4755,7 +4753,7 @@ public class ProfileUtilities extends TranslatingUtilities { System.out.println("no structure!"); } if (!structure.hasSnapshot()) { - throw new DefinitionException(context.formatMessage(I18nConstants.NEEDS_A_SNAPSHOT)); + throw new DefinitionException("needs a snapshot"); } XLSXWriter xlsx = new XLSXWriter(dest, structure, asXml, hideMustSupportFalse); @@ -4915,7 +4913,7 @@ public class ProfileUtilities extends TranslatingUtilities { for (ElementDefinition ed : list) { List paths = new ArrayList(); if (!ed.hasPath()) - throw new DefinitionException(context.formatMessage(I18nConstants.NO_PATH_ON_ELEMENT_DEFINITION__IN_, Integer.toString(list.indexOf(ed)), name)); + throw new DefinitionException("No path on element Definition "+Integer.toString(list.indexOf(ed))+" in "+name); sliceInfo.seeElement(ed); String[] pl = ed.getPath().split("\\."); for (int i = paths.size(); i < pl.length; i++) // -1 because the last path is in focus @@ -4939,7 +4937,7 @@ public class ProfileUtilities extends TranslatingUtilities { ed.setId(bs); if (idList.containsKey(bs)) { if (exception || messages == null) { - throw new DefinitionException(context.formatMessage(I18nConstants.SAME_ID_ON_MULTIPLE_ELEMENTS__IN_, bs, idList.get(bs), ed.getPath(), name)); + throw new DefinitionException("Same id '"+bs+"'on multiple elements "+idList.get(bs)+"/"+ed.getPath()+" in "+name); } else messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, name+"."+bs, "Duplicate Element id "+bs, ValidationMessage.IssueSeverity.ERROR)); } @@ -5133,7 +5131,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (sd.hasBaseDefinition()) { StructureDefinition base = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition()); if (base == null) - throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_FIND_BASE_DEFINITION_FOR_LOGICAL_MODEL__FROM_, sd.getBaseDefinition(), sd.getUrl())); + throw new FHIRException("Unable to find base definition for logical model: "+sd.getBaseDefinition()+" from "+sd.getUrl()); copyElements(sd, base.getSnapshot().getElement()); } copyElements(sd, sd.getDifferential().getElement()); @@ -5225,7 +5223,7 @@ public class ProfileUtilities extends TranslatingUtilities { else if (slicer.getPath().equals("Bundle.entry")) slicer.getSlicing().addDiscriminator().setType(DiscriminatorType.VALUE).setPath("resource.@profile"); else - throw new Error("No slicing for "+slicer.getPath()); + throw new Error("No slicing for "+slicer.getPath()); } public class SpanEntry { @@ -5344,7 +5342,7 @@ public class ProfileUtilities extends TranslatingUtilities { ElementDefinition ned = ed; while (ned != null && ned.getPath().contains(".")) { ned = findParent(ned, list); - if (ned != null) { // todo: this can happen if we've walked into a resoruce. Not sure what to about that? + if (ned != null) { // todo: this can happen if we've walked into a resoruce. Not sure what to about that? if ("0".equals(ned.getMax())) max = 0; else if (!ned.getMax().equals("1") && !ned.hasSlicing()) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java index 8b75abbcc..867f39771 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java @@ -22,18 +22,17 @@ package org.hl7.fhir.r5.context; import java.io.FileNotFoundException; import java.io.IOException; -import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; +import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; -import java.util.ResourceBundle; import java.util.Set; import org.apache.commons.lang3.StringUtils; @@ -42,6 +41,7 @@ import org.hl7.fhir.exceptions.DefinitionException; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.TerminologyServiceException; import org.hl7.fhir.r5.conformance.ProfileUtilities; +import org.hl7.fhir.r5.context.BaseWorkerContext.MetadataResourceVersionComparator; import org.hl7.fhir.r5.context.IWorkerContext.ILoggingService.LogCategory; import org.hl7.fhir.r5.context.TerminologyCache.CacheToken; import org.hl7.fhir.r5.model.BooleanType; @@ -82,7 +82,6 @@ import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome; import org.hl7.fhir.r5.terminologies.ValueSetExpanderSimple; import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.r5.utils.client.ToolingClientLogger; -import org.hl7.fhir.utilities.I18nConstants; import org.hl7.fhir.utilities.OIDUtils; import org.hl7.fhir.utilities.TranslationServices; import org.hl7.fhir.utilities.Utilities; @@ -96,7 +95,6 @@ import com.google.gson.JsonObject; public abstract class BaseWorkerContext implements IWorkerContext { - private ResourceBundle i18Nmessages; private Locale locale; public class MetadataResourceVersionComparator implements Comparator { @@ -168,23 +166,19 @@ public abstract class BaseWorkerContext implements IWorkerContext { private boolean tlogging = true; public BaseWorkerContext() throws FileNotFoundException, IOException, FHIRException { + super(); txCache = new TerminologyCache(lock, null); - setValidationMessageLanguage(getLocale()); } - public BaseWorkerContext(Locale locale) throws FileNotFoundException, IOException, FHIRException { - txCache = new TerminologyCache(lock, null); - setValidationMessageLanguage(locale); - } - - public BaseWorkerContext(CanonicalResourceManager codeSystems, CanonicalResourceManager valueSets, CanonicalResourceManager maps, CanonicalResourceManager profiles, + public BaseWorkerContext(CanonicalResourceManager codeSystems, CanonicalResourceManager valueSets, CanonicalResourceManager maps, CanonicalResourceManager profiles, CanonicalResourceManager guides) throws FileNotFoundException, IOException, FHIRException { - this(); + super(); this.codeSystems = codeSystems; this.valueSets = valueSets; this.maps = maps; this.structures = profiles; this.guides = guides; + txCache = new TerminologyCache(lock, null); } protected void copy(BaseWorkerContext other) { @@ -238,7 +232,7 @@ public abstract class BaseWorkerContext implements IWorkerContext { if (Utilities.existsInList(url, "http://hl7.org/fhir/SearchParameter/example")) { return; } - throw new DefinitionException(formatMessage(I18nConstants.DUPLICATE_RESOURCE_, url)); + throw new DefinitionException("Duplicate Resource " + url); } if (r instanceof StructureDefinition) structures.see((StructureDefinition) m); @@ -312,7 +306,7 @@ public abstract class BaseWorkerContext implements IWorkerContext { return laterVersion(newParts[i], oldParts[i]); } // This should never happen - throw new Error(formatMessage(I18nConstants.DELIMITED_VERSIONS_HAVE_EXACT_MATCH_FOR_DELIMITER____VS_, delimiter, newParts, oldParts)); + throw new Error("Delimited versions have exact match for delimiter '"+delimiter+"' : "+newParts+" vs "+oldParts); } protected void seeMetadataResource(T r, Map map, List list, boolean addId) throws FHIRException { @@ -426,12 +420,25 @@ public abstract class BaseWorkerContext implements IWorkerContext { this.expandCodesLimit = expandCodesLimit; } + @Override + public Locale getLocale() { + if (Objects.nonNull(locale)){ + return locale; + } else { + return Locale.US; + } + } + + @Override + public void setLocale(Locale locale) { + this.locale = locale; + } @Override public ValueSetExpansionOutcome expandVS(ElementDefinitionBindingComponent binding, boolean cacheOk, boolean heirarchical) throws FHIRException { ValueSet vs = null; vs = fetchResource(ValueSet.class, binding.getValueSet()); if (vs == null) - throw new FHIRException(formatMessage(I18nConstants.UNABLE_TO_RESOLVE_VALUE_SET_, binding.getValueSet())); + throw new FHIRException("Unable to resolve value Set "+binding.getValueSet()); return expandVS(vs, cacheOk, heirarchical); } @@ -450,7 +457,7 @@ public abstract class BaseWorkerContext implements IWorkerContext { p.setParameter("excludeNested", !hierarchical); if (noTerminologyServer) - return new ValueSetExpansionOutcome(formatMessage(I18nConstants.ERROR_EXPANDING_VALUESET_RUNNING_WITHOUT_TERMINOLOGY_SERVICES), TerminologyServiceErrorClass.NOSERVICE); + return new ValueSetExpansionOutcome("Error expanding ValueSet: running without terminology services", TerminologyServiceErrorClass.NOSERVICE); Map params = new HashMap(); params.put("_limit", Integer.toString(expandCodesLimit )); params.put("_incomplete", "true"); @@ -470,19 +477,19 @@ public abstract class BaseWorkerContext implements IWorkerContext { @Override public ValueSetExpansionOutcome expandVS(ValueSet vs, boolean cacheOk, boolean heirarchical) { if (expParameters == null) - throw new Error(formatMessage(I18nConstants.NO_EXPANSION_PARAMETERS_PROVIDED)); + throw new Error("No Expansion Parameters provided"); Parameters p = expParameters.copy(); return expandVS(vs, cacheOk, heirarchical, p); } public ValueSetExpansionOutcome expandVS(ValueSet vs, boolean cacheOk, boolean heirarchical, Parameters p) { if (p == null) - throw new Error(formatMessage(I18nConstants.NO_PARAMETERS_PROVIDED_TO_EXPANDVS)); + throw new Error("No Parameters provided to expandVS"); if (vs.hasExpansion()) { return new ValueSetExpansionOutcome(vs.copy()); } if (!vs.hasUrl()) - throw new Error(formatMessage(I18nConstants.NO_VALUE_SET)); + throw new Error("no value set"); CacheToken cacheToken = txCache.generateExpandToken(vs, heirarchical); ValueSetExpansionOutcome res; @@ -499,7 +506,7 @@ public abstract class BaseWorkerContext implements IWorkerContext { ValueSetExpanderSimple vse = new ValueSetExpanderSimple(this); res = vse.doExpand(vs, p); if (!res.getValueset().hasUrl()) - throw new Error(formatMessage(I18nConstants.NO_URL_IN_EXPAND_VALUE_SET)); + throw new Error("no url in expand value set"); txCache.cacheExpansion(cacheToken, res, TerminologyCache.TRANSIENT); return res; } catch (Exception e) { @@ -507,7 +514,7 @@ public abstract class BaseWorkerContext implements IWorkerContext { // if that failed, we try to expand on the server if (noTerminologyServer) - return new ValueSetExpansionOutcome(formatMessage(I18nConstants.ERROR_EXPANDING_VALUESET_RUNNING_WITHOUT_TERMINOLOGY_SERVICES), TerminologyServiceErrorClass.NOSERVICE); + return new ValueSetExpansionOutcome("Error expanding ValueSet: running without terminology services", TerminologyServiceErrorClass.NOSERVICE); Map params = new HashMap(); params.put("_limit", Integer.toString(expandCodesLimit )); params.put("_incomplete", "true"); @@ -517,7 +524,7 @@ public abstract class BaseWorkerContext implements IWorkerContext { if (!result.hasUrl()) result.setUrl(vs.getUrl()); if (!result.hasUrl()) - throw new Error(formatMessage(I18nConstants.NO_URL_IN_EXPAND_VALUE_SET_2)); + throw new Error("no url in expand value set 2"); res = new ValueSetExpansionOutcome(result).setTxLink(txLog.getLastId()); } catch (Exception e) { res = new ValueSetExpansionOutcome(e.getMessage() == null ? e.getClass().getName() : e.getMessage(), TerminologyServiceErrorClass.UNKNOWN).setTxLink(txLog == null ? null : txLog.getLastId()); @@ -577,12 +584,12 @@ public abstract class BaseWorkerContext implements IWorkerContext { } if (!options.isUseServer()) { - return new ValidationResult(IssueSeverity.WARNING,formatMessage(I18nConstants.UNABLE_TO_VALIDATE_CODE_WITHOUT_USING_SERVER), TerminologyServiceErrorClass.BLOCKED_BY_OPTIONS); + return new ValidationResult(IssueSeverity.WARNING, "Unable to validate code without using server", TerminologyServiceErrorClass.BLOCKED_BY_OPTIONS); } // if that failed, we try to validate on the server if (noTerminologyServer) { - return new ValidationResult(IssueSeverity.ERROR,formatMessage(I18nConstants.ERROR_VALIDATING_CODE_RUNNING_WITHOUT_TERMINOLOGY_SERVICES), TerminologyServiceErrorClass.NOSERVICE); + return new ValidationResult(IssueSeverity.ERROR, "Error validating code: running without terminology services", TerminologyServiceErrorClass.NOSERVICE); } String csumm = txCache != null ? txCache.summary(code) : null; if (txCache != null) { @@ -657,15 +664,15 @@ public abstract class BaseWorkerContext implements IWorkerContext { pin.addParameter().setName("valueSet").setResource(vs); for (ParametersParameterComponent pp : pin.getParameter()) if (pp.getName().equals("profile")) - throw new Error(formatMessage(I18nConstants.CAN_ONLY_SPECIFY_PROFILE_IN_THE_CONTEXT)); + throw new Error("Can only specify profile in the context"); if (expParameters == null) - throw new Error(formatMessage(I18nConstants.NO_EXPANSIONPROFILE_PROVIDED)); + throw new Error("No ExpansionProfile provided"); pin.addParameter().setName("profile").setResource(expParameters); if (txLog != null) { txLog.clearLastId(); } if (txClient == null) { - throw new FHIRException(formatMessage(I18nConstants.ATTEMPT_TO_USE_TERMINOLOGY_SERVER_WHEN_NO_TERMINOLOGY_SERVER_IS_AVAILABLE)); + throw new FHIRException("Attempt to use Terminology server when no Terminology server is available"); } Parameters pOut; if (vs == null) @@ -872,7 +879,7 @@ public abstract class BaseWorkerContext implements IWorkerContext { } if (supportedCodeSystems.contains(uri)) return null; - throw new FHIRException(formatMessage(I18nConstants.NOT_DONE_YET_CANT_FETCH_, uri)); + throw new FHIRException("not done yet: can't fetch "+uri); } } @@ -918,10 +925,10 @@ public abstract class BaseWorkerContext implements IWorkerContext { if (parts.length >= 2) { if (!Utilities.noString(type)) if (!type.equals(parts[parts.length-2])) - throw new Error(formatMessage(I18nConstants.RESOURCE_TYPE_MISMATCH_FOR___, type, uri)); + throw new Error("Resource type mismatch for "+type+" / "+uri); return allResourcesById.get(parts[parts.length-2]).get(parts[parts.length-1]); } else - throw new Error(formatMessage(I18nConstants.UNABLE_TO_PROCESS_REQUEST_FOR_RESOURCE_FOR___, type, uri)); + throw new Error("Unable to process request for resource for "+type+" / "+uri); } } @@ -1281,36 +1288,5 @@ public abstract class BaseWorkerContext implements IWorkerContext { return binaries; } - @Override - public Locale getLocale() { - if (Objects.nonNull(locale)){ - return locale; - } else { - return Locale.US; - } - } - @Override - public void setLocale(Locale locale) { - this.locale = locale; - setValidationMessageLanguage(getLocale()); - } - - @Override - public String formatMessage(String theMessage, Object... theMessageArguments) { - String message = theMessage; - if (Objects.nonNull(i18Nmessages) && i18Nmessages.containsKey(theMessage)) { - if (Objects.nonNull(theMessageArguments) && theMessageArguments.length > 0) { - message = MessageFormat.format(i18Nmessages.getString(theMessage), theMessageArguments); - } else { - message = i18Nmessages.getString(theMessage); - } - } - return message; - } - - @Override - public void setValidationMessageLanguage(Locale locale) { - i18Nmessages = ResourceBundle.getBundle("Messages", locale ); - } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/IWorkerContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/IWorkerContext.java index aa9143962..0b500b26e 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/IWorkerContext.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/IWorkerContext.java @@ -326,17 +326,13 @@ public interface IWorkerContext { * @return * @throws FHIRException */ - ValueSetExpansionOutcome expandVS(ConceptSetComponent inc, boolean hierarchical) throws TerminologyServiceException; + public ValueSetExpansionOutcome expandVS(ConceptSetComponent inc, boolean hierarchical) throws TerminologyServiceException; - Locale getLocale(); + Locale getLocale(); - void setLocale(Locale locale); + void setLocale(Locale locale); - String formatMessage(String theMessage, Object... theMessageArguments); - - void setValidationMessageLanguage(Locale locale); - - class ValidationResult { + public class ValidationResult { private ConceptDefinitionComponent definition; private IssueSeverity severity; private String message; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/SimpleWorkerContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/SimpleWorkerContext.java index 04aa00fc3..455dc659f 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/SimpleWorkerContext.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/SimpleWorkerContext.java @@ -35,7 +35,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.zip.ZipEntry; @@ -73,7 +72,6 @@ import org.hl7.fhir.r5.utils.INarrativeGenerator; import org.hl7.fhir.r5.utils.IResourceValidator; import org.hl7.fhir.r5.utils.NarrativeGenerator; import org.hl7.fhir.utilities.CSFileInputStream; -import org.hl7.fhir.utilities.I18nConstants; import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.cache.NpmPackage; @@ -119,20 +117,11 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon public SimpleWorkerContext() throws FileNotFoundException, IOException, FHIRException { super(); } - - public SimpleWorkerContext(Locale locale) throws FileNotFoundException, IOException, FHIRException { - super(locale); - } public SimpleWorkerContext(SimpleWorkerContext other) throws FileNotFoundException, IOException, FHIRException { super(); copy(other); } - - public SimpleWorkerContext(SimpleWorkerContext other, Locale locale) throws FileNotFoundException, IOException, FHIRException { - super(locale); - copy(other); - } protected void copy(SimpleWorkerContext other) { super.copy(other); @@ -260,7 +249,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon txClient.setLogger(txLog); return txClient.getCapabilitiesStatementQuick().getSoftware().getVersion(); } catch (Exception e) { - throw new FHIRException(formatMessage(I18nConstants.UNABLE_TO_CONNECT_TO_TERMINOLOGY_SERVER_USE_PARAMETER_TX_NA_TUN_RUN_WITHOUT_USING_TERMINOLOGY_SERVICES_TO_VALIDATE_LOINC_SNOMED_ICDX_ETC_ERROR__, e.getMessage()), e); + throw new FHIRException("Unable to connect to terminology server. Use parameter '-tx n/a' tun run without using terminology services to validate LOINC, SNOMED, ICD-X etc. Error = "+e.getMessage(), e); } } @@ -278,9 +267,9 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon f = xml.parse(stream); } } catch (DataFormatException e1) { - throw new org.hl7.fhir.exceptions.FHIRFormatError(formatMessage(I18nConstants.ERROR_PARSING_, name, e1.getMessage()), e1); + throw new org.hl7.fhir.exceptions.FHIRFormatError("Error parsing "+name+":" +e1.getMessage(), e1); } catch (Exception e1) { - throw new org.hl7.fhir.exceptions.FHIRFormatError(formatMessage(I18nConstants.ERROR_PARSING_, name, e1.getMessage()), e1); + throw new org.hl7.fhir.exceptions.FHIRFormatError("Error parsing "+name+":" +e1.getMessage(), e1); } if (f instanceof Bundle) { Bundle bnd = (Bundle) f; @@ -336,7 +325,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon try { loadDefinitionItem(s, pi.load("package", s), loader, filter); } catch (FHIRException | IOException e) { - throw new FHIRException(formatMessage(I18nConstants.ERROR_READING__FROM_PACKAGE__, s, pi.name(), pi.version(), e.getMessage()), e); + throw new FHIRException("Error reading "+s+" from package "+pi.name()+"#"+pi.version()+": "+e.getMessage(), e); } } for (String s : pi.list("other")) { @@ -388,7 +377,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon if (version == null) version = s.substring(8); else if (!version.equals(s.substring(8))) - throw new DefinitionException(formatMessage(I18nConstants.VERSION_MISMATCH_THE_CONTEXT_HAS_VERSION__LOADED_AND_THE_NEW_CONTENT_BEING_LOADED_IS_VERSION_, version, s.substring(8))); + throw new DefinitionException("Version mismatch. The context has version "+version+" loaded, and the new content being loaded is version "+s.substring(8)); } if (s.startsWith("revision=")) revision = s.substring(9); @@ -408,7 +397,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon case JSON: return newJsonParser(); case XML: return newXmlParser(); default: - throw new Error(formatMessage(I18nConstants.PARSER_TYPE__NOT_SUPPORTED, type.toString())); + throw new Error("Parser Type "+type.toString()+" not supported"); } } @@ -418,7 +407,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon return new JsonParser(); if (type.equalsIgnoreCase("XML")) return new XmlParser(); - throw new Error(formatMessage(I18nConstants.PARSER_TYPE__NOT_SUPPORTED, type.toString())); + throw new Error("Parser Type "+type.toString()+" not supported"); } @Override @@ -438,7 +427,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon @Override public IResourceValidator newValidator() throws FHIRException { if (validatorFactory == null) - throw new Error(formatMessage(I18nConstants.NO_VALIDATOR_CONFIGURED)); + throw new Error("No validator configured"); return validatorFactory.makeValidator(this); } @@ -666,13 +655,13 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon public void generateSnapshot(StructureDefinition p, boolean logical) throws DefinitionException, FHIRException { if (!p.hasSnapshot() && (logical || p.getKind() != StructureDefinitionKind.LOGICAL)) { if (!p.hasBaseDefinition()) - throw new DefinitionException(formatMessage(I18nConstants.PROFILE___HAS_NO_BASE_AND_NO_SNAPSHOT, p.getName(), p.getUrl())); + throw new DefinitionException("Profile "+p.getName()+" ("+p.getUrl()+") has no base and no snapshot"); StructureDefinition sd = fetchResource(StructureDefinition.class, p.getBaseDefinition()); if (sd == null && "http://hl7.org/fhir/StructureDefinition/Base".equals(p.getBaseDefinition())) { sd = ProfileUtilities.makeBaseDefinition(p.getFhirVersion()); } if (sd == null) { - throw new DefinitionException(formatMessage(I18nConstants.PROFILE___BASE__COULD_NOT_BE_RESOLVED, p.getName(), p.getUrl(), p.getBaseDefinition())); + throw new DefinitionException("Profile "+p.getName()+" ("+p.getUrl()+") base "+p.getBaseDefinition()+" could not be resolved"); } List msgs = new ArrayList(); List errors = new ArrayList(); @@ -688,10 +677,10 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon pu.generateSnapshot(sd, p, p.getUrl(), Utilities.extractBaseUrl(sd.getUserString("path")), p.getName()); for (ValidationMessage msg : msgs) { if ((!ignoreProfileErrors && msg.getLevel() == ValidationMessage.IssueSeverity.ERROR) || msg.getLevel() == ValidationMessage.IssueSeverity.FATAL) - throw new DefinitionException(formatMessage(I18nConstants.PROFILE___ELEMENT__ERROR_GENERATING_SNAPSHOT_, p.getName(), p.getUrl(), msg.getLocation(), msg.getMessage())); + throw new DefinitionException("Profile "+p.getName()+" ("+p.getUrl()+"), element "+msg.getLocation()+". Error generating snapshot: "+msg.getMessage()); } if (!p.hasSnapshot()) - throw new FHIRException(formatMessage(I18nConstants.PROFILE___ERROR_GENERATING_SNAPSHOT, p.getName(), p.getUrl())); + throw new FHIRException("Profile "+p.getName()+" ("+p.getUrl()+"). Error generating snapshot"); pu = null; } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/JsonParser.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/JsonParser.java index 68e1441bd..b73730ae1 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/JsonParser.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/JsonParser.java @@ -9,9 +9,9 @@ package org.hl7.fhir.r5.elementmodel; * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -45,7 +45,6 @@ import org.hl7.fhir.r5.formats.JsonCreatorCanonical; import org.hl7.fhir.r5.formats.JsonCreatorGson; import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent; import org.hl7.fhir.r5.model.StructureDefinition; -import org.hl7.fhir.utilities.I18nConstants; import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.json.JsonTrackingParser; @@ -91,20 +90,20 @@ public class JsonParser extends ParserBase { map = new IdentityHashMap(); String source = TextFile.streamToString(stream); if (policy == ValidationPolicy.EVERYTHING) { - JsonObject obj = null; + JsonObject obj = null; try { obj = JsonTrackingParser.parse(source, map); - } catch (Exception e) { - logError(-1, -1,context.formatMessage(I18nConstants.DOCUMENT), IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_JSON_, e.getMessage()), IssueSeverity.FATAL); + } catch (Exception e) { + logError(-1, -1, "(document)", IssueType.INVALID, "Error parsing JSON: "+e.getMessage(), IssueSeverity.FATAL); return null; } assert (map.containsKey(obj)); - return parse(obj); + return parse(obj); } else { JsonObject obj = JsonTrackingParser.parse(source, null); // (JsonObject) new com.google.gson.JsonParser().parse(source); // assert (map.containsKey(obj)); - return parse(obj); - } + return parse(obj); + } } public Element parse(JsonObject object, Map map) throws FHIRException { @@ -115,7 +114,7 @@ public class JsonParser extends ParserBase { public Element parse(JsonObject object) throws FHIRException { JsonElement rt = object.get("resourceType"); if (rt == null) { - logError(line(object), col(object), "$", IssueType.INVALID, context.formatMessage(I18nConstants.UNABLE_TO_FIND_RESOURCETYPE_PROPERTY), IssueSeverity.FATAL); + logError(line(object), col(object), "$", IssueType.INVALID, "Unable to find resourceType property", IssueSeverity.FATAL); return null; } else { String name = rt.getAsString(); @@ -145,13 +144,13 @@ public class JsonParser extends ParserBase { // } } if (!found) - logError(line(object), col(object), path, IssueType.INVALID, context.formatMessage(I18nConstants.OBJECT_MUST_HAVE_SOME_CONTENT), IssueSeverity.ERROR); + logError(line(object), col(object), path, IssueType.INVALID, "Object must have some content", IssueSeverity.ERROR); } } - private void parseChildren(String path, JsonObject object, Element element, boolean hasResourceType) throws FHIRException { - reapComments(object, element); - List properties = element.getProperty().getChildProperties(element.getName(), null); + private void parseChildren(String path, JsonObject object, Element context, boolean hasResourceType) throws FHIRException { + reapComments(object, context); + List properties = context.getProperty().getChildProperties(context.getName(), null); Set processed = new HashSet(); if (hasResourceType) processed.add("resourceType"); @@ -160,14 +159,14 @@ public class JsonParser extends ParserBase { // note that we do not trouble ourselves to maintain the wire format order here - we don't even know what it was anyway // first pass: process the properties for (Property property : properties) { - parseChildItem(path, object, element, processed, property); + parseChildItem(path, object, context, processed, property); } // second pass: check for things not processed if (policy != ValidationPolicy.NONE) { for (Entry e : object.entrySet()) { if (!processed.contains(e.getKey())) { - logError(line(e.getValue()), col(e.getValue()), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.UNRECOGNISED_PROPERTY_, e.getKey()), IssueSeverity.ERROR); + logError(line(e.getValue()), col(e.getValue()), path, IssueType.STRUCTURE, "Unrecognised property '@"+e.getKey()+"'", IssueSeverity.ERROR); } } } @@ -192,7 +191,7 @@ public class JsonParser extends ParserBase { } } - private void parseChildComplex(String path, JsonObject object, Element element, Set processed, Property property, String name) throws FHIRException { + private void parseChildComplex(String path, JsonObject object, Element context, Set processed, Property property, String name) throws FHIRException { processed.add(name); String npath = path+"."+property.getName(); JsonElement e = object.get(name); @@ -200,14 +199,14 @@ public class JsonParser extends ParserBase { JsonArray arr = (JsonArray) e; int c = 0; for (JsonElement am : arr) { - parseChildComplexInstance(npath+"["+c+"]", object, element, property, name, am); + parseChildComplexInstance(npath+"["+c+"]", object, context, property, name, am); c++; } } else { if (property.isList()) { - logError(line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_AN_ARRAY_NOT_, describeType(e)), IssueSeverity.ERROR); + logError(line(e), col(e), npath, IssueType.INVALID, "This property must be an Array, not "+describeType(e), IssueSeverity.ERROR); } - parseChildComplexInstance(npath, object, element, property, name, e); + parseChildComplexInstance(npath, object, context, property, name, e); } } @@ -223,20 +222,20 @@ public class JsonParser extends ParserBase { return null; } - private void parseChildComplexInstance(String npath, JsonObject object, Element element, Property property, String name, JsonElement e) throws FHIRException { + private void parseChildComplexInstance(String npath, JsonObject object, Element context, Property property, String name, JsonElement e) throws FHIRException { if (e instanceof JsonObject) { JsonObject child = (JsonObject) e; Element n = new Element(name, property).markLocation(line(child), col(child)); checkObject(child, npath); - element.getChildren().add(n); + context.getChildren().add(n); if (property.isResource()) parseResource(npath, child, n, property); else parseChildren(npath, child, n, false); - } else - logError(line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE__NOT_, (property.isList() ? "an Array" : "an Object"), describe(e)), IssueSeverity.ERROR); + } else + logError(line(e), col(e), npath, IssueType.INVALID, "This property must be "+(property.isList() ? "an Array" : "an Object")+", not "+describe(e), IssueSeverity.ERROR); } - + private String describe(JsonElement e) { if (e instanceof JsonArray) { return "an array"; @@ -247,21 +246,21 @@ public class JsonParser extends ParserBase { return "a primitive property"; } - private void parseChildPrimitive(JsonObject object, Element element, Set processed, Property property, String path, String name) throws FHIRException { + private void parseChildPrimitive(JsonObject object, Element context, Set processed, Property property, String path, String name) throws FHIRException { String npath = path+"."+property.getName(); processed.add(name); processed.add("_"+name); - JsonElement main = object.has(name) ? object.get(name) : null; + JsonElement main = object.has(name) ? object.get(name) : null; JsonElement fork = object.has("_"+name) ? object.get("_"+name) : null; if (main != null || fork != null) { if (property.isList()) { boolean ok = true; if (!(main == null || main instanceof JsonArray)) { - logError(line(main), col(main), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_AN_ARRAY_NOT_A_, describe(main)), IssueSeverity.ERROR); + logError(line(main), col(main), npath, IssueType.INVALID, "This property must be an Array, not a "+describe(main), IssueSeverity.ERROR); ok = false; } if (!(fork == null || fork instanceof JsonArray)) { - logError(line(fork), col(fork), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_BASE_PROPERTY_MUST_BE_AN_ARRAY_NOT_A_, describe(main)), IssueSeverity.ERROR); + logError(line(fork), col(fork), npath, IssueType.INVALID, "This base property must be an Array, not a "+describe(main), IssueSeverity.ERROR); ok = false; } if (ok) { @@ -270,11 +269,11 @@ public class JsonParser extends ParserBase { for (int i = 0; i < Math.max(arrC(arr1), arrC(arr2)); i++) { JsonElement m = arrI(arr1, i); JsonElement f = arrI(arr2, i); - parseChildPrimitiveInstance(element, property, name, npath, m, f); + parseChildPrimitiveInstance(context, property, name, npath, m, f); } } } else { - parseChildPrimitiveInstance(element, property, name, npath, main, fork); + parseChildPrimitiveInstance(context, property, name, npath, main, fork); } } } @@ -287,16 +286,15 @@ public class JsonParser extends ParserBase { return arr == null ? 0 : arr.size(); } - private void parseChildPrimitiveInstance(Element element, Property property, String name, String npath, + private void parseChildPrimitiveInstance(Element context, Property property, String name, String npath, JsonElement main, JsonElement fork) throws FHIRException { if (main != null && !(main instanceof JsonPrimitive)) - logError(line(main), col(main), npath, IssueType.INVALID, context.formatMessage( - I18nConstants.THIS_PROPERTY_MUST_BE_AN_SIMPLE_VALUE_NOT_, describe(main)), IssueSeverity.ERROR); + logError(line(main), col(main), npath, IssueType.INVALID, "This property must be an simple value, not "+describe(main), IssueSeverity.ERROR); else if (fork != null && !(fork instanceof JsonObject)) - logError(line(fork), col(fork), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_AN_OBJECT_NOT_, describe(fork)), IssueSeverity.ERROR); + logError(line(fork), col(fork), npath, IssueType.INVALID, "This property must be an object, not "+describe(fork), IssueSeverity.ERROR); else { Element n = new Element(name, property).markLocation(line(main != null ? main : fork), col(main != null ? main : fork)); - element.getChildren().add(n); + context.getChildren().add(n); if (main != null) { JsonPrimitive p = (JsonPrimitive) main; if (p.isNumber() && p.getAsNumber() instanceof JsonTrackingParser.PresentedBigDecimal) { @@ -309,19 +307,19 @@ public class JsonParser extends ParserBase { try { n.setXhtml(new XhtmlParser().setValidatorMode(policy == ValidationPolicy.EVERYTHING).parse(n.getValue(), null).getDocumentElement()); } catch (Exception e) { - logError(line(main), col(main), npath, IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_XHTML_, e.getMessage()), IssueSeverity.ERROR); + logError(line(main), col(main), npath, IssueType.INVALID, "Error parsing XHTML: "+e.getMessage(), IssueSeverity.ERROR); } } if (policy == ValidationPolicy.EVERYTHING) { // now we cross-check the primitive format against the stated type if (Utilities.existsInList(n.getType(), "boolean")) { if (!p.isBoolean()) - logError(line(main), col(main), npath, IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_JSON_THE_PRIMITIVE_VALUE_MUST_BE_A_BOOLEAN), IssueSeverity.ERROR); + logError(line(main), col(main), npath, IssueType.INVALID, "Error parsing JSON: the primitive value must be a boolean", IssueSeverity.ERROR); } else if (Utilities.existsInList(n.getType(), "integer", "unsignedInt", "positiveInt", "decimal")) { if (!p.isNumber()) - logError(line(main), col(main), npath, IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_JSON_THE_PRIMITIVE_VALUE_MUST_BE_A_NUMBER), IssueSeverity.ERROR); + logError(line(main), col(main), npath, IssueType.INVALID, "Error parsing JSON: the primitive value must be a number", IssueSeverity.ERROR); } else if (!p.isString()) - logError(line(main), col(main), npath, IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_JSON_THE_PRIMITIVE_VALUE_MUST_BE_A_STRING), IssueSeverity.ERROR); + logError(line(main), col(main), npath, IssueType.INVALID, "Error parsing JSON: the primitive value must be a string", IssueSeverity.ERROR); } } if (fork != null) { @@ -336,12 +334,12 @@ public class JsonParser extends ParserBase { private void parseResource(String npath, JsonObject res, Element parent, Property elementProperty) throws FHIRException { JsonElement rt = res.get("resourceType"); if (rt == null) { - logError(line(res), col(res), npath, IssueType.INVALID, context.formatMessage(I18nConstants.UNABLE_TO_FIND_RESOURCETYPE_PROPERTY), IssueSeverity.FATAL); + logError(line(res), col(res), npath, IssueType.INVALID, "Unable to find resourceType property", IssueSeverity.FATAL); } else { String name = rt.getAsString(); StructureDefinition sd = context.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(name, context.getOverrideVersionNs())); if (sd == null) - throw new FHIRFormatError(context.formatMessage(I18nConstants.CONTAINED_RESOURCE_DOES_NOT_APPEAR_TO_BE_A_FHIR_RESOURCE_UNKNOWN_NAME_, name)); + throw new FHIRFormatError("Contained resource does not appear to be a FHIR resource (unknown name '"+name+"')"); parent.updateProperty(new Property(context, sd.getSnapshot().getElement().get(0), sd), SpecialElement.fromProperty(parent.getProperty()), elementProperty); parent.setType(name); parseChildren(npath, res, parent, true); @@ -381,7 +379,7 @@ public class JsonParser extends ParserBase { protected void open(String name, String link) throws IOException { json.link(link); - if (name != null) + if (name != null) json.name(name); json.beginObject(); } @@ -392,7 +390,7 @@ public class JsonParser extends ParserBase { protected void openArray(String name, String link) throws IOException { json.link(link); - if (name != null) + if (name != null) json.name(name); json.beginArray(); } @@ -424,7 +422,7 @@ public class JsonParser extends ParserBase { public void compose(Element e, JsonCreator json) throws Exception { this.json = json; json.beginObject(); - + prop("resourceType", e.getType(), linkResolver == null ? null : linkResolver.resolveProperty(e.getProperty())); Set done = new HashSet(); for (Element child : e.getChildren()) { @@ -452,7 +450,7 @@ public class JsonParser extends ParserBase { if (list.get(0).isPrimitive()) { boolean prim = false; complex = false; - for (Element item : list) { + for (Element item : list) { if (item.hasValue()) prim = true; if (item.hasChildren()) @@ -460,19 +458,19 @@ public class JsonParser extends ParserBase { } if (prim) { openArray(name, linkResolver == null ? null : linkResolver.resolveProperty(list.get(0).getProperty())); - for (Element item : list) { + for (Element item : list) { if (item.hasValue()) primitiveValue(null, item); else json.nullValue(); - } + } closeArray(); } name = "_"+name; } if (complex) { openArray(name, linkResolver == null ? null : linkResolver.resolveProperty(list.get(0).getProperty())); - for (Element item : list) { + for (Element item : list) { if (item.hasChildren()) { open(null,null); if (item.getProperty().isResource()) { @@ -485,9 +483,9 @@ public class JsonParser extends ParserBase { close(); } else json.nullValue(); - } + } closeArray(); - } + } } private void primitiveValue(String name, Element item) throws IOException { @@ -505,10 +503,10 @@ public class JsonParser extends ParserBase { try { json.value(new BigDecimal(item.getValue())); } catch (Exception e) { - throw new NumberFormatException(context.formatMessage(I18nConstants.ERROR_WRITING_NUMBER__TO_JSON, item.getValue())); + throw new NumberFormatException("error writing number '"+item.getValue()+"' to JSON"); } else - json.value(item.getValue()); + json.value(item.getValue()); } private void compose(String path, Element element) throws IOException { diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ParserBase.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ParserBase.java index fe3d4a53d..12624b4f3 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ParserBase.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ParserBase.java @@ -35,7 +35,6 @@ import org.hl7.fhir.r5.formats.IParser.OutputStyle; import org.hl7.fhir.r5.model.StructureDefinition; import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule; import org.hl7.fhir.r5.utils.ToolingExtensions; -import org.hl7.fhir.utilities.I18nConstants; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; @@ -92,11 +91,11 @@ public abstract class ParserBase { protected StructureDefinition getDefinition(int line, int col, String ns, String name) throws FHIRFormatError { if (ns == null) { - logError(line, col, name, IssueType.STRUCTURE, context.formatMessage(I18nConstants.THIS__CANNOT_BE_PARSED_AS_A_FHIR_OBJECT_NO_NAMESPACE, name), IssueSeverity.FATAL); + logError(line, col, name, IssueType.STRUCTURE, "This '"+name+"' cannot be parsed as a FHIR object (no namespace)", IssueSeverity.FATAL); return null; } if (name == null) { - logError(line, col, name, IssueType.STRUCTURE, context.formatMessage(I18nConstants.THIS_CANNOT_BE_PARSED_AS_A_FHIR_OBJECT_NO_NAME), IssueSeverity.FATAL); + logError(line, col, name, IssueType.STRUCTURE, "This cannot be parsed as a FHIR object (no name)", IssueSeverity.FATAL); return null; } for (StructureDefinition sd : context.allStructures()) { @@ -108,13 +107,13 @@ public abstract class ParserBase { return sd; } } - logError(line, col, name, IssueType.STRUCTURE, context.formatMessage(I18nConstants.THIS_DOES_NOT_APPEAR_TO_BE_A_FHIR_RESOURCE_UNKNOWN_NAMESPACENAME_, ns, name), IssueSeverity.FATAL); + logError(line, col, name, IssueType.STRUCTURE, "This does not appear to be a FHIR resource (unknown namespace/name '"+ns+"::"+name+"')", IssueSeverity.FATAL); return null; } protected StructureDefinition getDefinition(int line, int col, String name) throws FHIRFormatError { if (name == null) { - logError(line, col, name, IssueType.STRUCTURE, context.formatMessage(I18nConstants.THIS_CANNOT_BE_PARSED_AS_A_FHIR_OBJECT_NO_NAME), IssueSeverity.FATAL); + logError(line, col, name, IssueType.STRUCTURE, "This cannot be parsed as a FHIR object (no name)", IssueSeverity.FATAL); return null; } // first pass: only look at base definitions @@ -130,7 +129,7 @@ public abstract class ParserBase { return sd; } } - logError(line, col, name, IssueType.STRUCTURE, context.formatMessage(I18nConstants.THIS_DOES_NOT_APPEAR_TO_BE_A_FHIR_RESOURCE_UNKNOWN_NAME_, name), IssueSeverity.FATAL); + logError(line, col, name, IssueType.STRUCTURE, "This does not appear to be a FHIR resource (unknown name '"+name+"')", IssueSeverity.FATAL); return null; } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/TurtleParser.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/TurtleParser.java index ea8f08214..5ede6fbd0 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/TurtleParser.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/TurtleParser.java @@ -46,7 +46,6 @@ import org.hl7.fhir.r5.utils.formats.Turtle.TTLList; import org.hl7.fhir.r5.utils.formats.Turtle.TTLLiteral; import org.hl7.fhir.r5.utils.formats.Turtle.TTLObject; import org.hl7.fhir.r5.utils.formats.Turtle.TTLURL; -import org.hl7.fhir.utilities.I18nConstants; import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; @@ -70,7 +69,7 @@ public class TurtleParser extends ParserBase { try { src.parse(TextFile.streamToString(input)); } catch (Exception e) { - logError(-1, -1, "(document)", IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_TURTLE_, e.getMessage()), IssueSeverity.FATAL); + logError(-1, -1, "(document)", IssueType.INVALID, "Error parsing Turtle: "+e.getMessage(), IssueSeverity.FATAL); return null; } return parse(src); @@ -102,7 +101,7 @@ public class TurtleParser extends ParserBase { private Element parse(Turtle src, TTLComplex cmp) throws FHIRException { TTLObject type = cmp.getPredicates().get("http://www.w3.org/2000/01/rdf-schema#type"); if (type == null) { - logError(cmp.getLine(), cmp.getCol(), "(document)", IssueType.INVALID, context.formatMessage(I18nConstants.UNKNOWN_RESOURCE_TYPE_MISSING_RDFSTYPE), IssueSeverity.FATAL); + logError(cmp.getLine(), cmp.getCol(), "(document)", IssueType.INVALID, "Unknown resource type (missing rdfs:type)", IssueSeverity.FATAL); return null; } if (type instanceof TTLList) { @@ -115,7 +114,7 @@ public class TurtleParser extends ParserBase { } } if (!(type instanceof TTLURL)) { - logError(cmp.getLine(), cmp.getCol(), "(document)", IssueType.INVALID, context.formatMessage(I18nConstants.UNEXPECTED_DATATYPE_FOR_RDFSTYPE), IssueSeverity.FATAL); + logError(cmp.getLine(), cmp.getCol(), "(document)", IssueType.INVALID, "Unexpected datatype for rdfs:type)", IssueSeverity.FATAL); return null; } String name = ((TTLURL) type).getUri(); @@ -135,9 +134,9 @@ public class TurtleParser extends ParserBase { return result; } - private void parseChildren(Turtle src, String path, TTLComplex object, Element element, boolean primitive) throws FHIRException { + private void parseChildren(Turtle src, String path, TTLComplex object, Element context, boolean primitive) throws FHIRException { - List properties = element.getProperty().getChildProperties(element.getName(), null); + List properties = context.getProperty().getChildProperties(context.getName(), null); Set processed = new HashSet(); if (primitive) processed.add(FHIR_URI_BASE + "value"); @@ -148,10 +147,10 @@ public class TurtleParser extends ParserBase { if (property.isChoice()) { for (TypeRefComponent type : property.getDefinition().getType()) { String eName = property.getName().substring(0, property.getName().length()-3) + Utilities.capitalize(type.getCode()); - parseChild(src, object, element, processed, property, path, getFormalName(property, eName)); + parseChild(src, object, context, processed, property, path, getFormalName(property, eName)); } } else { - parseChild(src, object, element, processed, property, path, getFormalName(property)); + parseChild(src, object, context, processed, property, path, getFormalName(property)); } } @@ -160,7 +159,7 @@ public class TurtleParser extends ParserBase { for (String u : object.getPredicates().keySet()) { if (!processed.contains(u)) { TTLObject n = object.getPredicates().get(u); - logError(n.getLine(), n.getCol(), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.UNRECOGNISED_PREDICATE_, u), IssueSeverity.ERROR); + logError(n.getLine(), n.getCol(), path, IssueType.STRUCTURE, "Unrecognised predicate '"+u+"'", IssueSeverity.ERROR); } } } @@ -182,13 +181,13 @@ public class TurtleParser extends ParserBase { } } - private void parseChildInstance(Turtle src, String npath, TTLComplex object, Element element, Property property, String name, TTLObject e) throws FHIRException { + private void parseChildInstance(Turtle src, String npath, TTLComplex object, Element context, Property property, String name, TTLObject e) throws FHIRException { if (property.isResource()) - parseResource(src, npath, object, element, property, name, e); + parseResource(src, npath, object, context, property, name, e); else if (e instanceof TTLComplex) { TTLComplex child = (TTLComplex) e; Element n = new Element(tail(name), property).markLocation(e.getLine(), e.getCol()); - element.getChildren().add(n); + context.getChildren().add(n); if (property.isPrimitive(property.getType(tail(name)))) { parseChildren(src, npath, child, n, true); TTLObject val = child.getPredicates().get(FHIR_URI_BASE + "value"); @@ -199,13 +198,13 @@ public class TurtleParser extends ParserBase { // todo: check type n.setValue(value); } else - logError(object.getLine(), object.getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_A_LITERAL_NOT_A_, e.getClass().getName()), IssueSeverity.ERROR); + logError(object.getLine(), object.getCol(), npath, IssueType.INVALID, "This property must be a Literal, not a "+e.getClass().getName(), IssueSeverity.ERROR); } } else parseChildren(src, npath, child, n, false); } else - logError(object.getLine(), object.getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_A_URI_OR_BNODE_NOT_A_, e.getClass().getName()), IssueSeverity.ERROR); + logError(object.getLine(), object.getCol(), npath, IssueType.INVALID, "This property must be a URI or bnode, not a "+e.getClass().getName(), IssueSeverity.ERROR); } @@ -213,7 +212,7 @@ public class TurtleParser extends ParserBase { return name.substring(name.lastIndexOf(".")+1); } - private void parseResource(Turtle src, String npath, TTLComplex object, Element element, Property property, String name, TTLObject e) throws FHIRException { + private void parseResource(Turtle src, String npath, TTLComplex object, Element context, Property property, String name, TTLObject e) throws FHIRException { TTLComplex obj; if (e instanceof TTLComplex) obj = (TTLComplex) e; @@ -221,15 +220,15 @@ public class TurtleParser extends ParserBase { String url = ((TTLURL) e).getUri(); obj = src.getObject(url); if (obj == null) { - logError(e.getLine(), e.getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.REFERENCE_TO__CANNOT_BE_RESOLVED, url), IssueSeverity.FATAL); + logError(e.getLine(), e.getCol(), npath, IssueType.INVALID, "reference to "+url+" cannot be resolved", IssueSeverity.FATAL); return; } } else - throw new FHIRFormatError(context.formatMessage(I18nConstants.WRONG_TYPE_FOR_RESOURCE)); + throw new FHIRFormatError("Wrong type for resource"); TTLObject type = obj.getPredicates().get("http://www.w3.org/2000/01/rdf-schema#type"); if (type == null) { - logError(object.getLine(), object.getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.UNKNOWN_RESOURCE_TYPE_MISSING_RDFSTYPE), IssueSeverity.FATAL); + logError(object.getLine(), object.getCol(), npath, IssueType.INVALID, "Unknown resource type (missing rdfs:type)", IssueSeverity.FATAL); return; } if (type instanceof TTLList) { @@ -242,7 +241,7 @@ public class TurtleParser extends ParserBase { } } if (!(type instanceof TTLURL)) { - logError(object.getLine(), object.getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.UNEXPECTED_DATATYPE_FOR_RDFSTYPE), IssueSeverity.FATAL); + logError(object.getLine(), object.getCol(), npath, IssueType.INVALID, "Unexpected datatype for rdfs:type)", IssueSeverity.FATAL); return; } String rt = ((TTLURL) type).getUri(); @@ -254,7 +253,7 @@ public class TurtleParser extends ParserBase { return; Element n = new Element(tail(name), property).markLocation(object.getLine(), object.getCol()); - element.getChildren().add(n); + context.getChildren().add(n); n.updateProperty(new Property(this.context, sd.getSnapshot().getElement().get(0), sd), SpecialElement.fromProperty(n.getProperty()), property); n.setType(rt); parseChildren(src, npath, obj, n, false); @@ -279,7 +278,7 @@ public class TurtleParser extends ParserBase { if (en == null) en = property.getDefinition().getPath(); if (!en.endsWith("[x]")) - throw new Error(context.formatMessage(I18nConstants.ATTEMPT_TO_REPLACE_ELEMENT_NAME_FOR_A_NONCHOICE_TYPE)); + throw new Error("Attempt to replace element name for a non-choice type"); return en.substring(0, en.lastIndexOf(".")+1)+elementName; } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/XmlParser.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/XmlParser.java index c8bf87a03..5592aeef9 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/XmlParser.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/XmlParser.java @@ -54,7 +54,6 @@ import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.r5.utils.formats.XmlLocationAnnotator; import org.hl7.fhir.r5.utils.formats.XmlLocationData; import org.hl7.fhir.utilities.ElementDecoration; -import org.hl7.fhir.utilities.I18nConstants; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; @@ -141,8 +140,7 @@ public class XmlParser extends ParserBase { Node node = document.getFirstChild(); while (node != null) { if (node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) - logError(line(document), col(document), "(document)", IssueType.INVALID, context.formatMessage( - I18nConstants.NO_PROCESSING_INSTRUCTIONS_ALLOWED_IN_RESOURCES), IssueSeverity.ERROR); + logError(line(document), col(document), "(document)", IssueType.INVALID, "No processing instructions allowed in resources", IssueSeverity.ERROR); node = node.getNextSibling(); } } @@ -216,14 +214,14 @@ public class XmlParser extends ParserBase { private void checkElement(org.w3c.dom.Element element, String path, Property prop) throws FHIRFormatError { if (policy == ValidationPolicy.EVERYTHING) { if (empty(element) && FormatUtilities.FHIR_NS.equals(element.getNamespaceURI())) // this rule only applies to FHIR Content - logError(line(element), col(element), path, IssueType.INVALID, context.formatMessage(I18nConstants.ELEMENT_MUST_HAVE_SOME_CONTENT), IssueSeverity.ERROR); + logError(line(element), col(element), path, IssueType.INVALID, "Element must have some content", IssueSeverity.ERROR); String ns = FormatUtilities.FHIR_NS; if (ToolingExtensions.hasExtension(prop.getDefinition(), "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace")) ns = ToolingExtensions.readStringExtension(prop.getDefinition(), "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace"); else if (ToolingExtensions.hasExtension(prop.getStructure(), "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace")) ns = ToolingExtensions.readStringExtension(prop.getStructure(), "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace"); if (!element.getNamespaceURI().equals(ns)) - logError(line(element), col(element), path, IssueType.INVALID, context.formatMessage(I18nConstants.WRONG_NAMESPACE__EXPECTED_, ns), IssueSeverity.ERROR); + logError(line(element), col(element), path, IssueType.INVALID, "Wrong namespace - expected '"+ns+"'", IssueSeverity.ERROR); } } @@ -238,10 +236,10 @@ public class XmlParser extends ParserBase { return result; } - private void parseChildren(String path, org.w3c.dom.Element node, Element element) throws FHIRFormatError, FHIRException, IOException, DefinitionException { + private void parseChildren(String path, org.w3c.dom.Element node, Element context) throws FHIRFormatError, FHIRException, IOException, DefinitionException { // this parsing routine retains the original order in a the XML file, to support validation - reapComments(node, element); - List properties = element.getProperty().getChildProperties(element.getName(), XMLUtil.getXsiType(node)); + reapComments(node, context); + List properties = context.getProperty().getChildProperties(context.getName(), XMLUtil.getXsiType(node)); String text = XMLUtil.getDirectText(node).trim(); if (!Utilities.noString(text)) { @@ -249,17 +247,17 @@ public class XmlParser extends ParserBase { if (property != null) { if ("ED.data[x]".equals(property.getDefinition().getId()) || (property.getDefinition()!=null && property.getDefinition().getBase()!=null && "ED.data[x]".equals(property.getDefinition().getBase().getPath()))) { if ("B64".equals(node.getAttribute("representation"))) { - element.getChildren().add(new Element("dataBase64Binary", property, "base64Binary", text).markLocation(line(node), col(node))); + context.getChildren().add(new Element("dataBase64Binary", property, "base64Binary", text).markLocation(line(node), col(node))); } else { - element.getChildren().add(new Element("dataString", property, "string", text).markLocation(line(node), col(node))); + context.getChildren().add(new Element("dataString", property, "string", text).markLocation(line(node), col(node))); } } else { - element.getChildren().add( + context.getChildren().add( new Element(property.getName(), property, property.getType(), text).markLocation(line(node), col(node))); } } else { - logError(line(node), col(node), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.TEXT_SHOULD_NOT_BE_PRESENT), IssueSeverity.ERROR); + logError(line(node), col(node), path, IssueType.STRUCTURE, "Text should not be present", IssueSeverity.ERROR); } } @@ -271,10 +269,10 @@ public class XmlParser extends ParserBase { String av = attr.getNodeValue(); if (ToolingExtensions.hasExtension(property.getDefinition(), "http://www.healthintersections.com.au/fhir/StructureDefinition/elementdefinition-dateformat")) av = convertForDateFormatFromExternal(ToolingExtensions.readStringExtension(property.getDefinition(), "http://www.healthintersections.com.au/fhir/StructureDefinition/elementdefinition-dateformat"), av); - if (property.getName().equals("value") && element.isPrimitive()) - element.setValue(av); + if (property.getName().equals("value") && context.isPrimitive()) + context.setValue(av); else - element.getChildren().add(new Element(property.getName(), property, property.getType(), av).markLocation(line(node), col(node))); + context.getChildren().add(new Element(property.getName(), property, property.getType(), av).markLocation(line(node), col(node))); } else { boolean ok = false; if (FormatUtilities.FHIR_NS.equals(node.getNamespaceURI())) { @@ -283,9 +281,9 @@ public class XmlParser extends ParserBase { } } else ok = ok || (attr.getLocalName().equals("schemaLocation")); // xsi:schemalocation allowed for non FHIR content - ok = ok || (hasTypeAttr(element) && attr.getLocalName().equals("type") && FormatUtilities.NS_XSI.equals(attr.getNamespaceURI())); // xsi:type allowed if element says so + ok = ok || (hasTypeAttr(context) && attr.getLocalName().equals("type") && FormatUtilities.NS_XSI.equals(attr.getNamespaceURI())); // xsi:type allowed if element says so if (!ok) - logError(line(node), col(node), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.UNDEFINED_ATTRIBUTE__ON__FOR_TYPE__PROPERTIES__, attr.getNodeName(), node.getNodeName(), element.fhirType(), properties), IssueSeverity.ERROR); + logError(line(node), col(node), path, IssueType.STRUCTURE, "Undefined attribute '@"+attr.getNodeName()+"' on "+node.getNodeName()+" for type "+context.fhirType()+" (properties = "+properties+")", IssueSeverity.ERROR); } } } @@ -297,11 +295,11 @@ public class XmlParser extends ParserBase { if (property != null) { if (!property.isChoice() && "xhtml".equals(property.getType())) { XhtmlNode xhtml; - if (property.getDefinition().hasRepresentation(PropertyRepresentation.CDATEXT)) + if (property.getDefinition().hasRepresentation(PropertyRepresentation.CDATEXT)) xhtml = new CDANarrativeFormat().convert((org.w3c.dom.Element) child); else xhtml = new XhtmlParser().setValidatorMode(true).parseHtmlNode((org.w3c.dom.Element) child); - element.getChildren().add(new Element(property.getName(), property, "xhtml", new XhtmlComposer(XhtmlComposer.XML, false).compose(xhtml)).setXhtml(xhtml).markLocation(line(child), col(child))); + context.getChildren().add(new Element(property.getName(), property, "xhtml", new XhtmlComposer(XhtmlComposer.XML, false).compose(xhtml)).setXhtml(xhtml).markLocation(line(child), col(child))); } else { String npath = path+"/"+pathPrefix(child.getNamespaceURI())+child.getLocalName(); Element n = new Element(child.getLocalName(), property).markLocation(line(child), col(child)); @@ -315,7 +313,7 @@ public class XmlParser extends ParserBase { xsiType = ToolingExtensions.readStringExtension(property.getDefinition(), "http://hl7.org/fhir/StructureDefinition/elementdefinition-defaulttype"); n.setType(xsiType); } else { - logError(line(child), col(child), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.NO_TYPE_FOUND_ON_, child.getLocalName()), IssueSeverity.ERROR); + logError(line(child), col(child), path, IssueType.STRUCTURE, "No type found on '"+child.getLocalName()+'"', IssueSeverity.ERROR); ok = false; } } else { @@ -327,7 +325,7 @@ public class XmlParser extends ParserBase { } else n.setType(n.getType()); } - element.getChildren().add(n); + context.getChildren().add(n); if (ok) { if (property.isResource()) parseResource(npath, (org.w3c.dom.Element) child, n, property); @@ -336,11 +334,11 @@ public class XmlParser extends ParserBase { } } } else - logError(line(child), col(child), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.UNDEFINED_ELEMENT_, child.getLocalName()), IssueSeverity.ERROR); + logError(line(child), col(child), path, IssueType.STRUCTURE, "Undefined element '"+child.getLocalName()+"'", IssueSeverity.ERROR); } else if (child.getNodeType() == Node.CDATA_SECTION_NODE){ - logError(line(child), col(child), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.CDATA_IS_NOT_ALLOWED), IssueSeverity.ERROR); + logError(line(child), col(child), path, IssueType.STRUCTURE, "CDATA is not allowed", IssueSeverity.ERROR); } else if (!Utilities.existsInList(child.getNodeType(), 3, 8)) { - logError(line(child), col(child), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.NODE_TYPE__IS_NOT_ALLOWED, Integer.toString(child.getNodeType())), IssueSeverity.ERROR); + logError(line(child), col(child), path, IssueType.STRUCTURE, "Node type "+Integer.toString(child.getNodeType())+" is not allowed", IssueSeverity.ERROR); } child = child.getNextSibling(); } @@ -357,8 +355,7 @@ public class XmlParser extends ParserBase { } }); for (Property p : propsSortedByLongestFirst) - if (!p.getDefinition().hasRepresentation(PropertyRepresentation.XMLATTR) && !p.getDefinition().hasRepresentation( - PropertyRepresentation.XMLTEXT)) { + if (!p.getDefinition().hasRepresentation(PropertyRepresentation.XMLATTR) && !p.getDefinition().hasRepresentation(PropertyRepresentation.XMLTEXT)) { if (p.getName().equals(nodeName)) return p; if (p.getName().endsWith("[x]") && nodeName.length() > p.getName().length()-3 && p.getName().substring(0, p.getName().length()-3).equals(nodeName.substring(0, p.getName().length()-3))) @@ -369,8 +366,7 @@ public class XmlParser extends ParserBase { private Property getAttrProp(List properties, String nodeName) { for (Property p : properties) - if (p.getName().equals(nodeName) && p.getDefinition().hasRepresentation( - PropertyRepresentation.XMLATTR)) + if (p.getName().equals(nodeName) && p.getDefinition().hasRepresentation(PropertyRepresentation.XMLATTR)) return p; return null; } @@ -387,7 +383,7 @@ public class XmlParser extends ParserBase { DateTimeType d = DateTimeType.parseV3(av); return d.asStringValue(); } else - throw new FHIRException(context.formatMessage(I18nConstants.UNKNOWN_DATA_FORMAT_, fmt)); + throw new FHIRException("Unknown Data format '"+fmt+"'"); } private String convertForDateFormatToExternal(String fmt, String av) throws FHIRException { @@ -395,7 +391,7 @@ public class XmlParser extends ParserBase { DateTimeType d = new DateTimeType(av); return d.getAsV3(); } else - throw new FHIRException(context.formatMessage(I18nConstants.UNKNOWN_DATE_FORMAT_, fmt)); + throw new FHIRException("Unknown Date format '"+fmt+"'"); } private void parseResource(String string, org.w3c.dom.Element container, Element parent, Property elementProperty) throws FHIRFormatError, DefinitionException, FHIRException, IOException { @@ -403,7 +399,7 @@ public class XmlParser extends ParserBase { String name = res.getLocalName(); StructureDefinition sd = context.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(name, context.getOverrideVersionNs())); if (sd == null) - throw new FHIRFormatError(context.formatMessage(I18nConstants.CONTAINED_RESOURCE_DOES_NOT_APPEAR_TO_BE_A_FHIR_RESOURCE_UNKNOWN_NAME_, res.getLocalName())); + throw new FHIRFormatError("Contained resource does not appear to be a FHIR resource (unknown name '"+res.getLocalName()+"')"); parent.updateProperty(new Property(context, sd.getSnapshot().getElement().get(0), sd), SpecialElement.fromProperty(parent.getProperty()), elementProperty); parent.setType(name); parseChildren(res.getLocalName(), res, parent); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetCheckerSimple.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetCheckerSimple.java index f3bcb334b..2cefc64ce 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetCheckerSimple.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetCheckerSimple.java @@ -9,9 +9,9 @@ package org.hl7.fhir.r5.terminologies; * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -45,7 +45,6 @@ import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent; import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; -import org.hl7.fhir.utilities.I18nConstants; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.validation.ValidationOptions; import org.hl7.fhir.utilities.validation.ValidationOptions.ValueSetMode; @@ -71,7 +70,7 @@ public class ValueSetCheckerSimple implements ValueSetChecker { if (options.getValueSetMode() != ValueSetMode.CHECK_MEMERSHIP_ONLY) { for (Coding c : code.getCoding()) { if (!c.hasSystem()) - warnings.add(context.formatMessage(I18nConstants.CODING_HAS_NO_SYSTEM__CANNOT_VALIDATE)); + warnings.add("Coding has no system - cannot validate"); CodeSystem cs = context.fetchCodeSystem(c.getSystem()); ValidationResult res = null; if (cs == null || cs.getContent() != CodeSystemContentMode.COMPLETE) { @@ -91,7 +90,7 @@ public class ValueSetCheckerSimple implements ValueSetChecker { ok = ok || codeInValueSet(c.getSystem(), c.getCode()); } if (!ok) - errors.add(0, context.formatMessage(I18nConstants.NONE_OF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_, valueset.getUrl())); + errors.add(0, "None of the provided codes are in the value set "+valueset.getUrl()); } if (errors.size() > 0) return new ValidationResult(IssueSeverity.ERROR, errors.toString()); @@ -139,7 +138,7 @@ public class ValueSetCheckerSimple implements ValueSetChecker { if (!inExpansion) res.setMessage("Not in value set "+valueset.getUrl()).setSeverity(IssueSeverity.ERROR); else if (warningMessage!=null) - res = new ValidationResult(IssueSeverity.WARNING, context.formatMessage(I18nConstants.CODE_FOUND_IN_EXPANSION_HOWEVER_, warningMessage)); + res = new ValidationResult(IssueSeverity.WARNING, "Code found in expansion, however: " + warningMessage); else res.setMessage("Code found in expansion, however: " + res.getMessage()); } @@ -166,7 +165,7 @@ public class ValueSetCheckerSimple implements ValueSetChecker { private ValidationResult validateCode(Coding code, CodeSystem cs) { ConceptDefinitionComponent cc = findCodeInConcept(cs.getConcept(), code.getCode()); if (cc == null) - return new ValidationResult(IssueSeverity.ERROR, context.formatMessage(I18nConstants.UNKNOWN_CODE__IN_, gen(code), cs.getUrl())); + return new ValidationResult(IssueSeverity.ERROR, "Unknown Code "+gen(code)+" in "+cs.getUrl()); if (code.getDisplay() == null) return new ValidationResult(cc); CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); @@ -194,7 +193,7 @@ public class ValueSetCheckerSimple implements ValueSetChecker { return new ValidationResult(cc); } } - return new ValidationResult(IssueSeverity.WARNING, context.formatMessage(I18nConstants.DISPLAY_NAME_FOR__SHOULD_BE_ONE_OF__INSTEAD_OF_, code.getSystem(), code.getCode(), b.toString(), code.getDisplay()), cc); + return new ValidationResult(IssueSeverity.WARNING, "Display Name for "+code.getSystem()+"#"+code.getCode()+" should be one of '"+b.toString()+"' instead of '"+code.getDisplay()+"'", cc); } private ConceptReferenceComponent findValueSetRef(String system, String code) { @@ -234,25 +233,25 @@ public class ValueSetCheckerSimple implements ValueSetChecker { private String getValueSetSystem() throws FHIRException { if (valueset == null) - throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_SYSTEM__NO_VALUE_SET)); + throw new FHIRException("Unable to resolve system - no value set"); if (valueset.getCompose().hasExclude()) - throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_SYSTEM__VALUE_SET_HAS_EXCLUDES)); + throw new FHIRException("Unable to resolve system - value set has excludes"); if (valueset.getCompose().getInclude().size() == 0) { if (!valueset.hasExpansion() || valueset.getExpansion().getContains().size() == 0) - throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_SYSTEM__VALUE_SET_HAS_NO_INCLUDES_OR_EXPANSION)); + throw new FHIRException("Unable to resolve system - value set has no includes or expansion"); else { String cs = valueset.getExpansion().getContains().get(0).getSystem(); if (cs != null && checkSystem(valueset.getExpansion().getContains(), cs)) return cs; else - throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_SYSTEM__VALUE_SET_EXPANSION_HAS_MULTIPLE_SYSTEMS)); + throw new FHIRException("Unable to resolve system - value set expansion has multiple systems"); } } for (ConceptSetComponent inc : valueset.getCompose().getInclude()) { if (inc.hasValueSet()) - throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_SYSTEM__VALUE_SET_HAS_IMPORTS)); + throw new FHIRException("Unable to resolve system - value set has imports"); if (!inc.hasSystem()) - throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_SYSTEM__VALUE_SET_HAS_INCLUDE_WITH_NO_SYSTEM)); + throw new FHIRException("Unable to resolve system - value set has include with no system"); } if (valueset.getCompose().getInclude().size() == 1) return valueset.getCompose().getInclude().get(0).getSystem(); @@ -361,7 +360,7 @@ public class ValueSetCheckerSimple implements ValueSetChecker { // ok, we need the code system CodeSystem cs = context.fetchCodeSystem(system); if (cs == null || cs.getContent() != CodeSystemContentMode.COMPLETE) { - // make up a transient value set with + // make up a transient value set with ValueSet vs = new ValueSet(); vs.setUrl(Utilities.makeUuidUrn()); vs.getCompose().addInclude(vsi); @@ -396,7 +395,7 @@ public class ValueSetCheckerSimple implements ValueSetChecker { return codeInConceptFilter(cs, f, code); else { System.out.println("todo: handle filters with property = "+f.getProperty()); - throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_HANDLE_SYSTEM__FILTER_WITH_PROPERTY__, cs.getUrl(), f.getProperty())); + throw new FHIRException("Unable to handle system "+cs.getUrl()+" filter with property = "+f.getProperty()); } } @@ -406,7 +405,7 @@ public class ValueSetCheckerSimple implements ValueSetChecker { case ISNOTA: return !codeInConceptIsAFilter(cs, f, code); default: System.out.println("todo: handle concept filters with op = "+f.getOp()); - throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_HANDLE_SYSTEM__CONCEPT_FILTER_WITH_OP__, cs.getUrl(), f.getOp())); + throw new FHIRException("Unable to handle system "+cs.getUrl()+" concept filter with op = "+f.getOp()); } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/IResourceValidator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/IResourceValidator.java index 8f2ec973c..86852318a 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/IResourceValidator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/IResourceValidator.java @@ -143,10 +143,9 @@ public interface IResourceValidator { public boolean isShowMessagesFromReferences(); public void setShowMessagesFromReferences(boolean value); - - //FIXME: don't need that, gets never used? -// public String getValidationLanguage(); -// public void setValidationLanguage(String value); + + public String getValidationLanguage(); + public void setValidationLanguage(String value); /** * It's common to see references such as Patient/234234 - these usually mean a reference to a Patient resource. diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java index e1f616090..1a0b6e97a 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java @@ -64,16 +64,17 @@ public class BaseValidator { protected Source source; protected IWorkerContext context; - + private ResourceBundle messages; public BaseValidator(IWorkerContext context){ this.context = context; + messages = ResourceBundle.getBundle("Messages", context.getLocale() ); } -// public void setContext(IWorkerContext context) { -// this.context = context; -// i18Nmessages = ResourceBundle.getBundle("Messages", context.getLocale() ); -// } + public void setContext(IWorkerContext context) { + this.context = context; + messages = ResourceBundle.getBundle("Messages", context.getLocale() ); + } /** * Test a rule and add a {@link IssueSeverity#FATAL} validation message if the validation fails @@ -92,7 +93,7 @@ public class BaseValidator { protected boolean fail(List errors, IssueType type, int line, int col, String path, boolean thePass, String theMessage, Object... theMessageArguments) { if (!thePass) { - String msg = context.formatMessage(theMessage, theMessageArguments); + String msg = formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, type, line, col, path, msg, IssueSeverity.FATAL); } return thePass; @@ -123,7 +124,7 @@ public class BaseValidator { protected boolean fail(List errors, IssueType type, List pathParts, boolean thePass, String theMessage, Object... theMessageArguments) { if (!thePass) { String path = toPath(pathParts); - addValidationMessage(errors, type, -1, -1, path, context.formatMessage(theMessage, theMessageArguments), IssueSeverity.FATAL); + addValidationMessage(errors, type, -1, -1, path, formatMessage(theMessage, theMessageArguments), IssueSeverity.FATAL); } return thePass; } @@ -142,6 +143,21 @@ public class BaseValidator { return thePass; } + + protected String formatMessage(String theMessage, Object... theMessageArguments) { + String message = ""; + if (messages.containsKey(theMessage)) { + if (theMessageArguments != null && theMessageArguments.length > 0) { + message = MessageFormat.format(messages.getString(theMessage), theMessageArguments); + } else if (messages.containsKey(theMessage)) { + message = messages.getString(theMessage); + } + } else { + message = theMessage; + } + return message; + } + protected boolean grammarWord(String w) { return w.equals("and") || w.equals("or") || w.equals("a") || w.equals("the") || w.equals("for") || w.equals("this") || w.equals("that") || w.equals("of"); } @@ -155,7 +171,7 @@ public class BaseValidator { */ protected boolean hint(List errors, IssueType type, int line, int col, String path, boolean thePass, String msg) { if (!thePass) { - String message = context.formatMessage(msg); + String message = formatMessage(msg); addValidationMessage(errors, type, line, col, path, message, IssueSeverity.INFORMATION); } return thePass; @@ -185,7 +201,7 @@ public class BaseValidator { */ protected boolean hint(List errors, IssueType type, int line, int col, String path, boolean thePass, String theMessage, Object... theMessageArguments) { if (!thePass) { - String message = context.formatMessage(theMessage, theMessageArguments); + String message = formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, type, line, col, path, message, IssueSeverity.INFORMATION); } return thePass; @@ -193,7 +209,7 @@ public class BaseValidator { protected boolean txHint(List errors, String txLink, IssueType type, int line, int col, String path, boolean thePass, String theMessage, Object... theMessageArguments) { if (!thePass) { - String message = context.formatMessage(theMessage, theMessageArguments); + String message = formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, type, line, col, path, message, IssueSeverity.INFORMATION, Source.TerminologyEngine).setTxLink(txLink); } return thePass; @@ -209,7 +225,7 @@ public class BaseValidator { protected boolean hint(List errors, IssueType type, List pathParts, boolean thePass, String theMessage, Object... theMessageArguments) { if (!thePass) { String path = toPath(pathParts); - String message = context.formatMessage(theMessage, theMessageArguments); + String message = formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, type, -1, -1, path, message, IssueSeverity.INFORMATION); } return thePass; @@ -238,7 +254,7 @@ public class BaseValidator { */ protected boolean rule(List errors, IssueType type, int line, int col, String path, boolean thePass, String theMessage, Object... theMessageArguments) { if (!thePass) { - String message = context.formatMessage(theMessage, theMessageArguments); + String message = formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, type, line, col, path, message, IssueSeverity.ERROR); } return thePass; @@ -246,7 +262,7 @@ public class BaseValidator { protected boolean txRule(List errors, String txLink, IssueType type, int line, int col, String path, boolean thePass, String theMessage, Object... theMessageArguments) { if (!thePass) { - String message = context.formatMessage(theMessage, theMessageArguments); + String message = formatMessage(theMessage, theMessageArguments); errors.add(new ValidationMessage(Source.TerminologyEngine, type, line, col, path, message, IssueSeverity.ERROR).setTxLink(txLink)); } return thePass; @@ -277,7 +293,7 @@ public class BaseValidator { protected boolean rule(List errors, IssueType type, List pathParts, boolean thePass, String theMessage, Object... theMessageArguments) { if (!thePass) { String path = toPath(pathParts); - String message = context.formatMessage(theMessage, theMessageArguments); + String message = formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, type, -1, -1, path, message, IssueSeverity.ERROR); } return thePass; @@ -301,7 +317,7 @@ public class BaseValidator { protected boolean rule(List errors, IssueType type, String path, boolean thePass, String theMessage, Object... theMessageArguments) { if (!thePass) { - String message = context.formatMessage(theMessage, theMessageArguments); + String message = formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, type, -1, -1, path, message, IssueSeverity.ERROR); } return thePass; @@ -365,7 +381,7 @@ public class BaseValidator { */ protected boolean warning(List errors, IssueType type, int line, int col, String path, boolean thePass, String msg, Object... theMessageArguments) { if (!thePass) { - msg = context.formatMessage(msg, theMessageArguments); + msg = formatMessage(msg, theMessageArguments); IssueSeverity severity = IssueSeverity.WARNING; addValidationMessage(errors, type, line, col, path, msg, severity); } @@ -393,7 +409,7 @@ public class BaseValidator { */ protected boolean txWarning(List errors, String txLink, IssueType type, int line, int col, String path, boolean thePass, String msg, Object... theMessageArguments) { if (!thePass) { - msg = context.formatMessage(msg, theMessageArguments); + msg = formatMessage(msg, theMessageArguments); errors.add(new ValidationMessage(Source.TerminologyEngine, type, line, col, path, msg, IssueSeverity.WARNING).setTxLink(txLink)); } return thePass; @@ -402,7 +418,7 @@ public class BaseValidator { protected boolean warningOrError(boolean isError, List errors, IssueType type, int line, int col, String path, boolean thePass, String msg, Object... theMessageArguments) { if (!thePass) { - msg = context.formatMessage(msg, theMessageArguments); + msg = formatMessage(msg, theMessageArguments); addValidationMessage(errors, type, line, col, path, msg, isError ? IssueSeverity.ERROR : IssueSeverity.WARNING); } return thePass; @@ -419,7 +435,7 @@ public class BaseValidator { protected boolean warning(List errors, IssueType type, List pathParts, boolean thePass, String theMessage, Object... theMessageArguments) { if (!thePass) { String path = toPath(pathParts); - String message = context.formatMessage(theMessage, theMessageArguments); + String message = formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, type, -1, -1, path, message, IssueSeverity.WARNING); } return thePass; @@ -462,7 +478,7 @@ public class BaseValidator { */ protected boolean warning(List errors, IssueType type, String path, boolean thePass, String msg, String html, Object... theMessageArguments) { if (!thePass) { - msg = context.formatMessage(msg, theMessageArguments); + msg = formatMessage(msg, theMessageArguments); addValidationMessage(errors, type, path, msg, html, IssueSeverity.WARNING); } return thePass; @@ -478,7 +494,7 @@ public class BaseValidator { */ protected boolean suppressedwarning(List errors, IssueType type, int line, int col, String path, boolean thePass, String msg, Object... theMessageArguments) { if (!thePass) { - msg = context.formatMessage(msg, theMessageArguments); + msg = formatMessage(msg, theMessageArguments); addValidationMessage(errors, type, line, col, path, msg, IssueSeverity.INFORMATION); } return thePass; @@ -495,7 +511,7 @@ public class BaseValidator { protected boolean suppressedwarning(List errors, IssueType type, List pathParts, boolean thePass, String theMessage, Object... theMessageArguments) { if (!thePass) { String path = toPath(pathParts); - String message = context.formatMessage(theMessage, theMessageArguments); + String message = formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, type, -1, -1, path, message, IssueSeverity.INFORMATION); } return thePass; @@ -543,7 +559,7 @@ public class BaseValidator { */ protected boolean suppressedwarning(List errors, IssueType type, String path, boolean thePass, String msg, String html, Object... theMessageArguments) { if (!thePass) { - msg = context.formatMessage(msg, theMessageArguments); + msg = formatMessage(msg, theMessageArguments); addValidationMessage(errors, type, path, msg, html, IssueSeverity.INFORMATION); } return thePass; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java index f6ccb25f0..2cff601ae 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java @@ -126,7 +126,6 @@ import org.hl7.fhir.r5.utils.FHIRPathEngine; import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext; import org.hl7.fhir.r5.utils.IResourceValidator; import org.hl7.fhir.r5.utils.ToolingExtensions; -import org.hl7.fhir.utilities.I18nConstants; import org.hl7.fhir.validation.BaseValidator; import org.hl7.fhir.validation.instance.EnableWhenEvaluator.QStack; import org.hl7.fhir.validation.XVerExtensionManager; @@ -142,6 +141,7 @@ import org.hl7.fhir.utilities.validation.ValidationMessage.Source; import org.hl7.fhir.utilities.xhtml.NodeType; import org.hl7.fhir.utilities.xhtml.XhtmlNode; import org.hl7.fhir.validation.instance.utils.*; +import org.hl7.fhir.validation.utils.I18nConstants; import org.w3c.dom.Document; import com.google.gson.Gson; @@ -197,17 +197,17 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat @Override public FunctionDetails resolveFunction(String functionName) { - throw new Error(context.formatMessage(I18nConstants.NOT_DONE_YET_VALIDATORHOSTSERVICESRESOLVEFUNCTION_, functionName)); + throw new Error(formatMessage(I18nConstants.NOT_DONE_YET_VALIDATORHOSTSERVICESRESOLVEFUNCTION_, functionName)); } @Override public TypeDetails checkFunction(Object appContext, String functionName, List parameters) throws PathEngineException { - throw new Error(context.formatMessage(I18nConstants.NOT_DONE_YET_VALIDATORHOSTSERVICESCHECKFUNCTION)); + throw new Error(formatMessage(I18nConstants.NOT_DONE_YET_VALIDATORHOSTSERVICESCHECKFUNCTION)); } @Override public List executeFunction(Object appContext, String functionName, List> parameters) { - throw new Error(context.formatMessage(I18nConstants.NOT_DONE_YET_VALIDATORHOSTSERVICESEXECUTEFUNCTION)); + throw new Error(formatMessage(I18nConstants.NOT_DONE_YET_VALIDATORHOSTSERVICESEXECUTEFUNCTION)); } @Override @@ -240,7 +240,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat throw new FHIRException(e); } else - throw new Error(context.formatMessage(I18nConstants.NOT_DONE_YET__RESOLVE__LOCALLY_2, url)); + throw new Error(formatMessage(I18nConstants.NOT_DONE_YET__RESOLVE__LOCALLY_2, url)); } @@ -269,7 +269,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat ValidatorHostContext ctxt = (ValidatorHostContext) appContext; StructureDefinition sd = context.fetchResource(StructureDefinition.class, url); if (sd == null) { - throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_, url)); + throw new FHIRException(formatMessage(I18nConstants.UNABLE_TO_RESOLVE_, url)); } InstanceValidator self = InstanceValidator.this; List valerrors = new ArrayList(); @@ -285,10 +285,10 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (e.isResource()) { self.validateResource(new ValidatorHostContext(ctxt.getAppContext(), e), valerrors, e, e, sd, IdStatus.OPTIONAL, new NodeStack(e)); } else { - throw new FHIRException(context.formatMessage(I18nConstants.NOT_SUPPORTED_YET)); + throw new FHIRException(formatMessage(I18nConstants.NOT_SUPPORTED_YET)); } } else - throw new NotImplementedException(context.formatMessage(I18nConstants.NOT_DONE_YET_VALIDATORHOSTSERVICESCONFORMSTOPROFILE_WHEN_ITEM_IS_NOT_AN_ELEMENT)); + throw new NotImplementedException(formatMessage(I18nConstants.NOT_DONE_YET_VALIDATORHOSTSERVICESCONFORMSTOPROFILE_WHEN_ITEM_IS_NOT_AN_ELEMENT)); boolean ok = true; List record = new ArrayList<>(); for (ValidationMessage v : valerrors) { @@ -312,7 +312,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (r instanceof ValueSet) return (ValueSet) r; else - throw new FHIRException(context.formatMessage(I18nConstants.REFERENCE__REFERS_TO_A__NOT_A_VALUESET, url, r.fhirType())); + throw new FHIRException(formatMessage(I18nConstants.REFERENCE__REFERS_TO_A__NOT_A_VALUESET, url, r.fhirType())); } } return null; @@ -515,7 +515,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat private StructureDefinition getSpecifiedProfile(String profile) { StructureDefinition sd = context.fetchResource(StructureDefinition.class, profile); if (sd == null) { - throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_LOCATE_THE_PROFILE__IN_ORDER_TO_VALIDATE_AGAINST_IT, profile)); + throw new FHIRException(formatMessage(I18nConstants.UNABLE_TO_LOCATE_THE_PROFILE__IN_ORDER_TO_VALIDATE_AGAINST_IT, profile)); } return sd; } @@ -1568,7 +1568,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat ok = true; } } else { - throw new Error(context.formatMessage(I18nConstants.UNRECOGNISED_EXTENSION_CONTEXT_, ctxt.getTypeElement().asStringValue())); + throw new Error(formatMessage(I18nConstants.UNRECOGNISED_EXTENSION_CONTEXT_, ctxt.getTypeElement().asStringValue())); } } if (!ok) { @@ -2095,7 +2095,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (we == null) { if (fetcher == null) { if (!refType.equals("contained")) - throw new FHIRException(context.formatMessage(I18nConstants.RESOURCE_RESOLUTION_SERVICES_NOT_PROVIDED)); + throw new FHIRException(formatMessage(I18nConstants.RESOURCE_RESOLUTION_SERVICES_NOT_PROVIDED)); } else { Element ext = null; if (fetchCache.containsKey(ref)) { @@ -2190,8 +2190,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (!isShowMessagesFromReferences()) { rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, areAllBaseProfiles(profiles), I18nConstants.REFERENCE_REF_CANTMATCHCHOICE, ref, asList(type.getTargetProfile())); for (StructureDefinition sd : badProfiles.keySet()) { - slicingHint(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, - context.formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, ref, sd.getUrl()), errorSummaryForSlicingAsHtml(badProfiles.get(sd))); + slicingHint(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, "Details for " + ref + " matching against Profile" + sd.getUrl(), errorSummaryForSlicingAsHtml(badProfiles.get(sd))); } } else { rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, profiles.size() == 1, I18nConstants.REFERENCE_REF_CANTMATCHCHOICE, ref, asList(type.getTargetProfile())); @@ -2207,7 +2206,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (!isShowMessagesFromReferences()) { warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, I18nConstants.REFERENCE_REF_MULTIPLEMATCHES, ref, asListByUrl(goodProfiles.keySet())); for (StructureDefinition sd : badProfiles.keySet()) { - slicingHint(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, context.formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, ref, sd.getUrl()), errorSummaryForSlicingAsHtml(badProfiles.get(sd))); + slicingHint(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, "Details for " + ref + " matching against Profile" + sd.getUrl(), errorSummaryForSlicingAsHtml(badProfiles.get(sd))); } } else { warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, I18nConstants.REFERENCE_REF_MULTIPLEMATCHES, ref, asListByUrl(goodProfiles.keySet())); @@ -2481,7 +2480,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat String id = p.hasExtension(ToolingExtensions.EXT_PROFILE_ELEMENT) ? p.getExtensionString(ToolingExtensions.EXT_PROFILE_ELEMENT) : null; StructureDefinition sd = context.fetchResource(StructureDefinition.class, p.getValue()); if (sd == null) - throw new DefinitionException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_PROFILE_, p)); + throw new DefinitionException(formatMessage(I18nConstants.UNABLE_TO_RESOLVE_PROFILE_, p)); profile = sd; if (id == null) element = sd.getSnapshot().getElementFirstRep(); @@ -2492,7 +2491,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat element = t; } if (element == null) - throw new DefinitionException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_ELEMENT__IN_PROFILE_, id, p)); + throw new DefinitionException(formatMessage(I18nConstants.UNABLE_TO_RESOLVE_ELEMENT__IN_PROFILE_, id, p)); } expr = fpe.parse(fixExpr(discriminator)); t2 = System.nanoTime(); @@ -2643,20 +2642,20 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (focus.fhirType().equals("Reference") && d.equals("reference")) { String url = focus.getChildValue("reference"); if (Utilities.noString(url)) - throw new FHIRException(context.formatMessage(I18nConstants.NO_REFERENCE_RESOLVING_DISCRIMINATOR__FROM_, discriminator, element.getProperty().getName())); + throw new FHIRException(formatMessage(I18nConstants.NO_REFERENCE_RESOLVING_DISCRIMINATOR__FROM_, discriminator, element.getProperty().getName())); // Note that we use the passed in stack here. This might be a problem if the discriminator is deep enough? Element target = resolve(appContext, url, stack, errors, p); if (target == null) - throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_FIND_RESOURCE__AT__RESOLVING_DISCRIMINATOR__FROM_, url, d, discriminator, element.getProperty().getName())); + throw new FHIRException(formatMessage(I18nConstants.UNABLE_TO_FIND_RESOURCE__AT__RESOLVING_DISCRIMINATOR__FROM_, url, d, discriminator, element.getProperty().getName())); focus = target; } else if (d.equals("value") && focus.isPrimitive()) { return focus; } else { List children = focus.getChildren(d); if (children.isEmpty()) - throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_FIND__RESOLVING_DISCRIMINATOR__FROM_, d, discriminator, element.getProperty().getName())); + throw new FHIRException(formatMessage(I18nConstants.UNABLE_TO_FIND__RESOLVING_DISCRIMINATOR__FROM_, d, discriminator, element.getProperty().getName())); if (children.size() > 1) - throw new FHIRException(context.formatMessage(I18nConstants.FOUND__ITEMS_FOR__RESOLVING_DISCRIMINATOR__FROM_, Integer.toString(children.size()), d, discriminator, element.getProperty().getName())); + throw new FHIRException(formatMessage(I18nConstants.FOUND__ITEMS_FOR__RESOLVING_DISCRIMINATOR__FROM_, Integer.toString(children.size()), d, discriminator, element.getProperty().getName())); focus = children.get(0); p = p + "." + d; } @@ -3081,23 +3080,23 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat discriminator = discriminator.substring(0, discriminator.indexOf('[')); type = criteriaElement.getType().get(0).getWorkingCode(); } else if (criteriaElement.getType().size() > 1) { - throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_MULTIPLE_TYPES_, discriminator, ed.getId(), profile.getUrl(), criteriaElement.typeSummary())); + throw new DefinitionException(formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_MULTIPLE_TYPES_, discriminator, ed.getId(), profile.getUrl(), criteriaElement.typeSummary())); } else - throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_NO_TYPES, discriminator, ed.getId(), profile.getUrl())); + throw new DefinitionException(formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_NO_TYPES, discriminator, ed.getId(), profile.getUrl())); if (discriminator.isEmpty()) expression.append(" and $this is " + type); else expression.append(" and " + discriminator + " is " + type); } else if (s.getType() == DiscriminatorType.PROFILE) { if (criteriaElement.getType().size() == 0) { - throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_A_TYPE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl())); + throw new DefinitionException(formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_A_TYPE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl())); } if (criteriaElement.getType().size() != 1) { - throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_ONLY_ONE_TYPE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl())); + throw new DefinitionException(formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_ONLY_ONE_TYPE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl())); } List list = discriminator.endsWith(".resolve()") || discriminator.equals("resolve()") ? criteriaElement.getType().get(0).getTargetProfile() : criteriaElement.getType().get(0).getProfile(); if (list.size() == 0) { - throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_A_TYPE_WITH_A_PROFILE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl())); + throw new DefinitionException(formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_A_TYPE_WITH_A_PROFILE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl())); } else if (list.size() > 1) { CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(" or "); for (CanonicalType c : list) { @@ -3113,7 +3112,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat else if (criteriaElement.hasMax() && criteriaElement.getMax().equals("0")) expression.append(" and (" + discriminator + ".exists().not())"); else - throw new FHIRException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_ELEMENT_EXISTENCE_BUT_SLICE__NEITHER_SETS_MIN1_OR_MAX0, discriminator, ed.getId())); + throw new FHIRException(formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_ELEMENT_EXISTENCE_BUT_SLICE__NEITHER_SETS_MIN1_OR_MAX0, discriminator, ed.getId())); } else if (criteriaElement.hasFixed()) { buildFixedExpression(ed, expression, discriminator, criteriaElement); } else if (criteriaElement.hasPattern()) { @@ -3131,15 +3130,15 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } if (!anyFound) { if (slicer.getSlicing().getDiscriminator().size() > 1) - throw new DefinitionException(context.formatMessage(I18nConstants.COULD_NOT_MATCH_ANY_DISCRIMINATORS__FOR_SLICE__IN_PROFILE___NONE_OF_THE_DISCRIMINATOR__HAVE_FIXED_VALUE_BINDING_OR_EXISTENCE_ASSERTIONS, discriminators, ed.getId(), profile.getUrl(), discriminators)); + throw new DefinitionException(formatMessage(I18nConstants.COULD_NOT_MATCH_ANY_DISCRIMINATORS__FOR_SLICE__IN_PROFILE___NONE_OF_THE_DISCRIMINATOR__HAVE_FIXED_VALUE_BINDING_OR_EXISTENCE_ASSERTIONS, discriminators, ed.getId(), profile.getUrl(), discriminators)); else - throw new DefinitionException(context.formatMessage(I18nConstants.COULD_NOT_MATCH_DISCRIMINATOR__FOR_SLICE__IN_PROFILE___THE_DISCRIMINATOR__DOES_NOT_HAVE_FIXED_VALUE_BINDING_OR_EXISTENCE_ASSERTIONS, discriminators, ed.getId(), profile.getUrl(), discriminators)); + throw new DefinitionException(formatMessage(I18nConstants.COULD_NOT_MATCH_DISCRIMINATOR__FOR_SLICE__IN_PROFILE___THE_DISCRIMINATOR__DOES_NOT_HAVE_FIXED_VALUE_BINDING_OR_EXISTENCE_ASSERTIONS, discriminators, ed.getId(), profile.getUrl(), discriminators)); } try { n = fpe.parse(fixExpr(expression.toString())); } catch (FHIRLexerException e) { - throw new FHIRException(context.formatMessage(I18nConstants.PROBLEM_PROCESSING_EXPRESSION__IN_PROFILE__PATH__, expression, profile.getUrl(), path, e.getMessage())); + throw new FHIRException(formatMessage(I18nConstants.PROBLEM_PROCESSING_EXPRESSION__IN_PROFILE__PATH__, expression, profile.getUrl(), path, e.getMessage())); } fpeTime = fpeTime + (System.nanoTime() - t); ed.setUserData("slice.expression.cache", n); @@ -3148,13 +3147,10 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat ValidatorHostContext shc = hostContext.forSlicing(); boolean pass = evaluateSlicingExpression(shc, element, path, profile, n); if (!pass) { - slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, (context.formatMessage(I18nConstants.DOES_NOT_MATCH_SLICE_, ed.getSliceName())), "discriminator = " + Utilities.escapeXml(n.toString())); + slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, "Does not match slice'" + ed.getSliceName(), "discriminator = " + Utilities.escapeXml(n.toString())); for (String url : shc.getSliceRecords().keySet()) { - slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, - context.formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, stack.getLiteralPath(), url), - context.formatMessage(I18nConstants.PROFILE__DOES_NOT_MATCH_FOR__BECAUSE_OF_THE_FOLLOWING_PROFILE_ISSUES__, - url, - stack.getLiteralPath(), errorSummaryForSlicingAsHtml(shc.getSliceRecords().get(url)))); + slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, "Details for " + stack.getLiteralPath() + " against profile " + url, + "Profile " + url + " does not match for " + stack.getLiteralPath() + " because of the following profile issues: " + errorSummaryForSlicingAsHtml(shc.getSliceRecords().get(url))); } } return pass; @@ -3170,7 +3166,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat msg = fpe.forLog(); } catch (Exception ex) { ex.printStackTrace(); - throw new FHIRException(context.formatMessage(I18nConstants.PROBLEM_EVALUATING_SLICING_EXPRESSION_FOR_ELEMENT_IN_PROFILE__PATH__FHIRPATH___, profile.getUrl(), path, n, ex.getMessage())); + throw new FHIRException(formatMessage(I18nConstants.PROBLEM_EVALUATING_SLICING_EXPRESSION_FOR_ELEMENT_IN_PROFILE__PATH__FHIRPATH___, profile.getUrl(), path, n, ex.getMessage())); } return ok; } @@ -3189,15 +3185,14 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat Identifier ii = (Identifier) pattern; expression.append(" and "); buildIdentifierExpression(ed, expression, discriminator, ii); - } else { - throw new DefinitionException(context.formatMessage(I18nConstants.UNSUPPORTED_FIXED_PATTERN_TYPE_FOR_DISCRIMINATOR_FOR_SLICE__, discriminator, ed.getId(), pattern.getClass().getName())); - } + } else + throw new DefinitionException(formatMessage(I18nConstants.UNSUPPORTED_FIXED_PATTERN_TYPE_FOR_DISCRIMINATOR_FOR_SLICE__, discriminator, ed.getId(), pattern.getClass().getName())); } private void buildIdentifierExpression(ElementDefinition ed, StringBuilder expression, String discriminator, Identifier ii) throws DefinitionException { if (ii.hasExtension()) - throw new DefinitionException(context.formatMessage(I18nConstants.UNSUPPORTED_IDENTIFIER_PATTERN__EXTENSIONS_ARE_NOT_ALLOWED__FOR_DISCRIMINATOR_FOR_SLICE_, discriminator, ed.getId())); + throw new DefinitionException(formatMessage(I18nConstants.UNSUPPORTED_IDENTIFIER_PATTERN__EXTENSIONS_ARE_NOT_ALLOWED__FOR_DISCRIMINATOR_FOR_SLICE_, discriminator, ed.getId())); boolean first = true; expression.append(discriminator + ".where("); if (ii.hasSystem()) { @@ -3231,15 +3226,15 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat private void buildCodeableConceptExpression(ElementDefinition ed, StringBuilder expression, String discriminator, CodeableConcept cc) throws DefinitionException { if (cc.hasText()) - throw new DefinitionException(context.formatMessage(I18nConstants.UNSUPPORTED_CODEABLECONCEPT_PATTERN__USING_TEXT__FOR_DISCRIMINATOR_FOR_SLICE_, discriminator, ed.getId())); + throw new DefinitionException(formatMessage(I18nConstants.UNSUPPORTED_CODEABLECONCEPT_PATTERN__USING_TEXT__FOR_DISCRIMINATOR_FOR_SLICE_, discriminator, ed.getId())); if (!cc.hasCoding()) - throw new DefinitionException(context.formatMessage(I18nConstants.UNSUPPORTED_CODEABLECONCEPT_PATTERN__MUST_HAVE_AT_LEAST_ONE_CODING__FOR_DISCRIMINATOR_FOR_SLICE_, discriminator, ed.getId())); + throw new DefinitionException(formatMessage(I18nConstants.UNSUPPORTED_CODEABLECONCEPT_PATTERN__MUST_HAVE_AT_LEAST_ONE_CODING__FOR_DISCRIMINATOR_FOR_SLICE_, discriminator, ed.getId())); if (cc.hasExtension()) - throw new DefinitionException(context.formatMessage(I18nConstants.UNSUPPORTED_CODEABLECONCEPT_PATTERN__EXTENSIONS_ARE_NOT_ALLOWED__FOR_DISCRIMINATOR_FOR_SLICE_, discriminator, ed.getId())); + throw new DefinitionException(formatMessage(I18nConstants.UNSUPPORTED_CODEABLECONCEPT_PATTERN__EXTENSIONS_ARE_NOT_ALLOWED__FOR_DISCRIMINATOR_FOR_SLICE_, discriminator, ed.getId())); boolean firstCoding = true; for (Coding c : cc.getCoding()) { if (c.hasExtension()) - throw new DefinitionException(context.formatMessage(I18nConstants.UNSUPPORTED_CODEABLECONCEPT_PATTERN__EXTENSIONS_ARE_NOT_ALLOWED__FOR_DISCRIMINATOR_FOR_SLICE_, discriminator, ed.getId())); + throw new DefinitionException(formatMessage(I18nConstants.UNSUPPORTED_CODEABLECONCEPT_PATTERN__EXTENSIONS_ARE_NOT_ALLOWED__FOR_DISCRIMINATOR_FOR_SLICE_, discriminator, ed.getId())); if (firstCoding) firstCoding = false; else expression.append(" and "); expression.append(discriminator + ".coding.where("); @@ -3270,7 +3265,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat private void buildCodingExpression(ElementDefinition ed, StringBuilder expression, String discriminator, Coding c) throws DefinitionException { if (c.hasExtension()) - throw new DefinitionException(context.formatMessage(I18nConstants.UNSUPPORTED_CODEABLECONCEPT_PATTERN__EXTENSIONS_ARE_NOT_ALLOWED__FOR_DISCRIMINATOR_FOR_SLICE_, discriminator, ed.getId())); + throw new DefinitionException(formatMessage(I18nConstants.UNSUPPORTED_CODEABLECONCEPT_PATTERN__EXTENSIONS_ARE_NOT_ALLOWED__FOR_DISCRIMINATOR_FOR_SLICE_, discriminator, ed.getId())); expression.append(discriminator + ".where("); boolean first = true; if (c.hasSystem()) { @@ -3326,7 +3321,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } else if (fixed instanceof BooleanType) { expression.append(((BooleanType) fixed).asStringValue()); } else - throw new DefinitionException(context.formatMessage(I18nConstants.UNSUPPORTED_FIXED_VALUE_TYPE_FOR_DISCRIMINATOR_FOR_SLICE__, discriminator, ed.getId(), fixed.getClass().getName())); + throw new DefinitionException(formatMessage(I18nConstants.UNSUPPORTED_FIXED_VALUE_TYPE_FOR_DISCRIMINATOR_FOR_SLICE__, discriminator, ed.getId(), fixed.getClass().getName())); expression.append(" in " + discriminator + ")"); } } @@ -3340,7 +3335,6 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } startInner(hostContext, errors, resource, element, defn, stack, hostContext.isCheckSpecials()); - List res = new ArrayList<>(); Element meta = element.getNamedChild("meta"); if (meta != null) { List profiles = new ArrayList(); @@ -3688,7 +3682,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat byte[] json = bs.toByteArray(); switch (v) { case DSTU1: - throw new FHIRException(context.formatMessage(I18nConstants.UNSUPPORTED_VERSION_R1)); + throw new FHIRException(formatMessage(I18nConstants.UNSUPPORTED_VERSION_R1)); case DSTU2: org.hl7.fhir.dstu2.model.Resource r2 = new org.hl7.fhir.dstu2.formats.JsonParser().parse(json); Resource r5 = VersionConvertor_10_50.convertResource(r2); @@ -4630,7 +4624,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat else dt = this.context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/" + actualType); if (dt == null) - throw new DefinitionException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_ACTUAL_TYPE_, actualType)); + throw new DefinitionException(formatMessage(I18nConstants.UNABLE_TO_RESOLVE_ACTUAL_TYPE_, actualType)); trackUsage(dt, hostContext, element); childDefinitions = profileUtilities.getChildMap(dt, dt.getSnapshot().getElement().get(0)); @@ -4988,7 +4982,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat String errorContext = "profile " + profile.getUrl(); if (!resource.getChildValue("id").isEmpty()) errorContext += "; instance " + resource.getChildValue("id"); - throw new DefinitionException(context.formatMessage(I18nConstants.SLICE_ENCOUNTERED_MIDWAY_THROUGH_SET_PATH___ID___, slicer.getPath(), slicer.getId(), errorContext)); + throw new DefinitionException(formatMessage(I18nConstants.SLICE_ENCOUNTERED_MIDWAY_THROUGH_SET_PATH___ID___, slicer.getPath(), slicer.getId(), errorContext)); } slicer = ed; process = false; @@ -5013,12 +5007,10 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (ei.additionalSlice && ei.definition != null) { if (ei.definition.getSlicing().getRules().equals(ElementDefinition.SlicingRules.OPEN) || ei.definition.getSlicing().getRules().equals(ElementDefinition.SlicingRules.OPENATEND) && true /* TODO: replace "true" with condition to check that this element is at "end" */) { - slicingHint(errors, IssueType.INFORMATIONAL, ei.line(), ei.col(), ei.getPath(), false, - context.formatMessage(I18nConstants.THIS_ELEMENT_DOES_NOT_MATCH_ANY_KNOWN_SLICE_, - profile == null ? "" : " defined in the profile " + profile.getUrl()), - context.formatMessage(I18nConstants.THIS_ELEMENT_DOES_NOT_MATCH_ANY_KNOWN_SLICE_, profile == null ? "" : I18nConstants.DEFINED_IN_THE_PROFILE + profile.getUrl()) + errorSummaryForSlicingAsHtml(ei.sliceInfo)); + slicingHint(errors, IssueType.INFORMATIONAL, ei.line(), ei.col(), ei.getPath(), false, "This element does not match any known slice" + (profile == null ? "" : " defined in the profile " + profile.getUrl()), + "This element does not match any known slice" + (profile == null ? "" : " defined in the profile " + profile.getUrl() + ": " + errorSummaryForSlicingAsHtml(ei.sliceInfo))); } else if (ei.definition.getSlicing().getRules().equals(ElementDefinition.SlicingRules.CLOSED)) { - rule(errors, IssueType.INVALID, ei.line(), ei.col(), ei.getPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_NOTSLICE, (profile == null ? "" : " defined in the profile " + profile.getUrl()), errorSummaryForSlicing(ei.sliceInfo)); + rule(errors, IssueType.INVALID, ei.line(), ei.col(), ei.getPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_NOTSLICE, (profile == null ? "" : " defined in the profile " + profile.getUrl() + " and slicing is CLOSED: " + errorSummaryForSlicing(ei.sliceInfo))); } } else { // Don't raise this if we're in an abstract profile, like Resource @@ -5114,7 +5106,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (tail.equals(t.getId())) return t; } - throw new DefinitionException(context.formatMessage(I18nConstants.UNABLE_TO_FIND_ELEMENT_WITH_ID_, tail)); + throw new DefinitionException(formatMessage(I18nConstants.UNABLE_TO_FIND_ELEMENT_WITH_ID_, tail)); } private IdStatus idStatusForEntry(Element ep, ElementInfo ei) { @@ -5201,7 +5193,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat try { n = fpe.parse(fixExpr(inv.getExpression())); } catch (FHIRLexerException e) { - throw new FHIRException(context.formatMessage(I18nConstants.PROBLEM_PROCESSING_EXPRESSION__IN_PROFILE__PATH__, inv.getExpression(), profile.getUrl(), path, e.getMessage())); + throw new FHIRException(formatMessage(I18nConstants.PROBLEM_PROCESSING_EXPRESSION__IN_PROFILE__PATH__, inv.getExpression(), profile.getUrl(), path, e.getMessage())); } fpeTime = fpeTime + (System.nanoTime() - t); inv.setUserData("validator.expression.cache", n); @@ -5340,9 +5332,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat checkFixedValue(msgs, "{virtual}", value, criteria.getFixed(), profile.getUrl(), "value", null); return msgs.size() == 0; } else if (criteria.hasBinding() && criteria.getBinding().getStrength() == BindingStrength.REQUIRED && criteria.getBinding().hasValueSet()) { - throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_SLICE_MATCHING__SLICE_MATCHING_BY_VALUE_SET_NOT_DONE)); + throw new FHIRException(formatMessage(I18nConstants.UNABLE_TO_RESOLVE_SLICE_MATCHING__SLICE_MATCHING_BY_VALUE_SET_NOT_DONE)); } else { - throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_SLICE_MATCHING__NO_FIXED_VALUE_OR_REQUIRED_VALUE_SET)); + throw new FHIRException(formatMessage(I18nConstants.UNABLE_TO_RESOLVE_SLICE_MATCHING__NO_FIXED_VALUE_OR_REQUIRED_VALUE_SET)); } } @@ -5601,4 +5593,6 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat public void setDebug(boolean debug) { this.debug = debug; } + + } diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/I18nConstants.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/utils/I18nConstants.java similarity index 58% rename from org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/I18nConstants.java rename to org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/utils/I18nConstants.java index 62810d399..2a30f494c 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/I18nConstants.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/utils/I18nConstants.java @@ -1,7 +1,4 @@ -package org.hl7.fhir.utilities; - -import java.text.MessageFormat; -import java.util.ResourceBundle; +package org.hl7.fhir.validation.utils; public class I18nConstants { @@ -271,163 +268,5 @@ public class I18nConstants { public final static String NOT_DONE_YET_VALIDATORHOSTSERVICESEXECUTEFUNCTION = "Not_done_yet_ValidatorHostServicesexecuteFunction"; public final static String NOT_DONE_YET_VALIDATORHOSTSERVICESCHECKFUNCTION = "Not_done_yet_ValidatorHostServicescheckFunction"; public final static String NOT_DONE_YET_VALIDATORHOSTSERVICESRESOLVEFUNCTION_ = "Not_done_yet_ValidatorHostServicesresolveFunction_"; - public final static String UNABLE_TO_FIND_BASE_DEFINITION_FOR_LOGICAL_MODEL__FROM_ = "Unable_to_find_base_definition_for_logical_model__from_"; - public final static String SAME_ID_ON_MULTIPLE_ELEMENTS__IN_ = "Same_id_on_multiple_elements__in_"; - public final static String NO_PATH_ON_ELEMENT_DEFINITION__IN_ = "No_path_on_element_Definition__in_"; - public final static String NEEDS_A_SNAPSHOT = "needs_a_snapshot"; - public final static String NOT_THE_RIGHT_KIND_OF_STRUCTURE_TO_GENERATE_SCHEMATRONS_FOR = "not_the_right_kind_of_structure_to_generate_schematrons_for"; - public final static String NOT_HANDLED_YET_SORTELEMENTS_ = "Not_handled_yet_sortElements_"; - public final static String UNABLE_TO_RESOLVE_PROFILE__IN_ELEMENT_ = "Unable_to_resolve_profile__in_element_"; - public final static String CANT_HAVE_CHILDREN_ON_AN_ELEMENT_WITH_A_POLYMORPHIC_TYPE__YOU_MUST_SLICE_AND_CONSTRAIN_THE_TYPES_FIRST_SORTELEMENTS_ = "Cant_have_children_on_an_element_with_a_polymorphic_type__you_must_slice_and_constrain_the_types_first_sortElements_"; - public final static String UNABLE_TO_FIND_PROFILE__AT_ = "Unable_to_find_profile__at_"; - public final static String UNHANDLED_SITUATION_RESOURCE_IS_PROFILED_TO_MORE_THAN_ONE_OPTION__CANNOT_SORT_PROFILE = "Unhandled_situation_resource_is_profiled_to_more_than_one_option__cannot_sort_profile"; - public final static String INTERNAL_RECURSION_DETECTION_FIND_LOOP_PATH_RECURSION____CHECK_PATHS_ARE_VALID_FOR_PATH_ = "Internal_recursion_detection_find_loop_path_recursion____check_paths_are_valid_for_path_"; - public final static String INTERNAL_ERROR___TYPE_NOT_KNOWN_ = "Internal_error___type_not_known_"; - public final static String UNABLE_TO_FIND_ELEMENT_ = "Unable_to_find_element_"; - public final static String ERROR_GENERATING_TABLE_FOR_PROFILE__ = "Error_generating_table_for_profile__"; - public final static String STRUCTUREDEFINITION__AT__ILLEGAL_CONSTRAINED_TYPE__FROM__IN_ = "StructureDefinition__at__illegal_constrained_type__from__in_"; - public final static String ERROR_AT__THE_TARGET_PROFILE__IS_NOT__VALID_CONSTRAINT_ON_THE_BASE_ = "Error_at__The_target_profile__is_not__valid_constraint_on_the_base_"; - public final static String ERROR_IN_PROFILE__AT__BASE_ISSUMMARY___DERIVED_ISSUMMARY__ = "Error_in_profile__at__Base_isSummary___derived_isSummary__"; - public final static String UNEXPECTED_CONDITION_IN_DIFFERENTIAL_TYPESLICETYPELISTSIZE__1_AT_ = "Unexpected_condition_in_differential_typeslicetypelistsize__1_at_"; - public final static String UNEXPECTED_CONDITION_IN_DIFFERENTIAL_TYPESLICETYPELISTSIZE__10_AND_IMPLICIT_SLICE_NAME_DOES_NOT_CONTAIN_A_VALID_TYPE__AT_ = "Unexpected_condition_in_differential_typeslicetypelistsize__10_and_implicit_slice_name_does_not_contain_a_valid_type__at_"; - public final static String ATTEMPT_TO_USE_A_SNAPSHOT_ON_PROFILE__AS__BEFORE_IT_IS_GENERATED = "Attempt_to_use_a_snapshot_on_profile__as__before_it_is_generated"; - public final static String NULL_MIN = "null_min"; - public final static String _HAS_CHILDREN__FOR_TYPE__IN_PROFILE__BUT_CANT_FIND_TYPE = "_has_children__for_type__in_profile__but_cant_find_type"; - public final static String _HAS_CHILDREN__AND_MULTIPLE_TYPES__IN_PROFILE_ = "_has_children__and_multiple_types__in_profile_"; - public final static String ADDING_WRONG_PATH = "Adding_wrong_path"; - public final static String NAMED_ITEMS_ARE_OUT_OF_ORDER_IN_THE_SLICE = "Named_items_are_out_of_order_in_the_slice"; - public final static String THE_BASE_SNAPSHOT_MARKS_A_SLICING_AS_CLOSED_BUT_THE_DIFFERENTIAL_TRIES_TO_EXTEND_IT_IN__AT__ = "The_base_snapshot_marks_a_slicing_as_closed_but_the_differential_tries_to_extend_it_in__at__"; - public final static String NOT_DONE_YET = "Not_done_yet"; - public final static String UNKNOWN_TYPE__AT_ = "Unknown_type__at_"; - public final static String DIFFERENTIAL_WALKS_INTO____BUT_THE_BASE_DOES_NOT_AND_THERE_IS_NOT_A_SINGLE_FIXED_TYPE_THE_TYPE_IS__THIS_IS_NOT_HANDLED_YET = "Differential_walks_into____but_the_base_does_not_and_there_is_not_a_single_fixed_type_The_type_is__This_is_not_handled_yet"; - public final static String SLICING_RULES_ON_DIFFERENTIAL__DO_NOT_MATCH_THOSE_ON_BASE___RULE___ = "Slicing_rules_on_differential__do_not_match_those_on_base___rule___"; - public final static String SLICING_RULES_ON_DIFFERENTIAL__DO_NOT_MATCH_THOSE_ON_BASE___DISCIMINATOR___ = "Slicing_rules_on_differential__do_not_match_those_on_base___disciminator___"; - public final static String SLICING_RULES_ON_DIFFERENTIAL__DO_NOT_MATCH_THOSE_ON_BASE___ORDER___ = "Slicing_rules_on_differential__do_not_match_those_on_base___order___"; - public final static String INVALID_SLICING__THERE_IS_MORE_THAN_ONE_TYPE_SLICE_AT__BUT_ONE_OF_THEM__HAS_MIN__1_SO_THE_OTHER_SLICES_CANNOT_EXIST = "Invalid_slicing__there_is_more_than_one_type_slice_at__but_one_of_them__has_min__1_so_the_other_slices_cannot_exist"; - public final static String DID_NOT_FIND_TYPE_ROOT_ = "Did_not_find_type_root_"; - public final static String ERROR_AT_PATH__SLICE_FOR_TYPE__HAS_WRONG_TYPE_ = "Error_at_path__Slice_for_type__has_wrong_type_"; - public final static String ERROR_AT_PATH__SLICE_FOR_TYPE__HAS_MORE_THAN_ONE_TYPE_ = "Error_at_path__Slice_for_type__has_more_than_one_type_"; - public final static String ERROR_AT_PATH__SLICE_NAME_MUST_BE__BUT_IS_ = "Error_at_path__Slice_name_must_be__but_is_"; - public final static String ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGDISCRIMINATORPATH__THIS = "Error_at_path__in__Type_slicing_with_slicingdiscriminatorpath__this"; - public final static String ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGDISCRIMINATORTYPE__TYPE = "Error_at_path__in__Type_slicing_with_slicingdiscriminatortype__type"; - public final static String ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGDISCRIMINATORCOUNT__1 = "Error_at_path__in__Type_slicing_with_slicingdiscriminatorcount__1"; - public final static String ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGORDERED__TRUE = "Error_at_path__in__Type_slicing_with_slicingordered__true"; - public final static String ADDING_WRONG_PATH_IN_PROFILE___VS_ = "Adding_wrong_path_in_profile___vs_"; - public final static String _HAS_NO_CHILDREN__AND_NO_TYPES_IN_PROFILE_ = "_has_no_children__and_no_types_in_profile_"; - public final static String DID_NOT_FIND_SINGLE_SLICE_ = "Did_not_find_single_slice_"; - public final static String DIFFERENTIAL_DOES_NOT_HAVE_A_SLICE__B_OF_____IN_PROFILE_ = "Differential_does_not_have_a_slice__b_of_____in_profile_"; - public final static String ATTEMPT_TO_A_SLICE_AN_ELEMENT_THAT_DOES_NOT_REPEAT__FROM__IN_ = "Attempt_to_a_slice_an_element_that_does_not_repeat__from__in_"; - public final static String UNABLE_TO_RESOLVE_REFERENCE_TO_ = "Unable_to_resolve_reference_to_"; - public final static String UNABLE_TO_FIND_ELEMENT__IN_ = "Unable_to_find_element__in_"; - public final static String UNABLE_TO_FIND_BASE__FOR_ = "Unable_to_find_base__for_"; - public final static String ADDING_WRONG_PATH__OUTCOMEGETPATH___RESULTPATHBASE__ = "Adding_wrong_path__outcomegetPath___resultPathBase__"; - public final static String ILLEGAL_PATH__IN_DIFFERENTIAL_IN__ILLEGAL_CHARACTERS_ = "Illegal_path__in_differential_in__illegal_characters_"; - public final static String ILLEGAL_PATH__IN_DIFFERENTIAL_IN__ILLEGAL_CHARACTER_ = "Illegal_path__in_differential_in__illegal_character_"; - public final static String ILLEGAL_PATH__IN_DIFFERENTIAL_IN__NO_UNICODE_WHITESPACE = "Illegal_path__in_differential_in__no_unicode_whitespace"; - public final static String ILLEGAL_PATH__IN_DIFFERENTIAL_IN__NAME_PORTION_EXCEEDS_64_CHARS_IN_LENGTH = "Illegal_path__in_differential_in__name_portion_exceeds_64_chars_in_length"; - public final static String ILLEGAL_PATH__IN_DIFFERENTIAL_IN__NAME_PORTION_MISING_ = "Illegal_path__in_differential_in__name_portion_mising_"; - public final static String ILLEGAL_PATH__IN_DIFFERENTIAL_IN__MUST_START_WITH_ = "Illegal_path__in_differential_in__must_start_with_"; - public final static String NO_PATH_VALUE_ON_ELEMENT_IN_DIFFERENTIAL_IN_ = "No_path_value_on_element_in_differential_in_"; - public final static String NO_PATH_ON_ELEMENT_IN_DIFFERENTIAL_IN_ = "No_path_on_element_in_differential_in_"; - public final static String UNXPECTED_INTERNAL_CONDITION__NO_SOURCE_ON_DIFF_ELEMENT = "Unxpected_internal_condition__no_source_on_diff_element"; - public final static String TYPE_ON_FIRST_SNAPSHOT_ELEMENT_FOR__IN__FROM_ = "type_on_first_snapshot_element_for__in__from_"; - public final static String TYPE_ON_FIRST_DIFFERENTIAL_ELEMENT = "type_on_first_differential_element"; - public final static String CIRCULAR_SNAPSHOT_REFERENCES_DETECTED_CANNOT_GENERATE_SNAPSHOT_STACK__ = "Circular_snapshot_references_detected_cannot_generate_snapshot_stack__"; - public final static String BASE__DERIVED_PROFILES_HAVE_DIFFERENT_TYPES____VS___ = "Base__Derived_profiles_have_different_types____vs___"; - public final static String DERIVED_PROFILE__HAS_NO_DERIVATION_VALUE_AND_SO_CANT_BE_PROCESSED = "Derived_profile__has_no_derivation_value_and_so_cant_be_processed"; - public final static String DERIVED_PROFILE__HAS_NO_TYPE = "Derived_profile__has_no_type"; - public final static String BASE_PROFILE__HAS_NO_TYPE = "Base_profile__has_no_type"; - public final static String NO_DERIVED_STRUCTURE_PROVIDED = "no_derived_structure_provided"; - public final static String NO_BASE_PROFILE_PROVIDED = "no_base_profile_provided"; - public final static String ELEMENT_ID__NULL__ON_ = "element_id__null__on_"; - public final static String ELEMENT__NULL_ = "element__null_"; - public final static String GETSLICELIST_SHOULD_ONLY_BE_CALLED_WHEN_THE_ELEMENT_HAS_SLICING = "getSliceList_should_only_be_called_when_the_element_has_slicing"; - public final static String UNABLE_TO_RESOLVE_NAME_REFERENCE__AT_PATH_ = "Unable_to_resolve_name_reference__at_path_"; - public final static String DETAILS_FOR__MATCHING_AGAINST_PROFILE_ = "Details_for__matching_against_Profile_"; - public final static String DOES_NOT_MATCH_SLICE_ = "Does_not_match_slice_"; - public final static String PROFILE__DOES_NOT_MATCH_FOR__BECAUSE_OF_THE_FOLLOWING_PROFILE_ISSUES__ = "Profile__does_not_match_for__because_of_the_following_profile_issues__"; - public final static String THIS_ELEMENT_DOES_NOT_MATCH_ANY_KNOWN_SLICE_ = "This_element_does_not_match_any_known_slice_"; - public final static String DEFINED_IN_THE_PROFILE = "defined_in_the_profile"; - public final static String THIS_DOES_NOT_APPEAR_TO_BE_A_FHIR_RESOURCE_UNKNOWN_NAME_ = "This_does_not_appear_to_be_a_FHIR_resource_unknown_name_"; - public final static String THIS_CANNOT_BE_PARSED_AS_A_FHIR_OBJECT_NO_NAME = "This_cannot_be_parsed_as_a_FHIR_object_no_name"; - public final static String THIS_DOES_NOT_APPEAR_TO_BE_A_FHIR_RESOURCE_UNKNOWN_NAMESPACENAME_ = "This_does_not_appear_to_be_a_FHIR_resource_unknown_namespacename_"; - public final static String THIS__CANNOT_BE_PARSED_AS_A_FHIR_OBJECT_NO_NAMESPACE = "This__cannot_be_parsed_as_a_FHIR_object_no_namespace"; - public final static String UNABLE_TO_FIND_RESOURCETYPE_PROPERTY = "Unable_to_find_resourceType_property"; - public final static String ERROR_PARSING_JSON_THE_PRIMITIVE_VALUE_MUST_BE_A_STRING = "Error_parsing_JSON_the_primitive_value_must_be_a_string"; - public final static String ERROR_PARSING_JSON_THE_PRIMITIVE_VALUE_MUST_BE_A_NUMBER = "Error_parsing_JSON_the_primitive_value_must_be_a_number"; - public final static String ERROR_PARSING_JSON_THE_PRIMITIVE_VALUE_MUST_BE_A_BOOLEAN = "Error_parsing_JSON_the_primitive_value_must_be_a_boolean"; - public final static String ERROR_PARSING_XHTML_ = "Error_parsing_XHTML_"; - public final static String THIS_PROPERTY_MUST_BE_AN_OBJECT_NOT_ = "This_property_must_be_an_object_not_"; - public final static String THIS_PROPERTY_MUST_BE_AN_SIMPLE_VALUE_NOT_ = "This_property_must_be_an_simple_value_not_"; - public final static String THIS_PROPERTY_MUST_BE__NOT_ = "This_property_must_be__not_"; - public final static String THIS_PROPERTY_MUST_BE_AN_ARRAY_NOT_ = "This_property_must_be_an_Array_not_"; - public final static String UNRECOGNISED_PROPERTY_ = "Unrecognised_property_"; - public final static String OBJECT_MUST_HAVE_SOME_CONTENT = "Object_must_have_some_content"; - public final static String ERROR_PARSING_JSON_ = "Error_parsing_JSON_"; - public final static String NODE_TYPE__IS_NOT_ALLOWED = "Node_type__is_not_allowed"; - public final static String CDATA_IS_NOT_ALLOWED = "CDATA_is_not_allowed"; - public final static String UNDEFINED_ELEMENT_ = "Undefined_element_"; - public final static String UNDEFINED_ATTRIBUTE__ON__FOR_TYPE__PROPERTIES__ = "Undefined_attribute__on__for_type__properties__"; - public final static String TEXT_SHOULD_NOT_BE_PRESENT = "Text_should_not_be_present"; - public final static String WRONG_NAMESPACE__EXPECTED_ = "Wrong_namespace__expected_"; - public final static String ELEMENT_MUST_HAVE_SOME_CONTENT = "Element_must_have_some_content"; - public final static String NO_PROCESSING_INSTRUCTIONS_ALLOWED_IN_RESOURCES = "No_processing_instructions_allowed_in_resources"; - public final static String UNKNOWN_RESOURCE_TYPE_MISSING_RDFSTYPE = "Unknown_resource_type_missing_rdfstype"; - public final static String REFERENCE_TO__CANNOT_BE_RESOLVED = "reference_to__cannot_be_resolved"; - public final static String THIS_PROPERTY_MUST_BE_A_URI_OR_BNODE_NOT_A_ = "This_property_must_be_a_URI_or_bnode_not_a_"; - public final static String THIS_PROPERTY_MUST_BE_A_LITERAL_NOT_A_ = "This_property_must_be_a_Literal_not_a_"; - public final static String UNRECOGNISED_PREDICATE_ = "Unrecognised_predicate_"; - public final static String ERROR_PARSING_TURTLE_ = "Error_parsing_Turtle_"; - public final static String UNEXPECTED_DATATYPE_FOR_RDFSTYPE = "Unexpected_datatype_for_rdfstype"; - public final static String ATTEMPT_TO_REPLACE_ELEMENT_NAME_FOR_A_NONCHOICE_TYPE = "Attempt_to_replace_element_name_for_a_nonchoice_type"; - public final static String WRONG_TYPE_FOR_RESOURCE = "Wrong_type_for_resource"; - public final static String CONTAINED_RESOURCE_DOES_NOT_APPEAR_TO_BE_A_FHIR_RESOURCE_UNKNOWN_NAME_ = "Contained_resource_does_not_appear_to_be_a_FHIR_resource_unknown_name_"; - public final static String UNKNOWN_DATE_FORMAT_ = "Unknown_Date_format_"; - public final static String UNKNOWN_DATA_FORMAT_ = "Unknown_Data_format_"; - public final static String NO_TYPE_FOUND_ON_ = "No_type_found_on_"; - public final static String ERROR_WRITING_NUMBER__TO_JSON = "error_writing_number__to_JSON"; - public final static String UNABLE_TO_PROCESS_REQUEST_FOR_RESOURCE_FOR___ = "Unable_to_process_request_for_resource_for___"; - public final static String RESOURCE_TYPE_MISMATCH_FOR___ = "Resource_type_mismatch_for___"; - public final static String NOT_DONE_YET_CANT_FETCH_ = "not_done_yet_cant_fetch_"; - public final static String ATTEMPT_TO_USE_TERMINOLOGY_SERVER_WHEN_NO_TERMINOLOGY_SERVER_IS_AVAILABLE = "Attempt_to_use_Terminology_server_when_no_Terminology_server_is_available"; - public final static String NO_EXPANSIONPROFILE_PROVIDED = "No_ExpansionProfile_provided"; - public final static String CAN_ONLY_SPECIFY_PROFILE_IN_THE_CONTEXT = "Can_only_specify_profile_in_the_context"; - public final static String NO_URL_IN_EXPAND_VALUE_SET_2 = "no_url_in_expand_value_set_2"; - public final static String NO_URL_IN_EXPAND_VALUE_SET = "no_url_in_expand_value_set"; - public final static String NO_VALUE_SET = "no_value_set"; - public final static String NO_PARAMETERS_PROVIDED_TO_EXPANDVS = "No_Parameters_provided_to_expandVS"; - public final static String NO_EXPANSION_PARAMETERS_PROVIDED = "No_Expansion_Parameters_provided"; - public final static String UNABLE_TO_RESOLVE_VALUE_SET_ = "Unable_to_resolve_value_Set_"; - public final static String DELIMITED_VERSIONS_HAVE_EXACT_MATCH_FOR_DELIMITER____VS_ = "Delimited_versions_have_exact_match_for_delimiter____vs_"; - public final static String DUPLICATE_RESOURCE_ = "Duplicate_Resource_"; - public final static String ERROR_EXPANDING_VALUESET_RUNNING_WITHOUT_TERMINOLOGY_SERVICES = "Error_expanding_ValueSet_running_without_terminology_services"; - public final static String ERROR_VALIDATING_CODE_RUNNING_WITHOUT_TERMINOLOGY_SERVICES = "Error_validating_code_running_without_terminology_services"; - public final static String UNABLE_TO_VALIDATE_CODE_WITHOUT_USING_SERVER = "Unable_to_validate_code_without_using_server"; - public final static String PROFILE___ERROR_GENERATING_SNAPSHOT = "Profile___Error_generating_snapshot"; - public final static String PROFILE___ELEMENT__ERROR_GENERATING_SNAPSHOT_ = "Profile___element__Error_generating_snapshot_"; - public final static String PROFILE___BASE__COULD_NOT_BE_RESOLVED = "Profile___base__could_not_be_resolved"; - public final static String PROFILE___HAS_NO_BASE_AND_NO_SNAPSHOT = "Profile___has_no_base_and_no_snapshot"; - public final static String NO_VALIDATOR_CONFIGURED = "No_validator_configured"; - public final static String PARSER_TYPE__NOT_SUPPORTED = "Parser_Type__not_supported"; - public final static String VERSION_MISMATCH_THE_CONTEXT_HAS_VERSION__LOADED_AND_THE_NEW_CONTENT_BEING_LOADED_IS_VERSION_ = "Version_mismatch_The_context_has_version__loaded_and_the_new_content_being_loaded_is_version_"; - public final static String ERROR_READING__FROM_PACKAGE__ = "Error_reading__from_package__"; - public final static String ERROR_PARSING_ = "Error_parsing_"; - public final static String UNABLE_TO_CONNECT_TO_TERMINOLOGY_SERVER_USE_PARAMETER_TX_NA_TUN_RUN_WITHOUT_USING_TERMINOLOGY_SERVICES_TO_VALIDATE_LOINC_SNOMED_ICDX_ETC_ERROR__ = "Unable_to_connect_to_terminology_server_Use_parameter_tx_na_tun_run_without_using_terminology_services_to_validate_LOINC_SNOMED_ICDX_etc_Error__"; - public final static String DISPLAY_NAME_FOR__SHOULD_BE_ONE_OF__INSTEAD_OF_ = "Display_Name_for__should_be_one_of__instead_of_"; - public final static String UNKNOWN_CODE__IN_ = "Unknown_Code__in_"; - public final static String CODE_FOUND_IN_EXPANSION_HOWEVER_ = "Code_found_in_expansion_however_"; - public final static String NONE_OF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_ = "None_of_the_provided_codes_are_in_the_value_set_"; - public final static String CODING_HAS_NO_SYSTEM__CANNOT_VALIDATE = "Coding_has_no_system__cannot_validate"; - public final static String UNABLE_TO_HANDLE_SYSTEM__CONCEPT_FILTER_WITH_OP__ = "Unable_to_handle_system__concept_filter_with_op__"; - public final static String UNABLE_TO_HANDLE_SYSTEM__FILTER_WITH_PROPERTY__ = "Unable_to_handle_system__filter_with_property__"; - public final static String UNABLE_TO_RESOLVE_SYSTEM__VALUE_SET_HAS_INCLUDE_WITH_NO_SYSTEM = "Unable_to_resolve_system__value_set_has_include_with_no_system"; - public final static String UNABLE_TO_RESOLVE_SYSTEM__VALUE_SET_HAS_IMPORTS = "Unable_to_resolve_system__value_set_has_imports"; - public final static String UNABLE_TO_RESOLVE_SYSTEM__VALUE_SET_EXPANSION_HAS_MULTIPLE_SYSTEMS = "Unable_to_resolve_system__value_set_expansion_has_multiple_systems"; - public final static String UNABLE_TO_RESOLVE_SYSTEM__VALUE_SET_HAS_NO_INCLUDES_OR_EXPANSION = "Unable_to_resolve_system__value_set_has_no_includes_or_expansion"; - public final static String UNABLE_TO_RESOLVE_SYSTEM__VALUE_SET_HAS_EXCLUDES = "Unable_to_resolve_system__value_set_has_excludes"; - public final static String UNABLE_TO_RESOLVE_SYSTEM__NO_VALUE_SET = "Unable_to_resolve_system__no_value_set"; - public final static String THIS_BASE_PROPERTY_MUST_BE_AN_ARRAY_NOT_A_ = "This_base_property_must_be_an_Array_not_a_"; - public final static String THIS_PROPERTY_MUST_BE_AN_ARRAY_NOT_A_ = "This_property_must_be_an_Array_not_a_"; - public final static String DOCUMENT = "documentmsg"; } diff --git a/org.hl7.fhir.validation/src/main/resources/Messages.properties b/org.hl7.fhir.validation/src/main/resources/Messages.properties index 000d99036..5a4646466 100644 --- a/org.hl7.fhir.validation/src/main/resources/Messages.properties +++ b/org.hl7.fhir.validation/src/main/resources/Messages.properties @@ -212,7 +212,7 @@ Validation_VAL_Profile_NoMatch = Unable to find matching profile among choices: Validation_VAL_Profile_NoSnapshot = StructureDefinition has no snapshot - validation is against the snapshot, so it must be provided Validation_VAL_Profile_NoType = The type of element {0} is not known, which is illegal. Valid types at this point are {1} Validation_VAL_Profile_NotAllowed = This element is not allowed by the profile {0} -Validation_VAL_Profile_NotSlice = This element does not match any known slice {0} and slicing is CLOSED: {1} +Validation_VAL_Profile_NotSlice = This element does not match any known slice {0} Validation_VAL_Profile_OutOfOrder = As specified by profile {0}, Element "{1}" is out of order Validation_VAL_Profile_SliceOrder = As specified by profile {0}, Element "{1}" is out of order in ordered slice Validation_VAL_Profile_Unknown = Profile reference "{0}" could not be resolved, so has not been checked @@ -265,166 +265,3 @@ Not_done_yet__resolve__locally_2 = Not done yet - resolve {0} locally (2) Not_done_yet_ValidatorHostServicesexecuteFunction = Not done yet (ValidatorHostServices.executeFunction) Not_done_yet_ValidatorHostServicescheckFunction = Not done yet (ValidatorHostServices.checkFunction) Not_done_yet_ValidatorHostServicesresolveFunction_ = Not done yet (ValidatorHostServices.resolveFunction): {0} -Unable_to_find_base_definition_for_logical_model__from_ = Unable to find base definition for logical model: {0} from {1} -Same_id_on_multiple_elements__in_ = Same id ''{0}''on multiple elements {1}/{2} in {3} -No_path_on_element_Definition__in_ = No path on element Definition {0} in {1} -needs_a_snapshot = needs a snapshot -not_the_right_kind_of_structure_to_generate_schematrons_for = not the right kind of structure to generate schematrons for -Not_handled_yet_sortElements_ = Not handled yet (sortElements: {0}:{1}) -Unable_to_resolve_profile__in_element_ = Unable to resolve profile {0} in element {1} -Cant_have_children_on_an_element_with_a_polymorphic_type__you_must_slice_and_constrain_the_types_first_sortElements_ = Can''t have children on an element with a polymorphic type - you must slice and constrain the types first (sortElements: {0}:{1}) -Unable_to_find_profile__at_ = Unable to find profile ''{0}'' at {1} -Unhandled_situation_resource_is_profiled_to_more_than_one_option__cannot_sort_profile = Unhandled situation: resource is profiled to more than one option - cannot sort profile -Internal_recursion_detection_find_loop_path_recursion____check_paths_are_valid_for_path_ = Internal recursion detection: find() loop path recursion > {0} - check paths are valid (for path {1}/{2}) -Internal_error___type_not_known_ = Internal error - type not known {0} -Unable_to_find_element_ = Unable to find element {0} -Error_generating_table_for_profile__ = Error generating table for profile {0}: {1} -StructureDefinition__at__illegal_constrained_type__from__in_ = StructureDefinition {0} at {1}: illegal constrained type {2} from {3} in {4} -Error_at__The_target_profile__is_not__valid_constraint_on_the_base_ = Error at {0}#{1}: The target profile {2} is not valid constraint on the base ({3}) -Error_in_profile__at__Base_isSummary___derived_isSummary__ = Error in profile {0} at {1}: Base isSummary = {2}, derived isSummary = {3} -StructureDefinition__at__illegal_attempt_to_change_a_binding_from__to_ = StructureDefinition {0} at {1}: illegal attempt to change a binding from {2} to {3} -Unexpected_condition_in_differential_typeslicetypelistsize__1_at_ = Unexpected condition in differential: type-slice.type-list.size() != 1 at {0}/{1} -Unexpected_condition_in_differential_typeslicetypelistsize__10_and_implicit_slice_name_does_not_contain_a_valid_type__at_ = Unexpected condition in differential: type-slice.type-list.size() == 10 and implicit slice name does not contain a valid type (''{0}''?) at {1}/{2} -Attempt_to_use_a_snapshot_on_profile__as__before_it_is_generated = Attempt to use a snapshot on profile ''{0}'' as {1} before it is generated -null_min = null min -_has_children__for_type__in_profile__but_cant_find_type = {0} has children ({1}) for type {2} in profile {3}, but can''t find type -_has_children__and_multiple_types__in_profile_ = {0} has children ({1}) and multiple types ({2}) in profile {3} -Adding_wrong_path = Adding wrong path -Named_items_are_out_of_order_in_the_slice=Named items are out of order in the slice -The_base_snapshot_marks_a_slicing_as_closed_but_the_differential_tries_to_extend_it_in__at__ = The base snapshot marks a slicing as closed, but the differential tries to extend it in {0} at {1} ({2}) -Not_done_yet = Not done yet -Unknown_type__at_ = Unknown type {0} at {1} -Differential_walks_into____but_the_base_does_not_and_there_is_not_a_single_fixed_type_The_type_is__This_is_not_handled_yet = Differential walks into ''{0} (@ {1})'', but the base does not, and there is not a single fixed type. The type is {2}. This is not handled yet -Slicing_rules_on_differential__do_not_match_those_on_base___rule___ = Slicing rules on differential ({0}) do not match those on base ({1}) - rule @ {2} ({3}) -Slicing_rules_on_differential__do_not_match_those_on_base___disciminator___ = Slicing rules on differential ({0}) do not match those on base ({1}) - disciminator @ {2} ({3}) -Slicing_rules_on_differential__do_not_match_those_on_base___order___ = Slicing rules on differential ({0}) do not match those on base ({1}) - order @ {2} ({3}) -not_done_yet__slicing__types__ = not done yet - slicing / types @ {0} -Invalid_slicing__there_is_more_than_one_type_slice_at__but_one_of_them__has_min__1_so_the_other_slices_cannot_exist=Invalid slicing: there is more than one type slice at {0}, but one of them ({1}) has min = 1, so the other slices cannot exist -Did_not_find_type_root_ = Did not find type root: {0} -Error_at_path__Slice_for_type__has_wrong_type_ = Error at path {0}: Slice for type ''{1}'' has wrong type ''{2}'' -Error_at_path__Slice_for_type__has_more_than_one_type_ = Error at path {0}: Slice for type '{1}' has more than one type '{2}' -Error_at_path__Slice_name_must_be__but_is_ = Error at path {0}: Slice name must be ''{1}'' but is ''{2}'' -Error_at_path__in__Type_slicing_with_slicingdiscriminatorpath__this = Error at path {0} in {1}: Type slicing with slicing.discriminator.path != ''$this'' -Error_at_path__in__Type_slicing_with_slicingdiscriminatortype__type = Error at path {0} in {1}: Type slicing with slicing.discriminator.type != ''type'' -Error_at_path__in__Type_slicing_with_slicingdiscriminatorcount__1 = Error at path {0} in {1}: Type slicing with slicing.discriminator.count() > 1 -Error_at_path__in__Type_slicing_with_slicingordered__true = Error at path {0} in {1}: Type slicing with slicing.ordered = true -Adding_wrong_path_in_profile___vs_ = Adding wrong path in profile {0}: {1} vs {2} -_has_no_children__and_no_types_in_profile_ = {0} has no children ({1}) and no types in profile {2} -not_done_yet = not done yet -Did_not_find_single_slice_ = Did not find single slice: {0} -Differential_does_not_have_a_slice__b_of_____in_profile_ = Differential does not have a slice: {0}/ (b:{1} of {2} / {3}/ {4}) in profile {5} -Attempt_to_a_slice_an_element_that_does_not_repeat__from__in_ = Attempt to a slice an element that does not repeat: {0}/{1} from {2} in {3} -Unable_to_resolve_reference_to_ = Unable to resolve reference to {0} -Unable_to_find_element__in_ = Unable to find element {0} in {1} -Unable_to_find_base__for_ = Unable to find base {0} for {1} -Adding_wrong_path__outcomegetPath___resultPathBase__ = Adding wrong path - outcome.getPath() = {0}, resultPathBase = {1} -Illegal_path__in_differential_in__illegal_characters_ = Illegal path ''{0}'' in differential in {1}: illegal characters [] -Illegal_path__in_differential_in__illegal_character_ = Illegal path ''{0}'' in differential in {1}: illegal character ''{2}'' -Illegal_path__in_differential_in__no_unicode_whitespace = Illegal path ''{0}'' in differential in {1}: no unicode whitespace -Illegal_path__in_differential_in__name_portion_exceeds_64_chars_in_length = Illegal path ''{0}'' in differential in {1}: name portion exceeds 64 chars in length -Illegal_path__in_differential_in__name_portion_mising_ = Illegal path ''{0}'' in differential in {1}: name portion missing (''..'') -Illegal_path__in_differential_in__must_start_with_ = Illegal path ''{0}'' in differential in {1}: must start with {2}.{3} -No_path_value_on_element_in_differential_in_ = No path value on element in differential in {0} -No_path_on_element_in_differential_in_ = No path on element in differential in {0} -Unxpected_internal_condition__no_source_on_diff_element = Unxpected internal condition - no source on diff element -type_on_first_snapshot_element_for__in__from_ = type on first snapshot element for {0} in {1} from {2} -type_on_first_differential_element = type on first differential element! -Circular_snapshot_references_detected_cannot_generate_snapshot_stack__ = Circular snapshot references detected; cannot generate snapshot (stack = {0}) -Base__Derived_profiles_have_different_types____vs___ = Base & Derived profiles have different types ({0} = {1} vs {2} = {3}) -Derived_profile__has_no_derivation_value_and_so_cant_be_processed = Derived profile {0} has no derivation value and so can''t be processed -Derived_profile__has_no_type = Derived profile {0} has no type -Base_profile__has_no_type = Base profile {0} has no type -no_derived_structure_provided = no derived structure provided -no_base_profile_provided = no base profile provided -element_id__null__on_ = element id = null: {0} on {1} -element__null_ = element = null: {0} -getSliceList_should_only_be_called_when_the_element_has_slicing = getSliceList should only be called when the element has slicing -Unable_to_resolve_name_reference__at_path_ = Unable to resolve name reference {0} at path {1} -Details_for__matching_against_Profile_ = Details for {0} matching against Profile{1} -Does_not_match_slice_ = Does not match slice "{0}" -Profile__does_not_match_for__because_of_the_following_profile_issues__ = Profile {0} does not match for {1} because of the following profile issues: {2} -This_element_does_not_match_any_known_slice_ = This element does not match any known slice{0} -defined_in_the_profile = defined in the profile -This_does_not_appear_to_be_a_FHIR_resource_unknown_name_ = This does not appear to be a FHIR resource (unknown name "{0}") -This_cannot_be_parsed_as_a_FHIR_object_no_name = This cannot be parsed as a FHIR object (no name) -This_does_not_appear_to_be_a_FHIR_resource_unknown_namespacename_ = This does not appear to be a FHIR resource (unknown namespace/name "{0}::{1}") -This__cannot_be_parsed_as_a_FHIR_object_no_namespace = This "{0}2 cannot be parsed as a FHIR object (no namespace) -Unable_to_find_resourceType_property = Unable to find resourceType property -Error_parsing_JSON_the_primitive_value_must_be_a_string = Error parsing JSON: the primitive value must be a string -Error_parsing_JSON_the_primitive_value_must_be_a_number = Error parsing JSON: the primitive value must be a number -Error_parsing_JSON_the_primitive_value_must_be_a_boolean = Error parsing JSON: the primitive value must be a boolean -Error_parsing_XHTML_ = Error parsing XHTML: {0} -This_property_must_be_an_object_not_ = This property must be an object, not {0} -This_property_must_be_an_simple_value_not_ = This property must be an simple value, not {0} -This_property_must_be__not_ = This property must be {0}, not {1} -This_property_must_be_an_Array_not_ = This property must be an Array, not {0} -Unrecognised_property_ = Unrecognised property ''@{0}'' -Object_must_have_some_content = Object must have some content -Error_parsing_JSON_ = Error parsing JSON: {0} -Node_type__is_not_allowed = Node type {0} is not allowed -CDATA_is_not_allowed = CDATA is not allowed -Undefined_element_ = Undefined element ''{0}'' -Undefined_attribute__on__for_type__properties__ = Undefined attribute ''@{0}'' on {1} for type {2} (properties = {3}) -Text_should_not_be_present = Text should not be present -Wrong_namespace__expected_ = Wrong namespace - expected ''{0}'' -Element_must_have_some_content = Element must have some content -No_processing_instructions_allowed_in_resources = No processing instructions allowed in resources -Unknown_resource_type_missing_rdfstype = Unknown resource type (missing rdfs:type) -reference_to__cannot_be_resolved = reference to {0} cannot be resolved -This_property_must_be_a_URI_or_bnode_not_a_ = This property must be a URI or bnode, not a {0} -This_property_must_be_a_Literal_not_a_ = This property must be a Literal, not a {0} -Unrecognised_predicate_ = Unrecognised predicate ''{0}'' -Error_parsing_Turtle_ = Error parsing Turtle: {0} -Unexpected_datatype_for_rdfstype = Unexpected datatype for rdfs:type -Attempt_to_replace_element_name_for_a_nonchoice_type=Attempt to replace element name for a non-choice type -Wrong_type_for_resource = Wrong type for resource -Contained_resource_does_not_appear_to_be_a_FHIR_resource_unknown_name_ = Contained resource does not appear to be a FHIR resource (unknown name ''{0}'') -Unknown_Date_format_ = Unknown Date format ''{0}'' -Unknown_Data_format_ = Unknown Data format ''{0}'' -No_type_found_on_ = No type found on ''{0}'' -error_writing_number__to_JSON = error writing number ''{0}'' to JSON -Unable_to_process_request_for_resource_for___ = Unable to process request for resource for {0} / {1} -Resource_type_mismatch_for___ = Resource type mismatch for {0} / {1} -not_done_yet_cant_fetch_ = not done yet: can''t fetch {0} -Attempt_to_use_Terminology_server_when_no_Terminology_server_is_available = Attempt to use Terminology server when no Terminology server is available -No_ExpansionProfile_provided = No ExpansionProfile provided -Can_only_specify_profile_in_the_context = Can only specify profile in the context -no_url_in_expand_value_set_2 = no url in expand value set 2 -no_url_in_expand_value_set = no url in expand value set -no_value_set = no value set -No_Parameters_provided_to_expandVS = No Parameters provided to expandVS -No_Expansion_Parameters_provided = No Expansion Parameters provided -Unable_to_resolve_value_Set_ = Unable to resolve value Set {0} -Delimited_versions_have_exact_match_for_delimiter____vs_ = Delimited versions have exact match for delimiter ''{0}'' : {1} vs {2} -Duplicate_Resource_ = Duplicate Resource {0} -Error_expanding_ValueSet_running_without_terminology_services = Error expanding ValueSet: running without terminology services -Error_validating_code_running_without_terminology_services = Error validating code: running without terminology services -Unable_to_validate_code_without_using_server = Unable to validate code without using server -Profile___Error_generating_snapshot = Profile {0} ({1}). Error generating snapshot -Profile___element__Error_generating_snapshot_ = Profile {0} ({1}), element {2}. Error generating snapshot: {3} -Profile___base__could_not_be_resolved = Profile {0} ({1}) base {2} could not be resolved -Profile___has_no_base_and_no_snapshot = Profile {0} ({1}) has no base and no snapshot -No_validator_configured = No validator configured -Parser_Type__not_supported = Parser Type {0} not supported -Version_mismatch_The_context_has_version__loaded_and_the_new_content_being_loaded_is_version_ = Version mismatch. The context has version {0} loaded, and the new content being loaded is version {1} -Error_reading__from_package__ = Error reading {0} from package {1}#{2}: {3} -Error_parsing_ = Error parsing {0}:{1} -Unable_to_connect_to_terminology_server_Use_parameter_tx_na_tun_run_without_using_terminology_services_to_validate_LOINC_SNOMED_ICDX_etc_Error__ = Unable to connect to terminology server. Use parameter ''-tx n/a'' tun run without using terminology services to validate LOINC, SNOMED, ICD-X etc. Error = {0} -Display_Name_for__should_be_one_of__instead_of_ = Display Name for {0}#{1} should be one of ''{2}'' instead of ''{3}'' -Unknown_Code__in_ = Unknown Code {0} in {1} -Code_found_in_expansion_however_ = Code found in expansion, however: {0} -None_of_the_provided_codes_are_in_the_value_set_ = None of the provided codes are in the value set {0} -Coding_has_no_system__cannot_validate = Coding has no system - cannot validate -Unable_to_handle_system__concept_filter_with_op__ = Unable to handle system {0} concept filter with op = {1} -Unable_to_handle_system__filter_with_property__ = Unable to handle system {0} filter with property = {1} -Unable_to_resolve_system__value_set_has_include_with_no_system = Unable to resolve system - value set has include with no system -Unable_to_resolve_system__value_set_has_imports = Unable to resolve system - value set has imports -Unable_to_resolve_system__value_set_expansion_has_multiple_systems = Unable to resolve system - value set expansion has multiple systems -Unable_to_resolve_system__value_set_has_no_includes_or_expansion = Unable to resolve system - value set has no includes or expansion -Unable_to_resolve_system__value_set_has_excludes = Unable to resolve system - value set has excludes -Unable_to_resolve_system__no_value_set = Unable to resolve system - no value set -This_base_property_must_be_an_Array_not_a_ = This base property must be an Array, not a {0} -This_property_must_be_an_Array_not_a_ = This property must be an Array, not a {0} -documentmsg = (document) - -