From 54bcac00ed018b373858f6926d7139394f076eb1 Mon Sep 17 00:00:00 2001 From: patrick-werner Date: Thu, 5 Mar 2020 15:03:03 +0100 Subject: [PATCH] moved i18StringConstants class -> fhir.utilities Extracted error messages of ProfileUtilities --- .../fhir/r5/conformance/ProfileUtilities.java | 291 +++++++++--------- .../hl7/fhir/utilities}/I18nConstants.java | 90 +++++- .../hl7/fhir/validation/BaseValidator.java | 18 +- .../instance/InstanceValidator.java | 4 +- .../src/main/resources/Messages.properties | 75 +++++ 5 files changed, 328 insertions(+), 150 deletions(-) rename {org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/utils => org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities}/I18nConstants.java (72%) 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 a9135390a..2ee18d375 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. @@ -20,6 +20,10 @@ package org.hl7.fhir.r5.conformance; * #L% */ + + +import static org.hl7.fhir.utilities.I18nConstants.formatMessage; + import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; @@ -31,6 +35,7 @@ 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; @@ -95,6 +100,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; @@ -266,6 +272,7 @@ 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,6 +281,11 @@ public class ProfileUtilities extends TranslatingUtilities { this.pkp = pkp; } + public ProfileUtilities(IWorkerContext theContext, List messages, ProfileKnowledgeProvider pkp, ResourceBundle i18Nmessages) { + this(theContext, messages, pkp); + this.i18nMessages = i18Nmessages; + } + private class UnusedTracker { private boolean used; } @@ -298,19 +310,20 @@ public class ProfileUtilities extends TranslatingUtilities { } public interface ProfileKnowledgeProvider { - public class BindingResolution { + class BindingResolution { public String display; public String url; } - 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); + 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); } @@ -321,7 +334,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (element.getContentReference().equals("#"+e.getId())) return getChildMap(profile, e); } - throw new DefinitionException("Unable to resolve name reference "+element.getContentReference()+" at path "+element.getPath()); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.UNABLE_TO_RESOLVE_NAME_REFERENCE__AT_PATH_, element.getContentReference(), element.getPath())); } else { List res = new ArrayList(); @@ -343,7 +356,7 @@ public class ProfileUtilities extends TranslatingUtilities { public List getSliceList(StructureDefinition profile, ElementDefinition element) throws DefinitionException { if (!element.hasSlicing()) - throw new Error("getSliceList should only be called when the element has slicing"); + throw new Error(formatMessage(i18nMessages, I18nConstants.GETSLICELIST_SHOULD_ONLY_BE_CALLED_WHEN_THE_ELEMENT_HAS_SLICING)); List res = new ArrayList(); List elements = profile.getSnapshot().getElement(); @@ -382,9 +395,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("element = null: "+profile.getUrl()); + throw new Error(formatMessage(i18nMessages, I18nConstants.ELEMENT__NULL_, profile.getUrl())); if (e.getId() == null) - throw new Error("element id = null: "+e.toString()+" on "+profile.getUrl()); + throw new Error(formatMessage(i18nMessages, I18nConstants.ELEMENT_ID__NULL__ON_, e.toString(), profile.getUrl())); if (!capturing && id!=null && e.getId().equals(id)) { capturing = true; @@ -425,9 +438,9 @@ public class ProfileUtilities extends TranslatingUtilities { public void updateMaps(StructureDefinition base, StructureDefinition derived) throws DefinitionException { if (base == null) - throw new DefinitionException("no base profile provided"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.NO_BASE_PROFILE_PROVIDED)); if (derived == null) - throw new DefinitionException("no derived structure provided"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.NO_DERIVED_STRUCTURE_PROVIDED)); for (StructureDefinitionMappingComponent baseMap : base.getMapping()) { boolean found = false; @@ -458,30 +471,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("no base profile provided"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.NO_BASE_PROFILE_PROVIDED)); } if (derived == null) { - throw new DefinitionException("no derived structure provided"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.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("Base profile "+base.getUrl()+" has no type"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.BASE_PROFILE__HAS_NO_TYPE, base.getUrl())); } if (!derived.hasType()) { - throw new DefinitionException("Derived profile "+derived.getUrl()+" has no type"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.DERIVED_PROFILE__HAS_NO_TYPE, derived.getUrl())); } if (!derived.hasDerivation()) { - throw new DefinitionException("Derived profile "+derived.getUrl()+" has no derivation value and so can't be processed"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.DERIVED_PROFILE__HAS_NO_DERIVATION_VALUE_AND_SO_CANT_BE_PROCESSED, derived.getUrl())); } if (!base.getType().equals(derived.getType()) && derived.getDerivation() == TypeDerivationRule.CONSTRAINT) { - throw new DefinitionException("Base & Derived profiles have different types ("+base.getUrl()+" = "+base.getType()+" vs "+derived.getUrl()+" = "+derived.getType()+")"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.BASE__DERIVED_PROFILES_HAVE_DIFFERENT_TYPES____VS___, base.getUrl(), base.getType(), derived.getUrl(), derived.getType())); } if (snapshotStack.contains(derived.getUrl())) { - throw new DefinitionException("Circular snapshot references detected; cannot generate snapshot (stack = "+snapshotStack.toString()+")"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.CIRCULAR_SNAPSHOT_REFERENCES_DETECTED_CANNOT_GENERATE_SNAPSHOT_STACK__, snapshotStack.toString())); } snapshotStack.add(derived.getUrl()); @@ -505,7 +518,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("type on first differential element!"); + throw new Error(formatMessage(i18nMessages, I18nConstants.TYPE_ON_FIRST_DIFFERENTIAL_ELEMENT)); for (ElementDefinition e : derived.getDifferential().getElement()) e.clearUserData(GENERATED_IN_SNAPSHOT); @@ -536,7 +549,7 @@ public class ProfileUtilities extends TranslatingUtilities { } if (!derived.getSnapshot().getElementFirstRep().getType().isEmpty()) - throw new Error("type on first snapshot element for "+derived.getSnapshot().getElementFirstRep().getPath()+" in "+derived.getUrl()+" from "+base.getUrl()); + throw new Error(formatMessage(i18nMessages, I18nConstants.TYPE_ON_FIRST_SNAPSHOT_ELEMENT_FOR__IN__FROM_, derived.getSnapshot().getElementFirstRep().getPath(), derived.getUrl(), base.getUrl())); updateMaps(base, derived); if (debug) { @@ -553,7 +566,7 @@ public class ProfileUtilities extends TranslatingUtilities { int ce = 0; for (ElementDefinition e : diff.getElement()) { if (!e.hasUserData("diff-source")) - throw new Error("Unxpected internal condition - no source on diff element"); + throw new Error(formatMessage(i18nMessages, I18nConstants.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)); @@ -592,7 +605,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()) { @@ -632,14 +645,14 @@ public class ProfileUtilities extends TranslatingUtilities { boolean first = true; for (ElementDefinition ed : elements) { if (!ed.hasPath()) { - throw new FHIRException("No path on element in differential in "+url); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.NO_PATH_ON_ELEMENT_IN_DIFFERENTIAL_IN_, url)); } String p = ed.getPath(); if (p == null) { - throw new FHIRException("No path value on element in differential in "+url); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.NO_PATH_VALUE_ON_ELEMENT_IN_DIFFERENTIAL_IN_, url)); } if (!((first && type.equals(p)) || p.startsWith(type+"."))) { - throw new FHIRException("Illegal path '"+p+"' in differential in "+url+": must start with "+type+"."+(first ? " (o be '"+type+"')" : "")); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ILLEGAL_PATH__IN_DIFFERENTIAL_IN__MUST_START_WITH_, p, url, 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) @@ -649,25 +662,25 @@ public class ProfileUtilities extends TranslatingUtilities { String[] pl = p.split("\\."); for (String pp : pl) { if (pp.length() < 1) { - throw new FHIRException("Illegal path '"+p+"' in differential in "+url+": name portion mising ('..')"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ILLEGAL_PATH__IN_DIFFERENTIAL_IN__NAME_PORTION_MISING_, p, url)); } if (pp.length() > 64) { - throw new FHIRException("Illegal path '"+p+"' in differential in "+url+": name portion exceeds 64 chars in length"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ILLEGAL_PATH__IN_DIFFERENTIAL_IN__NAME_PORTION_EXCEEDS_64_CHARS_IN_LENGTH, p, url)); } for (char ch : pp.toCharArray()) { if (Character.isWhitespace(ch)) { - throw new FHIRException("Illegal path '"+p+"' in differential in "+url+": no unicode whitespace"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ILLEGAL_PATH__IN_DIFFERENTIAL_IN__NO_UNICODE_WHITESPACE, p, url)); } if (Utilities.existsInList(ch, ',', ':', ';', '\'', '"', '/', '|', '?', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '{', '}')) { - throw new FHIRException("Illegal path '"+p+"' in differential in "+url+": illegal character '"+ch+"'"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ILLEGAL_PATH__IN_DIFFERENTIAL_IN__ILLEGAL_CHARACTER_, p, url, ch)); } if (ch < ' ' || ch > 'z') { - throw new FHIRException("Illegal path '"+p+"' in differential in "+url+": illegal character '"+ch+"'"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ILLEGAL_PATH__IN_DIFFERENTIAL_IN__ILLEGAL_CHARACTER_, p, url, 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("Illegal path '"+p+"' in differential in "+url+": illegal characters []"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ILLEGAL_PATH__IN_DIFFERENTIAL_IN__ILLEGAL_CHARACTERS_, p, url)); } } } @@ -821,7 +834,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (resultPathBase == null) resultPathBase = outcome.getPath(); else if (!outcome.getPath().startsWith(resultPathBase)) - throw new DefinitionException("Adding wrong path - outcome.getPath() = "+outcome.getPath()+", resultPathBase = "+resultPathBase); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.ADDING_WRONG_PATH__OUTCOMEGETPATH___RESULTPATHBASE__, outcome.getPath(), 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 @@ -831,17 +844,17 @@ public class ProfileUtilities extends TranslatingUtilities { baseCursor = indexOfFirstNonChild(base, currentBase, baseCursor+1, baseLimit); } else { if (outcome.getType().size() == 0) { - throw new DefinitionException(diffMatches.get(0).getPath()+" has no children ("+differential.getElement().get(diffCursor).getPath()+") and no types in profile "+profileName); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants._HAS_NO_CHILDREN__AND_NO_TYPES_IN_PROFILE_, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), profileName)); } if (outcome.getType().size() > 1) { for (TypeRefComponent t : outcome.getType()) { if (!t.getWorkingCode().equals("Reference")) - throw new DefinitionException(diffMatches.get(0).getPath()+" has children ("+differential.getElement().get(diffCursor).getPath()+") and multiple types ("+typeCode(outcome.getType())+") in profile "+profileName); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants._HAS_CHILDREN__AND_MULTIPLE_TYPES__IN_PROFILE_, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName)); } } StructureDefinition dt = getProfileForDataType(outcome.getType().get(0)); if (dt == null) - throw new DefinitionException("Unknown type "+outcome.getType().get(0)+" at "+diffMatches.get(0).getPath()); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.UNKNOWN_TYPE__AT_, outcome.getType().get(0), diffMatches.get(0).getPath())); contextName = dt.getUrl(); int start = diffCursor; while (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), cpath+".")) @@ -861,7 +874,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (!sd.hasSnapshot()) { StructureDefinition sdb = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition()); if (sdb == null) - throw new DefinitionException("Unable to find base "+sd.getBaseDefinition()+" for "+sd.getUrl()); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.UNABLE_TO_FIND_BASE__FOR_, sd.getBaseDefinition(), sd.getUrl())); checkNotGenerating(sdb, "an extension base"); generateSnapshot(sdb, sd, sd.getUrl(), (sdb.hasUserData("path")) ? Utilities.extractBaseUrl(sdb.getUserString("path")) : webUrl, sd.getName()); } @@ -874,7 +887,7 @@ public class ProfileUtilities extends TranslatingUtilities { src = t; } if (src == null) - throw new DefinitionException("Unable to find element "+eid+" in "+p.getValue()); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.UNABLE_TO_FIND_ELEMENT__IN_, eid, p.getValue())); } else src = sd.getSnapshot().getElement().get(0); template = src.copy().setPath(currentBase.getPath()); @@ -907,7 +920,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (resultPathBase == null) resultPathBase = outcome.getPath(); else if (!outcome.getPath().startsWith(resultPathBase)) - throw new DefinitionException("Adding wrong path"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.ADDING_WRONG_PATH)); result.getElement().add(outcome); baseCursor++; diffCursor = differential.getElement().indexOf(diffMatches.get(0))+1; @@ -934,7 +947,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (ed != diffMatches.get(0) && !ed.getPath().endsWith(".extension")) nonExtension = true; if (nonExtension) - throw new DefinitionException(diffMatches.get(0).getPath()+" has children ("+differential.getElement().get(diffCursor).getPath()+") and multiple types ("+typeCode(outcome.getType())+") in profile "+profileName); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants._HAS_CHILDREN__AND_MULTIPLE_TYPES__IN_PROFILE_, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName)); } } } @@ -944,7 +957,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (outcome.hasContentReference()) { ElementDefinition tgt = getElementById(base.getElement(), outcome.getContentReference()); if (tgt == null) - throw new DefinitionException("Unable to resolve reference to "+outcome.getContentReference()); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.UNABLE_TO_RESOLVE_REFERENCE_TO_, outcome.getContentReference())); replaceFromContentReference(outcome, tgt); int nbc = base.getElement().indexOf(tgt)+1; int nbl = nbc; @@ -954,7 +967,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(diffMatches.get(0).getPath()+" has children ("+differential.getElement().get(diffCursor).getPath()+") for type "+typeCode(outcome.getType())+" in profile "+profileName+", but can't find type"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants._HAS_CHILDREN__FOR_TYPE__IN_PROFILE__BUT_CANT_FIND_TYPE, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName)); 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); @@ -967,9 +980,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 @@ -985,9 +998,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()); @@ -1004,18 +1017,18 @@ public class ProfileUtilities extends TranslatingUtilities { if (diffMatches.get(0).getSlicing().hasOrdered()) { if (diffMatches.get(0).getSlicing().getOrdered()) { - throw new FHIRException("Error at path "+cpath+" in "+url+": Type slicing with slicing.ordered = true"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGORDERED__TRUE, cpath, url)); } } if (diffMatches.get(0).getSlicing().hasDiscriminator()) { if (diffMatches.get(0).getSlicing().getDiscriminator().size() != 1) { - throw new FHIRException("Error at path "+cpath+" in "+url+": Type slicing with slicing.discriminator.count() > 1"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGDISCRIMINATORCOUNT__1, cpath, url)); } if (diffMatches.get(0).getSlicing().getDiscriminatorFirstRep().getType() != DiscriminatorType.TYPE) { - throw new FHIRException("Error at path "+cpath+" in "+url+": Type slicing with slicing.discriminator.type != 'type'"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGDISCRIMINATORTYPE__TYPE, cpath, url)); } if (!"$this".equals(diffMatches.get(0).getSlicing().getDiscriminatorFirstRep().getPath())) { - throw new FHIRException("Error at path "+cpath+" in "+url+": Type slicing with slicing.discriminator.path != '$this'"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGDISCRIMINATORPATH__THIS, cpath, url)); } } // check the slice names too while we're at it... @@ -1028,28 +1041,28 @@ public class ProfileUtilities extends TranslatingUtilities { if (autoFixSliceNames) { ts.defn.setSliceName(tn); } else { - throw new FHIRException("Error at path "+(!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath)+": Slice name must be '"+tn+"' but is '"+ts.defn.getSliceName()+"'"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ERROR_AT_PATH__SLICE_NAME_MUST_BE__BUT_IS_, (!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath), tn, ts.defn.getSliceName())); } } if (!ts.defn.hasType()) { ts.defn.addType().setCode(ts.type); } else if (ts.defn.getType().size() > 1) { - throw new FHIRException("Error at path "+(!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath)+": Slice for type '"+tn+"' has more than one type '"+ts.defn.typeSummary()+"'"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ERROR_AT_PATH__SLICE_FOR_TYPE__HAS_MORE_THAN_ONE_TYPE_, (!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath), tn, ts.defn.typeSummary())); } else if (!ts.defn.getType().get(0).getCode().equals(ts.type)) { - throw new FHIRException("Error at path "+(!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath)+": Slice for type '"+tn+"' has wrong type '"+ts.defn.typeSummary()+"'"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ERROR_AT_PATH__SLICE_FOR_TYPE__HAS_WRONG_TYPE_, (!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath), tn, 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("Did not find type root: " + diffMatches.get(0).getPath()); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.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++; @@ -1060,7 +1073,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("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"); + throw new FHIRException(formatMessage(i18nMessages, 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())); } else { e.setMin(1); } @@ -1092,9 +1105,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("Attempt to a slice an element that does not repeat: "+currentBase.getPath()+"/"+currentBase.getPath()+" from "+contextName+" in "+url); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.ATTEMPT_TO_A_SLICE_AN_ELEMENT_THAT_DOES_NOT_REPEAT__FROM__IN_, currentBase.getPath(), currentBase.getPath(), contextName, 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("Differential does not have a slice: "+currentBase.getPath()+"/ (b:"+baseCursor+" of "+ baseLimit+" / "+ diffCursor +"/ "+diffLimit+") in profile "+url); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.DIFFERENTIAL_DOES_NOT_HAVE_A_SLICE__B_OF_____IN_PROFILE_, currentBase.getPath(), baseCursor, baseLimit, diffCursor, diffLimit, url)); // well, if it passed those preconditions then we slice the dest. int start = 0; @@ -1106,7 +1119,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("Did not find single slice: " + diffMatches.get(0).getPath()); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.DID_NOT_FIND_SINGLE_SLICE_, diffMatches.get(0).getPath())); e.setSlicing(diffMatches.get(0).getSlicing()); start++; } else { @@ -1120,7 +1133,7 @@ public class ProfileUtilities extends TranslatingUtilities { else outcome.setSlicing(diffMatches.get(0).getSlicing().copy()); if (!outcome.getPath().startsWith(resultPathBase)) - throw new DefinitionException("Adding wrong path"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.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. @@ -1128,7 +1141,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("not done yet"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.NOT_DONE_YET)); } start++; // result.getElement().remove(result.getElement().size()-1); @@ -1177,7 +1190,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (resultPathBase == null) resultPathBase = outcome.getPath(); else if (!outcome.getPath().startsWith(resultPathBase)) - throw new DefinitionException("Adding wrong path"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.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? @@ -1186,17 +1199,17 @@ public class ProfileUtilities extends TranslatingUtilities { baseCursor = indexOfFirstNonChild(base, currentBase, baseCursor, baseLimit); } else { if (outcome.getType().size() == 0) { - throw new DefinitionException(diffMatches.get(0).getPath()+" has no children ("+differential.getElement().get(diffCursor).getPath()+") and no types in profile "+profileName); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants._HAS_NO_CHILDREN__AND_NO_TYPES_IN_PROFILE_, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), profileName)); } if (outcome.getType().size() > 1) { for (TypeRefComponent t : outcome.getType()) { if (!t.getWorkingCode().equals("Reference")) - throw new DefinitionException(diffMatches.get(0).getPath()+" has children ("+differential.getElement().get(diffCursor).getPath()+") and multiple types ("+typeCode(outcome.getType())+") in profile "+profileName); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants._HAS_CHILDREN__AND_MULTIPLE_TYPES__IN_PROFILE_, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName)); } } StructureDefinition dt = getProfileForDataType(outcome.getType().get(0)); if (dt == null) - throw new DefinitionException("Unknown type "+outcome.getType().get(0)+" at "+diffMatches.get(0).getPath()); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.UNKNOWN_TYPE__AT_, outcome.getType().get(0), diffMatches.get(0).getPath())); contextName = dt.getUrl(); int start = diffCursor; while (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), cpath+".")) @@ -1212,7 +1225,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("Adding wrong path in profile " + profileName + ": "+outcome.getPath()+" vs " + resultPathBase); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.ADDING_WRONG_PATH_IN_PROFILE___VS_, profileName, outcome.getPath(), resultPathBase)); result.getElement().add(outcome); // so we just copy it in baseCursor++; } @@ -1223,9 +1236,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 @@ -1241,9 +1254,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()); @@ -1260,18 +1273,18 @@ public class ProfileUtilities extends TranslatingUtilities { if (diffMatches.get(0).getSlicing().hasOrdered()) { if (diffMatches.get(0).getSlicing().getOrdered()) { - throw new FHIRException("Error at path "+cpath+" in "+url+": Type slicing with slicing.ordered = true"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGORDERED__TRUE, cpath, url)); } } if (diffMatches.get(0).getSlicing().hasDiscriminator()) { if (diffMatches.get(0).getSlicing().getDiscriminator().size() != 1) { - throw new FHIRException("Error at path "+cpath+" in "+url+": Type slicing with slicing.discriminator.count() > 1"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGDISCRIMINATORCOUNT__1, cpath, url)); } if (diffMatches.get(0).getSlicing().getDiscriminatorFirstRep().getType() != DiscriminatorType.TYPE) { - throw new FHIRException("Error at path "+cpath+" in "+url+": Type slicing with slicing.discriminator.type != 'type'"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGDISCRIMINATORTYPE__TYPE, cpath, url)); } if (!"$this".equals(diffMatches.get(0).getSlicing().getDiscriminatorFirstRep().getPath())) { - throw new FHIRException("Error at path "+cpath+" in "+url+": Type slicing with slicing.discriminator.path != '$this'"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGDISCRIMINATORPATH__THIS, cpath, url)); } } // check the slice names too while we're at it... @@ -1281,27 +1294,27 @@ public class ProfileUtilities extends TranslatingUtilities { if (!ts.defn.hasSliceName()) { ts.defn.setSliceName(tn); } else if (!ts.defn.getSliceName().equals(tn)) { - throw new FHIRException("Error at path "+(!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath)+": Slice name must be '"+tn+"' but is '"+ts.defn.getSliceName()+"'"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ERROR_AT_PATH__SLICE_NAME_MUST_BE__BUT_IS_, (!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath), tn, ts.defn.getSliceName())); } if (!ts.defn.hasType()) { ts.defn.addType().setCode(ts.type); } else if (ts.defn.getType().size() > 1) { - throw new FHIRException("Error at path "+(!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath)+": Slice for type '"+tn+"' has more than one type '"+ts.defn.typeSummary()+"'"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ERROR_AT_PATH__SLICE_FOR_TYPE__HAS_MORE_THAN_ONE_TYPE_, (!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath), tn, ts.defn.typeSummary())); } else if (!ts.defn.getType().get(0).getCode().equals(ts.type)) { - throw new FHIRException("Error at path "+(!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath)+": Slice for type '"+tn+"' has wrong type '"+ts.defn.typeSummary()+"'"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ERROR_AT_PATH__SLICE_FOR_TYPE__HAS_WRONG_TYPE_, (!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath), tn, 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("Did not find type root: " + diffMatches.get(0).getPath()); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.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++; @@ -1314,7 +1327,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("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"); + throw new FHIRException(formatMessage(i18nMessages, 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())); } fixedType = type; } @@ -1366,11 +1379,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("Slicing rules on differential ("+summarizeSlicing(dSlice)+") do not match those on base ("+summarizeSlicing(bSlice)+") - order @ "+path+" ("+contextName+")"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.SLICING_RULES_ON_DIFFERENTIAL__DO_NOT_MATCH_THOSE_ON_BASE___ORDER___, summarizeSlicing(dSlice), summarizeSlicing(bSlice), path, contextName)); if (!discriminatorMatches(dSlice.getDiscriminator(), bSlice.getDiscriminator())) - throw new DefinitionException("Slicing rules on differential ("+summarizeSlicing(dSlice)+") do not match those on base ("+summarizeSlicing(bSlice)+") - disciminator @ "+path+" ("+contextName+")"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.SLICING_RULES_ON_DIFFERENTIAL__DO_NOT_MATCH_THOSE_ON_BASE___DISCIMINATOR___, summarizeSlicing(dSlice), summarizeSlicing(bSlice), path, contextName)); if (!currentBase.isChoice() && !ruleMatches(dSlice.getRules(), bSlice.getRules())) - throw new DefinitionException("Slicing rules on differential ("+summarizeSlicing(dSlice)+") do not match those on base ("+summarizeSlicing(bSlice)+") - rule @ "+path+" ("+contextName+")"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.SLICING_RULES_ON_DIFFERENTIAL__DO_NOT_MATCH_THOSE_ON_BASE___RULE___, summarizeSlicing(dSlice), summarizeSlicing(bSlice), path, contextName)); } ElementDefinition outcome = updateURLs(url, webUrl, currentBase.copy()); outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc)); @@ -1380,7 +1393,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); @@ -1394,11 +1407,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("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"); + throw new Error(formatMessage(i18nMessages, 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())); } StructureDefinition dt = getProfileForDataType(base.getElement().get(baseCursor).getType().get(0)); if (dt == null) { - throw new DefinitionException("Unknown type "+outcome.getType().get(0)+" at "+diffMatches.get(0).getPath()); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.UNKNOWN_TYPE__AT_, outcome.getType().get(0), diffMatches.get(0).getPath())); } contextName = dt.getUrl(); while (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), cpath+".")) @@ -1429,7 +1442,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("Adding wrong path"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.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); @@ -1451,7 +1464,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("Adding wrong path"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.ADDING_WRONG_PATH)); result.getElement().add(outcome); baseCursor++; } @@ -1462,11 +1475,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("The base snapshot marks a slicing as closed, but the differential tries to extend it in "+profileName+" at "+path+" ("+cpath+")"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.THE_BASE_SNAPSHOT_MARKS_A_SLICING_AS_CLOSED_BUT_THE_DIFFERENTIAL_TRIES_TO_EXTEND_IT_IN__AT__, profileName, path, cpath)); } } if (diffpos == diffMatches.size()) { @@ -1477,14 +1490,14 @@ public class ProfileUtilities extends TranslatingUtilities { ElementDefinition diffItem = diffMatches.get(diffpos); for (ElementDefinition baseItem : baseMatches) if (baseItem.getSliceName().equals(diffItem.getSliceName())) - throw new DefinitionException("Named items are out of order in the slice"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.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("Adding wrong path"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.ADDING_WRONG_PATH)); result.getElement().add(outcome); updateFromDefinition(outcome, diffItem, profileName, trimDifferential, url, srcSD); removeStatusExtensions(outcome); @@ -1496,7 +1509,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (outcome.getType().size() > 1) for (TypeRefComponent t : outcome.getType()) { if (!t.getCode().equals("Reference")) - throw new DefinitionException(diffMatches.get(0).getPath()+" has children ("+differential.getElement().get(diffCursor).getPath()+") and multiple types ("+typeCode(outcome.getType())+") in profile "+profileName); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants._HAS_CHILDREN__AND_MULTIPLE_TYPES__IN_PROFILE_, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName)); } TypeRefComponent t = outcome.getType().get(0); if (t.getCode().equals("BackboneElement")) { @@ -1513,10 +1526,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(diffMatches.get(0).getPath()+" has children ("+differential.getElement().get(diffCursor).getPath()+") for type "+typeCode(outcome.getType())+" in profile "+profileName+", but can't find type"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants._HAS_CHILDREN__FOR_TYPE__IN_PROFILE__BUT_CANT_FIND_TYPE, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName)); contextName = dt.getUrl(); int start = diffCursor; while (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), diffMatches.get(0).getPath()+".")) @@ -1540,7 +1553,7 @@ public class ProfileUtilities extends TranslatingUtilities { for (ElementDefinition e : result.getElement()) { i++; if (e.hasMinElement() && e.getMinElement().getValue()==null) - throw new Error("null min"); + throw new Error(formatMessage(i18nMessages, I18nConstants.NULL_MIN)); } return res; } @@ -1548,7 +1561,7 @@ public class ProfileUtilities extends TranslatingUtilities { private void checkNotGenerating(StructureDefinition sd, String role) { if (sd.hasUserData("profileutils.snapshot.generating")) { - throw new FHIRException("Attempt to use a snapshot on profile '"+sd.getUrl()+"' as "+role+" before it is generated"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ATTEMPT_TO_USE_A_SNAPSHOT_ON_PROFILE__AS__BEFORE_IT_IS_GENERATED, sd.getUrl(), role)); } } @@ -1573,12 +1586,12 @@ public class ProfileUtilities extends TranslatingUtilities { } else if (isPrimitive(Utilities.uncapitalize(t))) { fixedType = Utilities.uncapitalize(t); } else { - 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()); + throw new FHIRException(formatMessage(i18nMessages, 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())); } } else if (diffMatches.get(i).getType().size() == 1) { fixedType = diffMatches.get(i).getType().get(0).getCode(); } else { - throw new FHIRException("Unexpected condition in differential: type-slice.type-list.size() != 1 at "+diffMatches.get(i).getPath()+"/"+diffMatches.get(i).getSliceName()); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.UNEXPECTED_CONDITION_IN_DIFFERENTIAL_TYPESLICETYPELISTSIZE__1_AT_, diffMatches.get(i).getPath(), diffMatches.get(i).getSliceName())); } return fixedType; } @@ -2147,14 +2160,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? @@ -2310,7 +2323,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) @@ -2453,7 +2466,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (derived.hasIsSummaryElement()) { if (!Base.compareDeep(derived.getIsSummaryElement(), base.getIsSummaryElement(), false)) { if (base.hasIsSummary()) - throw new Error("Error in profile "+pn+" at "+derived.getPath()+": Base isSummary = "+base.getIsSummaryElement().asStringValue()+", derived isSummary = "+derived.getIsSummaryElement().asStringValue()); + throw new Error(formatMessage(i18nMessages, I18nConstants.ERROR_IN_PROFILE__AT__BASE_ISSUMMARY___DERIVED_ISSUMMARY__, pn, derived.getPath(), base.getIsSummaryElement().asStringValue(), derived.getIsSummaryElement().asStringValue())); base.setIsSummaryElement(derived.getIsSummaryElement().copy()); } else if (trimDifferential) derived.setIsSummaryElement(null); @@ -2573,7 +2586,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); @@ -2592,7 +2605,7 @@ public class ProfileUtilities extends TranslatingUtilities { } if (!tgtOk) { if (messages == null) { - throw new FHIRException("Error at "+purl+"#"+derived.getPath()+": The target profile "+url+" is not valid constraint on the base ("+td.getTargetProfile()+")"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ERROR_AT__THE_TARGET_PROFILE__IS_NOT__VALID_CONSTRAINT_ON_THE_BASE_, purl, derived.getPath(), url, 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)); } @@ -2601,7 +2614,7 @@ public class ProfileUtilities extends TranslatingUtilities { } } if (!ok) { - throw new DefinitionException("StructureDefinition "+purl+" at "+derived.getPath()+": illegal constrained type "+t+" from "+b.toString()+" in "+srcSD.getUrl()); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.STRUCTUREDEFINITION__AT__ILLEGAL_CONSTRAINED_TYPE__FROM__IN_, purl, derived.getPath(), t, b.toString(), srcSD.getUrl())); } } @@ -3168,7 +3181,7 @@ public class ProfileUtilities extends TranslatingUtilities { try { return gen.generate(model, imagePath, 0, outputTracker); } catch (org.hl7.fhir.exceptions.FHIRException e) { - throw new FHIRException("Error generating table for profile " + profile.getUrl() + ": " + e.getMessage(), e); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.ERROR_GENERATING_TABLE_FOR_PROFILE__, profile.getUrl(), e.getMessage()), e); } } @@ -3178,7 +3191,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++; } @@ -3726,7 +3739,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 { @@ -3993,7 +4006,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (ed.getPath().equals(path)) return ed; } - throw new FHIRException("Unable to find element "+path); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.UNABLE_TO_FIND_ELEMENT_, path)); } @@ -4262,7 +4275,7 @@ public class ProfileUtilities extends TranslatingUtilities { return sd.getType(); if (Utilities.existsInList(value, "SimpleQuantity", "MoneyQuantity")) return "Quantity"; - throw new Error("Internal error - type not known "+value); + throw new Error(formatMessage(i18nMessages, I18nConstants.INTERNAL_ERROR___TYPE_NOT_KNOWN_, value)); } @@ -4562,7 +4575,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("Unhandled situation: resource is profiled to more than one option - cannot sort profile"); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.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) { @@ -4585,12 +4598,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("Unable to resolve profile " + sdNs(ed.getType().get(0).getWorkingCode()) + " in element " + ed.getPath()); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.UNABLE_TO_RESOLVE_PROFILE__IN_ELEMENT_, sdNs(ed.getType().get(0).getWorkingCode()), 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("Unable to resolve profile " + sdNs(ed.getType().get(0).getWorkingCode()) + " in element " + ed.getPath()); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.UNABLE_TO_RESOLVE_PROFILE__IN_ELEMENT_, sdNs(ed.getType().get(0).getWorkingCode()), 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"); @@ -4600,12 +4613,12 @@ public class ProfileUtilities extends TranslatingUtilities { p = Utilities.uncapitalize(p); StructureDefinition sd = context.fetchResource(StructureDefinition.class, sdNs(p)); if (sd == null) - throw new Error("Unable to find profile '"+p+"' at "+ed.getId()); + throw new Error(formatMessage(i18nMessages, I18nConstants.UNABLE_TO_FIND_PROFILE__AT_, p, 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("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())+")"); + throw new Error(formatMessage(i18nMessages, 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()))); } } StructureDefinition profile = context.fetchResource(StructureDefinition.class, sdNs(ed.getType().get(0).getWorkingCode())); @@ -4613,7 +4626,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("Not handled yet (sortElements: "+ed.getPath()+":"+typeCode(ed.getType())+")"); + throw new Error(formatMessage(i18nMessages, I18nConstants.NOT_HANDLED_YET_SORTELEMENTS_, ed.getPath(), typeCode(ed.getType()))); } } StructureDefinition profile = context.fetchResource(StructureDefinition.class, sdNs(ed.getType().get(0).getWorkingCode())); @@ -4622,7 +4635,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("Unable to resolve profile " + sdNs(ed.getType().get(0).getWorkingCode()) + " in element " + ed.getPath()); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.UNABLE_TO_RESOLVE_PROFILE__IN_ELEMENT_, sdNs(ed.getType().get(0).getWorkingCode()), 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())+")"); } @@ -4691,9 +4704,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("not the right kind of structure to generate schematrons for"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.NOT_THE_RIGHT_KIND_OF_STRUCTURE_TO_GENERATE_SCHEMATRONS_FOR)); if (!structure.hasSnapshot()) - throw new DefinitionException("needs a snapshot"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.NEEDS_A_SNAPSHOT)); StructureDefinition base = context.fetchResource(StructureDefinition.class, structure.getBaseDefinition()); @@ -4709,7 +4722,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("needs a snapshot"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.NEEDS_A_SNAPSHOT)); CSVWriter csv = new CSVWriter(dest, structure, asXml); @@ -4725,7 +4738,7 @@ public class ProfileUtilities extends TranslatingUtilities { System.out.println("no structure!"); } if (!structure.hasSnapshot()) { - throw new DefinitionException("needs a snapshot"); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.NEEDS_A_SNAPSHOT)); } XLSXWriter xlsx = new XLSXWriter(dest, structure, asXml, hideMustSupportFalse); @@ -4885,7 +4898,7 @@ public class ProfileUtilities extends TranslatingUtilities { for (ElementDefinition ed : list) { List paths = new ArrayList(); if (!ed.hasPath()) - throw new DefinitionException("No path on element Definition "+Integer.toString(list.indexOf(ed))+" in "+name); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.NO_PATH_ON_ELEMENT_DEFINITION__IN_, Integer.toString(list.indexOf(ed)), 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 @@ -4909,7 +4922,7 @@ public class ProfileUtilities extends TranslatingUtilities { ed.setId(bs); if (idList.containsKey(bs)) { if (exception || messages == null) { - throw new DefinitionException("Same id '"+bs+"'on multiple elements "+idList.get(bs)+"/"+ed.getPath()+" in "+name); + throw new DefinitionException(formatMessage(i18nMessages, I18nConstants.SAME_ID_ON_MULTIPLE_ELEMENTS__IN_, bs, idList.get(bs), ed.getPath(), name)); } else messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, name+"."+bs, "Duplicate Element id "+bs, ValidationMessage.IssueSeverity.ERROR)); } @@ -5103,7 +5116,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (sd.hasBaseDefinition()) { StructureDefinition base = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition()); if (base == null) - throw new FHIRException("Unable to find base definition for logical model: "+sd.getBaseDefinition()+" from "+sd.getUrl()); + throw new FHIRException(formatMessage(i18nMessages, I18nConstants.UNABLE_TO_FIND_BASE_DEFINITION_FOR_LOGICAL_MODEL__FROM_, sd.getBaseDefinition(), sd.getUrl())); copyElements(sd, base.getSnapshot().getElement()); } copyElements(sd, sd.getDifferential().getElement()); @@ -5195,7 +5208,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 { @@ -5314,7 +5327,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.validation/src/main/java/org/hl7/fhir/validation/utils/I18nConstants.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/I18nConstants.java similarity index 72% rename from org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/utils/I18nConstants.java rename to org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/I18nConstants.java index 2a30f494c..de0550613 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/utils/I18nConstants.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/I18nConstants.java @@ -1,7 +1,22 @@ -package org.hl7.fhir.validation.utils; +package org.hl7.fhir.utilities; + +import java.text.MessageFormat; +import java.util.ResourceBundle; public class I18nConstants { + public static String formatMessage(ResourceBundle resourceBundle, String theMessage, Object... theMessageArguments) { + String message; + if (theMessageArguments != null && theMessageArguments.length > 0) { + message = MessageFormat.format(resourceBundle.getString(theMessage), theMessageArguments); + } else if (resourceBundle.containsKey(theMessage)) { + message = resourceBundle.getString(theMessage); + } else { + message = theMessage; + } + return message; + } + public final static String BUNDLE_BUNDLE_ENTRY_CANONICAL = "Bundle_BUNDLE_Entry_Canonical"; public final static String BUNDLE_BUNDLE_ENTRY_DOCUMENT = "Bundle_BUNDLE_Entry_Document"; public final static String BUNDLE_BUNDLE_ENTRY_IDURLMISMATCH = "Bundle_BUNDLE_Entry_IdUrlMismatch"; @@ -268,5 +283,76 @@ 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_"; } 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 1a0b6e97a..e17e5d005 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,16 @@ public class BaseValidator { protected Source source; protected IWorkerContext context; - private ResourceBundle messages; + private ResourceBundle i18Nmessages; public BaseValidator(IWorkerContext context){ this.context = context; - messages = ResourceBundle.getBundle("Messages", context.getLocale() ); + i18Nmessages = ResourceBundle.getBundle("Messages", context.getLocale() ); } public void setContext(IWorkerContext context) { this.context = context; - messages = ResourceBundle.getBundle("Messages", context.getLocale() ); + i18Nmessages = ResourceBundle.getBundle("Messages", context.getLocale() ); } /** @@ -146,11 +146,11 @@ public class BaseValidator { protected String formatMessage(String theMessage, Object... theMessageArguments) { String message = ""; - if (messages.containsKey(theMessage)) { + if (i18Nmessages.containsKey(theMessage)) { if (theMessageArguments != null && theMessageArguments.length > 0) { - message = MessageFormat.format(messages.getString(theMessage), theMessageArguments); - } else if (messages.containsKey(theMessage)) { - message = messages.getString(theMessage); + message = MessageFormat.format(i18Nmessages.getString(theMessage), theMessageArguments); + } else if (i18Nmessages.containsKey(theMessage)) { + message = i18Nmessages.getString(theMessage); } } else { message = theMessage; @@ -564,4 +564,8 @@ public class BaseValidator { } return thePass; } + + public ResourceBundle getI18Nmessages() { + return i18Nmessages; + } } 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 75b782929..fad7276ba 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,6 +126,7 @@ 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; @@ -141,7 +142,6 @@ 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; @@ -375,7 +375,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat super(theContext); this.context = theContext; this.externalHostServices = hostServices; - this.profileUtilities = new ProfileUtilities(theContext, null, null); + this.profileUtilities = new ProfileUtilities(theContext, null, null, getI18Nmessages()); fpe = new FHIRPathEngine(context); validatorServices = new ValidatorHostServices(); fpe.setHostServices(validatorServices); diff --git a/org.hl7.fhir.validation/src/main/resources/Messages.properties b/org.hl7.fhir.validation/src/main/resources/Messages.properties index 5a4646466..233d851a7 100644 --- a/org.hl7.fhir.validation/src/main/resources/Messages.properties +++ b/org.hl7.fhir.validation/src/main/resources/Messages.properties @@ -265,3 +265,78 @@ 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 mising ('..') +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}