diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 25474490e..caf73180b 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,3 +6,9 @@ updates: interval: daily time: "11:00" open-pull-requests-limit: 10 +- package-ecosystem: github-actions + directory: "/" + schedule: + interval: daily + time: "11:00" + open-pull-requests-limit: 10 diff --git a/README.md b/README.md index 62224fe00..4ef0362f6 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ You can depend on parts of Archie, or the entire library at once. If you want th ```gradle dependencies { - compile 'com.nedap.healthcare.archie:archie-all:3.14.0' + compile 'com.nedap.healthcare.archie:archie-all:3.16.0' } ``` @@ -28,11 +28,11 @@ or if you use maven, in your pom.xml com.nedap.healthcare.archie archie-all - 3.14.0 + 3.16.0 ``` -If you want to depend on just the AOM and BMM, without any reference model implementation, depend on com.nedap.healthcare.archie:tools:3.14.0 and com.nedap.healthcare.archie:referencemodels:3.14.0 instead +If you want to depend on just the AOM and BMM, without any reference model implementation, depend on com.nedap.healthcare.archie:tools:3.16.0 and com.nedap.healthcare.archie:referencemodels:3.16.0 instead ## Build @@ -137,7 +137,7 @@ InMemoryFullArchetypeRepository repository = new InMemoryFullArchetypeRepository for(Archetype archetype:allArchetypes) { repository.addArchetype(archetype); } -repository.compile(BuiltinReferenceModels.getMetaModels()); +repository.compile(BuiltinReferenceModels.getMetaModelProvider()); for(ValidationResult result:repository.getAllValidationResults()) { ... your code here @@ -149,7 +149,7 @@ The validation result contains the validation result, listing any errors in the ### Reference model metadata -You may have noticed a call to ```BuiltinReferenceModels.getMetaModels()```. This retrieves the metadata for the reference models, which are needed to validate and flatten archetypes. Archie contains two types of metamodels: BMM, and reflection based metadata. +You may have noticed a call to ```BuiltinReferenceModels.getMetaModelProvider()```. This retrieves the metadata for the reference models, which are needed to validate and flatten archetypes. Archie contains two types of metamodels: BMM, and reflection based metadata. The BMM models are a file containing metadata in a form defined by the openEHR specifications. The reflection based metadata contains ModelInfoLookup classes. They are derived from an implementation of a reference model. Note that the ModelInfoLookup classes are only added if you depended on them. If you depended on archie-all, you're all set. @@ -162,7 +162,7 @@ Note that ADL 2 operational templates is fundamentally different from the ADL 1. To create an Operational Template: ```java -Flattener flattener = new Flattener(repository, BuiltinReferenceModels.getMetaModels()).createOperationalTemplate(true); +Flattener flattener = new Flattener(repository, BuiltinReferenceModels.getMetaModelProvider()).createOperationalTemplate(true); OperationalTemplate template = (OperationalTemplate) flattener.flatten(sourceArchetype); ``` @@ -221,7 +221,7 @@ The inverse operation of flattening archetypes is diffing. This is useful if you ```java Archetype flatChild, flatParent; //for how to parse and flatten, see elsewhere in the readme -Differentiator differentiator = new Differentiator(BuiltinReferenceModels.getMetaModels()); +Differentiator differentiator = new Differentiator(BuiltinReferenceModels.getMetaModelProvider()); Archetype diffed = differentiator.differentiate(flatChild, flatParent); ``` @@ -391,7 +391,7 @@ If you want to do this yourself, The RMObjectCreator creates empty reference mod Setting primitive object values works in a similar way, with ```creator.set(...)```, or by setting them explicitly on the reference model object directly. -Notice the call to ```ArchieRMInfoLookup.getInstance()```, which obtains the metadata about the reference model implementation. It can also be obtained from the result of ```BuiltinReferenceModels.getMetaModels()```, or you can define your own to make Archie work with your own reference model implementation. +Notice the call to ```ArchieRMInfoLookup.getInstance()```, which obtains the metadata about the reference model implementation. It can also be obtained from the result of ```BuiltinReferenceModels.getMetaModelProvider()```, or you can define your own to make Archie work with your own reference model implementation. ### Parsing JSON @@ -456,10 +456,10 @@ Starting from version 0.7, Archie can import ADL 1.4 files, and convert them to ```java ADL14ConversionConfiguration conversionConfiguration = new ADL14ConversionConfiguration(); -ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModels(), conversionConfiguration); +ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModelProvider(), conversionConfiguration); List archetypes = new ArrayList<>(); -ADL14Parser parser = new ADL14Parser(BuiltinReferenceModels.getMetaModels()); +ADL14Parser parser = new ADL14Parser(BuiltinReferenceModels.getMetaModelProvider()); for(String file:fileNames) { try(InputStream stream = new FileInputStream(file)) { diff --git a/adlchecker/build.gradle b/adlchecker/build.gradle index ef07c4738..d6f0e1815 100644 --- a/adlchecker/build.gradle +++ b/adlchecker/build.gradle @@ -15,4 +15,4 @@ run { args = ['archetypes', '--lint']//, '--outputFlat'] } -mainClassName='com.nedap.archie.adlchecker.AdlChecker' +mainClassName = 'com.nedap.archie.adlchecker.AdlChecker' diff --git a/aom/build.gradle b/aom/build.gradle index 2de9ebe81..675fb909f 100644 --- a/aom/build.gradle +++ b/aom/build.gradle @@ -1,10 +1,10 @@ description = "An OpenEHR archetype object model implementation, plus parser" dependencies { - api project(':grammars') - api project(':base') - api project(':odin') - api project(':utils') - api project(':bmm') - api project(':openehr-terminology') -} \ No newline at end of file + api project(':grammars') + api project(':base') + api project(':odin') + api project(':utils') + api project(':bmm') + api project(':openehr-terminology') +} diff --git a/aom/src/main/java/com/nedap/archie/adl14/ADL14DefaultMultiplicitiesSetter.java b/aom/src/main/java/com/nedap/archie/adl14/ADL14DefaultMultiplicitiesSetter.java index 80b86d0e6..095958cf7 100644 --- a/aom/src/main/java/com/nedap/archie/adl14/ADL14DefaultMultiplicitiesSetter.java +++ b/aom/src/main/java/com/nedap/archie/adl14/ADL14DefaultMultiplicitiesSetter.java @@ -4,6 +4,8 @@ import com.nedap.archie.aom.CAttribute; import com.nedap.archie.aom.CObject; import com.nedap.archie.base.MultiplicityInterval; +import com.nedap.archie.rminfo.MetaModel; +import com.nedap.archie.rminfo.MetaModelProvider; import com.nedap.archie.rminfo.MetaModels; /** @@ -17,24 +19,32 @@ */ public class ADL14DefaultMultiplicitiesSetter { - private final MetaModels metaModels; + private final MetaModelProvider metaModelProvider; + /** + * @deprecated Use {@link #ADL14DefaultMultiplicitiesSetter(MetaModelProvider)} instead. + */ + @Deprecated public ADL14DefaultMultiplicitiesSetter(MetaModels metaModels) { - this.metaModels = metaModels; + this((MetaModelProvider) metaModels); + } + + public ADL14DefaultMultiplicitiesSetter(MetaModelProvider metaModelProvider) { + this.metaModelProvider = metaModelProvider; } public void setDefaults(Archetype archetype) { - metaModels.selectModel(archetype); - correctItemsMultiplicities(archetype.getDefinition()); + MetaModel metaModel = metaModelProvider.selectAndGetMetaModel(archetype); + correctItemsMultiplicities(metaModel, archetype.getDefinition()); } - private void correctItemsMultiplicities(CObject cObject) { + private void correctItemsMultiplicities(MetaModel metaModel, CObject cObject) { for (CAttribute attribute : cObject.getAttributes()) { for (CObject child : attribute.getChildren()) { - if (child.getOccurrences() == null && metaModels.isMultiple(cObject.getRmTypeName(), attribute.getRmAttributeName())) { + if (child.getOccurrences() == null && metaModel.isMultiple(cObject.getRmTypeName(), attribute.getRmAttributeName())) { child.setOccurrences(new MultiplicityInterval(1, 1)); } - correctItemsMultiplicities(child); + correctItemsMultiplicities(metaModel, child); } } diff --git a/aom/src/main/java/com/nedap/archie/adl14/ADL14NodeIDConverter.java b/aom/src/main/java/com/nedap/archie/adl14/ADL14NodeIDConverter.java index 48ad8663d..aa06afe1a 100644 --- a/aom/src/main/java/com/nedap/archie/adl14/ADL14NodeIDConverter.java +++ b/aom/src/main/java/com/nedap/archie/adl14/ADL14NodeIDConverter.java @@ -13,6 +13,8 @@ import com.nedap.archie.base.Cardinality; import com.nedap.archie.paths.PathSegment; import com.nedap.archie.query.APathQuery; +import com.nedap.archie.rminfo.MetaModel; +import com.nedap.archie.rminfo.MetaModelProvider; import com.nedap.archie.rminfo.MetaModels; import com.nedap.archie.rules.*; @@ -33,7 +35,8 @@ public class ADL14NodeIDConverter { private final ADL14TermConstraintConverter termConstraintConverter; private final PreviousConversionApplier previousConversionApplier; private final ADL2ConversionResult conversionResult; - private final MetaModels metaModels; + private final MetaModelProvider metaModelProvider; + private final MetaModel metaModel; private IdCodeGenerator idCodeGenerator; @@ -45,8 +48,17 @@ public class ADL14NodeIDConverter { private final Map createdValueSets = new LinkedHashMap<>(); private final Map newCodeToOldCodeMap = new LinkedHashMap<>(); + /** + * @deprecated Use {@link #ADL14NodeIDConverter(MetaModelProvider, Archetype, Archetype, ADL14ConversionConfiguration, ADL2ConversionLog, ADL2ConversionResult)} instead. + */ + @Deprecated public ADL14NodeIDConverter(MetaModels metaModels, Archetype archetype, Archetype flatParentArchetype, ADL14ConversionConfiguration configuration, ADL2ConversionLog oldLog, ADL2ConversionResult conversionResult) { - this.metaModels = metaModels; + this((MetaModelProvider) metaModels, archetype, flatParentArchetype, configuration, oldLog, conversionResult); + } + + public ADL14NodeIDConverter(MetaModelProvider metaModelProvider, Archetype archetype, Archetype flatParentArchetype, ADL14ConversionConfiguration configuration, ADL2ConversionLog oldLog, ADL2ConversionResult conversionResult) { + this.metaModelProvider = metaModelProvider; + this.metaModel = metaModelProvider.getMetaModel(archetype); this.conversionConfiguration = configuration; this.archetype = archetype; this.flatParentArchetype = flatParentArchetype; @@ -61,7 +73,7 @@ public ADL14ConversionConfiguration getConversionConfiguration() { } public ADL2ConversionLog convert() { - metaModels.selectModel(archetype); + metaModelProvider.selectAndGetMetaModel(archetype); // For backwards compatibility correctItemsCardinality(archetype.getDefinition()); List unnecessaryCodes = findUnnecessaryCodes(archetype.getDefinition(), @@ -123,7 +135,7 @@ private List findUnnecessaryCodes(CObject cObject, Map seenMetaDataIdentifiers = new HashSet<>(); private Archetype archetype; - private CComplexObjectParser cComplexObjectParser; private TerminologyParser terminologyParser; - private MetaModels metaModels; + private final MetaModelProvider metaModelProvider; + /** + * @deprecated Use {@link #ADLListener(ANTLRParserErrors, MetaModelProvider)} instead. + */ + @Deprecated public ADLListener(ANTLRParserErrors errors, MetaModels metaModels) { + this(errors, (MetaModelProvider) metaModels); + } + + public ADLListener(ANTLRParserErrors errors, MetaModelProvider metaModelProvider) { this.errors = errors; - cComplexObjectParser = new CComplexObjectParser(errors, metaModels); terminologyParser = new TerminologyParser(errors); - this.metaModels = metaModels; + this.metaModelProvider = metaModelProvider; } /** top-level constructs */ @@ -110,8 +118,8 @@ private void parseArchetypeHRID(TerminalNode hrId) { if(hrId != null) { ArchetypeHRID archetypeID = new ArchetypeHRID(hrId.getText()); archetype.setArchetypeId(archetypeID); - if(metaModels != null) { - metaModels.selectModel(archetype); + if(metaModelProvider != null) { + metaModelProvider.selectAndGetMetaModel(archetype); // For backwards compatibility } } } @@ -195,6 +203,8 @@ public void enterMetaDataItem(AdlParser.MetaDataItemContext ctx) { */ @Override public void enterDefinitionSection(DefinitionSectionContext ctx) { + MetaModel metaModel = metaModelProvider == null ? null : metaModelProvider.getMetaModel(archetype); + CComplexObjectParser cComplexObjectParser = new CComplexObjectParser(errors, metaModel); CComplexObject definition = cComplexObjectParser.parseComplexObject(ctx.c_complex_object()); archetype.setDefinition(definition); } @@ -223,6 +233,8 @@ public void enterSpecializationSection(SpecializationSectionContext ctx) { @Override public void enterRulesSection(RulesSectionContext ctx) { + MetaModel metaModel = metaModelProvider == null ? null : metaModelProvider.getMetaModel(archetype); + CComplexObjectParser cComplexObjectParser = new CComplexObjectParser(errors, metaModel); archetype.setRules(cComplexObjectParser.parseRules(ctx)); } diff --git a/aom/src/main/java/com/nedap/archie/adlparser/treewalkers/CComplexObjectParser.java b/aom/src/main/java/com/nedap/archie/adlparser/treewalkers/CComplexObjectParser.java index 43bf2fbf3..1ac3c17b6 100644 --- a/aom/src/main/java/com/nedap/archie/adlparser/treewalkers/CComplexObjectParser.java +++ b/aom/src/main/java/com/nedap/archie/adlparser/treewalkers/CComplexObjectParser.java @@ -7,6 +7,7 @@ import com.nedap.archie.base.Cardinality; import com.nedap.archie.base.MultiplicityInterval; import com.nedap.archie.base.OpenEHRBase; +import com.nedap.archie.rminfo.MetaModel; import com.nedap.archie.rminfo.MetaModels; import com.nedap.archie.rules.Assertion; import com.nedap.archie.serializer.odin.AdlOdinToJsonConverter; @@ -24,12 +25,26 @@ public class CComplexObjectParser extends BaseTreeWalker { private final PrimitivesConstraintParser primitivesConstraintParser; + @Deprecated private final MetaModels metaModels; + private final MetaModel metaModel; + /** + * @deprecated Use {@link #CComplexObjectParser(ANTLRParserErrors, MetaModel)} instead. + */ + @Deprecated public CComplexObjectParser(ANTLRParserErrors errors, MetaModels metaModels) { super(errors); primitivesConstraintParser = new PrimitivesConstraintParser(errors); this.metaModels = metaModels; + this.metaModel = null; + } + + public CComplexObjectParser(ANTLRParserErrors errors, MetaModel metaModel) { + super(errors); + primitivesConstraintParser = new PrimitivesConstraintParser(errors); + this.metaModels = null; + this.metaModel = metaModel; } public RulesSection parseRules(RulesSectionContext context) { @@ -158,6 +173,10 @@ private void parseOdinDefaultValue(CComplexObject parent, Default_valueContext d } private ObjectMapper getDefaultValueJsonObjectMapper() { + if(metaModel != null) { + return metaModel.getJsonObjectMapper(); + } + // For backwards compatiblity if(metaModels == null) { return null; } @@ -168,6 +187,10 @@ private ObjectMapper getDefaultValueJsonObjectMapper() { } private ObjectMapper getDefaultValueOdinObjectMapper() { + if(metaModel != null) { + return metaModel.getOdinInputObjectMapper(); + } + // For backwards compatiblity if(metaModels == null) { return null; } diff --git a/aom/src/main/java/com/nedap/archie/aom/CAttributeTuple.java b/aom/src/main/java/com/nedap/archie/aom/CAttributeTuple.java index 5618be9ff..3be731f89 100644 --- a/aom/src/main/java/com/nedap/archie/aom/CAttributeTuple.java +++ b/aom/src/main/java/com/nedap/archie/aom/CAttributeTuple.java @@ -1,12 +1,11 @@ package com.nedap.archie.aom; +import com.nedap.archie.rminfo.AttributeAccessor; import com.nedap.archie.rminfo.ModelInfoLookup; -import com.nedap.archie.rminfo.RMAttributeInfo; import javax.annotation.Nullable; import javax.xml.bind.annotation.XmlType; -import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -96,18 +95,14 @@ private boolean isValid(ModelInfoLookup lookup, CPrimitiveTuple tuple, HashMap members = new HashMap<>(); for(CAttribute attribute:getMembers()) { - RMAttributeInfo attributeInfo = lookup.getAttributeInfo(value.getClass(), attribute.getRmAttributeName()); - try { - if (attributeInfo != null && attributeInfo.getGetMethod() != null) { - members.put(attribute.getRmAttributeName(), attributeInfo.getGetMethod().invoke(value)); - } else { - //warn? throw exception? - } - } catch (InvocationTargetException | IllegalAccessException e) { - throw new RuntimeException(e); + String attributeName = attribute.getRmAttributeName(); + if (attributeAccessor.hasAttribute(value, attributeName)) { + members.put(attributeName, attributeAccessor.getValue(value, attributeName)); + } else { + //warn? throw exception? } } return isValid(lookup, members); diff --git a/aom/src/main/java/com/nedap/archie/aom/utils/AOMUtils.java b/aom/src/main/java/com/nedap/archie/aom/utils/AOMUtils.java index d328799dc..a1efef59e 100644 --- a/aom/src/main/java/com/nedap/archie/aom/utils/AOMUtils.java +++ b/aom/src/main/java/com/nedap/archie/aom/utils/AOMUtils.java @@ -445,7 +445,9 @@ public static boolean valueSetContainsCodeOrParent(Collection valueSetMe * Check if the parent attribute of the given CObject is a container attribute. * * @see MetaModelInterface#isMultiple(String, String) + * @deprecated Use {@link #parentIsMultiple(CObject, Archetype, MetaModel)} instead. */ + @Deprecated public static boolean parentIsMultiple(CObject cObject, Archetype flatParentArchetype, MetaModels metaModels) { if(cObject.getParent() != null) { @@ -464,4 +466,28 @@ public static boolean parentIsMultiple(CObject cObject, Archetype flatParentArch } return false; } + + /** + * Check if the parent attribute of the given CObject is a container attribute. + * + * @see MetaModel#isMultiple(String, String) + */ + public static boolean parentIsMultiple(CObject cObject, Archetype flatParentArchetype, MetaModel metaModel) { + if(cObject.getParent() != null) { + + CAttribute parent = cObject.getParent(); + CObject owningObject = parent.getParent(); + if (parent.getDifferentialPath() != null && flatParentArchetype != null) { + CAttribute attributeFromParent = (CAttribute) AOMUtils.getDifferentialPathFromParent(flatParentArchetype, parent); + if(attributeFromParent != null) { + owningObject = attributeFromParent.getParent(); + } + + } + if(owningObject != null) { + return metaModel.isMultiple(owningObject.getRmTypeName(), parent.getRmAttributeName()); + } + } + return false; + } } diff --git a/aom/src/main/java/com/nedap/archie/rminfo/AttributeAccessor.java b/aom/src/main/java/com/nedap/archie/rminfo/AttributeAccessor.java new file mode 100644 index 000000000..f67f57439 --- /dev/null +++ b/aom/src/main/java/com/nedap/archie/rminfo/AttributeAccessor.java @@ -0,0 +1,304 @@ +package com.nedap.archie.rminfo; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; + +/** + * This class provides access to the attributes of AOM and RM objects. + *

+ * In this class, attributes of type array (e.g. {@code byte[]}) are treated as single valued attributes. + */ +public class AttributeAccessor { + private final ModelInfoLookup modelInfoLookup; + + public AttributeAccessor(ModelInfoLookup modelInfoLookup) { + this.modelInfoLookup = Objects.requireNonNull(modelInfoLookup); + } + + /** + * Add value(s) to the given attribute in the given object. + *

+ * Will add the given value or values to the attribute using the {@link RMAttributeInfo#getAddMethod() add method} + * of the attribute if available. If the attribute does not have an add method, the value will be added by adding it + * to the collection obtained via the {@link RMAttributeInfo#getGetMethod() get method} or a new collection will be + * created via the {@link RMAttributeInfo#getSetMethod() set method} if the attribute is null. + * + * @param object Object to add the values to + * @param attributeName Name of the attribute of the object + * @param value A single value or {@link Collection} of values to add + * @throws IllegalArgumentException if the attribute is not a valid attribute of the object, the attribute is not + * a multiple valued attribute or the type of the value does not match the type of + * the attribute. + * @throws RuntimeException if the underlying add, get or set method throws an exception. + */ + public void addValue(Object object, String attributeName, Object value) throws IllegalArgumentException { + RMAttributeInfo attributeInfo = getAttributeInfo(object, attributeName); + + if (!attributeInfo.isMultipleValued() || attributeInfo.getType().isArray()) { + throw new IllegalArgumentException("Attribute " + attributeName + " of object " + object.getClass().getSimpleName() + " is not a multiple valued attribute"); + } + + Collection convertedValue = handleCollection(object, attributeInfo, Objects.requireNonNull(value, "value must not be null")); + + Method addMethod = attributeInfo.getAddMethod(); + if (addMethod != null) { + try { + for (Object v : convertedValue) { + addMethod.invoke(object, v); + } + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException( + "Error adding value to attribute " + attributeName + " of object " + object.getClass().getSimpleName(), + e + ); + } + } else { + @SuppressWarnings("unchecked") Collection attributeCollection = (Collection) getValue(object, attributeName); + if (attributeCollection == null) { + attributeCollection = newCollectionInstance(attributeInfo); + setValue(object, attributeName, attributeCollection); + } + attributeCollection.addAll(convertedValue); + } + } + + /** + * Add or set attribute value(s) in the given object. + *

+ * For single valued attributes, the value will be set, overwriting any existing value. This is equivalent to + * calling {@link #setValue(Object, String, Object)}. + *

+ * For multiple valued attributes, the value will be added to the existing values. This is equivalent to calling + * {@link #addValue(Object, String, Object)}. + * + * @param object Object to add the values to or set the attribute value of + * @param attributeName Name of the attribute of the object + * @param value Value(s) to add or set, or null to remove the value + * @throws IllegalArgumentException if the attribute is not a valid attribute of the object, the attribute is a + * read-only attribute, the type of the value does not match the type of the + * attribute or multiple values are assigned to a single valued attribute. + * @throws RuntimeException if the underlying add, get or set method throws an exception. + */ + public void addOrSetValue(Object object, String attributeName, Object value) throws IllegalArgumentException { + RMAttributeInfo attributeInfo = getAttributeInfo(object, attributeName); + + if (attributeInfo.isMultipleValued() && !attributeInfo.getType().isArray()) { + addValue(object, attributeName, value); + } else { + setValue(object, attributeName, value); + } + } + + /** + * Get attribute value in the given object. + *

+ * Will get the given value of the attribute using the {@link RMAttributeInfo#getGetMethod() get method} + * of the attribute. + * + * @param object Object to get the attribute value of + * @param attributeName Name of the attribute of the object + * @throws IllegalArgumentException if the attribute is not a valid attribute of the object. + * @throws RuntimeException if the underlying get method throws an exception. + */ + public Object getValue(Object object, String attributeName) throws IllegalArgumentException { + RMAttributeInfo attributeInfo = getAttributeInfo(object, attributeName); + + try { + return attributeInfo.getGetMethod().invoke(object); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException( + "Error getting value of attribute " + attributeName + " of object " + object.getClass().getSimpleName(), + e + ); + } + } + + /** + * Check that given object has an attribute of the given name. + * + * @param object Object to check the attribute of + * @param attributeName Name of the attribute of the object + * @return True if the given object has an attribute of the given name + */ + public boolean hasAttribute(Object object, String attributeName) { + return modelInfoLookup.getAttributeInfo( + Objects.requireNonNull(object, "object must not be null").getClass(), + Objects.requireNonNull(attributeName, "attributeName must not be null") + ) != null; + } + + /** + * Set attribute value(s) in the given object. + *

+ * Will set the given value or values to the attribute using the {@link RMAttributeInfo#getSetMethod() set method} + * of the attribute, overwriting any existing value. + *

+ * For single valued attributes, this method unwraps single values from a given {@link Collection}. + *

+ * For multiple valued attributes, this method wraps a single value in a new instance of the collection type. + * + * @param object Object to set the attribute value of + * @param attributeName Name of the attribute of the object + * @param value Value(s) to set, or null to remove the value + * @throws IllegalArgumentException if the attribute is not a valid attribute of the object, the attribute is a + * read-only attribute, the type of the value does not match the type of the + * attribute or multiple values are assigned to a single valued attribute. + * @throws RuntimeException if the underlying set method throws an exception. + */ + public void setValue(Object object, String attributeName, Object value) throws IllegalArgumentException { + RMAttributeInfo attributeInfo = getAttributeInfo(object, attributeName); + + Method setMethod = attributeInfo.getSetMethod(); + if (setMethod == null) { + throw new IllegalArgumentException( + "Attribute " + attributeName + " of object " + object.getClass().getSimpleName() + " is a read-only attribute" + ); + } + + Object convertedValue; + if (attributeInfo.isMultipleValued() && !attributeInfo.getType().isArray()) { + convertedValue = handleCollection(object, attributeInfo, value); + } else { + // Handle arrays (byte[]) as a single value + convertedValue = handleSingleValue(object, attributeInfo, value); + } + + try { + setMethod.invoke(object, convertedValue); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException( + "Error setting value on attribute " + attributeName + " of object " + object.getClass().getSimpleName(), + e + ); + } + } + + /** + * Get attribute info for the given object and attribute name. + * + * @param object Object to get the attribute info of + * @param attributeName Name of the attribute of the object + * @return Attribute info object + * @throws NullPointerException if the object or attribute name is null. + * @throws IllegalArgumentException if the attribute is not a valid attribute of the object. + */ + private RMAttributeInfo getAttributeInfo(Object object, String attributeName) { + RMAttributeInfo attributeInfo = modelInfoLookup.getAttributeInfo( + Objects.requireNonNull(object, "object must not be null").getClass(), + Objects.requireNonNull(attributeName, "attributeName must not be null") + ); + if (attributeInfo == null) { + throw new IllegalArgumentException( + "Attribute " + attributeName + " of object " + object.getClass().getSimpleName() + " is not a valid attribute" + ); + } + return attributeInfo; + } + + /** + * Validate and convert the given value for assignment to a multiple valued (collection) attribute. + *

+ * Non-collection values will be wrapped in a collection. + * + * @param object Object to set the attribute value of (for exception message) + * @param attributeInfo Attribute info object + * @param value value to validate and convert + * @return converted value or null if the given value is null + * @throws IllegalArgumentException if the given value is not assignable to the attribute type or multiple values + * are assigned to a single valued attribute + */ + private Collection handleCollection(Object object, RMAttributeInfo attributeInfo, Object value) + throws IllegalArgumentException { + String attributeName = attributeInfo.getRmName(); + Class typeInCollection = attributeInfo.getTypeInCollection(); + Collection collection; + + if (value == null) { + collection = null; + } else if (value instanceof Collection) { + collection = (Collection) value; + validateType(object, attributeName, collection, attributeInfo.getType()); + + for (Object element : collection) { + validateType(object, attributeName, element, typeInCollection); + } + } else { + validateType(object, attributeName, value, typeInCollection); + List newCollection = newCollectionInstance(attributeInfo); + newCollection.add(value); + collection = newCollection; + } + + return collection; + } + + /** + * Validate and convert the given value for assignment to a single valued attribute. + *

+ * Single valued attributes include byte arrays. + *

+ * This will unpack a collection with zero or one elements. + * + * @param object Object to set the attribute value of (for exception message) + * @param attributeInfo Attribute info object + * @param value value to validate and convert + * @return converted value or null if the given value is null or an empty collection + * @throws IllegalArgumentException if the given value is not assignable to the attribute type or the value is a + * collection with multiple elements. + */ + private Object handleSingleValue(Object object, RMAttributeInfo attributeInfo, Object value) + throws IllegalArgumentException { + if (value instanceof Collection) { + Collection collection = (Collection) value; + if (collection.size() > 1) { + throw new IllegalArgumentException( + "Attribute " + attributeInfo.getRmName() + " of object " + object.getClass().getSimpleName() + " does not support multiple values" + ); + } + value = collection.isEmpty() ? null : collection.iterator().next(); + } + + validateType(object, attributeInfo.getRmName(), value, attributeInfo.getType()); + return value; + } + + /** + * Validate that the given value is assignable to the given type. + * + * @param object Object to set the attribute value of (for exception message) + * @param attributeName Name of the attribute of the object (for exception message) + * @param value Value to check the type of + * @param type The required type for the value + * @throws IllegalArgumentException if the given value is not assignable to the given type. + */ + private void validateType(Object object, String attributeName, Object value, Class type) + throws IllegalArgumentException { + if (value != null && !type.isAssignableFrom(value.getClass())) { + throw new IllegalArgumentException( + "Value type " + value.getClass().getTypeName() + " is not a valid type for attribute " + attributeName + " of object " + object.getClass().getSimpleName() + ); + } + } + + /** + * Create new collection instance for the given attribute. + *

+ * Assumes the collection type is List. + * + * @param attributeInfo Attribute info object + * @return Empty list + * @throws IllegalArgumentException if the attribute type is not List. + */ + private List newCollectionInstance(RMAttributeInfo attributeInfo) throws IllegalArgumentException { + Class type = attributeInfo.getType(); + if (type.equals(List.class)) { + return new ArrayList<>(); + } else { + throw new IllegalArgumentException("Unknown collection type " + type.getTypeName()); + } + } +} diff --git a/aom/src/main/java/com/nedap/archie/rminfo/MetaModel.java b/aom/src/main/java/com/nedap/archie/rminfo/MetaModel.java index 2a8bae9d4..d8277f198 100644 --- a/aom/src/main/java/com/nedap/archie/rminfo/MetaModel.java +++ b/aom/src/main/java/com/nedap/archie/rminfo/MetaModel.java @@ -111,6 +111,10 @@ public ObjectMapper getJsonObjectMapper() { return jsonObjectMapper; } + /** + * determine if a property on a type is multiple or not. If the property cannot be found, returns false. + * Works both on properties on a type, or on path based lookup. + */ @Override public boolean isMultiple(String typeName, String attributeNameOrPath) { MultiplicityInterval multiplicityInterval = referenceModelPropMultiplicity(typeName, attributeNameOrPath); diff --git a/aom/src/main/java/com/nedap/archie/rminfo/MetaModelInterface.java b/aom/src/main/java/com/nedap/archie/rminfo/MetaModelInterface.java index 1dbda1879..ac4dccb2f 100644 --- a/aom/src/main/java/com/nedap/archie/rminfo/MetaModelInterface.java +++ b/aom/src/main/java/com/nedap/archie/rminfo/MetaModelInterface.java @@ -3,6 +3,10 @@ import com.nedap.archie.aom.CPrimitiveObject; import com.nedap.archie.base.MultiplicityInterval; +/** + * @deprecated Use {@link MetaModel} instead. + */ +@Deprecated public interface MetaModelInterface { /** * determine if a property on a type is multiple or not. If the property cannot be found, returns false. diff --git a/aom/src/main/java/com/nedap/archie/rminfo/MetaModelProvider.java b/aom/src/main/java/com/nedap/archie/rminfo/MetaModelProvider.java new file mode 100644 index 000000000..a34584847 --- /dev/null +++ b/aom/src/main/java/com/nedap/archie/rminfo/MetaModelProvider.java @@ -0,0 +1,75 @@ +package com.nedap.archie.rminfo; + +import com.nedap.archie.aom.Archetype; + +/** + * A provider for meta models, which can be used to retrieve the meta model for a specific reference model based on an + * archetype or reference model publisher, package and release version. + */ +public interface MetaModelProvider { + /** + * Get a meta model based on an archetype. + * + * @param archetype the archetype to find the meta model for + * @return the meta model for the reference model that the archetype is based on + * @throws ModelNotFoundException when no BMM and no ModelInfoLookup model has been found matching the archetype + */ + public default MetaModel getMetaModel(Archetype archetype) throws ModelNotFoundException { + return getMetaModel(archetype, archetype.getRmRelease()); + } + + /** + * Get a meta model based on an archetype, but override the RM release version from the archetype with the given RM + * release version. + * + * @param archetype the archetype to find the meta model for + * @param rmRelease the release version of the reference model. This will override the RM release version in the + * archetype. + * @return the meta model for the reference model that the archetype is based on + * @throws ModelNotFoundException when no BMM and no ModelInfoLookup model has been found matching the archetype and + * RM version + */ + public default MetaModel getMetaModel(Archetype archetype, String rmRelease) throws ModelNotFoundException { + return getMetaModel( + archetype.getArchetypeId().getRmPublisher(), + archetype.getArchetypeId().getRmPackage(), + rmRelease + ); + } + + /** + * Get a model based on a reference model publisher, package and release version. + * + * @param rmPublisher the publisher of the reference model + * @param rmPackage the package of the reference model + * @param rmRelease the release version of the reference model + * @return the meta model + * @throws ModelNotFoundException when no BMM and no ModelInfoLookup model has been found matching the publisher, + * package and release version + */ + public abstract MetaModel getMetaModel(String rmPublisher, String rmPackage, String rmRelease) throws ModelNotFoundException; + + /** + * @deprecated For backwards compatibility only. Use {@link #getMetaModel(Archetype)} instead. + */ + @Deprecated + public default MetaModel selectAndGetMetaModel(Archetype archetype) throws ModelNotFoundException { + return getMetaModel(archetype); + } + + /** + * @deprecated For backwards compatibility only. Use {@link #getMetaModel(Archetype, String)} instead. + */ + @Deprecated + public default MetaModel selectAndGetMetaModel(Archetype archetype, String rmVersion) throws ModelNotFoundException { + return getMetaModel(archetype, rmVersion); + } + + /** + * @deprecated For backwards compatibility only. Use {@link #getMetaModel(String, String, String)} instead. + */ + @Deprecated + public default MetaModel selectAndGetMetaModel(String rmPublisher, String rmPackage, String rmRelease) throws ModelNotFoundException { + return getMetaModel(rmPublisher, rmPackage, rmRelease); + } +} diff --git a/aom/src/main/java/com/nedap/archie/rminfo/MetaModels.java b/aom/src/main/java/com/nedap/archie/rminfo/MetaModels.java index 56d80e63d..eb491715e 100644 --- a/aom/src/main/java/com/nedap/archie/rminfo/MetaModels.java +++ b/aom/src/main/java/com/nedap/archie/rminfo/MetaModels.java @@ -6,12 +6,7 @@ import com.nedap.archie.aom.profile.AomProfiles; import com.nedap.archie.base.MultiplicityInterval; import org.openehr.bmm.core.BmmModel; -import org.openehr.bmm.persistence.validation.BmmDefinitions; import org.openehr.bmm.v2.validation.BmmRepository; -import org.openehr.bmm.v2.validation.BmmValidationResult; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; /** * MetaModel class that provides some opertaions for archetype validation and flattener that is either based on @@ -27,32 +22,28 @@ * * Note that this class is NOT thread-safe and is to be used by a single thread only. * + * @deprecated Use {@link SimpleMetaModelProvider}, {@link OverridingMetaModelProvider} or {@link MetaModel} instead. */ -public class MetaModels implements MetaModelInterface { - +@Deprecated +public class MetaModels implements MetaModelInterface, MetaModelProvider { private final ReferenceModels models; private final BmmRepository bmmRepository; - private AomProfiles aomProfiles; + private final AomProfiles aomProfiles; + private final OverridingMetaModelProvider overridingMetaModelProvider; private MetaModel selectedModel; - private AomProfile selectedAomProfile; - - /** - * Allows to set a specific RM version for a specific RM model, so that one is used instead of the one in the archetype - */ - private Map overriddenMetaModelVersions = new ConcurrentHashMap<>(); - public MetaModels(ReferenceModels models, BmmRepository repository) { - this.models = models; - this.bmmRepository = repository; - aomProfiles = new AomProfiles(); + this(models, repository, new AomProfiles()); } public MetaModels(ReferenceModels models, BmmRepository repository, AomProfiles profiles) { this.models = models; this.bmmRepository = repository; aomProfiles = profiles; + this.overridingMetaModelProvider = new OverridingMetaModelProvider( + new SimpleMetaModelProvider(models, repository, profiles) + ); } /** @@ -64,10 +55,7 @@ public MetaModels(ReferenceModels models, BmmRepository repository, AomProfiles * @param version the version that should be chosen */ public void overrideModelVersion(String rmPublisher, String rmPackage, String version) { - this.overriddenMetaModelVersions.put( - BmmDefinitions.publisherQualifiedRmClosureName(rmPublisher, rmPackage), - version - ); + overridingMetaModelProvider.overrideModelVersion(rmPublisher, rmPackage, version); } /** @@ -76,12 +64,47 @@ public void overrideModelVersion(String rmPublisher, String rmPackage, String ve * @param rmPackage the RM Package to remove the model version for */ public void removeOverridenModelVersion(String rmPublisher, String rmPackage) { - this.overriddenMetaModelVersions.remove(BmmDefinitions.publisherQualifiedRmClosureName(rmPublisher, rmPackage)); + overridingMetaModelProvider.removeOverridenModelVersion(rmPublisher, rmPackage); } - public String getOverriddenModelVersion(String rmPublisher, String rmPackage) { - return this.overriddenMetaModelVersions.get(BmmDefinitions.publisherQualifiedRmClosureName(rmPublisher, rmPackage)); + return overridingMetaModelProvider.getOverriddenModelVersion(rmPublisher, rmPackage); + } + + @Override + public MetaModel getMetaModel(Archetype archetype) throws ModelNotFoundException { + return overridingMetaModelProvider.getMetaModel(archetype); + } + + @Override + public MetaModel getMetaModel(Archetype archetype, String rmVersion) throws ModelNotFoundException { + return overridingMetaModelProvider.getMetaModel(archetype, rmVersion); + } + + @Override + public MetaModel getMetaModel(String rmPublisher, String rmPackage, String rmRelease) throws ModelNotFoundException { + return overridingMetaModelProvider.getMetaModel(rmPublisher, rmPackage, rmRelease); + } + + @Override + public MetaModel selectAndGetMetaModel(Archetype archetype) throws ModelNotFoundException { + MetaModel result = getMetaModel(archetype); + this.selectedModel = result; + return result; + } + + @Override + public MetaModel selectAndGetMetaModel(Archetype archetype, String rmVersion) throws ModelNotFoundException { + MetaModel result = getMetaModel(archetype, rmVersion); + this.selectedModel = result; + return result; + } + + @Override + public MetaModel selectAndGetMetaModel(String rmPublisher, String rmPackage, String rmRelease) throws ModelNotFoundException { + MetaModel result = getMetaModel(rmPublisher, rmPackage, rmRelease); + this.selectedModel = result; + return result; } /** @@ -90,8 +113,7 @@ public String getOverriddenModelVersion(String rmPublisher, String rmPackage) { * @throws ModelNotFoundException when no BMM and no ModelInfoLookup model has been found matching the archetype */ public void selectModel(Archetype archetype) throws ModelNotFoundException { ; - String overriddenVersion = getOverriddenModelVersion(archetype.getArchetypeId().getRmPublisher(), archetype.getArchetypeId().getRmPackage()); - selectModel(archetype, overriddenVersion == null ? archetype.getRmRelease(): overriddenVersion); + selectAndGetMetaModel(archetype); } /** @@ -101,7 +123,7 @@ public String getOverriddenModelVersion(String rmPublisher, String rmPackage) { * @throws ModelNotFoundException */ public void selectModel(Archetype archetype, String rmVersion) throws ModelNotFoundException { ; - selectModel(archetype.getArchetypeId().getRmPublisher(), archetype.getArchetypeId().getRmPackage(), rmVersion); + selectAndGetMetaModel(archetype, rmVersion); } /** @@ -113,48 +135,7 @@ public String getOverriddenModelVersion(String rmPublisher, String rmPackage) { * @throws ModelNotFoundException */ public void selectModel(String rmPublisher, String rmPackage, String rmRelease) throws ModelNotFoundException { - ModelInfoLookup selectedModel = null; - BmmModel selectedBmmModel = null; - RMObjectMapperProvider objectMapperProvider = null; - if(models != null) { - selectedModel = models.getModel(rmPublisher, rmPackage); - objectMapperProvider = models.getRmObjectMapperProvider(rmPublisher, rmPackage); - } - if(bmmRepository != null) { - BmmValidationResult validationResult = bmmRepository.getModelByClosure(BmmDefinitions.publisherQualifiedRmClosureName(rmPublisher, rmPackage) + "_" + rmRelease); - selectedBmmModel = validationResult == null ? null : validationResult.getModel(); - } - - this.selectedAomProfile = getAomProfileWithSchemaId(selectedBmmModel); - if(this.selectedAomProfile == null) { - this.selectedAomProfile = getAomProfileOnPublisher(rmPublisher); - } - - if(selectedModel == null && selectedBmmModel == null) { - throw new ModelNotFoundException(String.format("model for %s.%s version %s not found", rmPublisher, rmPackage, rmRelease)); - } - this.selectedModel = new MetaModel(selectedModel, selectedBmmModel, selectedAomProfile, objectMapperProvider); - - } - - private AomProfile getAomProfileWithSchemaId(BmmModel selectedBmmModel) { - if(selectedBmmModel != null) { - for (AomProfile profile : aomProfiles.getProfiles()) { - if (profile.getRmSchemaPattern().stream().anyMatch(pat -> selectedBmmModel.getSchemaId().matches(pat))) { - return profile; - } - } - } - return null; - } - - private AomProfile getAomProfileOnPublisher(String rmPublisher) { - for(AomProfile profile:aomProfiles.getProfiles()) { - if(profile.getProfileName().equalsIgnoreCase(rmPublisher)) { - return profile; - } - } - return null; + selectAndGetMetaModel(rmPublisher, rmPackage, rmRelease); } public ModelInfoLookup getSelectedModelInfoLookup() { @@ -242,7 +223,7 @@ public AomProfiles getAomProfiles() { } public AomProfile getSelectedAomProfile() { - return selectedAomProfile; + return selectedModel == null ? null : selectedModel.getAomProfile(); } diff --git a/aom/src/main/java/com/nedap/archie/rminfo/NoModelSelectedException.java b/aom/src/main/java/com/nedap/archie/rminfo/NoModelSelectedException.java index 2d09f3a64..2b85122e1 100644 --- a/aom/src/main/java/com/nedap/archie/rminfo/NoModelSelectedException.java +++ b/aom/src/main/java/com/nedap/archie/rminfo/NoModelSelectedException.java @@ -1,5 +1,9 @@ package com.nedap.archie.rminfo; +/** + * @deprecated This class will be removed. + */ +@Deprecated public class NoModelSelectedException extends RuntimeException { public NoModelSelectedException(String message) { diff --git a/aom/src/main/java/com/nedap/archie/rminfo/OverridingMetaModelProvider.java b/aom/src/main/java/com/nedap/archie/rminfo/OverridingMetaModelProvider.java new file mode 100644 index 000000000..e86ac527c --- /dev/null +++ b/aom/src/main/java/com/nedap/archie/rminfo/OverridingMetaModelProvider.java @@ -0,0 +1,84 @@ +package com.nedap.archie.rminfo; + +import com.nedap.archie.aom.Archetype; +import org.openehr.bmm.persistence.validation.BmmDefinitions; + +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +/** + * A MetaModelProvider that allows to override the RM release version for a specific RM publisher and package. + *

+ * When the RM release version is overridden for a specific RM publisher and package, the overridden version will be + * used by the {@link #getMetaModel(Archetype)} method to retrieve the meta model. + */ +public class OverridingMetaModelProvider implements MetaModelProvider { + private final MetaModelProvider delegate; + + /** + * Allows to set a specific RM release version for a specific RM model, so that one is used instead of the one in + * the archetype. + */ + private final Map overriddenMetaModelVersions = new ConcurrentHashMap<>(); + + /** + * Create an OverridingMetaModelProvider that delegates to the given MetaModelProvider. + * + * @param delegate the MetaModelProvider to delegate to + */ + public OverridingMetaModelProvider(MetaModelProvider delegate) { + this.delegate = Objects.requireNonNull(delegate, "delegate must not be null"); + } + + /** + * Indicate that the model version for the given package by the given publisher should be fixed + * to a specific version. Useful for validating archetypes against new RM versions, for example OpenEHR + * RM 1.0.2 archetypes against 1.0.4. + * + * @param rmPublisher the publisher of the RM + * @param rmPackage the package of the RM to override the version for + * @param overridingRmRelease the version that should be chosen + */ + public void overrideModelVersion(String rmPublisher, String rmPackage, String overridingRmRelease) { + overriddenMetaModelVersions.put( + BmmDefinitions.publisherQualifiedRmClosureName(rmPublisher, rmPackage), + overridingRmRelease + ); + } + + /** + * Remove the overriden model version for the given publisher and package. + * + * @param rmPublisher the publisher of the package + * @param rmPackage the RM Package to remove the model version for + */ + public void removeOverridenModelVersion(String rmPublisher, String rmPackage) { + overriddenMetaModelVersions.remove(BmmDefinitions.publisherQualifiedRmClosureName(rmPublisher, rmPackage)); + } + + /** + * Get the overriden model version for the given package, if any. + * + * @param rmPublisher the publisher of the package + * @param rmPackage the RM Package to remove the model version for + * @return the overridden model version, or null if no override has been set + */ + public String getOverriddenModelVersion(String rmPublisher, String rmPackage) { + return overriddenMetaModelVersions.get(BmmDefinitions.publisherQualifiedRmClosureName(rmPublisher, rmPackage)); + } + + @Override + public MetaModel getMetaModel(Archetype archetype) throws ModelNotFoundException { + String overriddenVersion = getOverriddenModelVersion( + archetype.getArchetypeId().getRmPublisher(), + archetype.getArchetypeId().getRmPackage() + ); + return getMetaModel(archetype, overriddenVersion == null ? archetype.getRmRelease() : overriddenVersion); + } + + @Override + public MetaModel getMetaModel(String rmPublisher, String rmPackage, String rmRelease) throws ModelNotFoundException { + return delegate.getMetaModel(rmPublisher, rmPackage, rmRelease); + } +} diff --git a/aom/src/main/java/com/nedap/archie/rminfo/SimpleMetaModelProvider.java b/aom/src/main/java/com/nedap/archie/rminfo/SimpleMetaModelProvider.java new file mode 100644 index 000000000..442803619 --- /dev/null +++ b/aom/src/main/java/com/nedap/archie/rminfo/SimpleMetaModelProvider.java @@ -0,0 +1,98 @@ +package com.nedap.archie.rminfo; + +import com.nedap.archie.aom.profile.AomProfile; +import com.nedap.archie.aom.profile.AomProfiles; +import org.openehr.bmm.core.BmmModel; +import org.openehr.bmm.persistence.validation.BmmDefinitions; +import org.openehr.bmm.v2.validation.BmmRepository; +import org.openehr.bmm.v2.validation.BmmValidationResult; + +import java.util.Objects; + +/** + * A simple implementation of the MetaModelProvider interface that retrieves meta models from either a ReferenceModels + * instance or a BmmRepository. It also supports AOM profiles. + */ +public class SimpleMetaModelProvider implements MetaModelProvider { + private final ReferenceModels referenceModels; + private final BmmRepository bmmRepository; + private final AomProfiles aomProfiles; + + /** + * Create a SimpleMetaModelProvider that retrieves meta models from the given ReferenceModels and BmmRepository. + * + * @param referenceModels the ReferenceModels to use for retrieving meta models or null + * @param bmmRepository the BmmRepository to use for retrieving BMM models or null + * @throws IllegalArgumentException if both referenceModels and bmmRepository are null + */ + public SimpleMetaModelProvider(ReferenceModels referenceModels, BmmRepository bmmRepository) { + this(referenceModels, bmmRepository, new AomProfiles()); + } + + /** + * Create a SimpleMetaModelProvider that retrieves meta models from the given ReferenceModels, BmmRepository, and + * AomProfiles. + * + * @param referenceModels the ReferenceModels to use for retrieving meta models or null + * @param bmmRepository the BmmRepository to use for retrieving BMM models or null + * @param aomProfiles the AomProfiles to use for retrieving AOM profiles + * @throws IllegalArgumentException if both referenceModels and bmmRepository are null + */ + public SimpleMetaModelProvider(ReferenceModels referenceModels, BmmRepository bmmRepository, AomProfiles aomProfiles) { + if (referenceModels == null && bmmRepository == null) { + throw new IllegalArgumentException("Either referenceModels or bmmRepository must be provided"); + } + this.referenceModels = referenceModels; + this.bmmRepository = bmmRepository; + this.aomProfiles = Objects.requireNonNull(aomProfiles, "aomProfiles must not be null"); + } + + @Override + public MetaModel getMetaModel(String rmPublisher, String rmPackage, String rmRelease) throws ModelNotFoundException { + ModelInfoLookup modelInfoLookup = null; + BmmModel bmmModel = null; + RMObjectMapperProvider objectMapperProvider = null; + if (referenceModels != null) { + modelInfoLookup = referenceModels.getModel(rmPublisher, rmPackage); + objectMapperProvider = referenceModels.getRmObjectMapperProvider(rmPublisher, rmPackage); + } + if (bmmRepository != null) { + BmmValidationResult validationResult = bmmRepository.getModelByClosure( + BmmDefinitions.publisherQualifiedRmClosureName(rmPublisher, rmPackage) + "_" + rmRelease + ); + bmmModel = validationResult == null ? null : validationResult.getModel(); + } + + AomProfile aomProfile = getAomProfileWithSchemaId(bmmModel); + if (aomProfile == null) { + aomProfile = getAomProfileOnPublisher(rmPublisher); + } + + if (modelInfoLookup == null && bmmModel == null) { + throw new ModelNotFoundException( + String.format("model for %s.%s version %s not found", rmPublisher, rmPackage, rmRelease) + ); + } + return new MetaModel(modelInfoLookup, bmmModel, aomProfile, objectMapperProvider); + } + + private AomProfile getAomProfileWithSchemaId(BmmModel bmmModel) { + if (bmmModel != null) { + for (AomProfile profile : aomProfiles.getProfiles()) { + if (profile.getRmSchemaPattern().stream().anyMatch(pat -> bmmModel.getSchemaId().matches(pat))) { + return profile; + } + } + } + return null; + } + + private AomProfile getAomProfileOnPublisher(String rmPublisher) { + for (AomProfile profile : aomProfiles.getProfiles()) { + if (profile.getProfileName().equalsIgnoreCase(rmPublisher)) { + return profile; + } + } + return null; + } +} diff --git a/aom/src/main/java/com/nedap/archie/xml/adapters/LifecycleStateXmlAdapter.java b/aom/src/main/java/com/nedap/archie/xml/adapters/LifecycleStateXmlAdapter.java new file mode 100644 index 000000000..8aa02a030 --- /dev/null +++ b/aom/src/main/java/com/nedap/archie/xml/adapters/LifecycleStateXmlAdapter.java @@ -0,0 +1,86 @@ +package com.nedap.archie.xml.adapters; + +import com.nedap.archie.base.terminology.TerminologyCode; +import org.w3c.dom.Element; + +import javax.xml.bind.annotation.XmlAnyElement; +import javax.xml.bind.annotation.XmlMixed; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.adapters.XmlAdapter; +import java.util.List; + +/** + * JAXB adapter for deserializing lifecycle_state from XML. + *

+ * Supports two XML representations: + * 1. Future/simple text form: {@code published} + * 2. Current form of type terminology_code with a code_string: {@code published} + * + * The adapter always returns the lifecycle state value as a terminology_code with a code_string value, regardless of the input format. + */ +public class LifecycleStateXmlAdapter extends XmlAdapter { + + /** + * Unmarshalls a lifecycle_state element to a terminology_code. + * + * @param holder the mixed content holder containing the element's content + * @return the lifecycle_state value as a terminology_code, or null if no value is found + */ + @Override + public TerminologyCode unmarshal(MixedHolder holder) { + if (holder == null || holder.content == null || holder.content.isEmpty()) { + return null; + } + + TerminologyCode resultTerminologyCode = new TerminologyCode(); + + for (Object o : holder.content) { + if (o instanceof Element) { + Element element = (Element) o; + String elementName = element.getLocalName() != null ? element.getLocalName() : element.getNodeName(); + + if ("code_string".equals(elementName)) { + String text = element.getTextContent(); + if (text != null) { + resultTerminologyCode.setCodeString(text.trim()); + return resultTerminologyCode; + } + } + } + } + + for (Object o : holder.content) { + if (o instanceof String) { + String text = ((String) o).trim(); + if (!text.isEmpty()) { + resultTerminologyCode.setCodeString(text.trim()); + return resultTerminologyCode; + } + } + } + + return null; + } + + /** + * Not implemented for this adapter as marshaling is not required. + */ + @Override + public MixedHolder marshal(TerminologyCode v) { + return null; + } + + /** + * Holder class for mixed XML content (text and elements). + *

+ * Used by JAXB to capture both text nodes and child elements within the + * lifecycle_state element. The content list may include whitespace strings + * (from XML formatting) and Element objects. + */ + @XmlRootElement(name = "lifecycle_state") + public static class MixedHolder { + @XmlMixed + @XmlAnyElement(lax = true) + public List content; + } +} \ No newline at end of file diff --git a/aom/src/main/java/com/nedap/archie/xml/types/XmlResourceDescription.java b/aom/src/main/java/com/nedap/archie/xml/types/XmlResourceDescription.java index 976ed0321..8fb5d8c7f 100644 --- a/aom/src/main/java/com/nedap/archie/xml/types/XmlResourceDescription.java +++ b/aom/src/main/java/com/nedap/archie/xml/types/XmlResourceDescription.java @@ -1,11 +1,13 @@ package com.nedap.archie.xml.types; import com.nedap.archie.base.terminology.TerminologyCode; +import com.nedap.archie.xml.adapters.LifecycleStateXmlAdapter; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import java.util.List; /** @@ -24,6 +26,7 @@ public class XmlResourceDescription { @XmlElement(name = "other_contributors") private List otherContributors; @XmlElement(name = "lifecycle_state", required = true) + @XmlJavaTypeAdapter(LifecycleStateXmlAdapter.class) private TerminologyCode lifecycleState; @XmlElement(name="custodian_namespace") private String custodianNamespace; diff --git a/aom/src/test/java/com/nedap/archie/rminfo/AttributeAccessorTest.java b/aom/src/test/java/com/nedap/archie/rminfo/AttributeAccessorTest.java new file mode 100644 index 000000000..21c773487 --- /dev/null +++ b/aom/src/test/java/com/nedap/archie/rminfo/AttributeAccessorTest.java @@ -0,0 +1,1021 @@ +package com.nedap.archie.rminfo; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.nedap.archie.aom.Archetype; +import com.nedap.archie.aom.CObject; +import com.nedap.archie.aom.CPrimitiveObject; +import org.junit.Test; + +import java.util.*; + +import static org.junit.Assert.*; + +public class AttributeAccessorTest { + private static final ModelInfoLookup modelInfoLookup = new LocalClassInfoLookup(); + private static final AttributeAccessor attributeAccessor = new AttributeAccessor(modelInfoLookup); + + private static class Dummy { + } + + @SuppressWarnings("unused") + private static class Thing { + private String name; + + private byte[] data; + + public Thing() { + } + + public Thing(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public byte[] getData() { + return data; + } + + public void setData(byte[] data) { + this.data = data; + } + + public int getFour() { + // Read-only attribute + return 4; + } + } + + @SuppressWarnings("unused") + private static class Group { + private List subgroups = new ArrayList<>(); + + private List things = new ArrayList<>(); + + private Thing mainThing; + + public List getSubgroups() { + return subgroups; + } + + public void setSubgroups(List subgroups) { + this.subgroups = subgroups; + } + + public List getThings() { + return things; + } + + public void setThings(List things) { + this.things = things; + } + + public void addThing(Thing thing) { + if (things == null) { + things = new ArrayList<>(); + } + this.things.add(thing); + } + + public Thing getMainThing() { + return mainThing; + } + + public void setMainThing(Thing mainThing) { + this.mainThing = mainThing; + } + } + + @SuppressWarnings({"unused", "FieldMayBeFinal"}) + private static class BrokenClass { + // This single valued attribute throws an exception when accessed + private BrokenClass child; + + // This multiple valued attribute throws an exception when accessed + private List items = new ArrayList<>(); + + private Set someSet = new HashSet<>(); + + public BrokenClass getChild() { + throw new RuntimeException("Some exception"); + } + + public void setChild(BrokenClass child) { + throw new RuntimeException("Some exception"); + } + + public List getItems() { + throw new RuntimeException("Some exception"); + } + + public void setItems(List values) { + throw new RuntimeException("Some exception"); + } + + public void addItem(BrokenClass value) { + throw new RuntimeException("Some exception"); + } + + public Set getSomeSet() { + return someSet; + } + + public void setSomeSet(Set values) { + this.someSet = values; + } + + public void addSomeSet(BrokenClass value) { + this.someSet.add(value); + } + } + + public static class LocalClassInfoLookup extends ReflectionModelInfoLookup { + private LocalClassInfoLookup() { + super(new ArchieModelNamingStrategy(), Object.class); + } + + @Override + protected void addTypes(Class baseClass) { + addClass(Thing.class); + addClass(Group.class); + addClass(BrokenClass.class); + } + + @Override + public void processCreatedObject(Object createdObject, CObject constraint) { + // Do nothing + } + + @Override + public String getArchetypeNodeIdFromRMObject(Object rmObject) { + return null; + } + + @Override + public String getArchetypeIdFromArchetypedRmObject(Object rmObject) { + return null; + } + + @Override + public String getNameFromRMObject(Object rmObject) { + return null; + } + + @Override + public Object clone(Object rmObject) { + throw new UnsupportedOperationException(); + } + + @Override + public Map pathHasBeenUpdated(Object rmObject, Archetype archetype, String pathOfParent, Object parent) { + return new HashMap<>(); + } + + @Override + public boolean validatePrimitiveType(String rmTypeName, String rmAttributeName, CPrimitiveObject cObject) { + return false; + } + + @Override + public Collection getId() { + return Lists.newArrayList(new RMPackageId("openEHR", "BROKEN")); + } + } + + public static class AddValue { + + @Test + public void testMultipleValuedSingle() { + Group group = new Group(); + Thing thing1 = new Thing(); + Thing thing2 = new Thing(); + group.setThings(Lists.newArrayList(thing1, thing2)); + + Thing thing3 = new Thing(); + + attributeAccessor.addValue(group, "things", thing3); + + assertEquals(3, group.getThings().size()); + assertSame(thing1, group.getThings().get(0)); + assertSame(thing2, group.getThings().get(1)); + assertSame(thing3, group.getThings().get(2)); + } + + @Test + public void testMultipleValuedNull() { + Group group = new Group(); + group.setThings(Lists.newArrayList(new Thing(), new Thing())); + + NullPointerException exception = assertThrows(NullPointerException.class, () -> attributeAccessor.addValue(group, "things", null)); + assertEquals("value must not be null", exception.getMessage()); + + assertEquals(2, group.getThings().size()); + } + + @Test + public void testMultipleValuedListIntialEmpty() { + Group group = new Group(); + + Thing thing1 = new Thing(); + Thing thing2 = new Thing(); + List newThings = Lists.newArrayList(thing1, thing2); + + attributeAccessor.addValue(group, "things", newThings); + + assertNotSame("A new collection should be created", newThings, group.getThings()); + assertEquals(2, group.getThings().size()); + assertSame(thing1, group.getThings().get(0)); + assertSame(thing2, group.getThings().get(1)); + } + + @Test + public void testMultipleValuedListIntialNull() { + Group group = new Group(); + group.setThings(null); + + Thing thing1 = new Thing(); + Thing thing2 = new Thing(); + List newThings = Lists.newArrayList(thing1, thing2); + + attributeAccessor.addValue(group, "things", newThings); + + assertNotSame("A new collection should be created", newThings, group.getThings()); + assertEquals(2, group.getThings().size()); + assertSame(thing1, group.getThings().get(0)); + assertSame(thing2, group.getThings().get(1)); + } + + @Test + public void testMultipleValuedListIntialFilled() { + Group group = new Group(); + Thing thing1 = new Thing(); + Thing thing2 = new Thing(); + group.setThings(Lists.newArrayList(thing1, thing2)); + + Thing thing3 = new Thing(); + Thing thing4 = new Thing(); + List newThings = Lists.newArrayList(thing3, thing4); + + attributeAccessor.addValue(group, "things", newThings); + + assertEquals(4, group.getThings().size()); + assertSame(thing1, group.getThings().get(0)); + assertSame(thing2, group.getThings().get(1)); + assertSame(thing3, group.getThings().get(2)); + assertSame(thing4, group.getThings().get(3)); + } + + @Test + public void testMultipleValuedListEmpty() { + Group group = new Group(); + Thing thing1 = new Thing(); + Thing thing2 = new Thing(); + group.setThings(Lists.newArrayList(thing1, thing2)); + + attributeAccessor.addValue(group, "things", Collections.emptyList()); + + assertEquals(2, group.getThings().size()); + assertSame(thing1, group.getThings().get(0)); + assertSame(thing2, group.getThings().get(1)); + } + + @Test + public void testMultipleValuedListNull() { + Group group = new Group(); + Thing thing1 = new Thing(); + Thing thing2 = new Thing(); + group.setThings(Lists.newArrayList(thing1, thing2)); + + attributeAccessor.addValue(group, "things", Collections.singletonList(null)); + + assertEquals(3, group.getThings().size()); + assertSame(thing1, group.getThings().get(0)); + assertSame(thing2, group.getThings().get(1)); + assertNull(group.getThings().get(2)); + } + + @Test + public void testMultipleValuedFallback() { + // Group has no addSubgroup method + Group group = new Group(); + group.setSubgroups(null); + + Group subgroup1 = new Group(); + Group subgroup2 = new Group(); + List newSubgroups = Lists.newArrayList(subgroup1, subgroup2); + + attributeAccessor.addValue(group, "subgroups", newSubgroups); + + assertNotSame("A new collection should be created", newSubgroups, group.getSubgroups()); + assertEquals(2, group.getSubgroups().size()); + assertSame(subgroup1, group.getSubgroups().get(0)); + assertSame(subgroup2, group.getSubgroups().get(1)); + } + + @Test + public void testMultipleValuedWrongCollection() { + Group group = new Group(); + Set things = new HashSet<>(); + things.add(new Thing()); + things.add(new Thing()); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.addValue(group, "things", things)); + assertEquals("Value type java.util.HashSet is not a valid type for attribute things of object Group", throwable.getMessage()); + } + + @Test + public void testMultipleValuedWrongType() { + Group group = new Group(); + List newThings = Lists.newArrayList(new Thing(), new Dummy()); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.addValue(group, "things", newThings)); + assertEquals("Value type com.nedap.archie.rminfo.AttributeAccessorTest$Dummy is not a valid type for attribute things of object Group", throwable.getMessage()); + } + + @Test + public void testMultipleValuedException() { + AttributeAccessor attributeAccessor = new AttributeAccessor(new LocalClassInfoLookup()); + BrokenClass brokenClass = new BrokenClass(); + + RuntimeException throwable = assertThrows(RuntimeException.class, () -> attributeAccessor.addValue(brokenClass, "items", new BrokenClass())); + assertEquals("Error adding value to attribute items of object BrokenClass", throwable.getMessage()); + } + + @Test + public void testMultipleValuedSetType() { + AttributeAccessor attributeAccessor = new AttributeAccessor(new LocalClassInfoLookup()); + BrokenClass brokenClass = new BrokenClass(); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.addValue(brokenClass, "some_set", new BrokenClass())); + assertEquals("Unknown collection type java.util.Set", throwable.getMessage()); + } + + @Test + public void testSingleValued() { + Thing thing = new Thing("old value"); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.addValue(thing, "name", "new value")); + assertEquals("Attribute name of object Thing is not a multiple valued attribute", throwable.getMessage()); + + assertEquals("old value", thing.getName()); + } + + @Test + public void testByteArray() { + Thing thing = new Thing(); + byte[] bytes = new byte[]{33, 42}; + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.addValue(thing, "data", bytes)); + assertEquals("Attribute data of object Thing is not a multiple valued attribute", throwable.getMessage()); + + assertNull(thing.getData()); + } + + @Test + public void testUnknownAttribute() { + Thing thing = new Thing(); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.addValue(thing, "unknown", "test string")); + assertEquals("Attribute unknown of object Thing is not a valid attribute", throwable.getMessage()); + } + + @Test + public void testNonRmObject() { + Dummy dummy = new Dummy(); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.addValue(dummy, "value", 12345)); + assertEquals("Attribute value of object Dummy is not a valid attribute", throwable.getMessage()); + } + } + + public static class AddOrSetValue { + + @Test + public void testMultipleValuedSingle() { + Group group = new Group(); + Thing thing1 = new Thing(); + Thing thing2 = new Thing(); + group.setThings(Lists.newArrayList(thing1, thing2)); + + Thing thing3 = new Thing(); + + attributeAccessor.addOrSetValue(group, "things", thing3); + + assertEquals(3, group.getThings().size()); + assertSame(thing1, group.getThings().get(0)); + assertSame(thing2, group.getThings().get(1)); + assertSame(thing3, group.getThings().get(2)); + } + + @Test + public void testMultipleValuedNull() { + Group group = new Group(); + group.setThings(Lists.newArrayList(new Thing(), new Thing())); + + NullPointerException exception = assertThrows(NullPointerException.class, () -> attributeAccessor.addOrSetValue(group, "things", null)); + assertEquals("value must not be null", exception.getMessage()); + + assertEquals(2, group.getThings().size()); + } + + @Test + public void testMultipleValuedListIntialEmpty() { + Group group = new Group(); + + Thing thing1 = new Thing(); + Thing thing2 = new Thing(); + List newThings = Lists.newArrayList(thing1, thing2); + + attributeAccessor.addOrSetValue(group, "things", newThings); + + assertNotSame("A new collection should be created", newThings, group.getThings()); + assertEquals(2, group.getThings().size()); + assertSame(thing1, group.getThings().get(0)); + assertSame(thing2, group.getThings().get(1)); + } + + @Test + public void testMultipleValuedListIntialNull() { + // Group has no addRow method + Group group = new Group(); + group.setThings(null); + + Thing thing1 = new Thing(); + Thing thing2 = new Thing(); + List newThings = Lists.newArrayList(thing1, thing2); + + attributeAccessor.addOrSetValue(group, "things", newThings); + + assertNotSame("A new collection should be created", newThings, group.getThings()); + assertEquals(2, group.getThings().size()); + assertSame(thing1, group.getThings().get(0)); + assertSame(thing2, group.getThings().get(1)); + } + + @Test + public void testMultipleValuedListIntialFilled() { + Group group = new Group(); + Thing thing1 = new Thing(); + Thing thing2 = new Thing(); + group.setThings(Lists.newArrayList(thing1, thing2)); + + Thing thing3 = new Thing(); + Thing thing4 = new Thing(); + List newThings = Lists.newArrayList(thing3, thing4); + + attributeAccessor.addOrSetValue(group, "things", newThings); + + assertEquals(4, group.getThings().size()); + assertSame(thing1, group.getThings().get(0)); + assertSame(thing2, group.getThings().get(1)); + assertSame(thing3, group.getThings().get(2)); + assertSame(thing4, group.getThings().get(3)); + } + + @Test + public void testMultipleValuedListEmpty() { + Group group = new Group(); + group.setThings(Lists.newArrayList(new Thing(), new Thing())); + + attributeAccessor.addOrSetValue(group, "things", Collections.emptyList()); + + assertEquals(2, group.getThings().size()); + } + + @Test + public void testMultipleValuedListNull() { + Group group = new Group(); + Thing thing1 = new Thing(); + Thing thing2 = new Thing(); + group.setThings(Lists.newArrayList(thing1, thing2)); + + attributeAccessor.addOrSetValue(group, "things", Collections.singletonList(null)); + + assertEquals(3, group.getThings().size()); + assertSame(thing1, group.getThings().get(0)); + assertSame(thing2, group.getThings().get(1)); + assertNull(group.getThings().get(2)); + } + + @Test + public void testMultipleValuedFallback() { + // Group has no addRow method + Group group = new Group(); + + Group subgroup1 = new Group(); + Group subgroup2 = new Group(); + List newSubgroups = Lists.newArrayList(subgroup1, subgroup2); + + attributeAccessor.addOrSetValue(group, "subgroups", newSubgroups); + + assertNotSame("A new collection should be created", newSubgroups, group.getSubgroups()); + assertEquals(2, group.getSubgroups().size()); + assertSame(subgroup1, group.getSubgroups().get(0)); + assertSame(subgroup2, group.getSubgroups().get(1)); + } + + @Test + public void testMultipleValuedWrongCollection() { + Group group = new Group(); + Set things = new HashSet<>(); + things.add(new Thing()); + things.add(new Thing()); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.addOrSetValue(group, "things", things)); + assertEquals("Value type java.util.HashSet is not a valid type for attribute things of object Group", throwable.getMessage()); + } + + @Test + public void testMultipleValuedWrongType() { + Group group = new Group(); + List newThings = Lists.newArrayList(new Thing(), new Dummy()); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.addOrSetValue(group, "things", newThings)); + assertEquals("Value type com.nedap.archie.rminfo.AttributeAccessorTest$Dummy is not a valid type for attribute things of object Group", throwable.getMessage()); + } + + @Test + public void testMultipleValuedException() { + AttributeAccessor attributeAccessor = new AttributeAccessor(new LocalClassInfoLookup()); + BrokenClass brokenClass = new BrokenClass(); + + RuntimeException throwable = assertThrows(RuntimeException.class, () -> attributeAccessor.addOrSetValue(brokenClass, "items", new BrokenClass())); + assertEquals("Error adding value to attribute items of object BrokenClass", throwable.getMessage()); + } + + @Test + public void testMultipleValuedSetType() { + AttributeAccessor attributeAccessor = new AttributeAccessor(new LocalClassInfoLookup()); + BrokenClass brokenClass = new BrokenClass(); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.addOrSetValue(brokenClass, "some_set", new BrokenClass())); + assertEquals("Unknown collection type java.util.Set", throwable.getMessage()); + } + + @Test + public void testSingleValued() { + Thing thing = new Thing("old value"); + attributeAccessor.addOrSetValue(thing, "name", "new value"); + assertEquals("new value", thing.getName()); + } + + @Test + public void testSingleValuedNull() { + Thing thing = new Thing("old value"); + attributeAccessor.addOrSetValue(thing, "name", null); + assertNull(thing.getName()); + } + + @Test + public void testSingleValuedList() { + Thing thing = new Thing("old value"); + List newValue = Lists.newArrayList("new value"); + attributeAccessor.addOrSetValue(thing, "name", newValue); + assertEquals("new value", thing.getName()); + } + + @Test + public void testSingleValuedListEmpty() { + Thing thing = new Thing("old value"); + List newValue = Lists.newArrayList(); + attributeAccessor.addOrSetValue(thing, "name", newValue); + assertNull(thing.getName()); + } + + @Test + public void testSingleValuedListNull() { + Thing thing = new Thing("old value"); + List newValue = Lists.newArrayList(); + newValue.add(null); + attributeAccessor.addOrSetValue(thing, "name", newValue); + assertNull(thing.getName()); + } + + @Test + public void testSingleValuedListMultiple() { + Thing thing = new Thing("old value"); + List newValue = Lists.newArrayList(); + newValue.add("first string"); + newValue.add("second string"); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.addOrSetValue(thing, "name", newValue)); + assertEquals("Attribute name of object Thing does not support multiple values", throwable.getMessage()); + + assertEquals("old value", thing.getName()); + } + + @Test + public void testSingleValuedSet() { + Thing thing = new Thing("old value"); + Set newValue = Sets.newHashSet("new value"); + attributeAccessor.addOrSetValue(thing, "name", newValue); + assertEquals("new value", thing.getName()); + } + + @Test + public void testSingleValuedReadOnlyAttribute() { + Thing thing = new Thing(); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.addOrSetValue(thing, "four", 5)); + assertEquals("Attribute four of object Thing is a read-only attribute", throwable.getMessage()); + } + + @Test + public void testSingleValuedWrongType() { + Thing thing = new Thing("old value"); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.addOrSetValue(thing, "name", 12345)); + assertEquals("Value type java.lang.Integer is not a valid type for attribute name of object Thing", throwable.getMessage()); + + assertEquals("old value", thing.getName()); + } + + @Test + public void testSingleValuedObject() { + Group group = new Group(); + Thing thing = new Thing(); + attributeAccessor.addOrSetValue(group, "main_thing", thing); + assertSame(thing, group.getMainThing()); + } + + @Test + public void testSingleValuedException() { + AttributeAccessor attributeAccessor = new AttributeAccessor(new LocalClassInfoLookup()); + BrokenClass brokenClass = new BrokenClass(); + + RuntimeException throwable = assertThrows(RuntimeException.class, () -> attributeAccessor.addOrSetValue(brokenClass, "child", new BrokenClass())); + assertEquals("Error setting value on attribute child of object BrokenClass", throwable.getMessage()); + } + + @Test + public void testByteArray() { + Thing thing = new Thing(); + byte[] bytes = new byte[]{33, 42}; + attributeAccessor.addOrSetValue(thing, "data", bytes); + assertSame(bytes, thing.getData()); + } + + @Test + public void testByteArrayByte() { + Thing thing = new Thing(); + byte singleByte = 42; + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.addOrSetValue(thing, "data", singleByte)); + assertEquals("Value type java.lang.Byte is not a valid type for attribute data of object Thing", throwable.getMessage()); + } + + @Test + public void testByteArrayIntArray() { + Thing thing = new Thing(); + int[] ints = new int[]{33, 42}; + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.addOrSetValue(thing, "data", ints)); + assertEquals("Value type int[] is not a valid type for attribute data of object Thing", throwable.getMessage()); + } + + @Test + public void testUnknownAttribute() { + Thing thing = new Thing(); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.addOrSetValue(thing, "unknown", "test string")); + assertEquals("Attribute unknown of object Thing is not a valid attribute", throwable.getMessage()); + } + + @Test + public void testNonRmObject() { + Dummy dummy = new Dummy(); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.addOrSetValue(dummy, "value", 12345)); + assertEquals("Attribute value of object Dummy is not a valid attribute", throwable.getMessage()); + } + } + + public static class GetValue { + @Test + public void testNormal() { + Thing thing = new Thing("test string"); + assertEquals("test string", attributeAccessor.getValue(thing, "name")); + } + + @Test + public void testNull() { + Thing thing = new Thing(); + assertNull(attributeAccessor.getValue(thing, "name")); + } + + @Test + public void testUnknownAttribute() { + Thing thing = new Thing(); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.getValue(thing, "unknown")); + assertEquals("Attribute unknown of object Thing is not a valid attribute", throwable.getMessage()); + } + + @Test + public void testNonRmObject() { + Dummy dummy = new Dummy(); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.getValue(dummy, "value")); + assertEquals("Attribute value of object Dummy is not a valid attribute", throwable.getMessage()); + } + + @Test + public void testException() { + AttributeAccessor attributeAccessor = new AttributeAccessor(new LocalClassInfoLookup()); + BrokenClass brokenClass = new BrokenClass(); + + RuntimeException throwable = assertThrows(RuntimeException.class, () -> attributeAccessor.getValue(brokenClass, "items")); + assertEquals("Error getting value of attribute items of object BrokenClass", throwable.getMessage()); + } + } + + public static class HasAttribute { + @Test + public void testHasAttribute() { + assertTrue(attributeAccessor.hasAttribute(new Thing(), "name")); + assertFalse(attributeAccessor.hasAttribute(new Thing(), "unknown")); + assertFalse(attributeAccessor.hasAttribute(new Dummy(), "value")); + } + } + + public static class SetValue { + @Test + public void testMultipleValuedSingle() { + Group group = new Group(); + Thing thing1 = new Thing(); + Thing thing2 = new Thing(); + group.setThings(Lists.newArrayList(thing1, thing2)); + + Thing thing3 = new Thing(); + + attributeAccessor.setValue(group, "things", thing3); + + assertEquals(1, group.getThings().size()); + assertSame(thing3, group.getThings().get(0)); + } + + @Test + public void testMultipleValuedNull() { + Group group = new Group(); + group.setThings(Lists.newArrayList(new Thing(), new Thing())); + + attributeAccessor.setValue(group, "things", null); + + assertNull(group.getThings()); + } + + @Test + public void testMultipleValuedListIntialEmpty() { + Group group = new Group(); + + Thing thing1 = new Thing(); + Thing thing2 = new Thing(); + List newThings = Lists.newArrayList(thing1, thing2); + + attributeAccessor.setValue(group, "things", newThings); + + assertEquals(2, group.getThings().size()); + assertSame(thing1, group.getThings().get(0)); + assertSame(thing2, group.getThings().get(1)); + } + + @Test + public void testMultipleValuedListIntialNull() { + Group group = new Group(); + group.setThings(null); + + Thing thing1 = new Thing(); + Thing thing2 = new Thing(); + List newThings = Lists.newArrayList(thing1, thing2); + + attributeAccessor.setValue(group, "things", newThings); + + assertEquals(2, group.getThings().size()); + assertSame(thing1, group.getThings().get(0)); + assertSame(thing2, group.getThings().get(1)); + } + + @Test + public void testMultipleValuedListIntialFilled() { + Group group = new Group(); + Thing thing1 = new Thing(); + Thing thing2 = new Thing(); + group.setThings(Lists.newArrayList(thing1, thing2)); + + Thing thing3 = new Thing(); + Thing thing4 = new Thing(); + List newThings = Lists.newArrayList(thing3, thing4); + + attributeAccessor.setValue(group, "things", newThings); + + assertEquals(2, group.getThings().size()); + assertSame(thing3, group.getThings().get(0)); + assertSame(thing4, group.getThings().get(1)); + } + + @Test + public void testMultipleValuedListEmpty() { + Group group = new Group(); + group.setThings(Lists.newArrayList(new Thing(), new Thing())); + + attributeAccessor.setValue(group, "things", Collections.emptyList()); + + assertEquals(0, group.getThings().size()); + } + + @Test + public void testMultipleValuedListNull() { + Group group = new Group(); + Thing thing1 = new Thing(); + Thing thing2 = new Thing(); + group.setThings(Lists.newArrayList(thing1, thing2)); + + attributeAccessor.setValue(group, "things", Collections.singletonList(null)); + + assertEquals(1, group.getThings().size()); + assertNull(group.getThings().get(0)); + } + + @Test + public void testMultipleValuedWrongCollection() { + Group group = new Group(); + Set things = new HashSet<>(); + things.add(new Thing()); + things.add(new Thing()); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.setValue(group, "things", things)); + assertEquals("Value type java.util.HashSet is not a valid type for attribute things of object Group", throwable.getMessage()); + } + + @Test + public void testMultipleValuedWrongType() { + Group group = new Group(); + List newThings = Lists.newArrayList(new Thing(), new Dummy()); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.setValue(group, "things", newThings)); + assertEquals("Value type com.nedap.archie.rminfo.AttributeAccessorTest$Dummy is not a valid type for attribute things of object Group", throwable.getMessage()); + } + + @Test + public void testMultipleValuedException() { + AttributeAccessor attributeAccessor = new AttributeAccessor(new LocalClassInfoLookup()); + BrokenClass brokenClass = new BrokenClass(); + + RuntimeException throwable = assertThrows(RuntimeException.class, () -> attributeAccessor.setValue(brokenClass, "items", new BrokenClass())); + assertEquals("Error setting value on attribute items of object BrokenClass", throwable.getMessage()); + } + + @Test + public void testMultipleValuedSetType() { + AttributeAccessor attributeAccessor = new AttributeAccessor(new LocalClassInfoLookup()); + BrokenClass brokenClass = new BrokenClass(); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.setValue(brokenClass, "some_set", new BrokenClass())); + assertEquals("Unknown collection type java.util.Set", throwable.getMessage()); + } + + @Test + public void testSingleValued() { + Thing thing = new Thing("old value"); + attributeAccessor.setValue(thing, "name", "new value"); + assertEquals("new value", thing.getName()); + } + + @Test + public void testSingleValuedNull() { + Thing thing = new Thing("old value"); + attributeAccessor.setValue(thing, "name", null); + assertNull(thing.getName()); + } + + @Test + public void testSingleValuedList() { + Thing thing = new Thing("old value"); + List newValue = Lists.newArrayList("new value"); + attributeAccessor.setValue(thing, "name", newValue); + assertEquals("new value", thing.getName()); + } + + @Test + public void testSingleValuedListEmpty() { + Thing thing = new Thing("old value"); + List newValue = Lists.newArrayList(); + attributeAccessor.setValue(thing, "name", newValue); + assertNull(thing.getName()); + } + + @Test + public void testSingleValuedListNull() { + Thing thing = new Thing("old value"); + List newValue = Lists.newArrayList(); + newValue.add(null); + attributeAccessor.setValue(thing, "name", newValue); + assertNull(thing.getName()); + } + + @Test + public void testSingleValuedListMultiple() { + Thing thing = new Thing("old value"); + List newValue = Lists.newArrayList(); + newValue.add("first string"); + newValue.add("second string"); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.setValue(thing, "name", newValue)); + assertEquals("Attribute name of object Thing does not support multiple values", throwable.getMessage()); + + assertEquals("old value", thing.getName()); + } + + @Test + public void testSingleValuedSet() { + Thing thing = new Thing("old value"); + Set newValue = Sets.newHashSet("new value"); + attributeAccessor.setValue(thing, "name", newValue); + assertEquals("new value", thing.getName()); + } + + @Test + public void testSingleValuedReadOnlyAttribute() { + Thing thing = new Thing(); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.setValue(thing, "four", 5)); + assertEquals("Attribute four of object Thing is a read-only attribute", throwable.getMessage()); + } + + @Test + public void testSingleValuedWrongType() { + Thing thing = new Thing("old value"); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.setValue(thing, "name", 12345)); + assertEquals("Value type java.lang.Integer is not a valid type for attribute name of object Thing", throwable.getMessage()); + + assertEquals("old value", thing.getName()); + } + + @Test + public void testSingleValuedObject() { + Group group = new Group(); + Thing thing = new Thing(); + attributeAccessor.setValue(group, "main_thing", thing); + assertSame(thing, group.getMainThing()); + } + + @Test + public void testSingleValuedException() { + AttributeAccessor attributeAccessor = new AttributeAccessor(new LocalClassInfoLookup()); + BrokenClass brokenClass = new BrokenClass(); + + RuntimeException throwable = assertThrows(RuntimeException.class, () -> attributeAccessor.setValue(brokenClass, "child", new BrokenClass())); + assertEquals("Error setting value on attribute child of object BrokenClass", throwable.getMessage()); + } + + @Test + public void testByteArray() { + Thing thing = new Thing(); + byte[] bytes = new byte[]{33, 42}; + attributeAccessor.setValue(thing, "data", bytes); + assertSame(bytes, thing.getData()); + } + + @Test + public void testByteArrayByte() { + Thing thing = new Thing(); + byte singleByte = 42; + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.setValue(thing, "data", singleByte)); + assertEquals("Value type java.lang.Byte is not a valid type for attribute data of object Thing", throwable.getMessage()); + } + + @Test + public void testByteArrayIntArray() { + Thing thing = new Thing(); + int[] ints = new int[]{33, 42}; + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.setValue(thing, "data", ints)); + assertEquals("Value type int[] is not a valid type for attribute data of object Thing", throwable.getMessage()); + } + + @Test + public void testUnknownAttribute() { + Thing thing = new Thing(); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.setValue(thing, "unknown", "test string")); + assertEquals("Attribute unknown of object Thing is not a valid attribute", throwable.getMessage()); + } + + @Test + public void testNonRmObject() { + Dummy dummy = new Dummy(); + + IllegalArgumentException throwable = assertThrows(IllegalArgumentException.class, () -> attributeAccessor.setValue(dummy, "value", 12345)); + assertEquals("Attribute value of object Dummy is not a valid attribute", throwable.getMessage()); + } + } +} diff --git a/archie-utils/build.gradle b/archie-utils/build.gradle index 64817f40d..99f013084 100644 --- a/archie-utils/build.gradle +++ b/archie-utils/build.gradle @@ -1,7 +1,7 @@ description = "Utils for the Archie OpenEHR library" dependencies { - api project(':base') - api project(':aom') - api project(':openehr-rm') -} \ No newline at end of file + api project(':base') + api project(':aom') + api project(':openehr-rm') +} diff --git a/archie-utils/src/main/java/com/nedap/archie/json/ArchieRMObjectMapperProvider.java b/archie-utils/src/main/java/com/nedap/archie/json/ArchieRMObjectMapperProvider.java index 91396bd48..eee93c7f6 100644 --- a/archie-utils/src/main/java/com/nedap/archie/json/ArchieRMObjectMapperProvider.java +++ b/archie-utils/src/main/java/com/nedap/archie/json/ArchieRMObjectMapperProvider.java @@ -22,7 +22,7 @@ public class ArchieRMObjectMapperProvider implements RMObjectMapperProvider { public ObjectMapper getInputOdinObjectMapper() { ObjectMapper odinMapper = new ObjectMapper(); JacksonUtil.configureObjectMapper(odinMapper); - odinMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); + odinMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE); //keywords = <"value"> is indistinguishable from keywords = <"value1", "value2"> odinMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY); //odin sometimes does <> where it can mean either an empty array OR a null object. Nastyness diff --git a/archie-utils/src/main/java/com/nedap/archie/json/JacksonUtil.java b/archie-utils/src/main/java/com/nedap/archie/json/JacksonUtil.java index 1506253e0..886483f6a 100644 --- a/archie-utils/src/main/java/com/nedap/archie/json/JacksonUtil.java +++ b/archie-utils/src/main/java/com/nedap/archie/json/JacksonUtil.java @@ -69,7 +69,7 @@ public static void configureObjectMapper(ObjectMapper objectMapper, ArchieJackso objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); objectMapper.disable(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); - objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); + objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE); objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY); objectMapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS); objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS, true); diff --git a/base/build.gradle b/base/build.gradle index db69568f7..4c72910bb 100644 --- a/base/build.gradle +++ b/base/build.gradle @@ -1,6 +1,6 @@ description = "Base classes for an OpenEHR implementation" dependencies { - //only for the xpath grammar. perhaps include it here? - api project(':grammars') -} \ No newline at end of file + //only for the xpath grammar. perhaps include it here? + api project(':grammars') +} diff --git a/bmm/build.gradle b/bmm/build.gradle index 91063ab94..991adac95 100644 --- a/bmm/build.gradle +++ b/bmm/build.gradle @@ -1,8 +1,8 @@ - description = "A basic metadata model implementation" +description = "A basic metadata model implementation" dependencies { - api project(':base') - api project(':utils') - api project(':odin') - testImplementation project(':i18n') -} \ No newline at end of file + api project(':base') + api project(':utils') + api project(':odin') + testImplementation project(':i18n') +} diff --git a/bmm/src/main/java/org/openehr/bmm/v2/persistence/jackson/BmmJacksonUtil.java b/bmm/src/main/java/org/openehr/bmm/v2/persistence/jackson/BmmJacksonUtil.java index a4b2a4ae5..0b452c42f 100644 --- a/bmm/src/main/java/org/openehr/bmm/v2/persistence/jackson/BmmJacksonUtil.java +++ b/bmm/src/main/java/org/openehr/bmm/v2/persistence/jackson/BmmJacksonUtil.java @@ -45,7 +45,7 @@ public static ObjectMapper getObjectMapper() { * @param objectMapper */ public static void configureObjectMapper(ObjectMapper objectMapper) { - objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); + objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE); //keywords = <"value"> is indistinguishable from keywords = <"value1", "value2"> objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY); objectMapper.enable(JsonParser.Feature.STRICT_DUPLICATE_DETECTION); diff --git a/build.gradle b/build.gradle index f0be9f514..f47bcc2f9 100644 --- a/build.gradle +++ b/build.gradle @@ -1,21 +1,21 @@ -repositories { - mavenCentral() +plugins { + alias(libs.plugins.nexus.publish) } - -wrapper { - gradleVersion = '5.6.4' +repositories { + mavenCentral() } + allprojects { - version = '3.14.0' - group = 'com.nedap.healthcare.archie' - ext.gradleScriptDir = "${rootProject.projectDir}/gradle" - //archivesBaseName = 'archie' - - tasks.withType(Javadoc) { - options.addStringOption('Xdoclint:all', '-quiet') - } + version = '3.16.0' + group = 'com.nedap.healthcare.archie' + ext.gradleScriptDir = "${rootProject.projectDir}/gradle" + //archivesBaseName = 'archie' + + tasks.withType(Javadoc) { + options.addStringOption('Xdoclint:all', '-quiet') + } } gradle.ext.ossrhUsernameSafe = hasProperty('ossrhUsername') ? ossrhUsername : "" @@ -26,93 +26,67 @@ gradle.ext.isParallel = hasProperty('org.gradle.parallel') ? project.property('o apply from: "${gradleScriptDir}/publish-maven.gradle" - subprojects { - apply plugin: 'java-library' - - // plugins { - // id 'com.github.ben-manes.versions' version '0.13.0' - // } - - sourceCompatibility = '1.8' - targetCompatibility = '1.8' - - compileJava.options.encoding = "UTF-8" - compileTestJava.options.encoding = "UTF-8" + apply plugin: 'java-library' - repositories { - mavenCentral() - maven { url 'https://jitpack.io' } - } + compileJava.options.encoding = "UTF-8" + compileTestJava.options.encoding = "UTF-8" - ext.reflectionsVersion = '0.10.2' - ext.jacksonVersion = '2.19.0' - - - java { - withJavadocJar() - withSourcesJar() - } + repositories { + mavenCentral() + maven { url = 'https://jitpack.io' } + } + java { + toolchain { + languageVersion = JavaLanguageVersion.of(8) + } - dependencies { - api 'org.slf4j:slf4j-api:1.7.36' + withJavadocJar() + withSourcesJar() + } - api "com.fasterxml.jackson.core:jackson-annotations:${jacksonVersion}" - api "com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}" - api "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:${jacksonVersion}" - implementation 'com.google.guava:guava:33.4.8-jre' + dependencies { + api(libs.slf4j.api) - implementation "org.reflections:reflections:${reflectionsVersion}" - implementation 'com.esotericsoftware.kryo:kryo5:5.6.2' + api(libs.bundles.jackson) - implementation('commons-io:commons-io:2.19.0'){ - exclude group: 'commons-logging', module: 'commons-logging' - } - implementation 'org.apache.commons:commons-text:1.13.1' - implementation 'org.apache.commons:commons-lang3:3.17.0' + implementation(libs.guava) - //java 10 no longer has these included by default, so explicit dependency is needed. - api 'javax.xml.bind:jaxb-api:2.3.1' - api 'com.sun.xml.bind:jaxb-core:2.3.0.1' - runtimeOnly 'com.sun.xml.bind:jaxb-impl:2.3.9' - api 'javax.activation:activation:1.1.1' + implementation(libs.reflections) + implementation(libs.kryo) - api 'org.threeten:threeten-extra:1.8.0' + implementation(libs.commons.io) + implementation(libs.commons.text) + implementation(libs.commons.lang3) - testImplementation 'junit:junit:4.+' - testImplementation 'org.slf4j:slf4j-simple:1.7.36' + //java 10 no longer has these included by default, so explicit dependency is needed. + api(libs.jaxb.api) + api(libs.jaxb.core) + runtimeOnly(libs.jaxb.impl) + api(libs.activation) - api 'com.github.zafarkhaja:java-semver:0.10.2' + api(libs.threeten.extra) + testImplementation(libs.junit4) + testImplementation(libs.slf4j.simple) - } - + api(libs.zafarkhaja.semver) + } - javadoc { - options.encoding = 'UTF-8' - } + javadoc { + options.encoding = 'UTF-8' + } - test { - if(JavaVersion.current() != JavaVersion.VERSION_1_8) { - jvmArgs = ['--add-opens', 'java.base/java.lang=ALL-UNNAMED' - , '--add-opens', 'java.base/java.lang.invoke=ALL-UNNAMED' - , '--add-opens', 'java.base/java.net=ALL-UNNAMED' - , '--add-opens', 'java.base/java.nio=ALL-UNNAMED' - , '--add-opens', 'java.base/java.time=ALL-UNNAMED' - , '--add-opens', 'java.base/java.util=ALL-UNNAMED' - , '--add-opens', 'java.base/java.util.concurrent.atomic=ALL-UNNAMED' - , '--add-opens', 'java.base/sun.nio.ch=ALL-UNNAMED' - , '--add-opens', 'java.base/sun.util.calendar=ALL-UNNAMED'] - } - testLogging { - events "failed" - exceptionFormat "full" + test { + testLogging { + events "failed" + exceptionFormat = "full" + } } - } } diff --git a/gradle/jacoco.gradle b/gradle/jacoco.gradle index 9c7a71049..e89d29674 100644 --- a/gradle/jacoco.gradle +++ b/gradle/jacoco.gradle @@ -1,47 +1,46 @@ - //the generated ANTLR sources plus the OpenEHR Test RM implementation do not need coverage def excludedPaths = ["**/nedap/archie/adlparser/antlr**", "**/nedap/archie/openehrtestrm/**"] allprojects { - apply plugin: 'jacoco' + apply plugin: 'jacoco' } subprojects { - jacoco { - toolVersion = "0.8.7" - } + jacoco { + toolVersion = "0.8.7" + } - test { - testLogging { - events "failed" - exceptionFormat "full" + test { + testLogging { + events "failed" + exceptionFormat = "full" + } } - } - jacocoTestReport { - reports { - xml.required = true - html.required = true - } - additionalSourceDirs.from = sourceSets.main.allSource.srcDirs - sourceDirectories.from = sourceSets.main.allSource.srcDirs - classDirectories.from = sourceSets.main.output - afterEvaluate { - classDirectories.from = classDirectories.files.collect { - fileTree(dir: it, excludes: excludedPaths) + jacocoTestReport { + reports { + xml.required = true + html.required = true } - } - } + additionalSourceDirs.from = sourceSets.main.allSource.srcDirs + sourceDirectories.from = sourceSets.main.allSource.srcDirs + classDirectories.from = sourceSets.main.output + afterEvaluate { + classDirectories.from = classDirectories.files.collect { + fileTree(dir: it, excludes: excludedPaths) + } + } + } - check.dependsOn jacocoTestReport + check.dependsOn jacocoTestReport } task jacocoRootReport(type: org.gradle.testing.jacoco.tasks.JacocoReport) { dependsOn = subprojects.test additionalSourceDirs.from = subprojects.sourceSets.main.allSource.srcDirs sourceDirectories.from = subprojects.sourceSets.main.allSource.srcDirs - classDirectories.from = subprojects.sourceSets.main.output - executionData.from = subprojects.findAll {!it.sourceSets.test.java.isEmpty()}.jacocoTestReport.executionData + classDirectories.from = subprojects.sourceSets.main.output + executionData.from = subprojects.findAll { !it.sourceSets.test.java.isEmpty() }.jacocoTestReport.executionData reports { html.required = true xml.required = true @@ -49,8 +48,8 @@ task jacocoRootReport(type: org.gradle.testing.jacoco.tasks.JacocoReport) { } afterEvaluate { - classDirectories.from = files(classDirectories.files.collect { - fileTree(dir: it, excludes: excludedPaths) - }) + classDirectories.from = files(classDirectories.files.collect { + fileTree(dir: it, excludes: excludedPaths) + }) } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 000000000..e61e1dfbb --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,54 @@ +[versions] +antlr = "4.13.2" + +jackson = "2.20.1" +jackson_annotations = "2.20" + +slf4j = "1.7.36" + +[plugins] +nexus-publish = { id = "io.github.gradle-nexus.publish-plugin", version = "2.0.0" } + +[bundles] +jackson = ["jackson-annotations", "jackson-databind", "jackson-datatype-jsr310"] + +[libraries] +activation = { module = "javax.activation:activation", version = "1.1.1" } + +antlr4 = { module = "org.antlr:antlr4", version.ref = "antlr" } +antlr4-runtime = { module = "org.antlr:antlr4-runtime", version.ref = "antlr" } + +commons-io = { module = "commons-io:commons-io", version = "2.21.0" } + +commons-lang3 = { module = "org.apache.commons:commons-lang3", version = "3.20.0" } + +commons-text = { module = "org.apache.commons:commons-text", version = "1.15.0" } + +guava = { module = "com.google.guava:guava", version = "33.5.0-jre" } + +jackson-annotations = { module = "com.fasterxml.jackson.core:jackson-annotations", version.ref = "jackson_annotations" } +jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" } +jackson-datatype-jsr310 = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", version.ref = "jackson" } + +jakarta-json = { module = "org.glassfish:jakarta.json", version = "2.0.1" } + +jaxb-api = { module = "javax.xml.bind:jaxb-api", version = "2.3.1" } + +jaxb-core = { module = "com.sun.xml.bind:jaxb-core", version = "2.3.0.1" } + +jaxb-impl = { module = "com.sun.xml.bind:jaxb-impl", version = "2.3.9" } + +junit4 = { module = "junit:junit", version = "4.+" } + +kryo = { module = "com.esotericsoftware.kryo:kryo5", version = "5.6.2" } + +leadpony-justify = { module = "org.leadpony.justify:justify", version = "3.1.0" } + +reflections = { module = "org.reflections:reflections", version = "0.10.2" } + +slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" } +slf4j-simple = { module = "org.slf4j:slf4j-simple", version.ref = "slf4j" } + +threeten-extra = { module = "org.threeten:threeten-extra", version = "1.8.0" } + +zafarkhaja-semver = { module = "com.github.zafarkhaja:java-semver", version = "0.10.2" } diff --git a/gradle/publish-maven.gradle b/gradle/publish-maven.gradle index 33a94ffa0..89f37d9a3 100644 --- a/gradle/publish-maven.gradle +++ b/gradle/publish-maven.gradle @@ -1,87 +1,82 @@ apply plugin: 'maven-publish' -if(gradle.ext.shouldSign) { - apply plugin: 'signing' - signing { - afterEvaluate { project -> - useGpgCmd() - sign publishing.publications +if (gradle.ext.shouldSign) { + apply plugin: 'signing' + signing { + afterEvaluate { project -> + useGpgCmd() + sign publishing.publications + } } - } } -//define the repositories on global level, not per project, or you get many of them -publishing { - repositories { - maven { - name = "ossrh" - // OSSRH URLS - def releasesRepoUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/' - def snapshotsRepoUrl = 'ttps://oss.sonatype.org/content/repositories/snapshots/' - url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl - credentials { - username = project.hasProperty('ossrhUsername') ? ossrhUsername : "Unknown user" - password = project.hasProperty('ossrhPassword') ? ossrhPassword : "Unknown password" - } +nexusPublishing { + repositories { + // see https://central.sonatype.org/publish/publish-portal-ossrh-staging-api/#configuration + sonatype { + nexusUrl.set(uri("https://ossrh-staging-api.central.sonatype.com/service/local/")) + snapshotRepositoryUrl.set(uri("https://central.sonatype.com/repository/maven-snapshots/")) + + username = project.hasProperty("centralTokenUsername") ? centralTokenUsername : "Unknown username" + password = project.hasProperty("centralTokenPassword") ? centralTokenPassword : "Unknown password" + } } - } } - //now uploading will have to be configured on a per subproject basis subprojects { - publishing { + publishing { - publications { - "$project.name"(MavenPublication) { + publications { + "$project.name"(MavenPublication) { - afterEvaluate { - from components.java - artifactId = project.name - pom { - name = project.name - description = project.description - } - } + afterEvaluate { + from components.java + artifactId = project.name + pom { + name = project.name + description = project.description + } + } - pom { + pom { - url = "https://github.com/openEHR/archie" - organization { - name = "Nedap Healthcare" - url = "http://www.nedap-healthcare.com" - } - licenses { - license { - name = "Apache License, Version 2.0" - url = "http://www.apache.org/licenses/LICENSE-2.0" - distribution = "repo" - } - } - scm { - url = "https://github.com/openEHR/archie" - connection = "scm:git:git://github.com/openEHR/archie" - developerConnection = "scm:git:git://github.com/openEHR/archie" - } - developers { - developer { - id = "pieterbos" - name = "Pieter Bos" - email = "pieter.bos@nedap.com" - } - developer { - id = "tanja.dejong" - name = "Tanja de Jong" - email = "tanja.dejong@nedap.com" + url = "https://github.com/openEHR/archie" + organization { + name = "Nedap Healthcare" + url = "http://www.nedap-healthcare.com" + } + licenses { + license { + name = "Apache License, Version 2.0" + url = "http://www.apache.org/licenses/LICENSE-2.0" + distribution = "repo" + } + } + scm { + url = "https://github.com/openEHR/archie" + connection = "scm:git:git://github.com/openEHR/archie" + developerConnection = "scm:git:git://github.com/openEHR/archie" + } + developers { + developer { + id = "pieterbos" + name = "Pieter Bos" + email = "pieter.bos@nedap.com" + } + developer { + id = "tanja.dejong" + name = "Tanja de Jong" + email = "tanja.dejong@nedap.com" + } + } + issueManagement { + system = "Github" + url = "https://github.com/openEHR/archie/issues" + } + } } - } - issueManagement { - system = "Github" - url = "https://github.com/openEHR/archie/issues" - } } - } } - } } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136f..1b33c55ba 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a4413138c..d4081da47 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index b740cf133..23d15a936 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,7 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -203,7 +205,7 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. @@ -211,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 7101f8e46..5eed7ee84 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,11 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar +set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/grammars/build.gradle b/grammars/build.gradle index dd44333be..8d2143cb2 100644 --- a/grammars/build.gradle +++ b/grammars/build.gradle @@ -1,23 +1,21 @@ description = "grammars for parsing ADL, ODIN and xpath" apply plugin: 'antlr' -ext.antlrVersion = '4.13.2' - generateGrammarSource { //antlr4 - outputDirectory = new File("${project.buildDir}/generated-src/antlr/main/com/nedap/archie/adlparser/antlr".toString()) + outputDirectory = new File("${project.buildDir}/generated-src/antlr/main/com/nedap/archie/adlparser/antlr".toString()) arguments = ['-visitor', '-package', 'com.nedap.archie.adlparser.antlr', '-encoding', 'utf-8'] + arguments } sourcesJar { - dependsOn generateGrammarSource + dependsOn generateGrammarSource } classes { - dependsOn generateGrammarSource + dependsOn generateGrammarSource } dependencies { - antlr "org.antlr:antlr4:${antlrVersion}" - api "org.antlr:antlr4-runtime:${antlrVersion}" + antlr(libs.antlr4) + api(libs.antlr4.runtime) } diff --git a/i18n/po/i18n_en.po b/i18n/po/i18n_en.po index 40eb0a4b1..8e0c8d573 100644 --- a/i18n/po/i18n_en.po +++ b/i18n/po/i18n_en.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-12-11 10:35+0100\n" +"POT-Creation-Date: 2025-09-17 15:14+0200\n" "PO-Revision-Date: \n" "Last-Translator: Pieter Bos \n" "Language-Team: \n" @@ -65,12 +65,12 @@ msgstr "" msgid "An object with the new node id {0} cannot be prohibited" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:65 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:60 #, java-format msgid "Archetype referenced in use_archetype points to class {0}, which does not exist in this reference model" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:75 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:70 msgid "Archetype root must have an archetype reference or be prohibited (occurrences matches 0)" msgstr "" @@ -86,7 +86,7 @@ msgstr "" msgid "Archetype terminology not defined" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:54 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:49 #, java-format msgid "Archetype with id {0} used in use_archetype, but it was not found" msgstr "" @@ -136,13 +136,13 @@ msgstr "" msgid "Attribute {0} of class {1} does not match existence {2}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:70 -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:82 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:63 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:75 #, java-format msgid "Attribute {0}.{1} cannot be constrained by a {2}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:48 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:41 #, java-format msgid "Attribute {0}.{1} cannot contain type {2}" msgstr "" @@ -190,7 +190,7 @@ msgstr "" msgid "Code {0} from the C_TERMINOLOGY_CODE constraint is not defined in the terminology" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:161 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:164 #, java-format msgid "Code {0} is in the terminology, but not used in the archetype" msgstr "" @@ -242,30 +242,23 @@ msgstr "" msgid "Error" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidator.java:153 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidator.java:156 #, java-format msgid "Error in parent archetype. Fix those errors before continuing with this archetype: {0}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/RMObjectValidator.java:130 -#, java-format -msgid "" -"Exception {0} invoking invariant {1} on {2}: {3}\n" -"{4}" -msgstr "" - -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:39 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:42 #, java-format msgid "Id code {0} in terminology is not a valid term code, should be id, ac or at, followed by digits" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:43 -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:47 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:46 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:50 #, java-format msgid "Id code {0} in terminology is of a different specialization depth than the archetype" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/AttributeTupleValidation.java:38 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/AttributeTupleValidation.java:36 #, java-format msgid "In the attribute tuple {0} members were specified, but the primitive tuple has {1} members instead" msgstr "" @@ -275,7 +268,7 @@ msgstr "" msgid "Incorrect root node id {0}: it must match the specialization depth of the archetype, which is {1}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/RMObjectValidator.java:125 +#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/RMObjectValidator.java:168 #, java-format msgid "Invariant {0} failed on type " msgstr "" @@ -314,7 +307,7 @@ msgstr "" msgid "No Reference Model schema found for package ''{0}''" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CString.java:112 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CString.java:114 #, java-format msgid "No matching constraint found in parent for contraint {0}" msgstr "" @@ -328,7 +321,7 @@ msgstr "" msgid "Node id numbers should be unique without their ac, at or id-prefix, to ensure the possibility of converting the archetype to ADL 1.4" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:175 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:178 #, java-format msgid "Node id {0} already used in archetype as {1} with a different at, id or ac prefix. The archetype will not be convertible to ADL 1.4" msgstr "" @@ -338,7 +331,7 @@ msgstr "" msgid "Node id {0} already used in path {1}" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/CObject.java:281 +#: ../aom/src/main/java/com/nedap/archie/aom/CObject.java:282 #, java-format msgid "Node id {0} does not conform to {1}" msgstr "" @@ -373,7 +366,7 @@ msgstr "" msgid "Object with node id {0} should be specialized before excluding the parent node" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:127 +#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:129 #, java-format msgid "Occurrences {0} does not conform to {1}" msgstr "" @@ -694,7 +687,7 @@ msgstr "" msgid "Sibling order {0} refers to missing node id" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:151 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:144 msgid "Single valued attributes can not have a cardinality" msgstr "" @@ -715,27 +708,27 @@ msgstr "" msgid "Syntax error: terminology not specified" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidator.java:199 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidator.java:202 #, java-format msgid "Template overlay {0} had validation errors" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:83 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:86 #, java-format msgid "Term binding key {0} in path format is not present in archetype" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:88 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:91 #, java-format msgid "Term binding key {0} is not present in terminology" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:88 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:91 #, java-format msgid "Term binding key {0} is not present in the terminology" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:81 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:84 #, java-format msgid "Term binding key {0} points to a path that cannot be found in the archetype" msgstr "" @@ -758,7 +751,7 @@ msgstr "" msgid "The attribute cardinality interval has lower > upper, this is not allowed" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:55 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:58 #, java-format msgid "The attribute contains {0} objects that are required, but only has an upper cardinality of {1}" msgstr "" @@ -768,12 +761,12 @@ msgstr "" msgid "The attribute {0} of type {1} can only have a single value, but the occurrences of the C_OBJECTS below has an upper limit of more than 1" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:135 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:128 #, java-format msgid "The cardinality of Attribute {0}.{1} is the same as in the reference model - this is not allowed due to strict multiplicities validation being enabled" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:143 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:136 #, java-format msgid "The cardinality {0} of attribute {2}.{3} does not match cardinality {1} of the reference model" msgstr "" @@ -793,12 +786,12 @@ msgstr "" msgid "The constraint interval for this {0} has lower > upper, this is not allowed" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:116 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:109 #, java-format msgid "The existence of attribute {0}.{1} is the same as in the reference model - this is not allowed due to strict existence validation being enabled" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:124 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:117 #, java-format msgid "The existence {0} of attribute {2}.{3} does not match existence {1} of the reference model" msgstr "" @@ -816,7 +809,7 @@ msgstr "" msgid "The occurrences interval has lower > upper, this is not allowed" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:52 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:55 #, java-format msgid "The occurrences of all C_OBJECTS under this attributes is at least {0}, which does not fit in the upper limit of the cardinality of the attribute, {1}" msgstr "" @@ -836,12 +829,12 @@ msgstr "" msgid "The path {0} referenced in the rm visibility does not exist in the flat archetype" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:134 +#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:136 #, java-format msgid "The primitive object of type {0} does not conform null" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:136 +#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:138 #, java-format msgid "The primitive object of type {0} does not conform to non-primitive object with type {1}" msgstr "" @@ -887,16 +880,21 @@ msgstr "" msgid "Translation details language {0} has an incorrect key: {1}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/AttributeTupleValidation.java:32 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/AttributeTupleValidation.java:30 #, java-format msgid "Tuple member attribute {0} is not an attribute of type {1}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:35 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:28 #, java-format msgid "Type name {0} does not exist" msgstr "" +#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/RMObjectValidator.java:173 +#, java-format +msgid "Unexpected error validating invariant {0} on {1}" +msgstr "" + #: ../bmm/src/main/java/org/openehr/bmm/persistence/validation/BmmMessageIds.java:54 #, java-format msgid "Unknown Reference Model ''{0}'' mentioned in ''rm_schemas_load_list'' config setting (ignored)" @@ -910,7 +908,7 @@ msgstr "" msgid "Unknown exception processing RM schemas" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:68 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:63 #, java-format msgid "Use_archetype points to type {0}, which is not conformant for type {1} of the archetype root used" msgstr "" @@ -931,21 +929,21 @@ msgstr "" msgid "Use_archetype {0} does not match the expression of the archetype slot it specialized in the parent" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:42 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:45 #, java-format msgid "Use_node (C_COMPLEX_OBJECT_PROXY) must point to a C_COMPLEX_OBJECT, but points to a {0}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:24 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:27 #, java-format msgid "Use_node (C_COMPLEX_OBJECT_PROXY) points to a path that cannot be found: {0}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:26 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:29 msgid "Use_node (C_COMPLEX_OBJECT_PROXY) points to a path that resolves to more than one object" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:36 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:39 #, java-format msgid "Use_node (C_COMPLEX_OBJECT_PROXY) points to type {0}, which does not conform to type {1}" msgstr "" @@ -1041,22 +1039,22 @@ msgstr "" msgid "cardinality/occurrences upper bound validity: where a cardinality with a finite upper bound is stated on an attribute, for all immediate child objects for which an occurrences constraint is stated, the occurrences must either have an open upper bound (i.e. n..*) which is interpreted as the maximum value allowed within the cardinality, or else a finite upper bound which is ⇐ the cardinality upper bound." msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:234 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:235 #, java-format msgid "child CTerminology code contains more than one constraint, that is not valid. Constraints are: {0}" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:279 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:280 #, java-format msgid "child terminology constraint value code {0} does not conform to parent constraint with value code {1}" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:263 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:264 #, java-format msgid "child terminology constraint value code {0} is not contained in {1}, or a direct specialization of one of its values" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:259 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:260 #, java-format msgid "child terminology constraint value set code {0} does not conform to parent constraint with value set code {1}" msgstr "" @@ -1069,7 +1067,8 @@ msgstr "" msgid "constraint code validity. Each value set code (ac-code) used in a term constraint in the archetype definition must be defined in the term_definitions part of the terminology of the current archetype." msgstr "" -#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/validations/RMPrimitiveObjectValidation.java:59 +#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/RmPrimitiveObjectValidator.java:60 +#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/validations/RMPrimitiveObjectValidation.java:71 msgid "empty" msgstr "" @@ -1136,7 +1135,7 @@ msgstr "" msgid "original language specified. An original_language section containing the meta-data of the original authoring language must exist." msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:237 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:238 #, java-format msgid "parent CTerminology code contains more than one constraint, that is not valid. Constraints are: {0}" msgstr "" @@ -1217,7 +1216,7 @@ msgstr "" msgid "specialised object node occurrences validity: the sum of the lower occurrences and the sum of the upper occurrences of all objects redefining a node in a specialised archetype, must be contained in the occurrences interval of the corresponding node in the flat parent archetype." msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:243 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:244 #, java-format msgid "specialized CTerminology code constraint status {0} is wider more than parent contraint status {1}" msgstr "" @@ -1238,8 +1237,8 @@ msgstr "" msgid "translations key does not match translations item language" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:130 -#: ../aom/src/main/java/com/nedap/archie/aom/CObject.java:284 +#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:132 +#: ../aom/src/main/java/com/nedap/archie/aom/CObject.java:285 #, java-format msgid "type name {0} does not conform to {1}" msgstr "" @@ -1260,13 +1259,13 @@ msgstr "" msgid "value code validity. Each value code (at-code) used in a term constraint in the archetype definition must be defined in the term_definitions part of the terminology of the flattened form of the current archetype." msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:140 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:143 #, java-format msgid "value code {0} is used in redefined value set {1}, but not present in its parent value set with members {2}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:118 -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:122 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:121 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:125 #, java-format msgid "value code {0} is used in value set {1}, but not present in terminology" msgstr "" @@ -1275,18 +1274,18 @@ msgstr "" msgid "value set assumed value code validity. Each value code (at-code) used as an assumed_value for a value set in a term constraint in the archetype definition must exist in the value set definition in the terminology for the identified value set." msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:103 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:106 #, java-format msgid "value set code {0} is not present in terminology" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:109 -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:113 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:112 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:116 #, java-format msgid "value set code {0} is used in value set {1}, but not present in terminology" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:135 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:138 #, java-format msgid "value set {0} has a specialized code, but the valueset it specialized cannot be found in the flat parent" msgstr "" @@ -1308,7 +1307,7 @@ msgstr "" msgid "{0} and {1}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:106 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:99 #, java-format msgid "{0} is not a known attribute of {1}" msgstr "" diff --git a/i18n/po/i18n_nl.po b/i18n/po/i18n_nl.po index ddaffbefa..c1308e77b 100644 --- a/i18n/po/i18n_nl.po +++ b/i18n/po/i18n_nl.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-12-11 10:35+0100\n" +"POT-Creation-Date: 2025-09-17 15:14+0200\n" "PO-Revision-Date: \n" "Last-Translator: Pieter Bos \n" "Language-Team: \n" @@ -65,12 +65,12 @@ msgstr "Een archetype slot is gebruikt in het archetype, maar er is geen archety msgid "An object with the new node id {0} cannot be prohibited" msgstr "Een object met een nieuw node id {0} mag geen occurrences van maximaal 0 hebben" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:65 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:60 #, java-format msgid "Archetype referenced in use_archetype points to class {0}, which does not exist in this reference model" msgstr "Het archetype waarnaar use_archetype verwijst, verwijst naar klasse {0}. Deze klasse bestaat niet in het referentiemodel" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:75 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:70 msgid "Archetype root must have an archetype reference or be prohibited (occurrences matches 0)" msgstr "Use_archetype moet verwijzen naar een archetype, of beperkt zijn tot occurrences 0" @@ -86,7 +86,7 @@ msgstr "De terminologie van dit archetype bevat geen termdefinities" msgid "Archetype terminology not defined" msgstr "Archetype terminology ontbreekt" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:54 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:49 #, java-format msgid "Archetype with id {0} used in use_archetype, but it was not found" msgstr "Archetype met id {0} is gebruikt met use_archetype, maar het archetype kon niet worden gevonden" @@ -136,13 +136,13 @@ msgstr "Attribuut {0} is geen tuple in het archetype dat gespecializeerd wordt, msgid "Attribute {0} of class {1} does not match existence {2}" msgstr "Attribuut {0} van class {1} komt niet overeen met existence {2}" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:70 -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:82 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:63 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:75 #, java-format msgid "Attribute {0}.{1} cannot be constrained by a {2}" msgstr "Attribuut {0}.{1} kan niet worden beperkt met een {2}" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:48 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:41 #, java-format msgid "Attribute {0}.{1} cannot contain type {2}" msgstr "Attribuut {0}.{1} mag geen type {2} bevatten" @@ -190,7 +190,7 @@ msgstr "Code {0} van de C_TERMINOLOGY_CODE heeft specialization depth {1}, maar msgid "Code {0} from the C_TERMINOLOGY_CODE constraint is not defined in the terminology" msgstr "Code {0} van deze C_TERMINOLOGY_CODE bestaat niet in de terminology" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:161 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:164 #, java-format msgid "Code {0} is in the terminology, but not used in the archetype" msgstr "Code {0} uit de terminologie is niet gebruikt in de definitie van het archetype" @@ -242,30 +242,23 @@ msgstr "" msgid "Error" msgstr "Fout" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidator.java:153 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidator.java:156 #, java-format msgid "Error in parent archetype. Fix those errors before continuing with this archetype: {0}" msgstr "Fout in het gespecialiseerde archetype. Los deze fout in het bovenliggende archetype eerst op, alvorens verder te gaan met dit archetype. De gevonden fouten: {0}" -#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/RMObjectValidator.java:130 -#, java-format -msgid "" -"Exception {0} invoking invariant {1} on {2}: {3}\n" -"{4}" -msgstr "" - -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:39 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:42 #, java-format msgid "Id code {0} in terminology is not a valid term code, should be id, ac or at, followed by digits" msgstr "Id code {0} in de terminology is geen geldige term-code. De code zou moeten beginnen met id, ac of at, gevolgd door getallen" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:43 -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:47 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:46 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:50 #, java-format msgid "Id code {0} in terminology is of a different specialization depth than the archetype" msgstr "Id code {0} uit de terminologie heeft een andere specialization depth dan het archetype" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/AttributeTupleValidation.java:38 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/AttributeTupleValidation.java:36 #, java-format msgid "In the attribute tuple {0} members were specified, but the primitive tuple has {1} members instead" msgstr "In het attribuut tupel zijn {0} members opgenomen, maar het primitive tuple heeft {1} members. Dit moet gelijk zijn" @@ -275,7 +268,7 @@ msgstr "In het attribuut tupel zijn {0} members opgenomen, maar het primitive tu msgid "Incorrect root node id {0}: it must match the specialization depth of the archetype, which is {1}" msgstr "Fout in root node id {0}: Dit moet kloppen met de specialization depth van het archetype, {1}" -#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/RMObjectValidator.java:125 +#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/RMObjectValidator.java:168 #, java-format msgid "Invariant {0} failed on type " msgstr "" @@ -314,7 +307,7 @@ msgstr "" msgid "No Reference Model schema found for package ''{0}''" msgstr "Geen referentiemodel-schema gevonden voor package “{0}”" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CString.java:112 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CString.java:114 #, java-format msgid "No matching constraint found in parent for contraint {0}" msgstr "" @@ -328,7 +321,7 @@ msgstr "De specialization depth van node id {0} klopt niet bij de specialization msgid "Node id numbers should be unique without their ac, at or id-prefix, to ensure the possibility of converting the archetype to ADL 1.4" msgstr "Node id nummers moeten uniek zijn zonder hun ac, at of id-prefix, om conversie van het archetype naar ADL 1.4 mogelijk te maken" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:175 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:178 #, java-format msgid "Node id {0} already used in archetype as {1} with a different at, id or ac prefix. The archetype will not be convertible to ADL 1.4" msgstr "Node id {0} wordt al gebruikt in het archetype als {1} met een andere at, id of ac prefix. Het archetype kan niet naar ADL 1.4 geconverteerd worden" @@ -338,7 +331,7 @@ msgstr "Node id {0} wordt al gebruikt in het archetype als {1} met een andere at msgid "Node id {0} already used in path {1}" msgstr "Node id {0} is al gebruikt in pad {1}" -#: ../aom/src/main/java/com/nedap/archie/aom/CObject.java:281 +#: ../aom/src/main/java/com/nedap/archie/aom/CObject.java:282 #, java-format msgid "Node id {0} does not conform to {1}" msgstr "Node id {0} komt niet overeen met {1}" @@ -373,7 +366,7 @@ msgstr "Object moet van type {0} zijn, maar is van type {1}" msgid "Object with node id {0} should be specialized before excluding the parent node" msgstr "Object met node id {0} moet gespecialiseerd worden voordat de parent node excluded wordt" -#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:127 +#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:129 #, java-format msgid "Occurrences {0} does not conform to {1}" msgstr "Occurrences {0} komt niet overeen met {1}" @@ -694,7 +687,7 @@ msgstr "" msgid "Sibling order {0} refers to missing node id" msgstr "Sibling order {0} verwijst naar een ontbrekende node id" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:151 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:144 msgid "Single valued attributes can not have a cardinality" msgstr "Attributen die maar één waarde kunnen bevatten mogen geen cardinaliteit hebben" @@ -715,27 +708,27 @@ msgstr "Syntaxfout: existence moet een van 0..0, 0..1 of 1..1 zijn, maar was {0} msgid "Syntax error: terminology not specified" msgstr "Syntaxfout: terminologie ontbreekt" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidator.java:199 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidator.java:202 #, java-format msgid "Template overlay {0} had validation errors" msgstr "Template overlay {0} heeft validatiefouten" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:83 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:86 #, java-format msgid "Term binding key {0} in path format is not present in archetype" msgstr "Het pad {0} uit een term binding kan niet worden gevonden in het archetype" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:88 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:91 #, java-format msgid "Term binding key {0} is not present in terminology" msgstr "De code {0} van een term binding bestaat niet in de terminologie" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:88 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:91 #, java-format msgid "Term binding key {0} is not present in the terminology" msgstr "De code {0} van een term binding bestaat niet in de terminologie" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:81 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:84 #, java-format msgid "Term binding key {0} points to a path that cannot be found in the archetype" msgstr "Het pad {0} uit een term binding kan niet worden gevonden in het archetype" @@ -758,7 +751,7 @@ msgstr "Het archetype id {0} komt niet overeen met de mogelijke archetype ids" msgid "The attribute cardinality interval has lower > upper, this is not allowed" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:55 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:58 #, java-format msgid "The attribute contains {0} objects that are required, but only has an upper cardinality of {1}" msgstr "Het attribuut bevat {0} waarden die verplicht zijn, maar heeft een maximale cardinaliteit van {1}" @@ -768,12 +761,12 @@ msgstr "Het attribuut bevat {0} waarden die verplicht zijn, maar heeft een maxim msgid "The attribute {0} of type {1} can only have a single value, but the occurrences of the C_OBJECTS below has an upper limit of more than 1" msgstr "Het attribuut {0} van type {1} kan maar één waarde hebben, maar de occurrences van de C_OBJECTS in dit attibuut heeft een maximale limiet van meer dan 1" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:135 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:128 #, java-format msgid "The cardinality of Attribute {0}.{1} is the same as in the reference model - this is not allowed due to strict multiplicities validation being enabled" msgstr "De cardinaliteit van attribuut {0}.{1} is hetzelfde als in het referentiemodel. Dit is niet toegestaan als strikte validatie is ingeschakeld" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:143 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:136 #, java-format msgid "The cardinality {0} of attribute {2}.{3} does not match cardinality {1} of the reference model" msgstr "De cardinaliteit {0} van attribuut {2}.{3} klopt niet met de cardinaliteit {1} uit het referentiemodel" @@ -793,12 +786,12 @@ msgstr "" msgid "The constraint interval for this {0} has lower > upper, this is not allowed" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:116 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:109 #, java-format msgid "The existence of attribute {0}.{1} is the same as in the reference model - this is not allowed due to strict existence validation being enabled" msgstr "De existence van attribuut {0}.{1} is hetzelfde als in het referentiemodel. Dit is niet toegestaan als strikte validatie ingeschakeld is" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:124 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:117 #, java-format msgid "The existence {0} of attribute {2}.{3} does not match existence {1} of the reference model" msgstr "De existence {0} van attribuut {2}.{3} klopt niet bij existence {1} van het referentiemodel" @@ -816,7 +809,7 @@ msgstr "De node id van het bovenste object van het archetype moet van de form id msgid "The occurrences interval has lower > upper, this is not allowed" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:52 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:55 #, java-format msgid "The occurrences of all C_OBJECTS under this attributes is at least {0}, which does not fit in the upper limit of the cardinality of the attribute, {1}" msgstr "De occurrences van alle C_OBJECTS onder dit attribuut is ten minste {0}. Dat past niet in de maximale cardinaliteit van het attibruut {1}" @@ -836,12 +829,12 @@ msgstr "Het pad {0} gebruikt in de annotations bestaat niet in het flattened arc msgid "The path {0} referenced in the rm visibility does not exist in the flat archetype" msgstr "Het pad {0} gebruikt in de rm zichtbaarheid bestaat niet in het flattened archetype" -#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:134 +#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:136 #, java-format msgid "The primitive object of type {0} does not conform null" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:136 +#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:138 #, java-format msgid "The primitive object of type {0} does not conform to non-primitive object with type {1}" msgstr "Het primitieve object van type {0} komt niet overeen met het niet-primitieve object met type {1}" @@ -887,16 +880,21 @@ msgstr "De waarde {0} moet {1} zijn" msgid "Translation details language {0} has an incorrect key: {1}" msgstr "De beschrijving van de vertaling {0} zou een gelijke sleutelwaarde als de taal moeten hebben, maar heeft de waarde {1}" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/AttributeTupleValidation.java:32 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/AttributeTupleValidation.java:30 #, java-format msgid "Tuple member attribute {0} is not an attribute of type {1}" msgstr "Onderdeel van tupel {0} is geen attribuut van type {1}" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:35 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:28 #, java-format msgid "Type name {0} does not exist" msgstr "Type met naam {0} bestaat niet" +#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/RMObjectValidator.java:173 +#, fuzzy, java-format +msgid "Unexpected error validating invariant {0} on {1}" +msgstr "Onverwachte fout bij het valideren van invariant {0} van {1}" + #: ../bmm/src/main/java/org/openehr/bmm/persistence/validation/BmmMessageIds.java:54 #, java-format msgid "Unknown Reference Model ''{0}'' mentioned in ''rm_schemas_load_list'' config setting (ignored)" @@ -910,7 +908,7 @@ msgstr "" msgid "Unknown exception processing RM schemas" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:68 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:63 #, java-format msgid "Use_archetype points to type {0}, which is not conformant for type {1} of the archetype root used" msgstr "Use_archetype verwijst naar een pad met type {0}. Dit komt niet overeen met type {1} zoals opgegeven in use_archetype" @@ -931,21 +929,21 @@ msgstr "Use_archetype {1} specialiseert een andere use_archetype die verwijst na msgid "Use_archetype {0} does not match the expression of the archetype slot it specialized in the parent" msgstr "Use_archetype {0} komt niet overeen met de restricties van het archetype slot dat het specialiseert" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:42 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:45 #, java-format msgid "Use_node (C_COMPLEX_OBJECT_PROXY) must point to a C_COMPLEX_OBJECT, but points to a {0}" msgstr "Use_node, hergebruik van een deel van het archetype, moet naar een C_COMPLEX_OBJECT verwijzen, maar verwijst naar een {0}" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:24 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:27 #, java-format msgid "Use_node (C_COMPLEX_OBJECT_PROXY) points to a path that cannot be found: {0}" msgstr "Use_node, hergebruik van een deel van het archetype, verwijst naar een pad dat niet kan worden gevonden: {0}" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:26 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:29 msgid "Use_node (C_COMPLEX_OBJECT_PROXY) points to a path that resolves to more than one object" msgstr "Use_node, hergebruik van een deel van het archetype, verwijst naar een pad dat verwijst naar meer dan één object" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:36 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:39 #, java-format msgid "Use_node (C_COMPLEX_OBJECT_PROXY) points to type {0}, which does not conform to type {1}" msgstr "Use_node, hergebruik van een deel van het archetype, verwijst naar type {0}, maar dat klopt niet met type {1} zoals gevonden uit het pad" @@ -1041,22 +1039,22 @@ msgstr "" msgid "cardinality/occurrences upper bound validity: where a cardinality with a finite upper bound is stated on an attribute, for all immediate child objects for which an occurrences constraint is stated, the occurrences must either have an open upper bound (i.e. n..*) which is interpreted as the maximum value allowed within the cardinality, or else a finite upper bound which is ⇐ the cardinality upper bound." msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:234 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:235 #, java-format msgid "child CTerminology code contains more than one constraint, that is not valid. Constraints are: {0}" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:279 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:280 #, java-format msgid "child terminology constraint value code {0} does not conform to parent constraint with value code {1}" msgstr "child terminology constraint value code {0} komt niet overeen met dat van de parent constraint met value code {1}" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:263 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:264 #, java-format msgid "child terminology constraint value code {0} is not contained in {1}, or a direct specialization of one of its values" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:259 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:260 #, java-format msgid "child terminology constraint value set code {0} does not conform to parent constraint with value set code {1}" msgstr "child terminology constraint value set code {0} komt niet overeen de parent constraint met value set code {1}" @@ -1069,7 +1067,8 @@ msgstr "code uit terminologie is niet gebruikt in de definitie van het archetype msgid "constraint code validity. Each value set code (ac-code) used in a term constraint in the archetype definition must be defined in the term_definitions part of the terminology of the current archetype." msgstr "" -#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/validations/RMPrimitiveObjectValidation.java:59 +#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/RmPrimitiveObjectValidator.java:60 +#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/validations/RMPrimitiveObjectValidation.java:71 msgid "empty" msgstr "leeg" @@ -1136,7 +1135,7 @@ msgstr "" msgid "original language specified. An original_language section containing the meta-data of the original authoring language must exist." msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:237 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:238 #, java-format msgid "parent CTerminology code contains more than one constraint, that is not valid. Constraints are: {0}" msgstr "" @@ -1217,7 +1216,7 @@ msgstr "" msgid "specialised object node occurrences validity: the sum of the lower occurrences and the sum of the upper occurrences of all objects redefining a node in a specialised archetype, must be contained in the occurrences interval of the corresponding node in the flat parent archetype." msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:243 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:244 #, java-format msgid "specialized CTerminology code constraint status {0} is wider more than parent contraint status {1}" msgstr "" @@ -1238,8 +1237,8 @@ msgstr "de gegeven id code is niet geldig" msgid "translations key does not match translations item language" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:130 -#: ../aom/src/main/java/com/nedap/archie/aom/CObject.java:284 +#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:132 +#: ../aom/src/main/java/com/nedap/archie/aom/CObject.java:285 #, java-format msgid "type name {0} does not conform to {1}" msgstr "Naam type {0} komt niet overeen met {1}" @@ -1260,13 +1259,13 @@ msgstr "" msgid "value code validity. Each value code (at-code) used in a term constraint in the archetype definition must be defined in the term_definitions part of the terminology of the flattened form of the current archetype." msgstr "Geldigheid van een value code. Elke value code (at-code) gebruikt in een term constraint in de definitie van het archetype moet in de term definities van de flat form van dit archetype opgenomen zijn." -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:140 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:143 #, java-format msgid "value code {0} is used in redefined value set {1}, but not present in its parent value set with members {2}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:118 -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:122 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:121 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:125 #, java-format msgid "value code {0} is used in value set {1}, but not present in terminology" msgstr "de code {0} is gebruikt in value set {1}, maar bestaat niet in de terminologie" @@ -1275,18 +1274,18 @@ msgstr "de code {0} is gebruikt in value set {1}, maar bestaat niet in de termin msgid "value set assumed value code validity. Each value code (at-code) used as an assumed_value for a value set in a term constraint in the archetype definition must exist in the value set definition in the terminology for the identified value set." msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:103 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:106 #, java-format msgid "value set code {0} is not present in terminology" msgstr "de code {0} van een value set bestaat niet in de terminologie" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:109 -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:113 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:112 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:116 #, java-format msgid "value set code {0} is used in value set {1}, but not present in terminology" msgstr "de value set code {0} is gebruikt in value set {1}, maar bestaat niet in de terminologie" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:135 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:138 #, java-format msgid "value set {0} has a specialized code, but the valueset it specialized cannot be found in the flat parent" msgstr "" @@ -1308,7 +1307,7 @@ msgstr "value-set waardes uniek. Elke waarde mag maar één keer gebruikt worden msgid "{0} and {1}" msgstr "{0} en {1}" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:106 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:99 #, java-format msgid "{0} is not a known attribute of {1}" msgstr "{0} is niet een bekend attribuut van {1}" diff --git a/i18n/po/keys.pot b/i18n/po/keys.pot index 82b49724b..5ca873152 100644 --- a/i18n/po/keys.pot +++ b/i18n/po/keys.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-12-14 13:44+0100\n" +"POT-Creation-Date: 2025-09-17 15:14+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -70,12 +70,12 @@ msgstr "" msgid "An object with the new node id {0} cannot be prohibited" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:65 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:60 #, java-format msgid "Archetype referenced in use_archetype points to class {0}, which does not exist in this reference model" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:75 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:70 msgid "Archetype root must have an archetype reference or be prohibited (occurrences matches 0)" msgstr "" @@ -91,7 +91,7 @@ msgstr "" msgid "Archetype terminology not defined" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:54 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:49 #, java-format msgid "Archetype with id {0} used in use_archetype, but it was not found" msgstr "" @@ -141,13 +141,13 @@ msgstr "" msgid "Attribute {0} of class {1} does not match existence {2}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:70 -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:82 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:63 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:75 #, java-format msgid "Attribute {0}.{1} cannot be constrained by a {2}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:48 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:41 #, java-format msgid "Attribute {0}.{1} cannot contain type {2}" msgstr "" @@ -195,7 +195,7 @@ msgstr "" msgid "Code {0} from the C_TERMINOLOGY_CODE constraint is not defined in the terminology" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:161 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:164 #, java-format msgid "Code {0} is in the terminology, but not used in the archetype" msgstr "" @@ -247,30 +247,23 @@ msgstr "" msgid "Error" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidator.java:153 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidator.java:156 #, java-format msgid "Error in parent archetype. Fix those errors before continuing with this archetype: {0}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/RMObjectValidator.java:130 -#, java-format -msgid "" -"Exception {0} invoking invariant {1} on {2}: {3}\n" -"{4}" -msgstr "" - -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:39 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:42 #, java-format msgid "Id code {0} in terminology is not a valid term code, should be id, ac or at, followed by digits" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:43 -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:47 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:46 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:50 #, java-format msgid "Id code {0} in terminology is of a different specialization depth than the archetype" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/AttributeTupleValidation.java:38 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/AttributeTupleValidation.java:36 #, java-format msgid "In the attribute tuple {0} members were specified, but the primitive tuple has {1} members instead" msgstr "" @@ -280,7 +273,7 @@ msgstr "" msgid "Incorrect root node id {0}: it must match the specialization depth of the archetype, which is {1}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/RMObjectValidator.java:125 +#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/RMObjectValidator.java:168 #, java-format msgid "Invariant {0} failed on type " msgstr "" @@ -319,7 +312,7 @@ msgstr "" msgid "No Reference Model schema found for package ''{0}''" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CString.java:112 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CString.java:114 #, java-format msgid "No matching constraint found in parent for contraint {0}" msgstr "" @@ -333,7 +326,7 @@ msgstr "" msgid "Node id numbers should be unique without their ac, at or id-prefix, to ensure the possibility of converting the archetype to ADL 1.4" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:175 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:178 #, java-format msgid "Node id {0} already used in archetype as {1} with a different at, id or ac prefix. The archetype will not be convertible to ADL 1.4" msgstr "" @@ -343,7 +336,7 @@ msgstr "" msgid "Node id {0} already used in path {1}" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/CObject.java:281 +#: ../aom/src/main/java/com/nedap/archie/aom/CObject.java:282 #, java-format msgid "Node id {0} does not conform to {1}" msgstr "" @@ -378,7 +371,7 @@ msgstr "" msgid "Object with node id {0} should be specialized before excluding the parent node" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:127 +#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:129 #, java-format msgid "Occurrences {0} does not conform to {1}" msgstr "" @@ -699,7 +692,7 @@ msgstr "" msgid "Sibling order {0} refers to missing node id" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:151 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:144 msgid "Single valued attributes can not have a cardinality" msgstr "" @@ -720,27 +713,27 @@ msgstr "" msgid "Syntax error: terminology not specified" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidator.java:199 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidator.java:202 #, java-format msgid "Template overlay {0} had validation errors" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:83 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:86 #, java-format msgid "Term binding key {0} in path format is not present in archetype" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:88 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:91 #, java-format msgid "Term binding key {0} is not present in terminology" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:88 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:91 #, java-format msgid "Term binding key {0} is not present in the terminology" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:81 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:84 #, java-format msgid "Term binding key {0} points to a path that cannot be found in the archetype" msgstr "" @@ -763,7 +756,7 @@ msgstr "" msgid "The attribute cardinality interval has lower > upper, this is not allowed" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:55 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:58 #, java-format msgid "The attribute contains {0} objects that are required, but only has an upper cardinality of {1}" msgstr "" @@ -773,12 +766,12 @@ msgstr "" msgid "The attribute {0} of type {1} can only have a single value, but the occurrences of the C_OBJECTS below has an upper limit of more than 1" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:135 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:128 #, java-format msgid "The cardinality of Attribute {0}.{1} is the same as in the reference model - this is not allowed due to strict multiplicities validation being enabled" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:143 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:136 #, java-format msgid "The cardinality {0} of attribute {2}.{3} does not match cardinality {1} of the reference model" msgstr "" @@ -798,12 +791,12 @@ msgstr "" msgid "The constraint interval for this {0} has lower > upper, this is not allowed" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:116 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:109 #, java-format msgid "The existence of attribute {0}.{1} is the same as in the reference model - this is not allowed due to strict existence validation being enabled" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:124 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:117 #, java-format msgid "The existence {0} of attribute {2}.{3} does not match existence {1} of the reference model" msgstr "" @@ -821,7 +814,7 @@ msgstr "" msgid "The occurrences interval has lower > upper, this is not allowed" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:52 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:55 #, java-format msgid "The occurrences of all C_OBJECTS under this attributes is at least {0}, which does not fit in the upper limit of the cardinality of the attribute, {1}" msgstr "" @@ -841,12 +834,12 @@ msgstr "" msgid "The path {0} referenced in the rm visibility does not exist in the flat archetype" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:134 +#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:136 #, java-format msgid "The primitive object of type {0} does not conform null" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:136 +#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:138 #, java-format msgid "The primitive object of type {0} does not conform to non-primitive object with type {1}" msgstr "" @@ -892,16 +885,21 @@ msgstr "" msgid "Translation details language {0} has an incorrect key: {1}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/AttributeTupleValidation.java:32 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/AttributeTupleValidation.java:30 #, java-format msgid "Tuple member attribute {0} is not an attribute of type {1}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:35 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:28 #, java-format msgid "Type name {0} does not exist" msgstr "" +#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/RMObjectValidator.java:173 +#, java-format +msgid "Unexpected error validating invariant {0} on {1}" +msgstr "" + #: ../bmm/src/main/java/org/openehr/bmm/persistence/validation/BmmMessageIds.java:54 #, java-format msgid "Unknown Reference Model ''{0}'' mentioned in ''rm_schemas_load_list'' config setting (ignored)" @@ -915,7 +913,7 @@ msgstr "" msgid "Unknown exception processing RM schemas" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:68 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java:63 #, java-format msgid "Use_archetype points to type {0}, which is not conformant for type {1} of the archetype root used" msgstr "" @@ -936,21 +934,21 @@ msgstr "" msgid "Use_archetype {0} does not match the expression of the archetype slot it specialized in the parent" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:42 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:45 #, java-format msgid "Use_node (C_COMPLEX_OBJECT_PROXY) must point to a C_COMPLEX_OBJECT, but points to a {0}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:24 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:27 #, java-format msgid "Use_node (C_COMPLEX_OBJECT_PROXY) points to a path that cannot be found: {0}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:26 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:29 msgid "Use_node (C_COMPLEX_OBJECT_PROXY) points to a path that resolves to more than one object" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:36 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java:39 #, java-format msgid "Use_node (C_COMPLEX_OBJECT_PROXY) points to type {0}, which does not conform to type {1}" msgstr "" @@ -1046,22 +1044,22 @@ msgstr "" msgid "cardinality/occurrences upper bound validity: where a cardinality with a finite upper bound is stated on an attribute, for all immediate child objects for which an occurrences constraint is stated, the occurrences must either have an open upper bound (i.e. n..*) which is interpreted as the maximum value allowed within the cardinality, or else a finite upper bound which is ⇐ the cardinality upper bound." msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:234 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:235 #, java-format msgid "child CTerminology code contains more than one constraint, that is not valid. Constraints are: {0}" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:279 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:280 #, java-format msgid "child terminology constraint value code {0} does not conform to parent constraint with value code {1}" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:263 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:264 #, java-format msgid "child terminology constraint value code {0} is not contained in {1}, or a direct specialization of one of its values" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:259 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:260 #, java-format msgid "child terminology constraint value set code {0} does not conform to parent constraint with value set code {1}" msgstr "" @@ -1074,7 +1072,8 @@ msgstr "" msgid "constraint code validity. Each value set code (ac-code) used in a term constraint in the archetype definition must be defined in the term_definitions part of the terminology of the current archetype." msgstr "" -#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/validations/RMPrimitiveObjectValidation.java:59 +#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/RmPrimitiveObjectValidator.java:60 +#: ../tools/src/main/java/com/nedap/archie/rmobjectvalidator/validations/RMPrimitiveObjectValidation.java:71 msgid "empty" msgstr "" @@ -1141,7 +1140,7 @@ msgstr "" msgid "original language specified. An original_language section containing the meta-data of the original authoring language must exist." msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:237 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:238 #, java-format msgid "parent CTerminology code contains more than one constraint, that is not valid. Constraints are: {0}" msgstr "" @@ -1222,7 +1221,7 @@ msgstr "" msgid "specialised object node occurrences validity: the sum of the lower occurrences and the sum of the upper occurrences of all objects redefining a node in a specialised archetype, must be contained in the occurrences interval of the corresponding node in the flat parent archetype." msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:243 +#: ../aom/src/main/java/com/nedap/archie/aom/primitives/CTerminologyCode.java:244 #, java-format msgid "specialized CTerminology code constraint status {0} is wider more than parent contraint status {1}" msgstr "" @@ -1243,8 +1242,8 @@ msgstr "" msgid "translations key does not match translations item language" msgstr "" -#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:130 -#: ../aom/src/main/java/com/nedap/archie/aom/CObject.java:284 +#: ../aom/src/main/java/com/nedap/archie/aom/CPrimitiveObject.java:132 +#: ../aom/src/main/java/com/nedap/archie/aom/CObject.java:285 #, java-format msgid "type name {0} does not conform to {1}" msgstr "" @@ -1265,13 +1264,13 @@ msgstr "" msgid "value code validity. Each value code (at-code) used in a term constraint in the archetype definition must be defined in the term_definitions part of the terminology of the flattened form of the current archetype." msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:140 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:143 #, java-format msgid "value code {0} is used in redefined value set {1}, but not present in its parent value set with members {2}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:118 -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:122 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:121 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:125 #, java-format msgid "value code {0} is used in value set {1}, but not present in terminology" msgstr "" @@ -1280,18 +1279,18 @@ msgstr "" msgid "value set assumed value code validity. Each value code (at-code) used as an assumed_value for a value set in a term constraint in the archetype definition must exist in the value set definition in the terminology for the identified value set." msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:103 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:106 #, java-format msgid "value set code {0} is not present in terminology" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:109 -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:113 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:112 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:116 #, java-format msgid "value set code {0} is used in value set {1}, but not present in terminology" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:135 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java:138 #, java-format msgid "value set {0} has a specialized code, but the valueset it specialized cannot be found in the flat parent" msgstr "" @@ -1313,7 +1312,7 @@ msgstr "" msgid "{0} and {1}" msgstr "" -#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:106 +#: ../tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java:99 #, java-format msgid "{0} is not a known attribute of {1}" msgstr "" diff --git a/json-schema/build.gradle b/json-schema/build.gradle index 86f89c413..5d5e1be12 100644 --- a/json-schema/build.gradle +++ b/json-schema/build.gradle @@ -13,15 +13,15 @@ plugins { description = "A tool that generates the official ITS-JSON json schema from the BMM files" -import com.nedap.archie.json.OpenEHRRmJSONSchemaCreator; -import com.nedap.archie.json.JsonSchemaUriProvider; -import com.nedap.archie.json.JsonSchemaUri; -import com.nedap.archie.json.ItsJsonUriProvider; -import org.openehr.referencemodels.BuiltinReferenceModels; -import jakarta.json.*; -import jakarta.json.stream.JsonGenerator; -import org.openehr.bmm.core.BmmClass; +import com.nedap.archie.json.ItsJsonUriProvider +import com.nedap.archie.json.JsonSchemaUri +import com.nedap.archie.json.OpenEHRRmJSONSchemaCreator +import jakarta.json.Json +import jakarta.json.JsonObject +import jakarta.json.JsonWriterFactory +import jakarta.json.stream.JsonGenerator +import org.openehr.referencemodels.BuiltinReferenceModels abstract class JsonSchemaCreationTask extends DefaultTask { @@ -81,23 +81,23 @@ abstract class JsonSchemaCreationTask extends DefaultTask { } def printSchemas(String version, Map schemas, JsonWriterFactory jsonWriterFactory) { - for(JsonSchemaUri name:schemas.keySet()) { + for (JsonSchemaUri name : schemas.keySet()) { def schema = schemas.get(name); def versionDir = getOutputDir().get().dir(version) - if(!versionDir.getAsFile().exists()) { + if (!versionDir.getAsFile().exists()) { versionDir.getAsFile().mkdir(); } System.out.println(name.getFilename()); def split = name.getFilename().split("/"); def fileName = null; - for(int i = 0; i < split.length-1;i++) { + for (int i = 0; i < split.length - 1; i++) { String dir = split[i]; versionDir = versionDir.dir(dir); - if(!versionDir.getAsFile().exists()) { + if (!versionDir.getAsFile().exists()) { versionDir.getAsFile().mkdir(); } } - fileName = split[split.length-1]; + fileName = split[split.length - 1]; versionDir.file(fileName).getAsFile().withWriter { writer -> jsonWriterFactory.createWriter(writer).write(schema); } @@ -109,5 +109,3 @@ abstract class JsonSchemaCreationTask extends DefaultTask { tasks.register('generateJsonSchema', JsonSchemaCreationTask) { outputDir = file(layout.buildDirectory.dir('schemaOutput')) } - - diff --git a/odin/build.gradle b/odin/build.gradle index 6ee48ea32..55875080b 100644 --- a/odin/build.gradle +++ b/odin/build.gradle @@ -1,6 +1,6 @@ description = "An odin implementation" dependencies { - api project(':grammars') - api project(':base') -} \ No newline at end of file + api project(':grammars') + api project(':base') +} diff --git a/odin/src/main/java/com/nedap/archie/serializer/odin/AdlOdinToJsonConverter.java b/odin/src/main/java/com/nedap/archie/serializer/odin/AdlOdinToJsonConverter.java index a8a67f28a..ff0ea97d7 100644 --- a/odin/src/main/java/com/nedap/archie/serializer/odin/AdlOdinToJsonConverter.java +++ b/odin/src/main/java/com/nedap/archie/serializer/odin/AdlOdinToJsonConverter.java @@ -38,7 +38,7 @@ public static ObjectMapper getObjectMapper() { } public static void configureObjectMapper(ObjectMapper objectMapper, boolean allowDuplicates) { - objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); + objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE); //keywords = <"value"> is indistinguishable from keywords = <"value1", "value2"> objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY); //odin sometimes does <> where it can mean either an empty array OR a null object. Nastyness diff --git a/odin/src/main/java/com/nedap/archie/serializer/odin/OdinToJsonConverter.java b/odin/src/main/java/com/nedap/archie/serializer/odin/OdinToJsonConverter.java index 1624d1aa1..c93fd1cbe 100644 --- a/odin/src/main/java/com/nedap/archie/serializer/odin/OdinToJsonConverter.java +++ b/odin/src/main/java/com/nedap/archie/serializer/odin/OdinToJsonConverter.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; import com.nedap.archie.adlparser.antlr.odinParser.*; import org.apache.commons.text.StringEscapeUtils; @@ -29,7 +29,7 @@ public class OdinToJsonConverter { private StringBuilder output = new StringBuilder(); static { - objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); + objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE); //keywords = <"value"> is indistinguishable from keywords = <"value1", "value2"> objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY); objectMapper.enable(JsonParser.Feature.STRICT_DUPLICATE_DETECTION); diff --git a/odin/src/main/java/org/openehr/odin/jackson/ODINMapper.java b/odin/src/main/java/org/openehr/odin/jackson/ODINMapper.java index fc963ab4e..d051e4442 100644 --- a/odin/src/main/java/org/openehr/odin/jackson/ODINMapper.java +++ b/odin/src/main/java/org/openehr/odin/jackson/ODINMapper.java @@ -2,10 +2,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.MappingJsonFactory; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.module.SimpleModule; import com.nedap.archie.base.Interval; import com.nedap.archie.base.terminology.TerminologyCode; @@ -44,7 +41,7 @@ public ODINMapper(ODINMapper base) { private void setup() { - setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); + setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE); disable(SerializationFeature.WRITE_NULL_MAP_VALUES); disable(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS); enable(SerializationFeature.INDENT_OUTPUT); diff --git a/openehr-rm/build.gradle b/openehr-rm/build.gradle index b9427b505..2866e4c89 100644 --- a/openehr-rm/build.gradle +++ b/openehr-rm/build.gradle @@ -1,9 +1,10 @@ description = "An implementation of the openehr reference model" dependencies { - api project(':base') - api project(':aom') //modelInfoLookup depends on CPrimitiveObject to convert from AOM objects to RM objects. So we need this dependency, at least for now - api project(':path-queries') - api project(':utils') - testImplementation project(':archie-utils') -} \ No newline at end of file + api project(':base') + //modelInfoLookup depends on CPrimitiveObject to convert from AOM objects to RM objects. So we need the AOM dependency, at least for now + api project(':aom') + api project(':path-queries') + api project(':utils') + testImplementation project(':archie-utils') +} diff --git a/openehr-rm/src/main/java/com/nedap/archie/rmutil/PathableUtil.java b/openehr-rm/src/main/java/com/nedap/archie/rmutil/PathableUtil.java index 79e68914e..cd918df8b 100644 --- a/openehr-rm/src/main/java/com/nedap/archie/rmutil/PathableUtil.java +++ b/openehr-rm/src/main/java/com/nedap/archie/rmutil/PathableUtil.java @@ -2,16 +2,17 @@ import com.nedap.archie.paths.PathSegment; import com.nedap.archie.paths.PathUtil; -import com.nedap.archie.query.RMObjectAttributes; import com.nedap.archie.rm.archetyped.Pathable; import com.nedap.archie.rminfo.ArchieRMInfoLookup; -import com.nedap.archie.rminfo.ModelInfoLookup; +import com.nedap.archie.rminfo.AttributeAccessor; import java.util.ArrayList; import java.util.Collection; import java.util.List; public class PathableUtil { + private static final AttributeAccessor attributeAccessor = new AttributeAccessor(ArchieRMInfoLookup.getInstance()); + /** * Determine the unique path segments from the toplevel-RM object. *

@@ -36,8 +37,7 @@ private static PathSegment getUniquePathSegment(Pathable pathable) { Pathable parent = pathable.getParent(); String parentAttributeName = unindexedPathSegment.getNodeName(); - ModelInfoLookup modelInfoLookup = ArchieRMInfoLookup.getInstance(); - Object attributeValue = RMObjectAttributes.getAttributeValueFromRMObject(parent, parentAttributeName, modelInfoLookup); + Object attributeValue = attributeAccessor.getValue(parent, parentAttributeName); Integer index = null; if (attributeValue instanceof Collection) { diff --git a/path-queries/build.gradle b/path-queries/build.gradle index c2132c65f..3eaaa9512 100644 --- a/path-queries/build.gradle +++ b/path-queries/build.gradle @@ -1,9 +1,9 @@ description = "An implementation of openehr path queries" dependencies { - //only for the xpath grammar. perhaps include it here? - api project(':grammars') - api project(':base') - api project(':aom') //modelInfoLookup is here and should be split and moved - testImplementation project(':openehr-rm') -} \ No newline at end of file + //only for the xpath grammar. perhaps include it here? + api project(':grammars') + api project(':base') + api project(':aom') //modelInfoLookup is here and should be split and moved + testImplementation project(':openehr-rm') +} diff --git a/path-queries/src/main/java/com/nedap/archie/query/RMObjectAttributes.java b/path-queries/src/main/java/com/nedap/archie/query/RMObjectAttributes.java index afe8e5bd6..091905053 100644 --- a/path-queries/src/main/java/com/nedap/archie/query/RMObjectAttributes.java +++ b/path-queries/src/main/java/com/nedap/archie/query/RMObjectAttributes.java @@ -5,6 +5,10 @@ import java.lang.reflect.InvocationTargetException; +/** + * @deprecated Use {@link com.nedap.archie.rminfo.AttributeAccessor} + */ +@Deprecated public class RMObjectAttributes { /** * Get the value of an attribute of a RM object. @@ -13,7 +17,9 @@ public class RMObjectAttributes { * @param attributeName The name of the attribute. * @return The value of the attribute. * @throws IllegalArgumentException When no attribute exists with the given attribute name. + * @deprecated Use {@link com.nedap.archie.rminfo.AttributeAccessor#getValue(Object, String)} */ + @Deprecated public static Object getAttributeValueFromRMObject(Object object, String attributeName, ModelInfoLookup modelInfoLookup) { Object result; diff --git a/path-queries/src/main/java/com/nedap/archie/query/RMPathQuery.java b/path-queries/src/main/java/com/nedap/archie/query/RMPathQuery.java index 4f98b3a39..254c33090 100644 --- a/path-queries/src/main/java/com/nedap/archie/query/RMPathQuery.java +++ b/path-queries/src/main/java/com/nedap/archie/query/RMPathQuery.java @@ -5,13 +5,11 @@ import com.nedap.archie.aom.utils.AOMUtils; import com.nedap.archie.definitions.AdlCodeDefinitions; import com.nedap.archie.paths.PathSegment; +import com.nedap.archie.rminfo.AttributeAccessor; import com.nedap.archie.rminfo.ModelInfoLookup; -import com.nedap.archie.rminfo.RMAttributeInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -46,152 +44,138 @@ public RMPathQuery(String query, boolean matchSpecialisedNodes) { //TODO: get diagnostic information about where the finder stopped in the path - could be very useful! public T find(ModelInfoLookup lookup, Object root) { + AttributeAccessor attributeAccessor = new AttributeAccessor(lookup); Object currentObject = root; - try { - for (PathSegment segment : pathSegments) { - if (currentObject == null) { - return null; + for (PathSegment segment : pathSegments) { + if (currentObject == null) { + return null; + } + if (!attributeAccessor.hasAttribute(currentObject, segment.getNodeName())) { + return null; + } + currentObject = attributeAccessor.getValue(currentObject, segment.getNodeName()); + if (currentObject == null) { + return null; + } + + String archetypeNodeIdFromObject = lookup.getArchetypeNodeIdFromRMObject(currentObject); + if (currentObject instanceof Collection) { + Collection collection = (Collection) currentObject; + if (!segment.hasExpressions()) { + //TODO: check if this is correct + currentObject = collection; + } else { + currentObject = findRMObject(lookup, segment, collection); } - RMAttributeInfo attributeInfo = lookup.getAttributeInfo(currentObject.getClass(), segment.getNodeName()); - if (attributeInfo == null) { - return null; + } else if (archetypeNodeIdFromObject != null) { + + if (segment.hasExpressions()) { + if (segment.hasIdCode()) { + if (!archetypeNodeIdFromObject.equals(segment.getNodeId())) { + return null; + } + } else if (segment.hasNumberIndex()) { + int number = segment.getIndex(); + if (number != 1) { + return null; + } + } else if (segment.hasArchetypeRef()) { + //operational templates in RM Objects have their archetype node ID set to an archetype ref. That + //we support. Other things not so much + if (!archetypeNodeIdFromObject.equals(segment.getNodeId())) { + throw new IllegalArgumentException("cannot handle RM-queries with node names or archetype references yet"); + } + + } } - Method method = attributeInfo.getGetMethod(); - currentObject = method.invoke(currentObject); - if (currentObject == null) { + } else if (segment.hasNumberIndex()) { + int number = segment.getIndex(); + if (number != 1) { return null; } + } else { + //not a locatable, but that's fine + //in openehr, in archetypes everythign has node ids. Datavalues do not in the rm. a bit ugly if you ask + //me, but that's why there's no 'if there's a nodeId set, this won't match!' code here. + } + } + return (T) currentObject; + } + /** + * You will want to use RMQueryContext in many cases. For perforamnce reasons, this could still be useful + */ + public List findList(ModelInfoLookup lookup, Object root) { + AttributeAccessor attributeAccessor = new AttributeAccessor(lookup); + List currentObjects = Lists.newArrayList(new RMObjectWithPath(root, "/")); + for (PathSegment segment : pathSegments) { + if(currentObjects.isEmpty()){ + return Collections.emptyList(); + } + List newCurrentObjects = new ArrayList<>(); + + for(int i = 0; i < currentObjects.size(); i++) { + RMObjectWithPath currentObject = currentObjects.get(i); + Object currentRMObject = currentObject.getObject(); + if (!attributeAccessor.hasAttribute(currentRMObject, segment.getNodeName())) { + continue; + } + currentRMObject = attributeAccessor.getValue(currentRMObject, segment.getNodeName()); + String pathSeparator = "/"; + if(currentObject.getPath().endsWith("/")) { + pathSeparator = ""; + } + String newPath = currentObject.getPath() + pathSeparator + segment.getNodeName(); + + if (currentRMObject == null) { + continue; + } String archetypeNodeIdFromObject = lookup.getArchetypeNodeIdFromRMObject(currentObject); - if (currentObject instanceof Collection) { - Collection collection = (Collection) currentObject; + if (currentRMObject instanceof Collection) { + Collection collection = (Collection) currentRMObject; if (!segment.hasExpressions()) { - //TODO: check if this is correct - currentObject = collection; + addAllFromCollection(lookup, newCurrentObjects, collection, newPath); } else { - currentObject = findRMObject(lookup, segment, collection); + //TODO + newCurrentObjects.addAll(findRMObjectsWithPathCollection(lookup, segment, collection, newPath)); } } else if (archetypeNodeIdFromObject != null) { if (segment.hasExpressions()) { if (segment.hasIdCode()) { if (!archetypeNodeIdFromObject.equals(segment.getNodeId())) { - return null; + continue; } } else if (segment.hasNumberIndex()) { int number = segment.getIndex(); if (number != 1) { - return null; + continue; } } else if (segment.hasArchetypeRef()) { //operational templates in RM Objects have their archetype node ID set to an archetype ref. That //we support. Other things not so much if (!archetypeNodeIdFromObject.equals(segment.getNodeId())) { - throw new IllegalArgumentException("cannot handle RM-queries with node names or archetype references yet"); + continue; } } + newCurrentObjects.add(createRMObjectWithPath(lookup, currentRMObject, newPath)); } } else if (segment.hasNumberIndex()) { int number = segment.getIndex(); if (number != 1) { - return null; + continue; } } else { - //not a locatable, but that's fine + //The object does not have an archetypeNodeId //in openehr, in archetypes everythign has node ids. Datavalues do not in the rm. a bit ugly if you ask //me, but that's why there's no 'if there's a nodeId set, this won't match!' code here. + newCurrentObjects.add(createRMObjectWithPath(lookup, currentRMObject, newPath)); } } - return (T) currentObject; - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - /** - * You will want to use RMQueryContext in many cases. For perforamnce reasons, this could still be useful - */ - public List findList(ModelInfoLookup lookup, Object root) { - List currentObjects = Lists.newArrayList(new RMObjectWithPath(root, "/")); - try { - for (PathSegment segment : pathSegments) { - if(currentObjects.isEmpty()){ - return Collections.emptyList(); - } - List newCurrentObjects = new ArrayList<>(); - - for(int i = 0; i < currentObjects.size(); i++) { - RMObjectWithPath currentObject = currentObjects.get(i); - Object currentRMObject = currentObject.getObject(); - RMAttributeInfo attributeInfo = lookup.getAttributeInfo(currentRMObject.getClass(), segment.getNodeName()); - if (attributeInfo == null) { - continue; - } - Method method = attributeInfo.getGetMethod(); - currentRMObject = method.invoke(currentRMObject); - String pathSeparator = "/"; - if(currentObject.getPath().endsWith("/")) { - pathSeparator = ""; - } - String newPath = currentObject.getPath() + pathSeparator + segment.getNodeName(); - - if (currentRMObject == null) { - continue; - } - String archetypeNodeIdFromObject = lookup.getArchetypeNodeIdFromRMObject(currentObject); - if (currentRMObject instanceof Collection) { - Collection collection = (Collection) currentRMObject; - if (!segment.hasExpressions()) { - addAllFromCollection(lookup, newCurrentObjects, collection, newPath); - } else { - //TODO - newCurrentObjects.addAll(findRMObjectsWithPathCollection(lookup, segment, collection, newPath)); - } - } else if (archetypeNodeIdFromObject != null) { - - if (segment.hasExpressions()) { - if (segment.hasIdCode()) { - if (!archetypeNodeIdFromObject.equals(segment.getNodeId())) { - continue; - } - } else if (segment.hasNumberIndex()) { - int number = segment.getIndex(); - if (number != 1) { - continue; - } - } else if (segment.hasArchetypeRef()) { - //operational templates in RM Objects have their archetype node ID set to an archetype ref. That - //we support. Other things not so much - if (!archetypeNodeIdFromObject.equals(segment.getNodeId())) { - continue; - } - - } - newCurrentObjects.add(createRMObjectWithPath(lookup, currentRMObject, newPath)); - } - } else if (segment.hasNumberIndex()) { - int number = segment.getIndex(); - if (number != 1) { - continue; - } - } else { - //The object does not have an archetypeNodeId - //in openehr, in archetypes everythign has node ids. Datavalues do not in the rm. a bit ugly if you ask - //me, but that's why there's no 'if there's a nodeId set, this won't match!' code here. - newCurrentObjects.add(createRMObjectWithPath(lookup, currentRMObject, newPath)); - } - } - currentObjects = newCurrentObjects; - } - return currentObjects; - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); + currentObjects = newCurrentObjects; } + return currentObjects; } diff --git a/referencemodels/build.gradle b/referencemodels/build.gradle index b947bb68b..ab534c052 100644 --- a/referencemodels/build.gradle +++ b/referencemodels/build.gradle @@ -1,9 +1,10 @@ description = "tools to access OpenEHR reference model metadata" dependencies { - api project(':bmm') - api project(':odin') - api project(':aom') - testImplementation project(':openehr-rm') - testImplementation project(':archie-utils') -} \ No newline at end of file + api project(':bmm') + api project(':odin') + api project(':aom') + testImplementation project(':openehr-rm') + testImplementation project(':test-rm') + testImplementation project(':archie-utils') +} diff --git a/referencemodels/src/main/java/org/openehr/referencemodels/BuiltinReferenceModels.java b/referencemodels/src/main/java/org/openehr/referencemodels/BuiltinReferenceModels.java index 2c89cabf6..8f2e4156b 100644 --- a/referencemodels/src/main/java/org/openehr/referencemodels/BuiltinReferenceModels.java +++ b/referencemodels/src/main/java/org/openehr/referencemodels/BuiltinReferenceModels.java @@ -2,10 +2,7 @@ import com.nedap.archie.aom.profile.AomProfile; import com.nedap.archie.aom.profile.AomProfiles; -import com.nedap.archie.rminfo.MetaModels; -import com.nedap.archie.rminfo.ModelInfoLookup; -import com.nedap.archie.rminfo.RMObjectMapperProvider; -import com.nedap.archie.rminfo.ReferenceModels; +import com.nedap.archie.rminfo.*; import org.openehr.bmm.v2.persistence.odin.BmmOdinParser; import org.openehr.bmm.v2.validation.BmmRepository; import org.openehr.bmm.v2.validation.BmmSchemaConverter; @@ -34,6 +31,8 @@ public class BuiltinReferenceModels { private static BmmRepository bmmRepository; + private static MetaModelProvider metaModelProvider; + public static BmmRepository getBmmRepository() { if(bmmRepository != null) { return bmmRepository; @@ -160,11 +159,24 @@ private static void addModelInfoLookupIfExists(ReferenceModels result, String cl } } + /** + * Returns a MetaModelProvider loaded with all BMM models, ModelInfoLookups and AOM profiles that are available. + */ + public static MetaModelProvider getMetaModelProvider() { + if (metaModelProvider != null) { + return metaModelProvider; + } + metaModelProvider = new SimpleMetaModelProvider(getAvailableModelInfoLookups(), getBmmRepository(), getAomProfiles()); + return metaModelProvider; + } + /** * Returns the MetaModels loaded with all BMM, ModelInfoLookup and AOM profiles that are available. * Returns a new MetaModels instance every call! * @return + * @deprecated Use {@link #getMetaModelProvider()} instead. */ + @Deprecated public static MetaModels getMetaModels() { MetaModels metaModels = new MetaModels(getAvailableModelInfoLookups(), getBmmRepository()); for(AomProfile profile:getAomProfiles().getProfiles()) { diff --git a/referencemodels/src/test/java/com/nedap/archie/rminfo/OverridingMetaModelProviderTest.java b/referencemodels/src/test/java/com/nedap/archie/rminfo/OverridingMetaModelProviderTest.java new file mode 100644 index 000000000..0986eddc3 --- /dev/null +++ b/referencemodels/src/test/java/com/nedap/archie/rminfo/OverridingMetaModelProviderTest.java @@ -0,0 +1,47 @@ +package com.nedap.archie.rminfo; + +import com.nedap.archie.aom.Archetype; +import com.nedap.archie.aom.ArchetypeHRID; +import org.junit.Test; +import org.openehr.referencemodels.BuiltinReferenceModels; + +import static org.junit.Assert.assertEquals; + +public class OverridingMetaModelProviderTest { + @Test + public void overrideModelVersion() { + MetaModelProvider metaModelProvider = BuiltinReferenceModels.getMetaModelProvider(); + OverridingMetaModelProvider overridingMetaModelProvider = new OverridingMetaModelProvider(metaModelProvider); + + Archetype archetype = new Archetype(); + archetype.setArchetypeId(new ArchetypeHRID("openEHR-EHR-CLUSTER.test.v1.0.0")); + archetype.setRmRelease("1.0.3"); + MetaModel metaModel = overridingMetaModelProvider.getMetaModel(archetype); + assertEquals("openehr", metaModel.getBmmModel().getRmPublisher()); + assertEquals("EHR", metaModel.getBmmModel().getModelName()); + assertEquals("1.0.3", metaModel.getBmmModel().getRmRelease()); + + + //now overide the version to 1.0.4, and assert + overridingMetaModelProvider.overrideModelVersion("openEHR", "EHR", "1.0.4"); + + metaModel = overridingMetaModelProvider.getMetaModel(archetype); + assertEquals("openehr", metaModel.getBmmModel().getRmPublisher()); + assertEquals("EHR", metaModel.getBmmModel().getModelName()); + assertEquals("1.0.4", metaModel.getBmmModel().getRmRelease()); + + //select a specific RM + metaModel = overridingMetaModelProvider.getMetaModel(archetype, "1.0.2"); + + assertEquals("openehr", metaModel.getBmmModel().getRmPublisher()); + assertEquals("EHR", metaModel.getBmmModel().getModelName()); + assertEquals("1.0.2", metaModel.getBmmModel().getRmRelease()); + + //remove Override + overridingMetaModelProvider.removeOverridenModelVersion("openEHR", "EHR"); + metaModel = overridingMetaModelProvider.getMetaModel(archetype); + assertEquals("openehr", metaModel.getBmmModel().getRmPublisher()); + assertEquals("EHR", metaModel.getBmmModel().getModelName()); + assertEquals("1.0.3", metaModel.getBmmModel().getRmRelease()); + } +} diff --git a/referencemodels/src/test/java/com/nedap/archie/rminfo/SimpleMetaModelProviderTest.java b/referencemodels/src/test/java/com/nedap/archie/rminfo/SimpleMetaModelProviderTest.java new file mode 100644 index 000000000..6816778ee --- /dev/null +++ b/referencemodels/src/test/java/com/nedap/archie/rminfo/SimpleMetaModelProviderTest.java @@ -0,0 +1,267 @@ +package com.nedap.archie.rminfo; + +import com.nedap.archie.aom.Archetype; +import com.nedap.archie.aom.ArchetypeHRID; +import com.nedap.archie.aom.profile.AomProfiles; +import com.nedap.archie.openehrtestrm.TestRMInfoLookup; +import org.junit.Test; +import org.openehr.referencemodels.BuiltinReferenceModels; + +import static org.junit.Assert.*; + +public class SimpleMetaModelProviderTest { + + @Test + public void testConstructors() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> new SimpleMetaModelProvider(null, null)); + assertEquals("Either referenceModels or bmmRepository must be provided", ex.getMessage()); + + ex = assertThrows(IllegalArgumentException.class, () -> new SimpleMetaModelProvider(null, null, new AomProfiles())); + assertEquals("Either referenceModels or bmmRepository must be provided", ex.getMessage()); + } + + @Test + public void testGetMetaModel() { + MetaModelProvider metaModelProvider = new SimpleMetaModelProvider( + BuiltinReferenceModels.getAvailableModelInfoLookups(), + BuiltinReferenceModels.getBmmRepository(), + BuiltinReferenceModels.getAomProfiles() + ); + + Archetype archetype = new Archetype(); + archetype.setArchetypeId(new ArchetypeHRID("openEHR-EHR-CLUSTER.test.v1.0.0")); + archetype.setRmRelease("1.0.3"); + + MetaModel metaModel = metaModelProvider.getMetaModel(archetype); + assertTrue(metaModel.getModelInfoLookup() instanceof ArchieRMInfoLookup); + assertEquals("openehr", metaModel.getBmmModel().getRmPublisher()); + assertEquals("EHR", metaModel.getBmmModel().getModelName()); + assertEquals("1.0.3", metaModel.getBmmModel().getRmRelease()); + assertEquals("openEHR", metaModel.getAomProfile().getProfileName()); + assertNotNull(metaModel.getOdinInputObjectMapper()); + assertNotNull(metaModel.getOdinOutputObjectMapper()); + assertNotNull(metaModel.getJsonObjectMapper()); + + archetype.setRmRelease("1.0.4"); + + metaModel = metaModelProvider.getMetaModel(archetype); + assertTrue(metaModel.getModelInfoLookup() instanceof ArchieRMInfoLookup); + assertEquals("openehr", metaModel.getBmmModel().getRmPublisher()); + assertEquals("EHR", metaModel.getBmmModel().getModelName()); + assertEquals("1.0.4", metaModel.getBmmModel().getRmRelease()); + assertEquals("openEHR", metaModel.getAomProfile().getProfileName()); + assertNotNull(metaModel.getOdinInputObjectMapper()); + assertNotNull(metaModel.getOdinOutputObjectMapper()); + assertNotNull(metaModel.getJsonObjectMapper()); + + archetype.setRmRelease("1.99.1"); + + metaModel = metaModelProvider.getMetaModel(archetype); + assertTrue(metaModel.getModelInfoLookup() instanceof ArchieRMInfoLookup); + assertNull(metaModel.getBmmModel()); + assertEquals("openEHR", metaModel.getAomProfile().getProfileName()); + assertNotNull(metaModel.getOdinInputObjectMapper()); + assertNotNull(metaModel.getOdinOutputObjectMapper()); + assertNotNull(metaModel.getJsonObjectMapper()); + + archetype.setArchetypeId(new ArchetypeHRID("openEHR-TEST_PKG-CLUSTER.test.v1.0.0")); + archetype.setRmRelease("1.0.2"); + + metaModel = metaModelProvider.getMetaModel(archetype); + assertTrue(metaModel.getModelInfoLookup() instanceof TestRMInfoLookup); + assertEquals("openehr", metaModel.getBmmModel().getRmPublisher()); + assertEquals("TEST_PKG", metaModel.getBmmModel().getModelName()); + assertEquals("1.0.2", metaModel.getBmmModel().getRmRelease()); + assertEquals("openEHR", metaModel.getAomProfile().getProfileName()); + assertNull(metaModel.getOdinInputObjectMapper()); + assertNull(metaModel.getOdinOutputObjectMapper()); + assertNull(metaModel.getJsonObjectMapper()); + + archetype.setArchetypeId(new ArchetypeHRID("other-OTHER-CLUSTER.test.v1.0.0")); + archetype.setRmRelease("0.9.0"); + + ModelNotFoundException ex = assertThrows(ModelNotFoundException.class, () -> metaModelProvider.getMetaModel(archetype)); + assertEquals("model for other.OTHER version 0.9.0 not found", ex.getMessage()); + } + + @Test + public void testGetMetaModelModelInfoLookupOnly() { + MetaModelProvider metaModelProvider = new SimpleMetaModelProvider( + BuiltinReferenceModels.getAvailableModelInfoLookups(), + null, + BuiltinReferenceModels.getAomProfiles() + ); + + Archetype archetype = new Archetype(); + archetype.setArchetypeId(new ArchetypeHRID("openEHR-EHR-CLUSTER.test.v1.0.0")); + archetype.setRmRelease("1.0.3"); + + MetaModel metaModel = metaModelProvider.getMetaModel(archetype); + assertTrue(metaModel.getModelInfoLookup() instanceof ArchieRMInfoLookup); + assertNull(metaModel.getBmmModel()); + assertEquals("openEHR", metaModel.getAomProfile().getProfileName()); + assertNotNull(metaModel.getOdinInputObjectMapper()); + assertNotNull(metaModel.getOdinOutputObjectMapper()); + assertNotNull(metaModel.getJsonObjectMapper()); + + archetype.setRmRelease("1.0.4"); + + metaModel = metaModelProvider.getMetaModel(archetype); + assertTrue(metaModel.getModelInfoLookup() instanceof ArchieRMInfoLookup); + assertNull(metaModel.getBmmModel()); + assertEquals("openEHR", metaModel.getAomProfile().getProfileName()); + assertNotNull(metaModel.getOdinInputObjectMapper()); + assertNotNull(metaModel.getOdinOutputObjectMapper()); + assertNotNull(metaModel.getJsonObjectMapper()); + + archetype.setRmRelease("1.99.1"); + + metaModel = metaModelProvider.getMetaModel(archetype); + assertTrue(metaModel.getModelInfoLookup() instanceof ArchieRMInfoLookup); + assertNull(metaModel.getBmmModel()); + assertEquals("openEHR", metaModel.getAomProfile().getProfileName()); + assertNotNull(metaModel.getOdinInputObjectMapper()); + assertNotNull(metaModel.getOdinOutputObjectMapper()); + assertNotNull(metaModel.getJsonObjectMapper()); + + archetype.setArchetypeId(new ArchetypeHRID("openEHR-TEST_PKG-CLUSTER.test.v1.0.0")); + archetype.setRmRelease("1.0.2"); + + metaModel = metaModelProvider.getMetaModel(archetype); + assertTrue(metaModel.getModelInfoLookup() instanceof TestRMInfoLookup); + assertNull(metaModel.getBmmModel()); + assertEquals("openEHR", metaModel.getAomProfile().getProfileName()); + assertNull(metaModel.getOdinInputObjectMapper()); + assertNull(metaModel.getOdinOutputObjectMapper()); + assertNull(metaModel.getJsonObjectMapper()); + + archetype.setArchetypeId(new ArchetypeHRID("other-OTHER-CLUSTER.test.v1.0.0")); + archetype.setRmRelease("0.9.0"); + + ModelNotFoundException ex = assertThrows(ModelNotFoundException.class, () -> metaModelProvider.getMetaModel(archetype)); + assertEquals("model for other.OTHER version 0.9.0 not found", ex.getMessage()); + } + + @Test + public void testGetMetaModelBmmOnly() { + MetaModelProvider metaModelProvider = new SimpleMetaModelProvider( + null, + BuiltinReferenceModels.getBmmRepository(), + BuiltinReferenceModels.getAomProfiles() + ); + + Archetype archetype = new Archetype(); + archetype.setArchetypeId(new ArchetypeHRID("openEHR-EHR-CLUSTER.test.v1.0.0")); + archetype.setRmRelease("1.0.3"); + + MetaModel metaModel = metaModelProvider.getMetaModel(archetype); + assertNull(metaModel.getModelInfoLookup()); + assertEquals("openehr", metaModel.getBmmModel().getRmPublisher()); + assertEquals("EHR", metaModel.getBmmModel().getModelName()); + assertEquals("1.0.3", metaModel.getBmmModel().getRmRelease()); + assertEquals("openEHR", metaModel.getAomProfile().getProfileName()); + assertNull(metaModel.getOdinInputObjectMapper()); + assertNull(metaModel.getOdinOutputObjectMapper()); + assertNull(metaModel.getJsonObjectMapper()); + + archetype.setRmRelease("1.0.4"); + + metaModel = metaModelProvider.getMetaModel(archetype); + assertNull(metaModel.getModelInfoLookup()); + assertEquals("openehr", metaModel.getBmmModel().getRmPublisher()); + assertEquals("EHR", metaModel.getBmmModel().getModelName()); + assertEquals("1.0.4", metaModel.getBmmModel().getRmRelease()); + assertEquals("openEHR", metaModel.getAomProfile().getProfileName()); + assertNull(metaModel.getOdinInputObjectMapper()); + assertNull(metaModel.getOdinOutputObjectMapper()); + assertNull(metaModel.getJsonObjectMapper()); + + archetype.setRmRelease("1.99.1"); + + ModelNotFoundException ex = assertThrows(ModelNotFoundException.class, () -> metaModelProvider.getMetaModel(archetype)); + assertEquals("model for openEHR.EHR version 1.99.1 not found", ex.getMessage()); + + archetype.setArchetypeId(new ArchetypeHRID("openEHR-TEST_PKG-CLUSTER.test.v1.0.0")); + archetype.setRmRelease("1.0.2"); + + metaModel = metaModelProvider.getMetaModel(archetype); + assertNull(metaModel.getModelInfoLookup()); + assertEquals("openehr", metaModel.getBmmModel().getRmPublisher()); + assertEquals("TEST_PKG", metaModel.getBmmModel().getModelName()); + assertEquals("1.0.2", metaModel.getBmmModel().getRmRelease()); + assertEquals("openEHR", metaModel.getAomProfile().getProfileName()); + assertNull(metaModel.getOdinInputObjectMapper()); + assertNull(metaModel.getOdinOutputObjectMapper()); + assertNull(metaModel.getJsonObjectMapper()); + + archetype.setArchetypeId(new ArchetypeHRID("other-OTHER-CLUSTER.test.v1.0.0")); + archetype.setRmRelease("0.9.0"); + + ex = assertThrows(ModelNotFoundException.class, () -> metaModelProvider.getMetaModel(archetype)); + assertEquals("model for other.OTHER version 0.9.0 not found", ex.getMessage()); + } + + + @Test + public void testGetMetaModelNoAomProfiles() { + MetaModelProvider metaModelProvider = new SimpleMetaModelProvider( + BuiltinReferenceModels.getAvailableModelInfoLookups(), + BuiltinReferenceModels.getBmmRepository() + ); + + Archetype archetype = new Archetype(); + archetype.setArchetypeId(new ArchetypeHRID("openEHR-EHR-CLUSTER.test.v1.0.0")); + archetype.setRmRelease("1.0.3"); + + MetaModel metaModel = metaModelProvider.getMetaModel(archetype); + assertTrue(metaModel.getModelInfoLookup() instanceof ArchieRMInfoLookup); + assertEquals("openehr", metaModel.getBmmModel().getRmPublisher()); + assertEquals("EHR", metaModel.getBmmModel().getModelName()); + assertEquals("1.0.3", metaModel.getBmmModel().getRmRelease()); + assertNull(metaModel.getAomProfile()); + assertNotNull(metaModel.getOdinInputObjectMapper()); + assertNotNull(metaModel.getOdinOutputObjectMapper()); + assertNotNull(metaModel.getJsonObjectMapper()); + + archetype.setRmRelease("1.0.4"); + + metaModel = metaModelProvider.getMetaModel(archetype); + assertTrue(metaModel.getModelInfoLookup() instanceof ArchieRMInfoLookup); + assertEquals("openehr", metaModel.getBmmModel().getRmPublisher()); + assertEquals("EHR", metaModel.getBmmModel().getModelName()); + assertEquals("1.0.4", metaModel.getBmmModel().getRmRelease()); + assertNull(metaModel.getAomProfile()); + assertNotNull(metaModel.getOdinInputObjectMapper()); + assertNotNull(metaModel.getOdinOutputObjectMapper()); + assertNotNull(metaModel.getJsonObjectMapper()); + + archetype.setRmRelease("1.99.1"); + + metaModel = metaModelProvider.getMetaModel(archetype); + assertTrue(metaModel.getModelInfoLookup() instanceof ArchieRMInfoLookup); + assertNull(metaModel.getBmmModel()); + assertNull(metaModel.getAomProfile()); + assertNotNull(metaModel.getOdinInputObjectMapper()); + assertNotNull(metaModel.getOdinOutputObjectMapper()); + assertNotNull(metaModel.getJsonObjectMapper()); + + archetype.setArchetypeId(new ArchetypeHRID("openEHR-TEST_PKG-CLUSTER.test.v1.0.0")); + archetype.setRmRelease("1.0.2"); + + metaModel = metaModelProvider.getMetaModel(archetype); + assertTrue(metaModel.getModelInfoLookup() instanceof TestRMInfoLookup); + assertEquals("openehr", metaModel.getBmmModel().getRmPublisher()); + assertEquals("TEST_PKG", metaModel.getBmmModel().getModelName()); + assertEquals("1.0.2", metaModel.getBmmModel().getRmRelease()); + assertNull(metaModel.getAomProfile()); + assertNull(metaModel.getOdinInputObjectMapper()); + assertNull(metaModel.getOdinOutputObjectMapper()); + assertNull(metaModel.getJsonObjectMapper()); + + archetype.setArchetypeId(new ArchetypeHRID("other-OTHER-CLUSTER.test.v1.0.0")); + archetype.setRmRelease("0.9.0"); + + ModelNotFoundException ex = assertThrows(ModelNotFoundException.class, () -> metaModelProvider.getMetaModel(archetype)); + assertEquals("model for other.OTHER version 0.9.0 not found", ex.getMessage()); + } +} diff --git a/referencemodels/src/test/java/org/openehr/referencemodels/BuiltInReferenceModelsTest.java b/referencemodels/src/test/java/org/openehr/referencemodels/BuiltInReferenceModelsTest.java index 3f403f8e5..72b0bbb3b 100644 --- a/referencemodels/src/test/java/org/openehr/referencemodels/BuiltInReferenceModelsTest.java +++ b/referencemodels/src/test/java/org/openehr/referencemodels/BuiltInReferenceModelsTest.java @@ -27,6 +27,7 @@ public void bmmRepository() throws Exception { } @Test + @Deprecated public void overrideModelVersion() throws Exception { MetaModels metaModels = BuiltinReferenceModels.getMetaModels(); Archetype archetype = new Archetype(); diff --git a/settings.gradle b/settings.gradle index 806003fdf..ba34972aa 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,7 @@ +plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '0.10.0' +} + rootProject.name = 'archie' include 'base', 'aom', 'grammars', 'tools', 'odin', 'openehr-rm', 'archie-utils' diff --git a/test-rm/build.gradle b/test-rm/build.gradle index d9a293192..76e32b58f 100644 --- a/test-rm/build.gradle +++ b/test-rm/build.gradle @@ -1,8 +1,9 @@ -description="OpenEHR Test RM package" +description = "OpenEHR Test RM package" dependencies { - api project(':base') - api project(':aom') //modelInfoLookup depends on CPrimitiveObject to convert from AOM objects to RM objects. So we need this dependency, at least for now - api project(':path-queries') - api project(':utils') - api project(':openehr-rm') -} \ No newline at end of file + api project(':base') + //modelInfoLookup depends on CPrimitiveObject to convert from AOM objects to RM objects. So we need the AOM dependency, at least for now + api project(':aom') + api project(':path-queries') + api project(':utils') + api project(':openehr-rm') +} diff --git a/tools/build.gradle b/tools/build.gradle index 615f06c8a..24265b5e4 100644 --- a/tools/build.gradle +++ b/tools/build.gradle @@ -1,19 +1,19 @@ description = "tools that operate on the archie reference models and archetype object model" dependencies { - api project(':grammars') - api project(':base') - api project(':aom') - api project(':bmm') - api project(':path-queries') - api project(':utils') - api project(':openehr-terminology') - testImplementation project(':openehr-rm') - testImplementation project(':archie-utils') - testImplementation project(':i18n') - testImplementation project(':test-rm') - testImplementation project(':referencemodels') + api project(':grammars') + api project(':base') + api project(':aom') + api project(':bmm') + api project(':path-queries') + api project(':utils') + api project(':openehr-terminology') + testImplementation project(':openehr-rm') + testImplementation project(':archie-utils') + testImplementation project(':i18n') + testImplementation project(':test-rm') + testImplementation project(':referencemodels') - api 'org.leadpony.justify:justify:3.1.0' - api 'org.glassfish:jakarta.json:2.0.1:module' + api(libs.leadpony.justify) + api(variantOf(libs.jakarta.json) { classifier("module") }) } diff --git a/tools/src/main/java/com/nedap/archie/adl14/ADL14Converter.java b/tools/src/main/java/com/nedap/archie/adl14/ADL14Converter.java index d8c6ab2c6..b22aec7ca 100644 --- a/tools/src/main/java/com/nedap/archie/adl14/ADL14Converter.java +++ b/tools/src/main/java/com/nedap/archie/adl14/ADL14Converter.java @@ -10,6 +10,7 @@ import com.nedap.archie.diff.Differentiator; import com.nedap.archie.flattener.Flattener; import com.nedap.archie.flattener.InMemoryFullArchetypeRepository; +import com.nedap.archie.rminfo.MetaModelProvider; import com.nedap.archie.rminfo.MetaModels; import java.text.MessageFormat; @@ -20,12 +21,20 @@ public class ADL14Converter { - private final MetaModels metaModels; + private final MetaModelProvider metaModelProvider; private final ADL14ConversionConfiguration conversionConfiguration; private InMemoryFullArchetypeRepository existingRepository; + /** + * @deprecated Use {@link #ADL14Converter(MetaModelProvider, ADL14ConversionConfiguration)} instead. + */ + @Deprecated public ADL14Converter(MetaModels metaModels, ADL14ConversionConfiguration conversionConfiguration) { - this.metaModels = metaModels; + this((MetaModelProvider) metaModels, conversionConfiguration); + } + + public ADL14Converter(MetaModelProvider metaModelProvider, ADL14ConversionConfiguration conversionConfiguration) { + this.metaModelProvider = metaModelProvider; this.conversionConfiguration = conversionConfiguration; } @@ -73,7 +82,7 @@ public ADL2ConversionResultList convert(List archetypes, ADL2Conversi // Process the archetypes ordered by specialization level unprocessed.sort(Comparator.comparingInt(Archetype::specializationDepth)); - Differentiator differentiator = new Differentiator(metaModels); + Differentiator differentiator = new Differentiator(metaModelProvider); for (Archetype archetype : unprocessed) { ADL2ConversionResult result; try { @@ -82,7 +91,7 @@ public ADL2ConversionResultList convert(List archetypes, ADL2Conversi if (parent == null) { throw new RuntimeException(MessageFormat.format("Cannot find parent {0} for archetype {1}", archetype.getParentArchetypeId(), archetype.getArchetypeId())); } - Archetype flatParent = new Flattener(repository, metaModels).flatten(parent); + Archetype flatParent = new Flattener(repository, metaModelProvider).flatten(parent); result = convert(archetype, flatParent, previousConversion); if (result.getArchetype() != null) { if (conversionConfiguration.isApplyDiff()) { @@ -125,16 +134,16 @@ private ADL2ConversionResult convert(Archetype archetype, Archetype flatParent, convertHeader(convertedArchetype); // Correct default multiplicities - new ADL14DefaultMultiplicitiesSetter(metaModels).setDefaults(convertedArchetype); + new ADL14DefaultMultiplicitiesSetter(metaModelProvider).setDefaults(convertedArchetype); // Convert nodeId's ADL2ConversionResult result = new ADL2ConversionResult(convertedArchetype); - ADL14NodeIDConverter adl14NodeIDConverter = new ADL14NodeIDConverter(this.metaModels, convertedArchetype, flatParent, conversionConfiguration, previousLog, result); + ADL14NodeIDConverter adl14NodeIDConverter = new ADL14NodeIDConverter(metaModelProvider, convertedArchetype, flatParent, conversionConfiguration, previousLog, result); ADL2ConversionLog conversionLog = adl14NodeIDConverter.convert(); result.setConversionLog(conversionLog); // Remove structures that are not default in ADL1.4, but are default in ADL2 - new DefaultRmStructureRemover(metaModels, true).removeRMDefaults(convertedArchetype); + new DefaultRmStructureRemover(metaModelProvider, true).removeRMDefaults(convertedArchetype); // Set some values that are not directly in ODIN or ADL ArchetypeParsePostProcessor.fixArchetype(convertedArchetype); diff --git a/tools/src/main/java/com/nedap/archie/adl14/DefaultRmStructureRemover.java b/tools/src/main/java/com/nedap/archie/adl14/DefaultRmStructureRemover.java index e69eb9675..069b3674d 100644 --- a/tools/src/main/java/com/nedap/archie/adl14/DefaultRmStructureRemover.java +++ b/tools/src/main/java/com/nedap/archie/adl14/DefaultRmStructureRemover.java @@ -3,6 +3,8 @@ import com.nedap.archie.adlparser.modelconstraints.BMMConstraintImposer; import com.nedap.archie.aom.*; import com.nedap.archie.base.MultiplicityInterval; +import com.nedap.archie.rminfo.MetaModel; +import com.nedap.archie.rminfo.MetaModelProvider; import com.nedap.archie.rminfo.MetaModels; import java.util.ArrayList; @@ -18,43 +20,63 @@ */ public class DefaultRmStructureRemover { - private final MetaModels metaModels; + private final MetaModelProvider metaModelProvider; private final boolean removeEmptyAttributes; + + private MetaModel metaModel; private BMMConstraintImposer constraintImposer; /** * Construct a DefaultRmStructureRemover that does not remove empty attributes * @param metaModels the metamodels containing metamodel information for the preset archetypes - * Part of the public API, do not remove + * @deprecated Use {@link #DefaultRmStructureRemover(MetaModelProvider)} instead. */ + @Deprecated public DefaultRmStructureRemover(MetaModels metaModels) { this(metaModels, false); } + /** + * Construct a DefaultRmStructureRemover that does not remove empty attributes + * @param metaModelProvider the metamodel provider for the preset archetypes + */ + public DefaultRmStructureRemover(MetaModelProvider metaModelProvider) { + this(metaModelProvider, false); + } + /** * Construct a DefaultRmStructureRemover * * @param metaModels the metamodels containing metamodel information for the preset archetypes * @param removeEmptyAttributes if true, will remove empty attributes. If false, will not + * @deprecated Use {@link #DefaultRmStructureRemover(MetaModelProvider, boolean)} instead. */ + @Deprecated public DefaultRmStructureRemover(MetaModels metaModels, boolean removeEmptyAttributes) { - this.metaModels = metaModels; + this((MetaModelProvider) metaModels, removeEmptyAttributes); + } + + /** + * Construct a DefaultRmStructureRemover + * + * @param metaModelProvider the metamodel provider for the preset archetypes + * @param removeEmptyAttributes if true, will remove empty attributes. If false, will not + */ + public DefaultRmStructureRemover(MetaModelProvider metaModelProvider, boolean removeEmptyAttributes) { + this.metaModelProvider = metaModelProvider; this.removeEmptyAttributes = removeEmptyAttributes; } public void removeRMDefaults(Archetype archetype) { - this.metaModels.selectModel(archetype); - if (metaModels.getSelectedModel() == null) { - throw new IllegalArgumentException("cannot find model for argument, so cannot remove default multiplicity"); - } - this.constraintImposer = new BMMConstraintImposer(metaModels.getSelectedBmmModel()); + metaModel = this.metaModelProvider.selectAndGetMetaModel(archetype); + this.constraintImposer = new BMMConstraintImposer(metaModel.getBmmModel()); removeRMDefaults(archetype.getDefinition()); } private void removeRMDefaults(CObject object) { // Remove occurrences if they are equal to the default occurrences of the object if (object.getOccurrences() != null) { - MultiplicityInterval defaultRMOccurrences = object.getDefaultRMOccurrences(metaModels::referenceModelPropMultiplicity); + MultiplicityInterval defaultRMOccurrences = object.getDefaultRMOccurrences(metaModel::referenceModelPropMultiplicity); if (defaultRMOccurrences.equals(object.getOccurrences())) { object.setOccurrences(null); } diff --git a/tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidation.java b/tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidation.java index b3da270dd..f62e89ba6 100644 --- a/tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidation.java +++ b/tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidation.java @@ -2,15 +2,25 @@ import com.nedap.archie.aom.Archetype; import com.nedap.archie.flattener.FullArchetypeRepository; +import com.nedap.archie.rminfo.MetaModel; import com.nedap.archie.rminfo.MetaModels; import java.util.List; +import java.util.Objects; /** * Created by pieter.bos on 31/03/2017. */ public interface ArchetypeValidation { - List validate(MetaModels models, Archetype archetype, Archetype flatParent, FullArchetypeRepository repository, ArchetypeValidationSettings settings); + /** + * @deprecated Use {@link #validate(MetaModel, Archetype, Archetype, FullArchetypeRepository, ArchetypeValidationSettings)} instead. + */ + @Deprecated + default List validate(MetaModels models, Archetype archetype, Archetype flatParent, FullArchetypeRepository repository, ArchetypeValidationSettings settings) { + return validate(Objects.requireNonNull(models.getSelectedModel(), "No MetaModel selected"), archetype, flatParent, repository, settings); + } + + List validate(MetaModel metaModel, Archetype archetype, Archetype flatParent, FullArchetypeRepository repository, ArchetypeValidationSettings settings); } diff --git a/tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidationBase.java b/tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidationBase.java index 2cf5684a4..b5a098af5 100644 --- a/tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidationBase.java +++ b/tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidationBase.java @@ -3,7 +3,7 @@ import com.nedap.archie.aom.Archetype; import com.nedap.archie.flattener.ArchetypeRepository; import com.nedap.archie.flattener.FullArchetypeRepository; -import com.nedap.archie.rminfo.MetaModels; +import com.nedap.archie.rminfo.MetaModel; import com.nedap.archie.rminfo.ModelInfoLookup; import java.util.ArrayList; @@ -16,19 +16,19 @@ public abstract class ArchetypeValidationBase implements ArchetypeValidation { protected FullArchetypeRepository repository; protected List messages; protected ModelInfoLookup lookup; - protected MetaModels combinedModels; + protected MetaModel metaModel; protected ArchetypeValidationSettings settings; public ArchetypeValidationBase() { } @Override - public List validate(MetaModels models, Archetype archetype, Archetype flatParent, FullArchetypeRepository repository, ArchetypeValidationSettings settings) { + public List validate(MetaModel metaModel, Archetype archetype, Archetype flatParent, FullArchetypeRepository repository, ArchetypeValidationSettings settings) { this.archetype = archetype; this.flatParent = flatParent; this.repository = repository; - this.lookup = models.getSelectedModelInfoLookup(); - this.combinedModels = models; + this.lookup = metaModel.getModelInfoLookup(); + this.metaModel = metaModel; this.settings = settings; messages = new ArrayList<>(); diff --git a/tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidator.java b/tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidator.java index 1b6dbe460..cd6f1997a 100644 --- a/tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidator.java +++ b/tools/src/main/java/com/nedap/archie/archetypevalidator/ArchetypeValidator.java @@ -1,6 +1,5 @@ package com.nedap.archie.archetypevalidator; -import com.google.common.base.Joiner; import com.nedap.archie.adlparser.modelconstraints.ReflectionConstraintImposer; import com.nedap.archie.aom.Archetype; import com.nedap.archie.aom.OperationalTemplate; @@ -11,8 +10,7 @@ import com.nedap.archie.flattener.FlattenerConfiguration; import com.nedap.archie.flattener.FullArchetypeRepository; import com.nedap.archie.flattener.OverridingInMemFullArchetypeRepository; -import com.nedap.archie.rminfo.MetaModels; -import com.nedap.archie.rminfo.ReferenceModels; +import com.nedap.archie.rminfo.*; import org.openehr.utils.message.I18n; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,7 +26,7 @@ public class ArchetypeValidator { private static final Logger logger = LoggerFactory.getLogger(ArchetypeValidator.class); - private MetaModels combinedModels; + private final MetaModelProvider metaModelProvider; private FlattenerConfiguration flattenerConfiguration = FlattenerConfiguration.forFlattened(); //see comment on why there is a phase 0 @@ -41,11 +39,19 @@ public class ArchetypeValidator { private List validationsPhase3; public ArchetypeValidator(ReferenceModels models) { - this(new MetaModels(models, null)); + this(new SimpleMetaModelProvider(models, null)); } + /** + * @deprecated Use {@link #ArchetypeValidator(MetaModelProvider)} instead. + */ + @Deprecated public ArchetypeValidator(MetaModels models) { - this.combinedModels = models; + this((MetaModelProvider) models); + } + + public ArchetypeValidator(MetaModelProvider metaModelProvider) { + this.metaModelProvider = metaModelProvider; validationsPhase0 = new ArrayList<>(); //defined in spec, but not in three phase validator and not in grammar //eiffel checks these in the parser @@ -120,14 +126,11 @@ public ValidationResult validate(Archetype archetype, FullArchetypeRepository re } repository = extraRepository; - combinedModels.selectModel(archetype); + MetaModel metaModel = metaModelProvider.selectAndGetMetaModel(archetype); - if(combinedModels.getSelectedModelInfoLookup() == null && combinedModels.getSelectedBmmModel() == null) { - throw new UnsupportedOperationException("reference model unknown for archetype " + archetype.getArchetypeId()); - } //we assume we always want a new validation to be run, for example because the archetype //has been updated. Therefore, do not retrieve the old result from the repository - archetype = cloneAndPreprocess(combinedModels, archetype);//this clones the actual archetype so the source does not get changed + archetype = cloneAndPreprocess(metaModel, archetype);//this clones the actual archetype so the source does not get changed Archetype flatParent = null; if(archetype.isSpecialized()) { ValidationResult infiniteLoopResult = checkForInfiniteLoopInSpecialisation(repository, archetype); @@ -135,7 +138,7 @@ public ValidationResult validate(Archetype archetype, FullArchetypeRepository re return infiniteLoopResult; } ValidationResult parentValidationResult = repository.compileAndRetrieveValidationResult(archetype.getParentArchetypeId(), this); - combinedModels.selectModel(archetype); + metaModelProvider.selectAndGetMetaModel(archetype); // For backwards compatibility if(parentValidationResult != null) { if(parentValidationResult.passes()) { flatParent = parentValidationResult.getFlattened(); @@ -171,23 +174,23 @@ public ValidationResult validate(Archetype archetype, FullArchetypeRepository re for(TemplateOverlay overlay:((Template) archetype).getTemplateOverlays()) { //validate the overlays first, but make sure to do that only once (so don't call this same method!) extraRepository.compileAndRetrieveValidationResult(overlay.getArchetypeId().toString(), this); - combinedModels.selectModel(archetype); + metaModelProvider.selectAndGetMetaModel(archetype); // For backwards compatibility } } - List messages = runValidations(archetype, repository, settings, flatParent, validationsPhase0); + List messages = runValidations(metaModel, archetype, repository, settings, flatParent, validationsPhase0); ValidationResult result = new ValidationResult(archetype); result.setErrors(messages); if(result.passes()) { //continue running only if the basic phase 0 validation run, otherwise we get annoying exceptions - messages.addAll(runValidations(archetype, repository, settings, flatParent, validationsPhase1)); + messages.addAll(runValidations(metaModel, archetype, repository, settings, flatParent, validationsPhase1)); //the separate validations will check if the archtype is specialized and if they need this in phase 2 //because the RM validations are technically phase 2 and required to run //also the separate validations are implemented so that they can run with errors in phase 1 without exceptions //plus exceptions will nicely be logged as an OTHER error type - we can safely run it and you will get //more errors in one go - could be useful - messages.addAll(runValidations(archetype, repository, settings, flatParent, validationsPhase2)); + messages.addAll(runValidations(metaModel, archetype, repository, settings, flatParent, validationsPhase2)); } result.setErrors(messages); @@ -203,25 +206,26 @@ public ValidationResult validate(Archetype archetype, FullArchetypeRepository re if(result.passes() || settings.isAlwaysTryToFlatten()) { try { - Archetype flattened = new Flattener(repository, combinedModels, flattenerConfiguration).flatten(archetype); + Archetype flattened = new Flattener(repository, metaModelProvider, flattenerConfiguration).flatten(archetype); try { - OperationalTemplate operationalTemplate = (OperationalTemplate) new Flattener(repository, combinedModels).createOperationalTemplate(true).flatten(archetype); + OperationalTemplate operationalTemplate = (OperationalTemplate) new Flattener(repository, metaModelProvider).createOperationalTemplate(true).flatten(archetype); extraRepository.addExtraOperationalTemplate(operationalTemplate); } catch (Exception e) { //this is probably an error in an included archetype, so ignore it here //the other archetype will not validate - ValidationMessage message = new ValidationMessage(ErrorType.OTHER, null, "Error during Operational template creation. This does not necessarily mean the current archetype has a problem, but perhaps one that is included with use_archetype: " + e); + ValidationMessage message = new ValidationMessage(ErrorType.OTHER, null, "Error during operational template creation. This does not necessarily mean the current archetype has a problem, but perhaps one that is included with use_archetype."); message.setWarning(true); messages.add(message); + logger.debug("Error during operational template creation", e); } result.setFlattened(flattened); if(result.passes()) { - messages.addAll(runValidations(flattened, repository, settings, flatParent, validationsPhase3)); + messages.addAll(runValidations(metaModel, flattened, repository, settings, flatParent, validationsPhase3)); } } catch (Exception e) { - messages.add(new ValidationMessage(ErrorType.OTHER, null, "flattening failed with exception " + e)); - logger.error("error during validation", e); + messages.add(new ValidationMessage(ErrorType.OTHER, null, "Unexpected error during flattening")); + logger.error("Unexpected error during flattening", e); } } @@ -229,23 +233,21 @@ public ValidationResult validate(Archetype archetype, FullArchetypeRepository re return result; } - private Archetype cloneAndPreprocess(MetaModels models, Archetype archetype) { + private Archetype cloneAndPreprocess(MetaModel metaModel, Archetype archetype) { Archetype preprocessed = archetype.clone(); - new ReflectionConstraintImposer(models).setSingleOrMultiple(preprocessed.getDefinition()); + new ReflectionConstraintImposer(metaModel).setSingleOrMultiple(preprocessed.getDefinition()); return preprocessed; } - private List runValidations(Archetype archetype, FullArchetypeRepository repository, ArchetypeValidationSettings settings, Archetype flatParent, List validations) { + private List runValidations(MetaModel metaModel, Archetype archetype, FullArchetypeRepository repository, ArchetypeValidationSettings settings, Archetype flatParent, List validations) { List messages = new ArrayList<>(); for(ArchetypeValidation validation: validations) { try { - messages.addAll(validation.validate(combinedModels, archetype, flatParent, repository, settings)); + messages.addAll(validation.validate(metaModel, archetype, flatParent, repository, settings)); } catch (Exception e) { - logger.error("error running validation processor", e); - e.printStackTrace(); - messages.add(new ValidationMessage(ErrorType.OTHER, null, "error running validator : " + e.getClass().getSimpleName() + - Joiner.on("\n").join(e.getStackTrace()))); + logger.error("Unexpected error running validation processor", e); + messages.add(new ValidationMessage(ErrorType.OTHER, null, "Unexpected error running validation processor")); } } return messages; diff --git a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/AnnotationsValidation.java b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/AnnotationsValidation.java index 122d4a2ad..35bcae8f3 100644 --- a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/AnnotationsValidation.java +++ b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/AnnotationsValidation.java @@ -32,7 +32,7 @@ public void validate() { //apparently the operational template creation failed. Try to lookup the path anyway in the original archetype operationalTemplate = archetype; } - if(!AOMUtils.isPathInArchetypeOrRm(combinedModels.getSelectedModel(), path, operationalTemplate)) { + if(!AOMUtils.isPathInArchetypeOrRm(metaModel, path, operationalTemplate)) { addMessage(ErrorType.VRANP, I18n.t("The path {0} referenced in the annotations does not exist in the flat archetype or reference model", path)); } } diff --git a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/AttributeTupleValidation.java b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/AttributeTupleValidation.java index 5896869ef..bca9cd5ce 100644 --- a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/AttributeTupleValidation.java +++ b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/AttributeTupleValidation.java @@ -25,7 +25,7 @@ protected void validate(CComplexObject cObject) { addMessageWithPath(ErrorType.OTHER, cObject.getPath(), "An attribute tuple must have members"); } else { for(CAttribute cAttribute:tuple.getMembers()) { - if (!combinedModels.attributeExists(cObject.getRmTypeName(), cAttribute.getRmAttributeName())) { + if (!metaModel.attributeExists(cObject.getRmTypeName(), cAttribute.getRmAttributeName())) { addMessageWithPath(ErrorType.VCARM, cObject.getPath(), I18n.t("Tuple member attribute {0} is not an attribute of type {1}", cAttribute.getRmAttributeName(), cObject.getRmTypeName())); } diff --git a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java index 6e4d8cc7d..35bddbcd5 100644 --- a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java +++ b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/BasicTerminologyValidation.java @@ -80,7 +80,7 @@ private void validateTerminologyBindings() { //if not a valid path, fine } if (!AOMUtils.isValidCode(constraintCodeOrPath) && !( - archetypeHasPath || combinedModels.hasReferenceModelPath(archetype.getDefinition().getRmTypeName(), constraintCodeOrPath) + archetypeHasPath || metaModel.hasReferenceModelPath(archetype.getDefinition().getRmTypeName(), constraintCodeOrPath) ) ) { addMessage(ErrorType.VTTBK, I18n.t("Term binding key {0} in path format is not present in archetype", constraintCodeOrPath)); diff --git a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/CodeValidation.java b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/CodeValidation.java index e1bcf560e..da52929ab 100644 --- a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/CodeValidation.java +++ b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/CodeValidation.java @@ -29,7 +29,7 @@ public void validate(CObject cObject) { addMessageWithPath(ErrorType.VTSD, cObject.path(), I18n.t("The code specialization depth of code {0} is {1}, which is greater than archetype specialization depth {2}", nodeId, codeSpecializationDepth, archetypeSpecializationDepth)); - } else if (cObject.isRoot() || parentIsMultiple(cObject, flatParent, combinedModels)) { + } else if (cObject.isRoot() || parentIsMultiple(cObject, flatParent, metaModel)) { if ((codeSpecializationDepth < archetypeSpecializationDepth && flatParent != null && !flatParent.getTerminology().hasIdCode(nodeId)) || (codeSpecializationDepth == archetypeSpecializationDepth && !archetype.getTerminology().hasIdCode(nodeId))) { addMessageWithPath(ErrorType.VATID, cObject.path(), diff --git a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/DefinitionStructureValidation.java b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/DefinitionStructureValidation.java index c6f0818a2..42a6707e7 100644 --- a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/DefinitionStructureValidation.java +++ b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/DefinitionStructureValidation.java @@ -58,7 +58,7 @@ protected void validate(CAttribute cAttribute) { addPathNotFoundInParentError(cAttribute); } else { PathSegment terminalNode = pathSegments.get(pathSegments.size() - 1); - if (!combinedModels.attributeExists(parent.getRmTypeName(), terminalNode.getNodeName())) { + if (!metaModel.attributeExists(parent.getRmTypeName(), terminalNode.getNodeName())) { addPathNotFoundInParentError(cAttribute); } } diff --git a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java index 010a7edbf..e68b15d8b 100644 --- a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java +++ b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/FlatFormValidation.java @@ -35,7 +35,7 @@ protected void validate(CComplexObjectProxy cObject) { CComplexObject replacementComplexObject = complexObjectProxyReplacement.getReplacement(); - if(!combinedModels.rmTypesConformant(replacementComplexObject.getRmTypeName(), cObject.getRmTypeName())) { + if(!metaModel.rmTypesConformant(replacementComplexObject.getRmTypeName(), cObject.getRmTypeName())) { addMessageWithPath(ErrorType.VUNT, cObject.path(), I18n.t("Use_node (C_COMPLEX_OBJECT_PROXY) points to type {0}, which does not conform to type {1}", replacementComplexObject.getRmTypeName(), cObject.getRmTypeName())); } } else { @@ -78,7 +78,7 @@ private void validateTerminologyBindings() { //if not a valid path, fine } if(!AOMUtils.isValidCode(constraintCodeOrPath) && !( - archetypeHasPath || combinedModels.hasReferenceModelPath(archetype.getDefinition().getRmTypeName(), constraintCodeOrPath) + archetypeHasPath || metaModel.hasReferenceModelPath(archetype.getDefinition().getRmTypeName(), constraintCodeOrPath) ) ) { addMessage(ErrorType.VTTBK, I18n.t("Term binding key {0} points to a path that cannot be found in the archetype", constraintCodeOrPath)); diff --git a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/RmOverlayValidation.java b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/RmOverlayValidation.java index 5f618e33b..dc119dbe5 100644 --- a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/RmOverlayValidation.java +++ b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/RmOverlayValidation.java @@ -30,7 +30,7 @@ public void validate() { //apparently the operational template creation failed. Try to lookup the path anyway in the original archetype operationalTemplate = archetype; } - if(!AOMUtils.isPathInArchetypeOrRm(combinedModels.getSelectedModel(), path, operationalTemplate)) { + if(!AOMUtils.isPathInArchetypeOrRm(metaModel, path, operationalTemplate)) { addMessage(ErrorType.VRANP, I18n.t("The path {0} referenced in the rm visibility does not exist in the flat archetype", path)); } diff --git a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/SpecializedDefinitionValidation.java b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/SpecializedDefinitionValidation.java index e13859cba..0056af95b 100644 --- a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/SpecializedDefinitionValidation.java +++ b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/SpecializedDefinitionValidation.java @@ -139,7 +139,7 @@ private boolean hasAssertions(List assertions) { } private void validateConformsTo(CObject cObject, CObject parentCObject) { - ConformanceCheckResult conformanceCheckResult = cObject.cConformsTo(parentCObject, combinedModels::rmTypesConformant); + ConformanceCheckResult conformanceCheckResult = cObject.cConformsTo(parentCObject, metaModel::rmTypesConformant); if(!conformanceCheckResult.doesConform()) { if(conformanceCheckResult.getErrorType() != null) { @@ -156,7 +156,7 @@ private void validateConformsTo(CObject cObject, CObject parentCObject) { if(cComplexObject.getAttributeTuples() != null && parentCComplexObject.getAttributeTuples() != null) { for(CAttributeTuple tuple:cComplexObject.getAttributeTuples()) { CAttributeTuple matchingTuple = AOMUtils.findMatchingTuple(parentCComplexObject.getAttributeTuples(), tuple); - if(matchingTuple != null && ! tuple.cConformsTo(matchingTuple, combinedModels::rmTypesConformant)) { + if(matchingTuple != null && ! tuple.cConformsTo(matchingTuple, metaModel::rmTypesConformant)) { //tuple does not conform addMessageWithPath(ErrorType.VTPNC, cObject.path(), @@ -187,7 +187,7 @@ private void validateConformsTo(CObject cObject, CObject parentCObject) { private boolean hasConformingParent(CAttribute parentAttribute, CPrimitiveObject member) { for(CObject parentCObject:parentAttribute.getChildren()) { - ConformanceCheckResult result = member.cConformsTo(parentCObject, (a, b) -> combinedModels.rmTypesConformant(a, b)); + ConformanceCheckResult result = member.cConformsTo(parentCObject, (a, b) -> metaModel.rmTypesConformant(a, b)); if(result.doesConform()) { return true; } @@ -257,12 +257,12 @@ private boolean rootMatchesSlotType(ArchetypeSlot slot, CArchetypeRoot root) { String rootRmTypeName = root.getRmTypeName(); String rootReferenceRmTypeName = new ArchetypeHRID(root.getArchetypeRef()).getRmClass(); - if(!combinedModels.typeNameExists(rootRmTypeName) || !combinedModels.typeNameExists(rootReferenceRmTypeName)) { + if(!metaModel.typeNameExists(rootRmTypeName) || !metaModel.typeNameExists(rootReferenceRmTypeName)) { return false; } - else if(!combinedModels.rmTypesConformant(rootRmTypeName, slotRmTypeName)) { + else if(!metaModel.rmTypesConformant(rootRmTypeName, slotRmTypeName)) { return false; - } else if (!combinedModels.rmTypesConformant(rootReferenceRmTypeName, slotRmTypeName)) { + } else if (!metaModel.rmTypesConformant(rootReferenceRmTypeName, slotRmTypeName)) { return false; } return true; diff --git a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/SpecializedOccurrencesValidation.java b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/SpecializedOccurrencesValidation.java index edb055089..a74619dfd 100644 --- a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/SpecializedOccurrencesValidation.java +++ b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/SpecializedOccurrencesValidation.java @@ -81,8 +81,8 @@ private ConformanceCheckResult childNodesConformToParent(CObject childCObject, C return ConformanceCheckResult.conforms(); } - MultiplicityInterval parentNodeOccurrences = parentCObject.effectiveOccurrences(combinedModels::referenceModelPropMultiplicity); - MultiplicityInterval childNodeOccurrences = childCObject.effectiveOccurrences(combinedModels::referenceModelPropMultiplicity); + MultiplicityInterval parentNodeOccurrences = parentCObject.effectiveOccurrences(metaModel::referenceModelPropMultiplicity); + MultiplicityInterval childNodeOccurrences = childCObject.effectiveOccurrences(metaModel::referenceModelPropMultiplicity); if(parentCObject.getNodeId().equals(childCObject.getNodeId()) && parentNodeOccurrences.equals(childNodeOccurrences)) { //this is the parent node appearing in the flattened child archetype without change in occurrence. That is guaranteed to be valid @@ -97,7 +97,7 @@ private ConformanceCheckResult childNodesConformToParent(CObject childCObject, C if (allRedefinedNodeOccurrencesSummed.isOpen()) { break; } - MultiplicityInterval redefinedOccurrences = childNode.effectiveOccurrences(combinedModels::referenceModelPropMultiplicity); + MultiplicityInterval redefinedOccurrences = childNode.effectiveOccurrences(metaModel::referenceModelPropMultiplicity); if (!allRedefinedNodeOccurrencesSummed.isLowerUnbounded()) { Integer lower = allRedefinedNodeOccurrencesSummed.getLower(); if (!redefinedOccurrences.isLowerUnbounded()) { @@ -119,7 +119,7 @@ private ConformanceCheckResult childNodesConformToParent(CObject childCObject, C } MultiplicityInterval cardinality = childCObject.getParent().getCardinality() == null ? null : childCObject.getParent().getCardinality().getInterval(); if(cardinality == null) { - cardinality = combinedModels.referenceModelPropMultiplicity(childCObject.getParent().getParent().getRmTypeName(), childCObject.getParent().getRmAttributeName()); + cardinality = metaModel.referenceModelPropMultiplicity(childCObject.getParent().getParent().getRmTypeName(), childCObject.getParent().getRmAttributeName()); } if(cardinality != null && !cardinality.isUpperUnbounded() && (allRedefinedNodeOccurrencesSummed.isUpperUnbounded() || allRedefinedNodeOccurrencesSummed.getUpper() > cardinality.getUpper())) { @@ -132,7 +132,7 @@ private ConformanceCheckResult childNodesConformToParent(CObject childCObject, C } return ConformanceCheckResult.fails(ErrorType.VSONCO, I18n.t("Occurrences {0}, which is the sum of {1}, does not conform to {2}", allRedefinedNodeOccurrencesSummed, - allRedefinedNodes.stream().map(c -> c.effectiveOccurrences(combinedModels::referenceModelPropMultiplicity).toString()).collect(Collectors.joining(", ")), + allRedefinedNodes.stream().map(c -> c.effectiveOccurrences(metaModel::referenceModelPropMultiplicity).toString()).collect(Collectors.joining(", ")), parentCObject.getOccurrences())); } } diff --git a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java index c53a068b2..205abf1cc 100644 --- a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java +++ b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/ValidateAgainstReferenceModel.java @@ -24,7 +24,7 @@ protected void validate(CComplexObject cObject) { } private void validateTypes(CObject cObject) { - if (!combinedModels.typeNameExists(cObject.getRmTypeName())) { + if (!metaModel.typeNameExists(cObject.getRmTypeName())) { addMessageWithPath(ErrorType.VCORM, cObject.getPath(), I18n.t("Type name {0} does not exist", cObject.getRmTypeName())); } else { CAttribute owningAttribute = cObject.getParent(); @@ -36,7 +36,7 @@ private void validateTypes(CObject cObject) { owningObject = differentialPathFromParent == null ? null : differentialPathFromParent.getParent(); } if (owningObject != null) { - if(!combinedModels.typeConformant(owningObject.getRmTypeName(), owningAttribute.getRmAttributeName(), cObject.getRmTypeName())) { + if(!metaModel.typeConformant(owningObject.getRmTypeName(), owningAttribute.getRmAttributeName(), cObject.getRmTypeName())) { addMessageWithPath(ErrorType.VCORMT, cObject.getPath(), I18n.t("Attribute {0}.{1} cannot contain type {2}", owningObject.getRmTypeName(), owningAttribute.getRmAttributeName(), cObject.getRmTypeName())); @@ -58,7 +58,7 @@ protected void validate(CPrimitiveObject cObject) { CAttribute attribute = cObject.getParent(); if(attribute.getDifferentialPath() == null) { CObject parentConstraint = attribute.getParent(); - if(!combinedModels.validatePrimitiveType(parentConstraint.getRmTypeName(), attribute.getRmAttributeName(), cObject)) { + if(!metaModel.validatePrimitiveType(parentConstraint.getRmTypeName(), attribute.getRmAttributeName(), cObject)) { addMessageWithPath(ErrorType.VCORMT, cObject.path(), I18n.t("Attribute {0}.{1} cannot be constrained by a {2}", parentConstraint.getRmTypeName(), attribute.getRmAttributeName(), cObject == null ? null : cObject.getClass().getSimpleName())); @@ -71,7 +71,7 @@ protected void validate(CPrimitiveObject cObject) { if(differentialPathFromParent instanceof CAttribute) { CAttribute parentAttribute = (CAttribute) differentialPathFromParent; CObject parentConstraint = parentAttribute.getParent(); - if(!combinedModels.validatePrimitiveType(parentConstraint.getRmTypeName(), parentAttribute.getRmAttributeName(), cObject)) { + if(!metaModel.validatePrimitiveType(parentConstraint.getRmTypeName(), parentAttribute.getRmAttributeName(), cObject)) { I18n.t("Attribute {0}.{1} cannot be constrained by a {2}", parentConstraint.getRmTypeName(), parentAttribute.getRmAttributeName(), cObject == null ? null : cObject.getClass().getSimpleName()); } @@ -94,11 +94,11 @@ public void validate(CAttribute cAttribute) { owningObject = differentialPathFromParent == null ? null : differentialPathFromParent.getParent(); } if(owningObject != null) { - if (!combinedModels.attributeExists(owningObject.getRmTypeName(), cAttribute.getRmAttributeName())) { + if (!metaModel.attributeExists(owningObject.getRmTypeName(), cAttribute.getRmAttributeName())) { addMessageWithPath(ErrorType.VCARM, cAttribute.getPath(), I18n.t("{0} is not a known attribute of {1}", cAttribute.getRmAttributeName(), owningObject.getRmTypeName())); } else { - CAttribute defaultAttribute = new ReflectionConstraintImposer(combinedModels).getDefaultAttribute(owningObject.getRmTypeName(), cAttribute.getRmAttributeName()); + CAttribute defaultAttribute = new ReflectionConstraintImposer(metaModel).getDefaultAttribute(owningObject.getRmTypeName(), cAttribute.getRmAttributeName()); if(defaultAttribute != null) { if(cAttribute.getExistence() != null) { if(!defaultAttribute.getExistence().contains(cAttribute.getExistence())) { diff --git a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java index 3d4935d7b..aa185bc0e 100644 --- a/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java +++ b/tools/src/main/java/com/nedap/archie/archetypevalidator/validations/VariousStructureValidation.java @@ -53,12 +53,12 @@ protected void validate(CComplexObject cComplexObject) { String archetypeRootTypeName = cComplexObject.getRmTypeName(); String archetypeReferenceTypeName = hrId.getRmClass(); - if (combinedModels.typeNameExists(archetypeRootTypeName)) { + if (metaModel.typeNameExists(archetypeRootTypeName)) { //if parent type info not found will be checked later in phase 2 - if (!combinedModels.typeNameExists(archetypeReferenceTypeName)) { + if (!metaModel.typeNameExists(archetypeReferenceTypeName)) { addMessageWithPath(ErrorType.VCORM, cComplexObject.getPath(), I18n.t("Archetype referenced in use_archetype points to class {0}, which does not exist in this reference model", cComplexObject.getRmTypeName())); - } else if (!combinedModels.rmTypesConformant(archetypeReferenceTypeName, archetypeRootTypeName)) { + } else if (!metaModel.rmTypesConformant(archetypeReferenceTypeName, archetypeRootTypeName)) { addMessageWithPath(ErrorType.VARXTV, cComplexObject.getPath(), I18n.t("Use_archetype points to type {0}, which is not conformant for type {1} of the archetype root used", cComplexObject.getRmTypeName(), archetypeRootTypeName)); diff --git a/tools/src/main/java/com/nedap/archie/creation/ExampleJsonInstanceGenerator.java b/tools/src/main/java/com/nedap/archie/creation/ExampleJsonInstanceGenerator.java index d8347502f..ee302ad85 100644 --- a/tools/src/main/java/com/nedap/archie/creation/ExampleJsonInstanceGenerator.java +++ b/tools/src/main/java/com/nedap/archie/creation/ExampleJsonInstanceGenerator.java @@ -10,6 +10,8 @@ import com.nedap.archie.aom.terminology.ValueSet; import com.nedap.archie.base.Interval; import com.nedap.archie.base.MultiplicityInterval; +import com.nedap.archie.rminfo.MetaModel; +import com.nedap.archie.rminfo.MetaModelProvider; import com.nedap.archie.rminfo.MetaModels; import org.openehr.bmm.core.*; import org.openehr.bmm.persistence.validation.BmmDefinitions; @@ -36,9 +38,10 @@ public class ExampleJsonInstanceGenerator { public static final String MISSING_TERM_IN_ARCHETYPE_FOR_LANGUAGE = "missing term in archetype for language "; private final String language; - private final MetaModels models; + private final MetaModelProvider metaModelProvider; private OperationalTemplate archetype; private String rmRelease; + private MetaModel metaModel; private BmmModel bmm; private AomProfile aomProfile; @@ -49,9 +52,17 @@ public class ExampleJsonInstanceGenerator { OpenEhrRmInstanceGenerator openEhrRmInstanceGenerator; + /** + * @deprecated Use {@link #ExampleJsonInstanceGenerator(MetaModelProvider, String)} instead. + */ + @Deprecated public ExampleJsonInstanceGenerator(MetaModels models, String language) { + this((MetaModelProvider) models, language); + } + + public ExampleJsonInstanceGenerator(MetaModelProvider metaModelProvider, String language) { this.language = language; - this.models = models; + this.metaModelProvider = metaModelProvider; openEhrRmInstanceGenerator = new OpenEhrRmInstanceGenerator(this, typePropertyName); } @@ -63,9 +74,9 @@ public Map generate(OperationalTemplate archetype) { !(rmRelease.equalsIgnoreCase("1.0.4") || rmRelease.equalsIgnoreCase("1.1.0"))) { rmRelease = "1.1.0"; } - models.selectModel(archetype, rmRelease); - aomProfile = models.getSelectedAomProfile(); - bmm = models.getSelectedBmmModel(); + metaModel = metaModelProvider.selectAndGetMetaModel(archetype, rmRelease); + aomProfile = metaModel.getAomProfile(); + bmm = metaModel.getBmmModel(); return generate(archetype.getDefinition()); } @@ -129,7 +140,7 @@ private Map generate(CComplexObject cObject) { List children = new ArrayList<>(); for (CObject child : attribute.getChildren()) { - MultiplicityInterval multiplicityInterval = child.effectiveOccurrences(models.getSelectedModel()::referenceModelPropMultiplicity); + MultiplicityInterval multiplicityInterval = child.effectiveOccurrences(metaModel::referenceModelPropMultiplicity); int occurrences = Math.max(1, multiplicityInterval.getLower()); if(multiplicityInterval.isProhibited()) { occurrences = 0; diff --git a/tools/src/main/java/com/nedap/archie/creation/RMObjectCreator.java b/tools/src/main/java/com/nedap/archie/creation/RMObjectCreator.java index 7d8661daa..512305e6b 100644 --- a/tools/src/main/java/com/nedap/archie/creation/RMObjectCreator.java +++ b/tools/src/main/java/com/nedap/archie/creation/RMObjectCreator.java @@ -11,8 +11,7 @@ import java.util.*; /** - * Utility to create Reference model objects based on their RM name. Also can set attribute values on RM Objects based - * on their RM Attribute name. + * Utility to create Reference model objects based on their RM name. * * Created by pieter.bos on 03/02/16. */ @@ -39,6 +38,10 @@ public T create(CObject constraint) { } } + /** + * @deprecated Use {@link com.nedap.archie.rminfo.AttributeAccessor#setValue(Object, String, Object)} + */ + @Deprecated public void set(Object object, String rmAttributeName, List values) { try { RMAttributeInfo attributeInfo = modelInfoLookup.getAttributeInfo(object.getClass(), rmAttributeName); @@ -69,6 +72,7 @@ public void set(Object object, String rmAttributeName, List values) { } + @Deprecated private void setSingleValuedAttribute(Object object, String rmAttributeName, List values, RMAttributeInfo attributeInfo) throws InvocationTargetException, IllegalAccessException { if(values == null || values.isEmpty()) { setField(object, attributeInfo, null); @@ -81,6 +85,7 @@ private void setSingleValuedAttribute(Object object, String rmAttributeName, Lis } } + @Deprecated private Object newInstance(RMAttributeInfo attributeInfo) throws InstantiationException, IllegalAccessException { if(attributeInfo.getType().equals(List.class)) { return new ArrayList<>(); @@ -93,6 +98,7 @@ private Object newInstance(RMAttributeInfo attributeInfo) throws InstantiationEx } } + @Deprecated private void setField(Object object, RMAttributeInfo field, Object value) throws InvocationTargetException, IllegalAccessException { Method setMethod = field.getSetMethod(); if(setMethod == null) { @@ -106,6 +112,10 @@ private void setField(Object object, RMAttributeInfo field, Object value) throws } } + /** + * @deprecated Use {@link com.nedap.archie.rminfo.AttributeAccessor#addValue(Object, String, Object)} + */ + @Deprecated public void addElementToList(Object object, RMAttributeInfo attributeInfo, Object element) { try { if(attributeInfo.getAddMethod() != null) { @@ -132,6 +142,10 @@ public void addElementToList(Object object, RMAttributeInfo attributeInfo, Objec } } + /** + * @deprecated Use {@link com.nedap.archie.rminfo.AttributeAccessor#addOrSetValue(Object, String, Object)} + */ + @Deprecated public void addElementToListOrSetSingleValues(Object object, String rmAttributeName, Object element) { RMAttributeInfo attributeInfo = this.modelInfoLookup.getAttributeInfo(object.getClass(), rmAttributeName); if(attributeInfo == null) { diff --git a/tools/src/main/java/com/nedap/archie/diff/Differentiator.java b/tools/src/main/java/com/nedap/archie/diff/Differentiator.java index 1c382ba77..51337baeb 100644 --- a/tools/src/main/java/com/nedap/archie/diff/Differentiator.java +++ b/tools/src/main/java/com/nedap/archie/diff/Differentiator.java @@ -5,34 +5,43 @@ import com.nedap.archie.adlparser.modelconstraints.ModelConstraintImposer; import com.nedap.archie.adlparser.modelconstraints.ReflectionConstraintImposer; import com.nedap.archie.aom.Archetype; +import com.nedap.archie.rminfo.MetaModel; +import com.nedap.archie.rminfo.MetaModelProvider; import com.nedap.archie.rminfo.MetaModels; public class Differentiator { - private final MetaModels metaModels; + private final MetaModelProvider metaModelProvider; + /** + * @deprecated Use {@link #Differentiator(MetaModelProvider)} instead. + */ + @Deprecated public Differentiator(MetaModels metaModels) { - this.metaModels = metaModels; + this((MetaModelProvider) metaModels); } + public Differentiator(MetaModelProvider metaModelProvider) { + this.metaModelProvider = metaModelProvider; + } public Archetype differentiate(Archetype flatChild, Archetype flatParent) { return differentiate(flatChild, flatParent, true); } public Archetype differentiate(Archetype flatChild, Archetype flatParent, boolean addSiblingOrder) { - metaModels.selectModel(flatChild); + MetaModel metaModel = metaModelProvider.selectAndGetMetaModel(flatChild); ModelConstraintImposer constraintImposer; - if(metaModels.getSelectedBmmModel() != null) { - constraintImposer = new BMMConstraintImposer(metaModels.getSelectedBmmModel()); + if(metaModel.getBmmModel() != null) { + constraintImposer = new BMMConstraintImposer(metaModel.getBmmModel()); } else { - constraintImposer = new ReflectionConstraintImposer(metaModels.getSelectedModelInfoLookup()); + constraintImposer = new ReflectionConstraintImposer(metaModel.getModelInfoLookup()); } Archetype result = flatChild.clone(); UnconstrainedIntervalRemover.removeUnconstrainedIntervals(result); if(addSiblingOrder) { - new LCSOrderingDiff(metaModels).addSiblingOrder(result, flatChild, flatParent); + new LCSOrderingDiff(metaModel).addSiblingOrder(result, flatChild, flatParent); } new ConstraintDifferentiator(constraintImposer, flatParent).removeUnspecializedConstraints(result, flatParent); new AnnotationDifferentiator().differentiate(result, flatParent); @@ -40,7 +49,7 @@ public Archetype differentiate(Archetype flatChild, Archetype flatParent, boolea new DifferentialPathGenerator().replace(result); new TerminologyDifferentiator().differentiate(result); - new DefaultRmStructureRemover(metaModels, false).removeRMDefaults(result); + new DefaultRmStructureRemover(metaModelProvider, false).removeRMDefaults(result); result.setDifferential(true); return result; diff --git a/tools/src/main/java/com/nedap/archie/diff/LCSOrderingDiff.java b/tools/src/main/java/com/nedap/archie/diff/LCSOrderingDiff.java index da4d597db..a3984092e 100644 --- a/tools/src/main/java/com/nedap/archie/diff/LCSOrderingDiff.java +++ b/tools/src/main/java/com/nedap/archie/diff/LCSOrderingDiff.java @@ -3,7 +3,7 @@ import com.nedap.archie.aom.*; import com.nedap.archie.aom.utils.AOMUtils; import com.nedap.archie.aom.utils.CodeRedefinitionStatus; -import com.nedap.archie.rminfo.MetaModels; +import com.nedap.archie.rminfo.MetaModel; import java.util.LinkedHashMap; import java.util.List; @@ -18,10 +18,10 @@ */ public class LCSOrderingDiff { - private final MetaModels metaModels; + private final MetaModel metaModel; - LCSOrderingDiff(MetaModels metaModels) { - this.metaModels = metaModels; + LCSOrderingDiff(MetaModel metaModel) { + this.metaModel = metaModel; } public void addSiblingOrder(Archetype result, Archetype flatChild, Archetype flatParent) { @@ -68,11 +68,11 @@ public void addSiblingOrder(CComplexObject result, CComplexObject flatChild, CCo //descend into children first addSiblingOrder(resultAttribute, flatChildAttribute, parentAttribute); - if(!metaModels.isMultiple(parentAttribute.getParent().getRmTypeName(), parentAttribute.getRmAttributeName())){ + if(!metaModel.isMultiple(parentAttribute.getParent().getRmTypeName(), parentAttribute.getRmAttributeName())){ continue; } - if(!metaModels.isOrdered(parentAttribute.getParent().getRmTypeName(), parentAttribute.getRmAttributeName())){ + if(!metaModel.isOrdered(parentAttribute.getParent().getRmTypeName(), parentAttribute.getRmAttributeName())){ continue; } diff --git a/tools/src/main/java/com/nedap/archie/flattener/CAttributeFlattener.java b/tools/src/main/java/com/nedap/archie/flattener/CAttributeFlattener.java index 916867d54..c37c6c4e4 100644 --- a/tools/src/main/java/com/nedap/archie/flattener/CAttributeFlattener.java +++ b/tools/src/main/java/com/nedap/archie/flattener/CAttributeFlattener.java @@ -315,7 +315,7 @@ private boolean shouldRemoveParent(CObject specializedChildCObject, CObject matc private boolean shouldReplaceSpecializedParent(CObject parent, List differentialNodes) { - MultiplicityInterval occurrences = parent.effectiveOccurrences(flattener.getMetaModels()::referenceModelPropMultiplicity); + MultiplicityInterval occurrences = parent.effectiveOccurrences(flattener.getMetaModel()::referenceModelPropMultiplicity); //isSingle/isMultiple is tricky and not doable just in the parser. Don't use those if(isSingle(parent.getParent())) { return true; @@ -332,9 +332,9 @@ private boolean shouldReplaceSpecializedParent(CObject parent, List dif //in the rm, data maps to an ITEM_STRUCTURE that does not have the attribute items. //in the parent archetype, that is then an ITEM_TREE. We need to use ITEM_TREE here, which is what this code accomplishes. if(parent.getParent() == null || parent.getParent().getParent() == null) { - effectiveOccurrences = differentialNodes.get(0).effectiveOccurrences(flattener.getMetaModels()::referenceModelPropMultiplicity); + effectiveOccurrences = differentialNodes.get(0).effectiveOccurrences(flattener.getMetaModel()::referenceModelPropMultiplicity); } else { - effectiveOccurrences = differentialNodes.get(0).effectiveOccurrences((s, s2) -> flattener.getMetaModels().referenceModelPropMultiplicity( + effectiveOccurrences = differentialNodes.get(0).effectiveOccurrences((s, s2) -> flattener.getMetaModel().referenceModelPropMultiplicity( parent.getParent().getParent().getRmTypeName(), parent.getParent().getRmAttributeName())); } if(effectiveOccurrences != null && effectiveOccurrences.upperIsOne()) { @@ -347,7 +347,7 @@ private boolean shouldReplaceSpecializedParent(CObject parent, List dif private boolean isSingle(CAttribute attribute) { if(attribute != null && attribute.getParent() != null && attribute.getDifferentialPath() == null) { - return !flattener.getMetaModels().isMultiple(attribute.getParent().getRmTypeName(), attribute.getRmAttributeName()); + return !flattener.getMetaModel().isMultiple(attribute.getParent().getRmTypeName(), attribute.getRmAttributeName()); } return false; } diff --git a/tools/src/main/java/com/nedap/archie/flattener/Flattener.java b/tools/src/main/java/com/nedap/archie/flattener/Flattener.java index 8f57246d0..7b56e59f3 100644 --- a/tools/src/main/java/com/nedap/archie/flattener/Flattener.java +++ b/tools/src/main/java/com/nedap/archie/flattener/Flattener.java @@ -3,9 +3,7 @@ import com.nedap.archie.adlparser.modelconstraints.ReflectionConstraintImposer; import com.nedap.archie.aom.*; import com.nedap.archie.aom.utils.ArchetypeParsePostProcessor; -import com.nedap.archie.rminfo.MetaModels; -import com.nedap.archie.rminfo.ReferenceModels; -import org.openehr.bmm.v2.validation.BmmRepository; +import com.nedap.archie.rminfo.*; import java.util.ArrayList; import java.util.Collections; @@ -22,10 +20,12 @@ */ public class Flattener implements IAttributeFlattenerSupport { - private final MetaModels metaModels; + private final MetaModelProvider metaModelProvider; //to be able to store Template Overlays transparently during flattening private OverridingArchetypeRepository repository; + private MetaModel metaModel; + private Archetype parent; private Archetype child; @@ -43,20 +43,32 @@ public class Flattener implements IAttributeFlattenerSupport { public Flattener(ArchetypeRepository repository, ReferenceModels models) { - this.repository = new OverridingArchetypeRepository(repository); - this.metaModels = new MetaModels(models, (BmmRepository) null); - config = FlattenerConfiguration.forFlattened(); + this(repository, new SimpleMetaModelProvider(models, null)); } + /** + * @deprecated Use {@link #Flattener(ArchetypeRepository, MetaModelProvider)} instead. + */ + @Deprecated public Flattener(ArchetypeRepository repository, MetaModels models) { - this.repository = new OverridingArchetypeRepository(repository); - this.metaModels = models; - config = FlattenerConfiguration.forFlattened(); + this(repository, (MetaModelProvider) models); + } + + public Flattener(ArchetypeRepository repository, MetaModelProvider metaModelProvider) { + this(repository, metaModelProvider, FlattenerConfiguration.forFlattened()); } + /** + * @deprecated Use {@link #Flattener(ArchetypeRepository, MetaModelProvider, FlattenerConfiguration)} instead. + */ + @Deprecated public Flattener(ArchetypeRepository repository, MetaModels models, FlattenerConfiguration configuration) { + this(repository, (MetaModelProvider) models, configuration); + } + + public Flattener(ArchetypeRepository repository, MetaModelProvider metaModelProvider, FlattenerConfiguration configuration) { this.repository = new OverridingArchetypeRepository(repository); - this.metaModels = models; + this.metaModelProvider = metaModelProvider; this.config = configuration.clone(); } @@ -106,7 +118,7 @@ public Archetype flatten(Archetype toFlatten) { throw new IllegalStateException("You've used this flattener before - single use instance, please create a new one!"); } - metaModels.selectModel(toFlatten); + metaModel = metaModelProvider.selectAndGetMetaModel(toFlatten); //validate that we can legally flatten first String parentId = toFlatten.getParentArchetypeId(); @@ -234,7 +246,7 @@ public Archetype flatten(Archetype toFlatten) { ArchetypeParsePostProcessor.fixArchetype(result); //set the single/multiple attributes correctly - new ReflectionConstraintImposer(metaModels.getSelectedModel()) + new ReflectionConstraintImposer(metaModel) .setSingleOrMultiple(result.getDefinition()); return result; @@ -415,7 +427,7 @@ private void flattenCComplexObject(CComplexObject newObject, CComplexObject spec * @return */ protected Flattener getNewFlattenerForParent() { - Flattener result = new Flattener(repository, metaModels, config) + Flattener result = new Flattener(repository, metaModelProvider, config) .createOperationalTemplate(false); //do not create operational template except at the end. if(config.isRemoveZeroOccurrencesInParents()) { //remove all zero occurrences objects EXCEPT in the top level archetype @@ -433,7 +445,7 @@ protected Flattener getNewFlattenerForParent() { * @return */ protected Flattener getNewFlattener() { - return new Flattener(repository, metaModels, config); + return new Flattener(repository, metaModelProvider, config); } private Flattener useComplexObjectForArchetypeSlotReplacement(boolean useComplexObjectForArchetypeSlotReplacement) { @@ -446,8 +458,18 @@ public boolean isUseComplexObjectForArchetypeSlotReplacement() { } @Override + public MetaModel getMetaModel() { + return metaModel; + } + + @Override + @Deprecated public MetaModels getMetaModels() { - return metaModels; + if(metaModelProvider instanceof MetaModels) { + return (MetaModels) metaModelProvider; + } else { + throw new IllegalStateException("MetaModels not available"); + } } @Override diff --git a/tools/src/main/java/com/nedap/archie/flattener/FullArchetypeRepository.java b/tools/src/main/java/com/nedap/archie/flattener/FullArchetypeRepository.java index 70c020d81..09b8da517 100644 --- a/tools/src/main/java/com/nedap/archie/flattener/FullArchetypeRepository.java +++ b/tools/src/main/java/com/nedap/archie/flattener/FullArchetypeRepository.java @@ -5,6 +5,7 @@ import com.nedap.archie.archetypevalidator.ArchetypeValidationSettings; import com.nedap.archie.archetypevalidator.ArchetypeValidator; import com.nedap.archie.archetypevalidator.ValidationResult; +import com.nedap.archie.rminfo.MetaModelProvider; import com.nedap.archie.rminfo.MetaModels; import com.nedap.archie.rminfo.ReferenceModels; @@ -40,18 +41,26 @@ default void compile(ReferenceModels models) { compile(validator); } + /** + * @deprecated Use {@link #compile(MetaModelProvider)} instead. + */ + @Deprecated default void compile(MetaModels models) { - ArchetypeValidator validator = new ArchetypeValidator(models); + compile((MetaModelProvider) models); + } + + default void compile(MetaModelProvider metaModelProvider) { + ArchetypeValidator validator = new ArchetypeValidator(metaModelProvider); compile(validator); } /** * validate the validation result if necessary, and return either the newly validated one or * the existing validation result - * @param models + * @param metaModelProvider * @return */ - default ValidationResult compileAndRetrieveValidationResult(String archetypeId, MetaModels models) { + default ValidationResult compileAndRetrieveValidationResult(String archetypeId, MetaModelProvider metaModelProvider) { Archetype archetype = getArchetype(archetypeId); if(archetype == null) { return null; @@ -63,10 +72,21 @@ default ValidationResult compileAndRetrieveValidationResult(String archetypeId, return validationResult; } - ArchetypeValidator validator = new ArchetypeValidator(models); + ArchetypeValidator validator = new ArchetypeValidator(metaModelProvider); return validator.validate(archetype, this); } + /** + * validate the validation result if necessary, and return either the newly validated one or + * the existing validation result + * @param models + * @return + */ + @Deprecated + default ValidationResult compileAndRetrieveValidationResult(String archetypeId, MetaModels models) { + return compileAndRetrieveValidationResult(archetypeId, (MetaModelProvider) models); + } + /** * validate the validation result if necessary, and return either the newly validated one or * the existing validation result diff --git a/tools/src/main/java/com/nedap/archie/flattener/IAttributeFlattenerSupport.java b/tools/src/main/java/com/nedap/archie/flattener/IAttributeFlattenerSupport.java index d9b6db9f0..1c6219649 100644 --- a/tools/src/main/java/com/nedap/archie/flattener/IAttributeFlattenerSupport.java +++ b/tools/src/main/java/com/nedap/archie/flattener/IAttributeFlattenerSupport.java @@ -2,12 +2,20 @@ import com.nedap.archie.aom.CAttribute; import com.nedap.archie.aom.CObject; +import com.nedap.archie.rminfo.MetaModel; import com.nedap.archie.rminfo.MetaModels; public interface IAttributeFlattenerSupport { CObject createSpecializeCObject(CAttribute attribute, CObject parent, CObject specialized); + + /** + * @deprecated Use {@link #getMetaModel()} instead. + */ + @Deprecated public MetaModels getMetaModels(); + public MetaModel getMetaModel(); + public FlattenerConfiguration getConfig(); } diff --git a/tools/src/main/java/com/nedap/archie/flattener/OperationalTemplateCreator.java b/tools/src/main/java/com/nedap/archie/flattener/OperationalTemplateCreator.java index 92d053cd3..76e292152 100644 --- a/tools/src/main/java/com/nedap/archie/flattener/OperationalTemplateCreator.java +++ b/tools/src/main/java/com/nedap/archie/flattener/OperationalTemplateCreator.java @@ -99,7 +99,7 @@ public void fillEmptyOccurrences(Archetype archetype) { CObject object = workList.pop(); if( (object instanceof CComplexObject || object instanceof ArchetypeSlot || object instanceof CComplexObjectProxy) && object.getOccurrences() == null) { - object.setOccurrences(object.effectiveOccurrences(flattener.getMetaModels()::referenceModelPropMultiplicity)); + object.setOccurrences(object.effectiveOccurrences(flattener.getMetaModel()::referenceModelPropMultiplicity)); } for (CAttribute attribute : object.getAttributes()) { diff --git a/tools/src/main/java/com/nedap/archie/json/flat/FlatJsonExampleInstanceGenerator.java b/tools/src/main/java/com/nedap/archie/json/flat/FlatJsonExampleInstanceGenerator.java index 0fd9e231e..ed090d616 100644 --- a/tools/src/main/java/com/nedap/archie/json/flat/FlatJsonExampleInstanceGenerator.java +++ b/tools/src/main/java/com/nedap/archie/json/flat/FlatJsonExampleInstanceGenerator.java @@ -5,6 +5,8 @@ import com.nedap.archie.aom.OperationalTemplate; import com.nedap.archie.base.OpenEHRBase; import com.nedap.archie.creation.ExampleJsonInstanceGenerator; +import com.nedap.archie.rminfo.MetaModel; +import com.nedap.archie.rminfo.MetaModelProvider; import com.nedap.archie.rminfo.MetaModels; import java.util.Map; @@ -21,26 +23,40 @@ public class FlatJsonExampleInstanceGenerator { * @return a flat json as generated by the FlatJsonGenerator, to be serialized with an objectmapper * @throws JsonProcessingException in case the ExampleJsonInstanceGenerator generates json that the objectmapper cannot process * @throws DuplicateKeyException in case the FlatJsonGenerator generates incorrect data for this OperationalTemplate + * @deprecated Use {@link #generateExample(OperationalTemplate, MetaModelProvider, String, FlatJsonFormatConfiguration)} instead. */ + @Deprecated public Map generateExample(OperationalTemplate template, MetaModels metaModels, String language, FlatJsonFormatConfiguration jsonFormatConfiguration) throws JsonProcessingException, DuplicateKeyException { - metaModels.selectModel(template); - if(metaModels.getSelectedModel() == null) { - throw new IllegalArgumentException("Cannot find MetaModel for archetype"); - } - if(metaModels.getSelectedModelInfoLookup() == null) { + return generateExample(template, (MetaModelProvider) metaModels, language, jsonFormatConfiguration); + } + + /** + * Generate a flat JSON example instance for the given OperationalTemplate. + * + * @param template the template for which to generate the example + * @param metaModelProvider the metamodels to use. Must contain an actual RM ModelInfoLookup and a JSON Object Mapper + * @param language the language to generate the example in + * @param jsonFormatConfiguration the configuratin of the flat format + * @return a flat json as generated by the FlatJsonGenerator, to be serialized with an objectmapper + * @throws JsonProcessingException in case the ExampleJsonInstanceGenerator generates json that the objectmapper cannot process + * @throws DuplicateKeyException in case the FlatJsonGenerator generates incorrect data for this OperationalTemplate + */ + public Map generateExample(OperationalTemplate template, MetaModelProvider metaModelProvider, String language, FlatJsonFormatConfiguration jsonFormatConfiguration) throws JsonProcessingException, DuplicateKeyException { + MetaModel metaModel = metaModelProvider.selectAndGetMetaModel(template); + if(metaModel.getModelInfoLookup() == null) { throw new IllegalArgumentException("Cannot find ModelInfoLookup for archetype"); } - if(metaModels.getSelectedModel().getJsonObjectMapper() == null) { + if(metaModel.getJsonObjectMapper() == null) { throw new IllegalArgumentException("Cannot find JSON Object mapper in selected metamodel"); } - ExampleJsonInstanceGenerator exampleJsonInstanceGenerator = new ExampleJsonInstanceGenerator(metaModels, language); + ExampleJsonInstanceGenerator exampleJsonInstanceGenerator = new ExampleJsonInstanceGenerator(metaModelProvider, language); exampleJsonInstanceGenerator.setTypePropertyName("_type"); Map generatedExample = exampleJsonInstanceGenerator.generate(template); - ObjectMapper objectMapper = metaModels.getSelectedModel().getJsonObjectMapper(); + ObjectMapper objectMapper = metaModel.getJsonObjectMapper(); String jsonRmObject = objectMapper.writeValueAsString(generatedExample); OpenEHRBase openEHRBase = objectMapper.readValue(jsonRmObject, OpenEHRBase.class); - return new FlatJsonGenerator(metaModels.getSelectedModelInfoLookup(), jsonFormatConfiguration).buildPathsAndValues(openEHRBase, template, "en"); + return new FlatJsonGenerator(metaModel.getModelInfoLookup(), jsonFormatConfiguration).buildPathsAndValues(openEHRBase, template, "en"); } diff --git a/tools/src/main/java/com/nedap/archie/json/flat/FlatJsonGenerator.java b/tools/src/main/java/com/nedap/archie/json/flat/FlatJsonGenerator.java index 06a2242dc..f2538027e 100644 --- a/tools/src/main/java/com/nedap/archie/json/flat/FlatJsonGenerator.java +++ b/tools/src/main/java/com/nedap/archie/json/flat/FlatJsonGenerator.java @@ -7,11 +7,11 @@ import com.nedap.archie.aom.terminology.ArchetypeTerm; import com.nedap.archie.base.OpenEHRBase; import com.nedap.archie.datetime.DateTimeSerializerFormatters; +import com.nedap.archie.rminfo.AttributeAccessor; import com.nedap.archie.rminfo.ModelInfoLookup; import com.nedap.archie.rminfo.RMAttributeInfo; import com.nedap.archie.rminfo.RMTypeInfo; -import java.lang.reflect.InvocationTargetException; import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; import java.time.temporal.TemporalAccessor; @@ -31,6 +31,7 @@ public class FlatJsonGenerator { private final ModelInfoLookup modelInfoLookup; + private final AttributeAccessor attributeAccessor; private final List ignoredAttributes; @@ -51,6 +52,7 @@ public class FlatJsonGenerator { */ public FlatJsonGenerator(ModelInfoLookup modelInfoLookup, FlatJsonFormatConfiguration config) { this.modelInfoLookup = modelInfoLookup; + this.attributeAccessor = new AttributeAccessor(modelInfoLookup); this.writePipesForPrimitiveTypes = config.isWritePipesForPrimitiveTypes(); this.humanReadableFormat = false;//TODO: this is quite a bit of work to do properly, so definately not doing this now. this.indexNotation = config.getIndexNotation(); @@ -121,18 +123,14 @@ private void buildPathsAndValuesInner(Map result, RMTypeInfo rmA CAttribute cAttribute = cObject == null ? null : cObject.getAttribute(attributeName); RMAttributeInfo attributeInfo = typeInfo.getAttributes().get(attributeName); if(!attributeInfo.isComputed() && !isIgnored(typeInfo, attributeName) && attributeInfo.getGetMethod() != null) { - if(filterNames && cObject != null && isNameAttribute(typeInfo, attributeName)) { + if(filterNames && name != null && cObject != null && isNameAttribute(typeInfo, attributeName)) { ArchetypeTerm term = cObject.getTerm(); if(term != null && name.equals(term.getText())) { continue; } } - try { - Object child = attributeInfo.getGetMethod().invoke(rmObject); - addAttribute(result, pathSoFar, rmObject, child, attributeName,null, cAttribute); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e);//TODO: fine for now... - } + Object child = attributeAccessor.getValue(rmObject, attributeName); + addAttribute(result, pathSoFar, rmObject, child, attributeName,null, cAttribute); } } @@ -293,8 +291,8 @@ private void addAttribute(Map result, String pathSoFar, OpenEHRB storeValue(result, newPath, DateTimeSerializerFormatters.ISO_8601_TIME.format(t)); } } else if (child instanceof TemporalAmount) { - //duration or period. now just a toString, should this be a specific formatter? - storeValue(result, newPath, child); + // Serialize using DateTimeSerializerFormatters.serializeDuration to correctly handle negative durations + storeValue(result, newPath, DateTimeSerializerFormatters.serializeDuration((TemporalAmount) child)); } else if(child instanceof byte[]) { storeValue(result, newPath, Base64.getEncoder().encodeToString((byte[]) child)); } else { diff --git a/tools/src/main/java/com/nedap/archie/query/RMQueryContext.java b/tools/src/main/java/com/nedap/archie/query/RMQueryContext.java index e04101b24..d9fa70c45 100644 --- a/tools/src/main/java/com/nedap/archie/query/RMQueryContext.java +++ b/tools/src/main/java/com/nedap/archie/query/RMQueryContext.java @@ -1,7 +1,7 @@ package com.nedap.archie.query; +import com.nedap.archie.rminfo.AttributeAccessor; import com.nedap.archie.rminfo.ModelInfoLookup; -import com.nedap.archie.rminfo.RMAttributeInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; @@ -19,7 +19,6 @@ import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; -import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; @@ -34,7 +33,7 @@ public class RMQueryContext { private final XPathFactory xPathFactory; - private final ModelInfoLookup modelInfoLooup; + private final AttributeAccessor attributeAccessor; private Binder binder; private Document domForQueries; private Object rootNode; @@ -55,7 +54,7 @@ public class RMQueryContext { public RMQueryContext(ModelInfoLookup lookup, Object rootNode, JAXBContext jaxbContext) { try { this.rootNode = rootNode; - this.modelInfoLooup = lookup; + this.attributeAccessor = new AttributeAccessor(lookup); this.binder = jaxbContext.createBinder(); domForQueries = createBlankDOMDocument(true); @@ -129,12 +128,7 @@ private T getJAXBNode(Node node) { logger.error("trying to get a node without a parent"); return null; } - RMAttributeInfo attributeInfo = modelInfoLooup.getAttributeInfo(parent.getClass(), nodeName); - try { - return (T) attributeInfo.getGetMethod().invoke(parent); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } + return (T) attributeAccessor.getValue(parent, nodeName); } } diff --git a/tools/src/main/java/com/nedap/archie/rmobjectvalidator/RMObjectValidator.java b/tools/src/main/java/com/nedap/archie/rmobjectvalidator/RMObjectValidator.java index 230501039..e34e4737f 100644 --- a/tools/src/main/java/com/nedap/archie/rmobjectvalidator/RMObjectValidator.java +++ b/tools/src/main/java/com/nedap/archie/rmobjectvalidator/RMObjectValidator.java @@ -13,6 +13,8 @@ import com.nedap.archie.rminfo.ModelInfoLookup; import com.nedap.archie.rminfo.RMTypeInfo; import org.openehr.utils.message.I18n; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; @@ -26,6 +28,7 @@ * Created by pieter.bos on 15/02/16. */ public class RMObjectValidator extends RMObjectValidatingProcessor { + private static final Logger logger = LoggerFactory.getLogger(RMObjectValidator.class); private final MetaModel metaModel; private final OperationalTemplateProvider operationalTemplateProvider; @@ -167,13 +170,11 @@ private List validateInvariants(RMObjectWithPath obje } } catch (IllegalAccessException | InvocationTargetException e) { result.add(new RMObjectValidationMessage(null, joinPaths(pathSoFar, objectWithPath.getPath()), - I18n.t("Exception {0} invoking invariant {1} on {2}: {3}\n{4}", - e.getCause() == null ? e.getClass().getSimpleName() : e.getCause().getClass().getSimpleName(), + I18n.t("Unexpected error validating invariant {0} on {1}", invariantMethod.getAnnotation().value(), - typeInfo.getRmName(), - e.getCause() == null ? e.getMessage() : e.getCause().getMessage(), - Joiner.on("\n\t").join(e.getStackTrace())), + typeInfo.getRmName()), RMObjectValidationMessageType.EXCEPTION)); + logger.error("Unexpected error validating invariant {} on {}", invariantMethod.getAnnotation().value(), typeInfo.getRmName(), e); } } } diff --git a/tools/src/main/java/com/nedap/archie/rmobjectvalidator/RmTupleValidator.java b/tools/src/main/java/com/nedap/archie/rmobjectvalidator/RmTupleValidator.java index f35860830..f60290d45 100644 --- a/tools/src/main/java/com/nedap/archie/rmobjectvalidator/RmTupleValidator.java +++ b/tools/src/main/java/com/nedap/archie/rmobjectvalidator/RmTupleValidator.java @@ -1,20 +1,20 @@ package com.nedap.archie.rmobjectvalidator; import com.nedap.archie.aom.*; -import com.nedap.archie.query.RMObjectAttributes; import com.nedap.archie.query.RMObjectWithPath; +import com.nedap.archie.rminfo.AttributeAccessor; import com.nedap.archie.rminfo.ModelInfoLookup; import java.util.ArrayList; import java.util.List; class RmTupleValidator { - private final ModelInfoLookup lookup; + private final AttributeAccessor attributeAccessor; private final ValidationHelper validationHelper; private final RmPrimitiveObjectValidator rmPrimitiveObjectValidator; RmTupleValidator(ModelInfoLookup lookup, ValidationHelper validationHelper, RmPrimitiveObjectValidator rmPrimitiveObjectValidator) { - this.lookup = lookup; + this.attributeAccessor = new AttributeAccessor(lookup); this.validationHelper = validationHelper; this.rmPrimitiveObjectValidator = rmPrimitiveObjectValidator; } @@ -56,7 +56,7 @@ private List validateSingleTuple(String pathSoFar, Ob for(CAttribute attribute:attributeTuple.getMembers()) { String attributeName = attribute.getRmAttributeName(); CPrimitiveObject cPrimitiveObject = tuple.getMembers().get(index); - Object value = RMObjectAttributes.getAttributeValueFromRMObject(rmObject, attributeName, lookup); + Object value = attributeAccessor.getValue(rmObject, attributeName); String path = pathSoFar + "/" + attributeName + "[" + cPrimitiveObject.getNodeId() + "]"; result.addAll(rmPrimitiveObjectValidator.validate_inner(value, path, cPrimitiveObject)); diff --git a/tools/src/main/java/com/nedap/archie/rmobjectvalidator/ValidationHelper.java b/tools/src/main/java/com/nedap/archie/rmobjectvalidator/ValidationHelper.java index 5d5ab4bdb..522719689 100644 --- a/tools/src/main/java/com/nedap/archie/rmobjectvalidator/ValidationHelper.java +++ b/tools/src/main/java/com/nedap/archie/rmobjectvalidator/ValidationHelper.java @@ -4,10 +4,9 @@ import com.nedap.archie.aom.CAttributeTuple; import com.nedap.archie.aom.CPrimitiveObject; import com.nedap.archie.aom.CPrimitiveTuple; +import com.nedap.archie.rminfo.AttributeAccessor; import com.nedap.archie.rminfo.ModelInfoLookup; -import com.nedap.archie.rminfo.RMAttributeInfo; -import java.lang.reflect.InvocationTargetException; import java.util.HashMap; /** @@ -15,10 +14,12 @@ */ public class ValidationHelper { private final ModelInfoLookup lookup; + private final AttributeAccessor attributeAccessor; private final PrimitiveObjectConstraintHelper primitiveObjectConstraintHelper; public ValidationHelper(ModelInfoLookup lookup, ValidationConfiguration validationConfiguration) { this.lookup = lookup; + this.attributeAccessor = new AttributeAccessor(lookup); this.primitiveObjectConstraintHelper = new PrimitiveObjectConstraintHelper(validationConfiguration); } @@ -84,15 +85,11 @@ boolean isValid(CAttributeTuple cAttributeTuple, Object value) { HashMap members = new HashMap<>(); for(CAttribute attribute:cAttributeTuple.getMembers()) { - RMAttributeInfo attributeInfo = lookup.getAttributeInfo(value.getClass(), attribute.getRmAttributeName()); - try { - if (attributeInfo != null && attributeInfo.getGetMethod() != null) { - members.put(attribute.getRmAttributeName(), attributeInfo.getGetMethod().invoke(value)); - } else { - //warn? throw exception? - } - } catch (InvocationTargetException | IllegalAccessException e) { - throw new RuntimeException(e); + String attributeName = attribute.getRmAttributeName(); + if (attributeAccessor.hasAttribute(value, attributeName)) { + members.put(attributeName, attributeAccessor.getValue(value, attributeName)); + } else { + //warn? throw exception? } } return isValid(cAttributeTuple, members); diff --git a/tools/src/main/java/com/nedap/archie/rmobjectvalidator/validations/RMTupleValidation.java b/tools/src/main/java/com/nedap/archie/rmobjectvalidator/validations/RMTupleValidation.java index 696dffcb0..ea109e54d 100644 --- a/tools/src/main/java/com/nedap/archie/rmobjectvalidator/validations/RMTupleValidation.java +++ b/tools/src/main/java/com/nedap/archie/rmobjectvalidator/validations/RMTupleValidation.java @@ -1,8 +1,8 @@ package com.nedap.archie.rmobjectvalidator.validations; import com.nedap.archie.aom.*; -import com.nedap.archie.query.RMObjectAttributes; import com.nedap.archie.query.RMObjectWithPath; +import com.nedap.archie.rminfo.AttributeAccessor; import com.nedap.archie.rminfo.ModelInfoLookup; import com.nedap.archie.rmobjectvalidator.RMObjectValidationMessage; import com.nedap.archie.rmobjectvalidator.RMObjectValidationMessageIds; @@ -48,6 +48,7 @@ public static List validate(ModelInfoLookup lookup, C * This will check each attribute in the tuple individually to get more specific validation messages. */ private static List validateSingleTuple(ModelInfoLookup lookup, String pathSoFar, Object rmObject, CAttributeTuple attributeTuple) { + AttributeAccessor attributeAccessor = new AttributeAccessor(lookup); List result = new ArrayList<>(); CPrimitiveTuple tuple = attributeTuple.getTuples().get(0); @@ -56,7 +57,7 @@ private static List validateSingleTuple(ModelInfoLook for(CAttribute attribute:attributeTuple.getMembers()) { String attributeName = attribute.getRmAttributeName(); CPrimitiveObject cPrimitiveObject = tuple.getMembers().get(index); - Object value = RMObjectAttributes.getAttributeValueFromRMObject(rmObject, attributeName, lookup); + Object value = attributeAccessor.getValue(rmObject, attributeName); String path = pathSoFar + "/" + attributeName + "[" + cPrimitiveObject.getNodeId() + "]"; result.addAll(RMPrimitiveObjectValidation.validate_inner(lookup, value, path, cPrimitiveObject)); diff --git a/tools/src/main/java/com/nedap/archie/rules/evaluation/AssertionsFixer.java b/tools/src/main/java/com/nedap/archie/rules/evaluation/AssertionsFixer.java index 166ca264c..6924f536e 100644 --- a/tools/src/main/java/com/nedap/archie/rules/evaluation/AssertionsFixer.java +++ b/tools/src/main/java/com/nedap/archie/rules/evaluation/AssertionsFixer.java @@ -1,16 +1,15 @@ package com.nedap.archie.rules.evaluation; -import com.google.common.collect.Lists; import com.nedap.archie.aom.*; import com.nedap.archie.creation.RMObjectCreator; import com.nedap.archie.query.RMObjectWithPath; import com.nedap.archie.query.RMPathQuery; +import com.nedap.archie.rminfo.AttributeAccessor; import com.nedap.archie.rminfo.ModelInfoLookup; import com.nedap.archie.rminfo.RMAttributeInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -24,17 +23,25 @@ public class AssertionsFixer { private static final Logger logger = LoggerFactory.getLogger(AssertionsFixer.class); - private final RMObjectCreator creator; private final RuleEvaluation ruleEvaluation; private final RMObjectCreator rmObjectCreator; private ModelInfoLookup modelInfoLookup; + private final AttributeAccessor attributeAccessor; + /** + * @deprecated Not intended for direct usage. Use RuleEvaluation instead. + */ + @Deprecated public AssertionsFixer(RuleEvaluation evaluation, RMObjectCreator creator) { - this.creator = creator; + this(evaluation); + } + + AssertionsFixer(RuleEvaluation evaluation) { this.ruleEvaluation = evaluation; this.modelInfoLookup = ruleEvaluation.getModelInfoLookup(); rmObjectCreator = new RMObjectCreator(evaluation.getModelInfoLookup()); + this.attributeAccessor = new AttributeAccessor(modelInfoLookup); } public Map fixSetPathAssertions(Archetype archetype, AssertionResult assertionResult) { @@ -63,15 +70,15 @@ public Map fixSetPathAssertions(Archetype archetype, AssertionRe throw new IllegalStateException("attribute " + lastPathSegment + " does not exist on type " + parent.getClass()); } if (value.getValue() == null) { - creator.set(parent, lastPathSegment, Lists.newArrayList(value.getValue())); + attributeAccessor.setValue(parent, lastPathSegment, value.getValue()); } else if (attributeInfo.getType().equals(Long.class) && value.getValue().getClass().equals(Double.class)) { Long convertedValue = ((Double) value.getValue()).longValue(); //TODO or should this round? - creator.set(parent, lastPathSegment, Lists.newArrayList(convertedValue)); + attributeAccessor.setValue(parent, lastPathSegment, convertedValue); } else if (attributeInfo.getType().equals(Double.class) && value.getValue().getClass().equals(Long.class)) { Double convertedValue = ((Long) value.getValue()).doubleValue(); //TODO or should this round? - creator.set(parent, lastPathSegment, Lists.newArrayList(convertedValue)); + attributeAccessor.setValue(parent, lastPathSegment, convertedValue); } else { - creator.set(parent, lastPathSegment, Lists.newArrayList(value.getValue())); + attributeAccessor.setValue(parent, lastPathSegment, value.getValue()); } result.putAll(modelInfoLookup.pathHasBeenUpdated(ruleEvaluation.getRMRoot(), archetype, pathOfParent, parent)); @@ -107,7 +114,7 @@ private void constructMissingStructure(Archetype archetype, String pathOfParent, Object newEmptyObject = null; newEmptyObject = constructEmptySimpleObject(newLastPathSegment, object, newEmptyObject); - creator.addElementToListOrSetSingleValues(object, newLastPathSegment, Lists.newArrayList(newEmptyObject)); + attributeAccessor.addOrSetValue(object, newLastPathSegment, newEmptyObject); ruleEvaluation.refreshQueryContext(); } else { CObject constraint = getCObjectFromResult(constraints); @@ -127,7 +134,7 @@ private void constructMissingStructure(Archetype archetype, String pathOfParent, attributeName = newLastPathSegment.substring(0, bracketIndex); } - creator.addElementToListOrSetSingleValues(object, attributeName, Lists.newArrayList(newEmptyObject)); + attributeAccessor.addOrSetValue(object, attributeName, newEmptyObject); ruleEvaluation.refreshQueryContext(); } @@ -202,18 +209,13 @@ private void removeObject(ObjectToRemove objectToRemove) { Object parent = objectToRemove.getParent(); Object object = objectToRemove.getObject(); - RMAttributeInfo attributeInfo = modelInfoLookup.getAttributeInfo(parent.getClass(), objectToRemove.getAttributeName()); - try { - Object attributeValue = attributeInfo.getGetMethod().invoke(parent); - if (attributeValue instanceof List) { - ((List) attributeValue).remove(object); - } else if (attributeValue == object) { - attributeInfo.getSetMethod().invoke(parent, (Object) null); - } else { - throw new IllegalStateException("Attribute value is not a list and not the object to remove"); - } - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); + Object attributeValue = attributeAccessor.getValue(parent, objectToRemove.getAttributeName()); + if (attributeValue instanceof List) { + ((List) attributeValue).remove(object); + } else if (attributeValue == object) { + attributeAccessor.setValue(parent, objectToRemove.getAttributeName(), null); + } else { + throw new IllegalStateException("Attribute value is not a list and not the object to remove"); } } diff --git a/tools/src/main/java/com/nedap/archie/rules/evaluation/RuleEvaluation.java b/tools/src/main/java/com/nedap/archie/rules/evaluation/RuleEvaluation.java index b03e79c30..1066d9879 100644 --- a/tools/src/main/java/com/nedap/archie/rules/evaluation/RuleEvaluation.java +++ b/tools/src/main/java/com/nedap/archie/rules/evaluation/RuleEvaluation.java @@ -2,7 +2,6 @@ import com.google.common.collect.ArrayListMultimap; import com.nedap.archie.aom.Archetype; -import com.nedap.archie.creation.RMObjectCreator; import com.nedap.archie.query.RMObjectWithPath; import com.nedap.archie.query.RMQueryContext; import com.nedap.archie.rminfo.ModelInfoLookup; @@ -47,8 +46,6 @@ public class RuleEvaluation { private ModelInfoLookup modelInfoLookup; - private RMObjectCreator creator; - private final JAXBContext jaxbContext; private RMQueryContext rmQueryContext; private APathQueryCache queryCache = new APathQueryCache(); @@ -96,8 +93,7 @@ public RuleEvaluation(ModelInfoLookup modelInfoLookup, JAXBContext jaxbContext, private RuleEvaluation(ModelInfoLookup modelInfoLookup, ValidationConfiguration validationConfiguration, JAXBContext jaxbContext, Archetype archetype) { this.jaxbContext = jaxbContext; this.modelInfoLookup = modelInfoLookup; - this.creator = new RMObjectCreator(modelInfoLookup); - this.assertionsFixer = new AssertionsFixer(this, creator); + this.assertionsFixer = new AssertionsFixer(this); this.archetype = archetype; this.functionEvaluator = new FunctionEvaluator(); add(new VariableDeclarationEvaluator()); diff --git a/tools/src/test/java/com/nedap/archie/adl14/ADL14DefaultOccurrencesConversionTest.java b/tools/src/test/java/com/nedap/archie/adl14/ADL14DefaultOccurrencesConversionTest.java index 3d85afb28..908cfb46d 100644 --- a/tools/src/test/java/com/nedap/archie/adl14/ADL14DefaultOccurrencesConversionTest.java +++ b/tools/src/test/java/com/nedap/archie/adl14/ADL14DefaultOccurrencesConversionTest.java @@ -19,10 +19,10 @@ public class ADL14DefaultOccurrencesConversionTest { @Test public void testDefaultOccurrencesConversion() throws Exception { ADL14ConversionConfiguration conversionConfiguration = ConversionConfigForTest.getConfig(); - ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModels(), conversionConfiguration); + ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModelProvider(), conversionConfiguration); //apply the first conversion and store the log. It has created an at code to bind to [openehr::124], used in a DV_QUANTITY.property try (InputStream stream = getClass().getResourceAsStream("/adl14/entry/evaluation/openEHR-EHR-EVALUATION.goal.v1.adl")) { - ADL14Parser parser = new ADL14Parser(BuiltinReferenceModels.getMetaModels()); + ADL14Parser parser = new ADL14Parser(BuiltinReferenceModels.getMetaModelProvider()); Archetype parsed = parser.parse(stream, conversionConfiguration); ADL2ConversionResultList result = converter.convert(Lists.newArrayList(parsed)); System.out.println(ADLArchetypeSerializer.serialize(result.getConversionResults().get(0).getArchetype())); diff --git a/tools/src/test/java/com/nedap/archie/adl14/ADL14ExternalTerminologyConversionTest.java b/tools/src/test/java/com/nedap/archie/adl14/ADL14ExternalTerminologyConversionTest.java index 13ebcb689..4afdae905 100644 --- a/tools/src/test/java/com/nedap/archie/adl14/ADL14ExternalTerminologyConversionTest.java +++ b/tools/src/test/java/com/nedap/archie/adl14/ADL14ExternalTerminologyConversionTest.java @@ -22,11 +22,11 @@ public class ADL14ExternalTerminologyConversionTest { @Test public void terminologyBindingsConverted() throws IOException, ADLParseException { ADL14ConversionConfiguration conversionConfiguration = ConversionConfigForTest.getConfig(); - ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModels(), conversionConfiguration); + ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModelProvider(), conversionConfiguration); //apply the first conversion and store the log. It has created an at code to bind to [openehr::124], used in a DV_QUANTITY.property try(InputStream stream = getClass().getResourceAsStream("/adl14/openEHR-EHR-CLUSTER.value_binding.v1.0.0.adl")) { ADL2ConversionResultList result = converter.convert( - Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModels()).parse(stream, conversionConfiguration))); + Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream, conversionConfiguration))); Archetype converted = result.getConversionResults().get(0).getArchetype(); CTerminologyCode termCodeConstraint = converted.itemAtPath("/items/value/property[1]"); String atCode = termCodeConstraint.getConstraint().get(0); @@ -43,10 +43,10 @@ public void terminologyBindingsConverted() throws IOException, ADLParseException @Test public void twoTermbindingsInOneConstraint() throws Exception { ADL14ConversionConfiguration conversionConfiguration = ConversionConfigForTest.getConfig(); - ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModels(), conversionConfiguration); + ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModelProvider(), conversionConfiguration); //apply the first conversion and store the log. It has created an at code to bind to [openehr::124], used in a DV_QUANTITY.property try(InputStream stream = getClass().getResourceAsStream("openEHR-EHR-CLUSTER.termbinding.v1.adl")) { - ADL14Parser parser = new ADL14Parser(BuiltinReferenceModels.getMetaModels()); + ADL14Parser parser = new ADL14Parser(BuiltinReferenceModels.getMetaModelProvider()); ADL2ConversionResultList result = converter.convert( Lists.newArrayList(parser.parse(stream, conversionConfiguration))); assertFalse(parser.getErrors().hasErrors()); diff --git a/tools/src/test/java/com/nedap/archie/adl14/ADL14InternalTerminologyTest.java b/tools/src/test/java/com/nedap/archie/adl14/ADL14InternalTerminologyTest.java index 3a9ac0951..b4a29b73b 100644 --- a/tools/src/test/java/com/nedap/archie/adl14/ADL14InternalTerminologyTest.java +++ b/tools/src/test/java/com/nedap/archie/adl14/ADL14InternalTerminologyTest.java @@ -19,11 +19,11 @@ public class ADL14InternalTerminologyTest { @Test public void internalTerminologyRemoved() throws IOException, ADLParseException { ADL14ConversionConfiguration conversionConfiguration = ConversionConfigForTest.getConfig(); - ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModels(), conversionConfiguration); + ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModelProvider(), conversionConfiguration); try(InputStream stream = getClass().getResourceAsStream("/adl14/openEHR-EHR-OBSERVATION.internal_terminology_test.v0.adl")) { ADL2ConversionResultList result = converter.convert( - Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModels()).parse(stream, conversionConfiguration))); + Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream, conversionConfiguration))); Archetype converted = result.getConversionResults().get(0).getArchetype(); // A terminology code is unnecessary if: // - The text.length < 19 diff --git a/tools/src/test/java/com/nedap/archie/adl14/ADL14TerminologyConversionTest.java b/tools/src/test/java/com/nedap/archie/adl14/ADL14TerminologyConversionTest.java index 99cf29b0d..9dc1ee02d 100644 --- a/tools/src/test/java/com/nedap/archie/adl14/ADL14TerminologyConversionTest.java +++ b/tools/src/test/java/com/nedap/archie/adl14/ADL14TerminologyConversionTest.java @@ -16,10 +16,10 @@ public class ADL14TerminologyConversionTest { @Test public void twoTermbindingsInOneConstraint() throws Exception { ADL14ConversionConfiguration conversionConfiguration = ConversionConfigForTest.getConfig(); - ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModels(), conversionConfiguration); + ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModelProvider(), conversionConfiguration); //apply the first conversion and store the log. It has created an at code to bind to [openehr::124], used in a DV_QUANTITY.property try(InputStream stream = getClass().getResourceAsStream("openEHR-EHR-CLUSTER.termbinding.v1.adl")) { - ADL14Parser parser = new ADL14Parser(BuiltinReferenceModels.getMetaModels()); + ADL14Parser parser = new ADL14Parser(BuiltinReferenceModels.getMetaModelProvider()); ADL2ConversionResultList result = converter.convert( Lists.newArrayList(parser.parse(stream, conversionConfiguration))); Archetype converted = result.getConversionResults().get(0).getArchetype(); diff --git a/tools/src/test/java/com/nedap/archie/adl14/ArchetypeSlotConversionTest.java b/tools/src/test/java/com/nedap/archie/adl14/ArchetypeSlotConversionTest.java index beecbad18..2f7dd51c0 100644 --- a/tools/src/test/java/com/nedap/archie/adl14/ArchetypeSlotConversionTest.java +++ b/tools/src/test/java/com/nedap/archie/adl14/ArchetypeSlotConversionTest.java @@ -20,12 +20,12 @@ public class ArchetypeSlotConversionTest { @Test public void testSlotConversion() throws Exception { ADL14ConversionConfiguration conversionConfiguration = ConversionConfigForTest.getConfig(); - ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModels(), conversionConfiguration); + ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModelProvider(), conversionConfiguration); ADL2ConversionRunLog log = null; try(InputStream stream = getClass().getResourceAsStream("/com/nedap/archie/adl14/openEHR-EHR-OBSERVATION.respiration.v1.adl")) { ADL2ConversionResultList result = converter.convert( - Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModels()).parse(stream, conversionConfiguration))); + Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream, conversionConfiguration))); Archetype archetype = result.getConversionResults().get(0).getArchetype(); ArchetypeSlot slot = archetype.itemAtPath("/data/events[1]/state[id23]/items[id56]"); String includesPattern = getPattern(slot.getIncludes().get(0)); diff --git a/tools/src/test/java/com/nedap/archie/adl14/AssumedValueConversionTest.java b/tools/src/test/java/com/nedap/archie/adl14/AssumedValueConversionTest.java index df7d572db..6d1b81612 100644 --- a/tools/src/test/java/com/nedap/archie/adl14/AssumedValueConversionTest.java +++ b/tools/src/test/java/com/nedap/archie/adl14/AssumedValueConversionTest.java @@ -18,11 +18,11 @@ public class AssumedValueConversionTest { @Test public void testAssumedValueConversion() throws Exception { ADL14ConversionConfiguration conversionConfiguration = ConversionConfigForTest.getConfig(); - ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModels(), conversionConfiguration); + ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModelProvider(), conversionConfiguration); Archetype adl14archetype; try(InputStream stream = getClass().getResourceAsStream("openEHR-EHR-OBSERVATION.height.v2.adl")) { - adl14archetype = new ADL14Parser(BuiltinReferenceModels.getMetaModels()).parse(stream, conversionConfiguration); + adl14archetype = new ADL14Parser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream, conversionConfiguration); } ADL2ConversionResultList result = converter.convert( @@ -35,7 +35,7 @@ public void testAssumedValueConversion() throws Exception { assertNull(cTerminologyCode.getAssumedValue().getTerminologyId()); assertEquals("at17", cTerminologyCode.getAssumedValue().getCodeString()); - ValidationResult validationResult = new ArchetypeValidator(BuiltinReferenceModels.getMetaModels()).validate(archetype); + ValidationResult validationResult = new ArchetypeValidator(BuiltinReferenceModels.getMetaModelProvider()).validate(archetype); assertTrue(validationResult.toString(), validationResult.passes()); } diff --git a/tools/src/test/java/com/nedap/archie/adl14/ConversionConfigurationTest.java b/tools/src/test/java/com/nedap/archie/adl14/ConversionConfigurationTest.java index a2144d322..913ba6e26 100644 --- a/tools/src/test/java/com/nedap/archie/adl14/ConversionConfigurationTest.java +++ b/tools/src/test/java/com/nedap/archie/adl14/ConversionConfigurationTest.java @@ -15,17 +15,17 @@ public class ConversionConfigurationTest { public void testRmRelease() throws Exception { ADL14ConversionConfiguration conversionConfiguration = ConversionConfigForTest.getConfig(); - ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModels(), conversionConfiguration); + ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModelProvider(), conversionConfiguration); try(InputStream stream = getClass().getResourceAsStream("openehr-EHR-COMPOSITION.review.v1.adl")) { - Archetype adl14 = new ADL14Parser(BuiltinReferenceModels.getMetaModels()).parse(stream, conversionConfiguration); + Archetype adl14 = new ADL14Parser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream, conversionConfiguration); ADL2ConversionResultList result = converter.convert(Lists.newArrayList(adl14)); assertEquals("1.1.0", result.getConversionResults().get(0).getArchetype().getRmRelease()); conversionConfiguration.setRmRelease("1.0.4"); - converter = new ADL14Converter(BuiltinReferenceModels.getMetaModels(), conversionConfiguration); + converter = new ADL14Converter(BuiltinReferenceModels.getMetaModelProvider(), conversionConfiguration); result = converter.convert(Lists.newArrayList(adl14)); assertEquals("1.0.4", result.getConversionResults().get(0).getArchetype().getRmRelease()); diff --git a/tools/src/test/java/com/nedap/archie/adl14/DvScaleConversionTest.java b/tools/src/test/java/com/nedap/archie/adl14/DvScaleConversionTest.java index e58ad4e4c..4dbc714a1 100644 --- a/tools/src/test/java/com/nedap/archie/adl14/DvScaleConversionTest.java +++ b/tools/src/test/java/com/nedap/archie/adl14/DvScaleConversionTest.java @@ -18,11 +18,11 @@ public class DvScaleConversionTest { public void testDvScale() throws Exception { ADL14ConversionConfiguration conversionConfiguration = ConversionConfigForTest.getConfig(); - ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModels(), conversionConfiguration); + ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModelProvider(), conversionConfiguration); try(InputStream stream = getClass().getResourceAsStream("openEHR-EHR-CLUSTER.ordinalandscale.v0.adl")) { - ADL14Parser adl14Parser = new ADL14Parser(BuiltinReferenceModels.getMetaModels()); + ADL14Parser adl14Parser = new ADL14Parser(BuiltinReferenceModels.getMetaModelProvider()); Archetype adl14 = adl14Parser.parse(stream, conversionConfiguration); assertFalse(adl14Parser.getErrors().hasErrors()); ADL2ConversionResultList result = converter.convert(Lists.newArrayList(adl14)); diff --git a/tools/src/test/java/com/nedap/archie/adl14/LargeSetOfADL14sTest.java b/tools/src/test/java/com/nedap/archie/adl14/LargeSetOfADL14sTest.java index c407cf774..5d6ba295f 100644 --- a/tools/src/test/java/com/nedap/archie/adl14/LargeSetOfADL14sTest.java +++ b/tools/src/test/java/com/nedap/archie/adl14/LargeSetOfADL14sTest.java @@ -54,14 +54,14 @@ public void parseUrn() { @Test public void testRiskFamilyhistory() throws Exception { - ADL14Parser parser = new ADL14Parser(BuiltinReferenceModels.getMetaModels()); + ADL14Parser parser = new ADL14Parser(BuiltinReferenceModels.getMetaModelProvider()); Archetype riskParent = parser.parse(getClass().getResourceAsStream("/adl14/risk_parent.adl"), conversionConfiguration); Archetype riskFamilyHistory = parser.parse(getClass().getResourceAsStream("/adl14/risk_history.adl"), conversionConfiguration); List archetypes = Arrays.asList(riskParent, riskFamilyHistory); - ADL2ConversionResultList converted = new ADL14Converter(BuiltinReferenceModels.getMetaModels(), conversionConfiguration) + ADL2ConversionResultList converted = new ADL14Converter(BuiltinReferenceModels.getMetaModelProvider(), conversionConfiguration) .convert(archetypes); for(ADL2ConversionResult conversionResult:converted.getConversionResults()) { @@ -81,7 +81,7 @@ public void testRiskFamilyhistory() throws Exception { adl2Repository.addArchetype(conversionResult.getArchetype()); } } - adl2Repository.compile(BuiltinReferenceModels.getMetaModels()); + adl2Repository.compile(BuiltinReferenceModels.getMetaModelProvider()); for(ValidationResult validationResult:adl2Repository.getAllValidationResults()) { if(!validationResult.passes()) { @@ -109,7 +109,7 @@ public void parseLots() throws Exception { } } - ADL2ConversionResultList converted = new ADL14Converter(BuiltinReferenceModels.getMetaModels(), conversionConfiguration) + ADL2ConversionResultList converted = new ADL14Converter(BuiltinReferenceModels.getMetaModelProvider(), conversionConfiguration) .convert(archetypes); for(ADL2ConversionResult result:converted.getConversionResults()) { if(result.getArchetype() != null) {// && result.getArchetype().getParentArchetypeId() != null) { @@ -156,7 +156,7 @@ public void parseLots() throws Exception { adl2Repository.addArchetype(conversionResult.getArchetype()); } } - adl2Repository.compile(BuiltinReferenceModels.getMetaModels()); + adl2Repository.compile(BuiltinReferenceModels.getMetaModelProvider()); int passingValidations = 0; for(ValidationResult validationResult:adl2Repository.getAllValidationResults()) { if(validationResult.passes()) { @@ -189,7 +189,7 @@ public void parseLots() throws Exception { private Archetype parse(Map exceptions, Map parseErrors, String file) { try (InputStream stream = getClass().getResourceAsStream("/" + file)) { logger.info("trying to parse " + file); - ADL14Parser parser = new ADL14Parser(BuiltinReferenceModels.getMetaModels()); + ADL14Parser parser = new ADL14Parser(BuiltinReferenceModels.getMetaModelProvider()); Archetype archetype = parser.parse(stream, conversionConfiguration); //logger.info(JacksonUtil.getObjectMapper().writeValueAsString(conversionResult.getConversionLog())); diff --git a/tools/src/test/java/com/nedap/archie/adl14/PreviousLogConversionTest.java b/tools/src/test/java/com/nedap/archie/adl14/PreviousLogConversionTest.java index 19f865a0c..950a7ecf2 100644 --- a/tools/src/test/java/com/nedap/archie/adl14/PreviousLogConversionTest.java +++ b/tools/src/test/java/com/nedap/archie/adl14/PreviousLogConversionTest.java @@ -25,12 +25,12 @@ public class PreviousLogConversionTest { public void applyConsistentConversion() throws Exception { ADL14ConversionConfiguration conversionConfiguration = ConversionConfigForTest.getConfig(); - ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModels(), conversionConfiguration); + ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModelProvider(), conversionConfiguration); ADL2ConversionRunLog log = null; try(InputStream stream = getClass().getResourceAsStream("openehr-EHR-COMPOSITION.review.v1.adl")) { ADL2ConversionResultList result = converter.convert( - Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModels()).parse(stream, conversionConfiguration))); + Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream, conversionConfiguration))); log = result.getConversionLog(); } @@ -38,7 +38,7 @@ public void applyConsistentConversion() throws Exception { try(InputStream stream = getClass().getResourceAsStream("openEHR-EHR-COMPOSITION.review.v1.modified.adl")) { ADL2ConversionResultList result = converter.convert( - Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModels()).parse(stream, conversionConfiguration)), + Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream, conversionConfiguration)), log); CAttribute attribute = result.getConversionResults().get(0).getArchetype().itemAtPath("/category"); assertEquals(2, attribute.getChildren().size()); @@ -55,15 +55,15 @@ public void applyConsistentConversion() throws Exception { @Test public void testValueSet() throws Exception { ADL14ConversionConfiguration conversionConfiguration = ConversionConfigForTest.getConfig(); - ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModels(), conversionConfiguration); + ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModelProvider(), conversionConfiguration); ADL2ConversionRunLog log = null; try(InputStream stream = getClass().getResourceAsStream("openEHR-EHR-OBSERVATION.respiration.v1.adl")) { ADL2ConversionResultList result = converter.convert( - Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModels()).parse(stream, conversionConfiguration))); + Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream, conversionConfiguration))); log = result.getConversionLog(); Archetype converted = result.getConversionResults().get(0).getArchetype(); - ValidationResult validated = new ArchetypeValidator(BuiltinReferenceModels.getMetaModels()).validate(converted); + ValidationResult validated = new ArchetypeValidator(BuiltinReferenceModels.getMetaModelProvider()).validate(converted); assertTrue(validated.toString(), validated.passes() ); assertTrue(converted.getTerminology().getTermDefinitions().get("nl").containsKey("ac9000")); assertTrue(converted.getTerminology().getTermDefinitions().get("nl").containsKey("ac9001")); @@ -75,11 +75,11 @@ public void testValueSet() throws Exception { try(InputStream stream = getClass().getResourceAsStream("openEHR-EHR-OBSERVATION.respiration.v1.adl")) { ADL2ConversionResultList result = converter.convert( - Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModels()).parse(stream, conversionConfiguration)), + Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream, conversionConfiguration)), log); Archetype converted = result.getConversionResults().get(0).getArchetype(); - ValidationResult validated = new ArchetypeValidator(BuiltinReferenceModels.getMetaModels()).validate(converted); + ValidationResult validated = new ArchetypeValidator(BuiltinReferenceModels.getMetaModelProvider()).validate(converted); assertTrue(validated.toString(), validated.passes() ); assertTrue(converted.getTerminology().getTermDefinitions().get("nl").containsKey("ac9000")); assertTrue(converted.getTerminology().getTermDefinitions().get("nl").containsKey("ac9001")); @@ -92,16 +92,16 @@ public void testValueSet() throws Exception { @Test public void unusedValuesAreRemoved() throws Exception { ADL14ConversionConfiguration conversionConfiguration = ConversionConfigForTest.getConfig(); - ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModels(), conversionConfiguration); + ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModelProvider(), conversionConfiguration); ADL2ConversionRunLog log = null; String createdAtCode = null; //apply the first conversion and store the log. It has created an at code to bind to [openehr::124], used in a DV_QUANTITY.property try(InputStream stream = getClass().getResourceAsStream("/adl14/openEHR-EHR-CLUSTER.value_binding.v1.0.0.adl")) { ADL2ConversionResultList result = converter.convert( - Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModels()).parse(stream, conversionConfiguration))); + Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream, conversionConfiguration))); log = result.getConversionLog(); Archetype converted = result.getConversionResults().get(0).getArchetype(); - ValidationResult validated = new ArchetypeValidator(BuiltinReferenceModels.getMetaModels()).validate(converted); + ValidationResult validated = new ArchetypeValidator(BuiltinReferenceModels.getMetaModelProvider()).validate(converted); assertTrue(validated.toString(), validated.passes() ); createdAtCode = log.getConversionLog("openEHR-EHR-CLUSTER.value_binding.v1").getCreatedCodes().get("[openehr::124]").getGeneratedCode(); ArchetypeTerm termDefinition = converted.getTerminology().getTermDefinition("en", createdAtCode); @@ -113,10 +113,10 @@ public void unusedValuesAreRemoved() throws Exception { //apply the first conversion. The openehr::124 term binding is gone, and should not be present in the result, but should remain in the conversion log for future readdition try(InputStream stream = getClass().getResourceAsStream("/adl14/openEHR-EHR-CLUSTER.value_binding.v1.0.1.adl")) { ADL2ConversionResultList result = converter.convert( - Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModels()).parse(stream, conversionConfiguration)), + Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream, conversionConfiguration)), log); Archetype converted = result.getConversionResults().get(0).getArchetype(); - ValidationResult validated = new ArchetypeValidator(BuiltinReferenceModels.getMetaModels()).validate(converted); + ValidationResult validated = new ArchetypeValidator(BuiltinReferenceModels.getMetaModelProvider()).validate(converted); assertTrue(validated.toString(), validated.passes() ); ArchetypeTerm termDefinition = converted.getTerminology().getTermDefinition("en", "at9000"); @@ -141,12 +141,12 @@ public void unusedValuesAreRemoved() throws Exception { public void acceptExplicitlySetCode() throws Exception { ADL14ConversionConfiguration conversionConfiguration = ConversionConfigForTest.getConfig(); - ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModels(), conversionConfiguration); + ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModelProvider(), conversionConfiguration); ADL2ConversionRunLog log = null; try(InputStream stream = getClass().getResourceAsStream("openehr-EHR-COMPOSITION.review.v1.adl")) { ADL2ConversionResultList result = converter.convert( - Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModels()).parse(stream, conversionConfiguration))); + Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream, conversionConfiguration))); log = result.getConversionLog(); } @@ -154,7 +154,7 @@ public void acceptExplicitlySetCode() throws Exception { try(InputStream stream = getClass().getResourceAsStream("openEHR-EHR-COMPOSITION.review.v1.codeadded.adl")) { ADL2ConversionResultList result = converter.convert( - Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModels()).parse(stream, conversionConfiguration)), + Lists.newArrayList(new ADL14Parser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream, conversionConfiguration)), log); CAttribute attribute = result.getConversionResults().get(0).getArchetype().itemAtPath("/category"); diff --git a/tools/src/test/java/com/nedap/archie/adlparser/AomUtilsPathFindingTest.java b/tools/src/test/java/com/nedap/archie/adlparser/AomUtilsPathFindingTest.java index 149e5b259..d7cc0f0b6 100644 --- a/tools/src/test/java/com/nedap/archie/adlparser/AomUtilsPathFindingTest.java +++ b/tools/src/test/java/com/nedap/archie/adlparser/AomUtilsPathFindingTest.java @@ -2,7 +2,7 @@ import com.nedap.archie.aom.Archetype; import com.nedap.archie.aom.utils.AOMUtils; -import com.nedap.archie.rminfo.MetaModels; +import com.nedap.archie.rminfo.MetaModel; import com.nedap.archie.testutil.TestUtil; import org.junit.Test; import org.openehr.referencemodels.BuiltinReferenceModels; @@ -15,15 +15,14 @@ public class AomUtilsPathFindingTest { @Test public void isPathInArchetypeOrRm() throws Exception{ Archetype archetype = TestUtil.parseFailOnErrors("/basic.adl"); - MetaModels metaModels = BuiltinReferenceModels.getMetaModels(); - metaModels.selectModel(archetype); + MetaModel metaModel = BuiltinReferenceModels.getMetaModelProvider().getMetaModel(archetype); //AOM path - assertTrue(AOMUtils.isPathInArchetypeOrRm(metaModels.getSelectedModel(), "/context[id11]", archetype)); + assertTrue(AOMUtils.isPathInArchetypeOrRm(metaModel, "/context[id11]", archetype)); //mixed aom + RM path - assertTrue(AOMUtils.isPathInArchetypeOrRm(metaModels.getSelectedModel(), "/context[id11]/health_care_facility/name", archetype)); + assertTrue(AOMUtils.isPathInArchetypeOrRm(metaModel, "/context[id11]/health_care_facility/name", archetype)); //path not in AOM, only in RM - assertTrue(AOMUtils.isPathInArchetypeOrRm(metaModels.getSelectedModel(), "/composer/external_ref", archetype)); + assertTrue(AOMUtils.isPathInArchetypeOrRm(metaModel, "/composer/external_ref", archetype)); //non-existing path - assertFalse(AOMUtils.isPathInArchetypeOrRm(metaModels.getSelectedModel(), "/doesnot_exists", archetype)); + assertFalse(AOMUtils.isPathInArchetypeOrRm(metaModel, "/doesnot_exists", archetype)); } } diff --git a/tools/src/test/java/com/nedap/archie/adlparser/RMPathQueryTest.java b/tools/src/test/java/com/nedap/archie/adlparser/RMPathQueryTest.java index 812b291fb..e3a26a967 100644 --- a/tools/src/test/java/com/nedap/archie/adlparser/RMPathQueryTest.java +++ b/tools/src/test/java/com/nedap/archie/adlparser/RMPathQueryTest.java @@ -121,7 +121,7 @@ public void findMatchSpecialisedNodes() throws Exception { inMemoryFullArchetypeRepository.addArchetype(archetype); Archetype archetype_specialised = TestUtil.parseFailOnErrors("/basic_specialised.adls"); inMemoryFullArchetypeRepository.addArchetype(archetype_specialised); - Flattener flattener = new Flattener(inMemoryFullArchetypeRepository, BuiltinReferenceModels.getMetaModels(), FlattenerConfiguration.forOperationalTemplate()); + Flattener flattener = new Flattener(inMemoryFullArchetypeRepository, BuiltinReferenceModels.getMetaModelProvider(), FlattenerConfiguration.forOperationalTemplate()); OperationalTemplate opt = (OperationalTemplate) flattener.flatten(archetype_specialised); root = (Pathable) testUtil.constructEmptyRMObject(opt.getDefinition()); @@ -136,7 +136,7 @@ public void findListMatchSpecialisedNodes() throws Exception { inMemoryFullArchetypeRepository.addArchetype(archetype); Archetype archetype_specialised = TestUtil.parseFailOnErrors("/basic_specialised.adls"); inMemoryFullArchetypeRepository.addArchetype(archetype_specialised); - Flattener flattener = new Flattener(inMemoryFullArchetypeRepository, BuiltinReferenceModels.getMetaModels(), FlattenerConfiguration.forOperationalTemplate()); + Flattener flattener = new Flattener(inMemoryFullArchetypeRepository, BuiltinReferenceModels.getMetaModelProvider(), FlattenerConfiguration.forOperationalTemplate()); OperationalTemplate opt = (OperationalTemplate) flattener.flatten(archetype_specialised); root = (Pathable) testUtil.constructEmptyRMObject(opt.getDefinition()); @@ -153,7 +153,7 @@ public void findListMatchTwiceSpecialisedNodes() throws Exception { Archetype archetype_specialised_twice = TestUtil.parseFailOnErrors("/basic_specialised2.adls"); inMemoryFullArchetypeRepository.addArchetype(archetype_specialised); inMemoryFullArchetypeRepository.addArchetype(archetype_specialised_twice); - Flattener flattener = new Flattener(inMemoryFullArchetypeRepository, BuiltinReferenceModels.getMetaModels(), FlattenerConfiguration.forOperationalTemplate()); + Flattener flattener = new Flattener(inMemoryFullArchetypeRepository, BuiltinReferenceModels.getMetaModelProvider(), FlattenerConfiguration.forOperationalTemplate()); OperationalTemplate opt = (OperationalTemplate) flattener.flatten(archetype_specialised_twice); root = (Pathable) testUtil.constructEmptyRMObject(opt.getDefinition()); diff --git a/tools/src/test/java/com/nedap/archie/aom/ArchetypeTerminologyTest.java b/tools/src/test/java/com/nedap/archie/aom/ArchetypeTerminologyTest.java index 6efbfd200..2f2e31771 100644 --- a/tools/src/test/java/com/nedap/archie/aom/ArchetypeTerminologyTest.java +++ b/tools/src/test/java/com/nedap/archie/aom/ArchetypeTerminologyTest.java @@ -31,11 +31,11 @@ public void termForUseArchetype() throws IOException, ADLParseException { repository.addArchetype(FlattenerTestUtil.parse("/com/nedap/archie/aom/openEHR-EHR-GENERIC_ENTRY.included.v1.0.0.adls")); //check that they are valid, just to be sure - repository.compile(BuiltinReferenceModels.getMetaModels()); + repository.compile(BuiltinReferenceModels.getMetaModelProvider()); repository.getAllValidationResults().forEach(s -> assertTrue(s.getErrors().toString(), s.getErrors().isEmpty())); //create operational template - Flattener flattener = new Flattener(repository, BuiltinReferenceModels.getMetaModels(), FlattenerConfiguration.forOperationalTemplate()); + Flattener flattener = new Flattener(repository, BuiltinReferenceModels.getMetaModelProvider(), FlattenerConfiguration.forOperationalTemplate()); OperationalTemplate opt = (OperationalTemplate) flattener.flatten(repository.getArchetype("openEHR-EHR-COMPOSITION.parent.v1.0.0")); //and check the getTerm() functionality diff --git a/tools/src/test/java/com/nedap/archie/aom/TerminologyCodeConstraintsTest.java b/tools/src/test/java/com/nedap/archie/aom/TerminologyCodeConstraintsTest.java index 0776536c5..e33656d30 100644 --- a/tools/src/test/java/com/nedap/archie/aom/TerminologyCodeConstraintsTest.java +++ b/tools/src/test/java/com/nedap/archie/aom/TerminologyCodeConstraintsTest.java @@ -186,7 +186,7 @@ public void validationInOptTest() throws Exception { repository.addArchetype(FlattenerTestUtil.parse("/com/nedap/archie/aom/openEHR-EHR-GENERIC_ENTRY.included.v1.0.0.adls")); //create operational template - Flattener flattener = new Flattener(repository, BuiltinReferenceModels.getMetaModels(), FlattenerConfiguration.forOperationalTemplate()); + Flattener flattener = new Flattener(repository, BuiltinReferenceModels.getMetaModelProvider(), FlattenerConfiguration.forOperationalTemplate()); OperationalTemplate opt = (OperationalTemplate) flattener.flatten(repository.getArchetype("openEHR-EHR-COMPOSITION.parent.v1.0.0")); CTerminologyCode code = opt.itemAtPath("/content/data/items/value/defining_code[1]"); assertEquals(Lists.newArrayList("at4", "at5", "at6"), code.getValueSetExpanded()); diff --git a/tools/src/test/java/com/nedap/archie/archetypevalidator/ArchetypeValidatorTest.java b/tools/src/test/java/com/nedap/archie/archetypevalidator/ArchetypeValidatorTest.java index bf3efb42f..e8dea76cc 100644 --- a/tools/src/test/java/com/nedap/archie/archetypevalidator/ArchetypeValidatorTest.java +++ b/tools/src/test/java/com/nedap/archie/archetypevalidator/ArchetypeValidatorTest.java @@ -212,7 +212,7 @@ public void parentWithDifferentRmRelease() throws IOException, ADLParseException repository.addArchetype(child); repository.addArchetype(parent); - ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModels()); + ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModelProvider()); ValidationResult validatedChild = archetypeValidator.validate(child, repository); ValidationResult validatedParent = archetypeValidator.validate(parent, repository); @@ -224,7 +224,7 @@ public void parentWithDifferentRmRelease() throws IOException, ADLParseException repository.addArchetype(child); repository.addArchetype(parent); - ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModels()); + ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModelProvider()); ValidationResult validatedParent = archetypeValidator.validate(parent, repository); ValidationResult validatedChild = archetypeValidator.validate(child, repository); @@ -295,7 +295,7 @@ public void infiniteSpecialisationTreeLoopTest() throws IOException, ADLParseExc repository.addArchetype(child1); repository.addArchetype(child2); - ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModels()); + ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModelProvider()); ValidationResult result = archetypeValidator.validate(child1, repository); assertFalse(result.passes()); assertEquals("Infinite loop caused by specialising: openEHR-EHR-CLUSTER.infinite_loop_child1.v0.0.1 in openEHR-EHR-CLUSTER.infinite_loop_child2.v0.0.1", result.getErrors().get(0).getMessage()); @@ -312,7 +312,7 @@ public void specializationAfterExclusionTest() throws IOException, ADLParseExcep repository.addArchetype(parent); repository.addArchetype(childWithSpecializationAfterExclusion); - ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModels()); + ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModelProvider()); ValidationResult result = archetypeValidator.validate(childWithSpecializationAfterExclusion, repository); assertTrue(result.passes()); assertEquals(2, result.getErrors().size()); @@ -327,7 +327,7 @@ public void incompatibleNodeIdValidationTest() throws IOException, ADLParseExcep { InMemoryFullArchetypeRepository repository = new InMemoryFullArchetypeRepository(); repository.addArchetype(archetypeWithIncompatibleNodeId); - ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModels()); + ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModelProvider()); ValidationResult result = archetypeValidator.validate(archetypeWithIncompatibleNodeId, repository); assertTrue(result.passes()); assertEquals(6, result.getErrors().size()); diff --git a/tools/src/test/java/com/nedap/archie/archetypevalidator/ArchetypeValidatorVersionsTest.java b/tools/src/test/java/com/nedap/archie/archetypevalidator/ArchetypeValidatorVersionsTest.java index e018b36e0..4a706638f 100644 --- a/tools/src/test/java/com/nedap/archie/archetypevalidator/ArchetypeValidatorVersionsTest.java +++ b/tools/src/test/java/com/nedap/archie/archetypevalidator/ArchetypeValidatorVersionsTest.java @@ -23,7 +23,7 @@ public void testMultipleVersions() throws IOException, ADLParseException { repo.addArchetype(parentv1); repo.addArchetype(parentv11); repo.addArchetype(child); - ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModels()); + ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModelProvider()); //the order of validation is important for this test! //first validate the first parent, which is valid assertTrue(archetypeValidator.validate(parentv1, repo).passes()); @@ -47,7 +47,7 @@ public void testMultipleVersionsFullyCompile() throws Exception { repo.addArchetype(parentv1); repo.addArchetype(parentv11); repo.addArchetype(child); - repo.compile(new ArchetypeValidator(BuiltinReferenceModels.getMetaModels())); + repo.compile(new ArchetypeValidator(BuiltinReferenceModels.getMetaModelProvider())); for(ValidationResult result:repo.getAllValidationResults()) { assertTrue(result.getErrors().toString(), result.passes()); } diff --git a/tools/src/test/java/com/nedap/archie/archetypevalidator/BigArchetypeValidatorTest.java b/tools/src/test/java/com/nedap/archie/archetypevalidator/BigArchetypeValidatorTest.java index 41563a17c..10d7a98a1 100644 --- a/tools/src/test/java/com/nedap/archie/archetypevalidator/BigArchetypeValidatorTest.java +++ b/tools/src/test/java/com/nedap/archie/archetypevalidator/BigArchetypeValidatorTest.java @@ -10,8 +10,9 @@ import com.nedap.archie.flattener.FullArchetypeRepository; import com.nedap.archie.flattener.InMemoryFullArchetypeRepository; import com.nedap.archie.rminfo.ArchieRMInfoLookup; -import com.nedap.archie.rminfo.MetaModels; +import com.nedap.archie.rminfo.MetaModelProvider; import com.nedap.archie.rminfo.ReferenceModels; +import com.nedap.archie.rminfo.SimpleMetaModelProvider; import org.apache.commons.io.FilenameUtils; import org.junit.Assert; import org.junit.Test; @@ -118,7 +119,7 @@ private FullArchetypeRepository parseAll() { @Test public void testFullValidityPackageBmm() { - testInner(new MetaModels(null, BuiltinReferenceModels.getBmmRepository(), BuiltinReferenceModels.getAomProfiles())); + testInner(new SimpleMetaModelProvider(null, BuiltinReferenceModels.getBmmRepository(), BuiltinReferenceModels.getAomProfiles())); } @@ -130,11 +131,11 @@ public void testFullValidityPackageModelInfoLookup() { models.registerModel(com.nedap.archie.openehrtestrm.TestRMInfoLookup.getInstance()); // access.initializeAll(schemaDirectories); - testInner(new MetaModels(models, (BmmRepository) null)); + testInner(new SimpleMetaModelProvider(models, null)); } - public void testInner(MetaModels metaModels) { + public void testInner(MetaModelProvider metaModelProvider) { Reflections reflections = new Reflections("adl2-tests.validity", Scanners.Resources); List adlFiles = new ArrayList<>(reflections.getResources(Pattern.compile(".*\\.adls"))); @@ -148,7 +149,7 @@ public void testInner(MetaModels metaModels) { int unexpectedParseErrors = 0; int wrongMessageCount = 0; List errorStrings = new ArrayList<>(); - ArchetypeValidator validator = new ArchetypeValidator(metaModels); + ArchetypeValidator validator = new ArchetypeValidator(metaModelProvider); InMemoryFullArchetypeRepository repository = new InMemoryFullArchetypeRepository(); for(String file:adlFiles) { if (file.contains("legacy_adl_1.4")) { diff --git a/tools/src/test/java/com/nedap/archie/archetypevalidator/CKMArchetypeValidatorTest.java b/tools/src/test/java/com/nedap/archie/archetypevalidator/CKMArchetypeValidatorTest.java index 4f4ca699f..e09dbd10a 100644 --- a/tools/src/test/java/com/nedap/archie/archetypevalidator/CKMArchetypeValidatorTest.java +++ b/tools/src/test/java/com/nedap/archie/archetypevalidator/CKMArchetypeValidatorTest.java @@ -2,8 +2,9 @@ import com.nedap.archie.flattener.FullArchetypeRepository; import com.nedap.archie.rminfo.ArchieRMInfoLookup; -import com.nedap.archie.rminfo.MetaModels; +import com.nedap.archie.rminfo.MetaModelProvider; import com.nedap.archie.rminfo.ReferenceModels; +import com.nedap.archie.rminfo.SimpleMetaModelProvider; import com.nedap.archie.testutil.TestUtil; import org.junit.Test; import org.openehr.referencemodels.BuiltinReferenceModels; @@ -58,11 +59,11 @@ public void fullCKMTest() { @Test public void fullCKMTestBmm() { - MetaModels bmmReferenceModels = new MetaModels(null, BuiltinReferenceModels.getBmmRepository(), BuiltinReferenceModels.getAomProfiles()); + MetaModelProvider bmmReferenceModelProvider = new SimpleMetaModelProvider(null, BuiltinReferenceModels.getBmmRepository(), BuiltinReferenceModels.getAomProfiles()); FullArchetypeRepository repository = TestUtil.parseCKM(); logger.info("archetypes parsed: " + repository.getAllArchetypes().size()); - repository.compile(bmmReferenceModels); + repository.compile(bmmReferenceModelProvider); runTest(repository); diff --git a/tools/src/test/java/com/nedap/archie/archetypevalidator/TermCodeSpecializationTest.java b/tools/src/test/java/com/nedap/archie/archetypevalidator/TermCodeSpecializationTest.java index 3c3862542..49da00b3c 100644 --- a/tools/src/test/java/com/nedap/archie/archetypevalidator/TermCodeSpecializationTest.java +++ b/tools/src/test/java/com/nedap/archie/archetypevalidator/TermCodeSpecializationTest.java @@ -26,12 +26,12 @@ public void validRequiredBindingStrength() throws Exception { InMemoryFullArchetypeRepository repo = new InMemoryFullArchetypeRepository(); repo.addArchetype(parent); repo.addArchetype(child); - ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModels()); + ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModelProvider()); repo.compile(archetypeValidator); for(ValidationResult validationResult:repo.getAllValidationResults()) { assertTrue(validationResult.toString(), validationResult.passes()); } - Flattener flattener = new Flattener(repo, BuiltinReferenceModels.getMetaModels(), FlattenerConfiguration.forOperationalTemplate()); + Flattener flattener = new Flattener(repo, BuiltinReferenceModels.getMetaModelProvider(), FlattenerConfiguration.forOperationalTemplate()); OperationalTemplate opt = (OperationalTemplate) flattener.flatten(child); ValueSet valueSet = opt.getTerminology().getValueSets().get("ac0.2"); assertEquals(new LinkedHashSet<>(Arrays.asList("at1", "at2", "at3", "at0.1")), valueSet.getMembers()); @@ -44,7 +44,7 @@ public void invalidRequiredBindingStrength() throws Exception { InMemoryFullArchetypeRepository repo = new InMemoryFullArchetypeRepository(); repo.addArchetype(parent); repo.addArchetype(child); - ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModels()); + ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModelProvider()); repo.compile(archetypeValidator); ValidationResult validationResult = repo.getValidationResult("openEHR-EHR-CLUSTER.constraint_strength_invalid_child.v1.0.0"); assertFalse(validationResult.toString(), validationResult.passes()); @@ -58,7 +58,7 @@ public void invalidConstraintStrengthRedefinition() throws Exception { InMemoryFullArchetypeRepository repo = new InMemoryFullArchetypeRepository(); repo.addArchetype(parent); repo.addArchetype(child); - ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModels()); + ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModelProvider()); repo.compile(archetypeValidator); ValidationResult validationResult = repo.getValidationResult("openEHR-EHR-CLUSTER.constraint_strength_invalid_redefinition.v1.0.0"); assertFalse(validationResult.toString(), validationResult.passes()); @@ -72,7 +72,7 @@ public void valueSetCodeChanges() throws IOException, ADLParseException { InMemoryFullArchetypeRepository repo = new InMemoryFullArchetypeRepository(); repo.addArchetype(parent); repo.addArchetype(child); - ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModels()); + ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModelProvider()); repo.compile(archetypeValidator); ValidationResult validationResult = repo.getValidationResult("openEHR-EHR-CLUSTER.constraint_strength_change_valueset_code.v1.0.0"); assertFalse(validationResult.toString(), validationResult.passes()); @@ -96,7 +96,7 @@ public void invalidValueSetRedefinition() throws IOException, ADLParseException InMemoryFullArchetypeRepository repo = new InMemoryFullArchetypeRepository(); repo.addArchetype(parent); repo.addArchetype(child); - ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModels()); + ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModelProvider()); repo.compile(archetypeValidator); ValidationResult validationResult = repo.getValidationResult("openEHR-EHR-CLUSTER.constraint_strength_invalid_redefined_value-set.v1.0.0"); assertFalse(validationResult.toString(), validationResult.passes()); @@ -110,7 +110,7 @@ public void nonExistingParentValueSet() throws IOException, ADLParseException { InMemoryFullArchetypeRepository repo = new InMemoryFullArchetypeRepository(); repo.addArchetype(parent); repo.addArchetype(child); - ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModels()); + ArchetypeValidator archetypeValidator = new ArchetypeValidator(BuiltinReferenceModels.getMetaModelProvider()); repo.compile(archetypeValidator); ValidationResult validationResult = repo.getValidationResult("openEHR-EHR-CLUSTER.incorrect_parent_valueset_code.v1.0.0"); assertFalse(validationResult.toString(), validationResult.passes()); diff --git a/tools/src/test/java/com/nedap/archie/creation/ExampleJsonInstanceGeneratorTest.java b/tools/src/test/java/com/nedap/archie/creation/ExampleJsonInstanceGeneratorTest.java index 6087fd158..f39680895 100644 --- a/tools/src/test/java/com/nedap/archie/creation/ExampleJsonInstanceGeneratorTest.java +++ b/tools/src/test/java/com/nedap/archie/creation/ExampleJsonInstanceGeneratorTest.java @@ -198,7 +198,7 @@ public void generateAllCKMExamples() throws Exception { int numberCreated = 0, validationFailed = 0, generatedException = 0, jsonSchemaValidationRan = 0, jsonSchemaValidationFailed = 0; int secondJsonSchemaValidationRan = 0, reserializedJsonSchemaValidationFailed = 0; int rmObjectValidatorRan = 0, rmObjectValidatorFailed = 0; - repository.compile(BuiltinReferenceModels.getMetaModels()); + repository.compile(BuiltinReferenceModels.getMetaModelProvider()); BmmModel model = BuiltinReferenceModels.getBmmRepository().getModel("openehr_rm_1.0.4").getModel(); JsonSchemaValidator firstValidator = new JsonSchemaValidator(model, true); JsonSchemaValidator secondValidator = new JsonSchemaValidator(model,false); @@ -210,7 +210,7 @@ public void generateAllCKMExamples() throws Exception { if(result.passes()) { String json = ""; try { - Flattener flattener = new Flattener(repository, BuiltinReferenceModels.getMetaModels()).createOperationalTemplate(true); + Flattener flattener = new Flattener(repository, BuiltinReferenceModels.getMetaModelProvider()).createOperationalTemplate(true); OperationalTemplate template = (OperationalTemplate) flattener.flatten(result.getSourceArchetype()); Map example = structureGenerator.generate(template); json = mapper.writeValueAsString(example); @@ -282,7 +282,7 @@ public void generateAllCKMExamples() throws Exception { } private ExampleJsonInstanceGenerator createExampleJsonInstanceGenerator() { - ExampleJsonInstanceGenerator structureGenerator = new ExampleJsonInstanceGenerator(BuiltinReferenceModels.getMetaModels(), "en"); + ExampleJsonInstanceGenerator structureGenerator = new ExampleJsonInstanceGenerator(BuiltinReferenceModels.getMetaModelProvider(), "en"); structureGenerator.setTypePropertyName(TYPE_PROPERTY_NAME); return structureGenerator; } @@ -292,7 +292,7 @@ private OperationalTemplate createOPT(String s2) throws IOException, ADLParseExc Archetype archetype = parse(s2); InMemoryFullArchetypeRepository repository = new InMemoryFullArchetypeRepository(); repository.addArchetype(archetype); - return (OperationalTemplate) new Flattener(repository, BuiltinReferenceModels.getMetaModels()).createOperationalTemplate(true).flatten(archetype); + return (OperationalTemplate) new Flattener(repository, BuiltinReferenceModels.getMetaModelProvider()).createOperationalTemplate(true).flatten(archetype); } private Archetype parse(String filename) throws IOException, ADLParseException { diff --git a/tools/src/test/java/com/nedap/archie/creation/RMObjectCreatorTest.java b/tools/src/test/java/com/nedap/archie/creation/RMObjectCreatorTest.java index 846748f51..142830d81 100644 --- a/tools/src/test/java/com/nedap/archie/creation/RMObjectCreatorTest.java +++ b/tools/src/test/java/com/nedap/archie/creation/RMObjectCreatorTest.java @@ -87,6 +87,7 @@ public void createUnknownType() { } @Test + @Deprecated public void setSingleValuedValue() { Element element = new Element(); DvBoolean booleanValue = new DvBoolean(); @@ -95,6 +96,7 @@ public void setSingleValuedValue() { } @Test + @Deprecated public void setSingleValuedValuePrimitive() { DvBoolean booleanValue = new DvBoolean(); creator.set(booleanValue, "value", Lists.newArrayList(true)); @@ -102,6 +104,7 @@ public void setSingleValuedValuePrimitive() { } @Test(expected = IllegalArgumentException.class) + @Deprecated public void setSingleValuedValueIncorrectly() { Element element = new Element(); DvBoolean booleanValue = new DvBoolean(); @@ -110,6 +113,7 @@ public void setSingleValuedValueIncorrectly() { } @Test(expected = IllegalArgumentException.class) + @Deprecated public void setSingleValuedValueUnknownArgument() { Element element = new Element(); DvBoolean booleanValue = new DvBoolean(); @@ -117,6 +121,7 @@ public void setSingleValuedValueUnknownArgument() { } @Test + @Deprecated public void setMultiValuedValue() { Cluster cluster = new Cluster(); Element element = new Element(); @@ -125,6 +130,7 @@ public void setMultiValuedValue() { } @Test + @Deprecated public void setMultiValuedValue2() { Cluster cluster = new Cluster(); Element element = new Element(); @@ -134,6 +140,7 @@ public void setMultiValuedValue2() { } @Test + @Deprecated public void addToListOrSetSingleValue() { Cluster cluster = new Cluster(); Element element = new Element(); @@ -144,6 +151,7 @@ public void addToListOrSetSingleValue() { } @Test + @Deprecated public void addToListOrSetSingleValue2() { Cluster cluster = new Cluster(); Element element = new Element(); @@ -155,6 +163,7 @@ public void addToListOrSetSingleValue2() { } @Test + @Deprecated public void addToListOrSetSingleValueWithSingleValue() { Element element = new Element(); DvBoolean booleanValue = new DvBoolean(); @@ -163,6 +172,7 @@ public void addToListOrSetSingleValueWithSingleValue() { } @Test + @Deprecated public void addToListOrSetSingleValueWithSingleValue2() { Element element = new Element(); DvBoolean booleanValue = new DvBoolean(); @@ -171,6 +181,7 @@ public void addToListOrSetSingleValueWithSingleValue2() { } @Test(expected = IllegalArgumentException.class) + @Deprecated public void addToListOrSetSingleValueWithSingleValueIncorrect() { Element element = new Element(); DvBoolean booleanValue = new DvBoolean(); diff --git a/tools/src/test/java/com/nedap/archie/diff/DiffTestUtil.java b/tools/src/test/java/com/nedap/archie/diff/DiffTestUtil.java index 5f4587c99..5e2866156 100644 --- a/tools/src/test/java/com/nedap/archie/diff/DiffTestUtil.java +++ b/tools/src/test/java/com/nedap/archie/diff/DiffTestUtil.java @@ -4,7 +4,8 @@ import com.nedap.archie.flattener.Flattener; import com.nedap.archie.flattener.InMemoryFullArchetypeRepository; import com.nedap.archie.flattener.specexamples.FlattenerTestUtil; -import com.nedap.archie.rminfo.MetaModels; +import com.nedap.archie.rminfo.MetaModelProvider; +import com.nedap.archie.rminfo.SimpleMetaModelProvider; import com.nedap.archie.serializer.adl.ADLArchetypeSerializer; import com.nedap.archie.testutil.TestUtil; import org.openehr.bmm.v2.validation.BmmRepository; @@ -20,23 +21,23 @@ public class DiffTestUtil { private String expectationsResourceLocation; private InMemoryFullArchetypeRepository repository; - private MetaModels models; + private final MetaModelProvider metaModelProvider; public DiffTestUtil(String archetypesResourceLocation, String expectationsResourceLocation) { this.archetypesResourceLocation = archetypesResourceLocation; this.expectationsResourceLocation = expectationsResourceLocation; repository = new InMemoryFullArchetypeRepository(); - models = new MetaModels(BuiltinReferenceModels.getAvailableModelInfoLookups(), (BmmRepository) null); + metaModelProvider = new SimpleMetaModelProvider(BuiltinReferenceModels.getAvailableModelInfoLookups(), null); } public void test(String parentFileName, String childFileName) throws Exception { Archetype parent = FlattenerTestUtil.parse(archetypesResourceLocation + parentFileName); repository.addArchetype(parent); Archetype child = FlattenerTestUtil.parse(archetypesResourceLocation + childFileName); - Archetype flattened = new Flattener(repository, models).flatten(child); + Archetype flattened = new Flattener(repository, metaModelProvider).flatten(child); assertEquals(child.getParentArchetypeId(), flattened.getParentArchetypeId()); - Archetype diffed = new Differentiator(BuiltinReferenceModels.getMetaModels()).differentiate(flattened, parent); + Archetype diffed = new Differentiator(BuiltinReferenceModels.getMetaModelProvider()).differentiate(flattened, parent); child.setGenerated(true);//this is set by the diff tool :) String originalSerialized = ADLArchetypeSerializer.serialize(child); String diffedSerialized = ADLArchetypeSerializer.serialize(diffed); @@ -53,10 +54,10 @@ public void testWithExplicitExpect(String parentFileName, String childFileName) repository.addArchetype(parent); Archetype child = FlattenerTestUtil.parse(archetypesResourceLocation + childFileName); Archetype expectedDiff = FlattenerTestUtil.parse(expectationsResourceLocation + childFileName); - Archetype flattened = new Flattener(repository, models).flatten(child); + Archetype flattened = new Flattener(repository, metaModelProvider).flatten(child); assertEquals(child.getParentArchetypeId(), flattened.getParentArchetypeId()); - Archetype diffed = new Differentiator(BuiltinReferenceModels.getMetaModels()).differentiate(flattened, parent); + Archetype diffed = new Differentiator(BuiltinReferenceModels.getMetaModelProvider()).differentiate(flattened, parent); expectedDiff.setGenerated(true);//this is set by the diff tool :) String expectedSerialized = ADLArchetypeSerializer.serialize(expectedDiff); String diffedSerialized = ADLArchetypeSerializer.serialize(diffed); diff --git a/tools/src/test/java/com/nedap/archie/flattener/OperationalTemplateCreatorTest.java b/tools/src/test/java/com/nedap/archie/flattener/OperationalTemplateCreatorTest.java index f3ae2b575..d8e7d21b9 100644 --- a/tools/src/test/java/com/nedap/archie/flattener/OperationalTemplateCreatorTest.java +++ b/tools/src/test/java/com/nedap/archie/flattener/OperationalTemplateCreatorTest.java @@ -49,8 +49,8 @@ public void includeZeroExistence() throws Exception { @Test public void fillEmptyOccurrences() throws Exception { try(InputStream stream = getClass().getResourceAsStream("openEHR-EHR-CLUSTER.cluster_with_annotations.v1.adls")) { - Archetype archetype = new ADLParser(BuiltinReferenceModels.getMetaModels()).parse(stream); - Flattener flattener = new Flattener(new SimpleArchetypeRepository(), BuiltinReferenceModels.getMetaModels(), FlattenerConfiguration.forOperationalTemplate()); + Archetype archetype = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream); + Flattener flattener = new Flattener(new SimpleArchetypeRepository(), BuiltinReferenceModels.getMetaModelProvider(), FlattenerConfiguration.forOperationalTemplate()); OperationalTemplate template = (OperationalTemplate) flattener.flatten(archetype); Stack workList = new Stack<>(); @@ -72,10 +72,10 @@ public void fillEmptyOccurrences() throws Exception { @Test public void dontFillEmptyOccurrencesUnlessSet() throws Exception { try(InputStream stream = getClass().getResourceAsStream("openEHR-EHR-CLUSTER.cluster_with_annotations.v1.adls")) { - Archetype archetype = new ADLParser(BuiltinReferenceModels.getMetaModels()).parse(stream); + Archetype archetype = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream); FlattenerConfiguration flattenerConfiguration = FlattenerConfiguration.forOperationalTemplate(); flattenerConfiguration.setFillEmptyOccurrences(false); - Flattener flattener = new Flattener(new SimpleArchetypeRepository(), BuiltinReferenceModels.getMetaModels(), flattenerConfiguration); + Flattener flattener = new Flattener(new SimpleArchetypeRepository(), BuiltinReferenceModels.getMetaModelProvider(), flattenerConfiguration); OperationalTemplate template = (OperationalTemplate) flattener.flatten(archetype); Stack workList = new Stack<>(); @@ -97,9 +97,9 @@ public void dontFillEmptyOccurrencesUnlessSet() throws Exception { public void failOnMissingArchetypeEnabled() throws Exception { SimpleArchetypeRepository repository = new SimpleArchetypeRepository(); try(InputStream stream = getClass().getResourceAsStream("openEHR-EHR-OBSERVATION.with_used_archetype.v1.adls")) { - Archetype archetype = new ADLParser(BuiltinReferenceModels.getMetaModels()).parse(stream); + Archetype archetype = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream); FlattenerConfiguration flattenerConfiguration = FlattenerConfiguration.forOperationalTemplate(); - Flattener flattener = new Flattener(repository, BuiltinReferenceModels.getMetaModels(), flattenerConfiguration); + Flattener flattener = new Flattener(repository, BuiltinReferenceModels.getMetaModelProvider(), flattenerConfiguration); OperationalTemplate template = (OperationalTemplate) flattener.flatten(archetype); fail(); } @@ -108,10 +108,10 @@ public void failOnMissingArchetypeEnabled() throws Exception { @Test public void failOnMissingArchetypeDisabled() throws Exception { try(InputStream stream = getClass().getResourceAsStream("openEHR-EHR-OBSERVATION.with_used_archetype.v1.adls")) { - Archetype archetype = new ADLParser(BuiltinReferenceModels.getMetaModels()).parse(stream); + Archetype archetype = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream); FlattenerConfiguration flattenerConfiguration = FlattenerConfiguration.forOperationalTemplate(); flattenerConfiguration.setFailOnMissingUsedArchetype(false); - Flattener flattener = new Flattener(new SimpleArchetypeRepository(), BuiltinReferenceModels.getMetaModels(), flattenerConfiguration); + Flattener flattener = new Flattener(new SimpleArchetypeRepository(), BuiltinReferenceModels.getMetaModelProvider(), flattenerConfiguration); OperationalTemplate template = (OperationalTemplate) flattener.flatten(archetype); CArchetypeRoot archetypeRoot = template.getDefinition().itemAtPath("/data[id2]/events[id3]/data[id4]/items[id8]"); @@ -163,7 +163,7 @@ private Archetype parseAndCreateOPTWithConfig(String fileName, InMemoryFullArche models.registerModel(ArchieRMInfoLookup.getInstance()); ValidationResult validationResult = new ArchetypeValidator(models).validate(result, repository); assertTrue(validationResult.getErrors().toString(), validationResult.passes()); - return new Flattener(repository, BuiltinReferenceModels.getMetaModels(), config).flatten(parse(fileName)); + return new Flattener(repository, BuiltinReferenceModels.getMetaModelProvider(), config).flatten(parse(fileName)); } private Archetype parse(String filePath) throws IOException, ADLParseException { diff --git a/tools/src/test/java/com/nedap/archie/flattener/RMOverlayFlattenerTest.java b/tools/src/test/java/com/nedap/archie/flattener/RMOverlayFlattenerTest.java index f297c67a5..24e794f17 100644 --- a/tools/src/test/java/com/nedap/archie/flattener/RMOverlayFlattenerTest.java +++ b/tools/src/test/java/com/nedap/archie/flattener/RMOverlayFlattenerTest.java @@ -19,7 +19,7 @@ public void flattenParentChild() throws Exception{ InMemoryFullArchetypeRepository repository = new InMemoryFullArchetypeRepository(); repository.addArchetype(parent); repository.addArchetype(child); - repository.compile(new ArchetypeValidator(BuiltinReferenceModels.getMetaModels())); + repository.compile(new ArchetypeValidator(BuiltinReferenceModels.getMetaModelProvider())); repository.getAllValidationResults().forEach(v -> assertTrue(v.getErrors().toString(), !v.hasWarningsOrErrors())); Archetype flattenedChild = repository.getFlattenedArchetype("openEHR-EHR-OBSERVATION.to_flatten_child_with_overlay.v1.0.0"); @@ -39,10 +39,10 @@ public void flattenIncludedArchetype() throws Exception { InMemoryFullArchetypeRepository repository = new InMemoryFullArchetypeRepository(); repository.addArchetype(parent); repository.addArchetype(composition); - repository.compile(new ArchetypeValidator(BuiltinReferenceModels.getMetaModels())); + repository.compile(new ArchetypeValidator(BuiltinReferenceModels.getMetaModelProvider())); repository.getAllValidationResults().forEach(v -> assertTrue(v.getErrors().toString(), !v.hasWarningsOrErrors())); - OperationalTemplate opt = (OperationalTemplate) new Flattener(repository, BuiltinReferenceModels.getMetaModels(), FlattenerConfiguration.forOperationalTemplate()).flatten(composition); + OperationalTemplate opt = (OperationalTemplate) new Flattener(repository, BuiltinReferenceModels.getMetaModelProvider(), FlattenerConfiguration.forOperationalTemplate()).flatten(composition); assertEquals(VisibilityType.HIDE, opt.getRmOverlay().getRmVisibility().get("/content[id2]/subject").getVisibility()); assertEquals("at12", opt.getRmOverlay().getRmVisibility().get("/content[id2]/subject").getAlias().getCodeString()); } diff --git a/tools/src/test/java/com/nedap/archie/flattener/SiblingOrderFlattenerTest.java b/tools/src/test/java/com/nedap/archie/flattener/SiblingOrderFlattenerTest.java index b97de4458..e64653ec9 100644 --- a/tools/src/test/java/com/nedap/archie/flattener/SiblingOrderFlattenerTest.java +++ b/tools/src/test/java/com/nedap/archie/flattener/SiblingOrderFlattenerTest.java @@ -230,7 +230,7 @@ private Archetype parseAndCreateOPT(String fileName) throws IOException, ADLPars ValidationResult validationResult = new ArchetypeValidator(models).validate(result, repository); assertTrue(validationResult.getErrors().toString(), validationResult.passes()); - return new Flattener(repository, BuiltinReferenceModels.getMetaModels(), FlattenerConfiguration.forOperationalTemplate()).flatten(parse(fileName)); + return new Flattener(repository, BuiltinReferenceModels.getMetaModelProvider(), FlattenerConfiguration.forOperationalTemplate()).flatten(parse(fileName)); } private Archetype parseAndFlattenRemoveZeroOccurrences(String fileName) throws IOException, ADLParseException { @@ -241,6 +241,6 @@ private Archetype parseAndFlattenRemoveZeroOccurrences(String fileName) throws I assertTrue(validationResult.getErrors().toString(), validationResult.passes()); FlattenerConfiguration config = FlattenerConfiguration.forFlattened(); config.setRemoveZeroOccurrencesObjects(true); - return new Flattener(repository, BuiltinReferenceModels.getMetaModels(), config).flatten(parse(fileName)); + return new Flattener(repository, BuiltinReferenceModels.getMetaModelProvider(), config).flatten(parse(fileName)); } } diff --git a/tools/src/test/java/com/nedap/archie/flattener/specexamples/FlattenerExamplesFromSpecBMMTest.java b/tools/src/test/java/com/nedap/archie/flattener/specexamples/FlattenerExamplesFromSpecBMMTest.java index 2a26a2738..0edf0dbf0 100644 --- a/tools/src/test/java/com/nedap/archie/flattener/specexamples/FlattenerExamplesFromSpecBMMTest.java +++ b/tools/src/test/java/com/nedap/archie/flattener/specexamples/FlattenerExamplesFromSpecBMMTest.java @@ -1,7 +1,7 @@ package com.nedap.archie.flattener.specexamples; import com.nedap.archie.flattener.SimpleArchetypeRepository; -import com.nedap.archie.rminfo.MetaModels; +import com.nedap.archie.rminfo.SimpleMetaModelProvider; import org.junit.Before; import org.openehr.referencemodels.BuiltinReferenceModels; @@ -10,6 +10,6 @@ public class FlattenerExamplesFromSpecBMMTest extends FlattenerExamplesFromSpecT @Before public void setup() throws Exception { repository = new SimpleArchetypeRepository(); - models = new MetaModels(null, BuiltinReferenceModels.getBmmRepository(), BuiltinReferenceModels.getAomProfiles()); + metaModelProvider = new SimpleMetaModelProvider(null, BuiltinReferenceModels.getBmmRepository(), BuiltinReferenceModels.getAomProfiles()); } } diff --git a/tools/src/test/java/com/nedap/archie/flattener/specexamples/FlattenerExamplesFromSpecTest.java b/tools/src/test/java/com/nedap/archie/flattener/specexamples/FlattenerExamplesFromSpecTest.java index d208686bf..b5991cde7 100644 --- a/tools/src/test/java/com/nedap/archie/flattener/specexamples/FlattenerExamplesFromSpecTest.java +++ b/tools/src/test/java/com/nedap/archie/flattener/specexamples/FlattenerExamplesFromSpecTest.java @@ -9,7 +9,8 @@ import com.nedap.archie.base.MultiplicityInterval; import com.nedap.archie.flattener.Flattener; import com.nedap.archie.flattener.SimpleArchetypeRepository; -import com.nedap.archie.rminfo.MetaModels; +import com.nedap.archie.rminfo.MetaModelProvider; +import com.nedap.archie.rminfo.SimpleMetaModelProvider; import org.junit.Before; import org.junit.Test; import org.openehr.bmm.v2.validation.BmmRepository; @@ -26,12 +27,12 @@ public class FlattenerExamplesFromSpecTest { protected SimpleArchetypeRepository repository; - protected MetaModels models; + protected MetaModelProvider metaModelProvider; @Before public void setup() throws Exception { repository = new SimpleArchetypeRepository(); - models = new MetaModels(BuiltinReferenceModels.getAvailableModelInfoLookups(), (BmmRepository) null); + metaModelProvider = new SimpleMetaModelProvider(BuiltinReferenceModels.getAvailableModelInfoLookups(), null); } @Test @@ -39,7 +40,7 @@ public void specializationPaths() throws Exception { Archetype labTest = parse("openEHR-EHR-OBSERVATION.lab-test.v1.0.0.adls"); repository.addArchetype(labTest); Archetype specializationPaths = parse("specialization_paths.adls"); - Archetype flattened = new Flattener(repository, models).flatten(specializationPaths); + Archetype flattened = new Flattener(repository, metaModelProvider).flatten(specializationPaths); assertEquals(specializationPaths.getParentArchetypeId(), flattened.getParentArchetypeId()); CObject originalConstraint = flattened.itemAtPath("/data[id2]/events[id3]/data[id4]/items[id79]"); @@ -64,7 +65,7 @@ public void redefinitionForRefinement() throws Exception { Archetype problem = parse("problem.adls"); repository.addArchetype(problem); Archetype diagnosis = parse("diagnosis.adls"); - Archetype flattenedDiagnosis = new Flattener(repository, models).flatten(diagnosis); + Archetype flattenedDiagnosis = new Flattener(repository, metaModelProvider).flatten(diagnosis); assertEquals("Recording of diagnosis", flattenedDiagnosis.getDefinition().getTerm().getText()); @@ -101,7 +102,7 @@ public void specialisationWithCloning() throws Exception { Archetype labTestPanel = parse("openEHR-EHR-CLUSTER.laboratory_test_panel.v1.0.0.adls"); repository.addArchetype(labTestPanel); Archetype lipidStudiesPanel = parse("openEHR-EHR-CLUSTER.lipid_studies_panel.adls"); - Archetype flattenedLipidStudies = new Flattener(repository, models).flatten(lipidStudiesPanel); + Archetype flattenedLipidStudies = new Flattener(repository, metaModelProvider).flatten(lipidStudiesPanel); List itemNodes = flattenedLipidStudies.getDefinition().getAttribute("items").getChildren(); List nodeIds = itemNodes.stream().map(cObject -> cObject.getNodeId()).collect(Collectors.toList()); @@ -131,8 +132,8 @@ public void existenceRedefinition() throws Exception { Archetype mandatory = parse("openEHR-EHR-OBSERVATION.protocol_mandatory.v1.0.0.adls"); Archetype exclusion = parse("openEHR-EHR-OBSERVATION.protocol_exclusion.v1.0.0.adls"); - Archetype mandatoryFlat = new Flattener(repository, models).flatten(mandatory); - Archetype exclusionFlat = new Flattener(repository, models).flatten(exclusion); + Archetype mandatoryFlat = new Flattener(repository, metaModelProvider).flatten(mandatory); + Archetype exclusionFlat = new Flattener(repository, metaModelProvider).flatten(exclusion); CAttribute mandatoryProtocol = mandatoryFlat.getDefinition().getAttribute("protocol"); assertTrue(mandatoryProtocol.getExistence().isMandatory()); @@ -150,7 +151,7 @@ public void cardinalityRedefinition() throws Exception { repository.addArchetype(cardinalityParent); Archetype specialized = parse("openEHR-EHR-CLUSTER.cardinality_specialized.v1.0.0.adls"); - Archetype flat = new Flattener(repository, models).flatten(specialized); + Archetype flat = new Flattener(repository, metaModelProvider).flatten(specialized); CAttribute items = flat.getDefinition().getAttribute("items").getChildren().get(0).getAttribute("items"); assertEquals(new Cardinality(3, 10), items.getCardinality()); @@ -173,7 +174,7 @@ public void exclusionRemoval() throws Exception { Archetype occurrencesSpecialized = parse("openEHR-EHR-CLUSTER.occurrences_specialized.v1.0.0.adls"); - Archetype flat = new Flattener(repository, models).removeZeroOccurrencesConstraints(true).flatten(occurrencesSpecialized); + Archetype flat = new Flattener(repository, metaModelProvider).removeZeroOccurrencesConstraints(true).flatten(occurrencesSpecialized); CAttribute attribute = flat.itemAtPath("/items[id3]/value"); assertNotNull(flat.itemAtPath("/items[id3]/value[id5]")); assertNotNull(flat.itemAtPath("/items[id3]/value[id6]")); @@ -190,7 +191,7 @@ public void exclusionDefault() throws Exception { Archetype occurrencesSpecialized = parse("openEHR-EHR-CLUSTER.occurrences_specialized.v1.0.0.adls"); - Archetype flat = new Flattener(repository, models).flatten(occurrencesSpecialized); + Archetype flat = new Flattener(repository, metaModelProvider).flatten(occurrencesSpecialized); CAttribute attribute = flat.itemAtPath("/items[id3]/value"); assertNotNull(flat.itemAtPath("/items[id3]/value[id5]")); assertNotNull(flat.itemAtPath("/items[id3]/value[id6]")); @@ -214,7 +215,7 @@ public void RMTypeRefinement() throws Exception { Archetype specialized = parse("openEHR-EHR-ELEMENT.type_refinement_specialized.v1.0.0.adls"); repository.addArchetype(rmTypeRefinement); - Archetype flat = new Flattener(repository, models).flatten(specialized); + Archetype flat = new Flattener(repository, metaModelProvider).flatten(specialized); CAttribute value = flat.itemAtPath("/value"); assertEquals(3, value.getChildren().size()); @@ -241,7 +242,7 @@ public void internalReferenceRedefinition() throws Exception { repository.addArchetype(parent); Archetype specialized = parse("openEHR-EHR-ENTRY.reference_redefinition_specialized.v1.0.0.adls"); - Archetype flat = new Flattener(repository, models).flatten(specialized); + Archetype flat = new Flattener(repository, metaModelProvider).flatten(specialized); assertNotNull(flat.itemAtPath("/data[id3]/items[id4]")); assertNotNull(flat.itemAtPath("/data[id3]/items[id0.1]")); assertNull(flat.itemAtPath("/data[id2]/items[id0.1]")); @@ -254,7 +255,7 @@ public void internalReferenceRedefinitionNoReplacement() throws Exception { Archetype parent = parse("openEHR-EHR-ENTRY.reference_redefinition_parent.v1.0.0.adls"); repository.addArchetype(parent); Archetype specialized = parse("openEHR-EHR-ENTRY.reference_redefinition_no_replacement.v1.0.0.adls"); - Archetype flat = new Flattener(repository, models).flatten(specialized); + Archetype flat = new Flattener(repository, metaModelProvider).flatten(specialized); ArchetypeModelObject cluster = flat.itemAtPath("/data[id3]"); assertEquals(CComplexObjectProxy.class, cluster.getClass()); @@ -267,7 +268,7 @@ public void numericPrimitiveRedefinition() throws Exception { Archetype parent = parse("openEHR-EHR-ELEMENT.numeric_primitive_parent.v1.0.0.adls"); repository.addArchetype(parent); Archetype specialized = parse("openEHR-EHR-ELEMENT.numeric_primitive_specialized.v1.0.0.adls"); - Archetype flat = new Flattener(repository, models).flatten(specialized); + Archetype flat = new Flattener(repository, metaModelProvider).flatten(specialized); CReal flatConstraint = flat.itemAtPath("/value[id3]/magnitude[1]"); assertEquals(4.0d, flatConstraint.getConstraint().get(0).getLower(), 0.0001d); @@ -283,7 +284,7 @@ public void tupleRedefinition() throws Exception { Archetype parent = parse("openEHR-EHR-ELEMENT.tuple_parent.v1.0.0.adls"); repository.addArchetype(parent); Archetype specialized = parse("openEHR-EHR-ELEMENT.tuple_specialized.v1.0.0.adls"); - Archetype flat = new Flattener(repository, models).flatten(specialized); + Archetype flat = new Flattener(repository, metaModelProvider).flatten(specialized); //the tuple should be completely replaced with the new tuple //the attributes should be correct CComplexObject dvQuantity = flat.itemAtPath("/value[1]"); @@ -311,7 +312,7 @@ public void addTuple() throws Exception { Archetype parent = parse("openEHR-EHR-ELEMENT.type_refinement_parent.v1.0.0.adls"); repository.addArchetype(parent); Archetype specialized = parse("openEHR-EHR-ELEMENT.add_tuple.v1.0.0.adls"); - Archetype flat = new Flattener(repository, models).flatten(specialized); + Archetype flat = new Flattener(repository, metaModelProvider).flatten(specialized); //the tuple should be completely replaced with the new tuple //the attributes should be correct CComplexObject dvQuantity = flat.itemAtPath("/value[1]"); diff --git a/tools/src/test/java/com/nedap/archie/json/AOMJacksonTest.java b/tools/src/test/java/com/nedap/archie/json/AOMJacksonTest.java index 11d036810..4f1b7f1d0 100644 --- a/tools/src/test/java/com/nedap/archie/json/AOMJacksonTest.java +++ b/tools/src/test/java/com/nedap/archie/json/AOMJacksonTest.java @@ -8,6 +8,7 @@ import com.nedap.archie.aom.Archetype; import com.nedap.archie.aom.ArchetypeSlot; import com.nedap.archie.aom.CComplexObject; +import com.nedap.archie.aom.ResourceDescription; import com.nedap.archie.aom.primitives.CDuration; import com.nedap.archie.aom.primitives.CString; import com.nedap.archie.aom.primitives.CTerminologyCode; @@ -71,10 +72,46 @@ public void roundTripDeliriumObservationScreening() throws Exception { } } + @Test + public void parseLifecycleStateStringTest() throws Exception { + ObjectMapper objectMapper = JacksonUtil.getObjectMapper(ArchieJacksonConfiguration.createLegacyConfiguration()); + String resourceDescriptionJson = "{ \"lifecycle_state\" :\"unmanaged\" }"; + ResourceDescription resourceDescription = objectMapper.readValue(resourceDescriptionJson, ResourceDescription.class); + // assert that the lifecycle state is set to unmanaged + assertEquals("unmanaged", resourceDescription.getLifecycleState().getCodeString()); + } + + @Test + public void parseLifecycleStateTerminologyCodeTest() throws Exception { + ObjectMapper objectMapper = JacksonUtil.getObjectMapper(ArchieJacksonConfiguration.createLegacyConfiguration()); + String resourceDescriptionJson = "{ \"lifecycle_state\" : { \"code_string\" : \"unmanaged\" }}"; + ResourceDescription resourceDescription = objectMapper.readValue(resourceDescriptionJson, ResourceDescription.class); + // assert that the lifecycle state is set to unmanaged + assertEquals("unmanaged", resourceDescription.getLifecycleState().getCodeString()); + } + + @Test + public void parseLifecycleStateTerminologyCodeCodeStringNullTest() throws Exception { + ObjectMapper objectMapper = JacksonUtil.getObjectMapper(ArchieJacksonConfiguration.createLegacyConfiguration()); + String resourceDescriptionJson = "{ \"lifecycle_state\" : { \"code_string\" : null }}"; + ResourceDescription resourceDescription = objectMapper.readValue(resourceDescriptionJson, ResourceDescription.class); + // assert that the lifecycle state is set to unmanaged + assertNull(resourceDescription.getLifecycleState().getCodeString()); + } + + @Test + public void parseLifecycleStateTerminologyCodeNoCodeStringTest() throws Exception { + ObjectMapper objectMapper = JacksonUtil.getObjectMapper(ArchieJacksonConfiguration.createLegacyConfiguration()); + String resourceDescriptionJson = "{ \"lifecycle_state\" : { \"placeholder\" : \"placeholder\" }}"; + ResourceDescription resourceDescription = objectMapper.readValue(resourceDescriptionJson, ResourceDescription.class); + // assert that the lifecycle state is set to unmanaged + assertNull(resourceDescription.getLifecycleState().getCodeString()); + } + @Test public void motricityIndex() throws Exception { try(InputStream stream = getClass().getResourceAsStream( "/com/nedap/archie/rules/evaluation/openEHR-EHR-OBSERVATION.motricity_index.v1.0.0.adls")) { - Archetype archetype = new ADLParser(BuiltinReferenceModels.getMetaModels()).parse(stream); + Archetype archetype = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream); String serialized = JacksonUtil.getObjectMapper(ArchieJacksonConfiguration.createStandardsCompliant()).writeValueAsString(archetype); //System.out.println(serialized); assertTrue(serialized.contains("EXPR_BINARY_OPERATOR")); @@ -116,7 +153,7 @@ public void motricityIndexRulesOldFormatAsList() throws Exception { @Test public void motriciyIndexJavascriptFormat() throws Exception { try(InputStream stream = getClass().getResourceAsStream( "/com/nedap/archie/rules/evaluation/openEHR-EHR-OBSERVATION.motricity_index.v1.0.0.adls")) { - Archetype archetype = new ADLParser(BuiltinReferenceModels.getMetaModels()).parse(stream); + Archetype archetype = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream); String serialized = JacksonUtil.getObjectMapper(ArchieJacksonConfiguration.createConfigForJavascriptUsage()).writeValueAsString(archetype); //System.out.println(serialized); assertTrue(serialized.contains("EXPR_BINARY_OPERATOR")); @@ -136,7 +173,7 @@ public void motriciyIndexJavascriptFormat() throws Exception { @Test public void motricityIndexOldFormat() throws Exception { try(InputStream stream = getClass().getResourceAsStream( "/com/nedap/archie/rules/evaluation/openEHR-EHR-OBSERVATION.motricity_index.v1.0.0.adls")) { - Archetype archetype = new ADLParser(BuiltinReferenceModels.getMetaModels()).parse(stream); + Archetype archetype = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream); ArchieJacksonConfiguration config = ArchieJacksonConfiguration.createStandardsCompliant(); config.setStandardsCompliantExpressions(false); String serialized = JacksonUtil.getObjectMapper(config).writeValueAsString(archetype); @@ -155,7 +192,7 @@ public void motricityIndexOldFormat() throws Exception { @Test public void archetypeSlot() throws Exception { try(InputStream stream = getClass().getResourceAsStream( "/basic.adl")) { - Archetype archetype = new ADLParser(BuiltinReferenceModels.getMetaModels()).parse(stream); + Archetype archetype = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream); ObjectMapper objectMapper = new ObjectMapper(); JacksonUtil.configureObjectMapper(objectMapper, ArchieJacksonConfiguration.createStandardsCompliant()); objectMapper.disable(SerializationFeature.INDENT_OUTPUT); @@ -181,7 +218,7 @@ private void assertArchetypeSlot(ObjectMapper objectMapper, String serialized) t @Test public void archetypeSlotOldExpressionClassNames() throws Exception { try(InputStream stream = getClass().getResourceAsStream( "/basic.adl")) { - Archetype archetype = new ADLParser(BuiltinReferenceModels.getMetaModels()).parse(stream); + Archetype archetype = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream); ArchieJacksonConfiguration config = ArchieJacksonConfiguration.createStandardsCompliant(); config.setStandardsCompliantExpressions(false); ObjectMapper objectMapper = JacksonUtil.getObjectMapper(config); diff --git a/tools/src/test/java/com/nedap/archie/json/flat/FlatJsonGeneratorTest.java b/tools/src/test/java/com/nedap/archie/json/flat/FlatJsonGeneratorTest.java index ad6f38389..2f7d24dce 100644 --- a/tools/src/test/java/com/nedap/archie/json/flat/FlatJsonGeneratorTest.java +++ b/tools/src/test/java/com/nedap/archie/json/flat/FlatJsonGeneratorTest.java @@ -18,17 +18,23 @@ import com.nedap.archie.rm.datavalues.DvText; import com.nedap.archie.rm.datavalues.encapsulated.DvMultimedia; import com.nedap.archie.rm.datavalues.quantity.DvCount; +import com.nedap.archie.rm.datavalues.quantity.datetime.DvDuration; import com.nedap.archie.rminfo.ArchieRMInfoLookup; -import com.nedap.archie.rminfo.MetaModels; +import com.nedap.archie.rminfo.MetaModel; +import com.nedap.archie.rminfo.MetaModelProvider; import org.junit.After; import org.junit.Test; import org.openehr.referencemodels.BuiltinReferenceModels; +import org.threeten.extra.PeriodDuration; import java.io.IOException; import java.io.InputStream; +import java.time.Duration; +import java.time.Period; import java.util.LinkedHashMap; import java.util.Map; +import static junit.framework.Assert.assertTrue; import static junit.framework.TestCase.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; @@ -73,7 +79,15 @@ public void testBloodPressureExample() throws Exception { } + @Test + public void testBloodPressureEmpty() throws Exception { + OperationalTemplate bloodPressureOpt = parseBloodPressure(); + FlatJsonGenerator flatJsonGenerator = new FlatJsonGenerator(ArchieRMInfoLookup.getInstance(), FlatJsonFormatConfiguration.nedapInternalFormat()); + Map pathsAndValues = flatJsonGenerator.buildPathsAndValues(new Observation(), bloodPressureOpt, "en"); + + assertTrue(pathsAndValues.isEmpty()); + } @Test public void testBloodPressureExampleWithPipesForFinalFields() throws Exception { @@ -131,6 +145,21 @@ public void testNedapInternalFormat() throws Exception { assertEquals("Systolic", stringObjectMap.get("/data[id2]/events[id7,2]/data[id4]/items[id5,1]/name/value")); } + @Test + public void testDurationFlattening() throws Exception { + FlatJsonGenerator flatJsonGenerator = new FlatJsonGenerator(ArchieRMInfoLookup.getInstance(), FlatJsonFormatConfiguration.nedapInternalFormat()); + + // Test a positive duration, make sure the value is a String and not a Duration object + DvDuration duration = new DvDuration(PeriodDuration.of(Period.of(1,0,0), Duration.ofHours(13))); + Map pathsAndValues = flatJsonGenerator.buildPathsAndValues(duration); + assertEquals("P1YT13H", pathsAndValues.get("/value")); + + // Also test a negative duration + DvDuration negativeDuration = new DvDuration(PeriodDuration.of(Period.of(-1,-2,-4), Duration.ofSeconds(-5736))); + Map secondPathsAndValues = flatJsonGenerator.buildPathsAndValues(negativeDuration); + assertEquals("-P1Y2M4DT1H35M36S", secondPathsAndValues.get("/value")); + } + @Test public void continuesIndices() throws Exception { Cluster cluster = new Cluster(); @@ -181,7 +210,7 @@ public void dontSerializeNames() throws Exception { config.setFilterNames(true); config.setFilterTypes(false); //config.getIgnoredAttributes().add(new AttributeReference("LOCATABLE", "name")); - Map stringObjectMap = new FlatJsonExampleInstanceGenerator().generateExample(bloodPressureOpt, BuiltinReferenceModels.getMetaModels(), "en", config); + Map stringObjectMap = new FlatJsonExampleInstanceGenerator().generateExample(bloodPressureOpt, BuiltinReferenceModels.getMetaModelProvider(), "en", config); System.out.println(JacksonUtil.getObjectMapper().writeValueAsString(stringObjectMap)); @@ -210,13 +239,13 @@ public void dontSerializeTypes() throws Exception { config.setFilterNames(true); config.setFilterTypes(true); //config.getIgnoredAttributes().add(new AttributeReference("LOCATABLE", "name")); - MetaModels metaModels = BuiltinReferenceModels.getMetaModels(); - metaModels.selectModel(bloodPressureOpt); + MetaModelProvider metaModelProvider = BuiltinReferenceModels.getMetaModelProvider(); + MetaModel metaModel = metaModelProvider.getMetaModel(bloodPressureOpt); - ExampleJsonInstanceGenerator exampleJsonInstanceGenerator = new ExampleJsonInstanceGenerator(metaModels, "en"); + ExampleJsonInstanceGenerator exampleJsonInstanceGenerator = new ExampleJsonInstanceGenerator(metaModelProvider, "en"); exampleJsonInstanceGenerator.setTypePropertyName("_type"); Map generatedExample = exampleJsonInstanceGenerator.generate(bloodPressureOpt); - ObjectMapper objectMapper = metaModels.getSelectedModel().getJsonObjectMapper(); + ObjectMapper objectMapper = metaModel.getJsonObjectMapper(); String jsonRmObject = objectMapper.writeValueAsString(generatedExample); Observation bloodPressure = objectMapper.readValue(jsonRmObject, Observation.class); //set the name to be different from the archetype, so it will be added here @@ -224,7 +253,7 @@ public void dontSerializeTypes() throws Exception { - Map stringObjectMap = new FlatJsonGenerator(metaModels.getSelectedModelInfoLookup(), config).buildPathsAndValues(bloodPressure, bloodPressureOpt, "en"); + Map stringObjectMap = new FlatJsonGenerator(metaModel.getModelInfoLookup(), config).buildPathsAndValues(bloodPressure, bloodPressureOpt, "en"); System.out.println(JacksonUtil.getObjectMapper().writeValueAsString(stringObjectMap)); @@ -259,19 +288,19 @@ public void restoresThreadLocalDescriptiongAndMeaningLanguage() throws Exceptio OperationalTemplate bloodPressureOpt = parseBloodPressure(); FlatJsonFormatConfiguration config = FlatJsonFormatConfiguration.nedapInternalFormat(); - MetaModels metaModels = BuiltinReferenceModels.getMetaModels(); - metaModels.selectModel(bloodPressureOpt); + MetaModelProvider metaModelProvider = BuiltinReferenceModels.getMetaModelProvider(); + MetaModel metaModel = metaModelProvider.getMetaModel(bloodPressureOpt); - ExampleJsonInstanceGenerator exampleJsonInstanceGenerator = new ExampleJsonInstanceGenerator(metaModels, "en"); + ExampleJsonInstanceGenerator exampleJsonInstanceGenerator = new ExampleJsonInstanceGenerator(metaModelProvider, "en"); exampleJsonInstanceGenerator.setTypePropertyName("_type"); Map generatedExample = exampleJsonInstanceGenerator.generate(bloodPressureOpt); - ObjectMapper objectMapper = metaModels.getSelectedModel().getJsonObjectMapper(); + ObjectMapper objectMapper = metaModel.getJsonObjectMapper(); String jsonRmObject = objectMapper.writeValueAsString(generatedExample); Observation bloodPressure = objectMapper.readValue(jsonRmObject, Observation.class); ArchieLanguageConfiguration.setThreadLocalDescriptiongAndMeaningLanguage("nl"); - new FlatJsonGenerator(metaModels.getSelectedModelInfoLookup(), config).buildPathsAndValues(bloodPressure, bloodPressureOpt, "en"); + new FlatJsonGenerator(metaModel.getModelInfoLookup(), config).buildPathsAndValues(bloodPressure, bloodPressureOpt, "en"); // The ThreadLocalDescriptiongAndMeaningLanguage should be restored to nl after the buildPathsAndValues call. assertEquals("nl", ArchieLanguageConfiguration.getThreadLocalDescriptiongAndMeaningLanguage()); @@ -287,7 +316,7 @@ public void filterTypesWithAlternatives() throws Exception { config.setFilterNames(true); config.setFilterTypes(true); //config.getIgnoredAttributes().add(new AttributeReference("LOCATABLE", "name")); - Map stringObjectMap = new FlatJsonExampleInstanceGenerator().generateExample(bloodPressureOpt, BuiltinReferenceModels.getMetaModels(), "en", config); + Map stringObjectMap = new FlatJsonExampleInstanceGenerator().generateExample(bloodPressureOpt, BuiltinReferenceModels.getMetaModelProvider(), "en", config); System.out.println(JacksonUtil.getObjectMapper().writeValueAsString(stringObjectMap)); @@ -303,21 +332,21 @@ public void filterTypesWithAlternatives() throws Exception { private OperationalTemplate parseBloodPressure() throws IOException, ADLParseException { try (InputStream stream = getClass().getResourceAsStream(BLOOD_PRESSURE_PATH)) { - Archetype bloodPressure = new ADLParser(BuiltinReferenceModels.getMetaModels()).parse(stream); - Flattener flattener = new Flattener(new SimpleArchetypeRepository(), BuiltinReferenceModels.getMetaModels(), FlattenerConfiguration.forOperationalTemplate()); + Archetype bloodPressure = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream); + Flattener flattener = new Flattener(new SimpleArchetypeRepository(), BuiltinReferenceModels.getMetaModelProvider(), FlattenerConfiguration.forOperationalTemplate()); return (OperationalTemplate) flattener.flatten(bloodPressure); } } private OperationalTemplate parseTypeAlternatives() throws IOException, ADLParseException { try (InputStream stream = getClass().getResourceAsStream("openEHR-EHR-CLUSTER.element_with_two_dv_types.v1.0.0.adls")) { - Archetype typeAlternatives = new ADLParser(BuiltinReferenceModels.getMetaModels()).parse(stream); - Flattener flattener = new Flattener(new SimpleArchetypeRepository(), BuiltinReferenceModels.getMetaModels(), FlattenerConfiguration.forOperationalTemplate()); + Archetype typeAlternatives = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()).parse(stream); + Flattener flattener = new Flattener(new SimpleArchetypeRepository(), BuiltinReferenceModels.getMetaModelProvider(), FlattenerConfiguration.forOperationalTemplate()); return (OperationalTemplate) flattener.flatten(typeAlternatives); } } private Map createExampleInstance(OperationalTemplate bloodPressureOpt, FlatJsonFormatConfiguration config) throws IOException, DuplicateKeyException { - return new FlatJsonExampleInstanceGenerator().generateExample(bloodPressureOpt, BuiltinReferenceModels.getMetaModels(), "en", config); + return new FlatJsonExampleInstanceGenerator().generateExample(bloodPressureOpt, BuiltinReferenceModels.getMetaModelProvider(), "en", config); } } diff --git a/tools/src/test/java/com/nedap/archie/query/RMObjectAttributesTest.java b/tools/src/test/java/com/nedap/archie/query/RMObjectAttributesTest.java index f9e641619..8ade2073c 100644 --- a/tools/src/test/java/com/nedap/archie/query/RMObjectAttributesTest.java +++ b/tools/src/test/java/com/nedap/archie/query/RMObjectAttributesTest.java @@ -23,6 +23,7 @@ import static com.nedap.archie.query.RMObjectAttributes.getAttributeValueFromRMObject; import static org.junit.Assert.assertSame; +@Deprecated public class RMObjectAttributesTest { private TestUtil testUtil; diff --git a/tools/src/test/java/com/nedap/archie/rmobjectvalidator/RmObjectValidatorTest.java b/tools/src/test/java/com/nedap/archie/rmobjectvalidator/RmObjectValidatorTest.java index 569fc5820..7f965e921 100644 --- a/tools/src/test/java/com/nedap/archie/rmobjectvalidator/RmObjectValidatorTest.java +++ b/tools/src/test/java/com/nedap/archie/rmobjectvalidator/RmObjectValidatorTest.java @@ -86,7 +86,7 @@ public void cardinalityMismatchValidation() throws Exception { } private OperationalTemplate createOpt(Archetype archetype) { - return (OperationalTemplate) new Flattener(emptyRepo, BuiltinReferenceModels.getMetaModels(), FlattenerConfiguration.forOperationalTemplate()).flatten(archetype); + return (OperationalTemplate) new Flattener(emptyRepo, BuiltinReferenceModels.getMetaModelProvider(), FlattenerConfiguration.forOperationalTemplate()).flatten(archetype); } @Test diff --git a/tools/src/test/java/com/nedap/archie/rmobjectvalidator/TerminologyCodeConstraintsTest.java b/tools/src/test/java/com/nedap/archie/rmobjectvalidator/TerminologyCodeConstraintsTest.java index 04d8afb9b..03d2eaa4a 100644 --- a/tools/src/test/java/com/nedap/archie/rmobjectvalidator/TerminologyCodeConstraintsTest.java +++ b/tools/src/test/java/com/nedap/archie/rmobjectvalidator/TerminologyCodeConstraintsTest.java @@ -213,7 +213,7 @@ public void validationInOptTest() throws Exception { repository.addArchetype(FlattenerTestUtil.parse("/com/nedap/archie/aom/openEHR-EHR-GENERIC_ENTRY.included.v1.0.0.adls")); //create operational template - Flattener flattener = new Flattener(repository, BuiltinReferenceModels.getMetaModels(), FlattenerConfiguration.forOperationalTemplate()); + Flattener flattener = new Flattener(repository, BuiltinReferenceModels.getMetaModelProvider(), FlattenerConfiguration.forOperationalTemplate()); OperationalTemplate opt = (OperationalTemplate) flattener.flatten(repository.getArchetype("openEHR-EHR-COMPOSITION.parent.v1.0.0")); CTerminologyCode code = opt.itemAtPath("/content/data/items/value/defining_code[1]"); assertEquals(Lists.newArrayList("at4", "at5", "at6"), code.getValueSetExpanded()); diff --git a/tools/src/test/java/com/nedap/archie/rmobjectvalidator/ValidateArchetypedTest.java b/tools/src/test/java/com/nedap/archie/rmobjectvalidator/ValidateArchetypedTest.java index b6524cee0..7fe9e1799 100644 --- a/tools/src/test/java/com/nedap/archie/rmobjectvalidator/ValidateArchetypedTest.java +++ b/tools/src/test/java/com/nedap/archie/rmobjectvalidator/ValidateArchetypedTest.java @@ -87,7 +87,7 @@ public void testArchetypedOtherDetails() { } private OperationalTemplate createOpt(Archetype archetype) { - return (OperationalTemplate) new Flattener(repo, BuiltinReferenceModels.getMetaModels(), FlattenerConfiguration.forOperationalTemplate()).flatten(archetype); + return (OperationalTemplate) new Flattener(repo, BuiltinReferenceModels.getMetaModelProvider(), FlattenerConfiguration.forOperationalTemplate()).flatten(archetype); } private Archetype parse(String filename) throws IOException, ADLParseException { diff --git a/tools/src/test/java/com/nedap/archie/rmobjectvalidator/validations/ArchetypeSlotValidationTest.java b/tools/src/test/java/com/nedap/archie/rmobjectvalidator/validations/ArchetypeSlotValidationTest.java index ac17ccaea..07c3d80aa 100644 --- a/tools/src/test/java/com/nedap/archie/rmobjectvalidator/validations/ArchetypeSlotValidationTest.java +++ b/tools/src/test/java/com/nedap/archie/rmobjectvalidator/validations/ArchetypeSlotValidationTest.java @@ -62,14 +62,14 @@ public void setup() throws IOException, ADLParseException { repository.setOperationalTemplate(includedOpt); repository.setOperationalTemplate(parentOfIncludedOpt); - generator = new ExampleJsonInstanceGenerator(BuiltinReferenceModels.getMetaModels(), "en"); + generator = new ExampleJsonInstanceGenerator(BuiltinReferenceModels.getMetaModelProvider(), "en"); Map generated = generator.generate(parentOpt); example = JacksonUtil.getObjectMapper().readValue(JacksonUtil.getObjectMapper().writeValueAsString(generated), Section.class); rmObjectValidator = new RMObjectValidator(ArchieRMInfoLookup.getInstance(), repository, new ValidationConfiguration.Builder().build()); } private Flattener createFlattener() { - return new Flattener(repository, BuiltinReferenceModels.getMetaModels(), FlattenerConfiguration.forOperationalTemplate()); + return new Flattener(repository, BuiltinReferenceModels.getMetaModelProvider(), FlattenerConfiguration.forOperationalTemplate()); } @Test diff --git a/tools/src/test/java/com/nedap/archie/rules/evaluation/FixableAssertionsCheckerTest.java b/tools/src/test/java/com/nedap/archie/rules/evaluation/FixableAssertionsCheckerTest.java index b6f611fe1..3fa41d240 100644 --- a/tools/src/test/java/com/nedap/archie/rules/evaluation/FixableAssertionsCheckerTest.java +++ b/tools/src/test/java/com/nedap/archie/rules/evaluation/FixableAssertionsCheckerTest.java @@ -38,7 +38,7 @@ public class FixableAssertionsCheckerTest { public void setup() { testUtil = new TestUtil(); rmObjectCreator = new RMObjectCreator(ArchieRMInfoLookup.getInstance()); - parser = new ADLParser(BuiltinReferenceModels.getMetaModels()); + parser = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()); ArchieLanguageConfiguration.setThreadLocalLogicalPathLanguage("en"); ArchieLanguageConfiguration.setThreadLocalDescriptiongAndMeaningLanguage("en"); } diff --git a/tools/src/test/java/com/nedap/archie/rules/evaluation/ParsedRulesEvaluationTest.java b/tools/src/test/java/com/nedap/archie/rules/evaluation/ParsedRulesEvaluationTest.java index 65ea42b23..75d177bf8 100644 --- a/tools/src/test/java/com/nedap/archie/rules/evaluation/ParsedRulesEvaluationTest.java +++ b/tools/src/test/java/com/nedap/archie/rules/evaluation/ParsedRulesEvaluationTest.java @@ -50,7 +50,7 @@ public abstract class ParsedRulesEvaluationTest { @Before public void setup() { testUtil = new TestUtil(); - parser = new ADLParser(BuiltinReferenceModels.getMetaModels()); + parser = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()); } public Archetype getArchetype() { @@ -781,9 +781,9 @@ public void flattenedRules() throws IOException, ADLParseException { InMemoryFullArchetypeRepository repository = new InMemoryFullArchetypeRepository(); repository.addArchetype(parent); repository.addArchetype(valueSet); - Flattener flattener = new Flattener(repository, BuiltinReferenceModels.getMetaModels(), FlattenerConfiguration.forOperationalTemplate()); + Flattener flattener = new Flattener(repository, BuiltinReferenceModels.getMetaModelProvider(), FlattenerConfiguration.forOperationalTemplate()); OperationalTemplate opt = (OperationalTemplate) flattener.flatten(parent); - ExampleJsonInstanceGenerator generator = new ExampleJsonInstanceGenerator(BuiltinReferenceModels.getMetaModels(), "en"); + ExampleJsonInstanceGenerator generator = new ExampleJsonInstanceGenerator(BuiltinReferenceModels.getMetaModelProvider(), "en"); Map exampleInstance = generator.generate(opt); Cluster cluster = JacksonUtil.getObjectMapper().readValue(JacksonUtil.getObjectMapper().writeValueAsString(exampleInstance), Cluster.class); //correct case first diff --git a/tools/src/test/java/com/nedap/archie/serializer/adl/ADLArchetypeSerializerParserRoundtripTest.java b/tools/src/test/java/com/nedap/archie/serializer/adl/ADLArchetypeSerializerParserRoundtripTest.java index 915be2668..42eff84ce 100644 --- a/tools/src/test/java/com/nedap/archie/serializer/adl/ADLArchetypeSerializerParserRoundtripTest.java +++ b/tools/src/test/java/com/nedap/archie/serializer/adl/ADLArchetypeSerializerParserRoundtripTest.java @@ -154,7 +154,7 @@ private Archetype roundtrip(Archetype archetype, RMObjectMapperProvider rmObject String serialized = ADLArchetypeSerializer.serialize(archetype, null, rmObjectMapperProvider); logger.info(serialized); - ADLParser parser = new ADLParser(BuiltinReferenceModels.getMetaModels()); + ADLParser parser = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()); Archetype result = parser.parse(serialized); assertTrue("roundtrip parsing should never cause errors: " + parser.getErrors().toString(), parser.getErrors().hasNoErrors()); @@ -166,11 +166,11 @@ private Archetype roundtrip(Archetype archetype, RMObjectMapperProvider rmObject } private Archetype load(String resourceName) throws IOException, ADLParseException { - return new ADLParser(BuiltinReferenceModels.getMetaModels()).parse(ADLArchetypeSerializerTest.class.getResourceAsStream(resourceName)); + return new ADLParser(BuiltinReferenceModels.getMetaModelProvider()).parse(ADLArchetypeSerializerTest.class.getResourceAsStream(resourceName)); } private Archetype loadRoot(String resourceName) throws IOException, ADLParseException { - return new ADLParser(BuiltinReferenceModels.getMetaModels()).parse(ADLArchetypeSerializerTest.class.getClassLoader().getResourceAsStream(resourceName)); + return new ADLParser(BuiltinReferenceModels.getMetaModelProvider()).parse(ADLArchetypeSerializerTest.class.getClassLoader().getResourceAsStream(resourceName)); } @Test @@ -245,7 +245,7 @@ public void operationalTemplate() throws Exception { repository.addArchetype(height); repository.addArchetype(heightTemplate); - Flattener flattener = new Flattener(repository, BuiltinReferenceModels.getMetaModels()).createOperationalTemplate(true); + Flattener flattener = new Flattener(repository, BuiltinReferenceModels.getMetaModelProvider()).createOperationalTemplate(true); Archetype operationalTemplate = flattener.flatten(bloodPressureComposition); Archetype parsed = roundtrip(operationalTemplate); TestUtil.assertCObjectEquals(operationalTemplate.getDefinition(), parsed.getDefinition()); diff --git a/tools/src/test/java/com/nedap/archie/serializer/adl/ADLArchetypeSerializerTest.java b/tools/src/test/java/com/nedap/archie/serializer/adl/ADLArchetypeSerializerTest.java index a176da12d..30f281725 100644 --- a/tools/src/test/java/com/nedap/archie/serializer/adl/ADLArchetypeSerializerTest.java +++ b/tools/src/test/java/com/nedap/archie/serializer/adl/ADLArchetypeSerializerTest.java @@ -119,7 +119,7 @@ public void rmOverlay() throws Exception { " >\n" + " >")); - Archetype parsed = new ADLParser(BuiltinReferenceModels.getMetaModels()).parse(serialized); + Archetype parsed = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()).parse(serialized); assertEquals(VisibilityType.HIDE, parsed.getRmOverlay().getRmVisibility().get("/subject").getVisibility()); assertEquals("at12", parsed.getRmOverlay().getRmVisibility().get("/subject").getAlias().getCodeString()); } diff --git a/tools/src/test/java/com/nedap/archie/serializer/adl/DefaultValueSerializerTest.java b/tools/src/test/java/com/nedap/archie/serializer/adl/DefaultValueSerializerTest.java index 21ed50106..313227fda 100644 --- a/tools/src/test/java/com/nedap/archie/serializer/adl/DefaultValueSerializerTest.java +++ b/tools/src/test/java/com/nedap/archie/serializer/adl/DefaultValueSerializerTest.java @@ -22,7 +22,7 @@ public class DefaultValueSerializerTest { @Test public void serializeDvTextOdin() throws Exception { - ADLParser adlParser = new ADLParser(BuiltinReferenceModels.getMetaModels()); + ADLParser adlParser = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()); try(InputStream stream = getClass().getResourceAsStream("openEHR-EHR-CLUSTER.simple.v1.adls")) { Archetype archetype = adlParser.parse(stream); CComplexObject cComplexObject = archetype.itemAtPath("/items[id2]/value[id21]"); @@ -46,7 +46,7 @@ public void serializeDvTextOdin() throws Exception { @Test public void serializeDvTextJson() throws Exception { - ADLParser adlParser = new ADLParser(BuiltinReferenceModels.getMetaModels()); + ADLParser adlParser = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()); try(InputStream stream = getClass().getResourceAsStream("openEHR-EHR-CLUSTER.simple.v1.adls")) { Archetype archetype = adlParser.parse(stream); CComplexObject cComplexObject = archetype.itemAtPath("/items[id2]/value[id21]"); @@ -72,7 +72,7 @@ public void serializeDvTextJson() throws Exception { @Test public void serializeDvCodedTextJson() throws Exception { - ADLParser adlParser = new ADLParser(BuiltinReferenceModels.getMetaModels()); + ADLParser adlParser = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()); try(InputStream stream = getClass().getResourceAsStream("openEHR-EHR-CLUSTER.simple.v1.adls")) { Archetype archetype = adlParser.parse(stream); CComplexObject cComplexObject = archetype.itemAtPath("/items[id2]/value[id21]"); @@ -99,7 +99,7 @@ public void serializeDvCodedTextJson() throws Exception { @Test public void serializeDvCodedTextOdin() throws Exception { - ADLParser adlParser = new ADLParser(BuiltinReferenceModels.getMetaModels()); + ADLParser adlParser = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()); try(InputStream stream = getClass().getResourceAsStream("openEHR-EHR-CLUSTER.simple.v1.adls")) { Archetype archetype = adlParser.parse(stream); CComplexObject cComplexObject = archetype.itemAtPath("/items[id2]/value[id21]"); @@ -126,7 +126,7 @@ public void serializeDvCodedTextOdin() throws Exception { @Test public void serializeClusterJson() throws Exception { - ADLParser adlParser = new ADLParser(BuiltinReferenceModels.getMetaModels()); + ADLParser adlParser = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()); try(InputStream stream = getClass().getResourceAsStream("openEHR-EHR-CLUSTER.simple.v1.adls")) { Archetype archetype = adlParser.parse(stream); CComplexObject cComplexObject = archetype.getDefinition(); @@ -155,7 +155,7 @@ public void serializeClusterJson() throws Exception { @Test public void serializeClusterOdin() throws Exception { - ADLParser adlParser = new ADLParser(BuiltinReferenceModels.getMetaModels()); + ADLParser adlParser = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()); try(InputStream stream = getClass().getResourceAsStream("openEHR-EHR-CLUSTER.simple.v1.adls")) { Archetype archetype = adlParser.parse(stream); CComplexObject cComplexObject = archetype.getDefinition(); diff --git a/tools/src/test/java/com/nedap/archie/testutil/TestUtil.java b/tools/src/test/java/com/nedap/archie/testutil/TestUtil.java index 55e04ffde..21228970f 100644 --- a/tools/src/test/java/com/nedap/archie/testutil/TestUtil.java +++ b/tools/src/test/java/com/nedap/archie/testutil/TestUtil.java @@ -1,6 +1,5 @@ package com.nedap.archie.testutil; -import com.google.common.collect.Lists; import com.nedap.archie.adlparser.ADLParseException; import com.nedap.archie.adlparser.ADLParser; import com.nedap.archie.antlr.errors.ANTLRParserErrors; @@ -10,6 +9,7 @@ import com.nedap.archie.flattener.InMemoryFullArchetypeRepository; import com.nedap.archie.rm.RMObject; import com.nedap.archie.rminfo.ArchieRMInfoLookup; +import com.nedap.archie.rminfo.AttributeAccessor; import org.reflections.Reflections; import org.reflections.scanners.Scanners; import org.slf4j.Logger; @@ -34,6 +34,7 @@ public class TestUtil { private static final Logger logger = LoggerFactory.getLogger(TestUtil.class); private RMObjectCreator creator = new RMObjectCreator(ArchieRMInfoLookup.getInstance()); + private final AttributeAccessor attributeAccessor = new AttributeAccessor(ArchieRMInfoLookup.getInstance()); /** * Creates an empty RM Object, fully nested, one object per CObject found. @@ -61,10 +62,10 @@ public RMObject constructEmptyRMObject(CObject object) { } if(!children.isEmpty()) { if(attribute.isMultiple()) { - creator.set(result, attribute.getRmAttributeName(), children); + attributeAccessor.setValue(result, attribute.getRmAttributeName(), children); } else if(!children.isEmpty()){ //set the first possible result in case of multiple children for a single valued value - creator.set(result, attribute.getRmAttributeName(), Lists.newArrayList(children.get(0))); + attributeAccessor.setValue(result, attribute.getRmAttributeName(), children.get(0)); } } } diff --git a/tools/src/test/java/com/nedap/archie/xml/JAXBAOMTest.java b/tools/src/test/java/com/nedap/archie/xml/JAXBAOMTest.java index f18b63052..316f91d96 100644 --- a/tools/src/test/java/com/nedap/archie/xml/JAXBAOMTest.java +++ b/tools/src/test/java/com/nedap/archie/xml/JAXBAOMTest.java @@ -17,6 +17,7 @@ import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; +import java.io.InputStream; import java.io.StringReader; import java.io.StringWriter; import java.time.temporal.TemporalAmount; @@ -285,4 +286,44 @@ public void templateXml() throws Exception { } + @Test + public void parseWithLifecycleStateString() throws Exception { + try(InputStream stream = getClass().getResourceAsStream("to_flatten_parent_with_overlay_lifecycle_state_string.xml")) { + Unmarshaller unmarshaller = JAXBUtil.getArchieJAXBContext().createUnmarshaller(); + Archetype unmarshalled = (Archetype) unmarshaller.unmarshal(stream); + // assert that the lifecycle state is set to published + assertEquals("published", unmarshalled.getDescription().getLifecycleState().getCodeString()); + } + } + + @Test + public void parseWithLifecycleStateTerminologyCode() throws Exception { + try(InputStream stream = getClass().getResourceAsStream("to_flatten_parent_with_overlay_lifecycle_state_term_code.xml")) { + Unmarshaller unmarshaller = JAXBUtil.getArchieJAXBContext().createUnmarshaller(); + Archetype unmarshalled = (Archetype) unmarshaller.unmarshal(stream); + // assert that the lifecycle state is set to published + assertEquals("published", unmarshalled.getDescription().getLifecycleState().getCodeString()); + } + } + + @Test + public void parseWithEmptyLifecycleStateBlock() throws Exception { + try(InputStream stream = getClass().getResourceAsStream("to_flatten_parent_with_overlay_empty_lifecycle_state_block.xml")) { + Unmarshaller unmarshaller = JAXBUtil.getArchieJAXBContext().createUnmarshaller(); + Archetype unmarshalled = (Archetype) unmarshaller.unmarshal(stream); + // assert that the lifecycle state is set to published + assertEquals(null, unmarshalled.getDescription().getLifecycleState()); + } + } + + @Test + public void parseWithNewlineLifecycleStateBlock() throws Exception { + try(InputStream stream = getClass().getResourceAsStream("to_flatten_parent_with_overlay_newline_lifecycle_state_block.xml")) { + Unmarshaller unmarshaller = JAXBUtil.getArchieJAXBContext().createUnmarshaller(); + Archetype unmarshalled = (Archetype) unmarshaller.unmarshal(stream); + // assert that the lifecycle state is set to published + assertEquals(null, unmarshalled.getDescription().getLifecycleState()); + } + } + } diff --git a/tools/src/test/java/com/nedap/archie/xml/JAXBRMRoundTripTest.java b/tools/src/test/java/com/nedap/archie/xml/JAXBRMRoundTripTest.java index 97c5fb38b..9ee8a65dd 100644 --- a/tools/src/test/java/com/nedap/archie/xml/JAXBRMRoundTripTest.java +++ b/tools/src/test/java/com/nedap/archie/xml/JAXBRMRoundTripTest.java @@ -40,7 +40,7 @@ public class JAXBRMRoundTripTest { @Before public void setup() { testUtil = new TestUtil(); - parser = new ADLParser(BuiltinReferenceModels.getMetaModels()); + parser = new ADLParser(BuiltinReferenceModels.getMetaModelProvider()); } @Test diff --git a/tools/src/test/resources/com/nedap/archie/xml/to_flatten_parent_with_overlay_empty_lifecycle_state_block.xml b/tools/src/test/resources/com/nedap/archie/xml/to_flatten_parent_with_overlay_empty_lifecycle_state_block.xml new file mode 100644 index 000000000..04a638191 --- /dev/null +++ b/tools/src/test/resources/com/nedap/archie/xml/to_flatten_parent_with_overlay_empty_lifecycle_state_block.xml @@ -0,0 +1,329 @@ + + + + Pieter Bos + + copyright © 2004 openEHR Foundation <http://www.openEHR.org> +
+ + ISO_639-1 + en + + Test for flattening + ADL + test +
+
+ + ISO_639-1 + en + + + + + false + + + true + + false + false + + 1 + + + + + 1 + + + false + + + true + + false + false + + 3 + 3 + + + + + false + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + + 0.0 + 1000.0 + + + + mmHg + + + + 1 + 1 + + + + + + + + + + false + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + + 0.0 + 1000.0 + + + + mmHg + + + + 1 + 1 + + + + + + + + + + false + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + + 0.0 + 1000.0 + + + + mmHg + + + + 1 + 1 + + + + + + + + + + + + + + + + + id1 + + + The local measurement of arterial blood pressure which is a surrogate for arterial. pressure in the systemic circulation. Most commonly, use of the term 'blood pressure' refers to measurement of brachial artery pressure in the upper arm. + Blood Pressure + + + any event + any event + + + Systolic Pressure + systolic + + + -- diastolic pressure + diastolic pressure + + + testing 1 2 3 + pressure difference + + + ingocnito mode activated + some subject + + + + + + /subject + hide + + local + at12 + + + + /data[id2]/events[id3]/data[id4]/items[id5] + show + + + /data[id2]/events[id3]/data[id4]/items[id6] + show + + +
diff --git a/tools/src/test/resources/com/nedap/archie/xml/to_flatten_parent_with_overlay_lifecycle_state_string.xml b/tools/src/test/resources/com/nedap/archie/xml/to_flatten_parent_with_overlay_lifecycle_state_string.xml new file mode 100644 index 000000000..1393c0900 --- /dev/null +++ b/tools/src/test/resources/com/nedap/archie/xml/to_flatten_parent_with_overlay_lifecycle_state_string.xml @@ -0,0 +1,329 @@ + + + + Pieter Bos + published + copyright © 2004 openEHR Foundation <http://www.openEHR.org> +
+ + ISO_639-1 + en + + Test for flattening + ADL + test +
+
+ + ISO_639-1 + en + + + + + false + + + true + + false + false + + 1 + + + + + 1 + + + false + + + true + + false + false + + 3 + 3 + + + + + false + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + + 0.0 + 1000.0 + + + + mmHg + + + + 1 + 1 + + + + + + + + + + false + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + + 0.0 + 1000.0 + + + + mmHg + + + + 1 + 1 + + + + + + + + + + false + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + + 0.0 + 1000.0 + + + + mmHg + + + + 1 + 1 + + + + + + + + + + + + + + + + + id1 + + + The local measurement of arterial blood pressure which is a surrogate for arterial. pressure in the systemic circulation. Most commonly, use of the term 'blood pressure' refers to measurement of brachial artery pressure in the upper arm. + Blood Pressure + + + any event + any event + + + Systolic Pressure + systolic + + + -- diastolic pressure + diastolic pressure + + + testing 1 2 3 + pressure difference + + + ingocnito mode activated + some subject + + + + + + /subject + hide + + local + at12 + + + + /data[id2]/events[id3]/data[id4]/items[id5] + show + + + /data[id2]/events[id3]/data[id4]/items[id6] + show + + +
diff --git a/tools/src/test/resources/com/nedap/archie/xml/to_flatten_parent_with_overlay_lifecycle_state_term_code.xml b/tools/src/test/resources/com/nedap/archie/xml/to_flatten_parent_with_overlay_lifecycle_state_term_code.xml new file mode 100644 index 000000000..54845877b --- /dev/null +++ b/tools/src/test/resources/com/nedap/archie/xml/to_flatten_parent_with_overlay_lifecycle_state_term_code.xml @@ -0,0 +1,331 @@ + + + + Pieter Bos + + published + + copyright © 2004 openEHR Foundation <http://www.openEHR.org> +
+ + ISO_639-1 + en + + Test for (de)serialization + ADL + test +
+
+ + ISO_639-1 + en + + + + + false + + + true + + false + false + + 1 + + + + + 1 + + + false + + + true + + false + false + + 3 + 3 + + + + + false + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + + 0.0 + 1000.0 + + + + mmHg + + + + 1 + 1 + + + + + + + + + + false + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + + 0.0 + 1000.0 + + + + mmHg + + + + 1 + 1 + + + + + + + + + + false + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + + 0.0 + 1000.0 + + + + mmHg + + + + 1 + 1 + + + + + + + + + + + + + + + + + id1 + + + The local measurement of arterial blood pressure which is a surrogate for arterial. pressure in the systemic circulation. Most commonly, use of the term 'blood pressure' refers to measurement of brachial artery pressure in the upper arm. + Blood Pressure + + + any event + any event + + + Systolic Pressure + systolic + + + -- diastolic pressure + diastolic pressure + + + testing 1 2 3 + pressure difference + + + ingocnito mode activated + some subject + + + + + + /subject + hide + + local + at12 + + + + /data[id2]/events[id3]/data[id4]/items[id5] + show + + + /data[id2]/events[id3]/data[id4]/items[id6] + show + + +
diff --git a/tools/src/test/resources/com/nedap/archie/xml/to_flatten_parent_with_overlay_newline_lifecycle_state_block.xml b/tools/src/test/resources/com/nedap/archie/xml/to_flatten_parent_with_overlay_newline_lifecycle_state_block.xml new file mode 100644 index 000000000..c1ce5877d --- /dev/null +++ b/tools/src/test/resources/com/nedap/archie/xml/to_flatten_parent_with_overlay_newline_lifecycle_state_block.xml @@ -0,0 +1,331 @@ + + + + Pieter Bos + + + + copyright © 2004 openEHR Foundation <http://www.openEHR.org> +
+ + ISO_639-1 + en + + Test for flattening + ADL + test +
+
+ + ISO_639-1 + en + + + + + false + + + true + + false + false + + 1 + + + + + 1 + + + false + + + true + + false + false + + 3 + 3 + + + + + false + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + + 0.0 + 1000.0 + + + + mmHg + + + + 1 + 1 + + + + + + + + + + false + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + + 0.0 + 1000.0 + + + + mmHg + + + + 1 + 1 + + + + + + + + + + false + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + false + + + 0.0 + 1000.0 + + + + + false + + mmHg + + + + false + + + 1 + 1 + + + + + + + 0.0 + 1000.0 + + + + mmHg + + + + 1 + 1 + + + + + + + + + + + + + + + + + id1 + + + The local measurement of arterial blood pressure which is a surrogate for arterial. pressure in the systemic circulation. Most commonly, use of the term 'blood pressure' refers to measurement of brachial artery pressure in the upper arm. + Blood Pressure + + + any event + any event + + + Systolic Pressure + systolic + + + -- diastolic pressure + diastolic pressure + + + testing 1 2 3 + pressure difference + + + ingocnito mode activated + some subject + + + + + + /subject + hide + + local + at12 + + + + /data[id2]/events[id3]/data[id4]/items[id5] + show + + + /data[id2]/events[id3]/data[id4]/items[id6] + show + + +
diff --git a/utils/build.gradle b/utils/build.gradle index 89a836df2..e2c0cd38d 100644 --- a/utils/build.gradle +++ b/utils/build.gradle @@ -1,5 +1,5 @@ description = "Basic utilities for use in the archie library" dependencies { - api project(':base') -} \ No newline at end of file + api project(':base') +} diff --git a/utils/src/test/java/com/nedap/archie/datetime/DateTimeParserTest.java b/utils/src/test/java/com/nedap/archie/datetime/DateTimeParserTest.java index ae5b55de0..b2ab9e3d0 100644 --- a/utils/src/test/java/com/nedap/archie/datetime/DateTimeParserTest.java +++ b/utils/src/test/java/com/nedap/archie/datetime/DateTimeParserTest.java @@ -82,6 +82,9 @@ public void negativeDurations() { TemporalAmount minusOneYear2Hours = DateTimeParsers.parseDurationValue("-P1YT2H"); assertEquals(PeriodDuration.of(Period.of(-1 ,0, 0), Duration.of(-2, ChronoUnit.HOURS)), minusOneYear2Hours); + + TemporalAmount minusMultiplePeriodDuration = DateTimeParsers.parseDurationValue("-P1Y2M4DT1H35M36S"); + assertEquals(PeriodDuration.of(Period.of(-1,-2,-4), Duration.ofSeconds(-5736)), minusMultiplePeriodDuration); } } diff --git a/utils/src/test/java/com/nedap/archie/datetime/DateTimeSerializerFormattersTest.java b/utils/src/test/java/com/nedap/archie/datetime/DateTimeSerializerFormattersTest.java index 6c7cef698..24b2483d1 100644 --- a/utils/src/test/java/com/nedap/archie/datetime/DateTimeSerializerFormattersTest.java +++ b/utils/src/test/java/com/nedap/archie/datetime/DateTimeSerializerFormattersTest.java @@ -57,6 +57,7 @@ public void serializeNegativeDurations() { TemporalAmount minusOneYearOneHour = PeriodDuration.of(Period.of(-1 ,0, 0), Duration.of(-2, ChronoUnit.HOURS)); TemporalAmount minusTwoHoursPeriodDuration = PeriodDuration.of(Period.ZERO, Duration.of(-2, ChronoUnit.HOURS)); TemporalAmount minusOneYearPeriodDuration = PeriodDuration.of(Period.of(-1 ,0, 0), Duration.ZERO); + TemporalAmount minusMultiplePeriodDuration = PeriodDuration.of(Period.of(-1,-2,-4), Duration.ofSeconds(-5736)); assertEquals("-PT2S", DateTimeSerializerFormatters.serializeDuration(minusTwoSeconds)); assertEquals("-P2Y", DateTimeSerializerFormatters.serializeDuration(minusTwoYears)); @@ -64,6 +65,7 @@ public void serializeNegativeDurations() { assertEquals("-P1YT2H", DateTimeSerializerFormatters.serializeDuration(minusOneYearOneHour)); assertEquals("-PT2H", DateTimeSerializerFormatters.serializeDuration(minusTwoHoursPeriodDuration)); assertEquals("-P1Y", DateTimeSerializerFormatters.serializeDuration(minusOneYearPeriodDuration)); + assertEquals("-P1Y2M4DT1H35M36S", DateTimeSerializerFormatters.serializeDuration(minusMultiplePeriodDuration)); }