diff --git a/.gitignore b/.gitignore new file mode 100755 index 00000000..e1526075 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.idea/ +*.iml +target +dadl-binding/tree_2_slots.dadl +oet-parser/term_map.txt +oet-parser/test_paths.txt +rm-skeleton/hypersensitivity_max.dadl +rm-skeleton/hypersensitivity_min.dadl +build.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 00000000..4349456a --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,39 @@ +image: java:8 + +stages: + - build + - release + - publish + +maven-build-snapshot: + image: gitlab.cambiocds.com:4567/tools/docker-builder + stage: build + script: + - mvn clean package sonar:sonar -P sonar + except: + - /^release-.*$/ + - tags + +maven-build-tag: + image: gitlab.cambiocds.com:4567/tools/docker-builder + stage: build + script: + - mvn clean deploy sonar:sonar -P sonar + only: + - tags + +release: + image: gitlab.cambiocds.com:4567/tools/docker-builder + stage: release + when: manual + script: + - git remote set-url origin $(echo $CI_REPOSITORY_URL | sed -e 's/[^@]\+@\([^\/]\+\)\//git@\1\:/') + - git checkout -b release-$CURRENT_VERSION + - git push -u origin release-$CURRENT_VERSION + - mvn versions:set -DnewVersion=$CURRENT_VERSION + - git commit -a -m "Changing to version "$CURRENT_VERSION + - git tag $CURRENT_VERSION + - git push origin $CURRENT_VERSION --tags + - git push origin --delete release-$CURRENT_VERSION + only: + - master diff --git a/INSTALL.txt b/INSTALL.txt deleted file mode 100755 index a5e4b9be..00000000 --- a/INSTALL.txt +++ /dev/null @@ -1,6 +0,0 @@ - -INSTALATION INSTRUCTIONS: - -INSTALLATION: - -java-libs/mvn clean install \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt old mode 100755 new mode 100644 diff --git a/README.md b/README.md new file mode 100644 index 00000000..98352717 --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# java-libs +Java openEHR Implementation project (ADL 1.4) + +## Getting Started + +### Requirements + +* Java 8 or higher +* Maven 3.0.4 or higher + +### Usage + +The java-libs project is available at [Maven Central](http://search.maven.org/). + +For example, if you need to use the adl-parser, add into your _pom.xml_: + +```xml + + org.openehr.java-libs + adl-parser + 1.0.71 + +``` + +### Installation + +To build the whole project, first clone it, and once inside the project's folder (by default _java-libs_), run: +```bash +mvn clean install +``` +This will create binary files in the _target_ directories of each submodule. + diff --git a/README.txt b/README.txt deleted file mode 100755 index 64f89611..00000000 --- a/README.txt +++ /dev/null @@ -1,5 +0,0 @@ -Java openEHR Implementation project ------------------------------------ - -VERSION - Current version 1.0.5-SNAPSHOT \ No newline at end of file diff --git a/adl-parser/docs/changes.txt b/adl-parser/docs/changes.txt old mode 100755 new mode 100644 diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml old mode 100755 new mode 100644 index ce1d0a96..ebc5b0f7 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -2,9 +2,9 @@ 4.0.0 - openehr - ref_impl_java - 1.0.5-SNAPSHOT + org.openehr.java-libs + java-libs + 0-SNAPSHOT adl-parser jar @@ -48,14 +48,14 @@ - + @@ -91,32 +91,32 @@ - openehr + org.openehr.java-libs openehr-rm-core ${project.version} - openehr + org.openehr.java-libs openehr-rm-domain ${project.version} - openehr + org.openehr.java-libs openehr-aom ${project.version} - openehr + org.openehr.java-libs openehr-ap ${project.version} - openehr + org.openehr.java-libs measure-serv ${project.version} - openehr + org.openehr.java-libs mini-termserv ${project.version} diff --git a/adl-parser/readme.txt b/adl-parser/readme.txt old mode 100755 new mode 100644 diff --git a/adl-parser/src/main/java/se/acode/openehr/parser/ArchetypeValidator.java b/adl-parser/src/main/java/se/acode/openehr/parser/ArchetypeValidator.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/main/java/se/acode/openehr/parser/AttributeValue.java b/adl-parser/src/main/java/se/acode/openehr/parser/AttributeValue.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/main/java/se/acode/openehr/parser/ContentObject.java b/adl-parser/src/main/java/se/acode/openehr/parser/ContentObject.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/main/java/se/acode/openehr/parser/Invariant.java b/adl-parser/src/main/java/se/acode/openehr/parser/Invariant.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/main/java/se/acode/openehr/parser/Parsed.java b/adl-parser/src/main/java/se/acode/openehr/parser/Parsed.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/main/javacc/adl.jj b/adl-parser/src/main/javacc/adl.jj index 9ef1ae04..a10c09af 100755 --- a/adl-parser/src/main/javacc/adl.jj +++ b/adl-parser/src/main/javacc/adl.jj @@ -339,7 +339,6 @@ PARSER_END(ADLParser) | < SYM_START_CBLOCK: "{"> | < SYM_END_CBLOCK: "}"> | < SYM_C_DV_QUANTITY: "c_dv_quantity" >: DOMAIN_TYPE_C_QUANTITY -| < SYM_UNITS: "units">: DOMAIN_TYPE_C_QUANTITY | < SYM_ASSUMED_VALUE: "assumed_value"> } @@ -434,7 +433,7 @@ PARSER_END(ADLParser) | < V_INTEGER: ()+ | (){1,3}(","(){3})+> -| < V_REAL: ()+"./"~[".","0"-"9"] +| < V_REAL: ()+"./"~[".","0"-"9"] | ()+"."()*["e","E"](["+","-"])?()+ | ()*"."()+(["e","E"](["+","-"])?()+)? | (){1,3}("_"(){3})+"./"~[".","0"-"9"] @@ -859,7 +858,7 @@ ResourceDescription arch_description() throws Exception : String value = null; List otherContributors = null; String lifecycleState = null; - List details = new ArrayList(); + Map details = new HashMap(); ResourceDescriptionItem item = null; String resourcePackageURI = null; Map otherDetails = null; @@ -880,7 +879,7 @@ ResourceDescription arch_description() throws Exception : LOOKAHEAD(2) item = arch_description_item() { - details.add(item); + details.put(item.getLanguage().getCodeString(),item); } )+ ">" @@ -1008,7 +1007,6 @@ CComplexObject arch_definition() : ArchetypeOntology arch_ontology() : { String primaryLanguage = null; - List languages = null; List terminologies = null; List termDefinitionsList = new ArrayList(); List constraintDefinitionsList = new ArrayList(); @@ -1024,17 +1022,17 @@ ArchetypeOntology arch_ontology() : { [primaryLanguage = primary_language()] - [languages = languages_available()] + [languages_available()] [ terminologies = terminologies_available() ] termDefinitionsList = term_definitions_list() - + [ constraintDefinitionsList = constraint_definitions_list() ] - - [ termBindingList = term_binding_list() ] - + + [ termBindingList = term_binding_list() ] + [ constraintBindingList = constraint_binding_list() ] - + ( t = { key = t.image; } "<" value = dadl_text() ">" @@ -1045,7 +1043,7 @@ ArchetypeOntology arch_ontology() : )* { - return new ArchetypeOntology(primaryLanguage, languages, terminologies, + return new ArchetypeOntology(primaryLanguage, terminologies, termDefinitionsList, constraintDefinitionsList, termBindingList, constraintBindingList); } @@ -1084,8 +1082,8 @@ List term_definitions_list() : OntologyDefinitions definitions = null; } { - "<" - ( + "<" + ( definitions = definitions_body() { list.add(definitions); } )+ @@ -1095,12 +1093,12 @@ List term_definitions_list() : List constraint_definitions_list() : { - List list = new ArrayList(); + List list = new ArrayList(); OntologyDefinitions definitions = null; } { - "<" - ( + "<" + ( definitions = definitions_body() { list.add(definitions); } )* @@ -1140,14 +1138,14 @@ DefinitionItem definition_item() : } { "[" code = local_code_value() "]" "<" - ( + ( "<" text = string_value() ">" [ ";" ] "<" description = string_value() ">" | "<" description = string_value() ">" [ ";" ] - "<" text = string_value() ">" + "<" text = string_value() ">" ) ">" { return new DefinitionItem(code, text, description); } @@ -1194,13 +1192,13 @@ ArchetypeTerm archetype_term() : List term_binding_list() : { - List list = new ArrayList(); + List list = new ArrayList(); OntologyBinding binding = null; } { "<" - ( - binding = ontology_binding_body() + ( + binding = ontology_binding_body() { list.add(binding); } )* ">" @@ -1209,12 +1207,12 @@ List term_binding_list() : List constraint_binding_list() : { - List list = new ArrayList(); + List list = new ArrayList(); OntologyBinding binding = null; } { "<" - ( + ( binding = ontology_binding_body() { list.add(binding); } )* @@ -1231,7 +1229,7 @@ OntologyBinding ontology_binding_body() : } { "[" terminology = string_value() "]" "<" - + "<" ( @@ -1302,7 +1300,7 @@ String local_code_path_value() : } { t = - { + { String value = t.image; return value.substring(1, value.length() - 1); } @@ -1410,21 +1408,21 @@ Set assertions() : Assertion assertion() : { - String tag = null; + String tag = null; ExpressionItem expression; - String stringExpression = null; - List variables = null; + String stringExpression = null; + List variables = null; } { - [ + [ LOOKAHEAD(2) - tag = any_identifier() ":" - ] - expression = boolean_expression() - + tag = any_identifier() ":" + ] + expression = boolean_expression() + { stringExpression = expression.toString(); - return new Assertion(tag, expression, stringExpression, variables); + return new Assertion(tag, expression, stringExpression, variables); } } @@ -1447,7 +1445,7 @@ Object basic_object_val() : | LOOKAHEAD( term_code() ) value = term_code() - ) + ) { return value; } } @@ -1566,10 +1564,10 @@ String string_value() : { // remove escape, \" -> " value = value.replace("\\\"","\""); - + // remove escape, \\ -> \ value = value.replace("\\\\","\\"); - + return value.substring(1, value.length() - 1); } } @@ -1582,7 +1580,7 @@ List index_string_list() :{ { ( index = string_value() - ( value = string_value()) + ( value = string_value()) { list.add(value); } )* @@ -1655,38 +1653,38 @@ Interval integer_interval_value() : { Interval i = null; int lower = 0; - int upper = 0; + int upper = 0; } { ( - LOOKAHEAD( 3 ) + LOOKAHEAD( 3 ) { boolean lowerInclusive = true; - boolean upperInclusive = true; - boolean upperSpecified = false; + boolean upperInclusive = true; + boolean upperSpecified = false; } [ { lowerInclusive = false; } ] - lower = integer_value() + lower = integer_value() { upper = lower; } - [ - - [ - { upperInclusive = false; } - ] + [ + + [ + { upperInclusive = false; } + ] upper = integer_value() - { upperSpecified =true; } + { upperSpecified =true; } ] { if(!lowerInclusive && !upperSpecified) { // specical case for |>100| i = new Interval(new Integer(lower), null, false, false); } else { - i = new Interval(new Integer(lower), new Integer(upper), lowerInclusive, + i = new Interval(new Integer(lower), new Integer(upper), lowerInclusive, upperInclusive); - } + } } | upper = integer_value() @@ -1721,7 +1719,63 @@ double real_value() : boolean negative = false; } { - [ ( "+" | "-" { negative = true; } ) ] t = + ( + [ ( "+" | "-" { negative = true; } ) ] t = + ) + { + try { + d = Double.parseDouble(t.image); + } catch(NumberFormatException e) { + throw new ParseException("Wrong format of double: " + t.image); + } + if(negative) { + d = -d; + } + return d; + } +} + +String realOrInt_valueAsStr() : +{ + Token t; + double d; + boolean negative = false; +} +{ + ( + LOOKAHEAD( 2 ) + [ ( "+" | "-" { negative = true; } ) ] t = + | + LOOKAHEAD( 2 ) + [ ( "+" | "-" { negative = true; } ) ] t = + ) + { + try { + d = Double.parseDouble(t.image); + } catch(NumberFormatException e) { + throw new ParseException("Wrong format of double: " + t.image); + } + if(negative) { + d = -d; + } + return "" + t.image; //d; + } +} + +double realOrInt_value() : +{ + Token t; + double d; + boolean negative = false; +} +{ + ( + LOOKAHEAD( 2 ) + [ ( "+" | "-" { negative = true; } ) ] t = + | + LOOKAHEAD( 2 ) + [ ( "+" | "-" { negative = true; } ) ] t = + ) { try { d = Double.parseDouble(t.image); @@ -1735,6 +1789,7 @@ double real_value() : } } + List real_list_value() : { List list = new ArrayList(); @@ -1761,31 +1816,31 @@ Interval real_interval_value() : { ( - LOOKAHEAD( 3 ) + LOOKAHEAD( 3 ) { boolean lowerInclusive = true; - boolean upperInclusive = true; - boolean upperSpecified = false; + boolean upperInclusive = true; + boolean upperSpecified = false; } [ { lowerInclusive = false; } ] - lower = real_value() + lower = real_value() { upper = lower; } - [ - - [ - { upperInclusive = false; } + [ + + [ + { upperInclusive = false; } ] - upper = real_value() - { upperSpecified = true; } + upper = real_value() + { upperSpecified = true; } ] { if(!lowerInclusive && !upperSpecified) { // specical case for |>100.0| i = new Interval(new Double(lower), null, false, false); - } else { - i = new Interval(new Double(lower), new Double(upper), lowerInclusive, + } else { + i = new Interval(new Double(lower), new Double(upper), lowerInclusive, upperInclusive); } } @@ -1913,7 +1968,7 @@ Interval date_interval_value() : { ( - lower = date_value() + lower = date_value() { upper = lower; } [ upper = date_value() ] { @@ -2085,7 +2140,7 @@ Interval date_time_interval_value() : { ( - lower = date_time_value() + lower = date_time_value() { upper = lower; } [ upper = date_time_value() ] { @@ -2153,14 +2208,34 @@ Interval duration_interval_value() : { ( - lower = duration_value() + + LOOKAHEAD( 3 ) + { + boolean lowerInclusive = true; + boolean upperInclusive = true; + boolean upperSpecified = false; + } + [ + { lowerInclusive = false; } + ] + lower = duration_value() { upper = lower; } - [ - upper = duration_value() + [ + + [ + { upperInclusive = false; } + ] + upper = duration_value() + { upperSpecified = true; } ] { - i = new Interval(lower, upper, true, true); - } + if(!lowerInclusive && !upperSpecified) { + // specical case for |>100| - important to avoid >100..100 + i = new Interval(lower, null, false, false); + } else { + i = new Interval(lower, upper, lowerInclusive, upperInclusive); + } + } | upper = duration_value() { @@ -2241,10 +2316,10 @@ CComplexObject c_complex_object(String path, CAttribute parent) : path = "/"; } else { path += (nodeID == null ? "" : "[" + nodeID + "]"); - } + } } - attributes = c_complex_object_body(path) + attributes = c_complex_object_body(path) { return new CComplexObject(path, type, occurrences, nodeID, attributes, parent); @@ -2279,7 +2354,7 @@ CObject c_object(String path, CAttribute parent) : } { ( - c = c_dv_quantity(path, parent) + c = c_dv_quantity(path, parent) | c = c_complex_object(path, parent) | @@ -2289,8 +2364,11 @@ CObject c_object(String path, CAttribute parent) : | c = c_code_phrase(path, parent) | + LOOKAHEAD( (integer_value() "|" code_phrase() ",")* real_value() "|" ) + c = c_dv_scale(path, parent) + | LOOKAHEAD( 3 ) - c = c_dv_ordinal(path, parent) + c = c_dv_ordinal(path, parent) | LOOKAHEAD( 3 ) c = c_primitive_object(path, parent) @@ -2307,7 +2385,7 @@ ConstraintRef constraint_ref_obj(String path, CAttribute parent) : String reference; String rmTypeName = "CODE_PHRASE"; Interval occurrences = new Interval(1, 1); - String nodeId = null; + String nodeId = null; } { reference = constraint_ref() @@ -2322,14 +2400,23 @@ ArchetypeInternalRef archetype_internal_ref(String path, CAttribute parent) : String type; Interval occurrences = new Interval(1, 1); String target; + String nodeID = null; } { - type = type_identifier() - [ occurrences = c_occurrences() ] - target = absolute_path() - { - return new ArchetypeInternalRef(path, type, occurrences, null, parent, - target); + type = type_identifier() + [ nodeID = constraint_ref() ] + [ occurrences = c_occurrences() ] + { + if(path == null) { + path = "/"; + } else { + path += (nodeID == null ? "" : "[" + nodeID + "]"); + } + } + target = absolute_path() + { + return new ArchetypeInternalRef(path, type, occurrences, nodeID, parent, + target); } } @@ -2343,11 +2430,11 @@ ArchetypeSlot archetype_slot(String path, CAttribute parent) : } { type = type_identifier() - + [ nodeID = constraint_ref() ] - - [ occurrences = c_occurrences() ] - + + [ occurrences = c_occurrences() ] + [ includes = c_includes() ] [ excludes = c_excludes() ] @@ -2357,8 +2444,8 @@ ArchetypeSlot archetype_slot(String path, CAttribute parent) : path = "/"; } else { path += (nodeID == null ? "" : "[" + nodeID + "]"); - } - return new ArchetypeSlot(path, type, occurrences, nodeID, parent, includes, + } + return new ArchetypeSlot(path, type, occurrences, nodeID, parent, includes, excludes); } } @@ -2417,7 +2504,7 @@ void c_any() : CAttribute c_attribute(String path) : { String name; - CAttribute.Existence existence = CAttribute.Existence.REQUIRED; + CAttribute.Existence existence = CAttribute.Existence.OPTIONAL; // SG 2019 - to enable archei to impose the constraints, and not always forcing 1..1 unless otherwise stated. Cardinality cardinality = null; // default to non-container type List children; CAttribute attribute; @@ -2426,8 +2513,8 @@ CAttribute c_attribute(String path) : { if( ! path.endsWith("/")) { path += "/"; - } - } + } + } name = attribute_identifier() [ existence = c_existence() ] [ cardinality = c_cardinality() ] @@ -2436,20 +2523,22 @@ CAttribute c_attribute(String path) : { path += name; - + if(cardinality == null) { attribute = new CSingleAttribute(path, name, existence, children); } else { attribute = new CMultipleAttribute(path, name, existence, cardinality, children); } - + // Set children parent to the attribute - for(Iterator it = children.iterator(); it.hasNext();) { - CObject co = (CObject) it.next(); - co.setParent(attribute); + if (children!=null){ + for(Iterator it = children.iterator(); it.hasNext();) { + CObject co = (CObject) it.next(); + co.setParent(attribute); + } } - + return attribute; } } @@ -2460,7 +2549,7 @@ List c_attr_values(String path, CAttribute parent) : CObject c = null; } { - ( + ( LOOKAHEAD(2) c_any() | @@ -2486,15 +2575,15 @@ Set c_invariants() : /* ----------------------- expressions ----------------------- */ ExpressionItem boolean_expression() : { - ExpressionItem item = null; + ExpressionItem item = null; } -{ - LOOKAHEAD( 2 ) +{ + LOOKAHEAD( 2 ) item = boolean_leaf() | LOOKAHEAD( 2 ) item = boolean_node() - + { return item; } } @@ -2502,18 +2591,18 @@ ExpressionItem boolean_node() : { ExpressionItem ret = null; ExpressionItem item = null; - ExpressionItem item2 = null; + ExpressionItem item2 = null; OperatorKind op = null; String path = null; boolean precedenceOverridden = false; // TODO - Token t = null; + Token t = null; String attrId = null; CPrimitive cp = null; } { ( path = absolute_path() - { + { item = ExpressionLeaf.pathConstant(path); ret = new ExpressionUnaryOperator(ExpressionItem.BOOLEAN, OperatorKind.OP_EXISTS, precedenceOverridden, item); @@ -2523,76 +2612,76 @@ ExpressionItem boolean_node() : attrId = relative_path() ( cp = c_primitive() - { item2 = new ExpressionLeaf("C_"+cp.getType().toUpperCase(), cp, //SG 2013-01-31: Need to add "C_" because it is a C_* constraint pattern here, with the type usually being displayed in upper case + { item2 = new ExpressionLeaf("C_"+cp.getType().toUpperCase(), cp, //SG 2013-01-31: Need to add "C_" because it is a C_* constraint pattern here, with the type usually being displayed in upper case ExpressionLeaf.ReferenceType.CONSTRAINT); } //SG 2013-01-31: instead of CONSTANT, which is not correct, at least not for archetype slots according to spec. | t = { item2 = ExpressionLeaf.stringConstant(t.image); } ) - { + { item = new ExpressionLeaf(ExpressionItem.STRING, attrId, ExpressionLeaf.ReferenceType.ATTRIBUTE); //SG 2013-01-31, needs to be attribute according to spec (not constant), relevant for archetype slots //item = ExpressionLeaf.stringConstant(attrId); - ret = new ExpressionBinaryOperator(ExpressionItem.BOOLEAN, + ret = new ExpressionBinaryOperator(ExpressionItem.BOOLEAN, OperatorKind.OP_MATCHES, false, item, item2); - } + } | item = boolean_expression() { ret = new ExpressionUnaryOperator(ExpressionItem.BOOLEAN, - OperatorKind.OP_NOT, precedenceOverridden, item); + OperatorKind.OP_NOT, precedenceOverridden, item); } | LOOKAHEAD( 3 ) item = arithmetic_expression() ( - "=" + "=" { op = OperatorKind.OP_EQ; } - | - + | + { op = OperatorKind.OP_NE; } - | - + | + { op = OperatorKind.OP_LT; } - | - + | + { op = OperatorKind.OP_GT; } - | - + | + { op = OperatorKind.OP_LE; } - | + | { op = OperatorKind.OP_GE; } ) - item2 = arithmetic_expression() - { + item2 = arithmetic_expression() + { ret = new ExpressionBinaryOperator(item.getType(), op, false, item, item2); } | - LOOKAHEAD( 3 ) - item = boolean_leaf() + LOOKAHEAD( 3 ) + item = boolean_leaf() ( ( - + { op = OperatorKind.OP_AND; } - | - + | + { op = OperatorKind.OP_OR; } | - + { op = OperatorKind.OP_XOR; } - | - + | + { op = OperatorKind.OP_IMPLIES; } ) item2 = boolean_expression() ) - { + { if(item2 == null) { ret = item; } else { - ret = new ExpressionBinaryOperator(ExpressionItem.BOOLEAN, op, false, + ret = new ExpressionBinaryOperator(ExpressionItem.BOOLEAN, op, false, item, item2); } } @@ -2605,22 +2694,22 @@ ExpressionItem boolean_leaf() : ExpressionItem item = null; } { - + LOOKAHEAD( 3 ) "(" item = boolean_expression() ")" | { item = ExpressionLeaf.booleanConstant(true); } -| +| { item = ExpressionLeaf.booleanConstant(false); } - - { return item; } + + { return item; } } ExpressionItem arithmetic_expression() : { - ExpressionItem item = null; + ExpressionItem item = null; } { LOOKAHEAD( 3 ) @@ -2639,63 +2728,63 @@ ExpressionItem arithmetic_node() : OperatorKind op = null; } { - left = arithmetic_leaf() + left = arithmetic_leaf() ( ( - "+" + "+" { op = OperatorKind.OP_PLUS; } - | - "-" + | + "-" { op = OperatorKind.OP_MINUS; } - | - "*" + | + "*" { op = OperatorKind.OP_MULTIPLY; } - | - "/" + | + "/" { op = OperatorKind.OP_DIVIDE; } - | - "^" - { op = OperatorKind.OP_EXP; } - ) - - right = arithmetic_expression() - ) - { + | + "^" + { op = OperatorKind.OP_EXP; } + ) + + right = arithmetic_expression() + ) + { if(right == null) { item = left; - } else { - item = new ExpressionBinaryOperator(right.getType(), op, false, left, - right); + } else { + item = new ExpressionBinaryOperator(right.getType(), op, false, left, + right); } - return item; + return item; } } ExpressionItem arithmetic_leaf() : -{ +{ ExpressionItem item = null; Token t = null; String str = null; } { "(" item = arithmetic_expression() ")" -| +| t = { int i = Integer.parseInt(t.image); item = ExpressionLeaf.intConstant(i); } -| +| t = { double d = Double.parseDouble(t.image); item = ExpressionLeaf.realConstant(d); } | - str = absolute_path() + str = absolute_path() { item = ExpressionLeaf.stringConstant(str); - } + } { return item; } } @@ -2805,7 +2894,7 @@ Interval occurrence_spec() : CDvOrdinal c_dv_ordinal(String path, CAttribute parent) : { - Set list = new LinkedHashSet(); + List list = new ArrayList(); org.openehr.am.openehrprofile.datatypes.quantity.Ordinal o; Ordinal defaultValue = null; int assumed = -1; @@ -2813,7 +2902,6 @@ CDvOrdinal c_dv_ordinal(String path, CAttribute parent) : Interval occurrences = new Interval(1, 1); } { - o = ordinal() { list.add(o); } ( "," o = ordinal() @@ -2828,15 +2916,15 @@ CDvOrdinal c_dv_ordinal(String path, CAttribute parent) : assumedValue = ord; break; } - } - } + } + } ] - { + { return new CDvOrdinal(path, occurrences, null, parent, list, defaultValue, - assumedValue); + assumedValue); } | - + { // any allowed return new CDvOrdinal(path, occurrences, null, parent, null, null, null); @@ -2851,12 +2939,60 @@ org.openehr.am.openehrprofile.datatypes.quantity.Ordinal ordinal() : } { value = integer_value() "|" code = code_phrase() - { + { return new org.openehr.am.openehrprofile.datatypes.quantity.Ordinal( - value, code); + value, code); + } +} + +CDvScale c_dv_scale(String path, CAttribute parent) : +{ + List list = new ArrayList(); + org.openehr.am.openehrprofile.datatypes.quantity.Scale o; + Scale defaultValue = null; + double assumed = -1.0; + Scale assumedValue = null; + Interval occurrences = new Interval(1, 1); +} +{ + o = scale() { list.add(o); } + ( + "," o = scale() + { list.add(o); } + )* + [ + ";" assumed = realOrInt_value() + { + for(Iterator it = list.iterator(); it.hasNext();) { + Scale scale = (Scale) it.next(); + if(scale.getValue() == assumed) { + assumedValue = scale; + break; + } + } + } + ] + { + return new CDvScale(path, occurrences, null, parent, list, defaultValue, assumedValue); + } +} + +org.openehr.am.openehrprofile.datatypes.quantity.Scale scale() : +{ + Token t; + String display; // We must maintain the way it is specified (2 vs 2.0 makes a difference to end users) + //double value; + CodePhrase code; +} +{ + display = realOrInt_valueAsStr() "|" code = code_phrase() + { + return new org.openehr.am.openehrprofile.datatypes.quantity.Scale(display, code); } } + + CCodePhrase c_code_phrase(String path, CAttribute parent) : { Token t; @@ -2865,55 +3001,55 @@ CCodePhrase c_code_phrase(String path, CAttribute parent) : List codeList = null; String assumed = null; CodePhrase assumedValue = null; - CodePhrase defaultValue = null; // not used + CodePhrase defaultValue = null; // not used CodePhrase singleValue = null; Interval occurrences = new Interval(1, 1); } { - ( - t = - { + ( + t = + { // remove leading "[" and trailing "::" - terminology = t.image; + terminology = t.image; terminology = terminology.substring(1, terminology.length() - 2); terminologyId = new TerminologyID(terminology); } [ - t = - { + t = + { codeList = new ArrayList(); - codeList.add(t.image); + codeList.add(t.image); } ( [","] t = { codeList.add(t.image); } )* - [ - ";" t = - { - assumed = t.image; + [ + ";" t = + { + assumed = t.image; assumedValue = new CodePhrase(terminologyId, assumed); - } - ] + } + ] ] "]" - { + { // leave lexical state "TERM_CODE" - token_source.SwitchTo(CADL); + token_source.SwitchTo(CADL); } - | + | singleValue = code_phrase() - { + { codeList = new ArrayList(); codeList.add(singleValue.getCodeString()); terminologyId = singleValue.getTerminologyId(); } ) - { - return new CCodePhrase(path, occurrences, null, parent, terminologyId, - codeList, defaultValue, assumedValue); + { + return new CCodePhrase(path, occurrences, null, parent, terminologyId, + codeList, defaultValue, assumedValue); } - - + + } CDvQuantity c_dv_quantity(String path, CAttribute parent) : @@ -2922,7 +3058,7 @@ CDvQuantity c_dv_quantity(String path, CAttribute parent) : String terminology = null; String code = null; List list = null; - CDvQuantityItem item = null; + CDvQuantityItem item = null; Token t = null; DvQuantity defaultValue = null; DvQuantity assumedValue = null; @@ -2931,33 +3067,33 @@ CDvQuantity c_dv_quantity(String path, CAttribute parent) : { "<" ( - - "<" property = code_phrase() ">" - - | - + + "<" property = code_phrase() ">" + + | + { list = new ArrayList(); } - "<" - ( - item = c_dv_quantity_item() + "<" + ( + item = c_dv_quantity_item() { list.add(item); } - )+ + )+ ">" - - | - + + | + "<" - assumedValue = dv_quantity() + assumedValue = dv_quantity() ">" - + )* - ">" - { + ">" + { { token_source.SwitchTo(CADL); } - - return new CDvQuantity(path, occurrences, null, parent, list, property, - defaultValue, assumedValue); - } + + return new CDvQuantity(path, occurrences, null, parent, list, property, + defaultValue, assumedValue); + } } DvQuantity dv_quantity() : @@ -2967,46 +3103,46 @@ DvQuantity dv_quantity() : int precision = 0; } { - ( + ( "<" units = string_value() ">" - | - "<" magnitude = real_value() ">" - | - "<" precision = integer_value() ">" - )* - { - return new DvQuantity(units, magnitude, precision, measureServ); - } + | + "<" magnitude = real_value() ">" + | + "<" precision = integer_value() ">" + )* + { + return new DvQuantity(units, magnitude, precision, measureServ); + } } CDvQuantityItem c_dv_quantity_item() : { Interval value = null; Interval precision = null; - String units; + String units; } { "[" string_value() "]" "<" - - (|) "<" - units = string_value() + + () "<" + units = string_value() ">" - + [ - "<" - value = real_interval_value() + "<" + value = real_interval_value() ">" ] - + [ - "<" + "<" precision = integer_interval_value() ">" ] ">" - { - return new CDvQuantityItem(value, precision, units); - } + { + return new CDvQuantityItem(value, precision, units); + } } List string_list() : @@ -3016,14 +3152,14 @@ List string_list() : } { ( - string_value() + string_value() value = string_value() - - { list.add(value); } - )* - - { return list; } -} + + { list.add(value); } + )* + + { return list; } +} CInteger c_integer() : { @@ -3046,8 +3182,8 @@ CInteger c_integer() : LOOKAHEAD( occurrence_spec()) interval = occurrence_spec() ) - [ ";" assumed = integer_value() - { assumedValue = new Integer(assumed); } + [ ";" assumed = integer_value() + { assumedValue = new Integer(assumed); } ] { if(interval != null) { @@ -3081,7 +3217,7 @@ CReal c_real() : LOOKAHEAD( real_value() ) d = real_value() ) - [ + [ ";" assumed = real_value() { assumedValue = new Double(assumed); } ] @@ -3116,7 +3252,7 @@ CDate c_date() : | interval = date_interval_value() ) - [ + [ ";" assumed = date_value() ] { @@ -3146,7 +3282,7 @@ CTime c_time() : | interval = time_interval_value() ) - [ + [ ";" assumed = time_value() ] { @@ -3176,7 +3312,7 @@ CDateTime c_date_time() : | interval = date_time_interval_value() ) - [ + [ ";" assumed = date_time_value() ] { @@ -3198,17 +3334,17 @@ CDuration c_duration() : } { ( - pattern = duration_pattern() + pattern = duration_pattern() [ "/" interval = duration_interval_value() - ] + ] | interval = duration_interval_value() | - value = duration_value() + value = duration_value() ) - - [ + + [ ";" assumed = duration_value() ] { @@ -3217,9 +3353,11 @@ CDuration c_duration() : } String duration_pattern() : -{ Token t = null; +{ + Token t = null; } -{ t = +{ + t = { return t.image; } } @@ -3264,7 +3402,7 @@ CBoolean c_boolean() : { boolean trueAllowed = false; boolean falseAllowed = false; - boolean assumed = false; + boolean assumed = false; boolean hasAssumed = false; } { @@ -3274,9 +3412,9 @@ CBoolean c_boolean() : | { falseAllowed = true; } [ "," { trueAllowed = true; } ] ) - [ - ";" - ( {assumed = true; } | {assumed = false;} ) + [ + ";" + ( {assumed = true; } | {assumed = false;} ) { hasAssumed = true; } ] { @@ -3315,10 +3453,10 @@ String type_identifier() : String type; } { - t = + t = { type = t.image; } - [ - "<" t = ">" + [ + "<" t = ">" { type += "<" + t.image + ">"; } ] { return type; } @@ -3335,8 +3473,8 @@ String attribute_identifier() : String absolute_path() : -{ - String path; +{ + String path; StringBuffer buf; Token t; } @@ -3346,57 +3484,57 @@ String absolute_path() : } String relative_path() : -{ +{ StringBuffer buf; - String path; + String path; Token t; } { - ( - t = - | - t = + ( + t = + | + t = ) { return t.image; } } String path_segment() : -{ - Token t; +{ + Token t; StringBuffer buf = new StringBuffer(); } { t = - { buf.append(t.image); } + { buf.append(t.image); } [ LOOKAHEAD(2) t = { buf.append(t.image); } - ] - { return buf.toString(); } + ] + { return buf.toString(); } } /* * ***** BEGIN LICENSE BLOCK ***** Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * + * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the 'License'); you may not use this file except in compliance with the * License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * + * * Software distributed under the License is distributed on an 'AS IS' basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. - * + * * The Original Code is ADLParser.java - * + * * The Initial Developer of the Original Code is Rong Chen. Portions created by * the Initial Developer are Copyright (C) 2003-2009 the Initial Developer. All * Rights Reserved. - * + * * Contributor(s): Sebastian Garde - * + * * Software distributed under the License is distributed on an 'AS IS' basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. - * + * * ***** END LICENSE BLOCK ***** - */ \ No newline at end of file + */ diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeDescriptionTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeDescriptionTest.java old mode 100755 new mode 100644 index f3bff7ca..80db7576 --- a/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeDescriptionTest.java +++ b/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeDescriptionTest.java @@ -56,11 +56,11 @@ public void testParseFullArchetypeDescription() throws Exception { // TODO: parent_resource - List details = description.getDetails(); + Map details = description.getDetails(); assertNotNull("details null", details); assertEquals("details size wrong", 1, details.size()); - ResourceDescriptionItem item = details.get(0); + ResourceDescriptionItem item = details.get("en"); assertNotNull("descriptionItem null", item); CodePhrase language = new CodePhrase("ISO_639-1", "en"); assertEquals("language wrong", language, item.getLanguage()); @@ -90,12 +90,12 @@ public void testParseFullArchetypeDescription() throws Exception { keywords.add("condition"); assertEquals("keywords wrong", keywords, item.getKeywords()); - map = details.get(0).getOriginalResourceUri(); + map = details.get("en").getOriginalResourceUri(); assertEquals("http://guidelines.are.us/wherever/fr", map.get("ligne guide")); assertEquals("http://some%20medline%20ref", map.get("medline")); - map = details.get(0).getOtherDetails(); + map = details.get("en").getOtherDetails(); assertEquals("item details 1", map.get("item other 1")); assertEquals("item details 2", map.get("item other 2")); } diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeIdentificationTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeIdentificationTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeInternalRefTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeInternalRefTest.java index 614c384e..735fa0cd 100755 --- a/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeInternalRefTest.java +++ b/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeInternalRefTest.java @@ -6,7 +6,19 @@ import org.openehr.rm.support.basic.Interval; public class ArchetypeInternalRefTest extends ParserTestBase { - public void testParseInternalRefWithOverwrittingOccurrences() + public void testParseCheckIfNodeIsIsTakenIntoAccount() throws Exception{ + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.archetype_internal_ref.test.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + + assertNotNull(archetype.node("/attribute3")); + assertNotNull(archetype.node("/attribute4[at0005]")); + assertNotNull(archetype.node("/attribute4[at0006]")); + } + + + public void testParseInternalRefWithOverwrittingOccurrences() throws Exception { ADLParser parser = new ADLParser(loadFromClasspath( "adl-test-entry.archetype_internal_ref.test.adl")); diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeLanguageTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeLanguageTest.java old mode 100755 new mode 100644 index 34b7c2ed..d0833ead --- a/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeLanguageTest.java +++ b/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeLanguageTest.java @@ -131,4 +131,13 @@ public void testParseTranslationsAuthorLanguage() throws Exception { Map map = td.getAuthor(); assertNotNull("author null", map); } + + public void testParseMultipleLanguageTerms() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.archetype_language.test2.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + + assertEquals(2, archetype.getOntology().getLanguages().size()); + } } diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeOntologyTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeOntologyTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeSlotTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeSlotTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeUncommonTermKeysTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeUncommonTermKeysTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeValidatorTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeValidatorTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/BasicGenericTypeTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/BasicGenericTypeTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/BasicTypesTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/BasicTypesTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/CCodePhraseTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/CCodePhraseTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/CDurationTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/CDurationTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/CDvOrdinalTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/CDvOrdinalTest.java index 3da83dbd..78d0efe3 100755 --- a/adl-parser/src/test/java/se/acode/openehr/parser/CDvOrdinalTest.java +++ b/adl-parser/src/test/java/se/acode/openehr/parser/CDvOrdinalTest.java @@ -43,12 +43,27 @@ public void testCDvOrdinalWithoutAssumedValue() throws Exception { String[] codes = { "at0003.0", "at0003.1", "at0003.2", "at0003.3", "at0003.4" }; + int[] values = { 0, 1, 2, 3, 4 }; String terminology = "local"; assertFalse("unexpected assumed value", ((CDvOrdinal) node).hasAssumedValue()); - assertCDvOrdinal(node, terminology, codes, null); + assertCDvOrdinal(node, terminology, codes, values, null); + } + + public void testCDvOrdinalWithDuplicatedValues() throws Exception { + node = archetype.node("/types[at0001]/items[at10004]/value"); + String[] codes = { + "at0003.0", "at0003.1", "at0003.2", "at0003.3", "at0003.4" + }; + int[] values = { 0, 1, 1, 3, 4 }; + String terminology = "local"; + + assertFalse("unexpected assumed value", + ((CDvOrdinal) node).hasAssumedValue()); + + assertCDvOrdinal(node, terminology, codes, values, null); } public void testCDvOrdinalWithAssumedValue() throws Exception { @@ -56,13 +71,14 @@ public void testCDvOrdinalWithAssumedValue() throws Exception { String[] codes = { "at0003.0", "at0003.1", "at0003.2", "at0003.3", "at0003.4" }; + int[] values = { 0, 1, 2, 3, 4 }; String terminology = "local"; Ordinal assumed = new Ordinal(0, new CodePhrase(terminology, codes[0])); assertTrue("expected to have assumed value", ((CDvOrdinal) node).hasAssumedValue()); - assertCDvOrdinal(node, terminology, codes, assumed); + assertCDvOrdinal(node, terminology, codes, values, assumed); } public void testEmptyCDvOrdinal() throws Exception { @@ -73,22 +89,21 @@ public void testEmptyCDvOrdinal() throws Exception { } private void assertCDvOrdinal(ArchetypeConstraint node, String terminoloy, - String[] codes, Ordinal assumedValue) { - - assertTrue("CDvOrdinal expected", node instanceof CDvOrdinal); + String[] codes, int[] values, Ordinal assumedValue) { + + assertTrue("CDvOrdinal expected", node instanceof CDvOrdinal); CDvOrdinal cordinal = (CDvOrdinal) node; - - List codeList = Arrays.asList(codes); - Set list = cordinal.getList(); + + List list = cordinal.getList(); assertEquals("codes.size", codes.length, list.size()); - for(Ordinal ordinal : list) { - assertEquals("terminology", "local", - ordinal.getSymbol().getTerminologyId().getValue()); - assertTrue("code missing", - codeList.contains(ordinal.getSymbol().getCodeString())); + for(int i = 0; i < codes.length; i++) { + assertEquals("terminology", terminoloy, + list.get(i).getSymbol().getTerminologyId().getValue()); + assertEquals("code missing", codes[i], list.get(i).getSymbol().getCodeString()); + assertEquals("value wrong", values[i], list.get(i).getValue()); } - assertEquals("assumedValue wrong", assumedValue, - cordinal.getAssumedValue()); + assertEquals("assumedValue wrong", assumedValue, + cordinal.getAssumedValue()); } private Archetype archetype; diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/CDvQuantityTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/CDvQuantityTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/CDvScaleTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/CDvScaleTest.java new file mode 100644 index 00000000..c908daf7 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/CDvScaleTest.java @@ -0,0 +1,131 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; +import org.openehr.am.archetype.constraintmodel.CComplexObject; +import org.openehr.am.archetype.Archetype; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvScale; +import org.openehr.am.openehrprofile.datatypes.quantity.Scale; +import org.openehr.rm.datatypes.text.CodePhrase; + +import java.util.*; + +/** + * Test case tests parsing of domain type constraints extension. + * + * @author Sebastian Garde + * @version 1.0 + */ + +public class CDvScaleTest extends ParserTestBase { + + public CDvScaleTest(String test) throws Exception { + super(test); + } + + /** + * The fixture set up called before every test method. + */ + protected void setUp() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-ENTRY.c_dv_scale.test.adl")); + archetype = parser.parse(); + } + + /** + * The fixture clean up called after every test method. + */ + protected void tearDown() throws Exception { + archetype = null; + node = null; + } + + public void testCDvScaleWithoutAssumedValue() throws Exception { + node = archetype.node("/types[at0001]/items[at10001]/value"); + String[] codes = { + "at0003.0", "at0003.1", "at0003.2", "at0003.3", "at0003.4" + }; + + double[] values = { 0.0, 1.0, 2.5, 3.8, 4.4 }; + String terminology = "local"; + + assertFalse("unexpected assumed value", + ((CDvScale) node).hasAssumedValue()); + + assertCDvScale(node, terminology, codes, values, null); + } + + public void testCDvScaleWithAssumedValueAndIntegers() throws Exception { + node = archetype.node("/types[at0001]/items[at10002]/value"); + String[] codes = { + "at0003.0", "at0003.1", "at0003.2", "at0003.3", "at0003.4" + }; + double[] values = { 0, 1, 2, 3, 4.1 }; + String terminology = "local"; + Scale assumed = new Scale(2, new CodePhrase(terminology, codes[2])); + + assertTrue("expected to have assumed value", + ((CDvScale) node).hasAssumedValue()); + + assertCDvScale(node, terminology, codes, values, assumed); + } + + public void testEmptyDvScale() throws Exception { + node = archetype.node("/types[at0001]/items[at10003]/value"); + + assertTrue("CComplexObject expected", node instanceof CComplexObject ); + assertTrue("DV_SCALE RM Type expected", ((CComplexObject) node).getRmTypeName().equals("DV_SCALE")); + + assertTrue("any allowed expected", node.isAnyAllowed()); + } + + public void testCDvScaleWithDuplicatedValues() throws Exception { + node = archetype.node("/types[at0001]/items[at10004]/value"); + String[] codes = { + "at0003.0", "at0003.1", "at0003.2", "at0003.3", "at0003.4" + }; + double[] values = { 0, 1.5, 1.5, 3.5, 4 }; + String terminology = "local"; + + assertFalse("unexpected assumed value", + ((CDvScale) node).hasAssumedValue()); + + assertCDvScale(node, terminology, codes, values, null); + } + + public void testDvScaleNormal() throws Exception { + node = archetype.node("/types[at0001]/items[at10005]/value"); + String[] codes = { + "at0003.0", "at0003.2" + }; + double[] values = { 0, 1.5 }; + String terminology = "local"; + + // DV_SCALE tests + //assertFalse("unexpected assumed value", + // ((DvScale) node).hasAssumedValue()); + + //assertCDvScale(node, terminology, codes, values, null); + } + + private void assertCDvScale(ArchetypeConstraint node, String terminoloy, + String[] codes, double[] values, Scale assumedValue) { + + assertTrue("CDvScale expected", node instanceof CDvScale); + CDvScale cordinal = (CDvScale) node; + + List list = cordinal.getList(); + assertEquals("codes.size", codes.length, list.size()); + for(int i = 0; i < codes.length; i++) { + assertEquals("terminology", terminoloy, + list.get(i).getSymbol().getTerminologyId().getValue()); + assertEquals("code missing", codes[i], list.get(i).getSymbol().getCodeString()); + assertEquals("value wrong", values[i], list.get(i).getValue()); + // could also add a test about the exact display here + } + assertEquals("assumedValue wrong", assumedValue, + cordinal.getAssumedValue()); + } + + private Archetype archetype; + private ArchetypeConstraint node; +} diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/ConstraintBindingTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/ConstraintBindingTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/ConstraintRefTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/ConstraintRefTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/DateTimeTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/DateTimeTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/DvCodedTextTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/DvCodedTextTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/DvDurationIntervalTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/DvDurationIntervalTest.java new file mode 100644 index 00000000..47f8a4d7 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/DvDurationIntervalTest.java @@ -0,0 +1,32 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.Archetype; +import org.openehr.rm.datatypes.quantity.datetime.DvDuration; +import org.openehr.rm.support.basic.Interval; + +public class DvDurationIntervalTest extends ParserTestBase { + + /** + * Create new test case + * + * @param test + * @throws Exception + */ + public DvDurationIntervalTest() throws Exception { + ADLParser parser = new ADLParser( + loadFromClasspath("openEHR-EHR-CLUSTER.duration_interval_test.v0.adl")); + archetype = parser.parse(); + } + + public void testParse() throws Exception { + // This test is mainly to ensure all examples parse ok. + // In addition, this is one test to ensure the special case of >X is working in the constraint. (No incorrect upper limit is imposed) + Interval interval = new Interval( + DvDuration.getInstance("PT0M"), null, false, true); + + assertCDuration(archetype.node("/items[at0003]/value/value"), null, interval); + + } + + private Archetype archetype; +} diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/EmptyOtherContributorsTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/EmptyOtherContributorsTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/MissingLanguageTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/MissingLanguageTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/MissingPurposeTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/MissingPurposeTest.java old mode 100755 new mode 100644 index 0c1b6ca0..114ac38b --- a/adl-parser/src/test/java/se/acode/openehr/parser/MissingPurposeTest.java +++ b/adl-parser/src/test/java/se/acode/openehr/parser/MissingPurposeTest.java @@ -13,6 +13,6 @@ public void testMissingLanguageCompatibility() throws Exception { assertNotNull(archetype); assertNotNull("purpose null", - archetype.getDescription().getDetails().get(0).getPurpose()); + archetype.getDescription().getDetails().get("en").getPurpose()); } } diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/MixedNodeTypesTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/MixedNodeTypesTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/MostMinimalADLTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/MostMinimalADLTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/MultiLanguageTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/MultiLanguageTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/ParserTestBase.java b/adl-parser/src/test/java/se/acode/openehr/parser/ParserTestBase.java old mode 100755 new mode 100644 index 30d891c7..0f29f45d --- a/adl-parser/src/test/java/se/acode/openehr/parser/ParserTestBase.java +++ b/adl-parser/src/test/java/se/acode/openehr/parser/ParserTestBase.java @@ -1,283 +1,283 @@ -package se.acode.openehr.parser; - -import junit.framework.TestCase; - -import java.io.File; -import java.io.InputStream; -import java.util.*; -import java.text.SimpleDateFormat; - -import org.openehr.am.archetype.constraintmodel.*; -import org.openehr.am.archetype.constraintmodel.primitive.*; -import org.openehr.rm.support.basic.Interval; -import org.openehr.rm.datatypes.quantity.datetime.*; - -/** - * ADLParser testing config and common logic - * - * @author Rong Chen - * @version 1.0 - */ -public class ParserTestBase extends TestCase { - - public ParserTestBase(String test) { - super(test); - } - - public ParserTestBase(){ - } - - protected InputStream loadFromClasspath(String adl) throws Exception { - return this.getClass().getClassLoader().getResourceAsStream(adl); - } - - // assert CComplexObject object has expected values - void assertCComplexObject(CComplexObject obj, String rmTypeName, - String nodeID, Interval occurrences, - int attributes) throws Exception { - assertCObject(obj, rmTypeName, nodeID, occurrences); - assertEquals("attributes.size", attributes, obj.getAttributes().size()); - } - - // assert CObject has expected valuess - void assertCObject(CObject obj, String rmTypeName, String nodeID, - Interval occurrences) throws Exception { - assertEquals("rmTypeName", rmTypeName, obj.getRmTypeName()); - assertEquals("nodeID", nodeID, obj.getNodeId()); - assertEquals("occurrences", occurrences, obj.getOccurrences()); - } - - // assert CAttribute has expected values - void assertCAttribute(CAttribute attr, String rmAttributeName, - CAttribute.Existence existence, - Cardinality cardinality, int children) - throws Exception { - assertEquals("rmAttributeName", rmAttributeName, - attr.getRmAttributeName()); - assertEquals("existence", existence, attr.getExistence()); - if(attr instanceof CMultipleAttribute) { - CMultipleAttribute mattr = (CMultipleAttribute) attr; - assertEquals("cardinality", cardinality, mattr.getCardinality()); - } - assertEquals("children.size", children, attr.getChildren().size()); - } - - // assert CAttribute has expected values - void assertCAttribute(CAttribute attr, String rmAttributeName, - int children) throws Exception { - assertCAttribute(attr, rmAttributeName, CAttribute.Existence.REQUIRED, - null, children); - } - - // assertion on primitive types - void assertCBoolean(Object obj, boolean trueValid, boolean falseValid, - boolean assumed, boolean hasAssumed) - throws Exception { - CBoolean b = (CBoolean) fetchFirst(obj); - assertEquals("trueValid", trueValid, b.isTrueValid()); - assertEquals("falseValid", falseValid, b.isFalseValid()); - assertEquals("assumed value", assumed, b.assumedValue().booleanValue()); - assertEquals("has assumed value", hasAssumed, b.hasAssumedValue()); - } - - void assertCInteger(Object obj, Interval interval, int[] values, - Integer assumed) throws Exception { - CInteger c = (CInteger) fetchFirst(obj); - assertEquals("interval", interval, c.getInterval()); - assertEquals("list", intSet(values), c.getList()); - assertEquals("unexpected assumed value", assumed, c.assumedValue()); - } - - void assertCReal(Object obj, Interval interval, double[] values, - Double assumed) throws Exception { - CReal c = (CReal) fetchFirst(obj); - assertEquals("interval", interval, c.getInterval()); - assertEquals("list", doubleSet(values), c.getList()); - assertEquals("unexpected assumed value", assumed, c.assumedValue()); - } - - void assertCDate(Object obj, String pattern, Interval interval, - String[] values, String assumed) - throws Exception { - CDate c = (CDate) fetchFirst(obj); - assertEquals("pattern", pattern, c.getPattern()); - assertEquals("interval", interval, c.getInterval()); - assertEquals("list", dateSet(values), c.getList()); - assertEquals("assumed value", - assumed == null? null :new DvDate(assumed), c.assumedValue()); - } - - void assertCDateTime(Object obj, String pattern, Interval interval, - String[] values, String assumed) - throws Exception { - CDateTime c = (CDateTime) fetchFirst(obj); - assertEquals("pattern", pattern, c.getPattern()); - assertEquals("interval", interval, c.getInterval()); - assertEquals("list", dateTimeSet(values), c.getList()); - assertEquals("assumed value", - assumed == null? null :new DvDateTime(assumed), c.assumedValue()); - } - - // without assumed value - void assertCDateTime(Object obj, String pattern, Interval interval, - String[] values) throws Exception { - assertCDateTime(obj, pattern, interval, values, null); - } - - - void assertCTime(Object obj, String pattern, Interval interval, - String[] values, String assumed) - throws Exception { - CTime c = (CTime) fetchFirst(obj); - assertEquals("pattern", pattern, c.getPattern()); - assertEquals("interval", interval, c.getInterval()); - assertEquals("list", timeSet(values), c.getList()); - assertEquals("assumed value", - assumed == null? null :new DvTime(assumed), c.assumedValue()); - } - - // without assumed value - void assertCTime(Object obj, String pattern, Interval interval, - String[] values) throws Exception { - assertCTime(obj, pattern, interval, values, null); - } - - // full assertion with CDuration - void assertCDuration(Object obj, String value, Interval interval, - String assumed, String pattern) throws Exception { - CDuration c = (CDuration) ((CPrimitiveObject) obj).getItem(); - assertEquals("list", value == null ? null : DvDuration.getInstance(value), - c.getValue()); - assertEquals("interval", interval, c.getInterval()); - assertEquals("assumed value", - assumed == null? null - : DvDuration.getInstance(assumed), c.assumedValue()); - assertEquals("pattern wrong", pattern, c.getPattern()); - } - - // without pattern - void assertCDuration(Object obj, String value, Interval interval, - String assumed) throws Exception { - assertCDuration(obj, value, interval, assumed, null); - } - - // without assumed value, pattern - void assertCDuration(Object obj, String value, Interval interval) - throws Exception { - assertCDuration(obj, value, interval, null); - } - - // fetch the first CPrimitive from the CAttribute - CPrimitive fetchFirst(Object obj) { - return ( (CPrimitiveObject) ( (CAttribute) obj ).getChildren() - .get(0) ).getItem(); - } - - void assertCString(Object obj, String pattern, String[] values, - String assumedValue) { - CString c = (CString) ( (CPrimitiveObject) ( (CAttribute) obj ).getChildren() - .get(0) ).getItem(); - if (pattern == null) { - assertTrue("pattern null", c.getPattern() == null); - } else { - assertEquals("pattern", pattern, c.getPattern()); - } - assertEquals("list", values == null - ? null : Arrays.asList(values), c.getList()); - assertEquals("unexpected CString assumed value", assumedValue, - c.assumedValue()); - } - - void assertDateEquals(List set, String[] dates, String pattern) - throws Exception { - if (dates == null) { - assertEquals("set not empty", 0, set.size()); - return; - } - List setFromArray = new ArrayList(); - for (int i = 0; i < dates.length; i++) { - setFromArray.add(new SimpleDateFormat(pattern).parse(dates[ i ])); - } - assertTrue("set not equals array, expected: " + setFromArray - + ", actual: " + set, set.equals(setFromArray)); - } - - // methods for coversion of data types - List intSet(int[] values) { - if (values == null) { - return null; - } - List set = new ArrayList(); - for (int i = 0; i < values.length; i++) { - set.add(new Integer(values[ i ])); - } - return set; - } - - List doubleSet(double[] values) { - if (values == null) { - return null; - } - List set = new ArrayList(); - for (int i = 0; i < values.length; i++) { - set.add(new Double(values[ i ])); - } - return set; - } - - // set of DvDate - List dateSet(String[] values) throws Exception { - if (values == null) { - return null; - } - List set = new ArrayList(); - for (int i = 0; i < values.length; i++) { - set.add(date(values[ i ])); - } - return set; - } - - // set of DvDateTime - List dateTimeSet(String[] values) throws Exception { - if (values == null) { - return null; - } - List set = new ArrayList(); - for (int i = 0; i < values.length; i++) { - set.add(dateTime(values[ i ])); - } - return set; - } - - // set of DvTime - List timeSet(String[] values) throws Exception { - if (values == null) { - return null; - } - List set = new ArrayList(); - for (int i = 0; i < values.length; i++) { - set.add(time(values[ i ])); - } - return set; - } - - // convert with default pattern - DvDateTime dateTime(String value) throws Exception { - return new DvDateTime(value); - } - - DvTime time(String value) throws Exception { - return new DvTime(value); - } - - DvDate date(String value) throws Exception { - return new DvDate(value); - } - - Interval interval(int low, int up) { - return new Interval(new Integer(low), new Integer(up)); - } - - /* fields */ - static protected File dir = new File("res" + File.separator + "test"); -} +package se.acode.openehr.parser; + +import junit.framework.TestCase; + +import java.io.File; +import java.io.InputStream; +import java.util.*; +import java.text.SimpleDateFormat; + +import org.openehr.am.archetype.constraintmodel.*; +import org.openehr.am.archetype.constraintmodel.primitive.*; +import org.openehr.rm.support.basic.Interval; +import org.openehr.rm.datatypes.quantity.datetime.*; + +/** + * ADLParser testing config and common logic + * + * @author Rong Chen + * @version 1.0 + */ +public class ParserTestBase extends TestCase { + + public ParserTestBase(String test) { + super(test); + } + + public ParserTestBase(){ + } + + protected InputStream loadFromClasspath(String adl) throws Exception { + return this.getClass().getClassLoader().getResourceAsStream(adl); + } + + // assert CComplexObject object has expected values + void assertCComplexObject(CComplexObject obj, String rmTypeName, + String nodeID, Interval occurrences, + int attributes) throws Exception { + assertCObject(obj, rmTypeName, nodeID, occurrences); + assertEquals("attributes.size", attributes, obj.getAttributes().size()); + } + + // assert CObject has expected valuess + void assertCObject(CObject obj, String rmTypeName, String nodeID, + Interval occurrences) throws Exception { + assertEquals("rmTypeName", rmTypeName, obj.getRmTypeName()); + assertEquals("nodeID", nodeID, obj.getNodeId()); + assertEquals("occurrences", occurrences, obj.getOccurrences()); + } + + // assert CAttribute has expected values + void assertCAttribute(CAttribute attr, String rmAttributeName, + CAttribute.Existence existence, + Cardinality cardinality, int children) + throws Exception { + assertEquals("rmAttributeName", rmAttributeName, + attr.getRmAttributeName()); + assertEquals("existence", existence, attr.getExistence()); + if(attr instanceof CMultipleAttribute) { + CMultipleAttribute mattr = (CMultipleAttribute) attr; + assertEquals("cardinality", cardinality, mattr.getCardinality()); + } + assertEquals("children.size", children, attr.getChildren().size()); + } + + // assert CAttribute has expected values + void assertCAttribute(CAttribute attr, String rmAttributeName, + int children) throws Exception { + assertCAttribute(attr, rmAttributeName, CAttribute.Existence.OPTIONAL, /*NB: We changed this to common practice (initially 1.4 logic specified this to be REQUIRED by default.)*/ + null, children); + } + + // assertion on primitive types + void assertCBoolean(Object obj, boolean trueValid, boolean falseValid, + boolean assumed, boolean hasAssumed) + throws Exception { + CBoolean b = (CBoolean) fetchFirst(obj); + assertEquals("trueValid", trueValid, b.isTrueValid()); + assertEquals("falseValid", falseValid, b.isFalseValid()); + assertEquals("assumed value", assumed, b.assumedValue().booleanValue()); + assertEquals("has assumed value", hasAssumed, b.hasAssumedValue()); + } + + void assertCInteger(Object obj, Interval interval, int[] values, + Integer assumed) throws Exception { + CInteger c = (CInteger) fetchFirst(obj); + assertEquals("interval", interval, c.getInterval()); + assertEquals("list", intSet(values), c.getList()); + assertEquals("unexpected assumed value", assumed, c.assumedValue()); + } + + void assertCReal(Object obj, Interval interval, double[] values, + Double assumed) throws Exception { + CReal c = (CReal) fetchFirst(obj); + assertEquals("interval", interval, c.getInterval()); + assertEquals("list", doubleSet(values), c.getList()); + assertEquals("unexpected assumed value", assumed, c.assumedValue()); + } + + void assertCDate(Object obj, String pattern, Interval interval, + String[] values, String assumed) + throws Exception { + CDate c = (CDate) fetchFirst(obj); + assertEquals("pattern", pattern, c.getPattern()); + assertEquals("interval", interval, c.getInterval()); + assertEquals("list", dateSet(values), c.getList()); + assertEquals("assumed value", + assumed == null? null :new DvDate(assumed), c.assumedValue()); + } + + void assertCDateTime(Object obj, String pattern, Interval interval, + String[] values, String assumed) + throws Exception { + CDateTime c = (CDateTime) fetchFirst(obj); + assertEquals("pattern", pattern, c.getPattern()); + assertEquals("interval", interval, c.getInterval()); + assertEquals("list", dateTimeSet(values), c.getList()); + assertEquals("assumed value", + assumed == null? null :new DvDateTime(assumed), c.assumedValue()); + } + + // without assumed value + void assertCDateTime(Object obj, String pattern, Interval interval, + String[] values) throws Exception { + assertCDateTime(obj, pattern, interval, values, null); + } + + + void assertCTime(Object obj, String pattern, Interval interval, + String[] values, String assumed) + throws Exception { + CTime c = (CTime) fetchFirst(obj); + assertEquals("pattern", pattern, c.getPattern()); + assertEquals("interval", interval, c.getInterval()); + assertEquals("list", timeSet(values), c.getList()); + assertEquals("assumed value", + assumed == null? null :new DvTime(assumed), c.assumedValue()); + } + + // without assumed value + void assertCTime(Object obj, String pattern, Interval interval, + String[] values) throws Exception { + assertCTime(obj, pattern, interval, values, null); + } + + // full assertion with CDuration + void assertCDuration(Object obj, String value, Interval interval, + String assumed, String pattern) throws Exception { + CDuration c = (CDuration) ((CPrimitiveObject) obj).getItem(); + assertEquals("list", value == null ? null : DvDuration.getInstance(value), + c.getValue()); + assertEquals("interval", interval, c.getInterval()); + assertEquals("assumed value", + assumed == null? null + : DvDuration.getInstance(assumed), c.assumedValue()); + assertEquals("pattern wrong", pattern, c.getPattern()); + } + + // without pattern + void assertCDuration(Object obj, String value, Interval interval, + String assumed) throws Exception { + assertCDuration(obj, value, interval, assumed, null); + } + + // without assumed value, pattern + void assertCDuration(Object obj, String value, Interval interval) + throws Exception { + assertCDuration(obj, value, interval, null); + } + + // fetch the first CPrimitive from the CAttribute + CPrimitive fetchFirst(Object obj) { + return ( (CPrimitiveObject) ( (CAttribute) obj ).getChildren() + .get(0) ).getItem(); + } + + void assertCString(Object obj, String pattern, String[] values, + String assumedValue) { + CString c = (CString) ( (CPrimitiveObject) ( (CAttribute) obj ).getChildren() + .get(0) ).getItem(); + if (pattern == null) { + assertTrue("pattern null", c.getPattern() == null); + } else { + assertEquals("pattern", pattern, c.getPattern()); + } + assertEquals("list", values == null + ? null : Arrays.asList(values), c.getList()); + assertEquals("unexpected CString assumed value", assumedValue, + c.assumedValue()); + } + + void assertDateEquals(List set, String[] dates, String pattern) + throws Exception { + if (dates == null) { + assertEquals("set not empty", 0, set.size()); + return; + } + List setFromArray = new ArrayList(); + for (int i = 0; i < dates.length; i++) { + setFromArray.add(new SimpleDateFormat(pattern).parse(dates[ i ])); + } + assertTrue("set not equals array, expected: " + setFromArray + + ", actual: " + set, set.equals(setFromArray)); + } + + // methods for coversion of data types + List intSet(int[] values) { + if (values == null) { + return null; + } + List set = new ArrayList(); + for (int i = 0; i < values.length; i++) { + set.add(new Integer(values[ i ])); + } + return set; + } + + List doubleSet(double[] values) { + if (values == null) { + return null; + } + List set = new ArrayList(); + for (int i = 0; i < values.length; i++) { + set.add(new Double(values[ i ])); + } + return set; + } + + // set of DvDate + List dateSet(String[] values) throws Exception { + if (values == null) { + return null; + } + List set = new ArrayList(); + for (int i = 0; i < values.length; i++) { + set.add(date(values[ i ])); + } + return set; + } + + // set of DvDateTime + List dateTimeSet(String[] values) throws Exception { + if (values == null) { + return null; + } + List set = new ArrayList(); + for (int i = 0; i < values.length; i++) { + set.add(dateTime(values[ i ])); + } + return set; + } + + // set of DvTime + List timeSet(String[] values) throws Exception { + if (values == null) { + return null; + } + List set = new ArrayList(); + for (int i = 0; i < values.length; i++) { + set.add(time(values[ i ])); + } + return set; + } + + // convert with default pattern + DvDateTime dateTime(String value) throws Exception { + return new DvDateTime(value); + } + + DvTime time(String value) throws Exception { + return new DvTime(value); + } + + DvDate date(String value) throws Exception { + return new DvDate(value); + } + + Interval interval(int low, int up) { + return new Interval(new Integer(low), new Integer(up)); + } + + /* fields */ + static protected File dir = new File("res" + File.separator + "test"); +} diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/PathTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/PathTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/RegularExpressionTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/RegularExpressionTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/SpecialStringTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/SpecialStringTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/StructureTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/StructureTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/TermBindingTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/TermBindingTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/UnicodeBOMSupportTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/UnicodeBOMSupportTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/java/se/acode/openehr/parser/UnicodeSupportTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/UnicodeSupportTest.java old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-SOME_TYPE.generic_type_basic.draft.adl b/adl-parser/src/test/resources/adl-test-SOME_TYPE.generic_type_basic.draft.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-SOME_TYPE.generic_type_use_node.draft.adl b/adl-parser/src/test/resources/adl-test-SOME_TYPE.generic_type_use_node.draft.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-car.paths.test.adl b/adl-parser/src/test/resources/adl-test-car.paths.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-car.use_node.test.adl b/adl-parser/src/test/resources/adl-test-car.use_node.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-composition.dv_coded_text.test.adl b/adl-parser/src/test/resources/adl-test-composition.dv_coded_text.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.archetype_bindings.test.adl b/adl-parser/src/test/resources/adl-test-entry.archetype_bindings.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.archetype_desc_missing_purpose.test.adl b/adl-parser/src/test/resources/adl-test-entry.archetype_desc_missing_purpose.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.archetype_description.test.adl b/adl-parser/src/test/resources/adl-test-entry.archetype_description.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.archetype_description2.test.adl b/adl-parser/src/test/resources/adl-test-entry.archetype_description2.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.archetype_identification.test.adl b/adl-parser/src/test/resources/adl-test-entry.archetype_identification.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.archetype_internal_ref.test.adl b/adl-parser/src/test/resources/adl-test-entry.archetype_internal_ref.test.adl old mode 100755 new mode 100644 index da16b430..c7bc6d86 --- a/adl-parser/src/test/resources/adl-test-entry.archetype_internal_ref.test.adl +++ b/adl-parser/src/test/resources/adl-test-entry.archetype_internal_ref.test.adl @@ -19,6 +19,10 @@ definition use_node COMPLEX_OBJECT /items[at0001] use_node COMPLEX_OBJECT /items[at0002] } + attribute4 matches { + use_node SECTION[at0005] /items[at0001] + use_node SECTION[at0006] /items[at0002] + } } ontology diff --git a/adl-parser/src/test/resources/adl-test-entry.archetype_internal_ref2.test.adl b/adl-parser/src/test/resources/adl-test-entry.archetype_internal_ref2.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.archetype_language.test.adl b/adl-parser/src/test/resources/adl-test-entry.archetype_language.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.archetype_language.test2.adl b/adl-parser/src/test/resources/adl-test-entry.archetype_language.test2.adl new file mode 100644 index 00000000..ae6b3e15 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.archetype_language.test2.adl @@ -0,0 +1,55 @@ +archetype + adl-test-ENTRY.archetype_language.draft + +concept + [at0000] -- test + +language + original_language = <[ISO_639-1::en]> + translations = < + ["de"] = < + language = <[ISO_639-1::de]> + author = < + ["name"] = <"Harry Potter"> + ["email"] = <"harry@something.somewhere.co.uk"> + > + accreditation = <"British Medical Translator id 00400595"> + other_details = < + ["review 1"] = <"Ron Weasley"> + ["review 2"] = <"Rubeus Hagrid"> + > + > + ["ru"] = < + language = <[ISO_639-1::ru]> + author = < + ["name"] = <"Vladimir Nabokov"> + ["email"] = <"vladimir@something.somewhere.ru"> + > + accreditation = <"Russion Translator id 892230A"> + > + > +definition + ENTRY[at0000] matches {*} + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test">; + description = <"test"> + > + > + > + ["ru"] = < + items = < + ["at0000"] = < + text = <"test">; + description = <"test2"> + > + > + > + > \ No newline at end of file diff --git a/adl-parser/src/test/resources/adl-test-entry.archetype_language_no_accreditation.test.adl b/adl-parser/src/test/resources/adl-test-entry.archetype_language_no_accreditation.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.archetype_language_order_of_translation_details.test.adl b/adl-parser/src/test/resources/adl-test-entry.archetype_language_order_of_translation_details.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.archetype_ontology.test.adl b/adl-parser/src/test/resources/adl-test-entry.archetype_ontology.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.archetype_slot.test.adl b/adl-parser/src/test/resources/adl-test-entry.archetype_slot.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.archetype_slot.test2.adl b/adl-parser/src/test/resources/adl-test-entry.archetype_slot.test2.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.archetype_uncommonkeys.test.adl b/adl-parser/src/test/resources/adl-test-entry.archetype_uncommonkeys.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.basic_types.test.adl b/adl-parser/src/test/resources/adl-test-entry.basic_types.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.c_code_phrase.test.adl b/adl-parser/src/test/resources/adl-test-entry.c_code_phrase.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.c_dv_ordinal.test.adl b/adl-parser/src/test/resources/adl-test-entry.c_dv_ordinal.test.adl index 1c2761fd..8e0abec5 100755 --- a/adl-parser/src/test/resources/adl-test-entry.c_dv_ordinal.test.adl +++ b/adl-parser/src/test/resources/adl-test-entry.c_dv_ordinal.test.adl @@ -36,8 +36,16 @@ definition C_DV_ORDINAL < > } - } - + } + ELEMENT[at10004] matches { -- ordinal with two duplicated values + value matches { + 0|[local::at0003.0], -- capsule + 1|[local::at0003.1], -- powder + 1|[local::at0003.2], -- tablet + 3|[local::at0003.3], -- solution + 4|[local::at0003.4] -- suspension + } + } } } } diff --git a/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_empty.test.adl b/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_empty.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_full.test.adl b/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_full.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_full2.test.adl b/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_full2.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_full3.test.adl b/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_full3.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_item_units_only.test.adl b/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_item_units_only.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_list.test.adl b/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_list.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_property.test.adl b/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_property.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_reversed.test.adl b/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_reversed.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.c_dv_scale.test.adl b/adl-parser/src/test/resources/adl-test-entry.c_dv_scale.test.adl new file mode 100644 index 00000000..f8e8605d --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.c_dv_scale.test.adl @@ -0,0 +1,97 @@ +archetype + adl-test-ENTRY.c_dv_scale.test + +concept + [at0000] + +language + original_language = <[ISO_639-1::en]> + +definition + ENTRY[at0000] matches { + types matches { + LIST[at0001] matches { + items cardinality matches {0..*} matches { + ELEMENT[at10001] matches { -- scale + value matches { + 0.0|[local::at0003.0], -- capsule + 1.0|[local::at0003.1], -- powder + 2.5|[local::at0003.2], -- tablet + 3.8|[local::at0003.3], -- solution + 4.4|[local::at0003.4] -- suspension + } + } + ELEMENT[at10002] matches { -- scale with assumed value + value matches { + 0|[local::at0003.0], -- capsule + 1|[local::at0003.1], -- powder + 2|[local::at0003.2], -- tablet + 3|[local::at0003.3], -- solution + 4.1|[local::at0003.4]; -- suspension + 2 -- assumed value + } + } + ELEMENT[at10003] matches { -- scale, any allowed + value matches { -- any allowed + DV_SCALE matches { * } + } + } + ELEMENT[at10004] matches { -- scale with two duplicated values + value matches { + 0|[local::at0003.0], -- capsule + 1.5|[local::at0003.1], -- powder + 1.5|[local::at0003.2], -- tablet + 3.5|[local::at0003.3], -- solution + 4|[local::at0003.4] -- suspension + } + } + ELEMENT[at10005] occurrences matches {0..1} matches { -- MyScale NORMAL + value matches { + DV_SCALE matches { + value matches {0} + symbol matches { + DV_CODED_TEXT matches { + defining_code matches { + [local::at0003.0] + } -- 0scale + } + } + } + DV_SCALE matches { + value matches {1.5} + symbol matches { + DV_CODED_TEXT matches { + defining_code matches { + [local::at0003.2] + } -- 1.5scale + } + } + } + } + } + } + } + } + } + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"domain types test"> + description = <"domain types test"> + > + ["at0001"] = < + text = <"items"> + description = <"items"> + > + ["at10001"] = < + text = <"c_dv_scale"> + description = <"c_dv_scale node"> + > + > + > + > \ No newline at end of file diff --git a/adl-parser/src/test/resources/adl-test-entry.constraint_binding.test.adl b/adl-parser/src/test/resources/adl-test-entry.constraint_binding.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.constraint_ref.test.adl b/adl-parser/src/test/resources/adl-test-entry.constraint_ref.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.datetime.test.adl b/adl-parser/src/test/resources/adl-test-entry.datetime.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.domain_types.test.adl b/adl-parser/src/test/resources/adl-test-entry.domain_types.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.durations.test.adl b/adl-parser/src/test/resources/adl-test-entry.durations.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.empty_other_contributors.test.adl b/adl-parser/src/test/resources/adl-test-entry.empty_other_contributors.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.missing_language.test.adl b/adl-parser/src/test/resources/adl-test-entry.missing_language.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.mixed_node_types.draft.adl b/adl-parser/src/test/resources/adl-test-entry.mixed_node_types.draft.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.most_minimal.test.adl b/adl-parser/src/test/resources/adl-test-entry.most_minimal.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.multi_language.test.adl b/adl-parser/src/test/resources/adl-test-entry.multi_language.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.regular_expression.test.adl b/adl-parser/src/test/resources/adl-test-entry.regular_expression.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.special_string.test.adl b/adl-parser/src/test/resources/adl-test-entry.special_string.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.structure_test1.test.adl b/adl-parser/src/test/resources/adl-test-entry.structure_test1.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.structure_test2.test.adl b/adl-parser/src/test/resources/adl-test-entry.structure_test2.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.term_binding.test.adl b/adl-parser/src/test/resources/adl-test-entry.term_binding.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.term_binding2.test.adl b/adl-parser/src/test/resources/adl-test-entry.term_binding2.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.testtranslations.test.adl b/adl-parser/src/test/resources/adl-test-entry.testtranslations.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.translations_author_language.test.adl b/adl-parser/src/test/resources/adl-test-entry.translations_author_language.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.translations_language_author.test.adl b/adl-parser/src/test/resources/adl-test-entry.translations_language_author.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.unicode_BOM_support.test.adl b/adl-parser/src/test/resources/adl-test-entry.unicode_BOM_support.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/adl-test-entry.unicode_support.test.adl b/adl-parser/src/test/resources/adl-test-entry.unicode_support.test.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/openEHR-EHR-CLUSTER.auscultation.v1.adl b/adl-parser/src/test/resources/openEHR-EHR-CLUSTER.auscultation.v1.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/openEHR-EHR-CLUSTER.duration_interval_test.v0.adl b/adl-parser/src/test/resources/openEHR-EHR-CLUSTER.duration_interval_test.v0.adl new file mode 100644 index 00000000..9e4e4a1b --- /dev/null +++ b/adl-parser/src/test/resources/openEHR-EHR-CLUSTER.duration_interval_test.v0.adl @@ -0,0 +1,129 @@ +archetype (adl_version=1.4) + openEHR-EHR-CLUSTER.duration_interval_test.v0 + +concept + [at0000] -- Duration interval test +language + original_language = <[ISO_639-1::de]> +description + original_author = < + ["name"] = <"s"> + > + details = < + ["de"] = < + language = <[ISO_639-1::de]> + purpose = <"test duration constraints"> + use = <""> + misuse = <""> + copyright = <""> + > + > + lifecycle_state = <"in_development"> + other_contributors = <> + other_details = < + ["MD5-CAM-1.0.1"] = <"56BA0D180BE093539E02771672EF6BA2"> + > + +definition + CLUSTER[at0000] matches { -- Duration interval test + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0001] occurrences matches {0..1} matches { -- D1 + value matches { + DV_DURATION matches { + value matches {PD/|>P10D..PT0M..PT0M|} + } + } + } + ELEMENT[at0004] occurrences matches {0..1} matches { -- D3 + value matches { + DV_DURATION matches { + value matches {PD/|=P10D|} + } + } + } + ELEMENT[at0008] occurrences matches {0..1} matches { -- D6 + value matches { + DV_DURATION matches { + value matches {|<=PT110M|} + } + } + } + } + } + +ontology + term_definitions = < + ["de"] = < + items = < + ["at0000"] = < + text = <"Duration interval test"> + description = <"unknown"> + > + ["at0001"] = < + text = <"D1"> + description = <"*"> + > + ["at0003"] = < + text = <"D2"> + description = <"*"> + > + ["at0004"] = < + text = <"D3"> + description = <"*"> + > + ["at0005"] = < + text = <"D4"> + description = <"*"> + > + ["at0006"] = < + text = <"D unconstrained"> + description = <"*"> + > + ["at0007"] = < + text = <"D5"> + description = <"*"> + > + ["at0008"] = < + text = <"D6"> + description = <"*"> + > + ["at0009"] = < + text = <"D1a"> + description = <"*"> + > + > + > + > diff --git a/adl-parser/src/test/resources/openEHR-EHR-CLUSTER.ordinalandscale.v0.adl b/adl-parser/src/test/resources/openEHR-EHR-CLUSTER.ordinalandscale.v0.adl new file mode 100644 index 00000000..c8cc6689 --- /dev/null +++ b/adl-parser/src/test/resources/openEHR-EHR-CLUSTER.ordinalandscale.v0.adl @@ -0,0 +1,178 @@ +archetype (adl_version=1.4; uid=64891061-481c-44ce-aa73-1913ef8dc66d) + openEHR-EHR-CLUSTER.ordinalandscale.v0 + +concept + [at0000] -- Ordinalandscale +language + original_language = <[ISO_639-1::de]> +description + original_author = < + ["name"] = <""> + > + details = < + ["de"] = < + language = <[ISO_639-1::de]> + purpose = <""> + use = <""> + misuse = <""> + copyright = <"© openEHR Foundation"> + > + > + lifecycle_state = <"in_development"> + other_contributors = <> + other_details = < + ["licence"] = <"This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/."> + ["custodian_organisation"] = <"openEHR Foundation"> + ["original_namespace"] = <"org.openehr"> + ["original_publisher"] = <"openEHR Foundation"> + ["custodian_namespace"] = <"org.openehr"> + ["MD5-CAM-1.0.1"] = <"60400C49A960FAF443B1EC1DB870040B"> + ["build_uid"] = <"73064b08-4ae3-46c7-941d-b45e5066e7a3"> + ["revision"] = <"0.0.1-alpha"> + > + +definition + CLUSTER[at0000] matches { -- Ordinalandscale + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0001] occurrences matches {0..1} matches { -- MYOrdinal + value matches { + 1|[local::at0002], -- 1ord + 2|[local::at0003], -- 2ord + 3|[local::at0004] -- 3ord + } + } + ELEMENT[at0005] occurrences matches {0..1} matches { -- MyScale + value matches { + 1.0|[local::at0006], -- 1.0scale + 2.5|[local::at0007], -- 2.5scale + 3.0|[local::at0008] -- 3.0scale + } + } + ELEMENT[at0009] occurrences matches {0..1} matches { -- MyScale2 + value matches { + 1.2|[local::at0010], -- 1.2scale + 2.5|[local::at0011], -- 2.5scale + 3|[local::at00012] -- 3scale + } + } + ELEMENT[at0013] occurrences matches {0..1} matches { -- MyScale3 + value matches { + 1.5|[local::at0014], -- 1.5scale + 2|[local::at0015], -- 2scale + 3|[local::at00016] -- 3scale + } + } + ELEMENT[at0017] occurrences matches {0..1} matches { -- MyScale NORMAL + value matches { + DV_SCALE matches { + value matches {0} + symbol matches { + DV_CODED_TEXT matches { + defining_code matches { + [local::at0018] + } -- 0scale + } + } + } + DV_SCALE matches { + value matches {1.5} + symbol matches { + DV_CODED_TEXT matches { + defining_code matches { + [local::at0019] + } -- 1.5scale + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["de"] = < + items = < + ["at0000"] = < + text = <"Ordinalandscale"> + description = <"unknown"> + > + ["at0001"] = < + text = <"My Ordinal"> + description = <"*"> + > + ["at0002"] = < + text = <"1ord"> + description = <"*"> + > + ["at0003"] = < + text = <"2ord"> + description = <"*"> + > + ["at0004"] = < + text = <"3ord"> + description = <"*"> + > + ["at0005"] = < + text = <"MyScale"> + description = <"*"> + > + ["at0006"] = < + text = <"1scale"> + description = <"*"> + > + ["at0007"] = < + text = <"2.5scale"> + description = <"*"> + > + ["at0008"] = < + text = <"3scale"> + description = <"*"> + > + ["at0009"] = < + text = <"MyScale2"> + description = <"*"> + > + ["at0010"] = < + text = <"1.2scale"> + description = <"*"> + > + ["at0011"] = < + text = <"2.5scale"> + description = <"*"> + > + ["at0012"] = < + text = <"3scale"> + description = <"*"> + > + ["at0013"] = < + text = <"MyScale2"> + description = <"*"> + > + ["at0014"] = < + text = <"1.5scale"> + description = <"*"> + > + ["at0015"] = < + text = <"2scale"> + description = <"*"> + > + ["at0016"] = < + text = <"3scale"> + description = <"*"> + > + ["at0017"] = < + text = <"MyScale NORMAL"> + description = <"*"> + > + ["at0018"] = < + text = <"0scale"> + description = <"*"> + > + ["at0019"] = < + text = <"1.5scale"> + description = <"*"> + > + > + > + > diff --git a/adl-parser/src/test/resources/openEHR-EHR-ELEMENT.uid_test.v1.adl b/adl-parser/src/test/resources/openEHR-EHR-ELEMENT.uid_test.v1.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/openEHR-EHR-ELEMENT.uid_test.v2.adl b/adl-parser/src/test/resources/openEHR-EHR-ELEMENT.uid_test.v2.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/openEHR-EHR-EVALUATION.columna_vertebral.v1.adl b/adl-parser/src/test/resources/openEHR-EHR-EVALUATION.columna_vertebral.v1.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/openEHR-EHR-OBSERVATION.test_internal_ref_binding.v1.adl b/adl-parser/src/test/resources/openEHR-EHR-OBSERVATION.test_internal_ref_binding.v1.adl old mode 100755 new mode 100644 diff --git a/adl-parser/src/test/resources/openEHR-EHR-OBSERVATION.testassumedvalue.v1.adl b/adl-parser/src/test/resources/openEHR-EHR-OBSERVATION.testassumedvalue.v1.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/docs/changes.txt b/adl-serializer/docs/changes.txt old mode 100755 new mode 100644 diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 0d39ed21..e6fc1ab7 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -1,9 +1,9 @@ 4.0.0 - openehr - ref_impl_java - 1.0.5-SNAPSHOT + org.openehr.java-libs + java-libs + 0-SNAPSHOT adl-serializer jar @@ -27,32 +27,32 @@ - openehr + org.openehr.java-libs openehr-rm-core ${project.version} - openehr + org.openehr.java-libs openehr-rm-domain ${project.version} - openehr + org.openehr.java-libs openehr-aom ${project.version} - openehr + org.openehr.java-libs openehr-ap ${project.version} - openehr + org.openehr.java-libs mini-termserv ${project.version} - openehr + org.openehr.java-libs adl-parser ${project.version} test diff --git a/adl-serializer/readme.txt b/adl-serializer/readme.txt old mode 100755 new mode 100644 diff --git a/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java b/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java old mode 100755 new mode 100644 index af138e25..27b08494 --- a/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java +++ b/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java @@ -1,1290 +1,1338 @@ -/* - * component: "openEHR Reference Implementation" - * description: "Class ADLSerializer" - * keywords: "archetype" - * - * author: "Rong Chen " - * support: "Acode HB " - * copyright: "Copyright (c) 2004,2005,2006 Acode HB, Sweden" - * license: "See notice at bottom of class" - * - * file: "$URL: $" - * revision: "$LastChangedRevision: 41 $" - * last_change: "$LastChangedDate: 2006-07-12 23:24:42 +0200 (Wed, 12 Jul 2006) $" - */ -package org.openehr.am.serialize; - -import java.io.BufferedOutputStream; -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.StringWriter; -import java.io.Writer; -import java.nio.charset.Charset; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.lang.StringUtils; -import org.openehr.am.archetype.Archetype; -import org.openehr.am.archetype.assertion.Assertion; -import org.openehr.am.archetype.constraintmodel.ArchetypeInternalRef; -import org.openehr.am.archetype.constraintmodel.ArchetypeSlot; -import org.openehr.am.archetype.constraintmodel.CAttribute; -import org.openehr.am.archetype.constraintmodel.CComplexObject; -import org.openehr.am.archetype.constraintmodel.CDomainType; -import org.openehr.am.archetype.constraintmodel.CMultipleAttribute; -import org.openehr.am.archetype.constraintmodel.CObject; -import org.openehr.am.archetype.constraintmodel.CPrimitiveObject; -import org.openehr.am.archetype.constraintmodel.Cardinality; -import org.openehr.am.archetype.constraintmodel.ConstraintRef; -import org.openehr.am.archetype.constraintmodel.primitive.CBoolean; -import org.openehr.am.archetype.constraintmodel.primitive.CDate; -import org.openehr.am.archetype.constraintmodel.primitive.CDateTime; -import org.openehr.am.archetype.constraintmodel.primitive.CDuration; -import org.openehr.am.archetype.constraintmodel.primitive.CInteger; -import org.openehr.am.archetype.constraintmodel.primitive.CPrimitive; -import org.openehr.am.archetype.constraintmodel.primitive.CReal; -import org.openehr.am.archetype.constraintmodel.primitive.CString; -import org.openehr.am.archetype.constraintmodel.primitive.CTime; -import org.openehr.am.archetype.ontology.ArchetypeOntology; -import org.openehr.am.archetype.ontology.ArchetypeTerm; -import org.openehr.am.archetype.ontology.OntologyBinding; -import org.openehr.am.archetype.ontology.OntologyDefinitions; -import org.openehr.am.archetype.ontology.QueryBindingItem; -import org.openehr.am.archetype.ontology.TermBindingItem; -import org.openehr.am.openehrprofile.datatypes.quantity.CDvOrdinal; -import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantity; -import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantityItem; -import org.openehr.am.openehrprofile.datatypes.quantity.Ordinal; -import org.openehr.am.openehrprofile.datatypes.text.CCodePhrase; -import org.openehr.rm.common.resource.AuthoredResource; -import org.openehr.rm.common.resource.ResourceDescription; -import org.openehr.rm.common.resource.ResourceDescriptionItem; -import org.openehr.rm.common.resource.TranslationDetails; -import org.openehr.rm.datatypes.quantity.DvQuantity; -import org.openehr.rm.datatypes.text.CodePhrase; -import org.openehr.rm.support.basic.Interval; -import org.openehr.rm.support.identification.ArchetypeID; -import org.openehr.rm.support.identification.ObjectID; - -/** - * ADL serializer for the openEHR Java kernel - * - * @author Rong Chen - * @author Mattias Forss, Johan Hjalmarsson - * @author Sebastian Garde - * - * @version 1.0 - */ -public class ADLSerializer { - - /** - * Create an outputter with default encoding, indent and lineSeparator - */ - public ADLSerializer() { - this.encoding = UTF8; - this.indent = " "; // 4 white space characters - this.lineSeparator = "\r\n"; - } - - /** - * Output given archetype as string in ADL format - * - * @param archetype - * @return a string in ADL format - * @throws IOException - */ - public String output(Archetype archetype) throws IOException { - StringWriter writer = new StringWriter(); - output(archetype, writer); - return writer.toString(); - } - - /** - * Output archetype DEFINITION as string in ADL format - * - * @param archetype - * @return a string in ADL format - * @throws IOException - */ - public String outputDefinitionOnly(Archetype archetype) throws IOException { - StringWriter writer = new StringWriter(); - - printDefinition(archetype.getDefinition(), writer); - - return writer.toString(); - } - - /** - * Output given archetype to outputStream - * - * @param archetype - * @param out - * @throws IOException - */ - public void output(Archetype archetype, OutputStream out) - throws IOException { - Writer writer = new BufferedWriter(new OutputStreamWriter( - new BufferedOutputStream(out), encoding)); - output(archetype, writer); - } - - /** - * Output given archetype to writer - * - * @param archetype - * @param out - * @throws IOException - */ - public void output(Archetype archetype, Writer out) throws IOException { - printHeader(archetype.getAdlVersion(), archetype.getArchetypeId(), - archetype.getParentArchetypeId(), archetype.getUid(), archetype.getConcept(), out); - newline(out); - - printLanguage(archetype, out); - newline(out); - - if(archetype.getDescription() != null) { - printDescription(archetype.getDescription(), out); - newline(out); - } - - printDefinition(archetype.getDefinition(), out); - newline(out); - - printOntology(archetype.getOntology(), out); - out.flush(); - out.close(); - } - - protected void printHeader(String adlVersion, - ArchetypeID id, ArchetypeID parentId, ObjectID uid, - String conceptCode, Writer out) throws IOException { - - out.write("archetype"); - if(StringUtils.isNotEmpty(adlVersion) || (uid != null && StringUtils.isNotEmpty(uid.toString()))) { - out.write(" ("); - } - - if(StringUtils.isNotEmpty(adlVersion)) { - out.write("adl_version="); - out.write(adlVersion); - } - if(uid != null && StringUtils.isNotEmpty(uid.toString())) { - out.write("uid="); - out.write(uid.toString()); - } - if(StringUtils.isNotEmpty(adlVersion) || (uid!=null &&StringUtils.isNotEmpty(uid.toString()))) { - out.write(")"); - } - newline(out); - indent(1, out); - out.write(id.toString()); - newline(out); - - if (parentId != null) { - out.write("specialize"); - newline(out); - indent(1, out); - out.write(parentId.toString()); - newline(out); - } - - newline(out); - out.write("concept"); - newline(out); - indent(1, out); - out.write("[" + conceptCode + "]"); - newline(out); - } - - protected void printLanguage(AuthoredResource authored, - Writer out) throws IOException { - - out.write("language"); - newline(out); - indent(1, out); - out.write("original_language = <"); - out.write("["); - out.write(authored.getOriginalLanguage().getTerminologyId().getValue()); - out.write("::"); - out.write(authored.getOriginalLanguage().getCodeString()); - out.write("]"); - out.write(">"); - newline(out); - if(authored.getTranslations() != null) { - indent(1, out); - out.write("translations = <"); - newline(out); - Map translations = - authored.getTranslations(); - for(String lang : translations.keySet()) { - TranslationDetails td = translations.get(lang); - - indent(2, out); - out.write("[\""); - out.write(lang); - out.write("\"] = <"); - newline(out); - - indent(3, out); - out.write("language = <"); - out.write("["); - out.write(td.getLanguage().getTerminologyId().getValue()); - out.write("::"); - out.write(td.getLanguage().getCodeString()); - out.write("]"); - out.write(">"); - newline(out); - - indent(3, out); - out.write("author = <"); - newline(out); - printMap(td.getAuthor(), out, 4); - indent(3, out); - out.write(">"); - newline(out); - - if(td.getAccreditation() != null) { - indent(3, out); - out.write("accreditation = <\""); - out.write(td.getAccreditation()); - out.write("\">"); - newline(out); - } - - if(td.getOtherDetails() != null) { - indent(3, out); - out.write("other_details = <"); - newline(out); - printMap(td.getOtherDetails(), out, 4); - indent(3, out); - out.write(">"); - newline(out); - } - - indent(2, out); - out.write(">"); - newline(out); - } - indent(1, out); - out.write(">"); - newline(out); - } - } - - protected void printMap(Map map, Writer out, int indent) - throws IOException { - if(map == null || map.size() == 0) { - return; - } - for(String key : map.keySet()) { - indent(indent, out); - out.write("[\""); - out.write(key); - out.write("\"] = <\""); - out.write(map.get(key)); - out.write("\">"); - newline(out); - } - } - - protected void printDescription(ResourceDescription description, Writer out) - throws IOException { - - if (description == null) { - return; - } - - out.write("description"); - newline(out); - - indent(1, out); - out.write("original_author = <"); - newline(out); - Map map = description.getOriginalAuthor(); - for (String key : map.keySet()) { - indent(2, out); - out.write("[\"" + key + "\"] = <\"" + map.get(key) + "\">"); - newline(out); - } - indent(1, out); - out.write(">"); - newline(out); - - indent(1, out); - out.write("lifecycle_state = <\""); - out.write(description.getLifecycleState()); - out.write("\">"); - newline(out); - - printNonEmptyString("resource_package_uri", description.getResourcePackageUri(), 1, out); - - indent(1, out); - out.write("details = <"); - newline(out); - for (ResourceDescriptionItem item : description.getDetails()) { - printDescriptionItem(item, 2, out); - } - indent(1, out); - out.write(">"); - newline(out); - } - - protected void printDescriptionItem(ResourceDescriptionItem item, - int indent, Writer out) throws IOException { - indent(indent, out); - out.write("[\""); - out.write(item.getLanguage().getCodeString()); - out.write("\"] = <"); - newline(out); - - indent(indent + 1, out); - out.write("language = <"); - out.write("["); - out.write(item.getLanguage().getTerminologyId().getValue()); - out.write("::"); - out.write(item.getLanguage().getCodeString()); - out.write("]>"); - newline(out); - - printNonEmptyString("purpose", item.getPurpose(), indent + 1, out); - printNonEmptyStringList("keywords", item.getKeywords(), indent + 1, - out); - printNonEmptyString("copyright", item.getCopyright(), indent + 1, out); - printNonEmptyString("use", item.getUse(), indent + 1, out); - printNonEmptyString("misuse", item.getMisuse(), indent + 1, out); - printNonEmptyStringMap("original_resource_uri", item.getOriginalResourceUri(), indent + 1, out); - - // other details not printed - - indent(indent, out); - out.write(">"); - newline(out); - } - - private void printNonEmptyString(String label, String value, int indent, - Writer out) throws IOException { - - if (StringUtils.isEmpty(value)) { - return; - } - indent(indent, out); - out.write(label); - out.write(" = <\""); - out.write(value); - out.write("\">"); - newline(out); - } - - private void printNonEmptyStringList(String label, List list, - int indent, Writer out) throws IOException { - - if (list == null || list.isEmpty()) { - return; - } - indent(indent, out); - out.write(label); - out.write(" = <"); - for (int i = 0, j = list.size(); i < j; i++) { - out.write("\""); - out.write(list.get(i)); - out.write("\""); - if (i != j - 1) { - out.write(","); - } - } - out.write(">"); - newline(out); - } - - private void printNonEmptyStringMap(String label, Map map, - int indent, Writer out) throws IOException { - if (map == null || map.isEmpty()) { - return; - } - - indent(indent, out); - out.write(label); - out.write(" = <"); - newline(out); - - for (String key : map.keySet()) { - indent(2, out); - out.write("[\"" + key + "\"] = <\"" + map.get(key) + "\">"); - newline(out); - } - - indent(indent, out); - out.write(">"); - newline(out); - } - - protected void printDefinition(CComplexObject definition, Writer out) - throws IOException { - - out.write("definition"); - newline(out); - - printCComplexObject(definition, 1, out); - } - - protected void printCComplexObject(CComplexObject ccobj, int indent, - Writer out) throws IOException { - - // TODO skip c_obj with [0,0] occurrences - Interval occurrences = ccobj.getOccurrences(); - if(occurrences != null - && (Integer.valueOf(0).equals(occurrences.getLower())) - && (Integer.valueOf(0).equals(occurrences.getUpper()))) { - return; - } - - - // print rmTypeName and nodeId - indent(indent, out); - out.write(ccobj.getRmTypeName()); - if (StringUtils.isNotEmpty(ccobj.getNodeId())) { - out.write("[" + ccobj.getNodeId() + "]"); - } - - printOccurrences(ccobj.getOccurrences(), out); - - out.write(" matches {"); - - // print all attributes - if (!ccobj.isAnyAllowed()) { - for (CAttribute cattribute : ccobj.getAttributes()) { - printCAttribute(cattribute, indent + 1, out); - } - newline(out); - indent(indent, out); - } else { - out.write("*"); - } - out.write("}"); - newline(out); - } - - protected void printOccurrences(Interval occurrences, Writer out) - throws IOException { - - Interval defaultOccurrences = new Interval(1, 1); - if(occurrences == null || defaultOccurrences.equals(occurrences)) { - return; - } - if (occurrences != null) { - out.write(" occurrences matches {"); - if (occurrences.getLower() == null) { - out.write("*"); - } else { - out.write(Integer.toString(occurrences.getLower())); - } - out.write(".."); - if (occurrences.getUpper() == null) { - out.write("*"); - } else { - out.write(Integer.toString(occurrences.getUpper())); - } - out.write("}"); - } - } - - protected void printArchetypeInternalRef(ArchetypeInternalRef ref, - int indent, Writer out) throws IOException { - indent(indent, out); - out.write("use_node "); - out.write(ref.getRmTypeName()); - printOccurrences(ref.getOccurrences(), out); - out.write(" "); - out.write(ref.getTargetPath()); - newline(out); - } - - protected void printArchetypeSlot(ArchetypeSlot slot, int indent, Writer out) - throws IOException { - - indent(indent, out); - out.write("allow_archetype "); - out.write(slot.getRmTypeName()); - if (StringUtils.isNotEmpty(slot.getNodeId())) { - out.write("[" + slot.getNodeId() + "]"); - } - - printOccurrences(slot.getOccurrences(), out); - out.write(" matches {"); - - if (slot.isAnyAllowed()) { - out.write("*}"); - } else { - if (slot.getIncludes() != null) { - printAssertions(slot.getIncludes(), "include", indent, out); - } - if (slot.getExcludes() != null) { - printAssertions(slot.getExcludes(), "exclude", indent, out); - } - newline(out); - indent(indent, out); - out.write("}"); - } - newline(out); - } - - private void printAssertions(Set assertions, String purpose, - int indent, Writer out) throws IOException { - - if(assertions == null) { - return; - } - - newline(out); - indent(indent + 1, out); - out.write(purpose); - - for (Assertion assertion : assertions) { - - if(assertion.getStringExpression() == null) { - continue; - } - - newline(out); - indent(indent + 2, out); - - // FIXME: The string expression is null when an archetype is parsed, but after the archetype is recreated in the archetype - // editor, the string expression exists. Please provide a valid string expression from the parser since it's _much_ easier to - // maintain this line of code instead of adding hundreds of lines just to output some expressions, operators etc. - // Opening an archetype directly in the ADL format view will show the output of the parsed archetype in this way: - // - // include - // null - out.write(assertion.getStringExpression()); - } - } - - protected void printCAttribute(CAttribute cattribute, int indent, Writer out) - throws IOException { - newline(out); - indent(indent, out); - out.write(cattribute.getRmAttributeName()); - if (!CAttribute.Existence.REQUIRED.equals(cattribute.getExistence())) { - out.write(" "); - } - printExistence(cattribute.getExistence(), out); - if (cattribute instanceof CMultipleAttribute) { - CMultipleAttribute cma = (CMultipleAttribute) cattribute; - if(cma.getCardinality() != null) { - out.write(" "); - printCardinality(cma.getCardinality(), out); - } - } - List children = cattribute.getChildren(); - out.write(" matches {"); - if(children == null || children.size() == 0) { - out.write("*"); - } else if (children.size() != 1 - || !(children.get(0) instanceof CPrimitiveObject)) { - newline(out); - for (CObject cobject : cattribute.getChildren()) { - printCObject(cobject, indent + 1, out); - } - indent(indent, out); - } else { - CObject child = children.get(0); - printCPrimitiveObject((CPrimitiveObject) child, out); - } - out.write("}"); - } - - protected void printExistence(CAttribute.Existence existence, Writer out) - throws IOException { - if (CAttribute.Existence.REQUIRED.equals(existence)) { - return; - } - out.write("existence matches "); - if (CAttribute.Existence.OPTIONAL.equals(existence)) { - out.write("{0..1}"); - } else { - out.write("{0}"); - } - } - - protected void printCObject(CObject cobj, int indent, Writer out) - throws IOException { - - // print specialised types - if (cobj instanceof CDomainType) { - printCDomainType((CDomainType) cobj, indent, out); - } else if (cobj instanceof CPrimitiveObject) { - printCPrimitiveObject((CPrimitiveObject) cobj, out); - } else if (cobj instanceof CComplexObject) { - printCComplexObject((CComplexObject) cobj, indent, out); - } else if (cobj instanceof ArchetypeInternalRef) { - printArchetypeInternalRef((ArchetypeInternalRef) cobj, indent, out); - } else if (cobj instanceof ArchetypeSlot) { - printArchetypeSlot((ArchetypeSlot) cobj, indent, out); - } else if (cobj instanceof ConstraintRef) { - printConstraintRef((ConstraintRef) cobj, indent, out); - } - } - - protected void printConstraintRef(ConstraintRef ref, int indent, Writer out) throws IOException { - indent(indent, out); - out.write("["); - out.write(ref.getReference()); - out.write("]"); - newline(out); - } - - protected void printCardinality(Cardinality cardinality, Writer out) - throws IOException { - out.write("cardinality matches {"); - Interval interval = cardinality.getInterval(); - if (interval != null) { - if (interval.isLowerUnbounded()) { - out.write("*"); - } else { - out.write(interval.getLower().toString()); - } - out.write(".."); - if (interval.isUpperUnbounded()) { - out.write("*"); - } else { - out.write(interval.getUpper().toString()); - } - } else { - out.write("*"); - } - out.write("; "); - if (cardinality.isOrdered()) { - out.write("ordered"); - } else { - out.write("unordered"); - } - if (cardinality.isUnique()) { - out.write("; unique"); - } - out.write("}"); - } - - protected void printCDomainType(CDomainType cdomain, int indent, Writer out) - throws IOException { - if (cdomain instanceof CDvOrdinal) { - printCDvOrdinal((CDvOrdinal) cdomain, indent, out); - } else if (cdomain instanceof CDvQuantity) { - printCDvQuantity((CDvQuantity) cdomain, indent, out); - } - else if (cdomain instanceof CCodePhrase) { - printCCodePhrase((CCodePhrase) cdomain, indent, out); - } - // unknow CDomainType - } - - protected void printCCodePhrase(CCodePhrase ccoded, int indent, Writer out) - throws IOException { - - indent(indent, out); - - if(ccoded.isAnyAllowed()) { - out.write("C_CODE_PHRASE <"); - newline(out); - indent(indent, out); - out.write(">"); - newline(out); - return; - } - - if (ccoded.getTerminologyId() != null) { - out.write("[" + ccoded.getTerminologyId().getValue() + "::"); - } - - if (ccoded.getCodeList() != null) { - if (ccoded.getCodeList().size() > 1) { - newline(out); - - for (int i = 0, j = ccoded.getCodeList().size(); i < j; i++) { - if (j > 1) { - indent(indent, out); - } - out.write(ccoded.getCodeList().get(i)); - if (i != j - 1) { - out.write(","); - } else { - if(ccoded.hasAssumedValue()) { - out.write(";"); - newline(out); - indent(indent, out); - out.write(ccoded.getAssumedValue().getCodeString()); - } - out.write("]"); - } - newline(out); - } - } else { - out.write(ccoded.getCodeList().get(0)); - if(ccoded.hasAssumedValue()) { - out.write(";" + ccoded.getAssumedValue().getCodeString()); - } - out.write("]"); - newline(out); - } - } else { - out.write("]"); - newline(out); - } - } - - protected void printCDvOrdinal(CDvOrdinal cordinal, int indent, Writer out) - throws IOException { - - // if the list is null, the CDvOrdinal is not further constrained - // (other than that it is a CDvOrdinal) - if (cordinal.isAnyAllowed()) { - indent(indent, out); - out.write("C_DV_ORDINAL <"); - newline(out); - indent(indent, out); - out.write(">"); - newline(out); - } - else { - for (Iterator it = cordinal.getList().iterator(); - it.hasNext();) { - Ordinal ordinal = it.next(); - indent(indent, out); - printOrdinal(ordinal, out); - if (it.hasNext()) { - out.write(","); - } else if(cordinal.hasAssumedValue()) { - out.write(";"); - } - newline(out); - } - if(cordinal.hasAssumedValue()) { - printOrdinal(cordinal.getAssumedValue(), out); - newline(out); - - } - } - } - - protected void printOrdinal(Ordinal ordinal, Writer out) - throws IOException { - CodePhrase symbol = ordinal.getSymbol(); - out.write(Integer.toString(ordinal.getValue())); - out.write("|["); - out.write(symbol.getTerminologyId().getValue()); - out.write("::"); - out.write(symbol.getCodeString()); - out.write("]"); - } - - protected void printCDvQuantity(CDvQuantity cquantity, int indent, - Writer out) throws IOException { - indent(indent, out); - out.write("C_DV_QUANTITY <"); - newline(out); - indent(indent + 1, out); - CodePhrase property = cquantity.getProperty(); - if (property != null) { - out.write("property = <["); - out.write(property.getTerminologyId().getValue()); - out.write("::"); - out.write(property.getCodeString()); - out.write("]>"); - } - List list = cquantity.getList(); - if (list != null) { - newline(out); - indent(indent + 1, out); - out.write("list = <"); - newline(out); - int index = 1; - for (CDvQuantityItem item : list) { - indent(indent + 2, out); - out.write("[\""); - out.write(Integer.toString(index)); - out.write("\"] = <"); - newline(out); - indent(indent + 3, out); - out.write("units = <\""); - out.write(item.getUnits()); - out.write("\">"); - newline(out); - Interval value = item.getMagnitude(); - if (value != null) { - indent(indent + 3, out); - out.write("magnitude = <"); - printInterval(value, out); - out.write(">"); - newline(out); - } - - Interval precision = item.getPrecision(); - if (precision != null) { - indent(indent + 3, out); - out.write("precision = <"); - printInterval(precision, out); - out.write(">"); - newline(out); - } - index++; - indent(indent + 2, out); - out.write(">"); - newline(out); - } - indent(indent + 1, out); - out.write(">"); - newline(out); - } - - - if(cquantity.getAssumedValue() != null) { - newline(out); - indent(indent + 1, out); - out.write("assumed_value = <"); - newline(out); - printDvQuantity(cquantity.getAssumedValue(), indent + 1, out); - indent(indent + 1, out); - out.write(">"); - newline(out); - } - - indent(indent, out); - out.write(">"); - newline(out); - } - - protected void printDvQuantity(DvQuantity quantity, int indent, Writer out) - throws IOException { - - indent(indent + 1, out); - printUnits(quantity.getUnits(), out); - newline(out); - - if(quantity.getMagnitude() != null) { - indent(indent + 1, out); - out.write("magnitude = <"); - out.write(quantity.getMagnitude().toString()); - out.write(">"); - newline(out); - } - indent(indent + 1, out); - out.write("precision = <"); - out.write(Integer.toString(quantity.getPrecision())); - out.write(">"); - newline(out); - } - - protected void printUnits(String units, Writer out) throws IOException { - out.write("units = <\""); - out.write(units); - out.write("\">"); - } - - protected void printOntology(ArchetypeOntology ontology, Writer out) - throws IOException { - - out.write("ontology"); - newline(out); - - if (ontology.getTerminologies() != null) { - indent(1, out); - out.write("terminologies_available = <"); - for (String terminology : ontology.getTerminologies()) { - out.write("\""); - out.write(terminology); - out.write("\", "); - } - out.write("...>"); - newline(out); - } - - // *** Term definition section *** (ADL 1.4 spec 8.6.3) - indent(1, out); - out.write("term_definitions = <"); - newline(out); - List termDefinitionsList = ontology.getTermDefinitionsList(); - printDefinitionList(out, termDefinitionsList); - indent(1, out); - out.write(">"); - newline(out); - - // *** Constraint definition section *** (ADL 1.4 spec 8.6.4) - List constraintDefinitionsList = ontology.getConstraintDefinitionsList(); - if (constraintDefinitionsList != null) { - indent(1, out); - out.write("constraint_definitions = <"); - newline(out); - printDefinitionList(out, constraintDefinitionsList); - indent(1, out); - out.write(">"); - newline(out); - } - - // *** Term binding section *** (ADL 1.4 spec 8.6.5) - if (ontology.getTermBindingList() != null) { - indent(1, out); - out.write("term_binding = <"); - newline(out); - for (int i = 0; i < ontology.getTermBindingList().size(); i++) { - OntologyBinding bind = ontology.getTermBindingList().get(i); - indent(2, out); - out.write("[\""); - out.write(bind.getTerminology()); - out.write("\"] = <"); - newline(out); - indent(3, out); - out.write("items = <"); - newline(out); - - for (int j = 0; j < ontology.getTermBindingList().get(i) - .getBindingList().size(); j++) { - TermBindingItem item = (TermBindingItem) ontology - .getTermBindingList().get(i).getBindingList() - .get(j); - indent(4, out); - out.write("[\""); - out.write(item.getCode()); - out.write("\"] = <"); - out.write(item.getTerms().get(0)); - - if (item.getTerms().size() > 1) { - for (int k = 1; k < item.getTerms().size(); k++) { - out.write("," + item.getTerms().get(k)); - } - } - - out.write(">"); - newline(out); - } - for (int l = 3; l > 1; l--) { - indent(l, out); - out.write(">"); - newline(out); - } - } - indent(1, out); - out.write(">"); - newline(out); - } - - // *** Constraint binding section *** (ADL 1.4 spec 8.6.6) - if (ontology.getConstraintBindingList() != null) { - indent(1, out); - out.write("constraint_binding = <"); - newline(out); - for (int i = 0; i < ontology.getConstraintBindingList().size(); i++) { - OntologyBinding bind = ontology.getConstraintBindingList().get( - i); - indent(2, out); - out.write("[\""); - out.write(bind.getTerminology()); - out.write("\"] = <"); - newline(out); - indent(3, out); - out.write("items = <"); - newline(out); - - for (int j = 0; j < ontology.getConstraintBindingList().get(i) - .getBindingList().size(); j++) { - QueryBindingItem item = (QueryBindingItem) ontology - .getConstraintBindingList().get(i).getBindingList() - .get(j); - indent(4, out); - out.write("[\""); - out.write(item.getCode()); - out.write("\"] = <"); - out.write(item.getQuery().getUrl()); - out.write(">"); - newline(out); - } - for (int l = 3; l > 1; l--) { - indent(l, out); - out.write(">"); - newline(out); - } - } - indent(1, out); - out.write(">"); - newline(out); - } - } - - private void printDefinitionList(Writer out, - List termDefinitionsList) throws IOException { - for (OntologyDefinitions defs : termDefinitionsList) { - indent(2, out); - out.write("[\""); - out.write(defs.getLanguage()); - out.write("\"] = <"); - newline(out); - indent(3, out); - out.write("items = <"); - newline(out); - for (ArchetypeTerm term : defs.getDefinitions()) { - indent(4, out); - out.write("[\""); - out.write(term.getCode()); - out.write("\"] = <"); - newline(out); - for (Map.Entry entry : term.getItems().entrySet()) { - indent(5, out); - out.write(entry.getKey()); - out.write(" = <\""); - out.write(entry.getValue()); - out.write("\">"); - newline(out); - } - newline(out); - indent(4, out); - out.write(">"); - newline(out); - } - for (int i = 3; i > 1; i--) { - indent(i, out); - out.write(">"); - newline(out); - } - } - } - - protected void printCPrimitiveObject(CPrimitiveObject cpo, Writer out) - throws IOException { - - CPrimitive cp = cpo.getItem(); - if (cp instanceof CBoolean) { - printCBoolean((CBoolean) cp, out); - } else if (cp instanceof CDate) { - printCDate((CDate) cp, out); - } else if (cp instanceof CDateTime) { - printCDateTime((CDateTime) cp, out); - } else if (cp instanceof CTime) { - printCTime((CTime) cp, out); - } else if (cp instanceof CDuration) { - printCDuration((CDuration) cp, out); - } else if (cp instanceof CInteger) { - printCInteger((CInteger) cp, out); - } else if (cp instanceof CReal) { - printCReal((CReal) cp, out); - } else if (cp instanceof CString) { - printCString((CString) cp, out); - } - // unknow CPrimitive type - } - - protected void printCBoolean(CBoolean cboolean, Writer out) - throws IOException { - if (cboolean.isTrueValid()) { - out.write("true"); - if (cboolean.isFalseValid()) { - out.write(", false"); - } - } else { - out.write("false"); - } - if(cboolean.hasAssumedValue()) { - out.write("; "); - if(cboolean.assumedValue().booleanValue()) { - out.write("true"); - } else { - out.write("false"); - } - } - } - - protected void printCDate(CDate cdate, Writer out) throws IOException { - if (cdate.getPattern() != null) { - out.write(cdate.getPattern()); - } else if (cdate.getList() != null) { - out.write(cdate.getList().get(0).toString()); - } else { - printInterval(cdate.getInterval(), out); - } - if(cdate.hasAssumedValue()) { - out.write("; "); - out.write(cdate.assumedValue().toString()); - } - } - - protected void printCDateTime(CDateTime cdatetime, Writer out) - throws IOException { - if (cdatetime.getPattern() != null) { - out.write(cdatetime.getPattern()); - } else if (cdatetime.getList() != null) { - out.write(cdatetime.getList().get(0).toString()); - } else { - printInterval(cdatetime.getInterval(), out); - } - if(cdatetime.hasAssumedValue()) { - out.write("; "); - out.write(cdatetime.assumedValue().toString()); - } - } - - protected void printCTime(CTime ctime, Writer out) throws IOException { - if (ctime.getPattern() != null) { - out.write(ctime.getPattern()); - } else if (ctime.getList() != null) { - out.write(ctime.getList().get(0).toString()); - } else { - printInterval(ctime.getInterval(), out); - } - if(ctime.hasAssumedValue()) { - out.write("; "); - out.write(ctime.assumedValue().toString()); - } - } - - protected void printCDuration(CDuration cduration, Writer out) - throws IOException { - if (cduration.getValue() != null) { - out.write(cduration.getValue().toString()); - } else if(cduration.getPattern() != null) { - out.write(cduration.getPattern()); - } else { - printInterval(cduration.getInterval(), out); - } - if(cduration.assumedValue() != null) { - out.write("; "); - out.write(cduration.assumedValue().toString()); - } - } - - protected void printCInteger(CInteger cinteger, Writer out) - throws IOException { - if (cinteger.getList() != null) { - printList(cinteger.getList(), out); - } else { - printInterval(cinteger.getInterval(), out); - } - if(cinteger.assumedValue() != null) { - out.write("; "); - out.write(cinteger.assumedValue().toString()); - } - } - - protected void printCReal(CReal creal, Writer out) throws IOException { - if (creal.getList() != null) { - printList(creal.getList(), out); - } else { - printInterval(creal.getInterval(), out); - } - if(creal.assumedValue() != null) { - out.write("; "); - out.write(creal.assumedValue().toString()); - } - } - - protected void printCString(CString cstring, Writer out) throws IOException { - if (cstring.getPattern() != null) { - out.write("/" + cstring.getPattern() + "/"); - } else if(cstring.getList() != null){ - printList(cstring.getList(), out, true); - } else if(cstring.defaultValue() != null) { - out.write("\""); - out.write(cstring.defaultValue()); - out.write("\""); - } - if(cstring.hasAssumedValue()) { - out.write("; "); - out.write("\"" + cstring.assumedValue() + "\""); - } - } - - protected void printList(List list, Writer out) throws IOException { - printList(list, out, false); - } - - protected void printList(List list, Writer out, boolean string) - throws IOException { - for (int i = 0, j = list.size(); i < j; i++) { - if (i != 0) { - out.write(","); - } - if (string) { - out.write("\""); - } - out.write(list.get(i).toString()); - if (string) { - out.write("\""); - } - } - } - - protected void printInterval(Interval interval, Writer out) - throws IOException { - out.write("|"); - if (interval.getLower() != null && interval.getUpper() != null) { - if(interval.getLower().equals(interval.getUpper()) - && interval.isLowerIncluded() - && interval.isUpperIncluded()) { - out.write(interval.getLower().toString()); - } else { - out.write(interval.getLower().toString()); - out.write(".."); - out.write(interval.getUpper().toString()); - } - } else if (interval.getLower() == null) { - out.write("<"); - if (interval.isUpperIncluded()) { - out.write("="); - } - out.write(interval.getUpper().toString()); - } else { - out.write(">"); - if (interval.isLowerIncluded()) { - out.write("="); - } - out.write(interval.getLower().toString()); - } - out.write("|"); - } - - private void newline(Writer out) throws IOException { - out.write(lineSeparator); - } - - private void indent(int level, Writer out) throws IOException { - for (int i = 0; i < level; i++) { - out.write(indent); - } - } - - /* charset encodings */ - public static final Charset UTF8 = Charset.forName("UTF-8"); - public static final Charset LATIN1 = Charset.forName("ISO-8859-1"); - - /* fields */ - private Charset encoding; - private String lineSeparator; - private String indent; -} -/* - * ***** BEGIN LICENSE BLOCK ***** Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the 'License'); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an 'AS IS' basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for - * the specific language governing rights and limitations under the License. - * - * The Original Code is ADLSerializer.java - * - * The Initial Developer of the Original Code is Rong Chen. Portions created by - * the Initial Developer are Copyright (C) 2004-2007 the Initial Developer. All - * Rights Reserved. - * - * Contributor(s): Mattias Forss, Johan Hjalmarsson, Erik Sundvall, - * Sebastian Garde - * - * Software distributed under the License is distributed on an 'AS IS' basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for - * the specific language governing rights and limitations under the License. - * - * ***** END LICENSE BLOCK ***** - */ +/* + * component: "openEHR Reference Implementation" + * description: "Class ADLSerializer" + * keywords: "archetype" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004,2005,2006 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL: $" + * revision: "$LastChangedRevision: 41 $" + * last_change: "$LastChangedDate: 2006-07-12 23:24:42 +0200 (Wed, 12 Jul 2006) $" + */ +package org.openehr.am.serialize; + +import java.io.BufferedOutputStream; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.nio.charset.Charset; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.ObjectUtils; +import org.apache.commons.lang.StringUtils; +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.assertion.Assertion; +import org.openehr.am.archetype.constraintmodel.ArchetypeInternalRef; +import org.openehr.am.archetype.constraintmodel.ArchetypeSlot; +import org.openehr.am.archetype.constraintmodel.CAttribute; +import org.openehr.am.archetype.constraintmodel.CComplexObject; +import org.openehr.am.archetype.constraintmodel.CDomainType; +import org.openehr.am.archetype.constraintmodel.CMultipleAttribute; +import org.openehr.am.archetype.constraintmodel.CObject; +import org.openehr.am.archetype.constraintmodel.CPrimitiveObject; +import org.openehr.am.archetype.constraintmodel.Cardinality; +import org.openehr.am.archetype.constraintmodel.ConstraintRef; +import org.openehr.am.archetype.constraintmodel.primitive.CBoolean; +import org.openehr.am.archetype.constraintmodel.primitive.CDate; +import org.openehr.am.archetype.constraintmodel.primitive.CDateTime; +import org.openehr.am.archetype.constraintmodel.primitive.CDuration; +import org.openehr.am.archetype.constraintmodel.primitive.CInteger; +import org.openehr.am.archetype.constraintmodel.primitive.CPrimitive; +import org.openehr.am.archetype.constraintmodel.primitive.CReal; +import org.openehr.am.archetype.constraintmodel.primitive.CString; +import org.openehr.am.archetype.constraintmodel.primitive.CTime; +import org.openehr.am.archetype.ontology.ArchetypeOntology; +import org.openehr.am.archetype.ontology.ArchetypeTerm; +import org.openehr.am.archetype.ontology.OntologyBinding; +import org.openehr.am.archetype.ontology.OntologyDefinitions; +import org.openehr.am.archetype.ontology.QueryBindingItem; +import org.openehr.am.archetype.ontology.TermBindingItem; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvOrdinal; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantity; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantityItem; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvScale; +import org.openehr.am.openehrprofile.datatypes.quantity.Ordinal; +import org.openehr.am.openehrprofile.datatypes.quantity.Scale; +import org.openehr.am.openehrprofile.datatypes.text.CCodePhrase; +import org.openehr.rm.common.resource.AuthoredResource; +import org.openehr.rm.common.resource.ResourceDescription; +import org.openehr.rm.common.resource.ResourceDescriptionItem; +import org.openehr.rm.common.resource.TranslationDetails; +import org.openehr.rm.datatypes.quantity.DvQuantity; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.basic.Interval; +import org.openehr.rm.support.identification.ArchetypeID; +import org.openehr.rm.support.identification.ObjectID; + +/** + * ADL serializer for the openEHR Java kernel + * + * @author Rong Chen + * @author Mattias Forss, Johan Hjalmarsson + * @author Sebastian Garde + * + * @version 1.0 + */ +public class ADLSerializer { + + /** + * Create an outputter with default encoding, indent and lineSeparator + */ + public ADLSerializer() { + this.encoding = UTF8; + this.indent = " "; // 4 white space characters + this.lineSeparator = "\r\n"; + } + + /** + * Output given archetype as string in ADL format + * + * @param archetype + * @return a string in ADL format + * @throws IOException + */ + public String output(Archetype archetype) throws IOException { + StringWriter writer = new StringWriter(); + output(archetype, writer); + return writer.toString(); + } + + /** + * Output archetype DEFINITION as string in ADL format + * + * @param archetype + * @return a string in ADL format + * @throws IOException + */ + public String outputDefinitionOnly(Archetype archetype) throws IOException { + StringWriter writer = new StringWriter(); + + printDefinition(archetype.getDefinition(), writer); + + return writer.toString(); + } + + /** + * Output given archetype to outputStream + * + * @param archetype + * @param out + * @throws IOException + */ + public void output(Archetype archetype, OutputStream out) + throws IOException { + Writer writer = new BufferedWriter(new OutputStreamWriter( + new BufferedOutputStream(out), encoding)); + output(archetype, writer); + } + + /** + * Output given archetype to writer + * + * @param archetype + * @param out + * @throws IOException + */ + public void output(Archetype archetype, Writer out) throws IOException { + printHeader(archetype.getAdlVersion(), archetype.getArchetypeId(), + archetype.getParentArchetypeId(), archetype.getUid(), archetype.getConcept(), out); + newline(out); + + printLanguage(archetype, out); + newline(out); + + if(archetype.getDescription() != null) { + printDescription(archetype.getDescription(), out); + newline(out); + } + + printDefinition(archetype.getDefinition(), out); + newline(out); + + printOntology(archetype.getOntology(), out); + out.flush(); + out.close(); + } + + protected void printHeader(String adlVersion, + ArchetypeID id, ArchetypeID parentId, ObjectID uid, + String conceptCode, Writer out) throws IOException { + + out.write("archetype"); + if(StringUtils.isNotEmpty(adlVersion) || (uid != null && StringUtils.isNotEmpty(uid.toString()))) { + out.write(" ("); + } + + if(StringUtils.isNotEmpty(adlVersion)) { + out.write("adl_version="); + out.write(adlVersion); + } + if(uid != null && StringUtils.isNotEmpty(uid.toString())) { + if (StringUtils.isNotEmpty(adlVersion)) { + out.write("; "); + } + out.write("uid="); + out.write(uid.toString()); + } + if(StringUtils.isNotEmpty(adlVersion) || (uid!=null &&StringUtils.isNotEmpty(uid.toString()))) { + out.write(")"); + } + newline(out); + indent(1, out); + out.write(id.toString()); + newline(out); + + if (parentId != null) { + out.write("specialize"); + newline(out); + indent(1, out); + out.write(parentId.toString()); + newline(out); + } + + newline(out); + out.write("concept"); + newline(out); + indent(1, out); + out.write("[" + conceptCode + "]"); + newline(out); + } + + protected void printLanguage(AuthoredResource authored, + Writer out) throws IOException { + + out.write("language"); + newline(out); + indent(1, out); + out.write("original_language = <"); + out.write("["); + out.write(authored.getOriginalLanguage().getTerminologyId().getValue()); + out.write("::"); + out.write(authored.getOriginalLanguage().getCodeString()); + out.write("]"); + out.write(">"); + newline(out); + if(authored.getTranslations() != null) { + indent(1, out); + out.write("translations = <"); + newline(out); + Map translations = + authored.getTranslations(); + for(String lang : translations.keySet()) { + TranslationDetails td = translations.get(lang); + + indent(2, out); + out.write("["); + out.write(quoteString(lang)); + out.write("] = <"); + newline(out); + + indent(3, out); + out.write("language = <"); + out.write("["); + out.write(td.getLanguage().getTerminologyId().getValue()); + out.write("::"); + out.write(td.getLanguage().getCodeString()); + out.write("]"); + out.write(">"); + newline(out); + + indent(3, out); + out.write("author = <"); + newline(out); + printMap(td.getAuthor(), out, 4); + indent(3, out); + out.write(">"); + newline(out); + + if(td.getAccreditation() != null) { + indent(3, out); + out.write("accreditation = <"); + out.write(quoteString(td.getAccreditation())); + out.write(">"); + newline(out); + } + + if(td.getOtherDetails() != null) { + indent(3, out); + out.write("other_details = <"); + newline(out); + printMap(td.getOtherDetails(), out, 4); + indent(3, out); + out.write(">"); + newline(out); + } + + indent(2, out); + out.write(">"); + newline(out); + } + indent(1, out); + out.write(">"); + newline(out); + } + } + + protected void printMap(Map map, Writer out, int indent) + throws IOException { + if(map == null || map.size() == 0) { + return; + } + for(String key : map.keySet()) { + indent(indent, out); + out.write("["); + out.write(quoteString(key)); + out.write("] = <"); + out.write(quoteString(map.get(key))); + out.write(">"); + newline(out); + } + } + + protected void printDescription(ResourceDescription description, Writer out) + throws IOException { + + if (description == null) { + return; + } + + out.write("description"); + newline(out); + + indent(1, out); + out.write("original_author = <"); + newline(out); + Map map = description.getOriginalAuthor(); + for (String key : map.keySet()) { + indent(2, out); + out.write("[" + quoteString(key) + "] = <" + quoteString(map.get(key)) + ">"); + newline(out); + } + indent(1, out); + out.write(">"); + newline(out); + + indent(1, out); + out.write("lifecycle_state = <"); + out.write(quoteString(description.getLifecycleState())); + out.write(">"); + newline(out); + + printNonEmptyString("resource_package_uri", description.getResourcePackageUri(), 1, out); + + indent(1, out); + out.write("details = <"); + newline(out); + for (ResourceDescriptionItem item : description.getDetails().values()) { + printDescriptionItem(item, 2, out); + } + indent(1, out); + out.write(">"); + newline(out); + } + + protected void printDescriptionItem(ResourceDescriptionItem item, + int indent, Writer out) throws IOException { + indent(indent, out); + out.write("["); + out.write(quoteString(item.getLanguage().getCodeString())); + out.write("] = <"); + newline(out); + + indent(indent + 1, out); + out.write("language = <"); + out.write("["); + out.write(item.getLanguage().getTerminologyId().getValue()); + out.write("::"); + out.write(item.getLanguage().getCodeString()); + out.write("]>"); + newline(out); + + printNonEmptyString("purpose", item.getPurpose(), indent + 1, out); + printNonEmptyStringList("keywords", item.getKeywords(), indent + 1, + out); + printNonEmptyString("copyright", item.getCopyright(), indent + 1, out); + printNonEmptyString("use", item.getUse(), indent + 1, out); + printNonEmptyString("misuse", item.getMisuse(), indent + 1, out); + printNonEmptyStringMap("original_resource_uri", item.getOriginalResourceUri(), indent + 1, out); + + // other details not printed + + indent(indent, out); + out.write(">"); + newline(out); + } + + private void printNonEmptyString(String label, String value, int indent, + Writer out) throws IOException { + + if (StringUtils.isEmpty(value)) { + return; + } + indent(indent, out); + out.write(label); + out.write(" = <"); + out.write(quoteString(value)); + out.write(">"); + newline(out); + } + + private void printNonEmptyStringList(String label, List list, + int indent, Writer out) throws IOException { + + if (list == null || list.isEmpty()) { + return; + } + indent(indent, out); + out.write(label); + out.write(" = <"); + for (int i = 0, j = list.size(); i < j; i++) { + out.write(quoteString(list.get(i))); + if (i != j - 1) { + out.write(","); + } + } + out.write(">"); + newline(out); + } + + private void printNonEmptyStringMap(String label, Map map, + int indent, Writer out) throws IOException { + if (map == null || map.isEmpty()) { + return; + } + + indent(indent, out); + out.write(label); + out.write(" = <"); + newline(out); + + for (String key : map.keySet()) { + indent(2, out); + out.write("[" + quoteString(key) + "] = <" + quoteString(map.get(key)) + ">"); + newline(out); + } + + indent(indent, out); + out.write(">"); + newline(out); + } + + protected void printDefinition(CComplexObject definition, Writer out) + throws IOException { + + out.write("definition"); + newline(out); + + printCComplexObject(definition, 1, out); + } + + protected void printCComplexObject(CComplexObject ccobj, int indent, + Writer out) throws IOException { + + // TODO skip c_obj with [0,0] occurrences + Interval occurrences = ccobj.getOccurrences(); + if(occurrences != null + && (Integer.valueOf(0).equals(occurrences.getLower())) + && (Integer.valueOf(0).equals(occurrences.getUpper()))) { + return; + } + + + // print rmTypeName and nodeId + indent(indent, out); + out.write(ccobj.getRmTypeName()); + if (StringUtils.isNotEmpty(ccobj.getNodeId())) { + out.write("[" + ccobj.getNodeId() + "]"); + } + + printOccurrences(ccobj.getOccurrences(), out); + + out.write(" matches {"); + + // print all attributes + if (!ccobj.isAnyAllowed()) { + for (CAttribute cattribute : ccobj.getAttributes()) { + printCAttribute(cattribute, indent + 1, out); + } + newline(out); + indent(indent, out); + } else { + out.write("*"); + } + out.write("}"); + newline(out); + } + + protected void printOccurrences(Interval occurrences, Writer out) + throws IOException { + + Interval defaultOccurrences = new Interval(1, 1); + if(occurrences == null || defaultOccurrences.equals(occurrences)) { + return; + } + if (occurrences != null) { + out.write(" occurrences matches {"); + if (occurrences.getLower() == null) { + out.write("*"); + } else { + out.write(Integer.toString(occurrences.getLower())); + } + out.write(".."); + if (occurrences.getUpper() == null) { + out.write("*"); + } else { + out.write(Integer.toString(occurrences.getUpper())); + } + out.write("}"); + } + } + + protected void printArchetypeInternalRef(ArchetypeInternalRef ref, + int indent, Writer out) throws IOException { + indent(indent, out); + out.write("use_node "); + out.write(ref.getRmTypeName()); + printOccurrences(ref.getOccurrences(), out); + out.write(" "); + out.write(ref.getTargetPath()); + newline(out); + } + + protected void printArchetypeSlot(ArchetypeSlot slot, int indent, Writer out) + throws IOException { + + indent(indent, out); + out.write("allow_archetype "); + out.write(slot.getRmTypeName()); + if (StringUtils.isNotEmpty(slot.getNodeId())) { + out.write("[" + slot.getNodeId() + "]"); + } + + printOccurrences(slot.getOccurrences(), out); + out.write(" matches {"); + + if (slot.isAnyAllowed()) { + out.write("*}"); + } else { + if (slot.getIncludes() != null) { + printAssertions(slot.getIncludes(), "include", indent, out); + } + if (slot.getExcludes() != null) { + printAssertions(slot.getExcludes(), "exclude", indent, out); + } + newline(out); + indent(indent, out); + out.write("}"); + } + newline(out); + } + + private void printAssertions(Set assertions, String purpose, + int indent, Writer out) throws IOException { + + if(assertions == null) { + return; + } + + newline(out); + indent(indent + 1, out); + out.write(purpose); + + for (Assertion assertion : assertions) { + + if(assertion.getStringExpression() == null) { + continue; + } + + newline(out); + indent(indent + 2, out); + + // FIXME: The string expression is null when an archetype is parsed, but after the archetype is recreated in the archetype + // editor, the string expression exists. Please provide a valid string expression from the parser since it's _much_ easier to + // maintain this line of code instead of adding hundreds of lines just to output some expressions, operators etc. + // Opening an archetype directly in the ADL format view will show the output of the parsed archetype in this way: + // + // include + // null + out.write(assertion.getStringExpression()); + } + } + + protected void printCAttribute(CAttribute cattribute, int indent, Writer out) + throws IOException { + newline(out); + indent(indent, out); + out.write(cattribute.getRmAttributeName()); + if (!CAttribute.Existence.REQUIRED.equals(cattribute.getExistence())) { + out.write(" "); + } + printExistence(cattribute.getExistence(), out); + if (cattribute instanceof CMultipleAttribute) { + CMultipleAttribute cma = (CMultipleAttribute) cattribute; + if(cma.getCardinality() != null) { + out.write(" "); + printCardinality(cma.getCardinality(), out); + } + } + List children = cattribute.getChildren(); + out.write(" matches {"); + if(children == null || children.size() == 0) { + out.write("*"); + } else if (children.size() != 1 + || !(children.get(0) instanceof CPrimitiveObject)) { + newline(out); + for (CObject cobject : cattribute.getChildren()) { + printCObject(cobject, indent + 1, out); + } + indent(indent, out); + } else { + CObject child = children.get(0); + printCPrimitiveObject((CPrimitiveObject) child, out); + } + out.write("}"); + } + + protected void printExistence(CAttribute.Existence existence, Writer out) + throws IOException { + if (CAttribute.Existence.REQUIRED.equals(existence)) { + return; + } + out.write("existence matches "); + if (CAttribute.Existence.OPTIONAL.equals(existence)) { + out.write("{0..1}"); + } else { + out.write("{0}"); + } + } + + protected void printCObject(CObject cobj, int indent, Writer out) + throws IOException { + + // print specialised types + if (cobj instanceof CDomainType) { + printCDomainType((CDomainType) cobj, indent, out); + } else if (cobj instanceof CPrimitiveObject) { + printCPrimitiveObject((CPrimitiveObject) cobj, out); + } else if (cobj instanceof CComplexObject) { + printCComplexObject((CComplexObject) cobj, indent, out); + } else if (cobj instanceof ArchetypeInternalRef) { + printArchetypeInternalRef((ArchetypeInternalRef) cobj, indent, out); + } else if (cobj instanceof ArchetypeSlot) { + printArchetypeSlot((ArchetypeSlot) cobj, indent, out); + } else if (cobj instanceof ConstraintRef) { + printConstraintRef((ConstraintRef) cobj, indent, out); + } + } + + protected void printConstraintRef(ConstraintRef ref, int indent, Writer out) throws IOException { + indent(indent, out); + out.write("["); + out.write(ref.getReference()); + out.write("]"); + newline(out); + } + + protected void printCardinality(Cardinality cardinality, Writer out) + throws IOException { + out.write("cardinality matches {"); + Interval interval = cardinality.getInterval(); + if (interval != null) { + if (interval.isLowerUnbounded()) { + out.write("*"); + } else { + out.write(interval.getLower().toString()); + } + out.write(".."); + if (interval.isUpperUnbounded()) { + out.write("*"); + } else { + out.write(interval.getUpper().toString()); + } + } else { + out.write("*"); + } + out.write("; "); + if (cardinality.isOrdered()) { + out.write("ordered"); + } else { + out.write("unordered"); + } + if (cardinality.isUnique()) { + out.write("; unique"); + } + out.write("}"); + } + + protected void printCDomainType(CDomainType cdomain, int indent, Writer out) + throws IOException { + if (cdomain instanceof CDvOrdinal) { + printCDvOrdinal((CDvOrdinal) cdomain, indent, out); + } else if (cdomain instanceof CDvScale) { + printCDvScale((CDvScale) cdomain, indent, out); + } else if (cdomain instanceof CDvQuantity) { + printCDvQuantity((CDvQuantity) cdomain, indent, out); + } + else if (cdomain instanceof CCodePhrase) { + printCCodePhrase((CCodePhrase) cdomain, indent, out); + } + // unknow CDomainType + } + + protected void printCCodePhrase(CCodePhrase ccoded, int indent, Writer out) + throws IOException { + + indent(indent, out); + + if(ccoded.isAnyAllowed()) { + out.write("C_CODE_PHRASE <"); + newline(out); + indent(indent, out); + out.write(">"); + newline(out); + return; + } + + if (ccoded.getTerminologyId() != null) { + out.write("[" + ccoded.getTerminologyId().getValue() + "::"); + } + + if (ccoded.getCodeList() != null) { + if (ccoded.getCodeList().size() > 1) { + newline(out); + + for (int i = 0, j = ccoded.getCodeList().size(); i < j; i++) { + if (j > 1) { + indent(indent, out); + } + out.write(ccoded.getCodeList().get(i)); + if (i != j - 1) { + out.write(","); + } else { + if(ccoded.hasAssumedValue()) { + out.write(";"); + newline(out); + indent(indent, out); + out.write(ccoded.getAssumedValue().getCodeString()); + } + out.write("]"); + } + newline(out); + } + } else { + out.write(ccoded.getCodeList().get(0)); + if(ccoded.hasAssumedValue()) { + out.write(";" + ccoded.getAssumedValue().getCodeString()); + } + out.write("]"); + newline(out); + } + } else { + out.write("]"); + newline(out); + } + } + + protected void printCDvScale(CDvScale cscale, int indent, Writer out) + throws IOException { + + // if the list is null, the CDvScale is not further constrained + // (other than that it is a CDvScale) + // NB: We currently have NOT enabled this (an unconstrained C_DV_ORDINAL) in the parser. + // It is easy to do, but really, a normal DVScale should be used instead. + if (cscale.isAnyAllowed()) { + indent(indent, out); + out.write("C_DV_ORDINAL <"); + newline(out); + indent(indent, out); + out.write(">"); + newline(out); + } + else { + for (Iterator it = cscale.getList().iterator(); + it.hasNext();) { + Scale ordinal = it.next(); + indent(indent, out); + printScale(ordinal, out); + if (it.hasNext()) { + out.write(","); + } else if (cscale.hasAssumedValue()) { + out.write(";"); + } + newline(out); + } + if (cscale.hasAssumedValue()) { + printScale(cscale.getAssumedValue(), out); + newline(out); + } + } + } + + protected void printScale(Scale scale, Writer out) + throws IOException { + CodePhrase symbol = scale.getSymbol(); + out.write(scale.getDisplay()); + out.write("|["); + out.write(symbol.getTerminologyId().getValue()); + out.write("::"); + out.write(symbol.getCodeString()); + out.write("]"); + } + + protected void printCDvOrdinal(CDvOrdinal cordinal, int indent, Writer out) throws IOException { + + // if the list is null, the CDvOrdinal is not further constrained + // (other than that it is a CDvOrdinal) + if (cordinal.isAnyAllowed()) { + indent(indent, out); + out.write("C_DV_ORDINAL <"); + newline(out); + indent(indent, out); + out.write(">"); + newline(out); + } else { + for (Iterator it = cordinal.getList().iterator(); it.hasNext();) { + Ordinal ordinal = it.next(); + indent(indent, out); + printOrdinal(ordinal, out); + if (it.hasNext()) { + out.write(","); + } else if (cordinal.hasAssumedValue()) { + out.write(";"); + } + newline(out); + } + if (cordinal.hasAssumedValue()) { + printOrdinal(cordinal.getAssumedValue(), out); + newline(out); + + } + } + } + + protected void printOrdinal(Ordinal ordinal, Writer out) throws IOException { + CodePhrase symbol = ordinal.getSymbol(); + out.write(Integer.toString(ordinal.getValue())); + out.write("|["); + out.write(symbol.getTerminologyId().getValue()); + out.write("::"); + out.write(symbol.getCodeString()); + out.write("]"); + } + + protected void printCDvQuantity(CDvQuantity cquantity, int indent, + Writer out) throws IOException { + indent(indent, out); + out.write("C_DV_QUANTITY <"); + newline(out); + indent(indent + 1, out); + CodePhrase property = cquantity.getProperty(); + if (property != null) { + out.write("property = <["); + out.write(property.getTerminologyId().getValue()); + out.write("::"); + out.write(property.getCodeString()); + out.write("]>"); + } + List list = cquantity.getList(); + if (list != null) { + newline(out); + indent(indent + 1, out); + out.write("list = <"); + newline(out); + int index = 1; + for (CDvQuantityItem item : list) { + indent(indent + 2, out); + out.write("["); + out.write(quoteString(Integer.toString(index))); + out.write("] = <"); + newline(out); + indent(indent + 3, out); + out.write("units = <"); + out.write(quoteString(item.getUnits())); + out.write(">"); + newline(out); + Interval value = item.getMagnitude(); + if (value != null) { + indent(indent + 3, out); + out.write("magnitude = <"); + printInterval(value, out); + out.write(">"); + newline(out); + } + + Interval precision = item.getPrecision(); + if (precision != null) { + indent(indent + 3, out); + out.write("precision = <"); + printInterval(precision, out); + out.write(">"); + newline(out); + } + index++; + indent(indent + 2, out); + out.write(">"); + newline(out); + } + indent(indent + 1, out); + out.write(">"); + newline(out); + } + + + if(cquantity.getAssumedValue() != null) { + newline(out); + indent(indent + 1, out); + out.write("assumed_value = <"); + newline(out); + printDvQuantity(cquantity.getAssumedValue(), indent + 1, out); + indent(indent + 1, out); + out.write(">"); + newline(out); + } + + indent(indent, out); + out.write(">"); + newline(out); + } + + protected void printDvQuantity(DvQuantity quantity, int indent, Writer out) + throws IOException { + + indent(indent + 1, out); + printUnits(quantity.getUnits(), out); + newline(out); + + if(quantity.getMagnitude() != null) { + indent(indent + 1, out); + out.write("magnitude = <"); + out.write(quantity.getMagnitude().toString()); + out.write(">"); + newline(out); + } + indent(indent + 1, out); + out.write("precision = <"); + out.write(Integer.toString(quantity.getPrecision())); + out.write(">"); + newline(out); + } + + protected void printUnits(String units, Writer out) throws IOException { + out.write("units = <"); + out.write(quoteString(units)); + out.write(">"); + } + + protected void printOntology(ArchetypeOntology ontology, Writer out) + throws IOException { + + out.write("ontology"); + newline(out); + + if (ontology.getTerminologies() != null) { + indent(1, out); + out.write("terminologies_available = <"); + for (String terminology : ontology.getTerminologies()) { + out.write(quoteString(terminology)); + out.write(", "); + } + out.write("...>"); + newline(out); + } + + // *** Term definition section *** (ADL 1.4 spec 8.6.3) + indent(1, out); + out.write("term_definitions = <"); + newline(out); + List termDefinitionsList = ontology.getTermDefinitionsList(); + printDefinitionList(out, termDefinitionsList); + indent(1, out); + out.write(">"); + newline(out); + + // *** Constraint definition section *** (ADL 1.4 spec 8.6.4) + List constraintDefinitionsList = ontology.getConstraintDefinitionsList(); + if (constraintDefinitionsList != null) { + indent(1, out); + out.write("constraint_definitions = <"); + newline(out); + printDefinitionList(out, constraintDefinitionsList); + indent(1, out); + out.write(">"); + newline(out); + } + + // *** Term binding section *** (ADL 1.4 spec 8.6.5) + if (ontology.getTermBindingList() != null) { + indent(1, out); + out.write("term_binding = <"); + newline(out); + for (int i = 0; i < ontology.getTermBindingList().size(); i++) { + OntologyBinding bind = ontology.getTermBindingList().get(i); + indent(2, out); + out.write("["); + out.write(quoteString(bind.getTerminology())); + out.write("] = <"); + newline(out); + indent(3, out); + out.write("items = <"); + newline(out); + + for (int j = 0; j < ontology.getTermBindingList().get(i) + .getBindingList().size(); j++) { + TermBindingItem item = (TermBindingItem) ontology + .getTermBindingList().get(i).getBindingList() + .get(j); + indent(4, out); + out.write("["); + out.write(quoteString(item.getCode())); + out.write("] = <"); + out.write(item.getTerms().get(0)); + + if (item.getTerms().size() > 1) { + for (int k = 1; k < item.getTerms().size(); k++) { + out.write("," + item.getTerms().get(k)); + } + } + + out.write(">"); + newline(out); + } + for (int l = 3; l > 1; l--) { + indent(l, out); + out.write(">"); + newline(out); + } + } + indent(1, out); + out.write(">"); + newline(out); + } + + // *** Constraint binding section *** (ADL 1.4 spec 8.6.6) + if (ontology.getConstraintBindingList() != null) { + indent(1, out); + out.write("constraint_binding = <"); + newline(out); + for (int i = 0; i < ontology.getConstraintBindingList().size(); i++) { + OntologyBinding bind = ontology.getConstraintBindingList().get( + i); + indent(2, out); + out.write("["); + out.write(quoteString(bind.getTerminology())); + out.write("] = <"); + newline(out); + indent(3, out); + out.write("items = <"); + newline(out); + + for (int j = 0; j < ontology.getConstraintBindingList().get(i) + .getBindingList().size(); j++) { + QueryBindingItem item = (QueryBindingItem) ontology + .getConstraintBindingList().get(i).getBindingList() + .get(j); + indent(4, out); + out.write("["); + out.write(quoteString(item.getCode())); + out.write("] = <"); + out.write(item.getQuery().getUrl()); + out.write(">"); + newline(out); + } + for (int l = 3; l > 1; l--) { + indent(l, out); + out.write(">"); + newline(out); + } + } + indent(1, out); + out.write(">"); + newline(out); + } + } + + private String quoteString(String value) { + return "\"" + value.replaceAll("[\"]", "\\\\$0") + "\""; + } + + private void printDefinitionList(Writer out, + List termDefinitionsList) throws IOException { + for (OntologyDefinitions defs : termDefinitionsList) { + indent(2, out); + out.write("["); + out.write(quoteString(defs.getLanguage())); + out.write("] = <"); + newline(out); + indent(3, out); + out.write("items = <"); + newline(out); + for (ArchetypeTerm term : defs.getDefinitions()) { + indent(4, out); + out.write("["); + out.write(quoteString(term.getCode())); + out.write("] = <"); + newline(out); + for (Map.Entry entry : term.getItems().entrySet()) { + indent(5, out); + out.write(entry.getKey()); + out.write(" = <"); + out.write(quoteString(entry.getValue())); + out.write(">"); + newline(out); + } + newline(out); + indent(4, out); + out.write(">"); + newline(out); + } + for (int i = 3; i > 1; i--) { + indent(i, out); + out.write(">"); + newline(out); + } + } + } + + protected void printCPrimitiveObject(CPrimitiveObject cpo, Writer out) + throws IOException { + + CPrimitive cp = cpo.getItem(); + if (cp instanceof CBoolean) { + printCBoolean((CBoolean) cp, out); + } else if (cp instanceof CDate) { + printCDate((CDate) cp, out); + } else if (cp instanceof CDateTime) { + printCDateTime((CDateTime) cp, out); + } else if (cp instanceof CTime) { + printCTime((CTime) cp, out); + } else if (cp instanceof CDuration) { + printCDuration((CDuration) cp, out); + } else if (cp instanceof CInteger) { + printCInteger((CInteger) cp, out); + } else if (cp instanceof CReal) { + printCReal((CReal) cp, out); + } else if (cp instanceof CString) { + printCString((CString) cp, out); + } + // unknow CPrimitive type + } + + protected void printCBoolean(CBoolean cboolean, Writer out) + throws IOException { + if (cboolean.isTrueValid()) { + out.write("true"); + if (cboolean.isFalseValid()) { + out.write(", false"); + } + } else { + out.write("false"); + } + if(cboolean.hasAssumedValue()) { + out.write("; "); + if(cboolean.assumedValue().booleanValue()) { + out.write("true"); + } else { + out.write("false"); + } + } + } + + protected void printCDate(CDate cdate, Writer out) throws IOException { + if (cdate.getPattern() != null) { + out.write(cdate.getPattern()); + } else if (cdate.getList() != null) { + out.write(cdate.getList().get(0).toString()); + } else { + printInterval(cdate.getInterval(), out); + } + if(cdate.hasAssumedValue()) { + out.write("; "); + out.write(cdate.assumedValue().toString()); + } + } + + protected void printCDateTime(CDateTime cdatetime, Writer out) + throws IOException { + if (cdatetime.getPattern() != null) { + out.write(cdatetime.getPattern()); + } else if (cdatetime.getList() != null) { + out.write(cdatetime.getList().get(0).toString()); + } else { + printInterval(cdatetime.getInterval(), out); + } + if(cdatetime.hasAssumedValue()) { + out.write("; "); + out.write(cdatetime.assumedValue().toString()); + } + } + + protected void printCTime(CTime ctime, Writer out) throws IOException { + if (ctime.getPattern() != null) { + out.write(ctime.getPattern()); + } else if (ctime.getList() != null) { + out.write(ctime.getList().get(0).toString()); + } else { + printInterval(ctime.getInterval(), out); + } + if(ctime.hasAssumedValue()) { + out.write("; "); + out.write(ctime.assumedValue().toString()); + } + } + + protected void printCDuration(CDuration cduration, Writer out) + throws IOException { + if (cduration.getValue() != null) { + out.write(cduration.getValue().toString()); + } else if(cduration.getPattern() != null) { + out.write(cduration.getPattern()); + } else { + printInterval(cduration.getInterval(), out); + } + if(cduration.assumedValue() != null) { + out.write("; "); + out.write(cduration.assumedValue().toString()); + } + } + + protected void printCInteger(CInteger cinteger, Writer out) + throws IOException { + if (cinteger.getList() != null) { + printList(cinteger.getList(), out); + } else { + printInterval(cinteger.getInterval(), out); + } + if(cinteger.assumedValue() != null) { + out.write("; "); + out.write(cinteger.assumedValue().toString()); + } + } + + protected void printCReal(CReal creal, Writer out) throws IOException { + if (creal.getList() != null) { + printList(creal.getList(), out); + } else { + printInterval(creal.getInterval(), out); + } + if(creal.assumedValue() != null) { + out.write("; "); + out.write(creal.assumedValue().toString()); + } + } + + protected void printCString(CString cstring, Writer out) throws IOException { + if (cstring.getPattern() != null) { + out.write("/" + cstring.getPattern() + "/"); + } else if(cstring.getList() != null){ + printList(cstring.getList(), out, true); + } else if(cstring.defaultValue() != null) { + out.write(quoteString(cstring.defaultValue())); + } + if(cstring.hasAssumedValue()) { + out.write("; "); + out.write(quoteString(ObjectUtils.toString(cstring.assumedValue(), ""))); + } + } + + protected void printList(List list, Writer out) throws IOException { + printList(list, out, false); + } + + protected void printList(List list, Writer out, boolean string) + throws IOException { + for (int i = 0, j = list.size(); i < j; i++) { + if (i != 0) { + out.write(","); + } + String item = list.get(i).toString(); + if (string) { + out.write(quoteString(item)); + } else { + out.write(item); + } + } + } + + protected void printInterval(Interval interval, Writer out) + throws IOException { + out.write("|"); + if (interval.getLower() != null && interval.getUpper() != null) { + if(interval.getLower().equals(interval.getUpper()) + && interval.isLowerIncluded() + && interval.isUpperIncluded()) { + out.write(interval.getLower().toString()); + } else { + out.write(interval.getLower().toString()); + out.write(".."); + out.write(interval.getUpper().toString()); + } + } else if (interval.getLower() == null) { + out.write("<"); + if (interval.isUpperIncluded()) { + out.write("="); + } + out.write(interval.getUpper().toString()); + } else { + out.write(">"); + if (interval.isLowerIncluded()) { + out.write("="); + } + out.write(interval.getLower().toString()); + } + out.write("|"); + } + + private void newline(Writer out) throws IOException { + out.write(lineSeparator); + } + + private void indent(int level, Writer out) throws IOException { + for (int i = 0; i < level; i++) { + out.write(indent); + } + } + + /* charset encodings */ + public static final Charset UTF8 = Charset.forName("UTF-8"); + public static final Charset LATIN1 = Charset.forName("ISO-8859-1"); + + /* fields */ + private Charset encoding; + private String lineSeparator; + private String indent; +} +/* + * ***** BEGIN LICENSE BLOCK ***** Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the 'License'); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + * the specific language governing rights and limitations under the License. + * + * The Original Code is ADLSerializer.java + * + * The Initial Developer of the Original Code is Rong Chen. Portions created by + * the Initial Developer are Copyright (C) 2004-2007 the Initial Developer. All + * Rights Reserved. + * + * Contributor(s): Mattias Forss, Johan Hjalmarsson, Erik Sundvall, + * Sebastian Garde + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + * the specific language governing rights and limitations under the License. + * + * ***** END LICENSE BLOCK ***** + */ diff --git a/adl-serializer/src/test/adl/adl-test-entry.most_minimal.test.adl b/adl-serializer/src/test/adl/adl-test-entry.most_minimal.test.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/adl/archetype-internal-ref-test.adl b/adl-serializer/src/test/adl/archetype-internal-ref-test.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/adl/archetype-language.adl b/adl-serializer/src/test/adl/archetype-language.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/adl/archetype-slot-any-allowed-test.adl b/adl-serializer/src/test/adl/archetype-slot-any-allowed-test.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/adl/archetype-slot-empty-excludes-test.adl b/adl-serializer/src/test/adl/archetype-slot-empty-excludes-test.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/adl/archetype-slot-empty-includes-test.adl b/adl-serializer/src/test/adl/archetype-slot-empty-includes-test.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/adl/archetype-slot-test.adl b/adl-serializer/src/test/adl/archetype-slot-test.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/adl/c-code-phrase-test-empty.adl b/adl-serializer/src/test/adl/c-code-phrase-test-empty.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/adl/c-code-phrase-test.adl b/adl-serializer/src/test/adl/c-code-phrase-test.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/adl/c-dv-ordinal-test-empty.adl b/adl-serializer/src/test/adl/c-dv-ordinal-test-empty.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/adl/c-dv-ordinal-test.adl b/adl-serializer/src/test/adl/c-dv-ordinal-test.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/adl/c-dv-ordinal-test2.adl b/adl-serializer/src/test/adl/c-dv-ordinal-test2.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/adl/c-dv-quantity-test-empty.adl b/adl-serializer/src/test/adl/c-dv-quantity-test-empty.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/adl/c-dv-quantity-test.adl b/adl-serializer/src/test/adl/c-dv-quantity-test.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/adl/c-string-test.adl b/adl-serializer/src/test/adl/c-string-test.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/adl/empty-attribute-list-test.adl b/adl-serializer/src/test/adl/empty-attribute-list-test.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/adl/empty-children-list-test.adl b/adl-serializer/src/test/adl/empty-children-list-test.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/adl/multi-language.adl b/adl-serializer/src/test/adl/multi-language.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/adl/multi-terminology.adl b/adl-serializer/src/test/adl/multi-terminology.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/adl/ontology.adl b/adl-serializer/src/test/adl/ontology.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/adl/openEHR-EHR-EVALUATION.test_concept.v1.adl b/adl-serializer/src/test/adl/openEHR-EHR-EVALUATION.test_concept.v1.adl old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/java/org/openehr/am/serialize/ArchetypeInternalRefTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/ArchetypeInternalRefTest.java old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/java/org/openehr/am/serialize/ArchetypeLanguageTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/ArchetypeLanguageTest.java old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/java/org/openehr/am/serialize/ArchetypeSlotTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/ArchetypeSlotTest.java old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/java/org/openehr/am/serialize/CCodePhraseTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/CCodePhraseTest.java old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/java/org/openehr/am/serialize/CDurationTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/CDurationTest.java old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/java/org/openehr/am/serialize/CDvOrdinalTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/CDvOrdinalTest.java index 74d79657..82ef53eb 100755 --- a/adl-serializer/src/test/java/org/openehr/am/serialize/CDvOrdinalTest.java +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/CDvOrdinalTest.java @@ -1,7 +1,6 @@ package org.openehr.am.serialize; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.*; import org.openehr.am.openehrprofile.datatypes.quantity.CDvOrdinal; import org.openehr.am.openehrprofile.datatypes.quantity.Ordinal; @@ -11,7 +10,7 @@ public class CDvOrdinalTest extends SerializerTestBase { public void testPrintCDvOrdinalWithAssumedValue() throws Exception { - Set list = new LinkedHashSet(); + List list = new ArrayList(); for (int i = 1; i <= 4; i++) { list.add(new Ordinal(i, new CodePhrase("local", "at200" + i))); } @@ -25,7 +24,7 @@ public void testPrintCDvOrdinalWithAssumedValue() throws Exception { } public void testPrintCDvOrdinal() throws Exception { - Set list = new LinkedHashSet(); + List list = new ArrayList(); for (int i = 1; i <= 4; i++) { list.add(new Ordinal(i, new CodePhrase("local", "at200" + i))); } @@ -38,10 +37,8 @@ public void testPrintCDvOrdinal() throws Exception { } public void testPrintEmptyCDvOrdinal() throws Exception { - Set list = null; - Interval occurrences = new Interval(1, 1); - cordinal = new CDvOrdinal("/path", occurrences, null, null, list, + cordinal = new CDvOrdinal("/path", occurrences, null, null, null, null, null); clean(); outputter.printCDvOrdinal(cordinal, 0, out); diff --git a/adl-serializer/src/test/java/org/openehr/am/serialize/CDvQuantityTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/CDvQuantityTest.java old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/java/org/openehr/am/serialize/CommonTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/CommonTest.java old mode 100755 new mode 100644 index 72f559ed..d2a88517 --- a/adl-serializer/src/test/java/org/openehr/am/serialize/CommonTest.java +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/CommonTest.java @@ -26,6 +26,7 @@ import org.openehr.am.archetype.constraintmodel.Cardinality; import org.openehr.rm.support.basic.Interval; import org.openehr.rm.support.identification.ArchetypeID; +import org.openehr.rm.support.identification.HierObjectID; public class CommonTest extends SerializerTestBase { @@ -47,6 +48,22 @@ public void testPrintHeader() throws Exception { + conceptCode + "]\r\n"); } + public void testPrintHeaderAttributes() throws Exception { + String id = "openEHR-EHR-EVALUATION.adverse_reaction-medication.v1"; + + clean(); + HierObjectID uid = new HierObjectID("23e1c56c-0a44-11e7-93ae-92361f002671"); + outputter.printHeader("1.4", new ArchetypeID(id), + null, uid, "at0000", out); + + verify("" + + "archetype (adl_version=1.4; uid=23e1c56c-0a44-11e7-93ae-92361f002671)\r\n" + + " openEHR-EHR-EVALUATION.adverse_reaction-medication.v1\r\n" + + "\r\n" + + "concept\r\n" + + " [at0000]\r\n"); + } + public void testPrintExistence() throws Exception { clean(); outputter.printExistence(CAttribute.Existence.REQUIRED, out); diff --git a/adl-serializer/src/test/java/org/openehr/am/serialize/DescriptionTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/DescriptionTest.java old mode 100755 new mode 100644 index 3fc3916f..a3d5cd09 --- a/adl-serializer/src/test/java/org/openehr/am/serialize/DescriptionTest.java +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/DescriptionTest.java @@ -1,126 +1,124 @@ -/* - * component: "openEHR Reference Implementation" - * description: "Class DescriptionTest" - * keywords: "archetype" - * - * author: "Rong Chen " - * support: "Acode HB " - * copyright: "Copyright (c) 2004,2005,2006 Acode HB, Sweden" - * license: "See notice at bottom of class" - * - * file: "$URL:$" - * revision: "$LastChangedRevision: $" - * last_change: "$LastChangedDate: $" - */ -package org.openehr.am.serialize; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.openehr.rm.common.resource.ResourceDescription; -import org.openehr.rm.common.resource.ResourceDescriptionItem; -import org.openehr.rm.datatypes.text.CodePhrase; -import org.openehr.rm.support.terminology.TerminologyService; -import org.openehr.terminology.SimpleTerminologyService; - -public class DescriptionTest extends SerializerTestBase { - - public DescriptionTest(String test) { - super(test); - } - - public void testPrintDescriptionItem() throws Exception { - String purpose = "purpose"; - String use = "use"; - String misuse = "misuse"; - String copyright = "copyright"; - List keywords = new ArrayList(); - keywords.add("apple"); - keywords.add("pear"); - Map urls = new HashMap(); - urls.put("key", "value"); - Map others = new HashMap(); - TerminologyService service = SimpleTerminologyService.getInstance(); - - ResourceDescriptionItem item = new ResourceDescriptionItem(ENGLISH, - purpose, keywords, use, misuse, copyright, urls, others, - service); - - clean(); - outputter.printDescriptionItem(item, 0, out); - - verify("[\"en\"] = <\r\n" + " language = <[ISO_639-1::en]>\r\n" - + " purpose = <\"purpose\">\r\n" - + " keywords = <\"apple\",\"pear\">\r\n" - + " copyright = <\"copyright\">\r\n" - + " use = <\"use\">\r\n" + " misuse = <\"misuse\">\r\n" - + " original_resource_uri = <\r\n" - + " [\"key\"] = <\"value\">\r\n" - + " >\r\n" - + ">\r\n"); - } - - public void testPrintDescription() throws Exception { - String author = "Jerry Mouse"; - String status = "draft"; - Map authorMap = new HashMap(); - authorMap.put("name", author); - - List items = - new ArrayList(); - String[][] others = { { "revision", "1.1" }, { "adl_version", "1.4" }, - { "rights", "all rights reserved" } }; - Map otherDetails = new HashMap(); - for (String[] pair : others) { - otherDetails.put(pair[0], pair[1]); - } - TerminologyService service = SimpleTerminologyService.getInstance(); - ResourceDescriptionItem item = new ResourceDescriptionItem(ENGLISH, - "purpose of this archetype", service); - items.add(item); - ResourceDescription description = new ResourceDescription(authorMap, - null, status, items, null, null, null); - - clean(); - outputter.printDescription(description, out); - - verify("description\r\n" + " original_author = <\r\n" - + " [\"name\"] = <\"" + author + "\">\r\n" + " >\r\n" - + " lifecycle_state = <\"" + status + "\">\r\n" - + " details = <\r\n" + " [\"en\"] = <\r\n" - + " language = <[ISO_639-1::en]>\r\n" - + " purpose = <\"purpose of this archetype\">\r\n" - + " >\r\n" + " >\r\n"); - } -} -/* - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the 'License'); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an 'AS IS' basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is DescriptionTest.java - * - * The Initial Developer of the Original Code is Rong Chen. - * Portions created by the Initial Developer are Copyright (C) 2004-2006 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Software distributed under the License is distributed on an 'AS IS' basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * ***** END LICENSE BLOCK ***** - */ +/* + * component: "openEHR Reference Implementation" + * description: "Class DescriptionTest" + * keywords: "archetype" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004,2005,2006 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL:$" + * revision: "$LastChangedRevision: $" + * last_change: "$LastChangedDate: $" + */ +package org.openehr.am.serialize; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.openehr.rm.common.resource.ResourceDescription; +import org.openehr.rm.common.resource.ResourceDescriptionItem; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.terminology.SimpleTerminologyService; + +public class DescriptionTest extends SerializerTestBase { + + public DescriptionTest(String test) { + super(test); + } + + public void testPrintDescriptionItem() throws Exception { + String purpose = "purpose"; + String use = "use"; + String misuse = "misuse"; + String copyright = "copyright"; + List keywords = new ArrayList(); + keywords.add("apple"); + keywords.add("pear"); + Map urls = new HashMap(); + urls.put("key", "value"); + Map others = new HashMap(); + TerminologyService service = SimpleTerminologyService.getInstance(); + + ResourceDescriptionItem item = new ResourceDescriptionItem(ENGLISH, + purpose, keywords, use, misuse, copyright, urls, others, + service); + + clean(); + outputter.printDescriptionItem(item, 0, out); + + verify("[\"en\"] = <\r\n" + " language = <[ISO_639-1::en]>\r\n" + + " purpose = <\"purpose\">\r\n" + + " keywords = <\"apple\",\"pear\">\r\n" + + " copyright = <\"copyright\">\r\n" + + " use = <\"use\">\r\n" + " misuse = <\"misuse\">\r\n" + + " original_resource_uri = <\r\n" + + " [\"key\"] = <\"value\">\r\n" + + " >\r\n" + + ">\r\n"); + } + + public void testPrintDescription() throws Exception { + String author = "Jerry Mouse"; + String status = "draft"; + Map authorMap = new HashMap(); + authorMap.put("name", author); + + Map items = new HashMap(); + String[][] others = { { "revision", "1.1" }, { "adl_version", "1.4" }, + { "rights", "all rights reserved" } }; + Map otherDetails = new HashMap(); + for (String[] pair : others) { + otherDetails.put(pair[0], pair[1]); + } + TerminologyService service = SimpleTerminologyService.getInstance(); + ResourceDescriptionItem item = new ResourceDescriptionItem(ENGLISH, + "purpose of this archetype", service); + items.put(ENGLISH.getCodeString(),item); + ResourceDescription description = new ResourceDescription(authorMap, + null, status, items, null, null, null); + + clean(); + outputter.printDescription(description, out); + + verify("description\r\n" + " original_author = <\r\n" + + " [\"name\"] = <\"" + author + "\">\r\n" + " >\r\n" + + " lifecycle_state = <\"" + status + "\">\r\n" + + " details = <\r\n" + " [\"en\"] = <\r\n" + + " language = <[ISO_639-1::en]>\r\n" + + " purpose = <\"purpose of this archetype\">\r\n" + + " >\r\n" + " >\r\n"); + } +} +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the 'License'); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is DescriptionTest.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2004-2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * ***** END LICENSE BLOCK ***** + */ diff --git a/adl-serializer/src/test/java/org/openehr/am/serialize/EmptyAttributeListTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/EmptyAttributeListTest.java old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/java/org/openehr/am/serialize/MultipleLanguageTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/MultipleLanguageTest.java old mode 100755 new mode 100644 index 1519ff90..afead957 --- a/adl-serializer/src/test/java/org/openehr/am/serialize/MultipleLanguageTest.java +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/MultipleLanguageTest.java @@ -97,13 +97,8 @@ public void testPrintOntology() throws Exception { items.add(item); definitions = new OntologyDefinitions("zh", items); constraintDefinitionsList.add(definitions); - - // List available languages - List languages = new ArrayList(); - languages.add("en"); - languages.add("zh"); - - ArchetypeOntology ontology = new ArchetypeOntology("en", languages, + + ArchetypeOntology ontology = new ArchetypeOntology("en", null, termDefinitionsList, constraintDefinitionsList, null, null); diff --git a/adl-serializer/src/test/java/org/openehr/am/serialize/MultipleTerminologyTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/MultipleTerminologyTest.java old mode 100755 new mode 100644 index 936c4999..2c8e16b0 --- a/adl-serializer/src/test/java/org/openehr/am/serialize/MultipleTerminologyTest.java +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/MultipleTerminologyTest.java @@ -47,8 +47,6 @@ public void testPrintOntology() throws Exception { new ArrayList(); termDefinitionsList.add(definitions); - List languages = new ArrayList(); - languages.add("en"); List terminologies = new ArrayList(); terminologies.add("SNOMED_CT"); terminologies.add("ICD10"); @@ -86,7 +84,7 @@ public void testPrintOntology() throws Exception { ontologyBind = new OntologyBinding("ICD10",constraintBindList); constraintBindingList.add(ontologyBind); - ArchetypeOntology ontology = new ArchetypeOntology("en", languages, + ArchetypeOntology ontology = new ArchetypeOntology("en", terminologies, termDefinitionsList, null, termBindingList, constraintBindingList); clean(); outputter.printOntology(ontology, out); diff --git a/adl-serializer/src/test/java/org/openehr/am/serialize/OntologyTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/OntologyTest.java old mode 100755 new mode 100644 index 62fc07d6..5aa60cd4 --- a/adl-serializer/src/test/java/org/openehr/am/serialize/OntologyTest.java +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/OntologyTest.java @@ -59,8 +59,6 @@ public void testPrintOntology() throws Exception { new ArrayList(); constraintDefinitionsList.add(definitions); - List languages = new ArrayList(); - languages.add("en"); List terminologies = new ArrayList(); terminologies.add("local"); @@ -90,7 +88,7 @@ public void testPrintOntology() throws Exception { new ArrayList(); constraintBindingList.add(ontologyBind); - ArchetypeOntology ontology = new ArchetypeOntology("en", languages, + ArchetypeOntology ontology = new ArchetypeOntology("en", terminologies, termDefinitionsList, constraintDefinitionsList, termBindingList, constraintBindingList); clean(); diff --git a/adl-serializer/src/test/java/org/openehr/am/serialize/PrimitiveTypesTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/PrimitiveTypesTest.java old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/java/org/openehr/am/serialize/RoundTripTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/RoundTripTest.java old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/java/org/openehr/am/serialize/SerializerTestBase.java b/adl-serializer/src/test/java/org/openehr/am/serialize/SerializerTestBase.java old mode 100755 new mode 100644 diff --git a/adl-serializer/src/test/java/org/openehr/am/serialize/SimpleArchetypeTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/SimpleArchetypeTest.java old mode 100755 new mode 100644 index 33be739e..1bbea8d7 --- a/adl-serializer/src/test/java/org/openehr/am/serialize/SimpleArchetypeTest.java +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/SimpleArchetypeTest.java @@ -57,13 +57,12 @@ public void testPrintArchetypeLanguagePart() throws Exception { termDefinitionsList.add(definitions); List constraintDefinitionsList = null; - List languages = new ArrayList(); - languages.add("en"); + List terminologies = null; List termBindingList = null; List constraintBindingList = null; - ArchetypeOntology ontology = new ArchetypeOntology("en", languages, + ArchetypeOntology ontology = new ArchetypeOntology("en", terminologies, termDefinitionsList, constraintDefinitionsList, termBindingList, constraintBindingList); diff --git a/adl-serializer/src/test/java/org/openehr/am/serialize/StringEscapeTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/StringEscapeTest.java new file mode 100644 index 00000000..45c413be --- /dev/null +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/StringEscapeTest.java @@ -0,0 +1,61 @@ +package org.openehr.am.serialize; + +import java.io.IOException; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * @author markopi + */ +public class StringEscapeTest extends SerializerTestBase { + + public void testEscapeMapValues() throws IOException { + Map map = new LinkedHashMap(); + map.put("at0002", "Characters to escape: \""); + + StringWriter writer = new StringWriter(); + outputter.printMap(map, writer, 0); + String serialized = writer.toString().trim(); + + assertEquals("[\"at0002\"] = <\"Characters to escape: \\\"\">", serialized); + } + + public void testEscapeMapKeys() throws IOException { + Map map = new LinkedHashMap(); + map.put("term\"inology", "Terminology"); + + StringWriter writer = new StringWriter(); + outputter.printMap(map, writer, 0); + String serialized = writer.toString().trim(); + + assertEquals("[\"term\\\"inology\"] = <\"Terminology\">", serialized); + } + + public void testEscapeStringList() throws IOException { + List list = new ArrayList(); + list.add("Escape: \""); + list.add("Other"); + + StringWriter writer = new StringWriter(); + outputter.printList(list, writer, true); + String serialized = writer.toString().trim(); + + assertEquals("\"Escape: \\\"\",\"Other\"", serialized); + } + + public void testKeepNonStringList() throws IOException { + List list = new ArrayList(); + list.add(1); + list.add(2); + + StringWriter writer = new StringWriter(); + outputter.printList(list, writer, false); + String serialized = writer.toString().trim(); + + assertEquals("1,2", serialized); + } + +} diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml new file mode 100755 index 00000000..5114e79c --- /dev/null +++ b/archetype-validator/pom.xml @@ -0,0 +1,87 @@ + + + 4.0.0 + + org.openehr.java-libs + java-libs + 0-SNAPSHOT + + archetype-validator + jar + Archetype Validator + http://svn.openehr.org/ref_impl_java/TRUNK/project_page.htm + + openEHR + http://www.openehr.org/ + + 2008 + + Archetype Validator + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.7 + 1.7 + + + + + + + + commons-lang + commons-lang + 2.4 + + + log4j + log4j + 1.2.13 + + + org.openehr.java-libs + openehr-rm-core + ${project.version} + + + org.openehr.java-libs + openehr-rm-domain + ${project.version} + + + org.openehr.java-libs + openehr-aom + ${project.version} + + + org.openehr.java-libs + openehr-ap + ${project.version} + + + org.openehr.java-libs + mini-termserv + ${project.version} + + + org.openehr.java-libs + measure-serv + ${project.version} + + + org.openehr.java-libs + adl-parser + ${project.version} + test + + + junit + junit + 3.8.1 + + + diff --git a/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java new file mode 100755 index 00000000..f3be889c --- /dev/null +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java @@ -0,0 +1,1648 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Archetype Validator" + * keywords: "archetype" + * + * author: "Rong Chen" + * support: "openEHR Java Project " + * copyright: "Copyright (c) 2008 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.am.validation; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.assertion.Assertion; +import org.openehr.am.archetype.assertion.ExpressionBinaryOperator; +import org.openehr.am.archetype.assertion.ExpressionLeaf; +import org.openehr.am.archetype.constraintmodel.ArchetypeInternalRef; +import org.openehr.am.archetype.constraintmodel.ArchetypeSlot; +import org.openehr.am.archetype.constraintmodel.CAttribute; +import org.openehr.am.archetype.constraintmodel.CComplexObject; +import org.openehr.am.archetype.constraintmodel.CDomainType; +import org.openehr.am.archetype.constraintmodel.CMultipleAttribute; +import org.openehr.am.archetype.constraintmodel.CObject; +import org.openehr.am.archetype.constraintmodel.CPrimitiveObject; +import org.openehr.am.archetype.constraintmodel.CSingleAttribute; +import org.openehr.am.archetype.constraintmodel.ConstraintRef; +import org.openehr.am.archetype.constraintmodel.primitive.CPrimitive; +import org.openehr.am.archetype.constraintmodel.primitive.CString; +import org.openehr.am.archetype.ontology.ArchetypeTerm; +import org.openehr.am.archetype.ontology.OntologyBinding; +import org.openehr.am.archetype.ontology.OntologyBindingItem; +import org.openehr.am.archetype.ontology.OntologyDefinitions; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvOrdinal; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantity; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantityItem; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvScale; +import org.openehr.am.openehrprofile.datatypes.quantity.Ordinal; +import org.openehr.am.openehrprofile.datatypes.quantity.Scale; +import org.openehr.am.openehrprofile.datatypes.text.CCodePhrase; +import org.openehr.rm.common.resource.ResourceDescriptionItem; +import org.openehr.rm.datatypes.quantity.DvOrdered; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.basic.Interval; +import org.openehr.rm.support.identification.ArchetypeID; +import org.openehr.rm.support.measurement.MeasurementService; +import org.openehr.rm.support.measurement.SimpleMeasurementService; +import org.openehr.rm.support.terminology.TerminologyAccess; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.terminology.SimpleTerminologyService; + +/** + * Validator for archetypes + *

+ *

+ * It checks the following + * .archetype term validity + * .constraint code validity + * .ontology translations missing + * .archetype definition typename validity + * .archetype definition code validity + * .attribute constraint name validity + * .single-valued attribute child object occurrences validity + * .single-valued attribute child node uniqueness + * .single-valued attribute child node reference model type (redundant?) + * .multi-valued attribute child node identification + * .multi-valued attribute child node identifier uniqueness + * .object constraint type name validity + * .archetype concept specialisation depth + * .use_node type validity + * .use_node path validity + * .ontology code specialisation level validity + * .archetype specialisation parent identifier validity + * + * @author rong.chen + * @author sebastian.garde + * @version 1.0 + */ +public class ArchetypeValidator { + + /** + * Create an instance of RM inspector + */ + public ArchetypeValidator() { + this.rmInspector = new RMInspector(); + + try { + this.termService = SimpleTerminologyService.getInstance(); + this.openEHRTerminology = termService.terminology( + TerminologyService.OPENEHR); + + } catch (Exception e) { + log.error("failed to start the terminology service", e); + } + } + + private boolean reportConstraintsOnCommonFunctionalPropertiesAsInfo = false; + + public final void setReportConstraintsOnCommonFunctionalPropertiesAsInfo( + boolean reportConstraintsOnCommonFunctionalPropertiesAsInfo) { + this.reportConstraintsOnCommonFunctionalPropertiesAsInfo = reportConstraintsOnCommonFunctionalPropertiesAsInfo; + } + + /** + * Validates the given archetype + * + * @param archetype + * @param reportConstraintsOnCommonFunctionalPropertiesAsInfo if set to true, constraintson functional properties such as "is_integral" as part of DV_PROPORTION and "offset" in EVENT are reported as info only. If set to false (default), they are reported as errors. + * @return list of validation errors or empty list if valid + */ + + public List validate(Archetype archetype, boolean reportConstraintsOnCommonFunctionalPropertiesAsInfo) + throws RMInspectionException { + this.reportConstraintsOnCommonFunctionalPropertiesAsInfo = reportConstraintsOnCommonFunctionalPropertiesAsInfo; + List errors = new ArrayList(); + + checkDescription(archetype, errors); + checkArchetypeDefinitionTypename(archetype, errors); + checkArchetypeDefinitionCodeValidity(archetype, errors); + checkObjectConstraints(archetype, errors); + checkArchetypeTermValidity(archetype, errors); + checkCodeConstraintValidity(archetype, errors); + checkOntologyTranslation(archetype, errors); + checkConceptSpecializationDepth(archetype, errors); + checkSpecializationParentIdentifierValidity(archetype, errors); + checkOntologyCodeSpecialisationLevelValidity(archetype, errors); + checkArchetypeTermBindingsValidity(archetype, errors); + + return errors; + + } + + + /** + * Validates the given archetype + * + * @param archetype + * @return list of validation errors or empty list if valid + */ + public List validate(Archetype archetype) + throws RMInspectionException { + return validate(archetype, false); + } + + + public void checkDescription(Archetype archetype, List errors) { + if (archetype.getDescription() == null) { + return; + } + + ArrayList checkedLanguages = new ArrayList<>(); + // check purpose in each available language + for (ResourceDescriptionItem detail : archetype.getDescription().getDetails().values()) { + if (!checkedLanguages.contains(detail.getLanguage().getCodeString())) { + checkedLanguages.add(detail.getLanguage().getCodeString()); + } else { + errors.add(new ValidationError(ErrorType.VDL, null, detail.getLanguage().getCodeString())); + } + if (StringUtils.isBlank(detail.getPurpose()) || StringUtils.containsIgnoreCase(detail.getPurpose(), "unknown")) { + ValidationError error = new ValidationError(ErrorType.VDSCR, "PURPOSE", + detail.getLanguage().getCodeString()); + errors.add(error); + } + } + + // check original author + Map originalAuthor = archetype.getDescription().getOriginalAuthor(); + if (originalAuthor == null || originalAuthor.isEmpty()) { + ValidationError error = new ValidationError(ErrorType.VDSCR, "ORIGINALAUTHOR"); + errors.add(error); + } else { + for (Entry authorItem : originalAuthor.entrySet()) { + if (StringUtils.isBlank(authorItem.getValue()) || + StringUtils.containsIgnoreCase(authorItem.getValue(), "unknown")) { + ValidationError error = new ValidationError(ErrorType.VDSCR, "ORIGINALAUTHORPART", authorItem.getKey()); + errors.add(error); + } + } + } + + // check lifecycle state + String lifecycle = archetype.getDescription().getLifecycleState(); + if (StringUtils.isBlank(lifecycle) || + StringUtils.containsIgnoreCase(lifecycle, "unknown") || + StringUtils.isNumeric(lifecycle)) { + ValidationError error = new ValidationError(ErrorType.VDSCR, "LIFECYCLE"); + errors.add(error); + } + } + + public void checkArchetypeDefinitionCodeValidity(Archetype archetype, + List errors) { + String concept = archetype.getConcept(); + String rootNodeId = archetype.getDefinition().getNodeId(); + if (!concept.equals(rootNodeId)) { + ValidationError error = new ValidationError(ErrorType.VACCD, null); + + errors.add(error); + } + } + + public void checkArchetypeUnitsValidity(CDvQuantity cDvQuantity, List errors) { + List qis = cDvQuantity.getList(); + if (qis != null && qis.size() > 0) { + MeasurementService sms = SimpleMeasurementService.getInstance(); + for (CDvQuantityItem qi : qis) { + if (!sms.isValidUnitsString(qi.getUnits())) { + ValidationError error = new ValidationError(ErrorType.VUI, null, qi.getUnits()); + errors.add(error); + } + } + } + } + + /** + * Checks the archetype concept specialisation depth + * + * @param archetype + * @param errors + */ + public void checkConceptSpecializationDepth(Archetype archetype, + List errors) { + String concept = archetype.getConcept(); + List specialization = archetype.getArchetypeId().specialisation(); + StringTokenizer tokens = new StringTokenizer(concept, "."); + + if (specialization.size() != tokens.countTokens() - 1) { + ValidationError error = new ValidationError(ErrorType.VACSD, null, + specialization.size(), tokens.countTokens() - 1); + errors.add(error); + } + } + + /** + * Checks the validity of the archetype specialisation parent identifier, i.e. + * that the archetype identifier stated in the specialise clause is the + * identifier of the immediate specialisation parent archetype. + * + * @param archetype + * @param errors + */ + public void checkSpecializationParentIdentifierValidity(Archetype archetype, + List errors) { + + if (archetype.getParentArchetypeId() == null) { + return; // no specialise clause at all + } + + ArchetypeID atId = archetype.getArchetypeId(); + String base = atId.base(); + String calculatedBaseForParent = base.substring(0, base.lastIndexOf("-")); + + if (!calculatedBaseForParent.equals(archetype.getParentArchetypeId().base())) { + ValidationError error = new ValidationError( + ErrorType.VASID, "NORMAL", archetype.getArchetypeId().toString(), archetype.getParentArchetypeId().toString()); + errors.add(error); + } + if (archetype.getParentArchetypeId().versionID().endsWith("draft")) { + ValidationError error = new ValidationError( + ErrorType.VASID, "DEPRECATED", archetype.getParentArchetypeId().toString()); + errors.add(error); + } + } + + /** + * Checks ontology code specialisation level validity. No archetype code + * (at-code or ac-code) defined in the ontology can be of a greater + * specialisation depth than the archetype. + * + * @param archetype + * @param errors + */ + public void checkOntologyCodeSpecialisationLevelValidity( + Archetype archetype, List errors) { + + log.debug("validating ontology code specialisation of archetype: " + + archetype.getArchetypeId()); + + List specialisation = archetype.getArchetypeId().specialisation(); + + log.debug("specialisation list: " + specialisation); + + int level = specialisation == null ? 0 : specialisation.size(); + + log.debug("specialisation level: " + level); + + List list = null; + + list = archetype.getOntology().getTermDefinitionsList(); + checkOntologyDefinitions(list, errors, level); + + list = archetype.getOntology().getConstraintDefinitionsList(); + checkOntologyDefinitions(list, errors, level); + } + + private void checkOntologyDefinitions(List defList, + List errors, int level) { + + ValidationError error = null; + for (OntologyDefinitions defs : defList) { + for (ArchetypeTerm term : defs.getDefinitions()) { + if (hasGreaterSpecialisationLevel(term.getCode(), level)) { + error = new ValidationError(ErrorType.VONSD, null, term.getCode(), level); + errors.add(error); + } + } + } + } + + private boolean hasGreaterSpecialisationLevel(String code, int level) { + StringTokenizer tokens = new StringTokenizer(code, "."); + if (tokens.countTokens() - 1 > level) { + return true; + } + return false; + } + + + /** + * Checks various object constraints + * + * @param archetype + * @param errors + * @throws RMInspectionException + */ + public void checkObjectConstraints(Archetype archetype, + List errors) throws RMInspectionException { + validateCComplexObject(archetype.getDefinition(), archetype, errors); + } + + + /** + * checks whether the rmAttrName is a commonly constrained functional property of the parentRMType + * + * @param rmAttrName + * @param parentRMTypeName + * @return + */ + private boolean isCommonFunctionalProperty(String rmAttrName, String parentRMTypeName) { + if (rmAttrName.equals("is_integral") && parentRMTypeName.equals("DV_PROPORTION")) { + return true; + } + if (rmAttrName.equals("offset") && parentRMTypeName.endsWith("EVENT")) { + return true; + } + if (rmAttrName.equals("type") && parentRMTypeName.endsWith("PARTY_RELATIONSHIP")) { + return true; + } + + return false; + + } + + private void validateCAttribute(CAttribute cattr, + Map rmAttrs, CComplexObject parent, + Archetype archetype, List errors) + throws RMInspectionException { + + + String rmAttrName = cattr.getRmAttributeName(); + Class rmAttrType = rmAttrs.get(rmAttrName); + + Set rmAttrNames = rmAttrs.keySet(); + ValidationError error = null; + + + String parentRmClassName = parent.getRmTypeName(); + parentRmClassName = removeGenericTypes(parentRmClassName); + String parentGenericTypeName = getGenericType(parent.getRmTypeName()); + log.debug("Generic type name: " + parentGenericTypeName); + Class parentRmClass = rmInspector.retrieveRMType(parentRmClassName); + Class parentGenericType = null; + + if (parentGenericTypeName != null) { + parentGenericType = rmInspector.retrieveRMType(parentGenericTypeName); + } + + // replace primitive types with object types + if (int.class.equals(rmAttrType)) { + rmAttrType = Integer.class; + } else if (double.class.equals(rmAttrType)) { + rmAttrType = Double.class; + } else if (boolean.class.equals(rmAttrType)) { + rmAttrType = Boolean.class; + } + + log.debug("1- validating attribute [" + rmAttrName + "] of type [" + + rmAttrType + "]"); + if (!rmAttrNames.contains(rmAttrName)) { + // if it is a commonly constrained functional property, only show this as information according to validator setting. + if (reportConstraintsOnCommonFunctionalPropertiesAsInfo && isCommonFunctionalProperty(rmAttrName, parent.getRmTypeName())) { + error = new ValidationError(ErrorType.ICARM, null, + rmAttrName, cattr.path(), parent.getRmTypeName()); + } else { + + error = new ValidationError(ErrorType.VCARM, null, + rmAttrName, parent.getRmTypeName(), cattr.path()); + } + errors.add(error); + return; + } + + if (cattr instanceof CMultipleAttribute) { + CMultipleAttribute cmattr = (CMultipleAttribute) cattr; + checkCardinalityConformsToRMCardinality(cmattr, parent, errors); + + //check Cardinality fits with the minimum and maximum of all occurrences of the children + checkCardinalityConformsToChildrenOccurrences(cmattr, errors); + } + + + if (cattr.getChildren() == null) { + return; + } + + for (CObject cobj : cattr.getChildren()) { + + if (cattr instanceof CSingleAttribute) { + + // check rm type + String childRMTypeName = cobj.getRmTypeName(); + childRMTypeName = removeGenericTypes(childRMTypeName); + + log.debug("2- validating attribute.child constraint of type: " + + cobj.getClass() + ", with rmType: " + + childRMTypeName); + + Class childRMType = + rmInspector.retrieveRMType(childRMTypeName); + + if (childRMType == null) { + error = new ValidationError(ErrorType.VCORM, null, + childRMTypeName, cobj.path()); + errors.add(error); + continue; + + } else if (cobj instanceof CPrimitiveObject) { + // need to check the assumed value for primitive objects before skipping if parentRMClass and childRMType are equal (which is the case for SOME, but not all primitive objects) + log.debug("validating CPrimitiveObject at: " + cobj.path()); + validateCPrimitiveObject((CPrimitiveObject) cobj, archetype, errors); + log.debug("skipping unnecessary additional checks on " + parentRmClass); + continue; // otherwise this is done twice + } else if (parentRmClass.equals(childRMType)) { + + log.debug("skipping unnecessary check on " + parentRmClass); + continue; + } else if (!rmAttrType.isEnum() + && !(rmAttrType.isAssignableFrom(childRMType))) { + + log.debug("3- rmAttrType: " + rmAttrType + " with name [" + + rmAttrName + "] is NOT assignable from type [" + + childRMType + "]"); + + ErrorType type = ErrorType.VCORMT; + if (cobj instanceof ArchetypeInternalRef) { + type = ErrorType.VUNT; + } + error = new ValidationError(type, "NORMAL", + childRMTypeName, cobj.path(), rmAttrType.getSimpleName()); + if (!errors.contains(error)) { + errors.add(error); + } + continue; + + } else if (parentGenericType != null + && !(parentGenericType.isAssignableFrom(childRMType))) { + // the generic type is not assignable from the childRMType, e.g + // DV_INTERVAL is wrong as DV_TEXT is a valid RMType, but not one that fits here: must be DV_ORDERED or subclass + log.debug("4- rmAttrType: " + rmAttrType + " of name [" + + rmAttrName + "] with generic type <" + + parentGenericTypeName + + "> is NOT assignable from type [" + + childRMType + "]"); + + ErrorType type = ErrorType.VCORMT; + if (cobj instanceof ArchetypeInternalRef) { + type = ErrorType.VUNT; + } + + error = new ValidationError(type, "PARENT", + parentGenericTypeName, parent.path(), childRMType.getSimpleName(), cobj.path()); + errors.add(error); + continue; + + } + + log.debug("5- rmAttrType: " + rmAttrType + " with name " + + rmAttrName + " IS assignable from " + childRMType); + + // check csingle attribute child object occurrences + Interval occu = cobj.getOccurrences(); + if (occu != null && occu.isUpperIncluded() + && occu.getUpper() > 1) { + error = new ValidationError(ErrorType.VACSO, null, + cobj.path()); + errors.add(error); + } + for (CObject cobj2 : cattr.getChildren()) { + if (cobj == cobj2) { + continue; + } + // check child uniqueness + if (cobj2.getRmTypeName().equals(cobj.getRmTypeName()) + && cobj.getNodeId() == null) { + error = new ValidationError(ErrorType.VACSU, null, + cobj.path()); + if (!errors.contains(error)) { + errors.add(error); + } + } + // check child identifier + if (cobj2.getNodeId() != null + && cobj2.getNodeId().equals(cobj.getNodeId())) { + error = new ValidationError(ErrorType.VACSI, null, + cobj.path()); + if (!errors.contains(error)) { + errors.add(error); + } + } + /*VASCIT just seems to be a special case of VACSU?? + * else if (cobj2.getNodeId() == null + && cobj.getRmTypeName().equals(cobj2.getRmTypeName())) { + // check for multiple attributes with the same rm type when the nodeId is null for one of them + error = new ValidationError(ErrorType.VACSIT, + "Cannot add "+cobj.getRmTypeName()+" object with node_id "+cobj.getNodeId()+" to singly-valued attribute "+cattr.getRmAttributeName()+" because attribute already has child with same RM type. (path="+cobj.path()+")"); + if( ! errors.contains(error)) { + errors.add(error); + } + } */ + } + } else { // CMultipleAttribute + + // checking for cardinality/occurrences validity (VACMC): the interval represented by, (sum of all occurrences minimum values) .. (sum of all occurrences maximum values) must be contained by the interval stated by the cardinality. + Interval cardinalityInterval = + ((CMultipleAttribute) cattr).getCardinality().getInterval(); + if (!cardinalityInterval.isUpperUnbounded() + && (cobj.getOccurrences().isUpperUnbounded() + || cardinalityInterval.getUpper().compareTo( + cobj.getOccurrences().getUpper()) < 0)) { + error = new ValidationError(ErrorType.VACMC, "CONTAIN", + rmInspector.toUnderscoreSeparated(cobj.getClass().getSimpleName()).toUpperCase(), + cobj.getRmTypeName(), + cobj.getNodeId(), + getIntervalFormalString(cardinalityInterval), + getIntervalFormalString(cobj.getOccurrences()), + cattr.path()); + + if (!errors.contains(error)) { + errors.add(error); + } + + } else if (cobj.getNodeId() == null) { + // check missing child identifier + // this is only legal (in most cases) if it is a ArchetypeInternalRef i.e. a use_node reference, but not if there is more than one witohut a node id + if (cobj instanceof ArchetypeInternalRef) { + // TODO if the object id at the target end of the ref happens to be the same as the object id of a sibling member at the source end then an explicit source-end id is needed even for an internal reference. + // Could use hasSiblingWithTargetNodeId((ArchetypeInternalRef) cobj, archetype) for this + + for (CObject cobj2 : cattr.getChildren()) { + if (cobj == cobj2) { + continue; + } + if (cobj2.getNodeId() == null && cobj2 instanceof ArchetypeInternalRef && + ((ArchetypeInternalRef) cobj).getTargetPath().equals(((ArchetypeInternalRef) cobj2).getTargetPath())) { + error = new ValidationError(ErrorType.VACMM, "INTREF", + cobj.path()); + if (!errors.contains(error)) { + errors.add(error); + } + } + } + } else { + error = new ValidationError(ErrorType.VACMI, null, + cobj.path()); + errors.add(error); + } + } else { + // check duplicated child identifier + for (CObject cobj2 : cattr.getChildren()) { + if (cobj == cobj2) { + continue; + } + if (cobj.getNodeId().equals(cobj2.getNodeId())) { + error = new ValidationError(ErrorType.VACMM, "NORMAL", + cobj.path()); + if (!errors.contains(error)) { + errors.add(error); + } + } + } + } + + // how about rmType check for multi-valued attributes? + } + + if (cobj instanceof CDomainType) { // also includes CDVQuantity! + log.debug("validating CDomainType of node_id: " + cobj.getNodeId()); + validateCDomainType((CDomainType) cobj, archetype, errors); + } else if (cobj instanceof CPrimitiveObject) { + log.debug("validating CPrimitiveObject at: " + cobj.path()); + validateCPrimitiveObject((CPrimitiveObject) cobj, archetype, errors); + } else if (cobj instanceof CComplexObject) { + log.debug("validating ccobj at: " + cobj.getNodeId()); + validateCComplexObject((CComplexObject) cobj, archetype, errors); + } else if (cobj instanceof ArchetypeInternalRef) { + log.debug("validating Internal Reference: " + cobj.path()); + checkArchetypeInternalRef((ArchetypeInternalRef) cobj, archetype, errors); + } else if (cobj instanceof ArchetypeSlot) { + log.debug("validating ArchetypeSlot: " + cobj.path()); + checkArchetypeSlot((ArchetypeSlot) cobj, rmAttrType, archetype, errors); + } else { + log.debug("not continuing with recursion for class: " + cobj.getClass()); + } + } + } + + + private void checkCardinalityConformsToChildrenOccurrences( + CMultipleAttribute cmattr, List errors) { + + if (cmattr.getChildren() == null || cmattr.getChildren().size() == 0) { // in the new RM implementation it is no longer null then, but empty + return; // nothing to check + } + + + Interval cardinalityInterval = + (cmattr).getCardinality().getInterval(); + + int minOcc = 0; + int maxOcc = 0; + boolean isOccUpperUnbounded = false; + for (CObject cobj : cmattr.getChildren()) { + + minOcc += cobj.getOccurrences().getLower(); + + if (cobj.getOccurrences().isUpperUnbounded()) { + isOccUpperUnbounded = true; + } else { + maxOcc += cobj.getOccurrences().getUpper(); + } + } + + // check lower: + if (!cardinalityInterval.isUpperUnbounded() && minOcc > cardinalityInterval.getUpper()) { + // no intersection of occurrences and cardinality because the minimal sum of occurrences is greater than the maximal cardinality + ValidationError error = new ValidationError(ErrorType.VACMC, "INTERSECT", + cmattr.path(), getIntervalFormalString(cardinalityInterval), getIntervalFormalString(minOcc, maxOcc, isOccUpperUnbounded) + ); + if (!errors.contains(error)) { + errors.add(error); + return; // found an error, so can return + } + } + + // check upper + if (!isOccUpperUnbounded + && maxOcc < cardinalityInterval.getLower()) { + + // no intersection of occurrences and cardinality because the maximal sum of occurrences is lower than the minimal cardinality + ValidationError error = new ValidationError(ErrorType.VACMC, "INTERSECT", + cmattr.path(), getIntervalFormalString(cardinalityInterval), getIntervalFormalString(minOcc, maxOcc, isOccUpperUnbounded) + ); + + if (!errors.contains(error)) { + errors.add(error); + } + } + + if (!cardinalityInterval.isUpperUnbounded() && + minOcc != maxOcc && + cardinalityInterval.getUpper().intValue() == minOcc) { + // Although there is an intersection, this intersection doesn't really make sense + // because it would mean that at least one element could never fulfil its occurrence potential + // This may not be an error, but should at least be a warning + ValidationError error = new ValidationError(ErrorType.WACMC, null, + cmattr.path(), getIntervalFormalString(cardinalityInterval), getIntervalFormalString(minOcc, maxOcc, isOccUpperUnbounded)); + + if (!errors.contains(error)) { + errors.add(error); + } + } + } + + private void checkCardinalityConformsToRMCardinality(CMultipleAttribute cattr, CObject cobj, List errors) { + Interval rmCardinality = rmInspector.defaultCardinalityInterval(cattr, cobj); + Interval actualCardinality = cattr.getCardinality().getInterval(); + if (rmCardinality.getLower().compareTo(actualCardinality.getLower()) > 0) { + //VCACA actual lower cardinality lower than allowed + ValidationError error = new ValidationError(ErrorType.VCACA, null, + cattr.path(), getIntervalFormalString(actualCardinality), getIntervalFormalString(rmCardinality)); + errors.add(error); + + //attribute items in object node at /items cardinality 0..* does not conform to cardinality >=1 in reference model + } else if (rmCardinality.getLower().compareTo(actualCardinality.getLower()) == 0) { + //WCACA the same...can we do this ... is this not simply ok??? as default is set + } + + if (!rmCardinality.isUpperUnbounded()) { + if (actualCardinality.isUpperUnbounded() || + (rmCardinality.getUpper().compareTo(actualCardinality.getUpper()) < 0)) { + //VCACA upper too high ... this may e.g. occur for cardinality of credentials in demographics archetypes + ValidationError error = new ValidationError(ErrorType.VCACA, null, + cattr.path(), getIntervalFormalString(actualCardinality), getIntervalFormalString(rmCardinality)); + errors.add(error); + + } else if (rmCardinality.getUpper().compareTo(actualCardinality.getUpper()) == 0) { + //WCACA + } + } + } + + + /** + * Checks the assertions of an archetype for validity + * + * @param slot + * @param rmAttrType + * @param archetype + * @param errors + */ + private void checkArchetypeSlot(ArchetypeSlot slot, Class rmAttrType, Archetype archetype, List errors) { + if (slot.getIncludes() != null) { + for (Assertion include : slot.getIncludes()) { + checkAssertionHasValidArchetypeIds(include, slot, errors); + } + } + if (slot.getExcludes() != null) { + for (Assertion exclude : slot.getExcludes()) { + checkAssertionHasValidArchetypeIds(exclude, slot, errors); + } + } + //any_allowed xor (includes /= Void or excludes /= Void) + if (!slot.isAnyAllowed() && slot.getExcludes() == null && slot.getIncludes() == null) { + ValidationError error = new ValidationError(ErrorType.VDFAI, "SLOTVALIDITY", slot.path()); + errors.add(error); + } + } + + /** + * Checks that an assertion contains valid archetype ids + * + * @param assertion + * @param slot + * @param errors + */ + private void checkAssertionHasValidArchetypeIds(Assertion assertion, ArchetypeSlot slot, List errors) { + if (assertion.getExpression() instanceof ExpressionBinaryOperator) { + + ExpressionBinaryOperator ebo = (ExpressionBinaryOperator) assertion.getExpression(); + if (ebo.getRightOperand() instanceof ExpressionLeaf) { + ExpressionLeaf elR = (ExpressionLeaf) ebo.getRightOperand(); + if (elR.getItem() != null && elR.getItem() instanceof CString) { + CString elRCStr = (CString) elR.getItem(); + if (elRCStr.getPattern() != null) { + String pattern = elRCStr.getPattern(); + + try { + Pattern.compile(pattern); + } catch (PatternSyntaxException exception) { + ValidationError error = new ValidationError(ErrorType.VDFAI, "INVALIDPATTERN", pattern, slot.path()); + errors.add(error); + return; + // System.err.println(exception.getDescription()); + } + + if (!pattern.equals(".*")) { + // make readability modifications for the pattern + while (pattern.indexOf("(-[a-zA-Z0-9_]+)*\\") > 0) { + pattern = pattern.replace("(-[a-zA-Z0-9_]+)*\\", ""); + // ignore any specialised syntax for now + //pattern = pattern.substring(0,i+3) + " and specialisations"+ pattern.substring(i+3); + } + + // delete the regex \ + while (pattern.indexOf("\\.") > 0) { + pattern = pattern.replace("\\.", "."); + } + + String prevPipeStart = ""; + while (pattern.indexOf("|") > 0) { + // We check if the number of opening and closing brackets match up to the point of the pipe symbol. + // If not, this is an indication that the pipe represents a choice in the middle of an archetype id, + // and is not separating two archetype ids from each other: + String subStringUpToPipe = pattern.substring(0, pattern.indexOf("|")); + int openingBrackets = StringUtils.countMatches(subStringUpToPipe, "("); + int closingBrackets = StringUtils.countMatches(subStringUpToPipe, ")"); + + String oneId = prevPipeStart + subStringUpToPipe; + pattern = pattern.substring(pattern.indexOf("|") + 1); + + if (openingBrackets != closingBrackets) { + prevPipeStart += subStringUpToPipe + "|"; // can be more than once! + continue; // we are in the middle of an archetype id and need to continue looking for the end + } else { + prevPipeStart = ""; // reset + checkOneArchetypeId(slot, errors, oneId); + } + + } + // the rest of the pattern is the last archetype id, so test this one too. + checkOneArchetypeId(slot, errors, pattern); + } + } + } + } + } + } + + /** + * Checks one archetype id to be a valid id or not + * + * @param slot + * @param errors + * @param oneId + */ + private void checkOneArchetypeId(ArchetypeSlot slot, List errors, String oneId) { + // check for the right number of dots in the id - note that since this is a regex, we would need to look for \. but this has been replace before already + boolean containsCorrectNumberOfDots = (StringUtils.countMatches(oneId, ".") == 2); + + boolean containsAnyString = StringUtils.contains(oneId, ".*") || StringUtils.contains(oneId, ".+"); + if (containsAnyString && !containsCorrectNumberOfDots) { + return; // if there are parts in the regex that can be anything our validation here is not sophisticated enough + } + + if (!containsCorrectNumberOfDots) { + ValidationError error = new ValidationError(ErrorType.VDFAI, "NUMBEROFDOTS", oneId, slot.path()); + errors.add(error); + return; // Without the correct number of dots, there is too much guessing afterwards + } + + // Guaranteed to have the three parts now, e.g. openEHR-EHR-Cluster + my_concept + v1 + String[] idParts = StringUtils.split(oneId, "."); + // String rmPart = idParts[0]; + // String conceptPart = idParts[1]; + String versionPart = idParts[2]; + + // check that the id ends with .v[0..9]+ + boolean endsWithDotVNumber = true; // assume it is ok, until proven false + if (!versionPart.startsWith("v") && !versionPart.startsWith("*") && !versionPart.startsWith("+")) { // a dot unescaped would be any character - we may have to accept this even if it is odd + endsWithDotVNumber = false; + } else if (versionPart.startsWith("v")) { // we can only (easily) continue with this part of the validation then + String tail = versionPart.substring(1); + log.debug("tail: " + tail); + + // In addition to specifying a concrete version number, it is also possible in a slot regex to match any number. + // Unfortunately, there are unlimited ways of specifying this in a regex, therefore we check for a few common ones, + // and - as a last resort - we check if at least one number from 0 to 1000 is matched as version number. + if (tail.length() == 0 || + (!StringUtils.isNumeric(tail) + && !tail.equals("[1-9][0-9]*") + && !tail.equals("([0-9]+)") + && !tail.equals("[0-9]+") + && !tail.equals("[0-9]") + && !tail.equals("[1-9]") + && !tail.equals("(0|[1-9][0-9]*)") + && !tail.equals("([0-9]|[1-9][0-9]+)") + && !tail.equals("[1-9][0-9]*") + && !tail.equals(".+") // This is far too lose, but if VDFAI only postulates that the regex can(!) be an archetype id, we need to allow this + && !tail.equals(".*") // This is far too lose, but if VDFAI only postulates that the regex can(!) be an archetype id, we need to allow this + )) { + + boolean matchedANumber = false; + for (int testNumber = 0; testNumber <= 1000; testNumber ++) { + if (Pattern.matches(tail, "" + testNumber)) { + matchedANumber = true; + break; + } + } + endsWithDotVNumber = matchedANumber; + } + } + + if (!endsWithDotVNumber) { + ValidationError error = new ValidationError(ErrorType.VDFAI, "DOTVNUMBER", oneId, slot.path()); + errors.add(error); + } + + // check that the first part of the id (the qualified RM Entity) contains the right number of hyphens + String qualifiedRMEntity = idParts[0]; // oneId.substring(0, oneId.indexOf("\\.")); + if (StringUtils.countMatches(qualifiedRMEntity, "-") != 2 + && StringUtils.countMatches(qualifiedRMEntity, "|") == 0 // If there are pipes there is choice in this part of the pattern. This is unusal and beyond the competency of this validator. + && !StringUtils.contains(qualifiedRMEntity, ".")) { // the . could be .* or .+ or just . unescaped = any char -> in that case we cannot guarantee it is not meant to be a dash + ValidationError error = new ValidationError(ErrorType.VDFAI, "NUMBEROFHYPHENS", oneId, slot.path()); + errors.add(error); + } + } + + + /** + * Validates a given c_domain_type constraint + *

+ * TODO: does not report a problem on values that have a higher precision than specified + * + * @param cdtobj + * @param archetype + * @param errors + */ + private void validateCDomainType(CDomainType cdtobj, Archetype archetype, + List errors) { + + if (cdtobj.hasAssumedValue()) { + log.debug("validating assumed value: " + cdtobj.getAssumedValue()); + if (!cdtobj.validValue(cdtobj.getAssumedValue())) { + ValidationError error = new ValidationError(ErrorType.VOBAV, null, + cdtobj.getAssumedValue(), cdtobj.getRmTypeName(), cdtobj.path()); + errors.add(error); + } + } else { + log.debug("No assumed value found for : " + cdtobj.getRmTypeName() + " at " + cdtobj.path()); + } + + if (cdtobj instanceof CCodePhrase) { + validateCCodePhrase((CCodePhrase) cdtobj, errors); + } else if (cdtobj instanceof CDvQuantity) { + log.debug("validating CDVQuantity object at " + cdtobj.path()); + checkArchetypeUnitsValidity((CDvQuantity) cdtobj, errors); + } + + } + + /* + * Checks validity of openEHR codes in given ccodephrase + */ + private void validateCCodePhrase(CCodePhrase ccodephrase, + List errors) { + + if (ccodephrase.getCodeList() == null + || !TerminologyService.OPENEHR.equalsIgnoreCase( + ccodephrase.getTerminologyId().toString())) { + return; + } + StringBuffer buf = new StringBuffer(); + for (String code : ccodephrase.getCodeList()) { + if (!openEHRTerminology.allCodes().contains( + new CodePhrase(TerminologyService.OPENEHR, code))) { + buf.append(code + ", "); + } + } + String codes = buf.toString(); + if (codes.length() != 0) { + ValidationError error = new ValidationError(ErrorType.VOTC, null, + codes, ccodephrase.path()); + errors.add(error); + } + } + + /** + * @param cpobj + * @param archetype + * @param errors + */ + private void validateCPrimitiveObject(CPrimitiveObject cpobj, Archetype archetype, List errors) { + // This finds VOBAV validation problems. + CPrimitive item = cpobj.getItem(); + if (item.hasAssumedValue()) { + Object assumedValue = item.assumedValue(); + log.debug("Assumed value for CPrimitiveObject: " + assumedValue); + + if (!item.validValue(assumedValue)) { + ValidationError error = new ValidationError(ErrorType.VOBAV, null, + assumedValue, cpobj.getRmTypeName(), cpobj.path()); + errors.add(error); + } else { + log.debug("Found valid assumed value for CPrimitiveObject: " + cpobj.getRmTypeName() + " at " + cpobj.path()); + } + } else { + log.debug("No assumed value found for CPrimitiveObject : " + cpobj.getRmTypeName() + " at " + cpobj.path()); + } + } + + + private void validateCComplexObject(CComplexObject ccobj, Archetype archetype, + List errors) throws RMInspectionException { + + checkGenericTypeName(ccobj, errors); + if (ccobj.getAttributes() == null) { + return; + } + + String rmTypeNameWithoutGeneric = ccobj.getRmTypeName(); + rmTypeNameWithoutGeneric = removeGenericTypes(rmTypeNameWithoutGeneric); + + Set rmAttrNames = rmInspector.retrieveRMAttributeNames( + rmTypeNameWithoutGeneric); + Map rmAttrs = rmInspector.retrieveRMAttributes( + rmTypeNameWithoutGeneric); + + ValidationError error = null; + if (rmAttrNames.isEmpty()) { + error = new ValidationError(ErrorType.VCORM, null, + rmTypeNameWithoutGeneric, ccobj.path()); + errors.add(error); + return; + } + + + HashSet attributeNames = new HashSet(); + for (CAttribute cattr : ccobj.getAttributes()) { + validateCAttribute(cattr, rmAttrs, ccobj, archetype, errors); + + // also check on the fly if all the attributes are uniquely named + if (!attributeNames.contains(cattr.getRmAttributeName())) { + attributeNames.add(cattr.getRmAttributeName()); + } else { + error = new ValidationError(ErrorType.VCATU, null, + cattr.getRmAttributeName(), ccobj.path()); + errors.add(error); + } + } + } + + /** + * Checks that a generic type name actually exists. For example would generate an error for + * DV_INTERVAL, which should really be DV_INTERVAL + * + * @param ccobj + * @param errors + */ + private void checkGenericTypeName(CComplexObject ccobj, List errors) { + ValidationError error; + String genericTypeName = getGenericType(ccobj.getRmTypeName()); + log.debug("Generic type name: " + genericTypeName); + Class genericType = null; + if (genericTypeName != null) { + genericType = rmInspector.retrieveRMType(genericTypeName); + log.debug("Generic type: " + genericType); + + } + if (genericTypeName != null && genericType == null) { + error = new ValidationError(ErrorType.VCORM, null, + ccobj.getRmTypeName(), ccobj.path()); + errors.add(error); + } else if (genericType != null) { + // found a generic type, but we still need to know if it is assignable from here + if (!DvOrdered.class.isAssignableFrom(genericType)) { + error = new ValidationError(ErrorType.VCORMT, "NORMAL", + ccobj.getRmTypeName(), ccobj.path(), genericType.getSimpleName()); + errors.add(error); + } + } + } + + protected String removeGenericTypes(String rmTypeName) { + if (rmTypeName.indexOf("<") > 0 && rmTypeName.indexOf(">") > 0) { + rmTypeName = rmTypeName.substring(0, rmTypeName.indexOf("<")); + } + return rmTypeName; + } + + // TODO very simple solution, only works with one generic type + protected String getGenericType(String rmTypeName) { + int start = rmTypeName.indexOf("<"); + int end = rmTypeName.indexOf(">"); + String genericType = null; + if (start > 0 && end > start) { + genericType = rmTypeName.substring(start + 1, end); + } + return genericType; + } + + /** + * Checks the given ArchetypeInternalRef + * + * @param ref + * @param archetype + * @param errors + */ + public void checkArchetypeInternalRef(ArchetypeInternalRef ref, + /*Class rmAttributeType,*/ Archetype archetype, + List errors) { + + + log.debug("validating internal_ref of rmType: " + ref.getRmTypeName() + + " at " + ref.path() + " with target " + ref.getTargetPath()); + //" for rmAttributeType: " + rmAttributeType); + + // right now unnecessary, should be checked already + Class rmType = rmInspector.retrieveRMType(ref.getRmTypeName()); + ValidationError error = null; + if (rmType == null) { + + error = new ValidationError(ErrorType.VUNT, "UNKNOWN", + ref.getRmTypeName(), ref.path()); + errors.add(error); + } + + // Checking the target and its consistency with the source + CObject target = (CObject) archetype.node(ref.getTargetPath()); + if (target == null) { + error = new ValidationError(ErrorType.VUNP, "INVALIDPATH", + ref.getTargetPath(), ref.path()); + errors.add(error); + } else { + Class targetType = rmInspector.retrieveRMType(target.getRmTypeName()); + log.debug("Target type: " + targetType); + log.debug("rmtype: " + rmType); + if (targetType == null) { + error = new ValidationError(ErrorType.VUNP, "UNKNOWNTARGETRM", + "Unknown target rm type at path: " + ref.getTargetPath() + + " of internalRef at: " + ref.path()); + errors.add(error); + } else if (!rmType.isAssignableFrom(targetType)) { + error = new ValidationError(ErrorType.VUNP, "INVALIDTARGETRM", + targetType, ref.path()); + errors.add(error); + } + } + } + + /** + * Checks the archetype definition typename validity: The topmost typename mentioned + * in the archetype definition section must match the type mentioned in the type-name + * slot of the first segment of the archetype id. + * + * @param archetype + * @param errors + */ + public void checkArchetypeDefinitionTypename(Archetype archetype, + List errors) { + String conceptType = archetype.getArchetypeId().rmEntity(); + String topType = archetype.getDefinition().getRmTypeName(); + ValidationError error = null; + if (!conceptType.equals(topType)) { + error = new ValidationError(ErrorType.VARDT, null, topType, conceptType); + errors.add(error); + } + } + + /** Checks if languages listed in translation section are provided in + * term_definition and constraint_definition sections. + * Also checks if the respective language is present in the description details. + *

+ * TODO: how about missing individual term_def/constraint_def translations? + * @param archetype + * @return errors */ + public void checkOntologyTranslation(Archetype archetype, List errors) { + Set languages = archetype.languagesAvailable(); + String primaryLang = archetype.getOriginalLanguage().getCodeString(); + + List termDefList = archetype.getOntology().getTermDefinitionsList(); + checkDuplicateLanguage(errors, termDefList); + + List constraintDefList = archetype.getOntology().getConstraintDefinitionsList(); + checkDuplicateLanguage(errors, constraintDefList); + + Set termDefLangs = retrieveLanguageSet(termDefList); + Set constraintDefLangs = retrieveLanguageSet(constraintDefList); + + ValidationError error = null; + for (String lang : languages) { + // Checks if for all available languages, there are also equivalents in the description/details - if there are description/details at all. + // This is important to prevent inconsistencies and is also relevant for the primary language. + if (archetype.getDescription() != null && archetype.getDescription().getDetails() != null && !archetype.getDescription().getDetails().containsKey(lang)) { + error = new ValidationError(ErrorType.VOTM, "DESCRIPTIONDETAILS", lang); + errors.add(error); + } + + if (primaryLang.equals(lang)) { + continue; + } + + if (!termDefLangs.contains(lang)) { + error = new ValidationError(ErrorType.VOTM, "TERM", lang); + errors.add(error); + } + + if (!constraintDefList.isEmpty() + && !constraintDefLangs.contains(lang)) { + error = new ValidationError(ErrorType.VOTM, "CONSTRAINT", lang); + errors.add(error); + } + } + } + + private void checkDuplicateLanguage(List errors, List ontDefsList) { + ArrayList checkedLanguages = new ArrayList<>(); + for (OntologyDefinitions ontDefs : ontDefsList) { + if (!checkedLanguages.contains(ontDefs.getLanguage())) { + checkedLanguages.add(ontDefs.getLanguage()); + } else { + errors.add(new ValidationError(ErrorType.VDL, null, ontDefs.getLanguage())); + } + } + } + + private Set retrieveLanguageSet(List list) { + Set set = new LinkedHashSet(); + for (OntologyDefinitions defs : list) { + set.add(defs.getLanguage()); + } + return set; + } + + /** + * TODO not used + *

+ * Check internal references + * + * @return map of node path, target path if any wrong internal references + */ + Map checkInternalReferences(Archetype archetype) { + Map errors = new HashMap(); + return checkInternalReferences(archetype, archetype.getDefinition(), + errors); + } + + private Map checkInternalReferences(Archetype archetype, + CComplexObject ccobj, + Map errors) { + for (CAttribute cattribute : ccobj.getAttributes()) { + for (CObject cobj : cattribute.getChildren()) { + if (cobj instanceof ArchetypeInternalRef) { + ArchetypeInternalRef ref = (ArchetypeInternalRef) cobj; + CObject target = (CObject) archetype.node(ref.getTargetPath()); + if (target == null + || !target.getRmTypeName().equals( + cobj.getRmTypeName())) { + // either target unknown or wrong type + errors.put(ref.path(), ref.getTargetPath()); + } + } + if (cobj instanceof CComplexObject) { + checkInternalReferences(archetype, (CComplexObject) cobj, + errors); + } + } + } + return errors; + } + + public void checkArchetypeTermValidity(Archetype archetype, + List errors) { + Set codes = fetchAllATCodes(archetype); + String lang = archetype.getOriginalLanguage().getCodeString(); + List defList = + archetype.getOntology().getTermDefinitionsList(); + OntologyDefinitions priDefs = null; + ValidationError error = null; + + ArrayList secondaryLanguageOntDefs = new ArrayList(); + for (OntologyDefinitions defs : defList) { + if (lang.equals(defs.getLanguage())) { + priDefs = defs; + } else { + secondaryLanguageOntDefs.add(defs); + } + } + + // first check for the primary language + Set definedCodesPrimLang = new LinkedHashSet(); + if (priDefs == null) { + for (String code : codes) { + error = new ValidationError(ErrorType.VATDF, "NORMAL", + code); + errors.add(error); + } + } else { + List terms = priDefs.getDefinitions(); + + for (ArchetypeTerm term : terms) { + definedCodesPrimLang.add(term.getCode()); + } + for (String code : codes) { + if (!definedCodesPrimLang.contains(code)) { + error = new ValidationError(ErrorType.VATDF, "NORMAL", + code); + errors.add(error); + } + } + } + + // now check for the secondary languages + for (OntologyDefinitions secDefs : secondaryLanguageOntDefs) { + List terms = secDefs.getDefinitions(); + Set definedCodesSecLang = new LinkedHashSet(); + + for (ArchetypeTerm term : terms) { + definedCodesSecLang.add(term.getCode()); + } + for (String code : codes) { + // if not present in sec lang, but present in prim lang: + if (!definedCodesSecLang.contains(code) && definedCodesPrimLang.contains(code)) { + error = new ValidationError(ErrorType.VONLC, "TERM", + code, secDefs.getLanguage()); + errors.add(error); + } + } + } + + checkForUnusedCodes(defList, errors, archetype, codes); + checkForDoubleCodes(defList, errors, archetype); + + } + + public void checkCodeConstraintValidity(Archetype archetype, + List errors) { + Set codes = fetchAllACCodes(archetype); + String lang = archetype.getOriginalLanguage().getCodeString(); + List defList = + archetype.getOntology().getConstraintDefinitionsList(); + OntologyDefinitions priDefs = null; + ValidationError error = null; + + ArrayList secondaryLanguageOntDefs = new ArrayList(); + for (OntologyDefinitions defs : defList) { + if (lang.equals(defs.getLanguage())) { + priDefs = defs; + } else { + secondaryLanguageOntDefs.add(defs); + } + } + + Set definedCodesPrimLang = new LinkedHashSet(); + + if (priDefs == null) { + for (String code : codes) { + error = new ValidationError(ErrorType.VACDF, null, + code); + errors.add(error); + } + } else { + List terms = priDefs.getDefinitions(); + for (ArchetypeTerm term : terms) { + definedCodesPrimLang.add(term.getCode()); + } + for (String code : codes) { + if (!definedCodesPrimLang.contains(code)) { + error = new ValidationError(ErrorType.VACDF, null, + code); + errors.add(error); + } + } + } + + // now check for the secondary languages + for (OntologyDefinitions secDefs : secondaryLanguageOntDefs) { + List terms = secDefs.getDefinitions(); + Set definedCodesSecLang = new LinkedHashSet(); + + for (ArchetypeTerm term : terms) { + definedCodesSecLang.add(term.getCode()); + } + for (String code : codes) { + // if not present in sec lang, but present in prim lang: + if (!definedCodesSecLang.contains(code) && definedCodesPrimLang.contains(code)) { + error = new ValidationError(ErrorType.VONLC, "CONSTRAINT", + code, secDefs.getLanguage()); + errors.add(error); + } + } + } + + + checkForUnusedCodes(defList, errors, archetype, codes); + checkForDoubleCodes(defList, errors, archetype); + } + + + /** + * Checks for unused codes in the ontology + * + * @param defList + * @param errors + * @param archetype + */ + private void checkForUnusedCodes(List defList, + List errors, Archetype archetype, Set actuallyUsedCodes) { + + int specialisationDepth = StringUtils.countMatches(archetype.getArchetypeId().domainConcept(), "-"); + + // now check for each code if it exists in the definition + ValidationError error = null; + for (OntologyDefinitions defs : defList) { + for (ArchetypeTerm term : defs.getDefinitions()) { + if (!actuallyUsedCodes.contains(term.getCode())) { + // at the moment, we only want to report on unused codes + // that are on the same specialisation depth as this archetype. + if (specialisationDepth == StringUtils.countMatches(term.getCode(), ".")) { + error = new ValidationError(ErrorType.WOUC, null, + term.getCode(), defs.getLanguage()); + errors.add(error); + } + } + } + } + } + + /** + * Checks for codes in the ontology that are there more than once + * + * @param defList + * @param errors + * @param archetype + */ + private void checkForDoubleCodes(List defList, + List errors, Archetype archetype) { + + // now check for each code if it exists in the definition + ValidationError error = null; + for (OntologyDefinitions defs : defList) { + HashSet foundCodes = new HashSet(); + for (ArchetypeTerm term : defs.getDefinitions()) { + if (foundCodes.contains(term.getCode())) { + // at the moment, we only want to report on unused codes + // that are on the same specialisation depth as this archetype. + error = new ValidationError(ErrorType.VOKU, null, + term.getCode(), defs.getLanguage()); + errors.add(error); + } else { + foundCodes.add(term.getCode()); + } + } + } + } + + public void checkArchetypeTermBindingsValidity(Archetype archetype, + List errors) { + + List termBindings = archetype.getOntology().getTermBindingList(); + ValidationError error = null; + if (termBindings != null) { + for (OntologyBinding binding : termBindings) { + for (OntologyBindingItem obi : binding.getBindingList()) { + if (obi.getCode().startsWith("at")) { // bound to an atcode + if (archetype.getOntology().termDefinition(archetype.getOriginalLanguage().getCodeString(), obi.getCode()) == null) { + error = new ValidationError(ErrorType.WITB, "ATCODE", + obi.getCode()); + errors.add(error); + } + } else { // bound to a complete path + if (!archetype.physicalPaths().contains(obi.getCode())) { + error = new ValidationError(ErrorType.WITB, "PATH", + obi.getCode()); + errors.add(error); + } + } + } + } + } + } + + + /** + * Traverse the archetype and gather all at codes + * + * @param archetype + * @return a set of at codes + */ + Set fetchAllATCodes(Archetype archetype) { + Set codes = new LinkedHashSet(); + // main concept + codes.add(archetype.getConcept()); + + CComplexObject ccobj = archetype.getDefinition(); + + fetchATCodes(ccobj, codes); + + return codes; + } + + void fetchATCodes(CObject cobj, Set codes) { + if (cobj.getNodeId() != null) { + codes.add(cobj.getNodeId()); + } + if (cobj instanceof CComplexObject) { + CComplexObject ccobj = (CComplexObject) cobj; + List cattrList = ccobj.getAttributes(); + if (cattrList == null) { + return; + } + for (CAttribute cattr : cattrList) { + List children = cattr.getChildren(); + if (children == null) { + continue; + } + for (CObject child : children) { + fetchATCodes(child, codes); + } + } + } else if (cobj instanceof CDvOrdinal) { + CDvOrdinal cord = (CDvOrdinal) cobj; + List list = cord.getList(); + if (list != null) { + for (Ordinal ord : list) { + CodePhrase code = ord.getSymbol(); + if ("local".equalsIgnoreCase( + code.getTerminologyId().name())) { + codes.add(code.getCodeString()); + } + } + } + } else if (cobj instanceof CDvScale) { + CDvScale cord = (CDvScale) cobj; + List list = cord.getList(); + if (list != null) { + for (Scale ord : list) { + CodePhrase code = ord.getSymbol(); + if ("local".equalsIgnoreCase(code.getTerminologyId().name())) { + codes.add(code.getCodeString()); + } + } + } + } else if (cobj instanceof CCodePhrase) { + CCodePhrase ccod = (CCodePhrase) cobj; + List list = ccod.getCodeList(); + if ("local".equalsIgnoreCase(ccod.getTerminologyId().name()) + && list != null) { + for (String code : list) { + if (code.startsWith("at")) { + codes.add(code); + } + } + } + } + } + + /** + * Traverse the archetype and gather all "ac" codes + * + * @param archetype + * @return a set of at codes + */ + Set fetchAllACCodes(Archetype archetype) { + Set codes = new LinkedHashSet(); + CComplexObject ccobj = archetype.getDefinition(); + fetchACCodes(ccobj, codes); + return codes; + } + + void fetchACCodes(CObject cobj, Set codes) { + if (cobj instanceof CComplexObject) { + CComplexObject ccobj = (CComplexObject) cobj; + List cattrList = ccobj.getAttributes(); + if (cattrList == null) { + return; + } + for (CAttribute cattr : cattrList) { + List children = cattr.getChildren(); + if (children == null) { + continue; + } + for (CObject child : children) { + fetchACCodes(child, codes); + } + } + } else if (cobj instanceof CCodePhrase) { + CCodePhrase ccod = (CCodePhrase) cobj; + List list = ccod.getCodeList(); + if (list != null) { + for (String code : list) { + if (code.startsWith("ac")) { + codes.add(code); + } + } + } + } else if (cobj instanceof ConstraintRef) { + ConstraintRef ref = (ConstraintRef) cobj; + if (ref.getReference().startsWith("ac")) { + codes.add(ref.getReference()); + } + } + } + + /** + * Constructs a formal String for representing this Interval + * + * @param interval + * @return + */ + protected String getIntervalFormalString(Interval interval) { + Integer lower = interval.getLower(); + Integer upper = interval.getUpper(); + boolean isUpperUnbounded = interval.isUpperUnbounded(); + return getIntervalFormalString(lower, upper, isUpperUnbounded); + } + + protected String getIntervalFormalString(Integer lower, Integer upper, boolean isUpperUnbounded) { + if (lower == null) { + lower = Integer.valueOf(0); + } + + String formal = "" + lower.intValue() + ".."; + if (isUpperUnbounded) { + formal += "*"; + } else { + formal += upper.intValue(); + } + + return formal; + } + + + /* Reference Model inspector */ + protected RMInspector rmInspector; + + /* simple terminology service */ + private TerminologyService termService; + + private TerminologyAccess openEHRTerminology; + + protected static final Logger log = Logger.getLogger(ArchetypeValidator.class); +} +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the 'License'); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Archetype.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Sebastian Garde + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * ***** END LICENSE BLOCK ***** + */ diff --git a/archetype-validator/src/main/java/org/openehr/am/validation/ErrorType.java b/archetype-validator/src/main/java/org/openehr/am/validation/ErrorType.java new file mode 100644 index 00000000..4133dfe6 --- /dev/null +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ErrorType.java @@ -0,0 +1,81 @@ +package org.openehr.am.validation; + +/** + * Error type reported by the archetype validator + * + * MUST BE IN SYNC WITH THE ERROR TYPE IN THE SPECS + * + * @author rong.chen + */ +public enum ErrorType { + + VASID, //archetype specialisation parent identifier validity. the archetype identifier stated in the specialise clause must be the identifier of the immediate specialisation parent archetype. + VACSD, //archetype concept specialisation depth. the specialisation depth of the concept code must match the specialisation depth of the archetype identifier. + VARDT, //archetype definition typename validity. The topmost typename mentioned in the archetype definition section must match the type mentioned in the type-name slot of the first segment of the archetype id. + VATCD, //archetype code specialisation level validity. Each archetype term (?at? code) and constraint code (?ac? code) used in the archetype definition part must have a specialisation level no greater than the specialisation level of the archetype. + VACCD, //archetype definition code validity. The node identifier of the root node of the definition section must be the concept code mentioned earlier in the archetype. + VATDF, //archetype term validity. Each archetype term (?at? code) used as a node identifier the archetype definition must be defined in the term_definitions part of the ontology. + VACDF, //constraint code validity. Each constraint code (?ac? code) used in the archetype definition part must be defined in the constraint_definitions part of the ontology. + VONLC, //Secondary languages consistency. Each archetype term used as a node identifier the archetype definition must be defined for each secondary language term_definitions part of the ontology. + VOTM, //ontology translations missing. Translations must exist for term_definitions and constraint_definitions sections for all languages defined in the description / translations section. + VONSD, //ontology code specialisation level validity. No archetype code (at-code or ac-code) defined in the ontology can be of a greater specialisation depth than the archetype. + VCARM, //attribute constraint name validity, //an attribute name introducing an attribute constraint block must be defined in the underlying information model as an attribute of the type which introduces the enclosing object block. + VSAM, //specialised archetype attribute multiplicity conformance, //the multiplicity of a redefined attribute must conform, i.e. be the same or narrower, to that of the corresponding attribute in the parent archetype. + VSANCE, //specialised archetype attribute node existence conformance, //the existence of a redefined attribute node in a specialised archetype must conform to the existence of the corresponding node in the flat parent archetype by having an identical range, or a range wholly contained by the latter. + VACSO, //single-valued attribute child object occurrences validity, //the occurrences of a child object of a single-valued attribute cannot have an upper limit greater than 1. + VACSU, //single-valued attribute child node uniqueness, //any object node added as a child to a single-valued attribute must either have a node identifier or reference model type that is unique with respect to the node identifier or the reference model type of all other siblings. + VACSI, //single-valued attribute child node identifier, //any object node with a node identifier added as a child to a single-valued attribute must have a node identifier that is unique with respect to the node identifiers of all other siblings. + VACSIT, //single-valued attribute child node reference model type, //any object node without a node identifier added as a child to a single-valued attribute must have a reference model type that is unique with respect to the reference model types of all other siblings. + VACMI, //child node identification, //any object node added as a child to a container attribute must have a node identifier. + VACMM, //child node identifier uniqueness, //the node identifier of an object node added as a child to a container attribute must be unique with respect to the siblings in the container. + VACMC, //cardinality/occurrences validity: where occurrences and cardinality are stated, the interval represented by: (sum of all occurrences minimum values) .. (sum of all occurrences maximum values) must intersect with the interval stated by the cardinality. + VCACA, // NEW: attribute items in object node at /items[at0034]/items[at0033]/items[at0014]/items[at0.135]/items cardinality 0..* does not conform to cardinality >=1 in reference model + VSANCC, //specialised archetype attribute node cardinality conformance, //the cardinality of a redefined (multiply-valued) attribute node in a specialised archetype must conform to the cardinality of the corresponding node in the flat parent archetype by either being identical, or being wholly contained by the latter. + VCORM, //object constraint type name validity, //a type name introducing an object constraint block must be defined in the underlying information model. + VCORMT, //NEW: object constraint type validity: a type name introducing an object constraint block must be the same as or conform to the type stated in the underlying information model of its owning attribute. + VSONCT, //specialised archetype object node type conformance, //the reference model type of a redefined object node in a specialised archetype must conform to the reference model type in the corresponding node in the flat parent archetype by either being identical, or conforming via an inheritance relationship in the relevant reference model. + VSONIR, //specialised archetype object node redefinition, //if defined, the node identifier of a redefined object node in a specialised archetype must be redefined into its specialised form if any other aspect of the immediate object constraint is redefined. + VSONCI, //specialised archetype object node identifier conformance, //if defined, the node identifier of a redefined object node in a specialised archetype must conform to the node identifier in the corresponding node in the flat parent archetype by either being identical, or being a derived identifier at the specialisation level of the child archetype. + VSONCO, //specialised archetype object node occurrences conformance, //the occurrences of a redefined object node in a specialised archetype must conform to the occurrences in the corresponding node in the flat parent archetype by either being identical, or being wholly contained by the latter. + VSSM, //specialised archetype sibling marker validity, //the sibling code used in a sibling marker in a specialised archetype must refer to a node found within the same container in the flat parent archetype. + VOBAV, //object node assumed value validity, //the value of an assumed value must fall within the value space defined by the constraint to which it is attached. + VCATU, //attribute uniqueness, //sibling attributes occurring within an object node must be uniquely named with respect to each other, in the same way as for class definitions in an object reference model. + VDFAI, //archetype identifier validity in definition. Any archetype identifier mentioned in an archetype slot in the definition section must conform to the published openEHR specification for archetype identifiers. + VUNT, //use_node type validity, //the type mentioned in a use_node statement must be the same as or a super-type (according to the reference model) of the reference model type of the node referred to. + VUNP, //use_node path validity, //the path mentioned in a use_node statement must refer to an object node defined elsewhere in the same archetype or any of its specialisation parent archetypes, that is not itself an internal reference node, and which carries a node identifier if one is needed at the reference point. + VSCNR, //placeholder constraint node conformance, //a placeholder node can only be defined into a reference model type conformant with the type of the original constraint in the parent archetype. + VOTC, // openEHR terminology code validity + VDSCR, // null, empty or unknown mandatory description item such as purpose or original_author + VSONT, // different dynamic types of parent and child node (e.g. not both CComplexObjects) + VOKU, // dADL object key must be unique. A code in the ontology is present more than once for a language + VUI, // Additional Validation: Units of a DV_QUANTITY must be expressed in UCUM syntax, e.g. kg/m2, mm[Hg], ms-1, km + VDL, // Additional Validation: A language code may not be present more than once (neither in description/details nor for term or constraint definitions) + WOUC, // Warning: A code in the ontology is not used. + WACMC, //Not an official warning ... cardinality/occurrences validity edge case: where occurrences and cardinality are stated, the interval represented by: (sum of all occurrences minimum values) .. (sum of all occurrences maximum values) must intersect with the interval stated by the cardinality. This is fulfilled, but none of the optional elements could ever be added. + + WITB, // Warning: A Term binding is invalid, the referenced path/code doesn't exist in the archetype + + ICARM // INFO: A commonly constrained functional property has been constrained, typical examples: offset or is_integral + + + /* Missing validation errors + - VCAEX: archetype attribute reference model existence conformance: the existence + of an attribute must conform, i.e. be the same or narrower, to the existence of + the corresponding attribute in the underlying information model. + + - VCAM: archetype attribute reference model multiplicity conformance: the multiplicity, + i.e. whether an attribute is multiply- or single-valued, of an attribute must conform + to that of the corresponding attribute in the underlying information model. + + - VSSM: This seems to be ADL 1.5 specific. specialised archetype sibling marker validity: the sibling code used in a + sibling marker in a specialised archetype must refer to a node found within the same + container in the flat parent archetype. + + The following validity rule applies to CONSTRAINT_REFs in a specialised archetype. + - VSCNR: placeholder constraint node conformance: a placeholder node can only + be defined into a reference model type conformant with the type of the original constraint + in the parent archetype. + + - VSONNC : not defined in specs, but seems to be the general error of non-conformance for specialised archetypes if nothing else fits (just in the algorithm for spec. validation as published in the specs). + */ +} diff --git a/archetype-validator/src/main/java/org/openehr/am/validation/RMInspectionException.java b/archetype-validator/src/main/java/org/openehr/am/validation/RMInspectionException.java new file mode 100644 index 00000000..43bef525 --- /dev/null +++ b/archetype-validator/src/main/java/org/openehr/am/validation/RMInspectionException.java @@ -0,0 +1,11 @@ +package org.openehr.am.validation; + +public class RMInspectionException extends Exception { + + public RMInspectionException(String value) { + super(value); + } + + public RMInspectionException() { + } +} diff --git a/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java b/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java new file mode 100755 index 00000000..2f872d1b --- /dev/null +++ b/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java @@ -0,0 +1,588 @@ +package org.openehr.am.validation; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.openehr.am.archetype.constraintmodel.CMultipleAttribute; +import org.openehr.am.archetype.constraintmodel.CObject; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.common.archetyped.Archetyped; +import org.openehr.rm.common.changecontrol.Contribution; +import org.openehr.rm.common.changecontrol.OriginalVersion; +import org.openehr.rm.common.generic.Attestation; +import org.openehr.rm.common.generic.AuditDetails; +import org.openehr.rm.common.generic.Participation; +import org.openehr.rm.common.generic.PartyIdentified; +import org.openehr.rm.common.generic.PartyProxy; +import org.openehr.rm.common.generic.PartyRelated; +import org.openehr.rm.common.generic.PartySelf; +import org.openehr.rm.composition.Composition; +import org.openehr.rm.composition.EventContext; +import org.openehr.rm.composition.content.entry.Action; +import org.openehr.rm.composition.content.entry.Activity; +import org.openehr.rm.composition.content.entry.AdminEntry; +import org.openehr.rm.composition.content.entry.Evaluation; +import org.openehr.rm.composition.content.entry.ISMTransition; +import org.openehr.rm.composition.content.entry.Instruction; +import org.openehr.rm.composition.content.entry.InstructionDetails; +import org.openehr.rm.composition.content.entry.Observation; +import org.openehr.rm.composition.content.navigation.Section; +import org.openehr.rm.datastructure.history.Event; +import org.openehr.rm.datastructure.history.History; +import org.openehr.rm.datastructure.history.IntervalEvent; +import org.openehr.rm.datastructure.history.PointEvent; +import org.openehr.rm.datastructure.itemstructure.ItemList; +import org.openehr.rm.datastructure.itemstructure.ItemSingle; +import org.openehr.rm.datastructure.itemstructure.ItemTable; +import org.openehr.rm.datastructure.itemstructure.ItemTree; +import org.openehr.rm.datastructure.itemstructure.representation.Cluster; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datatypes.basic.DvBoolean; +import org.openehr.rm.datatypes.basic.DvIdentifier; +import org.openehr.rm.datatypes.basic.DvState; +import org.openehr.rm.datatypes.encapsulated.DvMultimedia; +import org.openehr.rm.datatypes.encapsulated.DvParsable; +import org.openehr.rm.datatypes.quantity.DvCount; +import org.openehr.rm.datatypes.quantity.DvInterval; +import org.openehr.rm.datatypes.quantity.DvOrdinal; +import org.openehr.rm.datatypes.quantity.DvProportion; +import org.openehr.rm.datatypes.quantity.DvQuantity; +import org.openehr.rm.datatypes.quantity.DvScale; +import org.openehr.rm.datatypes.quantity.datetime.DvDate; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.quantity.datetime.DvDuration; +import org.openehr.rm.datatypes.quantity.datetime.DvTime; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.datatypes.text.DvParagraph; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.datatypes.uri.DvEHRURI; +import org.openehr.rm.datatypes.uri.DvURI; +import org.openehr.rm.demographic.Address; +import org.openehr.rm.demographic.Agent; +import org.openehr.rm.demographic.Capability; +import org.openehr.rm.demographic.Contact; +import org.openehr.rm.demographic.Group; +import org.openehr.rm.demographic.Organisation; +import org.openehr.rm.demographic.PartyIdentity; +import org.openehr.rm.demographic.PartyRelationship; +import org.openehr.rm.demographic.Person; +import org.openehr.rm.demographic.Role; +import org.openehr.rm.integration.GenericEntry; +import org.openehr.rm.support.basic.Interval; +import org.openehr.rm.support.identification.AccessGroupRef; +import org.openehr.rm.support.identification.ArchetypeID; +import org.openehr.rm.support.identification.GenericID; +import org.openehr.rm.support.identification.HierObjectID; +import org.openehr.rm.support.identification.ISO_OID; +import org.openehr.rm.support.identification.InternetID; +import org.openehr.rm.support.identification.LocatableRef; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.support.identification.ObjectVersionID; +import org.openehr.rm.support.identification.PartyRef; +import org.openehr.rm.support.identification.TemplateID; +import org.openehr.rm.support.identification.TerminologyID; +import org.openehr.rm.support.identification.UUID; +import org.openehr.rm.support.identification.VersionTreeID; + +public class RMInspector { + /** + * Create a RMInspector + */ + public RMInspector() { + + try { + loadTypeMap(); + } catch (ClassNotFoundException e) { + throw new RuntimeException("failed to load class, " + e + + " when starting RMInspector.."); + } + } + + // load all reference types that are possible to instantiate + // using FullConstructor annotation + private Map loadTypeMap() throws ClassNotFoundException { + Class[] classes = { + + // implied types + Integer.class, + String.class, + Boolean.class, + Double.class, // Also the corresponding class for the Real assumed type. + + // common classes + PartySelf.class, + Archetyped.class, + Attestation.class, + AuditDetails.class, + Participation.class, + PartyProxy.class, + PartyIdentified.class, + PartyRelated.class, + PartySelf.class, + OriginalVersion.class, + Contribution.class, + + // support classes + TerminologyID.class, + ArchetypeID.class, + HierObjectID.class, + AccessGroupRef.class, + GenericID.class, + InternetID.class, + ISO_OID.class, + LocatableRef.class, + ObjectVersionID.class, + ObjectRef.class, + PartyRef.class, + TemplateID.class, + TerminologyID.class, + UUID.class, + VersionTreeID.class, + + // datatypes classes + DvBoolean.class, + DvURI.class, + DvEHRURI.class, + DvState.class, + DvIdentifier.class, + DvText.class, + DvCodedText.class, + DvParagraph.class, + CodePhrase.class, + DvCount.class, + DvOrdinal.class, + DvScale.class, + DvQuantity.class, + DvInterval.class, + DvProportion.class, + DvDate.class, + DvDateTime.class, + DvTime.class, + DvDuration.class, + DvParsable.class, + DvMultimedia.class, + + // datastructure classes + Element.class, Cluster.class, ItemSingle.class, ItemList.class, + ItemTable.class, + ItemTree.class, + History.class, + Event.class, + IntervalEvent.class, + PointEvent.class, + + // ehr classes + Action.class, Activity.class, Evaluation.class, + Instruction.class, InstructionDetails.class, Observation.class, AdminEntry.class, + Section.class, Composition.class, + EventContext.class, ISMTransition.class, GenericEntry.class, + + // demographic classes + Address.class, PartyIdentity.class, Agent.class, Group.class, + Organisation.class, Person.class, Contact.class, + PartyRelationship.class, Role.class, Capability.class }; + + typeMap = new LinkedHashMap(); + upperCaseMap = new LinkedHashMap(); + for (Class klass : classes) { + String name = klass.getSimpleName(); + if (klass.getSimpleName().equalsIgnoreCase("Double")) { + name = "Real"; // For the assumed type Double the corresponding rm type name is Real, not Double + } + typeMap.put(name, klass); + upperCaseMap.put(name.toUpperCase(), klass); + } + return typeMap; + } + + /* + * Return a map with name as the key and index of position as the value for + * required parameters of the full constructor in the RMObject + * + * @param rmClass + * @return empty map if not found rm class + */ + private Map attributeType(Class rmClass) { + + Map map = new HashMap(); + Constructor constructor = fullConstructor(rmClass); + if (constructor == null) { + return map; + } + Annotation[][] annotations = constructor.getParameterAnnotations(); + Class[] types = constructor.getParameterTypes(); + + if (annotations.length != types.length) { + throw new IllegalArgumentException("less annotations"); + } + for (int i = 0; i < types.length; i++) { + if (annotations[i].length == 0) { + throw new IllegalArgumentException( + "missing annotations of attribute " + i); + } + Attribute attribute = (Attribute) annotations[i][0]; + map.put(attribute.name(), types[i]); + } + return map; + } + + /** + * Return a map with name as the key and index of position as the value for + * all parameters of the full constructor in the RMObject + * + * @param rmClass + * @return + */ + private Map attributeIndex(Class rmClass) { + Map map = new HashMap(); + Constructor constructor = fullConstructor(rmClass); + Annotation[][] annotations = constructor.getParameterAnnotations(); + + for (int i = 0; i < annotations.length; i++) { + if (annotations[i].length == 0) { + throw new IllegalArgumentException( + "missing annotation at position " + i); + } + Attribute attribute = (Attribute) annotations[i][0]; + map.put(attribute.name(), i); + } + return map; + } + + /** + * Return a map with name as the key and index of position as the value for + * all parameters of the full constructor in the RMObject + * + * @param rmClass + * @return + */ + private Map attributeMap(Class rmClass) { + Map map = new HashMap(); + Constructor constructor = fullConstructor(rmClass); + Annotation[][] annotations = constructor.getParameterAnnotations(); + + for (int i = 0; i < annotations.length; i++) { + if (annotations[i].length == 0) { + throw new IllegalArgumentException( + "missing annotation at position " + i); + } + Attribute attribute = (Attribute) annotations[i][0]; + map.put(attribute.name(), attribute); + } + return map; + } + + private static Constructor fullConstructor(Class klass) { + if(klass == null) { + return null; + } + Constructor[] array = klass.getConstructors(); + for (Constructor constructor : array) { + if (constructor.isAnnotationPresent(FullConstructor.class)) { + return constructor; + } + } + return null; + } + + /** + * Retrieves RM type using given name try both the CamelCase and + * Underscore-separated ways + * + * @param rmClassName + * @return null if not found + */ + public Class retrieveRMType(String rmClassName) { + log.debug("Getting rmClass for "+rmClassName); + Class rmClass = typeMap.get(rmClassName); + if (rmClass == null) { + rmClass = upperCaseMap.get(rmClassName.replace("_", "")); + } + + log.debug("Retrieved rmClass is: "+ rmClass); + return rmClass; + } + + /** + * Retrieves Map of attribute classes indexed by names of given class + * + * @param rmClassName + * @return + * @throws RMObjectBuildingException + */ + public Map retrieveRMAttributes(String rmClassName) { + Class rmClass = retrieveRMType(rmClassName); + + log.debug("----- rmClassName: "+ rmClassName); + log.debug("rmClass: "+ rmClass.getSimpleName()); + + + Map map = attributeType(rmClass); + Map ret = new HashMap(); + for(String name : map.keySet()) { + ret.put(toUnderscoreSeparated(name), map.get(name)); + + log.debug("rmattribute: " +name +": "+ map.get(name)); + } + return ret; + } + + /** + * Retrieves list of attribute names of given class; each name is converted + * from camel case to underscore delimited form + * + * @param rmClassName + * @return + * @throws RMObjectBuildingException + */ + public Set retrieveRMAttributeNames(String rmClassName) { + Class rmClass = retrieveRMType(rmClassName); + + // WHAT TO DO HERE IF not found (e.g. CODED_TEXT would not be found...) + log.debug("----- rmClassName: "+ rmClassName); + log.debug("rmClass: "+ rmClass.getSimpleName()); + + Map map = attributeType(rmClass); + Set names = new LinkedHashSet(); + for(String name : map.keySet()) { + names.add(toUnderscoreSeparated(name)); + + log.debug("name: " +name); + } + return names; + } + + public String toCamelCase(String underscoreSeparated) { + StringTokenizer tokens = new StringTokenizer(underscoreSeparated, "_"); + StringBuffer buf = new StringBuffer(); + while (tokens.hasMoreTokens()) { + String word = tokens.nextToken(); + if (buf.length() == 0) { + buf.append(word); + } else { + buf.append(word.substring(0, 1).toUpperCase()); + buf.append(word.substring(1)); + } + } + return buf.toString(); + } + + public String toUnderscoreSeparated(String camelCase) { + String[] array = StringUtils.splitByCharacterTypeCamelCase(camelCase); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < array.length; i++) { + String s = array[i]; + buf.append(s.substring(0, 1).toLowerCase()); + buf.append(s.substring(1)); + if (i != array.length - 1) { + buf.append("_"); + } + } + return buf.toString(); + } + + /** + * Finds the matching RM class that can be used to create RM object for + * given value map + * + * @param valueMap + * @return null if no match RM class is found + */ + public String findMatchingRMClass(Map valueMap) { + List simpleTypes = Arrays.asList(SKIPPED_TYPES_IN_MATCHING); + + for (Class rmClass : typeMap.values()) { + + log.debug("matching rmClass: " + rmClass.getName()); + + if (simpleTypes.contains(rmClass.getSimpleName())) { + continue; // skip simple value types + } + + // replace underscore separated names with camel case + Map filteredMap = new HashMap(); + for (String name : valueMap.keySet()) { + filteredMap.put(toCamelCase(name), valueMap.get(name)); + } + + Constructor constructor = fullConstructor(rmClass); + if (constructor == null) { + throw new RuntimeException("annotated constructor missing for " + + rmClass); + } + Annotation[][] annotations = constructor.getParameterAnnotations(); + if (annotations == null || annotations.length == 0) { + throw new RuntimeException("attribute annotations missing for " + + rmClass); + } + Class[] types = constructor.getParameterTypes(); + boolean matched = true; + Set attributes = new HashSet(); + + for (int i = 0; i < types.length; i++) { + if (annotations[i].length == 0) { + throw new RuntimeException( + "attribute annotation missing for" + rmClass); + } + Attribute attribute = (Attribute) annotations[i][0]; + attributes.add(attribute.name()); + + log.debug("checking attribute: " + attribute.name()); + + String attrName = attribute.name(); + Object attrValue = filteredMap.get(attrName); + + if (attribute.required() && attrValue == null) { + + log.debug("missing required attribute.."); + + matched = false; + break; + + } else if (attrValue != null) { + if (((attrValue instanceof Boolean) && types[i] != boolean.class) + || ((attrValue instanceof Integer) && types[i] != Integer.class) + || ((attrValue instanceof Double) && types[i] != double.class)) { + + log.debug("wrong primitive value type for attribute.."); + matched = false; + break; + + } else if (!types[i].isPrimitive() + && !types[i].isInstance(attrValue)) { + log.debug("wrong value type for attribute.."); + matched = false; + break; + + } + } + } + + for (String attr : filteredMap.keySet()) { + if (!attributes.contains(attr)) { + + log.debug("unknown attribute: " + attr); + + matched = false; + } + } + + // matching found + if (matched) { + String className = rmClass.getSimpleName(); + + log.debug(">>> MATCHING FOUND: " + className); + + return className; + } + } + return null; + } + + // todo: isn't there any support from java api on this? + private Object defaultValue(Class type) { + if (type == boolean.class) { + return Boolean.FALSE; + } else if (type == double.class) { + return new Double(0); + } else if (type == float.class) { + return new Float(0); + } else if (type == int.class) { + return new Integer(0); + } else if (type == short.class) { + return new Short((short) 0); + } else if (type == long.class) { + return new Long(0); + } else if (type == char.class) { + return new Character((char) 0); + } else if (type == byte.class) { + return new Byte((byte) 0); + } + return null; + } + + /** gets the default cardinality interval as specified by the reference model. + * In most cases this is 0..*, only in very few cases this has been constrained to 1..* + * RECONSIDER: This could be done using annotations as well, however for the couple of constraints from the RM, + * the approach taken here seems to be simple and sufficient. + * + * @param cattr + * @param parentObj + * @return + */ + Interval defaultCardinalityInterval(CMultipleAttribute cattr, CObject parentObj) { + log.debug("Checking: "+ cattr.getRmAttributeName() +"; "+ parentObj.getRmTypeName() +" at "+cattr.path() +" parent path: "+parentObj.path()); + + if (cattr.getRmAttributeName().equals("items")) { + if (parentObj.getRmTypeName().equalsIgnoreCase("CLUSTER") ) { // Note: For SECTION items, the intention seems to be cardinality = 0 + log.debug("--> >=1"); + return new Interval(1,null); + } + } else if (cattr.getRmAttributeName().equals("content")) { + if (parentObj.getRmTypeName().equalsIgnoreCase("COMPOSITION")) { + log.debug("--> >=1"); + return new Interval(1,null); + } + /* } else if (cattr.getRmAttributeName().equals("activities")) { // This seems to be incorrect + if (parentObj.getRmTypeName().equalsIgnoreCase("INSTRUCTION")) { + log.debug("--> >=1"); + return new Interval(1,null); + } + *//* } else if (cattr.getRmAttributeName().equals("events")) { // this seems to be too strict as well + if (parentObj.getRmTypeName().equalsIgnoreCase("HISTORY")) { + log.debug("--> >=1"); + return new Interval(1,null); + } + */ } else if (cattr.getRmAttributeName().equals("credentials")) { + if (parentObj.getRmTypeName().equalsIgnoreCase("CAPABILITY")) { + log.debug("--> ==1"); + return new Interval(1,1); + } + } + log.debug("--> >=0"); + return new Interval(0,null); // not constrained + + } + + /* + * Skipped types during matching: 1. Simple value types in DADL 2. Cluster + * due to clash with ItemList + */ + private static final String[] SKIPPED_TYPES_IN_MATCHING = { "DvDateTime", + "DvDate", "DvTime", "DvDuration", "Cluster", + // due to clash with DvText + "TerminologyID", "ArchetypeID", "TemplateID", "ISO_OID", + "HierObjectID", "DvBoolean", "InternetID", "UUID", + "ObjectVersionID" + }; + + + /* logger */ + private static final Logger log = Logger.getLogger(RMInspector.class); + + // loaded rm type map + private Map typeMap; + private Map upperCaseMap; + private static final Set stringParsingTypes; + + static { + // so far only types from quantity.datetime + stringParsingTypes = new HashSet(); + String[] types = { "DvDate", "DvDateTime", "DvTime", "DvDuration", + "DvPartialDate", "DvPartialTime" }; + stringParsingTypes.addAll(Arrays.asList(types)); + } +} diff --git a/archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java b/archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java new file mode 100644 index 00000000..115b1e37 --- /dev/null +++ b/archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java @@ -0,0 +1,767 @@ +package org.openehr.am.validation; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map.Entry; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; +import org.openehr.am.archetype.constraintmodel.ArchetypeInternalRef; +import org.openehr.am.archetype.constraintmodel.CAttribute; +import org.openehr.am.archetype.constraintmodel.CAttribute.Existence; +import org.openehr.am.archetype.constraintmodel.CComplexObject; +import org.openehr.am.archetype.constraintmodel.CMultipleAttribute; +import org.openehr.am.archetype.constraintmodel.CObject; +import org.openehr.am.archetype.constraintmodel.Cardinality; +import org.openehr.am.archetype.constraintmodel.ConstraintRef; +import org.openehr.am.archetype.ontology.ArchetypeTerm; +import org.openehr.am.archetype.ontology.OntologyDefinitions; +import org.openehr.rm.common.resource.TranslationDetails; + + +public class SpecialisedArchetypeValidator extends ArchetypeValidator { + + public SpecialisedArchetypeValidator() { + super(); + } + + + /** + * Validates the given specialised archetype including specialised validation to its stated parent archetype + * + * @param archetype + * @param parentArchetype + * @param reportConstraintsOnFunctionalPropertiesAsInfo if set to true, constraints on functional properties such as "is_integral" as part of DV_PROPORTION and "offset" in EVENT are reported as info only. If set to false (default), they are reported as errors. + * @return list of validation errors or empty list if valid + */ + + public List validate(Archetype archetype, Archetype parentArchetype, boolean reportConstraintsOnCommonFunctionalPropertiesAsInfo) + throws RMInspectionException { + List errors = new ArrayList(); + // normal non-specialised validation first. + errors.addAll(validate(archetype, reportConstraintsOnCommonFunctionalPropertiesAsInfo)); + + int childSpecialisationDepth = StringUtils.countMatches(archetype.getArchetypeId().domainConcept(), "-"); + + checkSpecialisedObjectConstraints(archetype, parentArchetype, childSpecialisationDepth, errors); + checkSpecialisationHierarchyOfAllAtAndAcCodesInTheDefinition(archetype, childSpecialisationDepth, errors); + log.debug("-- Error size:" +errors.size()); + for (ValidationError error : errors) { + log.debug("Error: " + error.getType() + " "+ error.getText()); + } + return errors; + + } + + + public void checkSpecialisationHierarchyOfAllAtAndAcCodesInTheDefinition(Archetype archetype, int childSpecialisationDepth, Listerrors) { + for (String atCode : fetchAllATCodes(archetype)) { + // For all codes: An extra check that the code is no specialised more than the maximum specialisation depth + if (StringUtils.countMatches(atCode, ".") > childSpecialisationDepth) { + errors.add (new ValidationError (ErrorType.VATCD, null, + atCode, StringUtils.countMatches(atCode, "."), childSpecialisationDepth)); + } + } + + for (String acCode : fetchAllACCodes(archetype)) { + // For all codes: An extra check that the code is no specialised more than the maximum specialisation depth + if (StringUtils.countMatches(acCode, ".") > childSpecialisationDepth) { + errors.add (new ValidationError (ErrorType.VATCD, null, + acCode, StringUtils.countMatches(acCode, "."), childSpecialisationDepth)); + } + } + } + + public void checkSpecialisedObjectConstraints(Archetype archetype, + Archetype parentArchetype, int childSpecialisationDepth, List errors) throws RMInspectionException { + validateSpecialisedCComplexObject(archetype.getDefinition(), archetype, parentArchetype, childSpecialisationDepth, errors); + + } + private void validateSpecialisedCComplexObject(CComplexObject ccobj, Archetype archetype, + Archetype parentArchetype, int childSpecialisationDepth, List errors) throws RMInspectionException { + + String parentPath = getExpectedPathInParentArchetype(ccobj.path(), childSpecialisationDepth-1); + String parentPathOrig = parentPath; + boolean continueWithAttributes = true; + + if (parentPath != null) { + CObject parentNode = (CObject)parentArchetype.node(parentPath); + + if (parentNode == null) { + log.debug("No parent node found for path: "+ parentPath + " (child path: "+ ccobj.path()); + + int goingUpTheSpecTree = childSpecialisationDepth -2; + boolean foundParentFurtherUp = false; + + // if it wasn't found, we have to check further up in the hierarchy of node ids to see if it + // is totally missing or if there is an error of the level of specialisation of the node id (e.g. at0001.1 where it should be at0001.0.1 + while (goingUpTheSpecTree >=0) { + parentPath = getExpectedPathInParentArchetype(ccobj.path(), goingUpTheSpecTree); + if (parentPath !=null) { + parentNode = (CObject)parentArchetype.node(parentPath); + if (parentNode != null) { + foundParentFurtherUp = true; + } + } + goingUpTheSpecTree -=1; + } + + if (foundParentFurtherUp) { + errors.add(new ValidationError(ErrorType.VSONCI, null, + ccobj.getNodeId(), parentNode.getNodeId())); + } else if (parentPath != null && parentPath.length() > 0 && (parentPath.endsWith("]") || + parentPath.endsWith(ArchetypeConstraint.PATH_SEPARATOR) || Character.isDigit(parentPath.charAt(parentPath.length()-1)))){ + // we do not want anything in there that ends with an attribute - e.g. /data[at0001]/items[at0004]/items[at0002]/items[at0003]/value as this is just a constraint introduced, but no at code + if (StringUtils.countMatches(ccobj.getNodeId(), ".") == childSpecialisationDepth) { + errors.add (new ValidationError (ErrorType.VATDF, "SPECIALISED", + parentPath, ccobj.path())); + } else { + errors.add (new ValidationError (ErrorType.VATDF, "INTRODUCED", + parentPath)); + } + } else if (parentPath==null) { + errors.add (new ValidationError (ErrorType.VATDF, "INTRODUCED", + parentPathOrig)); + } + + continueWithAttributes= false; + // node must be in ontology of parent.... + } else { + if (parentNode instanceof ArchetypeInternalRef) { + // if the child is a redefine of a parent use_node, then have to do the comparison to the + // use_node target, unless they both are use_nodes, in which case leave them as is + // Note: ccobj cannot be an ArchetypeInternalRef anyway - Thomas' Eiffel code is slightly different, so he needs to check... + parentNode = (CObject)parentArchetype.node(((ArchetypeInternalRef) parentNode).getTargetPath()); + } + + if (ccobj.getNodeId() != null) { + String parentNodeId = getExpectedPathInParentArchetype(ccobj.getNodeId(), childSpecialisationDepth-1); + log.debug("Checking that the corresponding term is in the parent archetype: "+parentNodeId + " for "+ccobj.getNodeId()); + + if (!checkDynamicArchetypeType(parentNode, ccobj, errors)) { + return; // if there is an error in the dynamic types already, this is so wrong, that we skip any subsequent validation. + } + + checkTermExistsInParent(parentArchetype, parentNodeId, errors); + // not sure this would ever do anything with the above VSONCI validation - as it would never find the parent in the first place + continueWithAttributes = checkSpecialisedNodeIdConformance(parentNode, ccobj,childSpecialisationDepth, errors); // VSONCI + checkNodeIdIsSpecialisedIfRequired(parentNode, ccobj, parentArchetype, archetype, errors); //VSONIR + + } + checkSpecialisedRMTypeCompatiblityForNonValueItems(parentNode, ccobj, errors); // VSONCT + + } + } else { + log.debug("No appropriate path exists in parent for child path: "+ccobj.path()); // this would be ok - newly introduced node without a parent, no further validation is required. + } + + + //VSONCI method not used - why + + // now check for all its attributes, which in turn check for all its cobjects again... + if(ccobj.getAttributes() != null && continueWithAttributes) { + for (CAttribute cattr : ccobj.getAttributes()) { + checkSpecialisedAttribute(cattr, archetype, parentArchetype, childSpecialisationDepth, errors); + } + } + } + + + + /** Checks that the dynamic class of the node and its corresponding node in the parent are equal (e.g. both CCOmplexObjects) + * VSONT + * + * @param parentNode + * @param ccobj + * @param errors + * @return true if all is ok, false otherwise, as this is a fatal condition + */ + private boolean checkDynamicArchetypeType(CObject parentNode, + CComplexObject ccobj, List errors) { + if (!ccobj.getClass().getSimpleName().equals(parentNode.getClass().getSimpleName())) { + errors.add(new ValidationError(ErrorType.VSONT, null, + ccobj.getClass().getSimpleName(), ccobj.path(), parentNode.getClass().getSimpleName())); + return false; + } + return true; + + } + + + private void checkSpecialisedAttribute(CAttribute cattr, Archetype archetype, + Archetype parentArchetype, int childSpecialisationDepth, List errors) throws RMInspectionException { + + // perform validations for attributes + String parentNodePathInParentArchetype = getExpectedPathInParentArchetype(cattr.parentNodePath(), childSpecialisationDepth-1); + CAttribute attrInParentArchetype = null; + if (parentNodePathInParentArchetype != null) { + CObject parentNodeInParentArchetype = null; + if (parentNodePathInParentArchetype.length()<=1) { + parentNodeInParentArchetype = parentArchetype.getDefinition(); + } else { + parentNodeInParentArchetype = (CObject)parentArchetype.node(parentNodePathInParentArchetype); + } + + if (parentNodeInParentArchetype == null) { + log.debug("PARENT NODE IN PARENT ARCHETYPE IS NULL"); + } + + if (parentNodeInParentArchetype instanceof CComplexObject) { + attrInParentArchetype = ((CComplexObject) parentNodeInParentArchetype).getAttribute(cattr.getRmAttributeName()); + } else { + // Can we really simply ignore this case where the parent node in the parent archetype is not a CComplexObject or do we need to introduce other handling here for _DV_QUANTITY and the like? + log.debug("PARENT NODE IN PARENT ARCHETYPE IS NOT A CCOMPLEXOBJECT, BUT "+ parentNodeInParentArchetype.getClass().getName()); + } + } + + if (attrInParentArchetype != null) { + checkSpecialisedAttributeNodeExistenceConformance(cattr, attrInParentArchetype, errors); //VSANCE + checkSpecialisedAttributeMultiplicityConformance(cattr, attrInParentArchetype, errors); // VSAM + checkSpecialisedAttributeNodeCardinalityConformance(cattr, attrInParentArchetype, errors); //VSANCC + } + + + // now get all the attribute's children and validate them. + if (cattr.getChildren() != null) { + for (CObject cobj : cattr.getChildren()) { + log.debug("-----"); + log.debug(cobj.getRmTypeName() + " " +cobj.path()); + + if (cobj instanceof CComplexObject) { + validateSpecialisedCComplexObject((CComplexObject)cobj, archetype, parentArchetype, childSpecialisationDepth, errors); + } else if (cobj instanceof ConstraintRef) { + checkSpecialisedConstraintRefConformance((ConstraintRef) cobj, archetype, parentArchetype, childSpecialisationDepth, errors); + } + + validateSpecialisedCObject(cobj, archetype, parentArchetype, childSpecialisationDepth, errors); + } + + // if we have a value field which is a choice, we want to make sure that all restrictions are a correct restriction of the + // parent values (whereas if this e.g. is a normal cluster with several items we can add some more that are not of the same or a compatible ref model type. + if (cattr.getRmAttributeName().equals("value")) { + checkSpecialisedRMTypeCompatiblityOfValueChildren(cattr, parentArchetype, childSpecialisationDepth, errors); // VSONCT + } + } + } + + private void validateSpecialisedCObject(CObject cobj, Archetype archetype, + Archetype parentArchetype, int childSpecialisationDepth, List errors) { + String pathInParent = getExpectedPathInParentArchetype(cobj.path(), childSpecialisationDepth-1); + if (pathInParent== null) { + return; + } + + CObject nodeInParent = (CObject)parentArchetype.node(pathInParent); + + if (nodeInParent == null) { + return; + } + + checkSpecialisedOccurrencesCompatiblity(nodeInParent, cobj, errors); + } + + + /** Checks for conformance of a constraint ref + * VSCNR: placeholder constraint node conformance: a placeholder node can only + * be defined into a reference model type conformant with the type of the original constraint + * in the parent archetype. + * + * @param cobj + * @param archetype + * @param parentArchetype + * @param errors + */ + private void checkSpecialisedConstraintRefConformance(ConstraintRef cr, + Archetype archetype, Archetype parentArchetype, int childSpecialisationDepth, + List errors) { + String pathInParent = getExpectedPathInParentArchetype(cr.path(), childSpecialisationDepth-1); + if (pathInParent== null) { + return; + } + + CObject nodeInParent = (CObject)parentArchetype.node(pathInParent); + + if (nodeInParent == null) { + return; + } + + /* Not sure what needs to be checked for a VSCNR error, this is not it. + Class parentRMType = + rmInspector.retrieveRMType(nodeInParent.getRmTypeName()); + Class childRMType = rmInspector.retrieveRMType(cr.getRmTypeName()); + if (! parentRMType.isAssignableFrom(childRMType)) { + errors.add(new ValidationError(ErrorType.VSCNR, "The reference model type ("+childRMType.getSimpleName()+") of the placeholder (Reference) "+cr.getReference()+" at "+cr.path()+" in the specialised archetype is not assignable from the reference model type ("+parentRMType.getSimpleName()+") of the corresponding placeholder in the parent archetype.")); + } + */ + // also check occurrences + + } + + + /** Checks that the existence of the parent archetype's corresponding attribute is conformant + * with the child archetype's attribute in the sense of VSANCE error validation + * + * @param cattr + * @param attrInParentArchetype + * @param errors + */ + private void checkSpecialisedAttributeNodeExistenceConformance( + CAttribute cattr, CAttribute attrInParentArchetype, + List errors) { + + if ((cattr.getExistence() == Existence.OPTIONAL && + (attrInParentArchetype.getExistence() == Existence.REQUIRED || + attrInParentArchetype.getExistence() == Existence.NOT_ALLOWED)) + || + (cattr.getExistence() == Existence.REQUIRED && + attrInParentArchetype.getExistence() == Existence.NOT_ALLOWED) + || (cattr.getExistence() == Existence.NOT_ALLOWED && + attrInParentArchetype.getExistence() != Existence.NOT_ALLOWED) + ) { + errors.add(new ValidationError(ErrorType.VSANCE, null, + cattr.getExistence().toString(), cattr.path(), attrInParentArchetype.getExistence(), attrInParentArchetype.path())); + } + } + + /** Checks that the multiplicity of the parent archetype's corresponding attribute is conformant + * with the child archetype's attribute in the sense of VSAM error validation + * + * @param cattr + * @param attrInParentArchetype + * @param errors + */ + private void checkSpecialisedAttributeMultiplicityConformance( + CAttribute cattr, CAttribute attrInParentArchetype, + List errors) { + + if (cattr instanceof CMultipleAttribute && !(attrInParentArchetype instanceof CMultipleAttribute)) { + errors.add(new ValidationError(ErrorType.VSAM, "MULTIPLE", + cattr.path(), attrInParentArchetype.path())); + } + // if it is the other way round, this is okay, as the cardinality is contained. + if (!(cattr instanceof CMultipleAttribute) && (attrInParentArchetype instanceof CMultipleAttribute)) { + errors.add(new ValidationError(ErrorType.VSAM, "SINGLE", + cattr.path(), attrInParentArchetype.path())); + } + + } + + + /** Checks that the cardinality of the parent archetype's corresponding attribute is conformant + * with the child archetype's attribute in the sense of VSANCC error validation + * + * @param cattr + * @param attrInParentArchetype + * @param errors + */ + private void checkSpecialisedAttributeNodeCardinalityConformance( + CAttribute cattr, CAttribute attrInParentArchetype, + List errors) { + + // if not both are CMultipleAttributes, there is nothing to check here (this would be a VSAM error) + if (!(cattr instanceof CMultipleAttribute) || !(attrInParentArchetype instanceof CMultipleAttribute)) { + return; + } + + CMultipleAttribute cmattr = (CMultipleAttribute) cattr; + CMultipleAttribute cmParentAttr = (CMultipleAttribute) attrInParentArchetype; + + Cardinality cardAttr = cmattr.getCardinality(); + + Cardinality cardParentAttr = cmParentAttr.getCardinality(); + + if (! cardParentAttr.getInterval().isUpperUnbounded() + && ( cardAttr.getInterval().isUpperUnbounded() + || cardParentAttr.getInterval().getUpper().compareTo( + cardAttr.getInterval().getUpper()) <0)) { + errors.add(new ValidationError(ErrorType.VSANCC, null, + getIntervalFormalString(cardAttr.getInterval()), cattr.path(), getIntervalFormalString(cardParentAttr.getInterval()), attrInParentArchetype.path())); + } else if (cardParentAttr.getInterval().getLower().compareTo( + cardAttr.getInterval().getLower()) >0) { + log.debug("Cardinality error"); + errors.add(new ValidationError(ErrorType.VSANCC, null, + getIntervalFormalString(cardAttr.getInterval()), cattr.path(), getIntervalFormalString(cardParentAttr.getInterval()), attrInParentArchetype.path())); + } + } + + + /* Checks that the specialised node id is a correct id in the sense of VSONCI + * @return true if all is ok, false if not (as this is a fatal error for any further validation) + */ + private boolean checkSpecialisedNodeIdConformance(CObject parentNode, + CComplexObject ccobj, int childSpecialisationDepth, List errors) { + //TODO THis is not used anywhere!! + if (ccobj.getNodeId().equals(parentNode.getNodeId())) { + return true; // identical, which is ok (non-specialised) + } + + if (StringUtils.countMatches(ccobj.getNodeId(), ".") == childSpecialisationDepth) { + return true; // correct number of specialisations. + } + + errors.add(new ValidationError(ErrorType.VSONCI, null, + ccobj.getNodeId(), parentNode.getNodeId())); + return false; + + } + + + /** Checks that the node is specialised if required in the sense of VSONIR. + * I.e. it needs to be redefined if any aspect of the immediate object constraint is redefined. + * + * @param parentNode + * @param ccobj + * @param errors + */ + private void checkNodeIdIsSpecialisedIfRequired(CObject parentNode, + CComplexObject ccobj, Archetype parentArchetype, Archetype archetype, List errors) { + if (!ccobj.getNodeId().equals(parentNode.getNodeId())) { + return; // they don't have the same node id, so we don't need to check here + } + + if (!equalsDirect(ccobj,parentNode)) { + // If they are different, but have the same node id, this is a VSONIR error. + errors.add(new ValidationError(ErrorType.VSONIR, "NORMAL", + ccobj.path(), ccobj.getRmTypeName(), parentNode.getRmTypeName(), ccobj.getNodeId())); + + } else { + // We also want to check whether term descriptions and texts are inconsistent between the two archetypes. + // This is something that wouldn't occur with source ADLS for the specialisation, as it is excluded automatically, but hence we are using flat archetypes for both child and parent + String langPrim = archetype.getOriginalLanguage().getCodeString(); + + if (!archetype.getOntology().termDefinition(langPrim, ccobj.getNodeId()).equals( + parentArchetype.getOntology().termDefinition(langPrim, ccobj.getNodeId()))) { + if (archetype.getOntology().termDefinition(langPrim, ccobj.getNodeId()) !=null) { + log.debug("child desc: "+archetype.getOntology().termDefinition(langPrim, ccobj.getNodeId()).getText()); + log.debug("child desc: "+archetype.getOntology().termDefinition(langPrim, ccobj.getNodeId()).getDescription()); + } + if (parentArchetype.getOntology().termDefinition(langPrim, ccobj.getNodeId()) !=null) { + log.debug("parent desc: "+ parentArchetype.getOntology().termDefinition(langPrim, ccobj.getNodeId()).getText()); + log.debug("parent desc: "+ parentArchetype.getOntology().termDefinition(langPrim, ccobj.getNodeId()).getDescription()); + } + // if the node doesn't exist in the parent at all, this is a VATDF error, checked elsewhere. + if (parentArchetype.getOntology().termDefinition(langPrim, ccobj.getNodeId()) != null) { + errors.add(new ValidationError(ErrorType.VSONIR, "TEXTDESCRIPTION", + ccobj.path(), ccobj.getRmTypeName(), parentNode.getRmTypeName(), ccobj.getNodeId(), langPrim)); + + } + } + else { + // if the main text and description is ok, we still should check that this is true for all translations as well + if (archetype.getTranslations() != null && archetype.getTranslations().entrySet()!= null) { + for (Entry trans : archetype.getTranslations().entrySet()) { + if (!archetype.getOntology().termDefinition(trans.getValue().getLanguage().getCodeString(), ccobj.getNodeId()).equals( + parentArchetype.getOntology().termDefinition(trans.getValue().getLanguage().getCodeString(), ccobj.getNodeId()))) { + // if the node doesn't exist in the parent at all, this is a VATDF error, checked elsewhere. + if (parentArchetype.getOntology().termDefinition(trans.getValue().getLanguage().getCodeString(), ccobj.getNodeId()) != null) { + errors.add(new ValidationError(ErrorType.VSONIR, "TEXTDESCRIPTION", + ccobj.path(), ccobj.getRmTypeName(), parentNode.getRmTypeName(), ccobj.getNodeId(), trans.getValue().getLanguage().getCodeString())); + } + } + } + } + } + } + } + + + /** Checks that the occurrences of the corresponding node in the parent conforms to the specialised node's occurrences + * + * @param parentNode + * @param ccobj + * @param errors + */ + private void checkSpecialisedOccurrencesCompatiblity(CObject parentNode, + CObject ccobj, List errors) { + + if (! parentNode.getOccurrences().isUpperUnbounded() + && ( ccobj.getOccurrences().isUpperUnbounded() + || parentNode.getOccurrences().getUpper().compareTo( + ccobj.getOccurrences().getUpper()) <0)) { + + errors.add(new ValidationError (ErrorType.VSONCO, null, + getIntervalFormalString(ccobj.getOccurrences()), ccobj.path(), getIntervalFormalString(parentNode.getOccurrences()), parentNode.path())); + } + } + + /** Checks that the RM type of the parent's corresponding node conforms to the child'S node RM type. + * + * @param parentNode + * @param ccobj + * @param errors + */ + + private void checkSpecialisedRMTypeCompatiblityForNonValueItems(CObject parentNode, + CComplexObject ccobj, List errors) { + if (ccobj.path().endsWith("value") || ccobj.path().endsWith("value/")) + { + return; // as value items have a choice construct without further node ids we need to test these differently, i.e. as a whole for all value restrictions. + } + + String rmChild = ccobj.getRmTypeName(); + + rmChild = removeGenericTypes(rmChild); + Class childRMType = + rmInspector.retrieveRMType(rmChild); + + String rmParent = parentNode.getRmTypeName(); + rmParent = removeGenericTypes(rmParent); + Class parentRMType = + rmInspector.retrieveRMType(rmParent); + + if (parentRMType == null || rmChild == null) { + errors.add (new ValidationError(ErrorType.VSONCT, "UNKNOWN", + rmChild, ccobj.path(), rmParent)); + // or simply return ?? // there is a problem with the rmtypes (probably one that is unknown), this is a different validation, so ignore here. + } else if (! parentRMType.isAssignableFrom(childRMType)) { + errors.add (new ValidationError(ErrorType.VSONCT, "NORMAL", + childRMType.getSimpleName(), ccobj.path(), parentRMType.getSimpleName())); + } + } + + /** Checks that the RM type(s) of the parent's corresponding node conforms to the child's node RM type(s). + * Note that because of choice type (multiple constraints to choose from), we need to test this for all children of an attribute at ones. + * + * @param parentNode + * @param ccobj + * @param errors + */ + private void checkSpecialisedRMTypeCompatiblityOfValueChildren(CAttribute cattr, + Archetype parentArchetype, int childArchetypeSpecialisationDepth, List errors) { + if (cattr.getChildren() == null || cattr.getChildren().size() ==0) { + return; // nothing to test + } + + List children = cattr.getChildren(); + + String parentPath = getExpectedPathInParentArchetype(cattr.parentNodePath(), childArchetypeSpecialisationDepth-1); + if (parentPath == null) { + return; // nothing to test + } + CObject parentNode =(CObject) parentArchetype.node(parentPath); + if (parentNode == null || !(parentNode instanceof CComplexObject)) { + return; + } + CComplexObject parentCNode = (CComplexObject) parentNode; + CAttribute parentAttr = parentCNode.getAttribute(cattr.getRmAttributeName()); + if (parentAttr == null || parentAttr.getChildren() == null || parentAttr.getChildren().size() == 0) { + return; // not restricted, nothing to test + } + + HashMap parentObjectsToRMTypesWithoutGenerics = new HashMap(); + for (CObject childInParent : parentAttr.getChildren()) { + // for all children - not only CComplexObjects - because of e.g. C_DV_QUANTITY constraints + String childInParentRMTypeWithoutGenerics = removeGenericTypes(childInParent.getRmTypeName()); + Class parentRMType = rmInspector.retrieveRMType(childInParentRMTypeWithoutGenerics); + if (parentRMType == null) { + errors.add (new ValidationError(ErrorType.VSONCT, "UNKNOWNFORPARENT", + childInParent.getRmTypeName(), childInParent.path())); + } else { + parentObjectsToRMTypesWithoutGenerics.put(childInParent, parentRMType); + } + } + + if (parentObjectsToRMTypesWithoutGenerics.size() == 0) { + return; + } + + for (CObject child : children) { + String rmChildWithoutGenerics = removeGenericTypes(child.getRmTypeName()); + Class childRMType = + rmInspector.retrieveRMType(rmChildWithoutGenerics); + if (childRMType == null) { + continue; // This is a different error and does not need to be tested here. + } + + boolean assignable = false; + // it needs to be assignable to at least one of them! This is relevant for choice datatypes + for (Entry parentToRMTypeWithoutGenerics : parentObjectsToRMTypesWithoutGenerics.entrySet()) { + if (parentToRMTypeWithoutGenerics.getValue().isAssignableFrom(childRMType)) { + + // the non-generic part is assignable, + // now we need to check if the generic part (if existing) is assignable as well. + String genericTypeInParentArchetype = getGenericType (parentToRMTypeWithoutGenerics.getKey().getRmTypeName()); + if (genericTypeInParentArchetype != null) { + String genericTypeInChildArchetype = getGenericType(child.getRmTypeName()); + if (genericTypeInChildArchetype != null) { + // if the parent generic type is set, but genericTypeInChildArchetype is not defined, this is not an assignable combination + Class childGenericRMType = + rmInspector.retrieveRMType(genericTypeInChildArchetype); + Class parentGenericRMType = + rmInspector.retrieveRMType(genericTypeInParentArchetype); + if (childGenericRMType != null && parentGenericRMType!=null && parentGenericRMType.isAssignableFrom(childGenericRMType)) { + assignable = true; + break; + } + } + } else { + assignable = true; + break; + } + } + } + + if (!assignable) { + log.debug("VSONCT error: at "+child.path()); + String parentRefTypes = ""; + for (Entry parentToRMTypeWithoutGenerics: parentObjectsToRMTypesWithoutGenerics.entrySet()) { + parentRefTypes += parentToRMTypeWithoutGenerics.getValue().getSimpleName() +", "; + } + parentRefTypes = parentRefTypes.substring(0,parentRefTypes.length()-2); + + if (parentObjectsToRMTypesWithoutGenerics.size() ==1) { + errors.add (new ValidationError(ErrorType.VSONCT, "NORMAL", + childRMType.getSimpleName(), child.path(), parentRefTypes)); + } else { + // more than one RM type possible + errors.add (new ValidationError(ErrorType.VSONCT, "MORETHANONE", + childRMType.getSimpleName(), child.path(), parentRefTypes)); + } + } + } + } + + + private void checkTermExistsInParent(Archetype parentArchetype, String code, + List errors) { + + String lang = parentArchetype.getOriginalLanguage().getCodeString(); + List defList = + parentArchetype.getOntology().getTermDefinitionsList(); + OntologyDefinitions priDefs = null; + ValidationError error = null; + + for(OntologyDefinitions defs : defList) { + if(lang.equals(defs.getLanguage())) { + priDefs = defs; + } + } + if(priDefs == null) { + error = new ValidationError(ErrorType.VATDF, "INPARENT", + code); + errors.add(error); + } else { + List terms = priDefs.getDefinitions(); + Set definedCodes = new LinkedHashSet(); + for(ArchetypeTerm term : terms) { + definedCodes.add(term.getCode()); + } + if( ! definedCodes.contains(code)) { + error = new ValidationError(ErrorType.VATDF, "INPARENT", + code); + errors.add(error); + } + } + + } + + + + + /** Calculates the expected path in a parent archetype derived from the given path. + * + * @param path + * @return + */ + private String getExpectedPathInParentArchetype(String path, int parentArchetypeSpecialisationDepth) { + log.debug("Path to unspecialise: "+ path); + log.debug("parent specialisation depth: "+ parentArchetypeSpecialisationDepth); + String sep=ArchetypeConstraint.PATH_SEPARATOR; + String expectedPath=path.startsWith(sep) ? sep :""; // only add the separator to the beginning if it is there in the original path (which may also be a simple node id... + ArrayList pathParts = new ArrayList(Arrays.asList(StringUtils.split(path, sep))); + + for (String pathPart : pathParts) { + String pathEnd = ""; + if (StringUtils.countMatches(pathPart, ".") > parentArchetypeSpecialisationDepth) { + if (pathPart.endsWith("]")) { + pathEnd = "]"; + } + if (StringUtils.countMatches(pathPart, ".") >0) { + pathPart = pathPart.substring(0, pathPart.lastIndexOf(".")); + } + + } + // We need to consider that the parent archetype is already a specialised archetype itself! + while (pathPart.endsWith(".0")) { + pathPart = pathPart.substring(0, pathPart.length()-2); // need to get the non-redefined node then, going up in the hierarchy as much as possible + } + if (pathPart.endsWith("at0")) { // newly introduced node + log.debug("Path ends with at0: "+ pathPart +" "+expectedPath); + return null; + } + expectedPath += pathPart + pathEnd+sep; + } + if (expectedPath.length() >1 && expectedPath.endsWith(sep)) { + expectedPath = expectedPath.substring(0,expectedPath.length()-1); // get rid of tailing separator + } + log.debug("Unspecialised Path: "+ expectedPath); + + return expectedPath; + + } + + /** Tests whether two objects are directly equals, including their attributes, but without taking into account any direct or indirect children. + * + * @param c1 + * @param c2 + * @return + */ + private boolean equalsDirect(CObject c1, CObject c2) { + if (!c1.getRmTypeName().equals(c2.getRmTypeName())) { + return false; + } + + if (!c1.getOccurrences().equals(c2.getOccurrences())) { + return false; + } + if (c1.isRequired() != c2.isRequired()) { + return false; + } + if (c1 instanceof CComplexObject) { + CComplexObject cc1 = (CComplexObject) c1; + CComplexObject cc2 = (CComplexObject) c2; + if (cc1.hasAssumedValue() != cc2.hasAssumedValue()) { + return false; + } + if (cc1.getAttributes() != null) { + if (cc2.getAttributes() == null) { + return false; + } + if (cc1.getAttributes().size() != cc2.getAttributes().size()) { + return false; + } + for (CAttribute cc1A : cc1.getAttributes()) { + CAttribute cc2A = cc2.getAttribute(cc1A.getRmAttributeName()); + if (cc2A == null) { + return false; + } + if (!cc1A.getExistence().toString().equals(cc2A.getExistence().toString())) { + return false; + } + if (cc1A.isRequired() != cc2A.isRequired()) { + return false; + } + if (cc1A.isAllowed() != cc2A.isAllowed()) { + return false; + } + if (cc1A instanceof CMultipleAttribute && cc2A instanceof CMultipleAttribute) { + // If not both are the same this is tested elswhere... + CMultipleAttribute cc1MA = (CMultipleAttribute) cc1A; + CMultipleAttribute cc2MA = (CMultipleAttribute) cc2A; + if (!cc1MA.getCardinality().equals(cc2MA.getCardinality())) { + return false; + } + } + } + } + } + + return true; // no differences found + } + +} diff --git a/archetype-validator/src/main/java/org/openehr/am/validation/UTF8Control.java b/archetype-validator/src/main/java/org/openehr/am/validation/UTF8Control.java new file mode 100644 index 00000000..420d32fc --- /dev/null +++ b/archetype-validator/src/main/java/org/openehr/am/validation/UTF8Control.java @@ -0,0 +1,61 @@ +package org.openehr.am.validation; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; +import java.util.Locale; +import java.util.PropertyResourceBundle; +import java.util.ResourceBundle; +import java.util.ResourceBundle.Control; + +/** Enables reading from UTF-8 property files + * + */ +public class UTF8Control extends Control { + private static UTF8Control utf8Control = null; + + public synchronized static UTF8Control getInstance() { + if (utf8Control==null) { + utf8Control = new UTF8Control(); + } + return utf8Control; + } + + private UTF8Control() { + + } + + @Override + public ResourceBundle newBundle + (String baseName, Locale locale, String format, ClassLoader loader, boolean reload) + throws IllegalAccessException, InstantiationException, IOException { + // The below is a copy of the default implementation. + String bundleName = toBundleName(baseName, locale); + String resourceName = toResourceName(bundleName, "properties"); + ResourceBundle bundle = null; + InputStream stream = null; + if (reload) { + URL url = loader.getResource(resourceName); + if (url != null) { + URLConnection connection = url.openConnection(); + if (connection != null) { + connection.setUseCaches(false); + stream = connection.getInputStream(); + } + } + } else { + stream = loader.getResourceAsStream(resourceName); + } + if (stream != null) { + try { + // Only this line is changed to make it to read properties files as UTF-8. + bundle = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8")); + } finally { + stream.close(); + } + } + return bundle; + } +} \ No newline at end of file diff --git a/archetype-validator/src/main/java/org/openehr/am/validation/ValidationError.java b/archetype-validator/src/main/java/org/openehr/am/validation/ValidationError.java new file mode 100644 index 00000000..3058bcad --- /dev/null +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ValidationError.java @@ -0,0 +1,146 @@ +package org.openehr.am.validation; + +import java.text.MessageFormat; +import java.util.Locale; +import java.util.ResourceBundle; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +/** + * Archetype validation error with error type, short text + * and a longer more specific explanation of the error + * + * @author rong.chen + * @author sebastian.garde + */ +public class ValidationError { + + + public ValidationError(ErrorType type, String subType, Object... params) { + this.type = type; + this.subType = subType; + this.params = params; + } + + public ErrorType getType() { + return type; + } + + + /** Gets the error text in the default locale + * + * @return + */ + public String getText() { + return getText(Locale.getDefault()); + } + + /** Gets the description in an explicitly specified locale + * + * @param locale + * @return + */ + public String getText(Locale locale) { + if (locale == null) { + locale = Locale.getDefault(); + } + + String textKey = getTextKey(); + ResourceBundle rb = ResourceBundle.getBundle("validations", locale, UTF8Control.getInstance()); + + // If the resource bundle doen't know the textkey, we try without the subtype + if (!rb.containsKey(textKey)) { + textKey = getTextKey(true); + } + // If for some reason the bundle doesn't contain the textKey, we don't fail completely but return the textkey at least. + String errorText = rb.containsKey(textKey) ? rb.getString(textKey) : textKey; + if (params != null) { + errorText= MessageFormat.format(errorText, params); + } + return errorText; + } + + protected String getTextKey() { + return getTextKey(false); + } + + protected String getTextKey(boolean ignoreSubtype) { + if (ignoreSubtype || subType == null) { + return this.type.toString()+"_TEXT"; + } else { + return this.type.toString() + "_" + subType + "_TEXT"; + } + } + + /** Gets the description in the default locale + * + * @return + */ + public String getDescription() { + return getDescription(Locale.getDefault()); + } + + /** Gets the description in an explicitly specified locale + * + * @param locale + * @return + */ + public String getDescription(Locale locale) { + if (locale == null) { + locale = Locale.getDefault(); + } + + + return ResourceBundle.getBundle("validations", locale, UTF8Control.getInstance()).getString(this.type.toString()); + } + + + /** + * String representation of this error + */ + @Override + public String toString() { + return type + ", " + getText() + ", "+ getDescription(); + } + + /** + * String representation of this error + */ + + public String toString(Locale locale) { + return type + ", " + getText(locale) + ", "+ getDescription(locale); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { return false; } + if (obj == this) { return true; } + if (obj.getClass() != getClass()) { + return false; + } + ValidationError ve = (ValidationError) obj; + return new EqualsBuilder() + .append(type, ve.type) + .append(subType, ve.subType) + .append(params, ve.params) + // .append(getDescription(), ve.getDescription()) + .isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(11, 47). + append(type). + append(subType). + append(params). + // append(getDescription()). + toHashCode(); + } + + + + // fields + private ErrorType type; + private String subType; + private Object[] params; +} diff --git a/archetype-validator/src/main/resources/log4j.properties b/archetype-validator/src/main/resources/log4j.properties new file mode 100644 index 00000000..3cad082b --- /dev/null +++ b/archetype-validator/src/main/resources/log4j.properties @@ -0,0 +1,9 @@ +# Set root logger level to DEBUG (or WARN) and its only appender to stdout. +log4j.rootLogger=WARN , stdout + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%-5p %c %x - %m%n + +# package logging level WARN or DEBUG +log4j.logger.org.openehr.am.validation=WARN \ No newline at end of file diff --git a/archetype-validator/src/main/resources/validations.properties b/archetype-validator/src/main/resources/validations.properties new file mode 100644 index 00000000..8ae7cc24 --- /dev/null +++ b/archetype-validator/src/main/resources/validations.properties @@ -0,0 +1,118 @@ +VASID=Archetype specialisation parent identifier validity. The archetype identifier stated in the specialise clause must be the identifier of the immediate specialisation parent archetype. +VACSD=Archetype concept specialisation depth. The specialisation depth of the concept code must match the specialisation depth of the archetype identifier. +VARDT=Archetype definition typename validity. The topmost typename mentioned in the archetype definition section must match the type mentioned in the type-name slot of the first segment of the archetype id. +VATCD=Archetype code specialisation level validity. Each archetype term (at code) and constraint code (ac code) used in the archetype definition part must have a specialisation level no greater than the specialisation level of the archetype. +VACCD=Archetype definition code validity. The node identifier of the root node of the definition section must be the concept code mentioned earlier in the archetype. +VATDF=Archetype term validity. Each archetype term (at code) used as a node identifier in the archetype definition must be defined in the term_definitions part of the ontology. +VACDF=Constraint code validity. Each constraint code (ac code) used in the archetype definition part must be defined in the constraint_definitions part of the ontology. +VONLC=Secondary languages consistency. Each archetype term used as a node identifier the archetype definition must be defined for each secondary language term_definitions part of the ontology. +VOTM=Ontology translations missing. Translations must exist for term_definitions and constraint_definitions sections for all languages defined in the description / translations section. +VONSD=Ontology code specialisation level validity. No archetype code (at code or ac code) defined in the ontology can be of a greater specialisation depth than the archetype. +VCARM=Attribute constraint name validity: an attribute name introducing an attribute constraint block must be defined in the underlying information model as an attribute of the type which introduces the enclosing object block. +VSAM=Specialised archetype attribute multiplicity conformance: the multiplicity of a redefined attribute must conform, i.e. be the same or narrower, to that of the corresponding attribute in the parent archetype. +VSANCE=Specialised archetype attribute node existence conformance: the existence of a redefined attribute node in a specialised archetype must conform to the existence of the corresponding node in the flat parent archetype by having an identical range, or a range wholly contained by the latter. +VACSO=Single-valued attribute child object occurrences validity: the occurrences of a child object of a single-valued attribute cannot have an upper limit greater than 1. +VACSU=Single-valued attribute child node uniqueness: any object node added as a child to a single-valued attribute must either have a node identifier or reference model type that is unique with respect to the node identifier or the reference model type of all other siblings. +VACSI=Single-valued attribute child node identifier: any object node with a node identifier added as a child to a single-valued attribute must have a node identifier that is unique with respect to the node identifiers of all other siblings. +VACSIT=Single-valued attribute child node reference model type: any object node without a node identifier added as a child to a single-valued attribute must have a reference model type that is unique with respect to the reference model types of all other siblings. +VACMI=Child node identification: any object node added as a child to a container attribute must have a node identifier. +VACMM=Child node identifier uniqueness: the node identifier of an object node added as a child to a container attribute must be unique with respect to the siblings in the container. +VACMC=Cardinality/occurrences validity: where occurrences and cardinality are stated, the interval represented by: (sum of all occurrences minimum values) .. (sum of all occurrences maximum values) must intersect with the interval stated by the cardinality. +VCACA=Archetype attribute reference model cardinality conformance: the cardinality of an attribute must conform, i.e. be the same or narrower, to the cardinality of the corresponding attribute in the underlying information model. +VSANCC=Specialised archetype attribute node cardinality conformance: the cardinality of a redefined (multiply-valued) attribute node in a specialised archetype must conform to the cardinality of the corresponding node in the flat parent archetype by either being identical, or being wholly contained by the latter. +VCORM=Object constraint type name validity: a type name introducing an object constraint block must be defined in the underlying information model. +VCORMT=Object constraint type validity: a type name introducing an object constraint block must be the same as or conform to the type stated in the underlying information model of its owning attribute. +VSONCT=Specialised archetype object node type conformance: the reference model type of a redefined object node in a specialised archetype must conform to the reference model type in the corresponding node in the flat parent archetype by either being identical, or conforming via an inheritance relationship in the relevant reference model. +VSONIR=Specialised archetype object node redefinition: if defined, the node identifier of a redefined object node in a specialised archetype must be redefined into its specialised form if any other aspect of the immediate object constraint is redefined. +VSONCI=Specialised archetype object node identifier conformance: if defined, the node identifier of a redefined object node in a specialised archetype must conform to the node identifier in the corresponding node in the flat parent archetype by either being identical, or being a derived identifier at the specialisation level of the child archetype. +VSONCO=Specialised archetype object node occurrences conformance: the occurrences of a redefined object node in a specialised archetype must conform to the occurrences in the corresponding node in the flat parent archetype by either being identical, or being wholly contained by the latter. +VSSM=Specialised archetype sibling marker validity: the sibling code used in a sibling marker in a specialised archetype must refer to a node found within the same container in the flat parent archetype. +VOBAV=Object node assumed value validity: the value of an assumed value must fall within the value space defined by the constraint to which it is attached. +VCATU=Attribute uniqueness: sibling attributes occurring within an object node must be uniquely named with respect to each other, in the same way as for class definitions in an object reference model. +VDFAI=Archetype identifier validity in definition. Any archetype identifier mentioned in an archetype slot in the definition section must conform to the published openEHR specification for archetype identifiers. +VUNT=Use_node type validity: the type mentioned in a use_node statement must be the same as or a super-type (according to the reference model) of the reference model type of the node referred to. +VUNP=Use_node path validity: the path mentioned in a use_node statement must refer to an object node defined elsewhere in the same archetype or any of its specialisation parent archetypes, that is not itself an internal reference node, and which carries a node identifier if one is needed at the reference point. +VSCNR=Placeholder constraint node conformance: a placeholder node can only be defined into a reference model type conformant with the type of the original constraint in the parent archetype. +VOTC=openEHR terminology code validity. The code must be defined in the published openEHR terminology. +VDSCR=Null, empty or unknown mandatory description item such as purpose, original_author or lifecycle. +VSONT=The dynamic types of the node in the specialised archetype and the corresponding node in the parent archetype are not equal (e.g. one is an ConstraintRef and one is a CComplexObject.) +WOUC=Unused Code Warning: A code is defined in the ontology section of the archetype, but is not used in the archetype definition. +WITB=Warning: The path/code referenced in the term binding does not exist in the archetype. +WACMC=Cardinality/occurrences validity warning: where occurrences and cardinality are stated, the interval represented by: (sum of all occurrences minimum values) .. (sum of all occurrences maximum values) must intersect with the interval stated by the cardinality. This is fulfilled, but none of the optional elements could ever be added, because the mandatory elements are already taking up all the space within the container as defined by its cardinality. +ICARM=Info: A commonly constrained functional property has been constrained. +VOKU=dADL object key must be unique, for example a code in the ontology is present more than once for a language. +VUI=Units of a DV_QUANTITY must be expressed in UCUM units syntax, e.g. kg/m2, mm[Hg], ms-1, km +VDL=A language code may not be present more than once (neither in description/details nor for term or constraint definitions). + +VASID_NORMAL_TEXT=The specialised archetype id ({0}) is not based on specialisation parent archetype id {1}. +VASID_DEPRECATED_TEXT=The specialised archetype id ({0}) is a deprecated draft id. +VACSD_TEXT=Expected concept specialisation depth {0}, but was {1} instead. +VARDT_TEXT=The topmost typename mentioned in the archetype definition section ({0}) does not match the type mentioned in the type-name slot of the first segment of the archetype id ({1}). +VATCD_TEXT=The code {0} which is used in the definition section of the archetype has a specialisation depth of {1} whereas the archetype itself only has a specialisation depth of {2}. +VACCD_TEXT=The concept code does not match the root node id of the archetype. +VATDF_NORMAL_TEXT=Missing term definition for {0}. +VATDF_SPECIALISED_TEXT=The path {0} could not be found in the parent, but is specialised to {1}. +VATDF_INTRODUCED_TEXT=The path {0} could not be found in the parent, but is introduced in the specialised archetype. +VATDF_INPARENT_TEXT=In parent archetype: Missing term definition for {0}. +VACDF_TEXT=Missing code constraint for {0}. +VONLC_TERM_TEXT=Archetype code {0} is missing in language {1}. +VONLC_CONSTRAINT_TEXT=Constraint code {0} is missing in language {1}. +VOTM_TERM_TEXT=Archetype term definition missing for language {0}. +VOTM_CONSTRAINT_TEXT=Code constraint definition missing for language {0}. +VOTM_DESCRIPTIONDETAILS_TEXT=Description Details are missing for language {0}. +VONSD_TEXT=Ontology code [{0}] has specialisation level greater than {1}. +VCARM_TEXT=Unknown attribute [{0}] of parent RM type [{1}] at path {2}. +VSAM_MULTIPLE_TEXT=Multiplicity (Multiple) of attribute at {0} does not conform to multiplicity (Single) of the attribute at {1} in the parent archetype. +VSAM_SINGLE_TEXT=Multiplicity (Single) of attribute at {0} does not conform to multiplicity (Multiple) of the attribute at {1} in the parent archetype. +VSANCE_TEXT=Existence {0} at {1} does not conform to existence {2} at {3} in the parent archetype. +VACSO_TEXT=Occurrences greater than 1 for child object of single-valued attribute at path {0}. +VACSU_TEXT=Missing identifier for non-unique child object at {0}. +VACSI_TEXT=Duplicated identifier for child object at {0}. +VACSIT_TEXT= +VACMI_TEXT=Missing child identification at {0}. +VACMM_NORMAL_TEXT=Duplicated identifier for child object at {0}. +VACMM_INTREF_TEXT=No identifier (node-id) for more than one child object (Archetype Internal Reference) with the same target at {0}. +VACMC_CONTAIN_TEXT=Cannot add {0} ({1}) object with node-id {2} to multiply-valued attribute items because cardinality {3} does not contain occurrences {4} of object. Attribute Path: {5} +VACMC_INTERSECT_TEXT=Cannot add child objects of the multi-valued attribute {0} because its cardinality {1} does not intersect with the sum of all occurrences of its children: {2} +VCACA_TEXT=Attribute items in object node at {0}: Cardinality {1} does not conform to cardinality {2} in reference model. +VSANCC_TEXT=Cardinality {0} at {1} does not conform to cardinality {2} at {3} in the parent archetype. +VCORM_TEXT=Unknown RM type {0} at path {1}. +VCORMT_NORMAL_TEXT=Unassignable RM type: {0} at path {1} is not assignable from type {2}. +VCORMT_PARENT_TEXT=Unassignable RM Type: {0} of object node at {1} is not assignable from {2} at {3}. +VSONCT_NORMAL_TEXT=RM Type {0} at {1} is not identical and does not conform to the reference model type {2} in the corresponding node of the parent archetype. +VSONCT_UNKNOWN_TEXT=RM Type {0} at {1} is not identical and does not conform to the reference model type {2} in the corresponding node of the parent archetype. At least one of these RM types is unknown. +VSONCT_UNKNOWNFORPARENT_TEXT=RM Type {0} in parent archetype at {1} is unknown. The child archetype cannot conform to an unknown RM type. +VSONCT_MORETHANONE_TEXT=RM Type {0} at {1} is not identical and does not conform to one of the reference model types {2} in the corresponding node of the parent archetype. +VSONIR_NORMAL_TEXT=Object node at path {0} (RM type: {1}) redefines corresponding node in parent archetype (RM type: {2}) but node id {3} is not redefined. +VSONIR_TEXTDESCRIPTION_TEXT=Object node at path {0} (RM type: {1}) redefines corresponding node in parent archetype (RM type: {2}) but node id {3} is not redefined. The text/description of the two terms is different for language {4}. +VSONCI_TEXT=The node id {0} does not conform to the node id of the parent archetype {1} by either being identical, or being a derived identifier at the exact specialisation level of the child. +VSONCO_TEXT=Occurrences {0} of object at {1} does not conform to occurrences {2} of the corresponding node of the parent archetype ({3}). +VSSM_TEXT= +VOBAV_TEXT=Invalid assumed value: {0} for {1} at path {2}. +VCATU_TEXT=Sibling nodes are not uniquely named: {0} at path {1}. +VDFAI_NUMBEROFDOTS_TEXT=Invalid Archetype Identifier {0} used in Archetype Slot at {1}: The id does not have the correct amount of ''.''. +VDFAI_DOTVNUMBER_TEXT=Invalid Archetype Identifier {0} used in Archetype Slot at {1}: The id does not end with .v and a number +VDFAI_NUMBEROFHYPHENS_TEXT=Invalid Archetype Identifier {0} used in Archetype Slot at {1}: The qualified RM Entity does not contain the correct number of hyphens. +VDFAI_SLOTVALIDITY_TEXT=Archetype Slot at {0} does not allow any archetypes to be included. +VDFAI_INVALIDPATTERN_TEXT=The pattern {0} of Archetype Slot at {1} contains an invalid pattern, i.e. the regular expression cannot be parsed. +VUNT_NORMAL_TEXT=Unassignable RM type {0} of archetype internal reference at path {1} is not assignable from type {2}. +VUNT_PARENT_TEXT=Unassignable RM Type {0} of object node at {1} is not assignable from {2} archetype internal reference at {3}. +VUNT_UNKOWN_TEXT="Unknown RM type: {0} of archetype internal reference at path {1}. +VUNP_INVALIDPATH_TEXT=Invalid path: {0} of archetype internal reference at {1}. +VUNP_UNKNOWNTARGETRM_TEXT=Unknown target RM type at path {0} of archetype internal reference at {1}. +VUNP_INVALIDTARGETRM_TEXT=Invalid target RM type {0} of archetype internal reference at {1}. +VSCNR_TEXT= +VOTC_TEXT=Unknown openEHR terminology code(s): {0} at path {1}. +VDSCR_PURPOSE_TEXT=The mandatory description of the Purpose is null, empty or unknown for language {0}. +VDSCR_ORIGINALAUTHOR_TEXT=The mandatory description of the original author is null, empty or unknown. +VDSCR_ORIGINALAUTHORPART_TEXT=The description of parts of the original author is null, empty or unknown: {0} +VDSCR_LIFECYCLE_TEXT=The mandatory description of the lifecycle is null, empty, unknown or a number. +VSONT_TEXT=The dynamic class {0} of the object at {1} is different to the dynamic type {2} of the corresponding node in the parent archetype. +WOUC_TEXT=Ontology code [{0}] for ontology language {1} is not used in archetype definition. +WITB_ATCODE_TEXT=The at-code {0} is referenced in the term bindings, but does not exist in the archetype. +WITB_PATH_TEXT=The path of the term binding {0} does not exist in the archetype. +WACMC_TEXT=Cannot add all child objects of the multi-valued attribute {0} because - while its cardinality {1} intersects with the sum of all occurrences of its children {2} - it would leave the occurrence potential of at least one element to be unsatisfiable, because all mandatory elements would already take up all the space in the container as defined by its cardinality. +ICARM_TEXT=Attribute [{0}] at {1} (type={2}) is a computed property in reference model. +VOKU_TEXT=Ontology code [{0}] is present more than once in archetype ontology (language: {1}). +VUI_TEXT=The unit ''{0}'' is not a valid UCUM unit. +VDL_TEXT=The language code ''{0}'' must not be present more than once. diff --git a/archetype-validator/src/main/resources/validations.txt b/archetype-validator/src/main/resources/validations.txt new file mode 100644 index 00000000..fb7162d5 --- /dev/null +++ b/archetype-validator/src/main/resources/validations.txt @@ -0,0 +1,34 @@ +x VASID: archetype specialisation parent identifier validity. the archetype identifier sated in the specialise clause must be the identifier of the immediate specialisation parent archetype. +x VACSD: archetype concept specialisation depth. the specialisation depth of the concept code must match the specialisation depth of the archetype identifier. +x VARDT: archetype definition typename validity. The topmost typename mentioned in the archetype definition section must match the type mentioned in the type-nxame slot of the first segment of the archetype id. +x VATCD: archetype code specialisation level validity. Each archetype term (?at? code) and constraint code (?ac? code) used in the archetype definition part must have a specialisation level no greater than the specialisation level of the archetype. +x VACCD: archetype definition code validity. The node identifier of the root node of the definition section must be the concept code mentioned earlier in the archetype. +x VATDF: archetype term validity. Each archetype term (?at? code) used as a node identifier the archetype definition must be defined in the term_definitions part of the ontology. +x VACDF: constraint code validity. Each constraint code (?ac? code) used in the archetype definition part must be defined in the constraint_definitions part of the ontology. +x VOTM: ontology translations missing. Translations must exist for term_definitions and constraint_definitions sections for all languages defined in the description / translations section. +x VONSD: ontology code specialisation level validity. No archetype code (at-code or ac-code) defined in the ontology can be of a greater specialisation depth than the archetype. +x VCARM: attribute constraint name validity: an attribute name introducing an attribute constraint block must be defined in the underlying information model as an attribute of the type which introduces the enclosing object block. + VSAM: specialised archetype attribute multiplicity conformance: the multiplicity of a redefined attribute must conform, i.e. be the same or narrower, to that of the corresponding attribute in the parent archetype. + VSANCE: specialised archetype attribute node existence conformance: the existence of a redefined attribute node in a specialised archetype must conform to the existence of the corresponding node in the flat parent archetype by having an identical range, or a range wholly contained by the latter. +x VACSO: single-valued attribute child object occurrences validity: the occurrences of a child object of a single-valued attribute cannot have an upper limit greater than 1. +x VACSU: single-valued attribute child node uniqueness: any object node added as a child to a single-valued attribute must either have a node identifier or reference model type that is unique with respect to the node identifier or the reference model type of all other siblings. +x VACSI: single-valued attribute child node identifier: any object node with a node identifier added as a child to a single-valued attribute must have a node identifier that is unique with respect to the node identifiers of all other siblings. ++ VACSIT: single-valued attribute child node reference model type: any object node without a node identifier added as a child to a single-valued attribute must have a reference model type that is unique with respect to the reference model types of all other siblings. +x VACMI: child node identification: any object node added as a child to a container attribute must have a node identifier. +x VACMM: child node identifier uniqueness: the node identifier of an object node added as a child to a container attribute must be unique with respect to the siblings in the container. +x VACMC: cardinality/occurrences validity: the interval represented by: (sum of all occurrences minimum values) .. (sum of all occurrences maximum values) must be contained by the interval stated by the cardinality. + VSANCC: specialised archetype attribute node cardinality conformance: the cardinality of a redefined (multiply-valued) attribute node in a specialised archetype must conform to the cardinality of the corresponding node in the flat parent archetype by either being identical, or being wholly contained by the latter. +x VCORM: object constraint type name validity: a type name introducing an object constraint block must be defined in the underlying information model. + VSONCT: specialised archetype object node type conformance: the reference model type of a redefined object node in a specialised archetype must conform to the reference model type in the corresponding node in the flat parent archetype by either being identical, or conforming via an inheritance relationship in the relevant reference model. + VSONIR: specialised archetype object node redefinition: if defined, the node identifier of a redefined object node in a specialised archetype must be redefined into its specialised form if any other aspect of the immediate object constraint is redefined. + VSONCI: specialised archetype object node identifier conformance: if defined, the node identifier of a redefined object node in a specialised archetype must conform to the node identifier in the corresponding node in the flat parent archetype by either being identical, or being a derived identifier at the specialisation level of the child archeytpe. + VSONCO: specialised archetype object node occurrences conformance: the occurrences of a redefined object node in a specialised archetype must conform to the occurrences in the corresponding node in the flat parent archetype by either being identical, or being wholly contained by the latter. + VSSM: specialised archetype sibling marker validity: the sibling code used in a sibling marker in a specialised archetype must refer to a node found within the same container in the flat parent archetype. +x VOBAV: object node assumed value validity: the value of an assumed value must fall within the value space defined by the constraint to which it is attached. +x VCATU: attribute uniqueness: sibling attributes occurring within an object node must be uniquely named with respect to each other, in the same way as for class definitions in an object reference model. +x VDFAI: archetype identifier validity in definition. Any archetype identifier mentioned in an archetype slot in the definition section must conform to the published openEHR specification for archetype identifiers. +x VUNT: use_node type validity: the type mentioned in a use_node statement must be the same as or a super-type (according to the reference model) of the reference model type of the node referred to. +x VUNP: use_node path validity: the path mentioned in a use_node statement must refer to an object node defined elsewhere in the same archetype or any of its specialisation parent archetypes, that is not itself an internal reference node, and which carries a node identifier if one is needed at the reference point. +? VSCNR: placeholder constraint node conformance: a placeholder node can only be defined into a reference model type conformant with the type of the original constraint in the parent archetype. + VOTC: openEHR terminology code validity. The code must be defined in the published openEHR terminology. +x VDSCR: Null, empty or unknown mandatory description item such as purpose, original_author or lifecycle. diff --git a/archetype-validator/src/main/resources/validations_de.properties b/archetype-validator/src/main/resources/validations_de.properties new file mode 100644 index 00000000..e905261b --- /dev/null +++ b/archetype-validator/src/main/resources/validations_de.properties @@ -0,0 +1,118 @@ +VASID=(de)Archetype specialisation parent identifier validity. The archetype identifier stated in the specialise clause must be the identifier of the immediate specialisation parent archetype. +VACSD=(de)Archetype concept specialisation depth. The specialisation depth of the concept code must match the specialisation depth of the archetype identifier. +VARDT=(de)Archetype definition typename validity. The topmost typename mentioned in the archetype definition section must match the type mentioned in the type-name slot of the first segment of the archetype id. +VATCD=(de)Archetype code specialisation level validity. Each archetype term (at code) and constraint code (ac code) used in the archetype definition part must have a specialisation level no greater than the specialisation level of the archetype. +VACCD=(de)Archetype definition code validity. The node identifier of the root node of the definition section must be the concept code mentioned earlier in the archetype. +VATDF=(de)Archetype term validity. Each archetype term (at code) used as a node identifier in the archetype definition must be defined in the term_definitions part of the ontology. +VACDF=(de)Constraint code validity. Each constraint code (ac code) used in the archetype definition part must be defined in the constraint_definitions part of the ontology. +VONLC=(de)Secondary languages consistency. Each archetype term used as a node identifier the archetype definition must be defined for each secondary language term_definitions part of the ontology. +VOTM=(de)Ontology translations missing. Translations must exist for term_definitions and constraint_definitions sections for all languages defined in the description / translations section. +VONSD=(de)Ontology code specialisation level validity. No archetype code (at code or ac code) defined in the ontology can be of a greater specialisation depth than the archetype. +VCARM=(de)Attribute constraint name validity: an attribute name introducing an attribute constraint block must be defined in the underlying information model as an attribute of the type which introduces the enclosing object block. +VSAM=(de)Specialised archetype attribute multiplicity conformance: the multiplicity of a redefined attribute must conform, i.e. be the same or narrower, to that of the corresponding attribute in the parent archetype. +VSANCE=(de)Specialised archetype attribute node existence conformance: the existence of a redefined attribute node in a specialised archetype must conform to the existence of the corresponding node in the flat parent archetype by having an identical range, or a range wholly contained by the latter. +VACSO=(de)Single-valued attribute child object occurrences validity: the occurrences of a child object of a single-valued attribute cannot have an upper limit greater than 1. +VACSU=(de)Single-valued attribute child node uniqueness: any object node added as a child to a single-valued attribute must either have a node identifier or reference model type that is unique with respect to the node identifier or the reference model type of all other siblings. +VACSI=(de)Single-valued attribute child node identifier: any object node with a node identifier added as a child to a single-valued attribute must have a node identifier that is unique with respect to the node identifiers of all other siblings. +VACSIT=(de)Single-valued attribute child node reference model type: any object node without a node identifier added as a child to a single-valued attribute must have a reference model type that is unique with respect to the reference model types of all other siblings. +VACMI=(de)Child node identification: any object node added as a child to a container attribute must have a node identifier. +VACMM=(de)Child node identifier uniqueness: the node identifier of an object node added as a child to a container attribute must be unique with respect to the siblings in the container. +VACMC=(de)Cardinality/occurrences validity: where occurrences and cardinality are stated, the interval represented by: (sum of all occurrences minimum values) .. (sum of all occurrences maximum values) must intersect with the interval stated by the cardinality. +VCACA=(de)Archetype attribute reference model cardinality conformance: the cardinality of an attribute must conform, i.e. be the same or narrower, to the cardinality of the corresponding attribute in the underlying information model. +VSANCC=(de)Specialised archetype attribute node cardinality conformance: the cardinality of a redefined (multiply-valued) attribute node in a specialised archetype must conform to the cardinality of the corresponding node in the flat parent archetype by either being identical, or being wholly contained by the latter. +VCORM=(de)Object constraint type name validity: a type name introducing an object constraint block must be defined in the underlying information model. +VCORMT=(de)Object constraint type validity: a type name introducing an object constraint block must be the same as or conform to the type stated in the underlying information model of its owning attribute. +VSONCT=(de)Specialised archetype object node type conformance: the reference model type of a redefined object node in a specialised archetype must conform to the reference model type in the corresponding node in the flat parent archetype by either being identical, or conforming via an inheritance relationship in the relevant reference model. +VSONIR=(de)Specialised archetype object node redefinition: if defined, the node identifier of a redefined object node in a specialised archetype must be redefined into its specialised form if any other aspect of the immediate object constraint is redefined. +VSONCI=(de)Specialised archetype object node identifier conformance: if defined, the node identifier of a redefined object node in a specialised archetype must conform to the node identifier in the corresponding node in the flat parent archetype by either being identical, or being a derived identifier at the specialisation level of the child archetype. +VSONCO=(de)Specialised archetype object node occurrences conformance: the occurrences of a redefined object node in a specialised archetype must conform to the occurrences in the corresponding node in the flat parent archetype by either being identical, or being wholly contained by the latter. +VSSM=(de)Specialised archetype sibling marker validity: the sibling code used in a sibling marker in a specialised archetype must refer to a node found within the same container in the flat parent archetype. +VOBAV=(de)Object node assumed value validity: the value of an assumed value must fall within the value space defined by the constraint to which it is attached. +VCATU=(de)Attribute uniqueness: sibling attributes occurring within an object node must be uniquely named with respect to each other, in the same way as for class definitions in an object reference model. +VDFAI=(de)Archetype identifier validity in definition. Any archetype identifier mentioned in an archetype slot in the definition section must conform to the published openEHR specification for archetype identifiers. +VUNT=(de)Use_node type validity: the type mentioned in a use_node statement must be the same as or a super-type (according to the reference model) of the reference model type of the node referred to. +VUNP=(de)Use_node path validity: the path mentioned in a use_node statement must refer to an object node defined elsewhere in the same archetype or any of its specialisation parent archetypes, that is not itself an internal reference node, and which carries a node identifier if one is needed at the reference point. +VSCNR=(de)Placeholder constraint node conformance: a placeholder node can only be defined into a reference model type conformant with the type of the original constraint in the parent archetype. +VOTC=(de)openEHR terminology code validity. The code must be defined in the published openEHR terminology. +VDSCR=(de)Null, empty or unknown mandatory description item such as purpose, original_author or lifecycle. +VSONT=(de)The dynamic types of the node in the specialised archetype and the corresponding node in the parent archetype are not equal (e.g. one is an ConstraintRef and one is a CComplexObject.) +WOUC=(de)Unused Code Warning: A code is defined in the ontology section of the archetype, but is not used in the archetype definition. +WITB=(de)Warning: The path/code referenced in the term binding does not exist in the archetype. +WACMC=(de)Cardinality/occurrences validity warning: where occurrences and cardinality are stated, the interval represented by: (sum of all occurrences minimum values) .. (sum of all occurrences maximum values) must intersect with the interval stated by the cardinality. This is fulfilled, but none of the optional elements could ever be added, because the mandatory elements are already taking up all the space within the container as defined by its cardinality. +ICARM=(de)Info: A commonly constrained functional property has been constrained. +VOKU=(de)dADL object key must be unique, for example a code in the ontology is present more than once for a language. +VUI=DV_QUANTITY Einheiten mssen in UCUM syntax ausgedrckt werden, z.B. kg/m2, mm[Hg], ms-1, km. +VDL=(de)A language code may not be present more than once (neither in description/details nor for term or constraint definitions). + +VASID_NORMAL_TEXT=(de)The specialised archetype id ({0}) is not based on specialisation parent archetype id {1}. +VASID_DEPRECATED_TEXT=(de)The specialised archetype id ({0}) is a deprecated draft id. +VACSD_TEXT=(de)Expected concept specialisation depth {0}, but was {1} instead. +VARDT_TEXT=(de) The topmost typename mentioned in the archetype definition section ({0}) does not match the type mentioned in the type-name slot of the first segment of the archetype id ({1}). +VATCD_TEXT=(de)The code {0} which is used in the definition section of the archetype has a specialisation depth of {1} whereas the archetype itself only has a specialisation depth of {2}. +VACCD_TEXT=(de)The concept code does not match the root node id of the archetype. +VATDF_NORMAL_TEXT=(de)Missing term definition for {0}. +VATDF_SPECIALISED_TEXT=(de)The path {0} could not be found in the parent, but is specialised to {1}. +VATDF_INTRODUCED_TEXT=(de)The path {0} could not be found in the parent, but is introduced in the specialised archetype. +VATDF_INPARENT_TEXT=(de)In parent archetype: Missing term definition for {0}. +VACDF_TEXT=(de)Missing code constraint for {0}. +VONLC_TERM_TEXT=(de)Archetype code {0} is missing in language {1}. +VONLC_CONSTRAINT_TEXT=(de)Constraint code {0} is missing in language {1}. +VOTM_TERM_TEXT=(de)Archetype term definition missing for language {0}. +VOTM_CONSTRAINT_TEXT=(de)Code constraint definition missing for language {0}. +VOTM_DESCRIPTIONDETAILS_TEXT=(en)Description Details are missing for language {0}. +VONSD_TEXT=(de)Ontology code [{0}] has specialisation level greater than {1}. +VCARM_TEXT=(de)Unknown attribute [{0}] of parent RM type [{1}] at path {2}. +VSAM_MULTIPLE_TEXT=(de)Multiplicity (Multiple) of attribute at {0} does not conform to multiplicity (Single) of the attribute at {1} in the parent archetype. +VSAM_SINGLE_TEXT=(de)Multiplicity (Single) of attribute at {0} does not conform to multiplicity (Multiple) of the attribute at {1} in the parent archetype. +VSANCE_TEXT=(de)Existence {0} at {1} does not conform to existence {2} at {3} in the parent archetype. +VACSO_TEXT=(de)Occurrences greater than 1 for child object of single-valued attribute at path {0}. +VACSU_TEXT=(de)Missing identifier for non-unique child object at {0}. +VACSI_TEXT=(de)Duplicated identifier for child object at {0}. +VACSIT_TEXT=(de) +VACMI_TEXT=(de)Missing child identification at {0}. +VACMM_NORMAL_TEXT=(de)Duplicated identifier for child object at {0}. +VACMM_INTREF_TEXT=(de)No identifier (node-id) for more than one child object (Archetype Internal Reference) with the same target at {0}. +VACMC_CONTAIN_TEXT=(de)Cannot add {0} ({1}) object with node-id {2} to multiply-valued attribute items because cardinality {3} does not contain occurrences {4} of object. Attribute Path: {5} +VACMC_INTERSECT_TEXT=(de)Cannot add child objects of the multi-valued attribute {0} because its cardinality {1} does not intersect with the sum of all occurrences of its children: {2} +VCACA_TEXT=(de)Attribute items in object node at {0}: Cardinality {1} does not conform to cardinality {2} in reference model. +VSANCC_TEXT=(de)Cardinality {0} at {1} does not conform to cardinality {2} at {3} in the parent archetype. +VCORM_TEXT=(de)Unknown RM type {0} at path {1}. +VCORMT_NORMAL_TEXT=(de)Unassignable RM type: {0} at path {1} is not assignable from type {2}. +VCORMT_PARENT_TEXT=(de)Unassignable RM Type: {0} of object node at {1} is not assignable from {2} at {3}. +VSONCT_NORMAL_TEXT=(de)RM Type {0} at {1} is not identical and does not conform to the reference model type {2} in the corresponding node of the parent archetype. +VSONCT_UNKNOWN_TEXT=(de)RM Type {0} at {1} is not identical and does not conform to the reference model type {2} in the corresponding node of the parent archetype. At least one of these RM types is unknown. +VSONCT_UNKNOWNFORPARENT_TEXT=(de)RM Type {0} in parent archetype at {1} is unknown. The child archetype cannot conform to an unknown RM type. +VSONCT_MORETHANONE_TEXT=(de)RM Type {0} at {1} is not identical and does not conform to one of the reference model types {2} in the corresponding node of the parent archetype. +VSONIR_NORMAL_TEXT=(de)Object node at path {0} (RM type: {1}) redefines corresponding node in parent archetype (RM type: {2}) but node id {3} is not redefined. +VSONIR_TEXTDESCRIPTION_TEXT=(de)Object node at path {0} (RM type: {1}) redefines corresponding node in parent archetype (RM type: {2}) but node id {3} is not redefined. The text/description of the two terms is different for language {4}. +VSONCI_TEXT=(de)The node id {0} does not conform to the node id of the parent archetype {1} by either being identical, or being a derived identifier at the exact specialisation level of the child. +VSONCO_TEXT=(de)Occurrences {0} of object at {1} does not conform to occurrences {2} of the corresponding node of the parent archetype ({3}). +VSSM_TEXT=(de) +VOBAV_TEXT=(de)Invalid assumed value: {0} for {1} at path {2}. +VCATU_TEXT=(de)Sibling nodes are not uniquely named: {0} at path {1}. +VDFAI_NUMBEROFDOTS_TEXT=(de)Invalid Archetype Identifier {0} used in Archetype Slot at {2}: The id does not have the correct amount of ''.''. +VDFAI_DOTVNUMBER_TEXT=(de)Invalid Archetype Identifier {0} used in Archetype Slot at {2}: The id does not end with .v and a number. +VDFAI_NUMBEROFHYPHENS_TEXT=(de)Invalid Archetype Identifier {0} used in Archetype Slot at {2}: The qualified RM Entity does not contain the correct number of hyphens. +VDFAI_SLOTVALIDITY_TEXT=(de)Archetype Slot at {0} does not allow any archetypes to be included. +VDFAI_INVALIDPATTERN_TEXT=(de)The pattern {0} of Archetype Slot at {1} contains an invalid pattern, i.e. the regular expression cannot be parsed. +VUNT_NORMAL_TEXT=(de)Unassignable RM type {0} of archetype internal reference at path {1} is not assignable from type {2}. +VUNT_PARENT_TEXT=(de)Unassignable RM Type {0} of object node at {1} is not assignable from {2} archetype internal reference at {3}. +VUNT_UNKOWN_TEXT=(de)"Unknown RM type: {0} of archetype internal reference at path {1}. +VUNP_INVALIDPATH_TEXT=(de)Invalid path: {0} of archetype internal reference at {1}. +VUNP_UNKNOWNTARGETRM_TEXT=(de)Unknown target RM type at path {0} of archetype internal reference at {1}. +VUNP_INVALIDTARGETRM_TEXT=(de)Invalid target RM type {0} of archetype internal reference at {1}. +VSCNR_TEXT=(de) +VOTC_TEXT=(de)Unknown openEHR terminology code(s): {0} at path {1}. +VDSCR_PURPOSE_TEXT=(de)The mandatory description of the Purpose is null, empty or unknown for language {0}. +VDSCR_ORIGINALAUTHOR_TEXT=(de)The mandatory description of the original author is null, empty or unknown. +VDSCR_ORIGINALAUTHORPART_TEXT=(de)The description of parts of the original author is null, empty or unknown: {0} +VDSCR_LIFECYCLE_TEXT=(de)The mandatory description of the lifecycle is null, empty, unknown or a number. +VSONT_TEXT=(de)The dynamic class {0} of the object at {1} is different to the dynamic type {2} of the corresponding node in the parent archetype. +WOUC_TEXT=(de)Ontology code [{0}] for ontology language {1} is not used in archetype definition. +WITB_ATCODE_TEXT=(de)The at-code {0} is referenced in the term bindings, but does not exist in the archetype. +WITB_PATH_TEXT=(de)The path of the term binding {0} does not exist in the archetype. +WACMC_TEXT=(de)Cannot add all child objects of the multi-valued attribute {0} because - while its cardinality {1} intersects with the sum of all occurrences of its children {2} - it would leave the occurrence potential of at least one element to be unsatisfiable, because all mandatory elements would already take up all the space in the container as defined by its cardinality. +ICARM_TEXT=(de)Attribute [{0}] at {1} (type={2}) is a computed property in reference model. +VOKU_TEXT=(de)Ontology code [{0}] is present more than once in archetype ontology (language: {1}). +VUI_TEXT=Die Einheit {0} ist keine korrekte UCUM Einheit. +VDL_TEXT=(de)The language code ''{0}'' must not be present more than once. diff --git a/archetype-validator/src/main/resources/validations_en.properties b/archetype-validator/src/main/resources/validations_en.properties new file mode 100644 index 00000000..093d97a8 --- /dev/null +++ b/archetype-validator/src/main/resources/validations_en.properties @@ -0,0 +1,2 @@ +// This file is intentionally empty to indicate that en is a supported language, even if all English terms are actually in the top-level fallback file validations.properties. +// This is to essentially trick Java into falling back to the root, and not to the JVM's Default locale. If that is e.g. set to de, en would otherwise fallback to de, insteado f the desired root. \ No newline at end of file diff --git a/archetype-validator/src/main/resources/validations_ru.properties b/archetype-validator/src/main/resources/validations_ru.properties new file mode 100644 index 00000000..9b5ba9a0 --- /dev/null +++ b/archetype-validator/src/main/resources/validations_ru.properties @@ -0,0 +1,118 @@ +VASID=Правильность материнского идентификатора специализации архетипа. Идентификатор архетипа, определенный в операторе специализации, должен быть идентификатором материнского архетипа с непосредственной специализацией. +VACSD=Глубина специализации концепции архетипа. Глубина специализации кода концепции должна соответствовать глубине специализации идентификатора архетипа. +VARDT=Правильность имени типа определения архетипа. Самое верхнее имя типа, указанное в разделе определения архетипа, должно соответствовать типу, указанному в отведенном для имени типа слоте первого сегмента идентификатора архетипа. +VATCD=Правильность уровня специализации кода архетипа. Каждый термин архетипа (код ‘at’) и код ограничения (код ‘ac’), используемые в определении архетипа, должны обладать уровнем специализации не выше уровня специализации архетипа. +VACCD=Правильность кода определения архетипа. Идентификатор корневого узла в разделе определения должен быть кодом концепции, указанным раньше в архетипе. +VATDF=Правильность термина архетипа. Каждый термин архетипа (код ‘at’), используемый как идентификатор узла в определении архетипа, должен быть определен в части ‘term_definitions’ (определения терминов) онтологии. +VACDF=Правильность кода ограничения. Каждый код ограничения (код ‘ac’), используемый в определении архетипа, должен быть определен в части ‘constraint_definitions’ (определения ограничений) онтологии. +VONLC=Согласованность вторичных (неосновных) языков. Каждый термин архетипа, используемый как идентификатор узла в определении архетипа, должен быть определен для каждой части ‘term_definitions’ (определения терминов) онтологии на вторичном языке. +VOTM=Отсутствуют переводы онтологии. Переводы должны быть в наличии для разделов ‘term_definitions’ и ‘constraint_definitions’ в разделе описания/переводов. +VONSD=Правильность уровня специализации кода онтологии. Ни один из кодов архетипа (код ‘at’ или код ‘ac’), определенных в онтологии, не может обладать большей глубиной специализации, нежели сам архетип. +VCARM=Правильность имени ограничения атрибутов: имя атрибута, задающее блок ограничений атрибутов, должно быть определено в базовой информационной модели как атрибут типа, вводящего вмещающий объектный блок. +VSAM=Согласованность многозначности атрибутов специализированных архетипов: многозначность переопределенного атрибута должна соответствовать (т ест быть не шире) многозначности соответствующего атрибута в материнском архетипе. +VSANCE =Согласованность существования узла специализированного атрибута: существование узла переопределенного атрибута в специализированном архетипе должно соответствовать существованию соответствующего узла в неструктурированном материнском архетипе (то есть должен быть тот же диапазон или диапазон, полностью укладывающийся в последнем). +VACSO=Правильность частоты возникновения дочерних объектов однозначного атрибута: частота возникновения дочерних объектов однозначного атрибута не может иметь верхний предел выше 1. +VACSU=Уникальность дочернего узла однозначного атрибута: любой объектный узел, добавляемый в качестве дочернего к однозначному атрибуту, должен иметь либо узловой идентификатор, либо тип исходной модели, уникальные по отношению к узловому идентификатору или типу исходной модели всех прочих узлов-братьев. +VACSI=Идентификатор дочернего узла однозначного атрибута: любой объектный узел с узловым идентификатором, добавляемый в качестве дочернего в однозначный атрибут, должен иметь узловой идентификатор, уникальный по отношению к узловым идентификаторам всех прочих узлов-братьев. +VACSIT=Тип модели дочернего узла однозначного атрибута: любой объектный узел без узлового идентификатора, добавляемый в качестве дочернего в однозначный атрибут, должен иметь тип исходной модели, уникальный по отношению к типам исходной модели всех прочих узлов-братьев. +VACMI=Идентификация дочернего узла: всякий объектный узел, добавляемый в качестве дочернего в атрибут контейнера, должен иметь узловой идентификатор. +VACMM=Уникальность идентификатора дочернего узла: идентификатор объектного узла, добавляемого в качестве дочернего в атрибут контейнера, должен быть уникальным по отношению к узлам-братьям в контейнере. +VACMC=Правильность мощности множества/частоты появления: там, где задаются частота появления и мощность, интервал, представленный как (сумма минимальных значений всех частот появления) … (сумма максимальных значений частот всех появлений) должен перекрываться с интервалом, задаваемым мощностью (множества). +VCACA=Соответствие мощности исходной модели атрибута архетипа: мощность атрибута должна соответствовать (то есть быть не шире) мощности соответствующего атрибута в базовой информационной модели. +VSANCC=Соответствие мощности узла атрибута архетипа: мощность переопределенного (многозначного) узла атрибута в специализированном архетипе должна соответствовать мощности соответствующего узла в неструктурированном материнском архетипе (то есть должна быть такой же или полностью укладывающейся в последний). +VCORM=Правильность имени типа ограничения объекта: имя типа, вводящее блок ограничения объекта, должно быть определено в базовой информационной модели. +VCORMT=Правильность типа ограничения объекта: имя типа, вводящее блок ограничения объекта, должно быть таким же, что и тип, заданный в базовой информационной модели собственного атрибута, или же соответствовать этому типу. +VSONCT=Согласованность типа объектного узла специализированного архетипа: тип исходной модели переопределенного объектного узла в специализированном архетипе должен соответствовать типу исходной модели в соответствующем узле неструктурированного материнского архетипа, а именно: он должен быть таким же или связан путем наследования с соответствующей исходной моделью. +VSONIR=Переопределение объектного узла специализированного архетипа: в случае определения идентификатор узла переопределенного объектного узла в специализированном архетипе должен быть переопределен в его специализированную форму, если переопределен любой другой аспект прямого объектного ограничения. +VSONCI=Согласованность идентификатора объектного узла специализированного архетипа: в случае определения идентификатор узла переопределенного объектного узла в специализированном архетипе должен быть согласованным с соответствующим идентификатором узла в неструктурированном материнском архетипе, а именно: он должен быть идентичным или производным идентификатором на уровне специализации дочернего архетипа. +VSONCO=Согласованность частот появления объектного узла специализированного архетипа: частоты появления переопределенного объектного узла в специализированном архетипе должны соответствовать частотам появления в соответствующем узле неструктурированного материнского архетипа, а именно: быть такими же или умещаться в них. +VSSM=Правильность маркера «брата» специализированного архетипа: код «брата», используемый в маркере «брата» в специализированном архетипе, должен ссылаться на узел, обнаруженный в том же контейнере в неструктурированном материнском архетипе. +VOBAV=Правильность принятого значения объектного узла: принятое значение должно укладываться в интервал значений, заданный соответствующим ограничением. +VCATU=Уникальность атрибута: атрибуты «братьев» в рамках того или иного объектного узла должны иметь уникальные по отношению друг к другу имена – точно так же, как и для определений классов в исходной модели объекта. +VDFAI=Правильность идентификатора архетипа в определении. Любой идентификатор архетипа, упомянутый в слоте архетипа в разделе определения, должен соответствовать опубликованной спецификации openEHR для идентификаторов архетипов. +VUNT=Правильность типа Use_node: тип, упомянутый в операторе use_node, должен быть тем же, что и тип исходной модели узла, на который делается ссылка, или превосходить его (согласно исходной модели). +VUNP=Правильность пути доступа Use_node: путь доступа, указанный в операторе use_node, должен ссылаться на объектный узел, определенный где-нибудь в архетипе или каком-либо из соответствующих специализированных материнских архетипов, причем этот узел не является внутренним базисным узлом и имеет идентификатор (если таковой требуется в опорной точке). +VSCNR=Согласованность узла ограничения метки-заполнителя: узел заполнителя может быть определен только в типе исходной модели в соответствии с типом оригинального ограничения в материнском архетипе. +VOTC=Правильность кода терминологии openEHR: Код должен быть определен в опубликованной терминологии openEHR. +VDSCR=Обязательный для описания элемент (к примеру, цель, оригинальный автор или жизненный цикл) является нулевым, пустым или неизвестным. +VSONT=Динамические типы узла в специализированном архетипе и соответствующий узел в материнском архетипе не равны (к при меру, один – ConstraintRef, а другой - CComplexObject.) +WOUC=Предупреждение о неиспользуемом коде: в разделе онтологии архетипа определен код, но он не используется в определении архетипа. +WITB=Предупреждение: Путь доступа/код, на который делается ссылка в связи терминов, не существует в архетипе. +WACMC=Предупреждение о правильности мощности/частоты появления: там, где задаются частота появления и мощность, интервал, представленный как (сумма минимальных значений всех частот появления) … (сумма максимальных значений частот всех появлений), должен перекрываться с интервалом, задаваемым мощностью (множества). Это выполнено, но не может быть добавлен ни один опционный элемент, поскольку обязательные элементы уже заполняют все пространство контейнера, определяемое его мощностью. +ICARM=Информация: Ограничена обычно ограничиваемая функциональность +VOKU=Ключ объекта dADL должен быть уникальным; к примеру, код в онтологии присутствует более одного раза для того или иного языка. +VUI=(ru)Units of a DV_QUANTITY must be expressed in UCUM units syntax, e.g. kg/m2, mm[Hg], ms-1, km +VDL=(ru)A language code may not be present more than once (neither in description/details nor for term or constraint definitions). + +VASID_NORMAL_TEXT=(ru)The specialised archetype id ({0}) is not based on specialisation parent archetype id {1}. +VASID_DEPRECATED_TEXT=(ru)The specialised archetype id ({0}) is a deprecated draft id. +VACSD_TEXT=(ru)Expected concept specialisation depth {0}, but was {1} instead. +VARDT_TEXT=(ru) The topmost typename mentioned in the archetype definition section ({0}) does not match the type mentioned in the type-name slot of the first segment of the archetype id ({1}). +VATCD_TEXT=(ru)The code {0} which is used in the definition section of the archetype has a specialisation depth of {1} whereas the archetype itself only has a specialisation depth of {2}. +VACCD_TEXT=(ru)The concept code does not match the root node id of the archetype. +VATDF_NORMAL_TEXT=(ru)Missing term definition for {0}. +VATDF_SPECIALISED_TEXT=(ru)The path {0} could not be found in the parent, but is specialised to {1}. +VATDF_INTRODUCED_TEXT=(ru)The path {0} could not be found in the parent, but is introduced in the specialised archetype. +VATDF_INPARENT_TEXT=(ru)In parent archetype: Missing term definition for {0}. +VACDF_TEXT=(ru)Missing code constraint for {0}. +VONLC_TERM_TEXT=(ru)Archetype code {0} is missing in language {1}. +VONLC_CONSTRAINT_TEXT=(ru)Constraint code {0} is missing in language {1}. +VOTM_TERM_TEXT=(ru)Archetype term definition missing for language {0}. +VOTM_CONSTRAINT_TEXT=(ru)Code constraint definition missing for language {0}. +VOTM_DESCRIPTIONDETAILS_TEXT=(ru)Description Details are missing for language {0}. +VONSD_TEXT=(ru)Ontology code [{0}] has specialisation level greater than {1}. +VCARM_TEXT=(ru)Unknown attribute [{0}] of parent RM type [{1}] at path {2}. +VSAM_MULTIPLE_TEXT=(ru)Multiplicity (Multiple) of attribute at {0} does not conform to multiplicity (Single) of the attribute at {1} in the parent archetype. +VSAM_SINGLE_TEXT=(ru)Multiplicity (Single) of attribute at {0} does not conform to multiplicity (Multiple) of the attribute at {1} in the parent archetype. +VSANCE_TEXT=(ru)Existence {0} at {1} does not conform to existence {2} at {3} in the parent archetype. +VACSO_TEXT=(ru)Occurrences greater than 1 for child object of single-valued attribute at path {0}. +VACSU_TEXT=(ru)Missing identifier for non-unique child object at {0}. +VACSI_TEXT=(ru)Duplicated identifier for child object at {0}. +VACSIT_TEXT=(ru) (Do not translate) +VACMI_TEXT=(ru)Missing child identification at {0}. +VACMM_NORMAL_TEXT=(ru)Duplicated identifier for child object at {0}. +VACMM_INTREF_TEXT=(ru)No identifier (node-id) for more than one child object (Archetype Internal Reference) with the same target at {0}. +VACMC_CONTAIN_TEXT=(ru)Cannot add {0} ({1}) object with node-id {2} to multiply-valued attribute items because cardinality {3} does not contain occurrences {4} of object. Attribute Path: {5} +VACMC_INTERSECT_TEXT=(ru)Cannot add child objects of the multi-valued attribute {0} because its cardinality {1} does not intersect with the sum of all occurrences of its children: {2} +VCACA_TEXT=(ru)Attribute items in object node at {0}: Cardinality {1} does not conform to cardinality {2} in reference model. +VSANCC_TEXT=(ru)Cardinality {0} at {1} does not conform to cardinality {2} at {3} in the parent archetype. +VCORM_TEXT=(ru)Unknown RM type {0} at path {1}. +VCORMT_NORMAL_TEXT=(ru)Unassignable RM type: {0} at path {1} is not assignable from type {2}. +VCORMT_PARENT_TEXT=(ru)Unassignable RM Type: {0} of object node at {1} is not assignable from {2} at {3}. +VSONCT_NORMAL_TEXT=(ru)RM Type {0} at {1} is not identical and does not conform to the reference model type {2} in the corresponding node of the parent archetype. +VSONCT_UNKNOWN_TEXT=(ru)RM Type {0} at {1} is not identical and does not conform to the reference model type {2} in the corresponding node of the parent archetype. At least one of these RM types is unknown. +VSONCT_UNKNOWNFORPARENT_TEXT=(ru)RM Type {0} in parent archetype at {1} is unknown. The child archetype cannot conform to an unknown RM type. +VSONCT_MORETHANONE_TEXT=(ru)RM Type {0} at {1} is not identical and does not conform to one of the reference model types {2} in the corresponding node of the parent archetype. +VSONIR_NORMAL_TEXT=(ru)Object node at path {0} (RM type: {1}) redefines corresponding node in parent archetype (RM type: {2}) but node id {3} is not redefined. +VSONIR_TEXTDESCRIPTION_TEXT=(ru)Object node at path {0} (RM type: {1}) redefines corresponding node in parent archetype (RM type: {2}) but node id {3} is not redefined. The text/description of the two terms is different for language {4}. +VSONCI_TEXT=(ru)The node id {0} does not conform to the node id of the parent archetype {1} by either being identical, or being a derived identifier at the exact specialisation level of the child. +VSONCO_TEXT=(ru)Occurrences {0} of object at {1} does not conform to occurrences {2} of the corresponding node of the parent archetype ({3}). +VSSM_TEXT=(ru) (Do not translate) +VOBAV_TEXT=(ru)Invalid assumed value: {0} for {1} at path {2}. +VCATU_TEXT=(ru)Sibling nodes are not uniquely named: {0} at path {1}. +VDFAI_NUMBEROFDOTS_TEXT=(ru)Invalid Archetype Identifier {0} used in Archetype Slot at {2}: The id does not have the correct amount of ''.''. +VDFAI_DOTVNUMBER_TEXT=(ru)Invalid Archetype Identifier {0} used in Archetype Slot at {2}: The id does not end with .v and a number. +VDFAI_NUMBEROFHYPHENS_TEXT=(ru)Invalid Archetype Identifier {0} used in Archetype Slot at {2}: The qualified RM Entity does not contain the correct number of hyphens. +VDFAI_SLOTVALIDITY_TEXT=(ru)Archetype Slot at {0} does not allow any archetypes to be included. +VDFAI_INVALIDPATTERN_TEXT=(ru)The pattern {0} of Archetype Slot at {1} contains an invalid pattern, i.e. the regular expression cannot be parsed. +VUNT_NORMAL_TEXT=(ru)Unassignable RM type {0} of archetype internal reference at path {1} is not assignable from type {2}. +VUNT_PARENT_TEXT=(ru)Unassignable RM Type {0} of object node at {1} is not assignable from {2} archetype internal reference at {3}. +VUNT_UNKOWN_TEXT=(ru)"Unknown RM type: {0} of archetype internal reference at path {1}. +VUNP_INVALIDPATH_TEXT=(ru)Invalid path: {0} of archetype internal reference at {1}. +VUNP_UNKNOWNTARGETRM_TEXT=(ru)Unknown target RM type at path {0} of archetype internal reference at {1}. +VUNP_INVALIDTARGETRM_TEXT=(ru)Invalid target RM type {0} of archetype internal reference at {1}. +VSCNR_TEXT=(ru) (Do not translate) +VOTC_TEXT=(ru)Unknown openEHR terminology code(s): {0} at path {1}. +VDSCR_PURPOSE_TEXT=(ru)The mandatory description of the Purpose is null, empty or unknown for language {0}. +VDSCR_ORIGINALAUTHOR_TEXT=(ru)The mandatory description of the original author is null, empty or unknown. +VDSCR_ORIGINALAUTHORPART_TEXT=(ru)The description of parts of the original author is null, empty or unknown: {0} +VDSCR_LIFECYCLE_TEXT=(ru)The mandatory description of the lifecycle is null, empty, unknown or a number. +VSONT_TEXT=(ru)The dynamic class {0} of the object at {1} is different to the dynamic type {2} of the corresponding node in the parent archetype. +WOUC_TEXT=(ru)Ontology code [{0}] for ontology language {1} is not used in archetype definition. +WITB_ATCODE_TEXT=(ru)The at-code {0} is referenced in the term bindings, but does not exist in the archetype. +WITB_PATH_TEXT=(ru)The path of the term binding {0} does not exist in the archetype. +WACMC_TEXT=(ru)Cannot add all child objects of the multi-valued attribute {0} because - while its cardinality {1} intersects with the sum of all occurrences of its children {2} - it would leave the occurrence potential of at least one element to be unsatisfiable, because all mandatory elements would already take up all the space in the container as defined by its cardinality. +ICARM_TEXT=(ru)Attribute [{0}] at {1} (type={2}) is a computed property in reference model. +VOKU_TEXT=(ru)Ontology code [{0}] is present more than once in archetype ontology (language: {1}). +VUI_TEXT=(ru)The unit {0} is not a valid UCUM unit. +VDL_TEXT=(ru)The language code ''{0}'' must not be present more than once. diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeDefinitionCodeCheckTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeDefinitionCodeCheckTest.java new file mode 100644 index 00000000..a8881794 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeDefinitionCodeCheckTest.java @@ -0,0 +1,20 @@ +package org.openehr.am.validation; + +public class ArchetypeDefinitionCodeCheckTest extends ArchetypeValidationTestBase { + + public void testCheckWithCorrectCode() throws Exception { + checkCode("adl-test-ENTRY.definition_code.v1"); + assertEquals("unexpected validation error: " + errors, 0, + errors.size()); + } + + public void testCheckWithWrongCode() throws Exception { + checkCode("adl-test-ENTRY.definition_code.v2"); + assertFirstErrorType(ErrorType.VACCD); + } + + private void checkCode(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkArchetypeDefinitionCodeValidity(archetype, errors); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeInternalRefCheckTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeInternalRefCheckTest.java new file mode 100644 index 00000000..848ee317 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeInternalRefCheckTest.java @@ -0,0 +1,58 @@ +package org.openehr.am.validation; + +public class ArchetypeInternalRefCheckTest extends ArchetypeValidationTestBase { + + public void testCheckWithRightReference() throws Exception { + checkInternalRef("openEHR-EHR-OBSERVATION.internal_reference.v1.adl"); + assertEquals("unexpected validation error: " + errors, 0, + errors.size()); + } + + public void testCheckWithInvalidType() throws Exception { + checkInternalRef("openEHR-EHR-OBSERVATION.internal_reference.v2.adl"); + assertFirstErrorType(ErrorType.VUNT); + } + + public void testCheckWithUnknownType() throws Exception { + checkInternalRef("openEHR-EHR-OBSERVATION.internal_reference.v5.adl"); + assertFirstErrorType(ErrorType.VCORM); + } + + public void testCheckWithPathToWrongObject() throws Exception { + checkInternalRef("openEHR-EHR-OBSERVATION.internal_reference.v3.adl"); + assertFirstErrorType(ErrorType.VUNP); + } + + public void testCheckWithPathToNonExistentObject() throws Exception { + checkInternalRef("openEHR-EHR-OBSERVATION.internal_reference.v4.adl"); + assertFirstErrorType(ErrorType.VUNP); + } + + public void testCheckNoNodeIdRequired() throws Exception { + checkInternalRef("openEHR-EHR-CLUSTER.internal_reference.v1.adl"); + assertEquals("unexpected validation error: " + errors, 0, + errors.size()); + } + + public void testCheckWithRightReferenceAndDifferentSourceParent() throws Exception { + checkInternalRef("openEHR-EHR-OBSERVATION.internal_reference.v6.adl"); + assertEquals("unexpected validation error: " + errors, 0, + errors.size()); + } + + public void testCheckWithNonUniqueArchetypeInternalRefForSameElement() throws Exception { + checkInternalRef("openEHR-EHR-CLUSTER.testNonUniqueInternalRef.v1.adl"); + assertFirstErrorType(ErrorType.VACMM); + } + + public void testCheckWithNonUniqueArchetypeInternalRefForDifferentElements() throws Exception { + checkInternalRef("openEHR-EHR-CLUSTER.testNonUniqueInternalRef.v2.adl"); + assertEquals("unexpected validation error: " + errors, 0, + errors.size()); + } + + private void checkInternalRef(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkObjectConstraints(archetype, errors); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeSlotCheckTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeSlotCheckTest.java new file mode 100644 index 00000000..cd3ca607 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeSlotCheckTest.java @@ -0,0 +1,51 @@ +package org.openehr.am.validation; + +public class ArchetypeSlotCheckTest extends ArchetypeValidationTestBase { + + public void testCheckWithRightArchetypeIdsInSlot() throws Exception { + checkSlot("openEHR-EHR-OBSERVATION.slot.v1.adl"); + assertEquals("unexpected validation error: " + errors, 0, + errors.size()); + } + + public void testCheckWithInvalidSlot() throws Exception { + checkSlot("openEHR-EHR-OBSERVATION.slot.v2.adl"); + assertEquals("wrong number of validation errors: " + errors, 4, errors.size()); + assertFirstErrorType(ErrorType.VDFAI); + assertSecondErrorType(ErrorType.VDFAI); + } + + public void testCheckWithValidSlotAllAllowed() throws Exception { + checkSlot("openEHR-EHR-OBSERVATION.slot.v3.adl"); + // SG: This slot is not giving an error * is the same as unconstrained + assertEquals("wrong number of validation errors: " + errors, 0, errors.size()); + + } + + public void testCheckWithValidInclude() throws Exception { + checkSlot("openEHR-EHR-OBSERVATION.slot.v4.adl"); + assertEquals("wrong number of validation errors: " + errors, 0, errors.size()); + } + + public void testCheckWithInvalidInclude() throws Exception { + checkSlot("openEHR-EHR-OBSERVATION.slot.v5.adl"); + assertEquals("wrong number of validation errors: " + errors, 1, errors.size()); + assertFirstErrorType(ErrorType.VDFAI); + } + + public void testCheckWithValidPipeInclude() throws Exception { + checkSlot("openEHR-EHR-OBSERVATION.slot.v6.adl"); + assertEquals("wrong number of validation errors: " + errors, 0, errors.size()); + } + + public void testCheckWithUnparsableRegexInclude() throws Exception { + checkSlot("openEHR-EHR-OBSERVATION.slot.v7.adl"); + assertEquals("wrong number of validation errors: " + errors, 1, errors.size()); + assertFirstErrorType(ErrorType.VDFAI); + } + + private void checkSlot(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkObjectConstraints(archetype, errors); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeTermValidityTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeTermValidityTest.java new file mode 100644 index 00000000..f43de6c8 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeTermValidityTest.java @@ -0,0 +1,78 @@ +package org.openehr.am.validation; + +public class ArchetypeTermValidityTest extends ArchetypeValidationTestBase { + + public void testCheckTermValidityWithMissingTermDef() throws Exception { + checkTerm("adl-test-ENTRY.term_definition.v1"); + assertEquals("wrong number of validation error in term def checking", 2, + errors.size()); + for(ValidationError error : errors) { + assertEquals("validation error type wrong", ErrorType.VATDF, + error.getType()); + } + } + + public void testCheckTermValidityWithCompleteTermDef() throws Exception { + checkTerm("adl-test-ENTRY.term_definition.v2"); + assertEquals("expected no validation error in term def checking", 0, + errors.size()); + } + + public void testCheckTermValidityWithMissingLanguage() throws Exception { + checkTerm("adl-test-ENTRY.term_definition.v3"); + assertEquals("expected validation error in term def checking", 1, + errors.size()); + for(ValidationError error : errors) { + assertEquals("validation error type wrong", ErrorType.VATDF, + error.getType()); + } + } + + public void testCheckTermValidityWithMissingTermInSecondaryLanguage() throws Exception { + checkTerm("adl-test-ENTRY.term_definition.v4"); + assertEquals("expected validation error in term def checking", 1, + errors.size()); + for(ValidationError error : errors) { + assertEquals("validation error type wrong", ErrorType.VONLC, + error.getType()); + } + } + + public void testCheckWithNoUnusedCodes() throws Exception { + checkTerm("adl-test-ENTRY.ontology-unusedcodes.v1.adl"); + assertEquals("unexpected validation error: " + errors, 0, + errors.size()); + } + + public void testCheckWithUnusedCodes() throws Exception { + checkTerm("adl-test-ENTRY.ontology-unusedcodes.v2.adl"); + assertEquals("unexpected amount of validation errors: " + errors, 1, + errors.size()); + assertFirstErrorType(ErrorType.WOUC); + } + + public void testCheckTermWithDoubleEntryInOntology() throws Exception { + checkTerm("openEHR-EHR-ELEMENT.doubleontologycode.v1.adl"); + assertEquals("expected 1 validation error in term def checking", 1, + errors.size()); + for(ValidationError error : errors) { + assertEquals("validation error type wrong", ErrorType.VOKU, + error.getType()); + } + } + + public void testCheckDoubleLanguage_Ontology() throws Exception { + archetype = loadArchetype("adl-test-ENTRY.term_definition.v6"); + validator.checkOntologyTranslation(archetype, errors); + + assertEquals("expected validation error in term def checking", 1, errors.size()); + for(ValidationError error : errors) { + assertEquals("validation error type wrong", ErrorType.VDL, error.getType()); + } + } + + private void checkTerm(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkArchetypeTermValidity(archetype, errors); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeValidationTestBase.java b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeValidationTestBase.java new file mode 100644 index 00000000..7eca841f --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeValidationTestBase.java @@ -0,0 +1,94 @@ +package org.openehr.am.validation; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.openehr.am.archetype.Archetype; + +import se.acode.openehr.parser.ADLParser; + +public class ArchetypeValidationTestBase extends TestCase { + + @Override + public void setUp() { + validator = new ArchetypeValidator(); + errors = new ArrayList(); + } + + @Override + public void tearDown() { + validator = null; + archetype = null; + errors = null; + } + + /** + * Loads archetype from given filename + * + * @param name + * @return + * @throws Exception + */ + protected Archetype loadArchetype(String name) throws Exception { + InputStream input = + this.getClass().getClassLoader().getResourceAsStream(name); + ADLParser parser = new ADLParser(input, "UTF-8"); + return parser.parse(); + } + + /** + * Asserts the first validation error is the same as the given error type + * + * @param type + */ + protected void assertFirstErrorType(ErrorType type) { + assertTrue("expected at least 1 error", errors.size() >= 1); + assertEquals("unexpected error(s): " + errors, type, + errors.get(0).getType()); + } + + /** + * Asserts the second validation error is the same as the given error type + * + * @param type + */ + protected void assertSecondErrorType(ErrorType type) { + assertTrue("expected at least 2 errors", errors.size() >= 2); + assertEquals("errorType wrong", type, errors.get(1).getType()); + } + + /** + * Asserts the 3rd validation error is the same as the given error type + * + * @param type + */ + protected void assertThirdErrorType(ErrorType type) { + assertTrue("expected at least 3 errors", errors.size() >= 3); + assertEquals("errorType wrong", type, errors.get(2).getType()); + } + + /** + * Asserts the 4th validation error is the same as the given error type + * + * @param type + */ + protected void assertFourthErrorType(ErrorType type) { + assertTrue("expected at least 4 errors", errors.size() >= 4); + assertEquals("errorType wrong", type, errors.get(3).getType()); + } + /** + * Asserts the 5th validation error is the same as the given error type + * + * @param type + */ + protected void assertFifthErrorType(ErrorType type) { + assertTrue("expected at least 5 errors", errors.size() >= 5); + assertEquals("errorType wrong", type, errors.get(4).getType()); + } + protected ArchetypeValidator validator; + protected Archetype archetype; + protected List errors; +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/AssumedValueTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/AssumedValueTest.java new file mode 100644 index 00000000..51054f48 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/AssumedValueTest.java @@ -0,0 +1,27 @@ +package org.openehr.am.validation; + +public class AssumedValueTest extends ArchetypeValidationTestBase { + + public void testCheckWrongQuantityAssumedValue() throws Exception { + CheckAssumedValue("adl-test-ELEMENT.assumed_value_quantity.v1.adl"); + assertEquals("expected wrong assumed value error", 1, errors.size()); + assertFirstErrorType(ErrorType.VOBAV); + } + + public void testCheckWrongBooleanAssumedValue() throws Exception { + CheckAssumedValue("adl-test-ELEMENT.assumed_value_boolean.v1.adl"); + assertEquals("expected wrong assumed value error", 1, errors.size()); + assertFirstErrorType(ErrorType.VOBAV); + } + + public void testCheckWrongCountAssumedValue() throws Exception { + CheckAssumedValue("adl-test-ELEMENT.assumed_value_boolean.v1.adl"); + assertEquals("expected wrong assumed value error", 1, errors.size()); + assertFirstErrorType(ErrorType.VOBAV); + } + + private void CheckAssumedValue(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkObjectConstraints(archetype, errors); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/AttributeNameCheckTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/AttributeNameCheckTest.java new file mode 100644 index 00000000..0424e525 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/AttributeNameCheckTest.java @@ -0,0 +1,46 @@ +package org.openehr.am.validation; + +public class AttributeNameCheckTest extends ArchetypeValidationTestBase { + + public void testCheckAttributeNameWithRightName() throws Exception { + checkAttributeName("adl-test-ENTRY.attribute_name.v1"); + assertEquals("expected no validation error", 0, errors.size()); + } + + public void testCheckAttributeNameWithWrongName() throws Exception { + checkAttributeName("adl-test-ENTRY.attribute_name.v2"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VCARM); + } + + public void testCheckAttributeNameWithFunctionalPropertyStrict() throws Exception { + checkAttributeName("adl-test-ENTRY.attribute_name.v3"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VCARM); + } + + public void testCheckAttributeNameWithFunctionalPropertyInfo() throws Exception { + validator.setReportConstraintsOnCommonFunctionalPropertiesAsInfo(true); + checkAttributeName("adl-test-ENTRY.attribute_name.v3"); + validator.setReportConstraintsOnCommonFunctionalPropertiesAsInfo(false); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.ICARM); + } + + public void testCheckNullFlavourAttributeName() throws Exception { + checkAttributeName("openEHR-EHR-EVALUATION.null_flavour.v1.adl"); + assertEquals("expected validation error", 0, errors.size()); + } + + public void testCheckNullFlavorAttributeName() throws Exception { + checkAttributeName("openEHR-EHR-EVALUATION.null_flavor.v1.adl"); + assertEquals("expected validation error", 2, errors.size()); + assertFirstErrorType(ErrorType.VCARM); + assertSecondErrorType(ErrorType.VCARM); + } + + private void checkAttributeName(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkObjectConstraints(archetype, errors); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/CodeConstraintValidityTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/CodeConstraintValidityTest.java new file mode 100644 index 00000000..82a00682 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/CodeConstraintValidityTest.java @@ -0,0 +1,48 @@ +package org.openehr.am.validation; + +public class CodeConstraintValidityTest extends ArchetypeValidationTestBase { + + public void testCodeConstraintCheckWithCompleteDef() throws Exception { + checkCodeConstraint("adl-test-ENTRY.code_constraint.v1"); + assertEquals("expected no error in code constraint checking", + 0, errors.size()); + } + + public void testCodeConstraintCheckWithMissingDef() throws Exception { + + checkCodeConstraint("adl-test-ENTRY.code_constraint.v2"); + assertEquals("expected 1 error in code constraint checking", + 1, errors.size()); + assertFirstErrorType(ErrorType.VACDF); + } + + public void testCodeConstraintCheckWithMissingDefInASecondaryLanguage() throws Exception { + // code constraint exists in primary language, but not in a translation + checkCodeConstraint("adl-test-ENTRY.code_constraint.v3"); + + assertEquals("expected 1 error in code constraint checking", + 1, errors.size()); + assertFirstErrorType(ErrorType.VONLC); + } + + public void testCheckWithNoUnusedConstraints() throws Exception { + checkCodeConstraint("adl-test-ENTRY.ontology-unusedcodes.v1.adl"); + assertEquals("unexpected validation error: " + errors, 0, + errors.size()); + } + + public void testCheckWithUnusedConstraints() throws Exception { + checkCodeConstraint("adl-test-ENTRY.ontology-unusedcodes.v2.adl"); + assertEquals("unexpected amount of validation errors: " + errors, 1, + errors.size()); + assertFirstErrorType(ErrorType.WOUC); + } + + + private void checkCodeConstraint(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkCodeConstraintValidity(archetype, errors); + } + + +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/DefinitionTypenameCheckTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/DefinitionTypenameCheckTest.java new file mode 100644 index 00000000..b42b8ebb --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/DefinitionTypenameCheckTest.java @@ -0,0 +1,24 @@ +package org.openehr.am.validation; + +public class DefinitionTypenameCheckTest extends ArchetypeValidationTestBase { + + public void testCheckTypenameWithWrongType() throws Exception { + checkTypename("adl-test-ENTRY.definition_typename.v1"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VARDT); + } + + public void testCheckTypenameWithRightType() throws Exception { + checkTypename("adl-test-ENTRY.definition_typename.v2"); + assertEquals("expected no validation error", 0, errors.size()); + + checkTypename("adl-test-ENTRY.definition_typename.v3"); + assertEquals("expected no validation error", 0, errors.size()); + } + + private void checkTypename(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkArchetypeDefinitionTypename(archetype, errors); + } + +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/DvQuantityUnitsTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/DvQuantityUnitsTest.java new file mode 100644 index 00000000..b80a4c12 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/DvQuantityUnitsTest.java @@ -0,0 +1,17 @@ +package org.openehr.am.validation; + +public class DvQuantityUnitsTest extends ArchetypeValidationTestBase { + + public void testCheckUnits() throws Exception { + CheckUnits("openEHR-EHR-CLUSTER.units_test.v1.adl"); + assertEquals("expected 10 wrong units", 10, errors.size()); + assertFirstErrorType(ErrorType.VUI); + assertSecondErrorType(ErrorType.VUI); + } + + + private void CheckUnits(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkObjectConstraints(archetype, errors); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/MultiValueAttributeChildIdentifierCheckTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/MultiValueAttributeChildIdentifierCheckTest.java new file mode 100644 index 00000000..228c76ae --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/MultiValueAttributeChildIdentifierCheckTest.java @@ -0,0 +1,28 @@ +package org.openehr.am.validation; + +public class MultiValueAttributeChildIdentifierCheckTest + extends ArchetypeValidationTestBase { + + public void testCheckMultiAttributeChildIdentifierWithGoodIds() throws Exception { + checkAttribute("adl-test-ITEM_TREE.multi_attribute_child_identifier.v1"); + assertEquals("expected no validation error", 0, errors.size()); + } + + public void testCheckMultiAttributeChildIdentifierWithMissingId() throws Exception { + checkAttribute("adl-test-ITEM_TREE.multi_attribute_child_identifier.v2"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VACMI); + } + + public void testCheckMultiAttributeChildIdentifierWithDuplicatedIds() throws Exception { + checkAttribute("adl-test-ITEM_TREE.multi_attribute_child_identifier.v3"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VACMM); + } + + private void checkAttribute(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkObjectConstraints(archetype, errors); + } +} + diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/MultipleValueAttributeCardinalityTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/MultipleValueAttributeCardinalityTest.java new file mode 100644 index 00000000..959ac226 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/MultipleValueAttributeCardinalityTest.java @@ -0,0 +1,55 @@ +package org.openehr.am.validation; + +public class MultipleValueAttributeCardinalityTest + extends ArchetypeValidationTestBase { + + public void testCheckMultiAttributeCardinalityNotContainingOccurence() throws Exception { + checkAttribute("adl-test-ITEM_TREE.attribute_cardinality.v1"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VACMC); + } + + public void testCheckMultiAttributeCardinalityNotConformingToReferenceModel() throws Exception { + // testing that a cardinality constraint from the reference model is honoured in the actual archetype + checkAttribute("adl-test-ITEM_TREE.attribute_cardinality.v2"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VCACA); + } + + public void testCheckMultiAttributeCardinalityCredentialsNotConformingToReferenceModel() throws Exception { + // testing that a cardinality constraint from the reference model is honoured in the actual archetype + checkAttribute("adl-test-ITEM_TREE.attribute_cardinality.v3"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VCACA); + } + + public void testCheckSumOfOccurrencesNotIntersectingWithCardinality () throws Exception { + // testing whether sum of occurrences intersects with cardinality + checkAttribute("openEHR-EHR-CLUSTER.cardinality_occurrences.v1.adl"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VACMC); + } + + + // As per now it is not clear how this should be handled - no error, VACMC or maybe a WACMC warning + // We use the warning for now + public void testCheckSumOfOccurrencesNotIntersectingWithCardinalityEdgeCase () throws Exception { + checkAttribute("openEHR-EHR-CLUSTER.cardinality_occurrences2.v1.adl"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.WACMC); + } + + + public void testCheckSumOfOccurrencesIntersectingWithCardinality () throws Exception { + // testing whether sum of occurrences intersects with cardinality + checkAttribute("openEHR-EHR-CLUSTER.cardinality_occurrences3.v1.adl"); + assertEquals("expected no validation errors", 0, errors.size()); + } + + + private void checkAttribute(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkObjectConstraints(archetype, errors); + } +} + diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/OntologyCodeSpecialisationCheckTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/OntologyCodeSpecialisationCheckTest.java new file mode 100644 index 00000000..2b2c1666 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/OntologyCodeSpecialisationCheckTest.java @@ -0,0 +1,37 @@ +package org.openehr.am.validation; + +public class OntologyCodeSpecialisationCheckTest extends ArchetypeValidationTestBase { + + public void testCheckWithNoCodeSpecialisation() throws Exception { + checkCodeSpecialisation("adl-test-ENTRY.ontology-specialisation.v1.adl"); + assertEquals("unexpected validation error: " + errors, 0, + errors.size()); + } + + public void testCheckWithCorrectCodeSpecialisation() throws Exception { + checkCodeSpecialisation("adl-test-ENTRY.ontology-specialisation.v2.adl"); + assertEquals("unexpected validation error: " + errors, 0, + errors.size()); + } + + public void testCheckWithCorrectThreeLevelSpecialisation() throws Exception { + checkCodeSpecialisation("adl-test-ENTRY.ontology-specialisation.v5.adl"); + assertEquals("unexpected validation error: " + errors, 0, + errors.size()); + } + + public void testCheckWithGreaterSpecialisationLevelInTermDef() throws Exception { + checkCodeSpecialisation("adl-test-ENTRY.ontology-specialisation.v3.adl"); + assertFirstErrorType(ErrorType.VONSD); + } + + public void testCheckWithGreaterSpecialisationLevelInConstraintDef() throws Exception { + checkCodeSpecialisation("adl-test-ENTRY.ontology-specialisation.v4.adl"); + assertFirstErrorType(ErrorType.VONSD); + } + + private void checkCodeSpecialisation(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkOntologyCodeSpecialisationLevelValidity(archetype, errors); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/OntologyTranslationCheckTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/OntologyTranslationCheckTest.java new file mode 100644 index 00000000..33309789 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/OntologyTranslationCheckTest.java @@ -0,0 +1,59 @@ +package org.openehr.am.validation; + +public class OntologyTranslationCheckTest extends ArchetypeValidationTestBase { + + public void testTranslationCheckWithNoTranslation() throws Exception { + checkTranslation("adl-test-ENTRY.ontology_translation.v1"); + assertEquals("expected no validation error", 0, errors.size()); + } + + public void testTranslationCheckWithoutConstraintDef() throws Exception { + checkTranslation("adl-test-ENTRY.ontology_translation.v7"); + assertEquals("expected no validation error", 0, errors.size()); + } + + public void testTranslationCheckWithMissingTermAndConstraintTranslation() + throws Exception { + checkTranslation("adl-test-ENTRY.ontology_translation.v2"); + assertEquals("expected validation error", 2, errors.size()); + assertFirstErrorType(ErrorType.VOTM); + assertSecondErrorType(ErrorType.VOTM); + } + + public void testTranslationCheckWithMissingTermTranslation() + throws Exception { + checkTranslation("adl-test-ENTRY.ontology_translation.v3"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VOTM); + } + + public void testTranslationCheckWithMissingConstraintTranslation() + throws Exception { + checkTranslation("adl-test-ENTRY.ontology_translation.v4"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VOTM); + } + + public void testTranslationCheckWithCompleteTranslation() throws Exception { + checkTranslation("adl-test-ENTRY.ontology_translation.v5"); + assertEquals("expected no validation error", 0, errors.size()); + } + + public void testTranslationCheckWithTwoMissingTranslation() throws Exception { + checkTranslation("adl-test-ENTRY.ontology_translation.v6"); + assertEquals("expected validation error", 2, errors.size()); + assertFirstErrorType(ErrorType.VOTM); + assertSecondErrorType(ErrorType.VOTM); + } + + public void testTranslationCheckWithoutMatchingDescriptionDetails() throws Exception { + checkTranslation("adl-test-ENTRY.ontology_translation.v8"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VOTM); + } + + private void checkTranslation(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkOntologyTranslation(archetype, errors); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/RMInspectorTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/RMInspectorTest.java new file mode 100644 index 00000000..b6d6a21b --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/RMInspectorTest.java @@ -0,0 +1,78 @@ +package org.openehr.am.validation; + +import java.util.Set; + +import org.openehr.rm.composition.content.entry.Evaluation; +import org.openehr.rm.datastructure.history.Event; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datatypes.quantity.DvQuantity; +import org.openehr.rm.datatypes.uri.DvURI; +import org.openehr.rm.common.generic.PartyProxy; + +import junit.framework.TestCase; + +public class RMInspectorTest extends TestCase { + + public void setUp() throws Exception { + inspector = new RMInspector(); + } + + public void testRetrieveRMTypeWithElement() throws Exception { + Class klass = inspector.retrieveRMType("ELEMENT"); + assertTrue("incorrect class for element", klass.equals(Element.class)); + } + + public void testRetrieveRMTypeWithEvaluation() throws Exception { + Class klass = inspector.retrieveRMType("EVALUATION"); + assertTrue("incorrect class for evaluation", klass.equals(Evaluation.class)); + } + + public void testRetrieveRMTypeWithInteger() throws Exception { + Class klass = inspector.retrieveRMType("INTEGER"); + assertTrue("incorrect class for integer", klass.equals(Integer.class)); + } + + public void testRetrieveRMTypeWithDvQuantity() throws Exception { + Class klass = inspector.retrieveRMType("DV_QUANTITY"); + assertTrue("incorrect class for dvQuantity", klass.equals(DvQuantity.class)); + } + + public void testRetrieveRMTypeWithDvURI() throws Exception { + Class klass = inspector.retrieveRMType("DV_URI"); + assertTrue("incorrect class for dvUri", klass.equals(DvURI.class)); + } + + public void testRetrieveRMTypeWithAbstractClassEVENT() throws Exception { + Class klass = inspector.retrieveRMType("EVENT"); + assertNotNull("failed to retrieve EVENT", klass); + assertTrue("incorrect class for Event", klass.equals(Event.class)); + } + + public void testRetrieveRMTypeWithAbstractClassPartyProxy() throws Exception { + Class klass = inspector.retrieveRMType("PARTY_PROXY"); + assertNotNull("failed to retrieve PARTY_PROXY", klass); + assertTrue("incorrect class for PARTY_PROXY", klass.equals(PartyProxy.class)); + } + + public void testRetrieveRMAttributeNamesWithEVENT() throws Exception { + assertFalse("failed to retrieve attribute names with EVENT", + inspector.retrieveRMAttributeNames("EVENT").isEmpty()); + } + + public void testRetrieveRMAttributeNamesWithObservation() throws Exception { + Set attrs = inspector.retrieveRMAttributeNames("OBSERVATION"); + assertTrue("data attribute missing", attrs.contains("data")); + assertTrue("state attribute missing", attrs.contains("state")); + assertTrue("protocol attribute missing", attrs.contains("protocol")); + assertTrue("subject attribute missing", attrs.contains("subject")); + assertTrue("provider attribute missing", attrs.contains("provider")); + } + + public void testRetrieveRMAttributeNamesWithCodedText() throws Exception { + Set attrs = inspector.retrieveRMAttributeNames("DV_CODED_TEXT"); + assertTrue("defining_code attribute missing", + attrs.contains("defining_code")); + } + + private RMInspector inspector; +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/SectionCardinalityTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/SectionCardinalityTest.java new file mode 100644 index 00000000..dbab30f4 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/SectionCardinalityTest.java @@ -0,0 +1,17 @@ +package org.openehr.am.validation; + +public class SectionCardinalityTest + extends ArchetypeValidationTestBase { + + public void testCheckSectionItemsCardinality() throws Exception { + checkObjectConstraints("openEHR-EHR-SECTION.testitemscardinality.v1.adl"); + assertEquals("expected NO validation error", 0, errors.size()); + } + + + private void checkObjectConstraints(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkObjectConstraints(archetype, errors); + } +} + diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/SingleValueAttributeChildIdentifierCheckTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/SingleValueAttributeChildIdentifierCheckTest.java new file mode 100644 index 00000000..f27676ca --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/SingleValueAttributeChildIdentifierCheckTest.java @@ -0,0 +1,21 @@ +package org.openehr.am.validation; + +public class SingleValueAttributeChildIdentifierCheckTest + extends ArchetypeValidationTestBase { + + public void testCheckSingleAttributeChildIdentifierWithGoodIds() throws Exception { + checkAttribute("adl-test-ENTRY.single_attribute_child_identifier.v1"); + assertEquals("expected no validation error", 0, errors.size()); + } + + public void testCheckSingleAttributeChildIdentifierWithDuplicatedIds() throws Exception { + checkAttribute("adl-test-ENTRY.single_attribute_child_identifier.v2"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VACSI); + } + + private void checkAttribute(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkObjectConstraints(archetype, errors); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/SingleValueAttributeChildOccurrencesCheckTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/SingleValueAttributeChildOccurrencesCheckTest.java new file mode 100644 index 00000000..8bfa417b --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/SingleValueAttributeChildOccurrencesCheckTest.java @@ -0,0 +1,26 @@ +package org.openehr.am.validation; + +public class SingleValueAttributeChildOccurrencesCheckTest + extends ArchetypeValidationTestBase { + + public void testCheckChildOccurrencesWithNoOccurrences() throws Exception { + checkAttributeName("adl-test-ENTRY.single_attribute_child_occurrences.v1"); + assertEquals("expected no validation error", 0, errors.size()); + } + + public void testCheckChildOccurrencesRightOccurrences() throws Exception { + checkAttributeName("adl-test-ENTRY.single_attribute_child_occurrences.v2"); + assertEquals("expected no validation error", 0, errors.size()); + } + + public void testCheckChildOccurrencesWithWrongOccurrences() throws Exception { + checkAttributeName("adl-test-ENTRY.single_attribute_child_occurrences.v3"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VACSO); + } + + private void checkAttributeName(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkObjectConstraints(archetype, errors); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/SingleValueAttributeChildUniquenessCheckTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/SingleValueAttributeChildUniquenessCheckTest.java new file mode 100644 index 00000000..63fa55ec --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/SingleValueAttributeChildUniquenessCheckTest.java @@ -0,0 +1,27 @@ +package org.openehr.am.validation; + +public class SingleValueAttributeChildUniquenessCheckTest + extends ArchetypeValidationTestBase { + + public void testCheckChildUniquenessithRightUniqueness() throws Exception { + checkAttribute("adl-test-ENTRY.single_attribute_child_uniqueness.v1"); + assertEquals("expected no validation error", 0, errors.size()); + } + + public void testCheckChildUniquenessWithSingleChild() throws Exception { + checkAttribute("adl-test-ENTRY.single_attribute_child_uniqueness.v3"); + assertEquals("expected no validation error", 0, errors.size()); + } + + public void testCheckChildUniquenessWithMissingIdentifier() throws Exception { + checkAttribute("adl-test-ENTRY.single_attribute_child_uniqueness.v2"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VACSU); + } + + private void checkAttribute(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkObjectConstraints(archetype, errors); + } +} + diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeCardinalityTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeCardinalityTest.java new file mode 100644 index 00000000..c228ffbb --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeCardinalityTest.java @@ -0,0 +1,22 @@ +package org.openehr.am.validation; + +public class SpecialisedArchetypeCardinalityTest extends SpecialisedArchetypeValidationTestBase{ + + public void testCheckArchetypesWithCorrectCardinalitySpecialisation() throws Exception { + checkSpecialization("adl-specialised-EVALUATION.cardinality-specialised.v1", "adl-specialised-EVALUATION.cardinality.v1"); + assertEquals("expected no validation error", 0, errors.size()); + } + + public void testCheckArchetypesWithIncorrectCardinalitySpecialisation() throws Exception { + checkSpecialization("adl-specialised-EVALUATION.cardinality-specialised.v2", "adl-specialised-EVALUATION.cardinality.v1"); + assertEquals("expected one validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VSANCC); + } + + private void checkSpecialization(String name, String parentName) throws Exception { + archetype = loadArchetype(name); + parentArchetype = loadArchetype(parentName); + + errors = validator.validate(archetype, parentArchetype, true); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeExistenceTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeExistenceTest.java new file mode 100644 index 00000000..807f81a2 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeExistenceTest.java @@ -0,0 +1,18 @@ +package org.openehr.am.validation; + +public class SpecialisedArchetypeExistenceTest extends SpecialisedArchetypeValidationTestBase{ + + public void testCheckArchetypesWithNonConformantExistence() throws Exception { + checkSpecialization("adl-specialised-EVALUATION.existence-specialised.v1", "adl-specialised-EVALUATION.existence.v1"); + assertEquals("expected one validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VSANCE); + } + + + private void checkSpecialization(String name, String parentName) throws Exception { + archetype = loadArchetype(name); + parentArchetype = loadArchetype(parentName); + + errors = validator.validate(archetype, parentArchetype, true); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeMultiplicityTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeMultiplicityTest.java new file mode 100644 index 00000000..f186743f --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeMultiplicityTest.java @@ -0,0 +1,18 @@ +package org.openehr.am.validation; + +public class SpecialisedArchetypeMultiplicityTest extends SpecialisedArchetypeValidationTestBase{ + + public void testCheckArchetypesWithNonConformantMultiplicity() throws Exception { + checkSpecialization("adl-specialised-EVALUATION.multiplicity-specialised.v1", "adl-specialised-EVALUATION.multiplicity.v1"); + assertEquals("expected one validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VSAM); + } + + + private void checkSpecialization(String name, String parentName) throws Exception { + archetype = loadArchetype(name); + parentArchetype = loadArchetype(parentName); + + errors = validator.validate(archetype, parentArchetype, true); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeNodeIdConformanceTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeNodeIdConformanceTest.java new file mode 100644 index 00000000..77c09bfa --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeNodeIdConformanceTest.java @@ -0,0 +1,17 @@ +package org.openehr.am.validation; + +public class SpecialisedArchetypeNodeIdConformanceTest extends SpecialisedArchetypeValidationTestBase{ + + public void testCheckArchetypesWithNonConformantMultiplicity() throws Exception { + checkSpecialization("adl-specialised-EVALUATION.node_id_conformance-specialised-again.v1", "adl-specialised-EVALUATION.node_id_conformance-specialised.v1"); + assertEquals("expected one validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VSONCI); + } + + + private void checkSpecialization(String name, String parentName) throws Exception { + archetype = loadArchetype(name); + parentArchetype = loadArchetype(parentName); + errors = validator.validate(archetype, parentArchetype, true); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeNodeSpecialisedAsRequiredTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeNodeSpecialisedAsRequiredTest.java new file mode 100644 index 00000000..7f39546e --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeNodeSpecialisedAsRequiredTest.java @@ -0,0 +1,18 @@ +package org.openehr.am.validation; + +public class SpecialisedArchetypeNodeSpecialisedAsRequiredTest extends SpecialisedArchetypeValidationTestBase{ + + public void testCheckArchetypesWithNodeThatShouldBeSpecialised() throws Exception { + checkSpecialization("adl-specialised-EVALUATION.node_specialised_as_required-specialised.v1", "adl-specialised-EVALUATION.node_specialised_as_required.v1"); + assertEquals("expected one validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VSONIR); + } + + + private void checkSpecialization(String name, String parentName) throws Exception { + archetype = loadArchetype(name); + parentArchetype = loadArchetype(parentName); + + errors = validator.validate(archetype, parentArchetype, true); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeNonCComplexObjectTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeNonCComplexObjectTest.java new file mode 100644 index 00000000..92ae8108 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeNonCComplexObjectTest.java @@ -0,0 +1,20 @@ +package org.openehr.am.validation; + +public class SpecialisedArchetypeNonCComplexObjectTest extends SpecialisedArchetypeValidationTestBase{ + + // Checks that there is no class cast exception anywhere for a C_DV_QUANTITY instead of a CComplexObject. + // Also checks that a loosening of constraints is being picked up where a choice construct is introduced. + public void testCheckArchetypesWithNonConformantMultiplicity() throws Exception { + checkSpecialization("openEHR-EHR-CLUSTER.test_non_ccomplexobject-spec.v1.adl", "openEHR-EHR-CLUSTER.test_non_ccomplexobject.v1.adl"); + assertEquals("expected one validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VSONCT); + } + + + private void checkSpecialization(String name, String parentName) throws Exception { + archetype = loadArchetype(name); + parentArchetype = loadArchetype(parentName); + + errors = validator.validate(archetype, parentArchetype, true); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeOccurrencesTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeOccurrencesTest.java new file mode 100644 index 00000000..ec8bc6b0 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeOccurrencesTest.java @@ -0,0 +1,18 @@ +package org.openehr.am.validation; + +public class SpecialisedArchetypeOccurrencesTest extends SpecialisedArchetypeValidationTestBase{ + + public void testCheckArchetypesWithNonConformantOccurrences() throws Exception { + checkSpecialization("adl-specialised-EVALUATION.occurrences-specialised.v1", "adl-specialised-EVALUATION.occurrences.v1"); + assertEquals("expected one validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VSONCO); + } + + + private void checkSpecialization(String name, String parentName) throws Exception { + archetype = loadArchetype(name); + parentArchetype = loadArchetype(parentName); + + errors = validator.validate(archetype, parentArchetype, true); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeTermExistsTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeTermExistsTest.java new file mode 100644 index 00000000..b7ae17a4 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeTermExistsTest.java @@ -0,0 +1,34 @@ +package org.openehr.am.validation; + +public class SpecialisedArchetypeTermExistsTest extends SpecialisedArchetypeValidationTestBase{ + + public void testCheckArchetypesWithCorrectTermsInParent() throws Exception { + checkSpecialization("adl-specialised-EVALUATION.term_existence-specialised.v1", "adl-specialised-EVALUATION.term_existence.v1"); + assertEquals("expected no validation errors", 0, errors.size()); + } + + + public void testCheckArchetypesWithMissingTermInParent() throws Exception { + checkSpecialization("adl-specialised-EVALUATION.term_existence-specialised.v2", "adl-specialised-EVALUATION.term_existence.v2"); + assertEquals("expected one validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VATDF); + } + + public void testCheckArchetypesWithSecondLevelNodeThatIsCorrectlyUsedInTheThirdLevel() throws Exception { + checkSpecialization("openEHR-EHR-OBSERVATION.order1-order2-order3.v1.adl", "openEHR-EHR-OBSERVATION.order1-order2.v1.adl"); + assertEquals("expected no validation error", 0, errors.size()); + } + + public void testCheckArchetypesWithSecondLevelNodeThatIsUsedInThirdLevelButNotPresentInSecondLevel() throws Exception { + checkSpecialization("openEHR-EHR-OBSERVATION.order1-order2-order3a.v1.adl", "openEHR-EHR-OBSERVATION.order1-order2.v1.adl"); + assertEquals("expected no validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VATDF); + } + + private void checkSpecialization(String name, String parentName) throws Exception { + archetype = loadArchetype(name); + parentArchetype = loadArchetype(parentName); + + errors = validator.validate(archetype, parentArchetype, true); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeValidationTestBase.java b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeValidationTestBase.java new file mode 100644 index 00000000..d6e70e14 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeValidationTestBase.java @@ -0,0 +1,68 @@ +package org.openehr.am.validation; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.openehr.am.archetype.Archetype; + +import se.acode.openehr.parser.ADLParser; + +public class SpecialisedArchetypeValidationTestBase extends TestCase { + + @Override + public void setUp() { + validator = new SpecialisedArchetypeValidator(); + errors = new ArrayList(); + } + + @Override + public void tearDown() { + validator = null; + archetype = null; + parentArchetype=null; + errors = null; + } + + /** + * Loads archetype from given filename + * + * @param name + * @return + * @throws Exception + */ + protected Archetype loadArchetype(String name) throws Exception { + InputStream input = + this.getClass().getClassLoader().getResourceAsStream(name); + ADLParser parser = new ADLParser(input, "UTF-8"); + return parser.parse(); + } + + /** + * Asserts the first validation error is the same as the given error type + * + * @param type + */ + protected void assertFirstErrorType(ErrorType type) { + assertTrue("expected at least 1 error", errors.size() >= 1); + assertEquals("unexpected error(s): " + errors, type, + errors.get(0).getType()); + } + + /** + * Asserts the second validation error is the same as the given error type + * + * @param type + */ + protected void assertSecondErrorType(ErrorType type) { + assertTrue("expected at least 2 error", errors.size() >= 2); + assertEquals("errorType wrong", type, errors.get(1).getType()); + } + + protected SpecialisedArchetypeValidator validator; + protected Archetype archetype; + protected Archetype parentArchetype; + protected List errors; +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeWrongRMTypeTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeWrongRMTypeTest.java new file mode 100644 index 00000000..ab4582f0 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeWrongRMTypeTest.java @@ -0,0 +1,30 @@ +package org.openehr.am.validation; + +public class SpecialisedArchetypeWrongRMTypeTest extends SpecialisedArchetypeValidationTestBase{ + + + + public void testCheckArchetypesWithConformantRMTypeForChoice() throws Exception { + checkSpecialization("adl-specialised-EVALUATION.wrongrmtype-specialised.v1", "adl-specialised-EVALUATION.wrongrmtype.v1"); + assertEquals("expected no validation errors", 0, errors.size()); + } + + public void testCheckArchetypesWithNonConformantRMType() throws Exception { + checkSpecialization("adl-specialised-EVALUATION.wrongrmtype-specialised.v2", "adl-specialised-EVALUATION.wrongrmtype.v2"); + assertEquals("expected one validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VSONCT); + } + + public void testCheckArchetypesWithRMTypeWithGenericsWrong() throws Exception { + checkSpecialization("adl-specialised-EVALUATION.wrongrmtype-specialised.v3", "adl-specialised-EVALUATION.wrongrmtype.v3"); + assertEquals("expected one validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VSONCT); + } + + private void checkSpecialization(String name, String parentName) throws Exception { + archetype = loadArchetype(name); + parentArchetype = loadArchetype(parentName); + + errors = validator.validate(archetype, parentArchetype, true); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/SpecializationArchetypeIdTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/SpecializationArchetypeIdTest.java new file mode 100644 index 00000000..c9c92b4a --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/SpecializationArchetypeIdTest.java @@ -0,0 +1,31 @@ +package org.openehr.am.validation; + +public class SpecializationArchetypeIdTest extends ArchetypeValidationTestBase{ + + public void testCheckArchetypeWithCorrectParentIdentifier() throws Exception { + checkSpecializationParentIdentifierValidity("adl-test-ELEMENT.specialization-archetypeid.v1.adl"); + assertEquals("expected no validation error", 0, errors.size()); + } + + public void testCheckArchetypeWithWrongParentIdentifier() throws Exception { + checkSpecializationParentIdentifierValidity("adl-test-ELEMENT.specialization-archetypeid.v2.adl"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VASID); + } + + public void testCheckArchetypeWithDraftParentIdentifier() throws Exception { + checkSpecializationParentIdentifierValidity("adl-test-ELEMENT.specialization-archetypeid.v3.adl"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VASID); + } + + public void testCheckArchetypeWithoutSpecialization() throws Exception { + checkSpecializationParentIdentifierValidity("openEHR-EHR-EVALUATION.adverse.v1.adl"); + assertEquals("expected no validation error", 0, errors.size()); + } + + private void checkSpecializationParentIdentifierValidity(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkSpecializationParentIdentifierValidity(archetype, errors); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/SpecializationDepthCheckTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/SpecializationDepthCheckTest.java new file mode 100644 index 00000000..39c5ad5d --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/SpecializationDepthCheckTest.java @@ -0,0 +1,60 @@ +package org.openehr.am.validation; + +import org.openehr.am.archetype.Archetype; + +public class SpecializationDepthCheckTest extends ArchetypeValidationTestBase{ + + public void testCheckAttributeNameWithRightLevel() throws Exception { + checkConceptNameSpecializationDepth("adl-test-ELEMENT.specialization-depth.v1.adl"); + assertEquals("expected no validation error", 0, errors.size()); + } + + public void testCheckAttributeNameWithWrongLevel() throws Exception { + checkConceptNameSpecializationDepth("adl-test-ELEMENT.specialization-depth.v2.adl"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VACSD); + } + + public void testCheckConceptNameWithLevelGenerallyToHighForTheLevelOfArchetypeSpecialisation() throws Exception { + checkAll("adl-test-ELEMENT.specialization-depth.v3.adl", "adl-test-ELEMENT.specialization.v1.adl"); + assertEquals("expected validation errors", 5, errors.size()); + + // These 5 errors are a little bit redundant or at least it may seem so. + // The order of the errors is of course not important and might change in the future + assertFirstErrorType(ErrorType.VACSD); // Especially for the concept specialisation depth + assertSecondErrorType(ErrorType.VONSD); // an error for the at code in the ontology which is generally too high for the archetype. + assertThirdErrorType(ErrorType.VATDF); // This is just a follow up error because the parent doesn't have the wrong(!) parent at code of at0000.1 + assertFourthErrorType(ErrorType.VSONCI); // Conformance of specialisation - again in a slightly different way. + assertFifthErrorType(ErrorType.VATCD); // an error for the at code in the definition part of the archetype which is generally too high for the archetype. + + } + + public void testCheckTermWithLevelGenerallyToHighForTheLevelOfArchetypeSpecialisation() throws Exception { + checkAll("adl-test-ELEMENT.specialization-depth.v4.adl", "adl-test-ELEMENT.specialization.v1.adl"); + + assertEquals("expected validation errors", 2, errors.size()); + assertFirstErrorType(ErrorType.VONSD); // an error for the at code in the ontology which is generally too high for the archetype. + assertSecondErrorType(ErrorType.VATCD); // an error for the at code in the definition part of the archetype which is generally too high for the archetype. + + } + + public void testCheckConstraintWithLevelGenerallyToHighForTheLevelOfArchetypeSpecialisation() throws Exception { + checkAll("adl-test-ELEMENT.specialization-depth.v5.adl", "adl-test-ELEMENT.specialization.v1.adl"); + assertEquals("expected validation errors", 2, errors.size()); + assertFirstErrorType(ErrorType.VONSD); // an error for the ac code in the ontology which is generally too high for the archetype. + assertSecondErrorType(ErrorType.VATCD); // an error for the ac code in the definition part of the archetype which is generally too high for the archetype. + + } + + private void checkConceptNameSpecializationDepth(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkConceptSpecializationDepth(archetype, errors); + } + + private void checkAll(String name, String parentName) throws Exception { + archetype = loadArchetype(name); + Archetype parentArchetype = loadArchetype(parentName); + errors = new SpecialisedArchetypeValidator().validate(archetype, parentArchetype, true); + + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/TermBindingsValidityTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/TermBindingsValidityTest.java new file mode 100644 index 00000000..9d758619 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/TermBindingsValidityTest.java @@ -0,0 +1,27 @@ +package org.openehr.am.validation; + +public class TermBindingsValidityTest extends ArchetypeValidationTestBase { + + public void testTermBindingCorrectOnly() throws Exception { + checkTermBinding("adl-test-ENTRY.term_bindings.v1"); + assertEquals("expected no error in term binding checking", + 0, errors.size()); + } + + public void testTermBindingWrongPaths() throws Exception { + checkTermBinding("adl-test-ENTRY.term_bindings.v2"); + assertEquals("expected validation errors in term binding checking", 4, + errors.size()); + for(ValidationError error : errors) { + assertEquals("validation error type wrong", ErrorType.WITB, + error.getType()); + } + } + + private void checkTermBinding(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkArchetypeTermBindingsValidity(archetype, errors); + } + + +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/TypeNameCheckTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/TypeNameCheckTest.java new file mode 100644 index 00000000..475bc046 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/TypeNameCheckTest.java @@ -0,0 +1,141 @@ +package org.openehr.am.validation; + +import org.openehr.rm.datatypes.basic.DataValue; +import org.openehr.rm.datatypes.quantity.DvCount; +import org.openehr.rm.datatypes.quantity.DvInterval; + +public class TypeNameCheckTest extends ArchetypeValidationTestBase { + + public void testCheckTypeNameWithRightName() throws Exception { + CheckTypeName("adl-test-ELEMENT.type_name.v1"); + assertEquals("expected no validation error", 0, errors.size()); + } + + public void testCheckTypeNameWithEvent() throws Exception { + CheckTypeName("openEHR-EHR-OBSERVATION.type_name.v4.adl"); + assertEquals("unexpected validation error: " + errors, 0, + errors.size()); + } + + public void testCheckTypeNameWithExplicitDvCount() throws Exception { + CheckTypeName("adl-test-ELEMENT.type_count.v1.adl"); + assertEquals("unexpected validation error(s): " + errors, 0, + errors.size()); + } + + public void testCheckTypeNameWithExplicitDvDuration() throws Exception { + CheckTypeName("adl-test-ELEMENT.type_duration.v1.adl"); + assertEquals("unexpected validation error(s): " + errors, 0, + errors.size()); + } + + public void testCheckTypeNameWithUnknownName() throws Exception { + CheckTypeName("adl-test-ELEMENT.type_name.v2"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VCORM); + } + + public void testCheckTypeNameWithExplicitPartyProxy() throws Exception { + CheckTypeName("adl-test-PARTY_PROXY.type_name.v1"); + assertEquals("unexpected validation error(s): " + errors, 0, + errors.size()); + } + + public void testCheckTypeNameWithUnassignableName() throws Exception { + CheckTypeName("adl-test-ELEMENT.type_name.v3"); + assertEquals("expected validation error", 1, errors.size()); + assertFirstErrorType(ErrorType.VCORMT); + } + + public void testCheckTypeNameExplicitDvDate() throws Exception { + CheckTypeName("adl-test-ELEMENT.type_date.v1.adl"); + assertEquals("unexpected validation error(s): " + errors, 0, + errors.size()); + } + + public void testCheckTypeNameExplicitDvDateTime() throws Exception { + CheckTypeName("adl-test-ELEMENT.type_datetime.v1.adl"); + assertEquals("unexpected validation error(s): " + errors, 0, + errors.size()); + } + + public void testCheckTypeNameExplicitDvBoolean() throws Exception { + CheckTypeName("adl-test-ELEMENT.type_boolean.v1.adl"); + assertEquals("unexpected validation error(s): " + errors, 0, + errors.size()); + } + + public void testCheckTypeNameExplicitDvURI() throws Exception { + CheckTypeName("adl-test-ELEMENT.type_uri.v1.adl"); + assertEquals("unexpected validation error(s): " + errors, 0, + errors.size()); + } + + public void testCheckTypeNameExplicitDvEHRURI() throws Exception { + CheckTypeName("adl-test-ELEMENT.type_ehr_uri.v1.adl"); + assertEquals("unexpected validation error(s): " + errors, 0, + errors.size()); + } + + public void testCheckTypeNameExplicitDvMultimedia() throws Exception { + CheckTypeName("adl-test-ELEMENT.type_multimedia.v1.adl"); + assertEquals("unexpected validation error(s): " + errors, 0, + errors.size()); + } + + public void testCheckTypeNameExplicitDvInterval() throws Exception { + CheckTypeName("adl-test-ELEMENT.type_interval.v1.adl"); + assertEquals("unexpected validation error(s): " + errors, 0, + errors.size()); + } + + public void testCheckTypeNameDvIntervalWithGenerics() throws Exception { + CheckTypeName("adl-test-ELEMENT.type_interval.v2.adl"); + assertEquals("unexpected validation error(s): " + errors, 0, + errors.size()); + } + + public void testCheckTypeNameDvIntervalWithUnassignableGenericType() throws Exception { + CheckTypeName("adl-test-ELEMENT.type_interval.v4.adl"); + assertFirstErrorType(ErrorType.VCORMT); + } + + public void testCheckTypeNameDvIntervalWithUnassignableGenericTypeSub() throws Exception { + CheckTypeName("adl-test-ELEMENT.type_interval.v3.adl"); + assertFirstErrorType(ErrorType.VCORMT); + } + + + public void testCheckTypeNameDvIntervalWithUnknownGenericType() throws Exception { + CheckTypeName("adl-test-ELEMENT.type_interval.v5.adl"); + assertFirstErrorType(ErrorType.VCORM); + } + + public void testCheckTypeNameDvIntervalWithUnknownGenericTypeSub() throws Exception { + CheckTypeName("adl-test-ELEMENT.type_interval.v6.adl"); + assertFirstErrorType(ErrorType.VCORM); + } + + public void testCheckTypeNameExplicitDvProportion() throws Exception { + CheckTypeName("adl-test-ELEMENT.type_proportion.v1.adl"); + assertEquals("unexpected validation error(s): " + errors, 0, + errors.size()); + } + + public void testCheckTypeNameWithInlinedDvDate() throws Exception { + CheckTypeName("adl-test-ELEMENT.type_date.v2.adl"); + assertEquals("unexpected validation error(s): " + errors, 0, + errors.size()); + } + + public void testCheckTypeNameWithISMTransition() throws Exception { + CheckTypeName("openEHR-EHR-ACTION.follow_up.v1.adl"); + assertEquals("unexpected validation error(s): " + errors, 0, + errors.size()); + } + + private void CheckTypeName(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkObjectConstraints(archetype, errors); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/UniqueSiblingAttributesCheckTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/UniqueSiblingAttributesCheckTest.java new file mode 100644 index 00000000..d55f58d5 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/UniqueSiblingAttributesCheckTest.java @@ -0,0 +1,25 @@ +package org.openehr.am.validation; + +public class UniqueSiblingAttributesCheckTest extends ArchetypeValidationTestBase { + + public void testCheckUniqueSiblingAttribute() throws Exception { + checkSiblings("adl-test-ENTRY.sibling_nodes.v1"); + assertEquals("encountered unexpected validation error", 0, + errors.size()); + } + + public void testCheckNonUniqueSiblingAttributes() throws Exception { + checkSiblings("adl-test-ENTRY.sibling_nodes.v2"); + assertEquals("wrong number of validation error in sibling node checking", 1, + errors.size()); + for(ValidationError error : errors) { + assertEquals("validation error type wrong", ErrorType.VCATU, + error.getType()); + } + } + + private void checkSiblings(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkObjectConstraints(archetype, errors); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/ValidateOpenEHRTerminologyCodesTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/ValidateOpenEHRTerminologyCodesTest.java new file mode 100644 index 00000000..d810dbec --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/ValidateOpenEHRTerminologyCodesTest.java @@ -0,0 +1,15 @@ +package org.openehr.am.validation; + +public class ValidateOpenEHRTerminologyCodesTest + extends ArchetypeValidationTestBase { + + public void testCheckTypeNameDvIntervalWithWrongGenericType() throws Exception { + CheckCodes("adl-test-ELEMENT.type_multimedia.v2.adl"); + // assertFirstErrorType(ErrorType.VOTC); + } + + private void CheckCodes(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkObjectConstraints(archetype, errors); + } +} diff --git a/archetype-validator/src/test/java/org/openehr/am/validation/ValidatorUtilityTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/ValidatorUtilityTest.java new file mode 100644 index 00000000..c129c3ae --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/ValidatorUtilityTest.java @@ -0,0 +1,52 @@ +package org.openehr.am.validation; + +import java.util.Set; + +public class ValidatorUtilityTest extends ArchetypeValidationTestBase { + + public void testFetchAllATCodes() throws Exception { + archetype = loadArchetype("openEHR-EHR-EVALUATION.problem-diagnosis.v1.adl"); + + Set codes = validator.fetchAllATCodes(archetype); + assertNotNull("fetched AT codes null", codes); + int expectedNumOfATCodes = archetype.getOntology() + .getTermDefinitionsList().get(1).getDefinitions().size(); + + assertTrue("main concept at0000.1 missing", codes.contains("at0000.1")); + + assertTrue("archetype node at0001 missing", codes.contains("at0001")); + + assertTrue("at0.33 in CCodedText missing", codes.contains("at0.33")); + + assertTrue("at0006 in CDvOrdinal missing", codes.contains("at0006")); + + // two codes are not used in the actual archetype + assertTrue("total number of fetched AT codes wrong", + expectedNumOfATCodes >= codes.size()); + } + + public void testFetchAllACCodes() throws Exception { + archetype = loadArchetype("openEHR-EHR-EVALUATION.problem-diagnosis.v1.adl"); + + Set codes = validator.fetchAllACCodes(archetype); + assertNotNull("fetched AT codes null", codes); + + assertEquals("total number of fetched AC codes wrong", 2, codes.size()); + + assertTrue("ac0000 missing", codes.contains("ac0000")); + + assertTrue("ac0.1 missing", codes.contains("ac0.1")); + } + + public void testCheckErrorDescriptionExists() throws Exception { + checkTerm("adl-test-ENTRY.term_definition.v3"); + for(ValidationError error : errors) { + assertNotNull("Error description loaded", error.getDescription()); + } + } + + private void checkTerm(String name) throws Exception { + archetype = loadArchetype(name); + validator.checkArchetypeTermValidity(archetype, errors); + } +} diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.cardinality-specialised.v1 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.cardinality-specialised.v1 new file mode 100644 index 00000000..b39ec09e --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.cardinality-specialised.v1 @@ -0,0 +1,63 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.cardinality-specialised.v1 + +concept + [at0000.1] -- cardinality spec +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000.1] matches { -- cardinality + data matches { + ITEM_TREE[at0001.1] matches { -- Tree + items cardinality matches {2..10; unordered} matches { + ELEMENT[at0002] occurrences matches {0..2} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"cardinality"> + description = <"unknown"> + > + ["at0000.1"] = < + text = <"cardinality-spec"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0001.1"] = < + text = <"Tree spec"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.cardinality-specialised.v2 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.cardinality-specialised.v2 new file mode 100644 index 00000000..c9dade0f --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.cardinality-specialised.v2 @@ -0,0 +1,63 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.cardinality-specialised.v2 + +concept + [at0000.1] -- cardinality spec +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000.1] matches { -- cardinality + data matches { + ITEM_TREE[at0001.1] matches { -- Tree + items cardinality matches {1..5; unordered} matches { + ELEMENT[at0002] occurrences matches {0..2} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"cardinality"> + description = <"unknown"> + > + ["at0000.1"] = < + text = <"cardinality-spec"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0001.1"] = < + text = <"Tree spec"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.cardinality.v1 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.cardinality.v1 new file mode 100644 index 00000000..718436db --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.cardinality.v1 @@ -0,0 +1,55 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.cardinality.v1 + +concept + [at0000] -- cardinality +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000] matches { -- cardinality + data matches { + ITEM_TREE[at0001] matches { -- Tree + items cardinality matches {2..*; unordered} matches { + ELEMENT[at0002] occurrences matches {0..2} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"cardinality"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.existence-specialised.v1 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.existence-specialised.v1 new file mode 100644 index 00000000..cad849e9 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.existence-specialised.v1 @@ -0,0 +1,67 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.existence-specialised.v1 + +concept + [at0000.1] -- occurrences spec +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000.1] matches { -- occurrences + data matches { + ITEM_TREE[at0001.1] matches { -- Tree + items cardinality matches {2..*; unordered} matches { + ELEMENT[at0002.1] occurrences matches {0..6} matches { -- New element + value existence matches {0..0} matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"occurrences"> + description = <"unknown"> + > + ["at0000.1"] = < + text = <"occurrences-spec"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0001.1"] = < + text = <"Tree spec"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"New element"> + description = <"*"> + > + ["at0002.1"] = < + text = <"New element spec"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.existence.v1 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.existence.v1 new file mode 100644 index 00000000..2c963f47 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.existence.v1 @@ -0,0 +1,55 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.existence.v1 + +concept + [at0000] -- occurrences +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000] matches { -- occurrences + data matches { + ITEM_TREE[at0001] matches { -- Tree + items cardinality matches {2..*; unordered} matches { + ELEMENT[at0002] occurrences matches {0..6} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"occurrences"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.multiplicity-specialised.v1 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.multiplicity-specialised.v1 new file mode 100644 index 00000000..a90754fc --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.multiplicity-specialised.v1 @@ -0,0 +1,63 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.multiplicity-specialised.v1 + +concept + [at0000.1] -- term_existence spec +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000.1] matches { -- term_existence spec + data matches { + ITEM_TREE[at0001.1] matches { -- Tree + items cardinality matches {1..2; unordered} matches { -- VSAM error which is a special case of the VSANCC error + ELEMENT[at0002] occurrences matches {0..1} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"cardinality"> + description = <"unknown"> + > + ["at0000.1"] = < + text = <"cardinality-spec"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0001.1"] = < + text = <"Tree-spec"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.multiplicity.v1 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.multiplicity.v1 new file mode 100644 index 00000000..678d4ca5 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.multiplicity.v1 @@ -0,0 +1,55 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.multiplicity.v1 + +concept + [at0000] -- terms +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000] matches { -- terms + data matches { + ITEM_TREE[at0001] matches { -- Tree + items matches { + ELEMENT[at0002] occurrences matches {0..1} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"terms"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_id_conformance-specialised-again.v1 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_id_conformance-specialised-again.v1 new file mode 100644 index 00000000..b219bfe7 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_id_conformance-specialised-again.v1 @@ -0,0 +1,67 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.node_id_conformance-specialised-again.v1 + +concept + [at0000.1.1] -- term_existence spec +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000.1.1] matches { -- term_existence spec + data matches { + ITEM_TREE[at0001.1] matches { -- Tree Wrong level of specialisation -> shoud be at0001.0.1 + items cardinality matches {1..2; unordered} matches { + ELEMENT[at0002] occurrences matches {0..1} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"cardinality"> + description = <"unknown"> + > + ["at0000.1"] = < + text = <"cardinality-spec"> + description = <"unknown"> + > + ["at0000.1.1"] = < + text = <"spec-again"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0001.1"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_id_conformance-specialised.v1 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_id_conformance-specialised.v1 new file mode 100644 index 00000000..b87a3ead --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_id_conformance-specialised.v1 @@ -0,0 +1,59 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.node_id_conformance-specialised.v1 + +concept + [at0000.1] -- term_existence spec +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000.1] matches { -- term_existence spec + data matches { + ITEM_TREE[at0001] matches { -- Tree Wrong level of specialisation -> + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0002] occurrences matches {0..1} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"cardinality"> + description = <"unknown"> + > + ["at0000.1"] = < + text = <"cardinality-spec"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_specialised_as_required-specialised.v1 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_specialised_as_required-specialised.v1 new file mode 100644 index 00000000..4ef3a489 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_specialised_as_required-specialised.v1 @@ -0,0 +1,59 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.node_specialised_as_required-specialised.v1 + +concept + [at0000.1] -- term_existence spec +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000.1] matches { -- term_existence spec + data matches { + ITEM_TREE[at0001] matches { -- Tree + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0002] occurrences matches {0..1} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"cardinality"> + description = <"unknown"> + > + ["at0000.1"] = < + text = <"cardinality-spec"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_specialised_as_required.v1 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_specialised_as_required.v1 new file mode 100644 index 00000000..76faab48 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_specialised_as_required.v1 @@ -0,0 +1,55 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.node_specialised_as_required.v1 + +concept + [at0000] -- terms +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000] matches { -- terms + data matches { + ITEM_TREE[at0001] matches { -- Tree + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0002] occurrences matches {0..2} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"terms"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.occurrences-specialised.v1 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.occurrences-specialised.v1 new file mode 100644 index 00000000..942d631c --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.occurrences-specialised.v1 @@ -0,0 +1,67 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.occurrences-specialised.v1 + +concept + [at0000.1] -- occurrences spec +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000.1] matches { -- occurrences + data matches { + ITEM_TREE[at0001.1] matches { -- Tree + items cardinality matches {2..*; unordered} matches { + ELEMENT[at0002.1] occurrences matches {0..7} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"occurrences"> + description = <"unknown"> + > + ["at0000.1"] = < + text = <"occurrences-spec"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0001.1"] = < + text = <"Tree spec"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"New element"> + description = <"*"> + > + ["at0002.1"] = < + text = <"New element spec"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.occurrences.v1 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.occurrences.v1 new file mode 100644 index 00000000..d7b68c09 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.occurrences.v1 @@ -0,0 +1,55 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.occurrences.v1 + +concept + [at0000] -- occurrences +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000] matches { -- occurrences + data matches { + ITEM_TREE[at0001] matches { -- Tree + items cardinality matches {2..*; unordered} matches { + ELEMENT[at0002] occurrences matches {0..6} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"occurrences"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence-specialised.v1 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence-specialised.v1 new file mode 100644 index 00000000..63c4b3dd --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence-specialised.v1 @@ -0,0 +1,59 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.term_existence-specialised.v1 + +concept + [at0000.1] -- term_existence spec +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000.1] matches { -- term_existence spec + data matches { + ITEM_TREE[at0001] matches { -- Tree + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0002] occurrences matches {0..1} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"cardinality"> + description = <"unknown"> + > + ["at0000.1"] = < + text = <"cardinality-spec"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence-specialised.v2 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence-specialised.v2 new file mode 100644 index 00000000..63c4b3dd --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence-specialised.v2 @@ -0,0 +1,59 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.term_existence-specialised.v1 + +concept + [at0000.1] -- term_existence spec +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000.1] matches { -- term_existence spec + data matches { + ITEM_TREE[at0001] matches { -- Tree + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0002] occurrences matches {0..1} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"cardinality"> + description = <"unknown"> + > + ["at0000.1"] = < + text = <"cardinality-spec"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence.v1 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence.v1 new file mode 100644 index 00000000..306b2291 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence.v1 @@ -0,0 +1,64 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.term_existence.v1 + +concept + [at0000] -- terms +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000] matches { -- terms + data matches { + ITEM_TREE[at0001] matches { -- Tree + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0002] occurrences matches {0..1} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0.1] occurrences matches {0..1} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"terms"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"New element"> + description = <"*"> + > + ["at0.1"] = < + text = <"New element spec"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence.v2 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence.v2 new file mode 100644 index 00000000..a85fc09e --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence.v2 @@ -0,0 +1,51 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.term_existence.v1 + +concept + [at0000] -- terms +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000] matches { -- terms + data matches { + ITEM_TREE[at0001] matches { -- Tree + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0002] occurrences matches {0..1} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"terms"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype-specialised.v1 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype-specialised.v1 new file mode 100644 index 00000000..969683a3 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype-specialised.v1 @@ -0,0 +1,110 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.wrongrmtype-specialised.v1 + +concept + [at0000.1] -- occurrences spec +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000.1] matches { -- occurrences + data matches { + ITEM_TREE[at0001] matches { -- Tree + items cardinality matches {2..*; unordered} matches { + ELEMENT[at0002] occurrences matches {0..6} matches { -- New element + value matches { -- a choice datatype conformant to the parent, must not throw a VSONCT error + DV_TEXT matches {*} + DV_URI matches {*} + } + } + ELEMENT[at0.1] occurrences matches {0..1} matches { -- should not throw a wrong rm type error + value matches { + DV_CODED_TEXT matches { * } + } + } + CLUSTER[at0.2] occurrences matches {0..1} matches { -- Engagement + items cardinality matches {1..*; unordered} matches { * } + } + ELEMENT[at0003] occurrences matches {0..1} matches { -- Dosage per kg body weight + value matches { + DV_INTERVAL matches { + upper matches { + C_DV_QUANTITY < + property = <[openehr::0]> + > + } + lower matches { + C_DV_QUANTITY < + property = <[openehr::0]> + > + } + } + } + } + ELEMENT[at0004] occurrences matches {0..1} matches { -- Quantity to be dispensed + value matches { + C_DV_QUANTITY < + > + DV_COUNT matches { + magnitude matches {|>0|; 1} + } + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0.1"] = < + text = <"new node"> + description = <"unknown"> + > + ["at0.2"] = < + text = <"new cluster"> + description = <"unknown"> + > + ["at0000"] = < + text = <"occurrences"> + description = <"unknown"> + > + ["at0000.1"] = < + text = <"occurrences-spec"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"New element"> + description = <"*"> + > + ["at0003"] = < + text = <"New element"> + description = <"*"> + > + ["at0004"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype-specialised.v2 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype-specialised.v2 new file mode 100644 index 00000000..4d5917fb --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype-specialised.v2 @@ -0,0 +1,65 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.wrongrmtype-specialised.v1 + +concept + [at0000.1] -- occurrences spec +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000.1] matches { -- occurrences + data matches { + ITEM_TREE[at0001.1] matches { -- Tree + items cardinality matches {2..*; unordered} matches { + ITEM_TREE[at0002.1] occurrences matches {0..6} matches { -- New element + * + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"occurrences"> + description = <"unknown"> + > + ["at0000.1"] = < + text = <"occurrences-spec"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0001.1"] = < + text = <"Tree spec"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"New element"> + description = <"*"> + > + ["at0002.1"] = < + text = <"New element spec"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype-specialised.v3 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype-specialised.v3 new file mode 100644 index 00000000..2f34f8d4 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype-specialised.v3 @@ -0,0 +1,61 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.wrongrmtype-specialised.v3 + +concept + [at0000.1] -- occurrences spec +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000.1] matches { -- occurrences + data matches { + ITEM_TREE[at0001] matches { -- Tree + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0003] occurrences matches {0..1} matches { -- Dosage per kg body weight + value matches { + DV_INTERVAL matches { -- without generics part this is right, with it is wrong! + * + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"occurrences"> + description = <"unknown"> + > + ["at0000.1"] = < + text = <"occurrences-spec"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0003"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype.v1 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype.v1 new file mode 100644 index 00000000..702e4316 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype.v1 @@ -0,0 +1,92 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.wrongrmtype.v1 + +concept + [at0000] -- occurrences +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000] matches { -- occurrences + data matches { + ITEM_TREE[at0001] matches { -- Tree + items cardinality matches {2..*; unordered} matches { + ELEMENT[at0002] occurrences matches {0..6} matches { -- New element + value matches { + DV_TEXT matches {*} + DV_URI matches {*} + } + } + ELEMENT[at0003] occurrences matches {0..1} matches { -- Dosage per kg body weight + value matches { -- this should not throw an VSONCT error + DV_INTERVAL matches { + upper matches { + C_DV_QUANTITY < + property = <[openehr::0]> + > + } + lower matches { + C_DV_QUANTITY < + property = <[openehr::0]> + > + } + } + } + } + ELEMENT[at0004] occurrences matches {0..1} matches { -- Quantity to be dispensed + value matches { -- this should not throw an VSONCT error + C_DV_QUANTITY < + > + DV_COUNT matches { + magnitude matches {|>0|; 1} + } + DV_TEXT matches {*} + } + } + + } + } + + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"occurrences"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"New element"> + description = <"*"> + > + ["at0003"] = < + text = <"New element"> + description = <"*"> + > + ["at0004"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype.v2 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype.v2 new file mode 100644 index 00000000..9ddb83fe --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype.v2 @@ -0,0 +1,55 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.wrongrmtype.v1 + +concept + [at0000] -- occurrences +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000] matches { -- occurrences + data matches { + ITEM_TREE[at0001] matches { -- Tree + items cardinality matches {2..*; unordered} matches { + ELEMENT[at0002] occurrences matches {0..6} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"occurrences"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype.v3 b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype.v3 new file mode 100644 index 00000000..2dde73cf --- /dev/null +++ b/archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype.v3 @@ -0,0 +1,58 @@ +archetype (adl_version=1.4) + adl-specialised-EVALUATION.wrongrmtype.v3 + +concept + [at0000] -- occurrences +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Draft"> + +definition + EVALUATION[at0000] matches { -- occurrences + data matches { + ITEM_TREE[at0001] matches { -- Tree + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0003] occurrences matches {0..1} matches { -- Dosage per kg body weight + value matches { + DV_INTERVAL matches { + * + } + } + } + } + } + + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"occurrences"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0003"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.assumed_value_boolean.v1.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.assumed_value_boolean.v1.adl new file mode 100644 index 00000000..c6df6e96 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.assumed_value_boolean.v1.adl @@ -0,0 +1,29 @@ +archetype + adl-test-ELEMENT.assumed_value_boolean.v1 + +concept + [at0000] -- wrong assumed value for Boolean test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] occurrences matches {0..1} matches { -- most minimal + value matches { + DV_BOOLEAN matches { + value matches {True; False} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.assumed_value_count.v1.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.assumed_value_count.v1.adl new file mode 100644 index 00000000..c9695efc --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.assumed_value_count.v1.adl @@ -0,0 +1,29 @@ +archetype + adl-test-ELEMENT.assumed_value_count.v1 + +concept + [at0000] -- wrong assumed value for count test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0011] occurrences matches {0..1} matches { -- most minimal + value matches { + DV_COUNT matches { + magnitude matches {|0..5|; -4} + } + } +} + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.assumed_value_quantity.v1.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.assumed_value_quantity.v1.adl new file mode 100644 index 00000000..303ab4d8 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.assumed_value_quantity.v1.adl @@ -0,0 +1,40 @@ +archetype + adl-test-ELEMENT.assumed_value_quantity.v1 + +concept + [at0000] -- wrong assumed value for DV_Quantity test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] occurrences matches {0..1} matches { -- most minimal + value matches { + C_DV_QUANTITY < + property = <[openehr::381]> + list = < + ["1"] = < + units = <"eq"> + magnitude = <|0.0..2.0|> + > + > + assumed_value = < + magnitude = <3.0> + units = <"eq"> + precision = <-1> + > + > + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-archetypeid.v1.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-archetypeid.v1.adl new file mode 100644 index 00000000..9160c234 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-archetypeid.v1.adl @@ -0,0 +1,32 @@ +archetype + adl-test-ELEMENT.specialization-archetypeid.v1 + +specialize + adl-test-ELEMENT.specialization.v1 + +concept + [at0000.1] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000.1] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {*} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000.1"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-archetypeid.v2.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-archetypeid.v2.adl new file mode 100644 index 00000000..e0d67a60 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-archetypeid.v2.adl @@ -0,0 +1,32 @@ +archetype + adl-test-ELEMENT.specialization-archetypeid.v1 + +specialize + adl-test-ELEMENT.specializationwrong.v1 + +concept + [at0000.1] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000.1] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {*} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000.1"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-archetypeid.v3.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-archetypeid.v3.adl new file mode 100644 index 00000000..08e94bb2 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-archetypeid.v3.adl @@ -0,0 +1,32 @@ +archetype + adl-test-ELEMENT.specialization-archetypeid.v3 + +specialize + adl-test-ELEMENT.specialization.v3draft + +concept + [at0000.1] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000.1] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {*} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000.1"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v1.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v1.adl new file mode 100644 index 00000000..a8188b37 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v1.adl @@ -0,0 +1,32 @@ +archetype + adl-test-ELEMENT.specialization-depth.v1 + +specialize + adl-test-ELEMENT.specialization.v1 + +concept + [at0000.1] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000.1] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {*} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000.1"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v2.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v2.adl new file mode 100644 index 00000000..1f7e6bb2 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v2.adl @@ -0,0 +1,32 @@ +archetype + adl-test-ELEMENT.specialization-depth.v2 + +specialize + adl-test-ELEMENT.specialization.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {*} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000.1"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v3.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v3.adl new file mode 100644 index 00000000..c65ed65f --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v3.adl @@ -0,0 +1,32 @@ +archetype + adl-test-ELEMENT.specialization-depth.v3 + +specialize + adl-test-ELEMENT.specialization.v1 + +concept + [at0000.1.1] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000.1.1] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {*} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000.1.1"] = < + text = <"most minimal - the specialisation hierarchy of this code is higher than the specialisation hierarchy of the archetype.">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v4.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v4.adl new file mode 100644 index 00000000..3865ac0e --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v4.adl @@ -0,0 +1,36 @@ +archetype + adl-test-ELEMENT.specialization-depth.v4 + +specialize + adl-test-ELEMENT.specialization.v1 + +concept + [at0000.1] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000.1] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0002.2.2]} -- t1 + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000.1"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0002.2.2"] = < + text = <"Specialisation hierarchy to high for this archetype"> + description = <"*"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v5.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v5.adl new file mode 100644 index 00000000..b0cc956e --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v5.adl @@ -0,0 +1,42 @@ +archetype + adl-test-ELEMENT.specialization-depth.v4 + +specialize + adl-test-ELEMENT.specialization.v1 + +concept + [at0000.1] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000.1] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0001.1.1]} -- New constraint + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000.1"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0001.1.1"] = < + text = <"Specialisation hierarchy to high for this archetype"> + description = <"*"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization.v1.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization.v1.adl new file mode 100644 index 00000000..309944aa --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.specialization.v1.adl @@ -0,0 +1,25 @@ +archetype + adl-test-ELEMENT.specialization.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { * } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.type_boolean.v1.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_boolean.v1.adl new file mode 100644 index 00000000..4e6c4003 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_boolean.v1.adl @@ -0,0 +1,29 @@ +archetype + adl-test-ELEMENT.type_boolean.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.type_count.v1.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_count.v1.adl new file mode 100644 index 00000000..193c979e --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_count.v1.adl @@ -0,0 +1,29 @@ +archetype + adl-test-ELEMENT.type_count.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_COUNT matches { + magnitude matches {|>=0|} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.type_date.v1.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_date.v1.adl new file mode 100644 index 00000000..ab7722a8 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_date.v1.adl @@ -0,0 +1,29 @@ +archetype + adl-test-ELEMENT.type_datetime.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_DATE_TIME matches { + value matches {yyyy-??-??T??:??:??} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.type_date.v2.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_date.v2.adl new file mode 100644 index 00000000..4ce44f7f --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_date.v2.adl @@ -0,0 +1,25 @@ +archetype + adl-test-ELEMENT.type_date.v2 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches {yyyy-??-??} + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.type_datetime.v1.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_datetime.v1.adl new file mode 100644 index 00000000..ad6bec9a --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_datetime.v1.adl @@ -0,0 +1,29 @@ +archetype + adl-test-ELEMENT.type_date.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_DATE matches { + value matches {yyyy-??-??} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.type_duration.v1.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_duration.v1.adl new file mode 100644 index 00000000..bfe41486 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_duration.v1.adl @@ -0,0 +1,29 @@ +archetype + adl-test-ELEMENT.type_duration.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_DURATION matches { + value matches {PW} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.type_ehr_uri.v1.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_ehr_uri.v1.adl new file mode 100644 index 00000000..37c4b390 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_ehr_uri.v1.adl @@ -0,0 +1,27 @@ +archetype + adl-test-ELEMENT.type_uri.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_EHR_URI matches {*} + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v1.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v1.adl new file mode 100644 index 00000000..45e499d7 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v1.adl @@ -0,0 +1,27 @@ +archetype + adl-test-ELEMENT.type_interval.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_INTERVAL matches {*} + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v2.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v2.adl new file mode 100644 index 00000000..4da04342 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v2.adl @@ -0,0 +1,37 @@ +archetype + adl-test-ELEMENT.type_interval.v2 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_INTERVAL matches { + upper matches { + DV_COUNT matches {*} + } + lower matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + } + } + + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v3.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v3.adl new file mode 100644 index 00000000..c8af476d --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v3.adl @@ -0,0 +1,37 @@ +archetype + adl-test-ELEMENT.type_interval.v6 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_INTERVAL matches { + upper matches { + DV_QUANTITY matches {*} -- VCORMT error + } + lower matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + } + } + + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v4.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v4.adl new file mode 100644 index 00000000..7babb4ef --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v4.adl @@ -0,0 +1,30 @@ +archetype + adl-test-ELEMENT.type_interval.v4 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_INTERVAL matches { --VCORMT error + * + } + + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v5.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v5.adl new file mode 100644 index 00000000..a03c91d3 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v5.adl @@ -0,0 +1,30 @@ +archetype + adl-test-ELEMENT.type_interval.v5 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_INTERVAL matches { --VCORM error + * + } + + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v6.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v6.adl new file mode 100644 index 00000000..4c8a5e1c --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v6.adl @@ -0,0 +1,37 @@ +archetype + adl-test-ELEMENT.type_interval.v3 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_INTERVAL matches { + upper matches { + COUNT matches {*} -- VCORM error + } + lower matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + } + } + + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.type_multimedia.v1.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_multimedia.v1.adl new file mode 100644 index 00000000..4b528462 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_multimedia.v1.adl @@ -0,0 +1,36 @@ +archetype + adl-test-ELEMENT.type_multimedia.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_MULTIMEDIA matches { + media_type matches { + [iana:: + 425, + 426, + 427, + 428, + 429] + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.type_multimedia.v2.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_multimedia.v2.adl new file mode 100644 index 00000000..0f67a351 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_multimedia.v2.adl @@ -0,0 +1,36 @@ +archetype + adl-test-ELEMENT.type_multimedia.v2 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_MULTIMEDIA matches { + media_type matches { + [openEHR:: + 425, + 426, + 427, + 428, + 429] + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.type_name.v1 b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_name.v1 new file mode 100644 index 00000000..0b067a04 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_name.v1 @@ -0,0 +1,29 @@ +archetype + adl-test-ELEMENT.type_name.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {*} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.type_name.v2 b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_name.v2 new file mode 100644 index 00000000..5a48ddf5 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_name.v2 @@ -0,0 +1,29 @@ +archetype + adl-test-ELEMENT.type_name.v2 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + UNKNOWN_RM_TYPE matches { -- unkown rm type + defining_code matches {*} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.type_name.v3 b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_name.v3 new file mode 100644 index 00000000..57fdfd74 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_name.v3 @@ -0,0 +1,29 @@ +archetype + adl-test-ELEMENT.type_name.v3 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + OBSERVATION matches { -- unassignable rm type here! + defining_code matches {*} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.type_proportion.v1.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_proportion.v1.adl new file mode 100644 index 00000000..7cbebd11 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_proportion.v1.adl @@ -0,0 +1,31 @@ +archetype + adl-test-ELEMENT.type_proportion.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { + value matches { + DV_PROPORTION matches { + numerator matches {|>=1.0|} + denominator matches {|1.0..4.0|} + type matches {1, 2, 4} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ELEMENT.type_uri.v1.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_uri.v1.adl new file mode 100644 index 00000000..e25ff2f1 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ELEMENT.type_uri.v1.adl @@ -0,0 +1,27 @@ +archetype + adl-test-ELEMENT.type_uri.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_URI matches {*} + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.attribute_name.v1 b/archetype-validator/src/test/resources/adl-test-ENTRY.attribute_name.v1 new file mode 100644 index 00000000..32c1ec95 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.attribute_name.v1 @@ -0,0 +1,39 @@ +archetype + adl-test-ELEMENT.attribute_name.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.attribute_name.v2 b/archetype-validator/src/test/resources/adl-test-ENTRY.attribute_name.v2 new file mode 100644 index 00000000..59a876a5 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.attribute_name.v2 @@ -0,0 +1,39 @@ +archetype + adl-test-ELEMENT.attribute_name.v2 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + wrong_value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.attribute_name.v3 b/archetype-validator/src/test/resources/adl-test-ENTRY.attribute_name.v3 new file mode 100644 index 00000000..60c88d96 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.attribute_name.v3 @@ -0,0 +1,36 @@ +archetype + adl-test-ELEMENT.attribute_name.v3 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + POINT_EVENT[at0000] matches { + offset matches { * + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.code_constraint.v1 b/archetype-validator/src/test/resources/adl-test-ENTRY.code_constraint.v1 new file mode 100644 index 00000000..dd84400a --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.code_constraint.v1 @@ -0,0 +1,35 @@ +archetype + adl-test-ENTRY.code_constraint.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that describes a body site + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0002"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.code_constraint.v2 b/archetype-validator/src/test/resources/adl-test-ENTRY.code_constraint.v2 new file mode 100644 index 00000000..d380b4eb --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.code_constraint.v2 @@ -0,0 +1,25 @@ +archetype + adl-test-ENTRY.code_constraint.v2 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that describes a body site + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0002"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.code_constraint.v3 b/archetype-validator/src/test/resources/adl-test-ENTRY.code_constraint.v3 new file mode 100644 index 00000000..359bbcb7 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.code_constraint.v3 @@ -0,0 +1,56 @@ +archetype + adl-test-ENTRY.code_constraint.v3 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + translations = < + ["de"] = < + language = <[ISO_639-1::de]> + author = < + ["organisation"] = <"Central Queensland University, University of Heidelberg"> + ["name"] = <"Sebastian Garde, Jasmin Buck"> + > + > + > + +definition + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that describes a body site + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + ["de"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + text = <"New constraint"> + description = <"*"> + > + > + > + ["de"] = < + items = < + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.definition_code.v1 b/archetype-validator/src/test/resources/adl-test-ENTRY.definition_code.v1 new file mode 100644 index 00000000..ebbe2ed5 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.definition_code.v1 @@ -0,0 +1,39 @@ +archetype + adl-test-ELEMENT.definition_code.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.definition_code.v2 b/archetype-validator/src/test/resources/adl-test-ENTRY.definition_code.v2 new file mode 100644 index 00000000..c1645b60 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.definition_code.v2 @@ -0,0 +1,39 @@ +archetype + adl-test-ELEMENT.definition_code.v2 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0001] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.definition_typename.v1 b/archetype-validator/src/test/resources/adl-test-ENTRY.definition_typename.v1 new file mode 100644 index 00000000..cefc50bd --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.definition_typename.v1 @@ -0,0 +1,23 @@ +archetype + adl-test-ENTRY.definition_typename.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches {*} + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.definition_typename.v2 b/archetype-validator/src/test/resources/adl-test-ENTRY.definition_typename.v2 new file mode 100644 index 00000000..78231b8a --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.definition_typename.v2 @@ -0,0 +1,23 @@ +archetype + adl-test-ELEMENT.definition_typename.v2 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches {*} + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.definition_typename.v3 b/archetype-validator/src/test/resources/adl-test-ENTRY.definition_typename.v3 new file mode 100644 index 00000000..d50c6794 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.definition_typename.v3 @@ -0,0 +1,23 @@ +archetype + adl-test-PARTY_PROXY.definition_typename.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + PARTY_PROXY[at0000] matches {*} + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v1.adl b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v1.adl new file mode 100644 index 00000000..64791ea5 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v1.adl @@ -0,0 +1,39 @@ +archetype + adl-test-ENTRY.ontology-specialisation.v1 + +concept + [at0000] -- + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v2.adl b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v2.adl new file mode 100644 index 00000000..c7068a12 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v2.adl @@ -0,0 +1,42 @@ +archetype + adl-test-ENTRY.ontology-specialisation.v2 + +specialize + adl-test-ENTRY.ontology.v1 + +concept + [at0000.1] -- + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000.1] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000.1]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000.1"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v3.adl b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v3.adl new file mode 100644 index 00000000..d822a390 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v3.adl @@ -0,0 +1,42 @@ +archetype + adl-test-ENTRY.ontology-specialisation.v3 + +specialize + adl-test-ENTRY.ontology.v1 + +concept + [at0000.1] -- + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000.1] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000.1]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000.1.1"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000.1"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v4.adl b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v4.adl new file mode 100644 index 00000000..367f12c5 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v4.adl @@ -0,0 +1,42 @@ +archetype + adl-test-ENTRY.ontology-specialisation.v4 + +specialize + adl-test-ENTRY.ontology.v1 + +concept + [at0000.1] -- + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000.1] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000.1]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000.1"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000.1.2"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v5.adl b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v5.adl new file mode 100644 index 00000000..49807a71 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v5.adl @@ -0,0 +1,42 @@ +archetype + adl-test-ENTRY.ontology-specialisation-third.v5 + +specialize + adl-test-ENTRY.ontology-specialisation.v1 + +concept + [at0000.1] -- + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000.1] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000.1]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000.1"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000.1.2"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-unusedcodes.v1.adl b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-unusedcodes.v1.adl new file mode 100644 index 00000000..1bcf8d96 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-unusedcodes.v1.adl @@ -0,0 +1,43 @@ +archetype + adl-test-ENTRY.ontology-unusedcodes.v2 + +concept + [at0000.1] -- + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000.1] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0000.1"] = < + text = <"specialised most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-unusedcodes.v2.adl b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-unusedcodes.v2.adl new file mode 100644 index 00000000..8bea6cdd --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology-unusedcodes.v2.adl @@ -0,0 +1,51 @@ +archetype + adl-test-ENTRY.ontology-unusedcodes.v2 + +concept + [at0000.1] -- + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000.1] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0000.1"] = < + text = <"specialised most minimal">; + description = <"most minimal"> + > + ["at0000.2"] = < + text = <"a code that isn't used">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + ["ac0.1"] = < + description = <"A constraint that isn't used"> + text = <"Any term that related to something"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v1 b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v1 new file mode 100644 index 00000000..b8b2d516 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v1 @@ -0,0 +1,25 @@ +archetype + adl-test-ENTRY.ontology_translation.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v2 b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v2 new file mode 100644 index 00000000..47884a2c --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v2 @@ -0,0 +1,48 @@ +archetype + adl-test-ENTRY.ontology_translation.v2 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + translations = < + ["de"] = < + language = <[ISO_639-1::de]> + author = < + ["name"] = <"Jasmin Buck, Sebastian Garde"> + ["organisation"] = <"University of Heidelberg, Central Queensland University"> + > + > + > + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v3 b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v3 new file mode 100644 index 00000000..f47f0fbd --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v3 @@ -0,0 +1,56 @@ +archetype + adl-test-ENTRY.ontology_translation.v3 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + translations = < + ["de"] = < + language = <[ISO_639-1::de]> + author = < + ["name"] = <"Jasmin Buck, Sebastian Garde"> + ["organisation"] = <"University of Heidelberg, Central Queensland University"> + > + > + > + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + ["de"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v4 b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v4 new file mode 100644 index 00000000..247ada7b --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v4 @@ -0,0 +1,56 @@ +archetype + adl-test-ENTRY.ontology_translation.v4 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + translations = < + ["de"] = < + language = <[ISO_639-1::de]> + author = < + ["name"] = <"Jasmin Buck, Sebastian Garde"> + ["organisation"] = <"University of Heidelberg, Central Queensland University"> + > + > + > + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + ["de"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v5 b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v5 new file mode 100644 index 00000000..1fe62a4e --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v5 @@ -0,0 +1,64 @@ +archetype + adl-test-ENTRY.ontology_translation.v5 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + translations = < + ["de"] = < + language = <[ISO_639-1::de]> + author = < + ["name"] = <"Jasmin Buck, Sebastian Garde"> + ["organisation"] = <"University of Heidelberg, Central Queensland University"> + > + > + > + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + ["de"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + ["de"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v6 b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v6 new file mode 100644 index 00000000..6263713a --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v6 @@ -0,0 +1,71 @@ +archetype + adl-test-ENTRY.ontology_translation.v6 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + translations = < + ["de"] = < + language = <[ISO_639-1::de]> + author = < + ["name"] = <"Jasmin Buck, Sebastian Garde"> + ["organisation"] = <"University of Heidelberg, Central Queensland University"> + > + > + ["zh"] = < + language = <[ISO_639-1::zh]> + author = < + ["name"] = <"Rong Chen"> + ["organisation"] = <"Cambio Healthcare Systems"> + > + > + > + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + ["de"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + ["zh"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v7 b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v7 new file mode 100644 index 00000000..23feaf7e --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v7 @@ -0,0 +1,46 @@ +archetype + adl-test-ENTRY.ontology_translation.v7 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + translations = < + ["de"] = < + language = <[ISO_639-1::de]> + author = < + ["name"] = <"Jasmin Buck, Sebastian Garde"> + ["organisation"] = <"University of Heidelberg, Central Queensland University"> + > + > + > + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {*} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + ["de"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v8 b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v8 new file mode 100644 index 00000000..990e32bd --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v8 @@ -0,0 +1,58 @@ +archetype + adl-test-ENTRY.ontology_translation.v7 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + translations = < + ["de"] = < + language = <[ISO_639-1::de]> + author = < + ["name"] = <"Jasmin Buck, Sebastian Garde"> + ["organisation"] = <"University of Heidelberg, Central Queensland University"> + > + > + > +description + original_author = < + ["name"] = <"Tester test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::de]> + purpose = <"Test"> + use = <"To test a missing German details equivalent."> + > + + > + lifecycle_state = <"draft"> +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {*} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + ["de"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.sibling_nodes.v1 b/archetype-validator/src/test/resources/adl-test-ENTRY.sibling_nodes.v1 new file mode 100644 index 00000000..19ecf6b8 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.sibling_nodes.v1 @@ -0,0 +1,38 @@ +archetype + adl-test-ENTRY.sibling_nodes.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Weber Test + value matches { + 0|[local::at0001], -- Normal + 1|[local::at00002]; -- Not normal + 0 -- assumed value + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0001"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0002"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.sibling_nodes.v2 b/archetype-validator/src/test/resources/adl-test-ENTRY.sibling_nodes.v2 new file mode 100644 index 00000000..059cc9b0 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.sibling_nodes.v2 @@ -0,0 +1,39 @@ +archetype + adl-test-ENTRY.sibling_nodes.v2 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Weber Test + value matches {*} + value matches { + 0|[local::at0001], -- Normal + 1|[local::at00002]; -- Not normal + 0 -- assumed value + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0001"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0002"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_identifier.v1 b/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_identifier.v1 new file mode 100644 index 00000000..4717fcaf --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_identifier.v1 @@ -0,0 +1,54 @@ +archetype + adl-test-ENTRY.single_attribute_child_identifier.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_CODED_TEXT[at0001] matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' diagnosis + } + DV_CODED_TEXT[at0002] matches { + defining_code matches {[ac0001]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0001"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0002"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + ["ac0001"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_identifier.v2 b/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_identifier.v2 new file mode 100644 index 00000000..efc3d910 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_identifier.v2 @@ -0,0 +1,54 @@ +archetype + adl-test-ENTRY.single_attribute_child_identifier.v2 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_CODED_TEXT[at0001] matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' diagnosis + } + DV_CODED_TEXT[at0001] matches { + defining_code matches {[ac0001]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0001"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0002"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + ["ac0001"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_occurrences.v1 b/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_occurrences.v1 new file mode 100644 index 00000000..dd3246c3 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_occurrences.v1 @@ -0,0 +1,39 @@ +archetype + adl-test-ENTRY.single_attribute_child_uniqueness.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_occurrences.v2 b/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_occurrences.v2 new file mode 100644 index 00000000..31ed9ebc --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_occurrences.v2 @@ -0,0 +1,39 @@ +archetype + adl-test-ENTRY.single_attribute_child_occurrences.v2 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_CODED_TEXT occurrences matches {0..1} matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_occurrences.v3 b/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_occurrences.v3 new file mode 100644 index 00000000..c4cdeac2 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_occurrences.v3 @@ -0,0 +1,39 @@ +archetype + adl-test-ENTRY.single_attribute_child_occurrences.v3 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_CODED_TEXT occurrences matches {0..2} matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_uniqueness.v1 b/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_uniqueness.v1 new file mode 100644 index 00000000..bfdec26c --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_uniqueness.v1 @@ -0,0 +1,54 @@ +archetype + adl-test-ENTRY.single_attribute_child_occurrences.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_CODED_TEXT[at0001] matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' diagnosis + } + DV_CODED_TEXT[at0002] matches { + defining_code matches {[ac0001]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0001"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0002"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + ["ac0001"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_uniqueness.v2 b/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_uniqueness.v2 new file mode 100644 index 00000000..e5f70d80 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_uniqueness.v2 @@ -0,0 +1,46 @@ +archetype + adl-test-ENTRY.single_attribute_child_uniqueness.v2 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' diagnosis + } + DV_CODED_TEXT matches { + defining_code matches {[ac0001]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + ["ac0001"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_uniqueness.v3 b/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_uniqueness.v3 new file mode 100644 index 00000000..1aad9602 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_uniqueness.v3 @@ -0,0 +1,39 @@ +archetype + adl-test-ENTRY.single_attribute_child_uniqueness.v3 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ELEMENT[at0000] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' diagnosis + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.term_bindings.v1 b/archetype-validator/src/test/resources/adl-test-ENTRY.term_bindings.v1 new file mode 100644 index 00000000..e47b05e8 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.term_bindings.v1 @@ -0,0 +1,73 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.term_bindings.v1 + +concept + [at0000] +language + original_language = <[ISO_639-1::en]> + +definition + OBSERVATION[at0000] matches { -- Apgar score + data matches { + HISTORY[at0002] matches { -- history + events cardinality matches {1..*; unordered} matches { + POINT_EVENT[at0003] occurrences matches {0..1} matches { -- 1 minute + data matches { + ITEM_LIST[at0001] matches { -- structure + items cardinality matches {1..6; ordered} matches { + ELEMENT[at0005] occurrences matches {0..1} matches { -- Heart rate + value matches { + 0|[local::at0006], -- No heart beat + 1|[local::at0007], -- Less than 100 beats per minute + 2|[local::at0008] -- Greater than or equal to 100 beats per minute + } + } + } + } + } + } + } + } + } + } + +ontology + terminologies_available = <"LNC205", ...> + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + description = <"Clinical score derived from assessment of breathing, colour, muscle tone, heart rate and reflex response usually taken at 1, 5 and 10 minutes after birth"> + text = <"Apgar score"> + > + ["at0001"] = < + description = <"@ internal @"> + text = <"structure"> + > + ["at0002"] = < + description = <"@ internal @"> + text = <"history"> + > + ["at0003"] = < + description = <"Apgar score at one minute from birth"> + text = <"1 minute"> + > + ["at0005"] = < + description = <"Assessment of heart function in the new born"> + text = <"Heart rate"> + > + ["at0006"] = < + description = <"No heart beat is present (palpation at base of umbilical cord)"> + text = <"No heart beat"> + > + > + > + > + term_binding = < + ["LNC205"] = < + items = < + ["/data[at0002]/events[at0003]/data[at0001]/items[at0005]"] = <[LNC205::1234-1]> + ["at0005"] = <[LNC205::1234-2]> + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.term_bindings.v2 b/archetype-validator/src/test/resources/adl-test-ENTRY.term_bindings.v2 new file mode 100644 index 00000000..2b31082e --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.term_bindings.v2 @@ -0,0 +1,76 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.term_bindings.v2 + +concept + [at0000] +language + original_language = <[ISO_639-1::en]> + +definition + OBSERVATION[at0000] matches { -- Apgar score + data matches { + HISTORY[at0002] matches { -- history + events cardinality matches {1..*; unordered} matches { + POINT_EVENT[at0003] occurrences matches {0..1} matches { -- 1 minute + data matches { + ITEM_LIST[at0001] matches { -- structure + items cardinality matches {1..6; ordered} matches { + ELEMENT[at0005] occurrences matches {0..1} matches { -- Heart rate + value matches { + 0|[local::at0006], -- No heart beat + 1|[local::at0007], -- Less than 100 beats per minute + 2|[local::at0008] -- Greater than or equal to 100 beats per minute + } + } + } + } + } + } + } + } + } + } + +ontology + terminologies_available = <"LNC205", ...> + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + description = <"Clinical score derived from assessment of breathing, colour, muscle tone, heart rate and reflex response usually taken at 1, 5 and 10 minutes after birth"> + text = <"Apgar score"> + > + ["at0001"] = < + description = <"@ internal @"> + text = <"structure"> + > + ["at0002"] = < + description = <"@ internal @"> + text = <"history"> + > + ["at0003"] = < + description = <"Apgar score at one minute from birth"> + text = <"1 minute"> + > + ["at0005"] = < + description = <"Assessment of heart function in the new born"> + text = <"Heart rate"> + > + ["at0006"] = < + description = <"No heart beat is present (palpation at base of umbilical cord)"> + text = <"No heart beat"> + > + > + > + > + term_binding = < + ["LNC205"] = < + items = < + ["/data[at0002]/events[at0003]/data[at0001]/items[at0005]"] = <[LNC205::1234-1]> + ["/data[at0002]/events[at0006]/data[at0001]/items[at0005]"] = <[LNC205::1234-2]> + ["/data[at0002]/events[at0003]/data/items[at0005]"] = <[LNC205::1234-3]> + ["/data[at0099]/events[at0028]/data[at0006]/items[at0025]"] = <[LNC205::1234-4]> + ["at0026"] = <[LNC205::1234-5]> + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v1 b/archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v1 new file mode 100644 index 00000000..4a2b9a5a --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v1 @@ -0,0 +1,19 @@ +archetype + adl-test-ENTRY.term_definition.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ENTRY[at0001] matches {*} + +ontology + term_definitions = < + ["en"] = < + items = < + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v2 b/archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v2 new file mode 100644 index 00000000..dee43394 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v2 @@ -0,0 +1,23 @@ +archetype + adl-test-ENTRY.term_definition.v2 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ENTRY[at0000] matches {*} + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v3 b/archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v3 new file mode 100644 index 00000000..3ead0c61 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v3 @@ -0,0 +1,23 @@ +archetype + adl-test-ENTRY.missing_term_definition.v3 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ENTRY[at0000] matches {*} + +ontology + term_definitions = < + ["de"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v4 b/archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v4 new file mode 100644 index 00000000..99d25f92 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v4 @@ -0,0 +1,36 @@ +archetype + adl-test-ENTRY.missing_term_definition.v4 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + translations = < + ["de"] = < + language = <[ISO_639-1::de]> + author = < + ["organisation"] = <"Central Queensland University, University of Heidelberg"> + ["name"] = <"Sebastian Garde, Jasmin Buck"> + > + > + > + +definition + ENTRY[at0000] matches {*} + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + ["de"] = < + items = < + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v5 b/archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v5 new file mode 100644 index 00000000..10f0c975 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v5 @@ -0,0 +1,47 @@ +archetype + adl-test-ENTRY.term_definition.v5 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + lifecycle_state = <"published"> + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"test"> + use = <"test"> + misuse = <"test"> + > + ["de"] = < + language = <[ISO_639-1::de]> + purpose = <"test"> + use = <"test"> + misuse = <"test"> + > + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"test"> + use = <"test"> + misuse = <"test"> + > + > +definition + ENTRY[at0001] matches {*} + +ontology + term_definitions = < + ["en"] = < + items = < + > + > + ["de"] = < + items = < + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v6 b/archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v6 new file mode 100644 index 00000000..0fd51e2d --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v6 @@ -0,0 +1,45 @@ +archetype + adl-test-ENTRY.term_definition.v5 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + lifecycle_state = <"published"> + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"test"> + use = <"test"> + misuse = <"test"> + > + ["de"] = < + language = <[ISO_639-1::de]> + purpose = <"test"> + use = <"test"> + misuse = <"test"> + > + > +definition + ENTRY[at0001] matches {*} + +ontology + term_definitions = < + ["en"] = < + items = < + > + > + ["de"] = < + items = < + > + > + ["en"] = < + items = < + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ITEM_TREE.attribute_cardinality.v1 b/archetype-validator/src/test/resources/adl-test-ITEM_TREE.attribute_cardinality.v1 new file mode 100644 index 00000000..8ec3449a --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ITEM_TREE.attribute_cardinality.v1 @@ -0,0 +1,36 @@ +archetype + adl-test-ITEM_TREE.attribute_cardinality.v1 + +concept + [at0000] -- cardinality test + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] matches { -- most minimal + items cardinality matches {0..1; ordered} matches { + allow_archetype CLUSTER[at0001] occurrences matches {0..*} matches { -- Device + include + archetype_id/value matches {/openEHR-EHR-CLUSTER\.device\.v1/} + } + } + } + + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"cardinality test">; + description = <"most minimal cardinality test"> + > + ["at0001"] = < + text = <"cluster with wrong cardinality for occurences">; + description = <"most minimal cardinality test cluster"> + > + > + > + > + \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ITEM_TREE.attribute_cardinality.v2 b/archetype-validator/src/test/resources/adl-test-ITEM_TREE.attribute_cardinality.v2 new file mode 100644 index 00000000..c394082f --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ITEM_TREE.attribute_cardinality.v2 @@ -0,0 +1,45 @@ +archetype + adl-test-ITEM_TREE.attribute_cardinality.v1 + +concept + [at0000] -- cardinality test + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] matches { -- most minimal + items cardinality matches {0..1; ordered} matches { + CLUSTER[at0001] occurrences matches {0..1} matches { -- New cluster + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0002] occurrences matches {0..*} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"cardinality test">; + description = <"most minimal cardinality test"> + > + ["at0001"] = < + text = <"cluster with cardinality that is too broad for the reference model">; + description = <"most minimal cardinality test cluster"> + > + ["at0002"] = < + text = <"an element">; + description = <"most minimal element"> + > + > + > + > + \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ITEM_TREE.attribute_cardinality.v3 b/archetype-validator/src/test/resources/adl-test-ITEM_TREE.attribute_cardinality.v3 new file mode 100644 index 00000000..238fcc38 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ITEM_TREE.attribute_cardinality.v3 @@ -0,0 +1,40 @@ +archetype + adl-test-ITEM_TREE.attribute_cardinality.v3 + +concept + [at0000] -- cardinality test + +language + original_language = <[ISO_639-1::en]> + +definition + ROLE[at0000] matches { -- Profissional de sade + identities cardinality matches {1..*; ordered} matches { + * + } + capabilities cardinality matches {0..*; ordered} matches { + CAPABILITY[at0001] occurrences matches {0..*} matches { -- Capacitao + credentials cardinality matches {1..*; ordered} matches { + * + } + } + } + } + + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"cardinality test">; + description = <"most minimal cardinality test"> + > + ["at0001"] = < + text = <"cluster with cardinality that is too broad for the reference model">; + description = <"most minimal cardinality test cluster"> + > + > + > + > + \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ITEM_TREE.multi_attribute_child_identifier.v1 b/archetype-validator/src/test/resources/adl-test-ITEM_TREE.multi_attribute_child_identifier.v1 new file mode 100644 index 00000000..24caa23d --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ITEM_TREE.multi_attribute_child_identifier.v1 @@ -0,0 +1,52 @@ +archetype + adl-test-ITEM_TREE.multi_attribute_child_identifier.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0001] matches { -- structure + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0002] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {*} + } + } + } + ELEMENT[at0003] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {*} + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0001"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0002"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0003"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ITEM_TREE.multi_attribute_child_identifier.v2 b/archetype-validator/src/test/resources/adl-test-ITEM_TREE.multi_attribute_child_identifier.v2 new file mode 100644 index 00000000..17fe9adc --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ITEM_TREE.multi_attribute_child_identifier.v2 @@ -0,0 +1,52 @@ +archetype + adl-test-ITEM_TREE.multi_attribute_child_identifier.v2 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0001] matches { -- structure + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0002] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {*} + } + } + } + ELEMENT matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {*} + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0001"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0002"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0003"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-ITEM_TREE.multi_attribute_child_identifier.v3 b/archetype-validator/src/test/resources/adl-test-ITEM_TREE.multi_attribute_child_identifier.v3 new file mode 100644 index 00000000..96ba65d7 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-ITEM_TREE.multi_attribute_child_identifier.v3 @@ -0,0 +1,52 @@ +archetype + adl-test-ITEM_TREE.multi_attribute_child_identifier.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0001] matches { -- structure + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0002] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {*} + } + } + } + ELEMENT[at0002] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {*} + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0001"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0002"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0003"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/adl-test-PARTY_PROXY.type_name.v1 b/archetype-validator/src/test/resources/adl-test-PARTY_PROXY.type_name.v1 new file mode 100644 index 00000000..af1bbce5 --- /dev/null +++ b/archetype-validator/src/test/resources/adl-test-PARTY_PROXY.type_name.v1 @@ -0,0 +1,25 @@ +archetype + adl-test-PARTY_PROXY.type_name.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + PARTY_PROXY[at0000] matches { -- most minimal + * + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/openEHR-EHR-ACTION.follow_up.v1.adl b/archetype-validator/src/test/resources/openEHR-EHR-ACTION.follow_up.v1.adl new file mode 100644 index 00000000..394c13c3 --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-ACTION.follow_up.v1.adl @@ -0,0 +1,46 @@ +archetype (adl_version=1.4) + openEHR-EHR-ACTION.follow_up_test.v1 + +concept + [at0000] -- Follow up action + +language + original_language = <[ISO_639-1::en]> + +definition + ACTION[at0000] matches { -- Follow up action + ism_transition matches { + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::524]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0001]} -- Planned + } + } + } + } + description matches { + allow_archetype ITEM_TREE occurrences matches {0..1} matches { + include + archetype_id/value matches {/openEHR-EHR-CLUSTER\.follow_up\.v1/} + exclude + archetype_id/value matches {/.*/} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + description = <"An action taken as part of a follow up"> + text = <"Follow up action"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.cardinality_occurrences.v1.adl b/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.cardinality_occurrences.v1.adl new file mode 100644 index 00000000..60710036 --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.cardinality_occurrences.v1.adl @@ -0,0 +1,69 @@ +archetype (adl_version=1.4) + openEHR-EHR-CLUSTER.cardinality_occurrences.v1 + +concept + [at0000] -- Cardinality occurrences +language + original_language = <[ISO_639-1::de]> +description + original_author = < + ["name"] = <""> + > + details = < + ["de"] = < + language = <[ISO_639-1::de]> + purpose = <"test VACMC"> + use = <""> + misuse = <""> + copyright = <""> + > + > + lifecycle_state = <"Initial"> + other_contributors = <> + other_details = < + ["MD5-CAM-1.0.1"] = <"544674A16697A8D3AF23245DF4EF0479"> + > + +definition + CLUSTER[at0000] matches { -- Cardinality occurrences + items cardinality matches {1..*; unordered} matches { + CLUSTER[at0001] occurrences matches {0..1} matches { -- Cluster + items cardinality matches {1; unordered} matches { + ELEMENT[at0003] matches { -- N1 + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0002] matches { -- N2 + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["de"] = < + items = < + ["at0000"] = < + text = <"Cardinality occurrences"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Cluster"> + description = <"Should report a VACMC error"> + > + ["at0002"] = < + text = <"N2"> + description = <"*"> + > + ["at0003"] = < + text = <"N1"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.cardinality_occurrences2.v1.adl b/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.cardinality_occurrences2.v1.adl new file mode 100644 index 00000000..fbbbfd8f --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.cardinality_occurrences2.v1.adl @@ -0,0 +1,69 @@ +archetype (adl_version=1.4) + openEHR-EHR-CLUSTER.cardinality_occurrences2.v1 + +concept + [at0000] -- Cardinality occurrences +language + original_language = <[ISO_639-1::de]> +description + original_author = < + ["name"] = <""> + > + details = < + ["de"] = < + language = <[ISO_639-1::de]> + purpose = <"test VACMC"> + use = <""> + misuse = <""> + copyright = <""> + > + > + lifecycle_state = <"Initial"> + other_contributors = <> + other_details = < + ["MD5-CAM-1.0.1"] = <"E4764136F795F770D33F308166E255D1"> + > + +definition + CLUSTER[at0000] matches { -- Cardinality occurrences + items cardinality matches {1..*; unordered} matches { + CLUSTER[at0001] occurrences matches {0..1} matches { -- Cluster + items cardinality matches {1; unordered} matches { + ELEMENT[at0003] matches { -- N1 + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0002] occurrences matches {0..1} matches { -- N2 + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["de"] = < + items = < + ["at0000"] = < + text = <"Cardinality occurrences"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Cluster"> + description = <"Should report a VACMC error"> + > + ["at0002"] = < + text = <"N2"> + description = <"*"> + > + ["at0003"] = < + text = <"N1"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.cardinality_occurrences3.v1.adl b/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.cardinality_occurrences3.v1.adl new file mode 100644 index 00000000..67f5869a --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.cardinality_occurrences3.v1.adl @@ -0,0 +1,69 @@ +archetype (adl_version=1.4) + openEHR-EHR-CLUSTER.cardinality_occurrences3.v1 + +concept + [at0000] -- Cardinality occurrences +language + original_language = <[ISO_639-1::de]> +description + original_author = < + ["name"] = <""> + > + details = < + ["de"] = < + language = <[ISO_639-1::de]> + purpose = <"test VACMC"> + use = <""> + misuse = <""> + copyright = <""> + > + > + lifecycle_state = <"Initial"> + other_contributors = <> + other_details = < + ["MD5-CAM-1.0.1"] = <"E4764136F795F770D33F308166E255D1"> + > + +definition + CLUSTER[at0000] matches { -- Cardinality occurrences + items cardinality matches {1..*; unordered} matches { + CLUSTER[at0001] occurrences matches {0..1} matches { -- Cluster + items cardinality matches {1; unordered} matches { + ELEMENT[at0003] occurrences matches {0..1} matches { -- N1 + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0002] occurrences matches {0..1} matches { -- N2 + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["de"] = < + items = < + ["at0000"] = < + text = <"Cardinality occurrences"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Cluster"> + description = <"Should NOT report a VACMC error"> + > + ["at0002"] = < + text = <"N2"> + description = <"*"> + > + ["at0003"] = < + text = <"N1"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.internal_reference.v1.adl b/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.internal_reference.v1.adl new file mode 100644 index 00000000..e5bc067a --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.internal_reference.v1.adl @@ -0,0 +1,60 @@ +archetype (adl_version=1.4) + openEHR-EHR-CLUSTER.use_node.v1 + +concept + [at0000] -- test +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"most minimal"> + use = <"most minimal"> + misuse = <"most minimal"> + > + > + lifecycle_state = <"0"> + other_contributors = <> + other_details = < + ["references"] = <""> + > + +definition + CLUSTER[at0000] matches { -- test + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0001] occurrences matches {0..1} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + CLUSTER[at0002] occurrences matches {0..1} matches { -- New cluster + items cardinality matches {1..*; unordered} matches { + use_node ELEMENT occurrences matches {0..1} /items[at0001] + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test"> + description = <"*"> + > + ["at0001"] = < + text = <"New element"> + description = <"*"> + > + ["at0002"] = < + text = <"New cluster"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.testNonUniqueInternalRef.v1.adl b/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.testNonUniqueInternalRef.v1.adl new file mode 100644 index 00000000..e5b5a499 --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.testNonUniqueInternalRef.v1.adl @@ -0,0 +1,54 @@ +archetype (adl_version=1.4) + openEHR-EHR-CLUSTER.testnonuniqueinternalref.v1 + +concept + [at0000] -- Testnonuniquearchetypeslot +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"test"> + use = <""> + misuse = <""> + copyright = <""> + > + > + lifecycle_state = <"Initial"> + other_contributors = <> + other_details = < + ["MD5-CAM-1.0.1"] = <"E1C6B42370DFDC1B7BFCFCCF1824A86A"> + > + +definition + CLUSTER[at0000] matches { -- Testnonuniquearchetypeslot + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0001] occurrences matches {0..1} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + use_node ELEMENT occurrences matches {0..1} /items[at0001] -- /items[New element] + use_node ELEMENT occurrences matches {0..1} /items[at0001] -- /items[New element] + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Testnonuniquearchetypeslot"> + description = <"unknown"> + > + ["at0001"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.testNonUniqueInternalRef.v2.adl b/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.testNonUniqueInternalRef.v2.adl new file mode 100644 index 00000000..3f85e385 --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.testNonUniqueInternalRef.v2.adl @@ -0,0 +1,63 @@ +archetype (adl_version=1.4) + openEHR-EHR-CLUSTER.testnonuniqueinternalref.v2 + +concept + [at0000] -- Testnonuniquearchetypeslot +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"test"> + use = <""> + misuse = <""> + copyright = <""> + > + > + lifecycle_state = <"Initial"> + other_contributors = <> + other_details = < + ["MD5-CAM-1.0.1"] = <"D51D9E80A7A0043C5179B1D2EC11ADC4"> + > + +definition + CLUSTER[at0000] matches { -- Testnonuniquearchetypeslot + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0001] occurrences matches {0..1} matches { -- New element + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0002] occurrences matches {0..1} matches { -- Neues Element + value matches { + DV_TEXT matches {*} + } + } + use_node ELEMENT occurrences matches {0..1} /items[at0001] -- /items[New element] + use_node ELEMENT occurrences matches {0..1} /items[at0002] -- /items[Neues Element] + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Testnonuniquearchetypeslot"> + description = <"unknown"> + > + ["at0001"] = < + text = <"New element"> + description = <"*"> + > + ["at0002"] = < + text = <"Neues Element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.test_non_ccomplexobject-spec.v1.adl b/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.test_non_ccomplexobject-spec.v1.adl new file mode 100644 index 00000000..aef3df3b --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.test_non_ccomplexobject-spec.v1.adl @@ -0,0 +1,97 @@ +archetype (adl_version=1.4) + openEHR-EHR-CLUSTER.test_non_ccomplexobject-spec.v1 +specialize + openEHR-EHR-CLUSTER.test_non_ccomplexobject.v1 + +concept + [at0000.1] -- Test non ccomplexobject! +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"test"> + use = <""> + misuse = <""> + copyright = <""> + > + > + lifecycle_state = <"DRAFT"> + other_contributors = <> + other_details = < + ["MD5-CAM-1.0.1"] = <"95C0D171FAD739872A3EC97854DC7B75"> + > + +definition + CLUSTER[at0000.1] matches { -- Test non ccomplexobject! + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0001.1] occurrences matches {0..1} matches { -- New element + value matches { + C_DV_QUANTITY < + property = <[openehr::382]> + list = < + ["1"] = < + units = <"/min"> + magnitude = <|>=0.0|> + precision = <|0|> + > + > + > + DV_INTERVAL matches { + upper matches { + C_DV_QUANTITY < + property = <[openehr::382]> + list = < + ["1"] = < + units = <"/min"> + magnitude = <|>=0.0|> + precision = <|0|> + > + > + > + } + lower matches { + C_DV_QUANTITY < + property = <[openehr::382]> + list = < + ["1"] = < + units = <"/min"> + magnitude = <|>=0.0|> + precision = <|0|> + > + > + > + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Test non ccomplexobject"> + description = <"unknown"> + > + ["at0000.1"] = < + text = <"Test non ccomplexobject!"> + description = <"unknown!"> + > + ["at0001"] = < + text = <"New element"> + description = <"*"> + > + ["at0001.1"] = < + text = <"Spec New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.test_non_ccomplexobject.v1.adl b/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.test_non_ccomplexobject.v1.adl new file mode 100644 index 00000000..c96fe08d --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.test_non_ccomplexobject.v1.adl @@ -0,0 +1,61 @@ +archetype (adl_version=1.4) + openEHR-EHR-CLUSTER.test_non_ccomplexobject.v1 + +concept + [at0000] -- Test non ccomplexobject +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"test"> + use = <""> + misuse = <""> + copyright = <""> + > + > + lifecycle_state = <"DRAFT"> + other_contributors = <> + other_details = < + ["MD5-CAM-1.0.1"] = <"BD6D3393EF6AC7781DCECCACC44A908C"> + > + +definition + CLUSTER[at0000] matches { -- Test non ccomplexobject + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0001] occurrences matches {0..1} matches { -- New element + value matches { + C_DV_QUANTITY < + property = <[openehr::382]> + list = < + ["1"] = < + units = <"/min"> + magnitude = <|>=0.0|> + precision = <|0|> + > + > + > + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Test non ccomplexobject"> + description = <"unknown"> + > + ["at0001"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.units_test.v1.adl b/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.units_test.v1.adl new file mode 100644 index 00000000..8ff561f2 --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.units_test.v1.adl @@ -0,0 +1,152 @@ +archetype (adl_version=1.4) + openEHR-EHR-CLUSTER.units_test.v1 + +concept + [at0000] -- Units test +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"test"> + use = <""> + misuse = <""> + copyright = <""> + > + > + lifecycle_state = <"Initial"> + other_contributors = <> + other_details = < + ["MD5-CAM-1.0.1"] = <"B9B352D7DC4C53B2C80C62C3291C3E53"> + > + +definition + CLUSTER[at0000] matches { -- Units test + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0001] occurrences matches {0..1} matches { -- New element + value matches { + C_DV_QUANTITY < + property = <[openehr::339]> + list = < + ["1"] = < + units = <"cm/s2"> --correct + > + ["2"] = < + units = <"m/h2"> -- correct + > + > + > + } + } + ELEMENT[at0003] occurrences matches {0..1} matches { -- New element2 + value matches { + C_DV_QUANTITY < + property = <[openehr::384]> + list = < + ["1"] = < + units = <"µmol"> -- incorrect, should be umol + > + + ["3"] = < + units = <"mol"> -- correct + > + ["4"] = < + units = <"umol/kg"> --correct + > + ["5"] = < + units = <"A"> --correct + > + ["6"] = < + units = <"C/s"> --correct, same as A(mpere) + > + ["7"] = < + units = <"osm"> --correct + > + ["77"] = < + units = <"OSM"> -- incorrect in case-sensitive UCUM variant + > + ["777"] = < + units = <"osmol"> -- incorrect, should be osm + > + ["8"] = < + units = <"IU"> --incorrect, should be [IU] or [iU] + > + ["88"] = < + units = <"mL"> --correct! + > + ["889"] = < + units = <"ml"> -- correct, both l and L are acceptable for Liter in case-sensitive UCUM + > + ["8888"] = < + units = <"mm[Hg]"> --correct! + > + ["888"] = < + units = <"[iU]"> --correct, case-sensitive + > + ["9"] = < + units = <"Gal"> --correct, eq. to cm/s2 + > + ["12"] = < + units = <"[degF]"> -- correct + > + ["121"] = < + units = <"°C"> -- incorrect + > + ["121"] = < + units = <"°"> -- incorrect + > + ["13"] = < + units = <"umol"> --correct + > + ["14"] = < + units = <"eq"> --correct + > + ["15"] = < + units = <"EQ"> -- incorrect in case-sensitive UCUM (but would be correct if we also use case-insensitive UCUM + > + ["16"] = < + units = <"[GAL_BR]"> -- incorrect in case-sensitive UCUM (but would be correct if we also use case-insensitive UCUM + > + ["17"] = < + units = <"[gal_us]"> --correct + > + ["18"] = < + units = <"[in_i]"> --correct + > + ["19"] = < units = <"erg"> > --correct + ["20"] = < units = <"R"> > -- correct for case-sensitive = Roentgen + ["21"] = < units = <"ROE"> > -- incorrect in case-sensitive UCUM (but would be correct if we also use case-insensitive UCUM + ["22"] = < units = <"RAD"> > -- correct in case-sensitive UCUM only + ["23"] = < units = <"[RAD]"> > -- incorrect in case-sensitive UCUM (but would be correct if we also use case-insensitive UCUM + + + > + > + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Units test"> + description = <"unknown"> + > + ["at0001"] = < + text = <"New element"> + description = <"*"> + > + ["at0003"] = < + text = <"New element2"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-ELEMENT.doubleontologycode.v1.adl b/archetype-validator/src/test/resources/openEHR-EHR-ELEMENT.doubleontologycode.v1.adl new file mode 100644 index 00000000..4adcd08b --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-ELEMENT.doubleontologycode.v1.adl @@ -0,0 +1,48 @@ +archetype + openEHR-EHR-ELEMENT.doubleontologycode.v1 + +concept + [at0000] -- doubleontologycode +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"Tester"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <""> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <> + other_details = < + ["references"] = <""> + > + +definition + ELEMENT[at0000] matches { -- doubleontologycode + value matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + } + } + + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"doubleontologycode"> + description = <"doubleontologycode desc"> + > + ["at0000"] = < + text = <"DOUBLE doubleontologycode"> + description = <"DOUBLE doubleontologycode desc"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.adverse.v1.adl b/archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.adverse.v1.adl new file mode 100644 index 00000000..0b358e3c --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.adverse.v1.adl @@ -0,0 +1,411 @@ +archetype (adl_version=1.4) + openEHR-EHR-EVALUATION.adverse.v1 + +concept + [at0000] -- Adverse reaction +language + original_language = <[ISO_639-1::en]> + translations = < + ["de"] = < + language = <[ISO_639-1::de]> + author = < + ["name"] = <"Jasmin Buck, Sebastian Garde"> + ["organisation"] = <"University of Heidelberg, Central Queensland University"> + > + > + > +description + original_author = < + ["name"] = <"Sam Heard"> + ["organisation"] = <"Ocean Informatics"> + ["date"] = <"23/04/2006"> + ["email"] = <"sam.heard@oceaninformatics.biz"> + > + details = < + ["de"] = < + language = <[ISO_639-1::de]> + purpose = <"Zur Dokumentation von Nebenwirkungen auf einen bestimmten Wirkstoff. Die Art dieses Stoffes kann ebenfalls Dokumentiert werden. Frherer Aufzeichnungen knnen hinzugefgt werden und auch die Art der Reaktion beim jeweiligen Ereignis."> + use = <""> + keywords = <"Reaktion", "allergisch", "Allergie", "Intoleranz"> + misuse = <"Nicht zur Dokumentation keines Verlaufs einer Reaktion auf eine Substanz. Fr diesen Zweck openEHR-EVALUATION.excluded-adverse benutzen. Fr unbekannte Reaktionen auf beliebige Wirkstoffe openEHR-EVALUATION.excluded benutzen."> + > + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"For recording adverse reaction(s) to a particular 'Agent' the type of which may be recorded also. Historical recordings may be added and the type of reaction on each occasion."> + use = <""> + keywords = <"reaction", "allergic", "allergy", "intolerance"> + misuse = <"Do not use for recording no history of a reaction to a substance. Use openEHR-EVALUATION.excluded-adverse for this purpose. No known reactions to any agents, use openEHR-EVALUATION.excluded."> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <"NEHTA data groups (Australia)", "General Practice Computing Group (Australia)"> + +definition + EVALUATION[at0000] matches { -- Adverse reaction + data matches { + ITEM_TREE[at0002] matches { -- structure + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0003] matches { -- Agent + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0010] occurrences matches {0..1} matches { -- Agent category + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0011, -- Food + at0012, -- Animal + at0013, -- Medication + at0014, -- Other chemical or substance + at0031, -- Non-active ingredient of medication + at0033, -- Imaging dye or media + at0034] -- Environmental + } + } + } + } + CLUSTER[at0019] occurrences matches {0..*} matches { -- Exposure and reaction detail + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0032] occurrences matches {0..1} matches { -- Specific substance + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0015] occurrences matches {0..1} matches { -- Reaction category + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0016, -- Intolerance + at0017, -- Sensitivity + at0018, -- Allergy + at0030] -- No reaction + } + } + } + } + ELEMENT[at0004] occurrences matches {0..1} matches { -- Probability of causation + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0005, -- Certain/Highly likely + at0006, -- Probable + at0007] -- Possible + } + } + } + } + ELEMENT[at0020] occurrences matches {0..1} matches { -- Date of exposure + value matches { + DV_DATE_TIME matches { + value matches {yyyy-??-??T??:??:??} + } + } + } + ELEMENT[at0021] occurrences matches {0..1} matches { -- Duration of the exposure + value matches { + DV_DURATION matches { + value matches {PYMWDTHMS} + } + } + } + ELEMENT[at0023] occurrences matches {0..1} matches { -- Reaction severity + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0024, -- Mild + at0025, -- Disabling + at0026] -- Life threatening + } + } + } + } + ELEMENT[at0022] matches { -- Reaction description + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0027] occurrences matches {0..1} matches { -- Date of onset of reaction + value matches { + DV_DATE_TIME matches { + value matches {yyyy-??-??T??:??:??} + } + } + } + ELEMENT[at0028] occurrences matches {0..1} matches { -- Duration of the reaction + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + > + } + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["de"] = < + items = < + ["at0000"] = < + description = <"Zur Dokumentation des Vorhandenseins von schdlichen oder unerwnschten Reaktionen auf einen Wirkstoff oder eine Substanz, einschlielich Nahrung, festgestellt von einem Klinikarzt - Vergiftungen und unsachgemer Gebrauch ausgeschlossen"> + text = <"Nebenwirkung"> + > + ["at0002"] = < + description = <"@ internal @"> + text = <"Structure"> + > + ["at0003"] = < + description = <"Der Wirkstoff, die Substanz oder die Klasse, welche die Nebenwirkung ausgelst hat"> + text = <"Wirkstoff"> + > + ["at0004"] = < + description = <"Grad an Sicherheit, dass der Wirkstoff der Auslser der Reaktion war"> + text = <"Wahrscheinlichkeit fr kausalen Zusammenhang"> + > + ["at0005"] = < + description = <"Die Reaktion ist laut einem Klinikarzt auf den Wirkstoff zurckzufhren"> + text = <"Sicher/ sehr wahrscheinlich"> + > + ["at0006"] = < + description = <"Die Reaktion ist wahrscheinlich auf den Wirkstoff zurckzufhren"> + text = <"Wahrscheinlich"> + > + ["at0007"] = < + description = <"Die Reaktion ist mglicherweise auf den Wirkstoff zurckzufhren"> + text = <"Mglicherweise"> + > + ["at0010"] = < + description = <"Die Gruppe des Wirkstoffs"> + text = <"Wirkstoffgruppe"> + > + ["at0011"] = < + description = <"Eine Substanz, die als Teil der Ernhrung zugefhrt wurde "> + text = <"Nahrungsmittel"> + > + ["at0012"] = < + description = <"Ein lebender Organismus und dessen Gift oder produzierter Stoff"> + text = <"Tier"> + > + ["at0013"] = < + description = <"Eine Substanz, die aus medizinischen Grnden eingenommen oder verabreicht wurde"> + text = <"Medikament"> + > + ["at0014"] = < + description = <"Nicht-medizinische Chemikalie oder Substanz"> + text = <"Andere Chemikalie oder Substanz"> + > + ["at0015"] = < + description = <"Die Art der von der Person erfahrenen Reaktion, von einem Klinikarzt ermittelt"> + text = <"Reaktionsart"> + > + ["at0016"] = < + description = <"Fhrt zu unerfreulichen Symptomen, die ausreichen um einen Gebrauch in der Zukunft zu vermeiden"> + text = <"Intoleranz"> + > + ["at0017"] = < + description = <"Fhrt zu Krankhaftigkeit die eventuell zum Wohle des Patienten behandelt werden muss"> + text = <"Empfindlichkeit"> + > + ["at0018"] = < + description = <"Fhrt zu einer IgE Reaktion"> + text = <"Allergie"> + > + ["at0019"] = < + description = <"Einzelheiten der von der Person erfahrenen Reaktion"> + text = <"Exposition und Einzelheiten der Reaktion"> + > + ["at0020"] = < + description = <"Das Datum (+/- Zeit) wann die Person gegenber dem Wirkstoff exponiert wurde"> + text = <"Datum der Exposition"> + > + ["at0021"] = < + description = <"Die Dauer der Exposition gegenber dem Wirkstoff"> + text = <"Dauer der Exposition"> + > + ["at0022"] = < + description = <"Eine Beschreibung der von einer Person erfahrenen Reaktion auf einen Wirkstoff"> + text = <"Beschreibung der Reaktion"> + > + ["at0023"] = < + description = <"Die Klasse der Reaktion fr zuknftige Empfehlungen"> + text = <"Schweregrad der Reaktion"> + > + ["at0024"] = < + description = <"Eine Reaktion, die wenig Leiden und keinen Verlust der Arbeitsfhigkeit/ Schulfhigkeit verursacht"> + text = <"Gelinde"> + > + ["at0025"] = < + description = <"Eine Reaktion, die Krankheit und/oder den Verlust Funktionen verursacht"> + text = <"Unfhig machend"> + > + ["at0026"] = < + description = <"Eine Reaktion die lebensbedrohlich wahr oder sein kann"> + text = <"Lebensbedrohlich"> + > + ["at0027"] = < + description = <"Das Datum, an dem die Reaktion eintrat"> + text = <"Datum des Beginns der Reaktion"> + > + ["at0028"] = < + description = <"Die Dauer der Reaktion"> + text = <"Dauer der Reaktion"> + > + ["at0030"] = < + description = <"Die Person war ohne Reaktion exponiert"> + text = <"Keine Reaktion"> + > + ["at0031"] = < + description = <"Ein nicht-medizinischer Bestandteil des Medikaments, wie Farbstoff, Konservierungsstoff, usw. (Untertyp von andere Chemikalien)"> + text = <"Inaktiver Bestandteil des Medikaments"> + > + ["at0032"] = < + description = <"Die charakteristische Substanz, die die Reaktion verursacht, falls verschieden vom Wirkstoff (z.B. Marken oder Teile einer Klasse)"> + text = <"Charakteristische Substanz"> + > + ["at0033"] = < + description = <"Zur diagnostischen Bildgebung benutzter Farbstoff oder Medium (Untertyp von anderen Chemikalien)"> + text = <"Abbildender Farbstoff oder Medium"> + > + ["at0034"] = < + description = <"Ein in der Umwelt vorhandener Wirkstoff"> + text = <"Umgebend"> + > + > + > + ["en"] = < + items = < + ["at0000"] = < + description = <"Recording the presence of a harmful or undesirable response to an agent or substance including food, as determined by the clinician - excluding poisoning and abnormal use"> + text = <"Adverse reaction"> + > + ["at0002"] = < + description = <"@ internal @"> + text = <"structure"> + > + ["at0003"] = < + description = <"The agent or substance or class that caused the adverse reaction"> + text = <"Agent"> + > + ["at0004"] = < + description = <"Degree of certainty that the agent was the cause of the reaction"> + text = <"Probability of causation"> + > + ["at0005"] = < + description = <"A reaction to the agent is deemed to be or have been present by the clinician"> + text = <"Certain/Highly likely"> + > + ["at0006"] = < + description = <"The reaction is deemed to be the probable cause of the reaction"> + text = <"Probable"> + > + ["at0007"] = < + description = <"The agent is deemed to be a possible cause of the reaction"> + text = <"Possible"> + > + ["at0010"] = < + description = <"The category of the agent"> + text = <"Agent category"> + > + ["at0011"] = < + description = <"A substance taken as part of the diet"> + text = <"Food"> + > + ["at0012"] = < + description = <"A living organism or its venom or produce"> + text = <"Animal"> + > + ["at0013"] = < + description = <"A substance taken or applied for medicinal purposes"> + text = <"Medication"> + > + ["at0014"] = < + description = <"Non-medicinal chemicals or substances"> + text = <"Other chemical or substance"> + > + ["at0015"] = < + description = <"The type of reaction experience by the person as determined by the clinician"> + text = <"Reaction category"> + > + ["at0016"] = < + description = <"Leads to unpleasant symptoms which are sufficient to avoid use in the future"> + text = <"Intolerance"> + > + ["at0017"] = < + description = <"Leads to morbidity which is potentially threatening to the wellbeing of the person"> + text = <"Sensitivity"> + > + ["at0018"] = < + description = <"Leads to an IgE mediated reaction"> + text = <"Allergy"> + > + ["at0019"] = < + description = <"Details of the reaction experienced by the person"> + text = <"Exposure and reaction detail"> + > + ["at0020"] = < + description = <"The date (+/- time) when the person became exposed to the agent"> + text = <"Date of exposure"> + > + ["at0021"] = < + description = <"The duration of the exposure to the agent"> + text = <"Duration of the exposure"> + > + ["at0022"] = < + description = <"A description of the reaction to this agent as experienced by the person"> + text = <"Reaction description"> + > + ["at0023"] = < + description = <"The category of the reaction for future reference"> + text = <"Reaction severity"> + > + ["at0024"] = < + description = <"A reaction which causes little distress and no loss of work/school"> + text = <"Mild"> + > + ["at0025"] = < + description = <"A reaction which causes morbidity and/or loss of function"> + text = <"Disabling"> + > + ["at0026"] = < + description = <"A reaction which was or could be lifethreatening"> + text = <"Life threatening"> + > + ["at0027"] = < + description = <"The date the reaction began"> + text = <"Date of onset of reaction"> + > + ["at0028"] = < + description = <"The duration of the reaction"> + text = <"Duration of the reaction"> + > + ["at0030"] = < + description = <"Person has been exposed with no reaction"> + text = <"No reaction"> + > + ["at0031"] = < + description = <"A non-medicinal ingredient of medication such as colouring, preservative, etc (subtype of other chemical)"> + text = <"Non-active ingredient of medication"> + > + ["at0032"] = < + description = <"The specific substance that caused the reaction if different from the agent (e.g. brands or members of a class)"> + text = <"Specific substance"> + > + ["at0033"] = < + description = <"A dye or media used in diagnostic imaging (subtype of other chemical)"> + text = <"Imaging dye or media"> + > + ["at0034"] = < + description = <"An agent present in the environment"> + text = <"Environmental"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.null_flavor.v1.adl b/archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.null_flavor.v1.adl new file mode 100644 index 00000000..21186c42 --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.null_flavor.v1.adl @@ -0,0 +1,90 @@ +archetype (adl_version=1.4) + openEHR-EHR-EVALUATION.null_flavor.v1 + +concept + [at0000] -- nf test +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"SG"> + > + details = < + ["de"] = < + language = <[ISO_639-1::en]> + purpose = <"Test if null_flavor is detected as a NON-valid attribute"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"0"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"A3858DD30CE8F41648F44E07C3C06D1F"> + > + +definition + EVALUATION[at0000] matches { -- nf test + data matches { + ITEM_TREE[at0001] matches { -- Baum + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0002] occurrences matches {0..1} matches { -- Neues Element + value matches { + C_DV_ORDINAL < + > + } + null_flavor existence matches {0..1} matches { + DV_CODED_TEXT matches { + defining_code matches { + [openehr:: + 253, + 272] + } + } + } + } + ELEMENT[at0003] occurrences matches {0..1} matches { -- Neues Element + value matches { + DV_COUNT matches { + magnitude matches {*} + } + } + null_flavor existence matches {0..1} matches { + DV_CODED_TEXT matches { + defining_code matches { + [openehr:: + 271, + 273] + } + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["de"] = < + items = < + ["at0000"] = < + text = <"nf test"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Baum"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Neues Element"> + description = <"*"> + > + ["at0003"] = < + text = <"Neues Element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.null_flavour.v1.adl b/archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.null_flavour.v1.adl new file mode 100644 index 00000000..0781b1db --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.null_flavour.v1.adl @@ -0,0 +1,90 @@ +archetype (adl_version=1.4) + openEHR-EHR-EVALUATION.null_flavour.v1 + +concept + [at0000] -- nf test +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"SG"> + > + details = < + ["de"] = < + language = <[ISO_639-1::en]> + purpose = <"Test if null_flavour is detected as a valid attribute"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"0"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"A3858DD30CE8F41648F44E07C3C06D1F"> + > + +definition + EVALUATION[at0000] matches { -- nf test + data matches { + ITEM_TREE[at0001] matches { -- Baum + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0002] occurrences matches {0..1} matches { -- Neues Element + value matches { + C_DV_ORDINAL < + > + } + null_flavour existence matches {0..1} matches { + DV_CODED_TEXT matches { + defining_code matches { + [openehr:: + 253, + 272] + } + } + } + } + ELEMENT[at0003] occurrences matches {0..1} matches { -- Neues Element + value matches { + DV_COUNT matches { + magnitude matches {*} + } + } + null_flavour existence matches {0..1} matches { + DV_CODED_TEXT matches { + defining_code matches { + [openehr:: + 271, + 273] + } + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["de"] = < + items = < + ["at0000"] = < + text = <"nf test"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Baum"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Neues Element"> + description = <"*"> + > + ["at0003"] = < + text = <"Neues Element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.problem-diagnosis.v1.adl b/archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.problem-diagnosis.v1.adl new file mode 100644 index 00000000..3c54d4a6 --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.problem-diagnosis.v1.adl @@ -0,0 +1,897 @@ +archetype (adl_version=1.4) + openEHR-EHR-EVALUATION.problem-diagnosis.v1 +specialize + openEHR-EHR-EVALUATION.problem.v1 + +concept + [at0000.1] -- Diagnosis +language + original_language = <[ISO_639-1::en]> + translations = < + ["de"] = < + language = <[ISO_639-1::de]> + author = < + ["name"] = <"Jasmin Buck, Sebastian Garde"> + ["organisation"] = <"University of Heidelberg, Central Queensland University"> + > + > + > +description + original_author = < + ["name"] = <"Sam Heard"> + ["organisation"] = <"Ocean Informatics"> + ["date"] = <"23/04/2006"> + ["email"] = <"sam.heard@oceaninformatics.biz"> + > + details = < + ["de"] = < + language = <[ISO_639-1::de]> + purpose = <"Zur Dokumentation klinischer Diagnosen mit optionalen diagnostischen Kriterien und Dringlichkeiten. Erfordert kodierten Eintrag der Diagnosen."> + use = <"Zur Dokumentation beliebiger frherer oder aktueller Diagnosen - also zur Dokumentation des frheren Verlaufs oder der aktuellen Diagnosen. Kann zur Dokumentation der Diagnosen wechselnder Patienten genutzt werden, also zur Familienanamnese."> + keywords = <"frher", "Verlauf", "Familie", "Historie", "Zustand"> + misuse = <"Fr histologische Diagnosen 'openEHR-EHR-EVALUATION.problem-diagnosis-histological' benutzen."> + > + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"For recording medical diagnoses with optional diagnostic criteria and staging. Requires coded entry of diagnosis. "> + use = <"Used for recording any diagnosis, present or past - so is used for recording past history as well as current diagnoses. Used with changed 'Subject of care' for recording diagnoses in relatives and so for family history."> + keywords = <"past", "history", "family", "history", "condition"> + misuse = <"Use 'openEHR-EHR-EVALUATION.problem-diagnosis-histological' for histological diagnoses."> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <> + +definition + EVALUATION[at0000.1] matches { -- Diagnosis + data matches { + ITEM_TREE[at0001] matches { -- structure + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0002.1] matches { -- Diagnosis + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0.1]} -- Any term that 'is_a' diagnosis + } + } + } + ELEMENT[at0.32] occurrences matches {0..1} matches { -- Status + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0.33, -- provisional + at0.34] -- working + } + } + } + } + ELEMENT[at0003] occurrences matches {0..1} matches { -- Date of initial onset + value matches { + DV_DATE matches { + value matches {yyyy-??-??} + } + } + } + ELEMENT[at0004] occurrences matches {0..1} matches { -- Age at initial onset + value matches { + DV_DURATION matches { + value matches {PYMWDTHMS} + } + } + } + ELEMENT[at0005] occurrences matches {0..1} matches { -- Severity + value matches { + 1|[local::at0006], -- Mild + 4|[local::at0007], -- Moderate + 7|[local::at0008] -- Severe + } + } + ELEMENT[at0009] occurrences matches {0..1} matches { -- Clinical description + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0010] occurrences matches {0..1} matches { -- Date clinically recognised + value matches { + DV_DATE matches { + value matches {yyyy-??-XX} + } + } + } + CLUSTER[at0011] occurrences matches {0..*} matches { -- Location + items cardinality matches {1..2; ordered} matches { + ELEMENT[at0012] occurrences matches {0..1} matches { -- Body site + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that describes a body site + } + } + } + ELEMENT[at0013] occurrences matches {0..1} matches { -- Location description + value matches { + DV_TEXT matches {*} + } + } + } + } + CLUSTER[at0014] occurrences matches {0..1} matches { -- Aetiology + items cardinality matches {1..2; unordered} matches { + ELEMENT[at0015] occurrences matches {0..*} matches { -- Agent + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0016] occurrences matches {0..*} matches { -- Complication of + value matches { + DV_TEXT matches {*} + DV_URI matches {*} + } + } + ELEMENT[at0017] occurrences matches {0..1} matches { -- Description + value matches { + DV_TEXT matches {*} + } + } + } + } + CLUSTER[at0018] occurrences matches {0..1} matches { -- Occurrences or exacerbations + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0019] occurrences matches {0..1} matches { -- Frequency of reccurrence + value matches { + C_DV_QUANTITY < + > + } + } + ELEMENT[at0020] occurrences matches {0..1} matches { -- Date of last occurrence + value matches { + DV_DATE matches { + value matches {yyyy-??-??} + } + } + } + CLUSTER[at0021] occurrences matches {0..*} matches { -- Occurence/exacerbation + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0022] occurrences matches {0..1} matches { -- Clinical description + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0023] occurrences matches {0..1} matches { -- Outcome + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0024] occurrences matches {0..1} matches { -- Date of onset of occurrence + value matches { + DV_DATE matches { + value matches {yyyy-??-??} + } + } + } + ELEMENT[at0036] occurrences matches {0..1} matches { -- Date of resolution of occurrence + value matches { + DV_DATE matches { + value matches {yyyy-??-??} + } + } + } + } + } + ELEMENT[at0025] occurrences matches {0..1} matches { -- Number of occurrences + value matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + } + } + } + } + CLUSTER[at0026] occurrences matches {0..1} matches { -- Related problems + name matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0037, -- Related problems + at0038] -- Complications + } + } + } + items cardinality matches {0..*; unordered} matches { + CLUSTER[at0027] occurrences matches {0..*} matches { -- Related problem + name matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0039, -- Related problem + at0040] -- Complication + } + } + } + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0028] occurrences matches {0..1} matches { -- Related problem + name matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0041, -- Problem + at0042] -- Complication + } + } + } + value matches { + DV_TEXT matches {*} + DV_URI matches {*} + } + } + ELEMENT[at0029] occurrences matches {0..1} matches { -- Clinical description + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + ELEMENT[at0030] occurrences matches {0..1} matches { -- Date of resolution + value matches { + DV_DATE matches { + value matches {yyyy-??-??} + } + } + } + ELEMENT[at0031] occurrences matches {0..1} matches { -- Age at resolution + value matches { + DV_DURATION matches { + value matches {PYMWDTHMS} + } + } + } + CLUSTER[at0.35] occurrences matches {0..1} matches { -- Diagnostic criteria + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0.36] occurrences matches {0..*} matches { -- Criterion + value matches { + DV_TEXT matches {*} + } + } + } + } + CLUSTER[at0.37] occurrences matches {0..1} matches { -- Clinical staging + items cardinality matches {0..4; ordered} matches { + ELEMENT[at0.38] occurrences matches {0..1} matches { -- Stage + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0.39] occurrences matches {0..1} matches { -- Tumour + value matches { + -1|[local::at0.40], -- Tx - primary tumour not assessed + 0|[local::at0.41], -- T0 - no primary tumour + 5|[local::at0.42], -- Tis - Carcinoma insitu + 10|[local::at0.43], -- T1 - Micorinvasion (0.5cm) + 20|[local::at0.44], -- T2 - Tumour invading 1 cm + 30|[local::at0.45], -- T3 - Full thickness of structure + 40|[local::at0.46] -- T5 - Invading adjacent structure + } + } + ELEMENT[at0.47] occurrences matches {0..1} matches { -- Nodes + value matches { + -1|[local::at0.48], -- Nx - regional nodes not assessed + 0|[local::at0.49], -- N0 - no regional nodes involved + 10|[local::at0.50] -- N1 - Regional nodes involved + } + } + ELEMENT[at0.51] occurrences matches {0..1} matches { -- Metastases + value matches { + -1|[local::at0.52], -- Mx - metastases not assessed + 0|[local::at0.53], -- M0 - No distant metastases + 10|[local::at0.54] -- M1 - Distant metastases + } + } + } + } + } + } + } + protocol matches { + ITEM_TREE[at0032] matches { -- Tree + items cardinality matches {0..*; unordered} matches { + CLUSTER[at0033] occurrences matches {0..1} matches { -- References + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0034] occurrences matches {0..*} matches { -- References + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0035] occurrences matches {0..*} matches { -- Web link + value matches { + DV_URI matches {*} + } + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["de"] = < + items = < + ["at0.32"] = < + description = <"Der Status der Diagnose"> + text = <"Status"> + > + ["at0.33"] = < + description = <"vorlufige, als wahrscheinlich erachtete Diagnose und eine Grundlage zum weiteren Vorgehen"> + text = <"vorlufig"> + > + ["at0.34"] = < + description = <"als sehr wahrscheinlich erachtete, aber noch nicht besttigte Diagnose"> + text = <"wahrscheinlich"> + > + ["at0.35"] = < + description = <"Merkmale, auf die die Diagnose begrndet ist"> + text = <"diagnostische Merkmale"> + > + ["at0.36"] = < + description = <"Eine Grundlage fr die Diagnose"> + text = <"Merkmale"> + > + ["at0.37"] = < + description = <"Die Einstufung der Erkrankung durch klinische Beurteilung"> + text = <"klinische Einstufung"> + > + ["at0.38"] = < + description = <"Die Einstufung der Erkrankung (nicht TNM)"> + text = <"Einstufung"> + > + ["at0.39"] = < + description = <"Die Ausdehnung des Befalls des lokalen Gewebes"> + text = <"Tumor"> + > + ["at0.40"] = < + description = <"Keine klinische Beurteilung des Primrtumors erfolgt"> + text = <"Tx - Primrtumor nicht beurteilt"> + > + ["at0.41"] = < + description = <"Kein klinischer Anhalt fr einen Primrtumor"> + text = <"T0 - kein Primrtumor"> + > + ["at0.42"] = < + description = <"Die malignen Zellen sind auf ihre bliche zellulre Region begrenzt"> + text = <"Tis - In-situ_Karzinom"> + > + ["at0.43"] = < + description = <"Mikroskopischer Befall von 5 mm"> + text = <"Ti - Mikroinvasion (0,5 cm)"> + > + ["at0.44"] = < + description = <"Tumorbefall 1 cm"> + text = <"T2 - Tumorbefall 1 cm"> + > + ["at0.45"] = < + description = <"Tumor hat die gesamte Dicke (oder Grenzen) der Struktur befallen"> + text = <"T3 - Tumorbefall der gesamten Dicke der Struktur"> + > + ["at0.46"] = < + description = <"Tumor hat sich ber die Struktur hinaus ausgebreitet, in der er entstanden ist"> + text = <"T5 - Befall angrenzender Strukturen"> + > + ["at0.47"] = < + description = <"Ausdehnung des Befalls regionrer Knoten"> + text = <"Knoten"> + > + ["at0.48"] = < + description = <"Keine klinische Beurteilung der regionren Knoten erfolgt"> + text = <"Nx - regionre Knoten nicht beurteilt"> + > + ["at0.49"] = < + description = <"Kein klinischer Anhalt fr einen Befall der regionren Knoten"> + text = <"N0 - keine regionren Knoten befallen"> + > + ["at0.50"] = < + description = <"Klinische Beurteilung deutet darauf hin, dass regionre Knoten befallen sind"> + text = <"N1 - -regionre Knoten befallen"> + > + ["at0.51"] = < + description = <"Ausdehnung der Metastasen"> + text = <"Metastasen"> + > + ["at0.52"] = < + description = <"Keine klinische Beurteilung der Metastasen"> + text = <"Mx - Metastasen nicht beurteilt"> + > + ["at0.53"] = < + description = <"Kein klinischer Anhalt fr Fernmetastasen"> + text = <"M0 - keine Fernmetastasen"> + > + ["at0.54"] = < + description = <"Klinischer Anhalt fr Fernmetastasen"> + text = <"M1 - Fernmetastasen"> + > + ["at0000"] = < + description = <"Ein Problem, ein Zustand oder Sachverhalt definiert von einem Kliniker, der als zusammenfassend fr eine Menge von Symptomen oder Anliegen der Person erachtet wird und dieses sinnvoll bezeichnet"> + text = <"Problem"> + > + ["at0000.1"] = < + description = <"Eine von einem Klinikarzt formulierte Diagnose, kodiert in einer anerkannten Terminologie, einschlielich der Stufe des Zustandes und den diagnostischen Kriterien"> + text = <"Diagnose"> + > + ["at0001"] = < + description = <"@ internal @"> + text = <"Structure"> + > + ["at0002"] = < + description = <"Das Problem, der Zustand oder Sachverhalt, der beschrieben wird"> + text = <"Problem"> + > + ["at0002.1"] = < + description = <"Die angezeigte Diagnose"> + text = <"Diagnose"> + > + ["at0003"] = < + description = <"Das Datum, an dem das Problem begonnen hat, Symptome oder Anzeichen zu verursachen"> + text = <"Datum des ersten Auftretens"> + > + ["at0004"] = < + description = <"Das Alter der Peson zum Zeitpunkt des ersten Auftreten des Problems"> + text = <"Alter beim ersten Auftreten"> + > + ["at0005"] = < + description = <"Der Schweregrad des Problems"> + text = <"Schweregrad"> + > + ["at0006"] = < + description = <"Der Schweregrad des Problems ist gelinde, hat keine Auswirkungen auf das Leben oder die Lebensdauer"> + text = <"Gelinde"> + > + ["at0007"] = < + description = <"Der Schweregrad des Problems verursacht erhebliche Morbiditt"> + text = <"Mig"> + > + ["at0008"] = < + description = <"Der Schweregrad des Problems hat bedeutende Auswirkungen auf das Leben und/oder die Lebensdauer"> + text = <"Schwerwiegend"> + > + ["at0009"] = < + description = <"Beschreibung der klinischen Gesichtspunkte des Problems"> + text = <"Klinische Beschreibung"> + > + ["at0010"] = < + description = <"Datum, an dem das Problem von einem Kliniker erkannt oder 'diagnostiziert' wurde"> + text = <"Datum der klinischen Erkennung"> + > + ["at0011"] = < + description = <"Lage des Problems bezglich der Krperseiten"> + text = <"Lokalisierung"> + > + ["at0012"] = < + description = <"Die betroffene Krperstelle"> + text = <"Krperstelle"> + > + ["at0013"] = < + description = <"Eine Freitext zur Beschreibung der Lage - kann zustzlich zu einer codierten Krperseite sein"> + text = <"Lagebeschreibung"> + > + ["at0014"] = < + description = <"Erreger oder Faktoren die als tiologisch signifikant bekannt sind"> + text = <"tiologie"> + > + ["at0015"] = < + description = <"Mikrobische oder andere Erreger, die als Verursacher des Problems festgestellt wurden"> + text = <"Erreger"> + > + ["at0016"] = < + description = <"Ein Problem oder ein Hinweis auf ein Problem oder eine Verletzung, an anderer Stelle in der EPA dokumentiert ist"> + text = <"Komplikation"> + > + ["at0017"] = < + description = <"Beschreibung des tiologischen Verlaufs"> + text = <"Beschreibung"> + > + ["at0018"] = < + description = <"Gruppierung von Informationen ber individuelle Vorkommen oder Verschlimmerungen"> + text = <"Auftreten oder Verschlimmerung"> + > + ["at0019"] = < + description = <"Die Hufigkeit der individuellen Vorkommen des Problems"> + text = <"Hufigkeit des Wiederauftritts"> + > + ["at0020"] = < + description = <"Das Datum des letzten Auftreten des Problems"> + text = <"Datum des letzten Auftretens"> + > + ["at0021"] = < + description = <"Informationen ber einen einzelnen Auftritt oder eine einzelne Verschlimmerung"> + text = <"Auftreten/ Verschlimmerung"> + > + ["at0022"] = < + description = <"Eine Beschreibung der Verschlimmerung oder des Auftretens"> + text = <"Klinische Beschreibung"> + > + ["at0023"] = < + description = <"Folge des Auftretens oder der Verschlimmerung"> + text = <"Folge"> + > + ["at0024"] = < + description = <"Datum des Ausbruchs des Ereignisses oder der Verschlimmerung"> + text = <"Datum des Auftretens"> + > + ["at0025"] = < + description = <"Anzahl, wie oft das Problem aufgetreten oder ersichtlich war"> + text = <"Anzahl der Vorkomnisse"> + > + ["at0026"] = < + description = <"Komplikationen, die diesem Problem zugeordnet werden knnen"> + text = <"Verwandte Probleme"> + > + ["at0027"] = < + description = <"Eine Gruppe an Kenndaten des Problems, welche die in diesem Archetypen erfassten Gegebenheiten erschweren"> + text = <"Verwandtes Problem"> + > + ["at0028"] = < + description = <"Einzelheiten des Problems als Text, kodierter Text oder URI"> + text = <"Verwandtes Problem"> + > + ["at0029"] = < + description = <"Beschreibung des erschwerenden Problems"> + text = <"Klinische Beschreibung"> + > + ["at0030"] = < + description = <"Datum, an dem das Problem behoben wurde oder in Remission berging"> + text = <"Datum der Heilung"> + > + ["at0031"] = < + description = <"Das Alter der Person bei der Behebung des Problems"> + text = <"Alter bei Heilung"> + > + ["at0032"] = < + description = <"@ internal @"> + text = <"Tree"> + > + ["at0033"] = < + description = <"Ntzliche Informationen ber diesen Zustand"> + text = <"Hinweis"> + > + ["at0034"] = < + description = <"Hinweise auf Material ber diesen Zustand"> + text = <"Hinweis"> + > + ["at0035"] = < + description = <"Ntzliche Informationen im Internet ber diesen Zustand"> + text = <"Internetverweis"> + > + ["at0036"] = < + description = <"Datum, an dem der Auftreten des Problems behoben wurde"> + text = <"Datum der Behebung"> + > + ["at0037"] = < + description = <"Zu diesem Problem eng verwandte Probleme mit gemeinsamer oder folgender tiologie"> + text = <"Verwandte Probleme"> + > + ["at0038"] = < + description = <"Probleme mit folgerichtiger tiologien"> + text = <"Komplikationen"> + > + ["at0039"] = < + description = <"Probleme mit gemeinsamer oder folgerichtiger tiologie"> + text = <"Verwandte Probleme"> + > + ["at0040"] = < + description = <"Problem mit folgerichtiger tiologie"> + text = <"Komplikation"> + > + ["at0041"] = < + description = <"Ein zum angezeigten Problem verwandtes Problem mit gemeinsamer tiologie"> + text = <"Problem"> + > + ["at0042"] = < + description = <"Ein Problem, das die Folge des angezeigten Problems ist"> + text = <"Komplikation"> + > + > + > + ["en"] = < + items = < + ["at0.32"] = < + description = <"The status of the diagnosis"> + text = <"Status"> + > + ["at0.33"] = < + description = <"provisional diagnosis considered likely and a basis for proceeding with management"> + text = <"provisional"> + > + ["at0.34"] = < + description = <"working diagnosis considered very likely but not yet confirmed"> + text = <"working"> + > + ["at0.35"] = < + description = <"The criteria on which the diagnosis is based"> + text = <"Diagnostic criteria"> + > + ["at0.36"] = < + description = <"A basis for the diagnosis"> + text = <"Criterion"> + > + ["at0.37"] = < + description = <"The stage of the disease by clinical assessment"> + text = <"Clinical staging"> + > + ["at0.38"] = < + description = <"The stage of the disease (not TNM staging)"> + text = <"Stage"> + > + ["at0.39"] = < + description = <"The extent of invasion of local tissue"> + text = <"Tumour"> + > + ["at0.40"] = < + description = <"No clinical assessment of the primary tumour made"> + text = <"Tx - primary tumour not assessed"> + > + ["at0.41"] = < + description = <"No primary tumour is evident clinically"> + text = <"T0 - no primary tumour"> + > + ["at0.42"] = < + description = <"The malignant cells are confined to their usual cellular region"> + text = <"Tis - Carcinoma insitu"> + > + ["at0.43"] = < + description = <"Microscopic invasion of 5mm"> + text = <"T1 - Micorinvasion (0.5cm)"> + > + ["at0.44"] = < + description = <"Tumour invading 1cm"> + text = <"T2 - Tumour invading 1 cm"> + > + ["at0.45"] = < + description = <"Tumour invading to full thickness (or border) of structure"> + text = <"T3 - Full thickness of structure"> + > + ["at0.46"] = < + description = <"Tumour has spread outside the structure in which it arose"> + text = <"T5 - Invading adjacent structure"> + > + ["at0.47"] = < + description = <"Extent of involvement of regional nodes"> + text = <"Nodes"> + > + ["at0.48"] = < + description = <"No clinical assessment of regional nodes made"> + text = <"Nx - regional nodes not assessed"> + > + ["at0.49"] = < + description = <"No clinical evidence of regional node involvement"> + text = <"N0 - no regional nodes involved"> + > + ["at0.50"] = < + description = <"Clinical assessment indicates that regional nodes are involved"> + text = <"N1 - Regional nodes involved"> + > + ["at0.51"] = < + description = <"Extent of metastases"> + text = <"Metastases"> + > + ["at0.52"] = < + description = <"No clinical assessment of metastases"> + text = <"Mx - metastases not assessed"> + > + ["at0.53"] = < + description = <"No clinical evidence of distanct metastases"> + text = <"M0 - No distant metastases"> + > + ["at0.54"] = < + description = <"Clinical evidence of distant metastases"> + text = <"M1 - Distant metastases"> + > + ["at0000"] = < + description = <"A problem, condition or issue defined by a clinician which is deemed summative of a range of symptoms or concerns of the person and a useful label of these."> + text = <"Problem"> + > + ["at0000.1"] = < + description = <"A diagnosis defined by a clinician which is coded in an accepted terminology and may include the stage of the condition and the diagnostic criteria"> + text = <"Diagnosis"> + > + ["at0001"] = < + description = <"@ internal @"> + text = <"structure"> + > + ["at0002"] = < + description = <"The index problem, condition or issue described"> + text = <"Problem"> + > + ["at0002.1"] = < + description = <"The index diagnosis"> + text = <"Diagnosis"> + > + ["at0003"] = < + description = <"The date that the problem began causing symptoms or signs"> + text = <"Date of initial onset"> + > + ["at0004"] = < + description = <"The age of the at the onset of the problem"> + text = <"Age at initial onset"> + > + ["at0005"] = < + description = <"The severity of the index problem"> + text = <"Severity"> + > + ["at0006"] = < + description = <"The severity of the index problem is mild, not affecting life or longevity"> + text = <"Mild"> + > + ["at0007"] = < + description = <"The severity of the index problem is such as to cause significant morbidity"> + text = <"Moderate"> + > + ["at0008"] = < + description = <"The severity of the index problem has had a major effect on life and/or longevity"> + text = <"Severe"> + > + ["at0009"] = < + description = <"Description of the clinical aspects of the problem"> + text = <"Clinical description"> + > + ["at0010"] = < + description = <"Date the problem was recognised by clinicians"> + text = <"Date clinically recognised"> + > + ["at0011"] = < + description = <"Location of the problem in terms of body site"> + text = <"Location"> + > + ["at0012"] = < + description = <"The body site affected"> + text = <"Body site"> + > + ["at0013"] = < + description = <"A free text description of the location - may be in addition to a coded body site"> + text = <"Location description"> + > + ["at0014"] = < + description = <"Agents or Factors known to have been of aetiological significance"> + text = <"Aetiology"> + > + ["at0015"] = < + description = <"Microbial or other agent known to have caused this problem"> + text = <"Agent"> + > + ["at0016"] = < + description = <"A problem or link to a problem or injury described elsewhere in the EHR"> + text = <"Complication of"> + > + ["at0017"] = < + description = <"Description of aetiological process"> + text = <"Description"> + > + ["at0018"] = < + description = <"Grouping of information about individual occurrences or exacerbations"> + text = <"Occurrences or exacerbations"> + > + ["at0019"] = < + description = <"The frequency of individual occurrences of the problem"> + text = <"Frequency of reccurrence"> + > + ["at0020"] = < + description = <"The date of the last occurrence or exacerbation"> + text = <"Date of last occurrence"> + > + ["at0021"] = < + description = <"Information about one occurrence or exacerbation"> + text = <"Occurence/exacerbation"> + > + ["at0022"] = < + description = <"A description of the exacerbation or occurrence"> + text = <"Clinical description"> + > + ["at0023"] = < + description = <"Outcome of the occurrence or exacerbation"> + text = <"Outcome"> + > + ["at0024"] = < + description = <"Date of onset of occurrence or exacerbation"> + text = <"Date of onset of occurrence"> + > + ["at0025"] = < + description = <"Number of times this problem has occurred or been apparent"> + text = <"Number of occurrences"> + > + ["at0026"] = < + description = <"Complications that are attributed to this problem"> + text = <"Related problems"> + > + ["at0027"] = < + description = <"A group of characteristics of the problem complicating the index condition in this archetype"> + text = <"Related problem"> + > + ["at0028"] = < + description = <"Details of the problem as text or coded text or URI"> + text = <"Related problem"> + > + ["at0029"] = < + description = <"Decription of the complicating problem"> + text = <"Clinical description"> + > + ["at0030"] = < + description = <"The date that the problem resolved or went into remission"> + text = <"Date of resolution"> + > + ["at0031"] = < + description = <"The age of the at the resolution of the problem"> + text = <"Age at resolution"> + > + ["at0032"] = < + description = <"@ internal @"> + text = <"Tree"> + > + ["at0033"] = < + description = <"Useful information about this condition"> + text = <"References"> + > + ["at0034"] = < + description = <"Reference to material about this condition"> + text = <"References"> + > + ["at0035"] = < + description = <"Useful information on the internet about this condition"> + text = <"Web link"> + > + ["at0036"] = < + description = <"Date of the resolution of the occurrence"> + text = <"Date of resolution of occurrence"> + > + ["at0037"] = < + description = <"Problems that are closely related to this problem having a common aetiology or consequent aetiology"> + text = <"Related problems"> + > + ["at0038"] = < + description = <"Problems with consequent aetiology"> + text = <"Complications"> + > + ["at0039"] = < + description = <"Problem with common or consequent aetiology"> + text = <"Related problem"> + > + ["at0040"] = < + description = <"Problem with consequent aetiology"> + text = <"Complication"> + > + ["at0041"] = < + description = <"A problem which is related to the index problem through common aetiology"> + text = <"Problem"> + > + ["at0042"] = < + description = <"A problem that is a consequence of the index problem"> + text = <"Complication"> + > + > + > + > + constraint_definitions = < + ["de"] = < + items = < + ["ac0.1"] = < + description = <"Ausdruck, der eine Diagnose in einer anerkannten Terminologie ist"> + text = <"Beliebiger Ausdruck der eine Diagnose ist"> + > + ["ac0000"] = < + description = <"Eine anatomische Struktur mit Vermerken"> + text = <"Beliebiger Ausdruck, der eine Krperstelle beschreibt"> + > + > + > + ["en"] = < + items = < + ["ac0.1"] = < + description = <"Any term that is a diagnosis in an accepted terminology"> + text = <"Any term that 'is_a' diagnosis"> + > + ["ac0000"] = < + description = <"An anatomical structure with qualifiers"> + text = <"Any term that describes a body site"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v1.adl b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v1.adl new file mode 100644 index 00000000..f04ba50c --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v1.adl @@ -0,0 +1,70 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.internal_reference.v1 + +concept + [at0000] +language + original_language = <[ISO_639-1::en]> + +definition + OBSERVATION[at0000] matches { -- Apgar score + data matches { + HISTORY[at0002] matches { -- history + events cardinality matches {1..*; unordered} matches { + POINT_EVENT[at0003] occurrences matches {0..1} matches { -- 1 minute + data matches { + ITEM_LIST[at0001] matches { -- structure + items cardinality matches {1..6; ordered} matches { + ELEMENT[at0005] occurrences matches {0..1} matches { -- Heart rate + value matches { + 0|[local::at0006], -- No heart beat + 1|[local::at0007], -- Less than 100 beats per minute + 2|[local::at0008] -- Greater than or equal to 100 beats per minute + } + } + } + } + } + } + POINT_EVENT[at0006] occurrences matches {0..1} matches { -- 2 minute + data matches { + use_node ITEM_LIST /data[at0002]/events[at0003]/data[at0001] + } + } + } + } + } + } + +ontology + terminologies_available = <"LNC205", ...> + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + description = <"Clinical score derived from assessment of breathing, colour, muscle tone, heart rate and reflex response usually taken at 1, 5 and 10 minutes after birth"> + text = <"Apgar score"> + > + ["at0001"] = < + description = <"@ internal @"> + text = <"structure"> + > + ["at0002"] = < + description = <"@ internal @"> + text = <"history"> + > + ["at0003"] = < + description = <"Apgar score at one minute from birth"> + text = <"1 minute"> + > + ["at0005"] = < + description = <"Assessment of heart function in the new born"> + text = <"Heart rate"> + > + ["at0006"] = < + description = <"No heart beat is present (palpation at base of umbilical cord)"> + text = <"No heart beat"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v2.adl b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v2.adl new file mode 100644 index 00000000..c3b2eb3c --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v2.adl @@ -0,0 +1,70 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.internal_reference.v2 + +concept + [at0000] +language + original_language = <[ISO_639-1::en]> + +definition + OBSERVATION[at0000] matches { -- Apgar score + data matches { + HISTORY[at0002] matches { -- history + events cardinality matches {1..*; unordered} matches { + POINT_EVENT[at0003] occurrences matches {0..1} matches { -- 1 minute + data matches { + ITEM_LIST[at0001] matches { -- structure + items cardinality matches {1..6; ordered} matches { + ELEMENT[at0005] occurrences matches {0..1} matches { -- Heart rate + value matches { + 0|[local::at0006], -- No heart beat + 1|[local::at0007], -- Less than 100 beats per minute + 2|[local::at0008] -- Greater than or equal to 100 beats per minute + } + } + } + } + } + } + POINT_EVENT[at0006] occurrences matches {0..1} matches { -- 2 minute + data matches { + use_node ELEMENT /data[at0002]/events[at0003]/data[at0001] + } + } + } + } + } + } + +ontology + terminologies_available = <"LNC205", ...> + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + description = <"Clinical score derived from assessment of breathing, colour, muscle tone, heart rate and reflex response usually taken at 1, 5 and 10 minutes after birth"> + text = <"Apgar score"> + > + ["at0001"] = < + description = <"@ internal @"> + text = <"structure"> + > + ["at0002"] = < + description = <"@ internal @"> + text = <"history"> + > + ["at0003"] = < + description = <"Apgar score at one minute from birth"> + text = <"1 minute"> + > + ["at0005"] = < + description = <"Assessment of heart function in the new born"> + text = <"Heart rate"> + > + ["at0006"] = < + description = <"No heart beat is present (palpation at base of umbilical cord)"> + text = <"No heart beat"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v3.adl b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v3.adl new file mode 100644 index 00000000..adb08514 --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v3.adl @@ -0,0 +1,70 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.internal_reference.v3 + +concept + [at0000] +language + original_language = <[ISO_639-1::en]> + +definition + OBSERVATION[at0000] matches { -- Apgar score + data matches { + HISTORY[at0002] matches { -- history + events cardinality matches {1..*; unordered} matches { + POINT_EVENT[at0003] occurrences matches {0..1} matches { -- 1 minute + data matches { + ITEM_LIST[at0001] matches { -- structure + items cardinality matches {1..6; ordered} matches { + ELEMENT[at0005] occurrences matches {0..1} matches { -- Heart rate + value matches { + 0|[local::at0006], -- No heart beat + 1|[local::at0007], -- Less than 100 beats per minute + 2|[local::at0008] -- Greater than or equal to 100 beats per minute + } + } + } + } + } + } + POINT_EVENT[at0006] occurrences matches {0..1} matches { -- 2 minute + data matches { + use_node ITEM_LIST /data[at0002]/events[at0003] + } + } + } + } + } + } + +ontology + terminologies_available = <"LNC205", ...> + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + description = <"Clinical score derived from assessment of breathing, colour, muscle tone, heart rate and reflex response usually taken at 1, 5 and 10 minutes after birth"> + text = <"Apgar score"> + > + ["at0001"] = < + description = <"@ internal @"> + text = <"structure"> + > + ["at0002"] = < + description = <"@ internal @"> + text = <"history"> + > + ["at0003"] = < + description = <"Apgar score at one minute from birth"> + text = <"1 minute"> + > + ["at0005"] = < + description = <"Assessment of heart function in the new born"> + text = <"Heart rate"> + > + ["at0006"] = < + description = <"No heart beat is present (palpation at base of umbilical cord)"> + text = <"No heart beat"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v4.adl b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v4.adl new file mode 100644 index 00000000..0aa7821f --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v4.adl @@ -0,0 +1,70 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.internal_reference.v1 + +concept + [at0000] +language + original_language = <[ISO_639-1::en]> + +definition + OBSERVATION[at0000] matches { -- Apgar score + data matches { + HISTORY[at0002] matches { -- history + events cardinality matches {1..*; unordered} matches { + POINT_EVENT[at0003] occurrences matches {0..1} matches { -- 1 minute + data matches { + ITEM_LIST[at0001] matches { -- structure + items cardinality matches {1..6; ordered} matches { + ELEMENT[at0005] occurrences matches {0..1} matches { -- Heart rate + value matches { + 0|[local::at0006], -- No heart beat + 1|[local::at0007], -- Less than 100 beats per minute + 2|[local::at0008] -- Greater than or equal to 100 beats per minute + } + } + } + } + } + } + POINT_EVENT[at0006] occurrences matches {0..1} matches { -- 2 minute + data matches { + use_node ITEM_LIST /data[at0002]/events[at0003]/data[at0099] + } + } + } + } + } + } + +ontology + terminologies_available = <"LNC205", ...> + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + description = <"Clinical score derived from assessment of breathing, colour, muscle tone, heart rate and reflex response usually taken at 1, 5 and 10 minutes after birth"> + text = <"Apgar score"> + > + ["at0001"] = < + description = <"@ internal @"> + text = <"structure"> + > + ["at0002"] = < + description = <"@ internal @"> + text = <"history"> + > + ["at0003"] = < + description = <"Apgar score at one minute from birth"> + text = <"1 minute"> + > + ["at0005"] = < + description = <"Assessment of heart function in the new born"> + text = <"Heart rate"> + > + ["at0006"] = < + description = <"No heart beat is present (palpation at base of umbilical cord)"> + text = <"No heart beat"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v5.adl b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v5.adl new file mode 100644 index 00000000..8f2b2118 --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v5.adl @@ -0,0 +1,70 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.internal_reference.v5 + +concept + [at0000] +language + original_language = <[ISO_639-1::en]> + +definition + OBSERVATION[at0000] matches { -- Apgar score + data matches { + HISTORY[at0002] matches { -- history + events cardinality matches {1..*; unordered} matches { + POINT_EVENT[at0003] occurrences matches {0..1} matches { -- 1 minute + data matches { + ITEM_LIST[at0001] matches { -- structure + items cardinality matches {1..6; ordered} matches { + ELEMENT[at0005] occurrences matches {0..1} matches { -- Heart rate + value matches { + 0|[local::at0006], -- No heart beat + 1|[local::at0007], -- Less than 100 beats per minute + 2|[local::at0008] -- Greater than or equal to 100 beats per minute + } + } + } + } + } + } + POINT_EVENT[at0006] occurrences matches {0..1} matches { -- 2 minute + data matches { + use_node UNKOWN_TYPE /data[at0002]/events[at0003]/data[at0001] + } + } + } + } + } + } + +ontology + terminologies_available = <"LNC205", ...> + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + description = <"Clinical score derived from assessment of breathing, colour, muscle tone, heart rate and reflex response usually taken at 1, 5 and 10 minutes after birth"> + text = <"Apgar score"> + > + ["at0001"] = < + description = <"@ internal @"> + text = <"structure"> + > + ["at0002"] = < + description = <"@ internal @"> + text = <"history"> + > + ["at0003"] = < + description = <"Apgar score at one minute from birth"> + text = <"1 minute"> + > + ["at0005"] = < + description = <"Assessment of heart function in the new born"> + text = <"Heart rate"> + > + ["at0006"] = < + description = <"No heart beat is present (palpation at base of umbilical cord)"> + text = <"No heart beat"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v6.adl b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v6.adl new file mode 100644 index 00000000..7fd76eb0 --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v6.adl @@ -0,0 +1,150 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.internal_reference.v6 + +concept + [at0000] -- Blood gas assessment +language + original_language = <[ISO_639-1::en]> + +description + original_author = < + ["name"] = <"Sam Heard"> + > + details = < + ["en"] = < + copyright = <"copyright (c) 2009 openEHR Foundation"> + language = <[ISO_639-1::en]> + purpose = <"For recording the arterial or venous blood gases and respiration products."> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"AuthorDraft"> + +definition + OBSERVATION[at0000] matches { -- Blood gas assessment + data matches { + HISTORY[at0002] matches { -- history + events cardinality matches {1..*; unordered} matches { + EVENT[at0003] occurrences matches {0..*} matches { -- Any event + data matches { + ITEM_TREE[at0001] matches { -- structure + items cardinality matches {0..*; ordered} matches { + CLUSTER[at0011] occurrences matches {0..1} matches { -- Arterial + items cardinality matches {1..8; ordered} matches { + ELEMENT[at0006] occurrences matches {0..1} matches { -- pH + value matches { + C_DV_QUANTITY < + property = <[openehr::119]> + list = < + ["1"] = < + units = <"[pH]"> + magnitude = <|0.0..14.0|> + > + > + > + } + } + } + } + CLUSTER[at0013] occurrences matches {0..1} matches { -- Venous + items cardinality matches {1..4; ordered} matches { + use_node ELEMENT /data[at0002]/events[at0003]/data[at0001]/items[at0011]/items[at0006] -- /data[history]/events[Any event]/data[structure]/items[Arterial]/items[pH] + } + } + } + } + } + state matches { + ITEM_LIST[at0009] matches { -- state structure + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0010] occurrences matches {0..1} matches { -- FiO2 + value matches { + C_DV_QUANTITY < + property = <[openehr::507]> + list = < + ["1"] = < + units = <"%"> + magnitude = <|0.0..100.0|> + precision = <|0|> + > + > + assumed_value = < + magnitude = <0.0> + units = <"%"> + precision = <0> + > + > + } + } + } + } + } + } + } + } + } + protocol matches { + ITEM_LIST[at0020] matches { -- List + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0021] occurrences matches {0..1} matches { -- Device + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Blood gas assessment"> + description = <"The assessment of blood gas concentrations and acid-base balance in blood"> + > + ["at0001"] = < + text = <"structure"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"history"> + description = <"@ internal @"> + > + ["at0003"] = < + text = <"Any event"> + description = <"*"> + > + ["at0006"] = < + text = <"pH"> + description = <"The negative logarithm of the Hydrogen ion concentration in blood"> + > + ["at0009"] = < + text = <"state structure"> + description = <"@ internal @"> + > + ["at0010"] = < + text = <"FiO2"> + description = <"The fractional concentration of inspired O2 - normally 21%"> + > + ["at0011"] = < + text = <"Arterial"> + description = <"Arterial readings"> + > + ["at0013"] = < + text = <"Venous"> + description = <"Venous readings"> + > + ["at0020"] = < + text = <"List"> + description = <"@ internal @"> + > + ["at0021"] = < + text = <"Device"> + description = <"The device used to measure the value"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.order1-order2-order3.v1.adl b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.order1-order2-order3.v1.adl new file mode 100644 index 00000000..85b30f69 --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.order1-order2-order3.v1.adl @@ -0,0 +1,112 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.order1-order2-order3.v1 +specialize + openEHR-EHR-OBSERVATION.order1-order2.v1 + +concept + [at0000.1.1] -- order3 +language + original_language = <[ISO_639-1::de]> +description + original_author = < + ["name"] = <"sg"> + > + details = < + ["de"] = < + language = <[ISO_639-1::de]> + purpose = <"none"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Initial"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"D7436FBED48E9D0106C55B398E634B93"> + > + +definition + OBSERVATION[at0000.1.1] matches { -- order3 + data matches { + HISTORY[at0001] matches { -- Event Series + events cardinality matches {1..*; unordered} matches { + EVENT[at0002] occurrences matches {0..1} matches { -- Jedes Ereignis + data matches { + ITEM_TREE[at0003] matches { -- Baum + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0004] occurrences matches {0..1} matches { -- Neues Element + value matches { + DV_TEXT matches {*} + } + } + CLUSTER[at0.5] occurrences matches {0..1} matches { -- Neues Cluster + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0.6] occurrences matches {0..1} matches { -- Neues Element + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0.0.7] occurrences matches {0..1} matches { -- Neues Element2 + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["de"] = < + items = < + ["at0.0.7"] = < + text = <"Neues Element2"> + description = <"*"> + > + ["at0.5"] = < + text = <"Neues Cluster"> + description = <"*"> + > + ["at0.6"] = < + text = <"Neues Element"> + description = <"*"> + > + ["at0000"] = < + text = <"order1"> + description = <"unknown"> + > + ["at0000.1"] = < + text = <"order2"> + description = <"unknown!"> + > + ["at0000.1.1"] = < + text = <"order3"> + description = <"unknown!!"> + > + ["at0001"] = < + text = <"Event Series"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Jedes Ereignis"> + description = <"*"> + > + ["at0003"] = < + text = <"Baum"> + description = <"@ internal @"> + > + ["at0004"] = < + text = <"Neues Element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.order1-order2-order3a.v1.adl b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.order1-order2-order3a.v1.adl new file mode 100644 index 00000000..012e732a --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.order1-order2-order3a.v1.adl @@ -0,0 +1,112 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.order1-order2-order3a.v1 +specialize + openEHR-EHR-OBSERVATION.order1-order2.v1 + +concept + [at0000.1.1] -- order3a +language + original_language = <[ISO_639-1::de]> +description + original_author = < + ["name"] = <"sg"> + > + details = < + ["de"] = < + language = <[ISO_639-1::de]> + purpose = <"none"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"Initial"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"D7436FBED48E9D0106C55B398E634B93"> + > + +definition + OBSERVATION[at0000.1.1] matches { -- order3a + data matches { + HISTORY[at0001] matches { -- Event Series + events cardinality matches {1..*; unordered} matches { + EVENT[at0002] occurrences matches {0..1} matches { -- Jedes Ereignis + data matches { + ITEM_TREE[at0003] matches { -- Baum + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0004] occurrences matches {0..1} matches { -- Neues Element + value matches { + DV_TEXT matches {*} + } + } + CLUSTER[at0.5] occurrences matches {0..1} matches { -- Neues Cluster + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0.6] occurrences matches {0..1} matches { -- Neues Element + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0.7] occurrences matches {0..1} matches { -- Neues Element2 + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["de"] = < + items = < + ["at0.7"] = < + text = <"Neues Element2"> + description = <"*"> + > + ["at0.5"] = < + text = <"Neues Cluster"> + description = <"*"> + > + ["at0.6"] = < + text = <"Neues Element"> + description = <"*"> + > + ["at0000"] = < + text = <"order1"> + description = <"unknown"> + > + ["at0000.1"] = < + text = <"order2"> + description = <"unknown!"> + > + ["at0000.1.1"] = < + text = <"order3a"> + description = <"unknown!!"> + > + ["at0001"] = < + text = <"Event Series"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Jedes Ereignis"> + description = <"*"> + > + ["at0003"] = < + text = <"Baum"> + description = <"@ internal @"> + > + ["at0004"] = < + text = <"Neues Element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.order1-order2.v1.adl b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.order1-order2.v1.adl new file mode 100644 index 00000000..6ad67dd0 --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.order1-order2.v1.adl @@ -0,0 +1,99 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.order1-order2.v1 +specialize + openEHR-EHR-OBSERVATION.order1.v1 + +concept + [at0000.1] -- order2 +language + original_language = <[ISO_639-1::de]> +description + original_author = < + ["name"] = <""> + > + details = < + ["de"] = < + language = <[ISO_639-1::de]> + purpose = <""> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"0"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"B2658F0CE882E4FB73F56C247DC40E02"> + > + +definition + OBSERVATION[at0000.1] matches { -- order2 + data matches { + HISTORY[at0001] matches { -- Event Series + events cardinality matches {1..*; unordered} matches { + EVENT[at0002] occurrences matches {0..1} matches { -- Jedes Ereignis + data matches { + ITEM_TREE[at0003] matches { -- Baum + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0004] occurrences matches {0..1} matches { -- Neues Element + value matches { + DV_TEXT matches {*} + } + } + CLUSTER[at0.5] occurrences matches {0..1} matches { -- Neues Cluster + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0.6] occurrences matches {0..1} matches { -- Neues Element + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["de"] = < + items = < + ["at0.5"] = < + text = <"Neues Cluster"> + description = <"*"> + > + ["at0.6"] = < + text = <"Neues Element"> + description = <"*"> + > + ["at0000"] = < + text = <"order1"> + description = <"unknown"> + > + ["at0000.1"] = < + text = <"order2"> + description = <"unknown!"> + > + ["at0001"] = < + text = <"Event Series"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Jedes Ereignis"> + description = <"*"> + > + ["at0003"] = < + text = <"Baum"> + description = <"@ internal @"> + > + ["at0004"] = < + text = <"Neues Element"> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v1.adl b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v1.adl new file mode 100644 index 00000000..8fce1be2 --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v1.adl @@ -0,0 +1,57 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.slot.v1 + +concept + [at0000] -- unknown +language + original_language = <[ISO_639-1::en]> + +definition + OBSERVATION[at0000] matches { -- unknown + data matches { + HISTORY[at0001] matches { -- Event Series + events cardinality matches {1..*; unordered} matches { + EVENT[at0002] occurrences matches {0..1} matches { -- Any event + data matches { + ITEM_TREE[at0003] matches { -- Tree + items cardinality matches {0..*; unordered} matches { + allow_archetype CLUSTER[at0004] occurrences matches {0..*} matches { -- correct Slot + include + archetype_id/value matches {/openEHR-EHR-CLUSTER\.balance\.v1|openEHR-EHR-CLUSTER\.change\.v233|openEHR-EHR-CLUSTER\.coordination(-[a-zA-Z0-9_]+)*\.v0/} + } + } + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"unknown"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Event Series"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Any event"> + description = <"*"> + > + ["at0003"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0004"] = < + text = <"correct Slot "> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v2.adl b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v2.adl new file mode 100644 index 00000000..150bd3df --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v2.adl @@ -0,0 +1,57 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.slot.v2 + +concept + [at0000] -- unknown +language + original_language = <[ISO_639-1::en]> + +definition + OBSERVATION[at0000] matches { -- unknown + data matches { + HISTORY[at0001] matches { -- Event Series + events cardinality matches {1..*; unordered} matches { + EVENT[at0002] occurrences matches {0..1} matches { -- Any event + data matches { + ITEM_TREE[at0003] matches { -- Tree + items cardinality matches {0..*; unordered} matches { + allow_archetype CLUSTER[at0004] occurrences matches {0..*} matches { -- incorrect Slot + include + archetype_id/value matches {/openEHR-EHR-CLUSTER\.balance\.v1draft|openEHREHR-CLUSTER\.change\.v1|openEHR-EHR-CLUSTERcoordination(-[a-zA-Z0-9_]+)*\.v1|openEHR-EHR-CLUSTER\.openEHR-EHR-CLUSTER.device\.v1/} + } + } + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"unknown"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Event Series"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Any event"> + description = <"*"> + > + ["at0003"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0004"] = < + text = <"correct Slot "> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v3.adl b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v3.adl new file mode 100644 index 00000000..af8e2e80 --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v3.adl @@ -0,0 +1,57 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.slot.v3 + +concept + [at0000] -- unknown +language + original_language = <[ISO_639-1::en]> + +definition + OBSERVATION[at0000] matches { -- unknown + data matches { + HISTORY[at0001] matches { -- Event Series + events cardinality matches {1..*; unordered} matches { + EVENT[at0002] occurrences matches {0..1} matches { -- Any event + data matches { + ITEM_TREE[at0003] matches { -- Tree + items cardinality matches {0..*; unordered} matches { + allow_archetype CLUSTER[at0004] occurrences matches {0..*} matches { + -- empty and * seems to be the same...therefore this a correct Slot based on Validity: any_allowed xor (includes /= Void or excludes /= Void) + + } + } + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"unknown"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Event Series"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Any event"> + description = <"*"> + > + ["at0003"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0004"] = < + text = <"correct Slot "> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v4.adl b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v4.adl new file mode 100644 index 00000000..3a36dbeb --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v4.adl @@ -0,0 +1,57 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.slot.v5 + +concept + [at0000] -- unknown +language + original_language = <[ISO_639-1::en]> + +definition + OBSERVATION[at0000] matches { -- unknown + data matches { + HISTORY[at0001] matches { -- Event Series + events cardinality matches {1..*; unordered} matches { + EVENT[at0002] occurrences matches {0..1} matches { -- Any event + data matches { + ITEM_TREE[at0003] matches { -- Tree + items cardinality matches {0..*; unordered} matches { + allow_archetype CLUSTER[at0004] occurrences matches {0..*} matches { + include + archetype_id/value matches {/openEHR-EHR-CLUSTER\.media_capture.*/} -- unfortunate because anything can come after capture, but it is possible to construct a valid id from this + } + } + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"unknown"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Event Series"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Any event"> + description = <"*"> + > + ["at0003"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0004"] = < + text = <"unfortunate but potentially valid Slot "> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v5.adl b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v5.adl new file mode 100644 index 00000000..a2d1ed15 --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v5.adl @@ -0,0 +1,57 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.slot.v5 + +concept + [at0000] -- unknown +language + original_language = <[ISO_639-1::en]> + +definition + OBSERVATION[at0000] matches { -- unknown + data matches { + HISTORY[at0001] matches { -- Event Series + events cardinality matches {1..*; unordered} matches { + EVENT[at0002] occurrences matches {0..1} matches { -- Any event + data matches { + ITEM_TREE[at0003] matches { -- Tree + items cardinality matches {0..*; unordered} matches { + allow_archetype CLUSTER[at0004] occurrences matches {0..*} matches { + include + archetype_id/value matches {/openEHR-EHR-CLUSTER\.media_capture*/} -- invalid - a version cannot be specified + } + } + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"unknown"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Event Series"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Any event"> + description = <"*"> + > + ["at0003"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0004"] = < + text = <"incorrect Slot "> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v6.adl b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v6.adl new file mode 100644 index 00000000..22551e07 --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v6.adl @@ -0,0 +1,67 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.slot.v6 + +concept + [at0000] -- unknown +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"Test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"To test a slot."> + > + > + lifecycle_state = <"in_development"> +definition + OBSERVATION[at0000] matches { -- unknown + data matches { + HISTORY[at0001] matches { -- Event Series + events cardinality matches {1..*; unordered} matches { + EVENT[at0002] occurrences matches {0..1} matches { -- Any event + data matches { + ITEM_TREE[at0003] matches { -- Tree + items cardinality matches {0..*; unordered} matches { + allow_archetype CLUSTER[at0004] occurrences matches {0..*} matches { + include + archetype_id/value matches {/openEHR-EHR-CLUSTER\.(anatomical_location|anatomical_location_circle)(-[a-zA-Z0-9_]+)*\.v1|openEHR-EHR-CLUSTER\.anatomical_location_relative(-[a-zA-Z0-9_]+)*\.v2/} -- complex wit h pipes, but valid. + } + } + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"unknown"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Event Series"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Any event"> + description = <"*"> + > + ["at0003"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0004"] = < + text = <"incorrect Slot "> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v7.adl b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v7.adl new file mode 100644 index 00000000..26cf4788 --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v7.adl @@ -0,0 +1,67 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.slot.v7 + +concept + [at0000] -- unknown +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"Test"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"To test a slot."> + > + > + lifecycle_state = <"in_development"> +definition + OBSERVATION[at0000] matches { -- unknown + data matches { + HISTORY[at0001] matches { -- Event Series + events cardinality matches {1..*; unordered} matches { + EVENT[at0002] occurrences matches {0..1} matches { -- Any event + data matches { + ITEM_TREE[at0003] matches { -- Tree + items cardinality matches {0..*; unordered} matches { + allow_archetype CLUSTER[at0004] occurrences matches {0..*} matches { + include + archetype_id/value matches {/openEHR-E)HR-CLUSTER\.(anatomical_location|anatomical_location_circle)(-[a-zA-Z0-9_]+)*\.v1|openEHR-EHR-CLUSTER\.anatomical_location_relative(-[a-zA-Z0-9_]+)*\.v2/} -- invalid regex due to the bracket. + } + } + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"unknown"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Event Series"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Any event"> + description = <"*"> + > + ["at0003"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0004"] = < + text = <"incorrect Slot "> + description = <"*"> + > + > + > + > diff --git a/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.type_name.v4.adl b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.type_name.v4.adl new file mode 100644 index 00000000..e80e480c --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.type_name.v4.adl @@ -0,0 +1,43 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.type_name.v4 + +concept + [at0000] -- type name test + +language + original_language = <[ISO_639-1::en]> + +definition + OBSERVATION[at0000] matches { -- + data matches { + HISTORY[at0002] matches { -- history + events cardinality matches {1..*; unordered} matches { + EVENT[at0003] matches {*} + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"type name test"> + description = <"test test"> + > + ["at0001"] = < + text = <"Single"> + description = <"*"> + > + ["at0002"] = < + text = <"history"> + description = <"@ internal @"> + > + ["at0003"] = < + text = <"Any event"> + description = <"Any event"> + > + > + > + > \ No newline at end of file diff --git a/archetype-validator/src/test/resources/openEHR-EHR-SECTION.testitemscardinality.v1.adl b/archetype-validator/src/test/resources/openEHR-EHR-SECTION.testitemscardinality.v1.adl new file mode 100644 index 00000000..0758e177 --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-SECTION.testitemscardinality.v1.adl @@ -0,0 +1,51 @@ +archetype (adl_version=1.4) + openEHR-EHR-SECTION.testitemscardinality.v1 + +concept + [at0000] -- Test items cardinality +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <""> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"test"> + use = <""> + misuse = <""> + copyright = <""> + > + > + lifecycle_state = <"Initial"> + other_contributors = <> + other_details = < + ["MD5-CAM-1.0.1"] = <"128F104BCE4BCD635A070BF1185FB184"> + > + +definition + SECTION[at0000] matches { -- Test items cardinality + items cardinality matches {0..*; unordered} matches { + allow_archetype SECTION[at0001] occurrences matches {0..*} matches { -- SECTION + include + archetype_id/value matches {/.*/} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Test items cardinality"> + description = <"test"> + > + ["at0001"] = < + text = <"SECTION"> + description = <"*"> + > + > + > + > diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index c81942cc..37822cb9 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -2,9 +2,9 @@ 4.0.0 - openehr - ref_impl_java - 1.0.5-SNAPSHOT + org.openehr.java-libs + java-libs + 0-SNAPSHOT dadl-binding jar @@ -19,48 +19,48 @@ - openehr + org.openehr.java-libs openehr-rm-core ${project.version} - openehr + org.openehr.java-libs openehr-aom ${project.version} - openehr + org.openehr.java-libs adl-parser ${project.version} - openehr + org.openehr.java-libs openehr-rm-domain ${project.version} - openehr + org.openehr.java-libs mini-termserv ${project.version} - openehr + org.openehr.java-libs measure-serv ${project.version} - openehr + org.openehr.java-libs rm-builder ${project.version} - openehr + org.openehr.java-libs dadl-parser ${project.version} diff --git a/dadl-binding/src/main/java/org/openehr/rm/binding/DADLBinding.java b/dadl-binding/src/main/java/org/openehr/rm/binding/DADLBinding.java index 025803ef..db2dba0c 100755 --- a/dadl-binding/src/main/java/org/openehr/rm/binding/DADLBinding.java +++ b/dadl-binding/src/main/java/org/openehr/rm/binding/DADLBinding.java @@ -140,8 +140,6 @@ Object bindPrimitiveBlock(PrimitiveObjectBlock block) } return list; } else if (block.getSimpleIntervalValue() != null) { - Interval values = block.getSimpleIntervalValue(); - // TODO return null; } else if (block.getTermCode() != null) { return block.getTermCode(); @@ -173,7 +171,6 @@ Object bindComplexBlock(ComplexObjectBlock block) } else { MultipleAttributeObjectBlock multiBlock = (MultipleAttributeObjectBlock) block; - String type = multiBlock.getTypeIdentifier(); List list = multiBlock.getKeyObjects(); // TODO assume list? List valueList = new ArrayList(); @@ -216,10 +213,9 @@ public List toDADL(Object obj, int indent, List lines) throws Ex String name = null; Object value = null; StringBuffer buf = null; - for(Iterator names = attributes.keySet().iterator(); names.hasNext();) { - name = names.next(); - - Attribute attribute = attributes.get(name); + for(Map.Entry entry : attributes.entrySet()) { + name = entry.getKey(); + Attribute attribute = entry.getValue(); if(attribute.system()) { continue; } diff --git a/dadl-binding/src/main/java/org/openehr/rm/binding/DADLBindingException.java b/dadl-binding/src/main/java/org/openehr/rm/binding/DADLBindingException.java old mode 100755 new mode 100644 diff --git a/dadl-binding/src/main/java/org/openehr/rm/binding/RMInspector.java b/dadl-binding/src/main/java/org/openehr/rm/binding/RMInspector.java index 84e72fa0..4707a8fd 100755 --- a/dadl-binding/src/main/java/org/openehr/rm/binding/RMInspector.java +++ b/dadl-binding/src/main/java/org/openehr/rm/binding/RMInspector.java @@ -6,7 +6,7 @@ import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; - +import org.openehr.build.RMObjectBuildingException; import org.openehr.rm.Attribute; import org.openehr.rm.FullConstructor; import org.openehr.rm.common.archetyped.Archetyped; @@ -184,8 +184,8 @@ private Map loadTypeMap() throws ClassNotFoundException { Organisation.class, Person.class, Contact.class, PartyRelationship.class, Role.class, Capability.class }; - typeMap = new HashMap(); - upperCaseMap = new HashMap(); + typeMap = new LinkedHashMap(); + upperCaseMap = new LinkedHashMap(); for (Class klass : classes) { String name = klass.getSimpleName(); typeMap.put(name, klass); @@ -315,10 +315,11 @@ public Map retrieveRMAttributes(String rmClassName) { Map map = attributeType(rmClass); Map ret = new HashMap(); - for(String name : map.keySet()) { - ret.put(toUnderscoreSeparated(name), map.get(name)); + for(Map.Entry entry : map.entrySet()) { + String name = entry.getKey(); + ret.put(toUnderscoreSeparated(name), entry.getValue()); - log.debug("rmattribute: " +name +": "+ map.get(name)); + log.debug("rmattribute: " +name +": "+ entry.getValue()); } return ret; } @@ -329,7 +330,6 @@ public Map retrieveRMAttributes(String rmClassName) { * * @param rmClassName * @return - * @throws RMObjectBuildingException */ public Set retrieveRMAttributeNames(String rmClassName) { Class rmClass = retrieveRMType(rmClassName); @@ -396,8 +396,8 @@ public String findMatchingRMClass(Map valueMap) { // replace underscore separated names with camel case Map filteredMap = new HashMap(); - for (String name : valueMap.keySet()) { - filteredMap.put(toCamelCase(name), valueMap.get(name)); + for (Map.Entry entry : valueMap.entrySet()) { + filteredMap.put(toCamelCase(entry.getKey()), entry.getValue()); } Constructor constructor = fullConstructor(rmClass); @@ -474,28 +474,6 @@ public String findMatchingRMClass(Map valueMap) { return null; } - // todo: isn't there any support from java api on this? - private Object defaultValue(Class type) { - if (type == boolean.class) { - return Boolean.FALSE; - } else if (type == double.class) { - return new Double(0); - } else if (type == float.class) { - return new Float(0); - } else if (type == int.class) { - return new Integer(0); - } else if (type == short.class) { - return new Short((short) 0); - } else if (type == long.class) { - return new Long(0); - } else if (type == char.class) { - return new Character((char) 0); - } else if (type == byte.class) { - return new Byte((byte) 0); - } - return null; - } - /* * Skipped types during matching: 1. Simple value types in DADL 2. Cluster * due to clash with ItemList diff --git a/dadl-binding/src/main/java/org/openehr/rm/binding/XPathUtil.java b/dadl-binding/src/main/java/org/openehr/rm/binding/XPathUtil.java index 50e512c9..567c03de 100755 --- a/dadl-binding/src/main/java/org/openehr/rm/binding/XPathUtil.java +++ b/dadl-binding/src/main/java/org/openehr/rm/binding/XPathUtil.java @@ -1,205 +1,200 @@ package org.openehr.rm.binding; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - import org.apache.log4j.Logger; import org.openehr.rm.Attribute; import org.openehr.rm.common.archetyped.Locatable; +import org.openehr.rm.composition.content.entry.Activity; +import org.openehr.rm.composition.content.entry.Entry; import org.openehr.rm.datastructure.itemstructure.representation.Element; +import java.lang.reflect.Method; +import java.util.*; + public class XPathUtil { public Set extractXPaths(Locatable root) throws Exception { - Set set = new HashSet(); - buildPath(root, "", set); - return set; + Set set = new HashSet(); + buildPath(root, "", set); + return set; } private void buildPath(Object obj, String path, Set paths) throws Exception { - if(obj instanceof List) { - List list = (List) obj; - for(int i = 0, j = list.size(); i attributeMap = inspector.attributeMap(klass); - for(String attributeName : attributeMap.keySet()) { - Attribute attribute = attributeMap.get(attributeName); - - if(attribute.system()) { - continue; - } - - Method method = klass.getMethod("get" + - attributeName.substring(0, 1).toUpperCase() + - attributeName.substring(1), null); - - assert(method != null); - - Object value = method.invoke(obj, null); - if(value != null) { - buildPath(value, path + "/" + attributeName, paths); - } - } - } + if(obj instanceof List) { + List list = (List) obj; + for(int i = 0, j = list.size(); i attributeMap = inspector.attributeMap(klass); + for(Map.Entry entry : attributeMap.entrySet()) { + String attributeName = entry.getKey(); + Attribute attribute = entry.getValue(); + + if(attribute.system()) { + continue; + } + + Method method = klass.getMethod("get" + + attributeName.substring(0, 1).toUpperCase() + + attributeName.substring(1), null); + + assert(method != null); + + Object value = method.invoke(obj, null); + if(value != null) { + buildPath(value, path + "/" + attributeName, paths); + } + } + } } public Map> extractPaths(Locatable root) throws Exception { - Map> map = new HashMap>(); - buildPaths(root, "", "", map); - return map; + Map> map = new HashMap>(); + buildPaths(root, "", "", map); + return map; } private void buildPaths(Object obj, String apath, String xpath, Map> paths) throws Exception { - //System.out.println("apath: " + apath + ", xpath: " + xpath - // + ", nodeId: " + (obj instanceof Locatable ? ((Locatable) obj).getArchetypeNodeId() : "")); - - if(obj instanceof List) { - List list = (List) obj; - for(int i = 0, j = list.size(); i set = paths.get(apath); + if(set == null) { + set = new HashSet(); + paths.put(apath, set); + } + set.add(xpath); - //System.out.println(">>> className: " + className); + } else if(obj instanceof Locatable) { - Map attributeMap = inspector.attributeMap(klass); - for(String attributeName : attributeMap.keySet()) { + Locatable locatable = (Locatable) obj; - //System.out.println("Attribute name: " + attributeName); + inspector.retrieveRMAttributes(obj.getClass().getSimpleName()); + Class klass = obj.getClass(); + Map attributeMap = inspector.attributeMap(klass); - Attribute attribute = attributeMap.get(attributeName); + for(Map.Entry entry : attributeMap.entrySet()) { + String attributeName = entry.getKey(); + Attribute attribute = entry.getValue(); - if(attribute.system()) { - continue; - } + if(attribute.system()) { + continue; + } - String methodName = "get" + - attributeName.substring(0, 1).toUpperCase() + - attributeName.substring(1); + String methodName = "get" + + attributeName.substring(0, 1).toUpperCase() + + attributeName.substring(1); - //System.out.println("method name: " + methodName); + Method method = klass.getMethod(methodName, null); - Method method = klass.getMethod(methodName, null); + assert(method != null); - assert(method != null); + Object value = method.invoke(obj, null); - Object value = method.invoke(obj, null); + if(value != null && !methodName.equals("getParent")) { - if(value != null && !methodName.equals("getParent")) { + String nodeIdStr = ""; + if (value instanceof Locatable){ + nodeIdStr = "[" + ((Locatable)value).getArchetypeNodeId() + "]"; + } + String currentAPath = apath + "/" + attributeName+nodeIdStr; + String currentXPath = xpath + "/" + attributeName; + buildPaths(value, currentAPath, currentXPath, paths); + } + } + } + } - //System.out.println("has value.."); - String nodeIdStr = ""; - if (value instanceof Locatable){ - nodeIdStr = "[" + ((Locatable)value).getArchetypeNodeId() + "]"; - } - String currentAPath = apath + "/" + attributeName+nodeIdStr; - String currentXPath = xpath + "/" + attributeName; - //System.out.println(methodName+"> "+currentAPath); - buildPaths(value, currentAPath, currentXPath, paths); - } - } - } else { - //System.out.println("---- skip class: " + obj.getClass().getSimpleName()); - } + private String getNodeId(Locatable loc, String nodeId) { + StringBuilder sb = new StringBuilder(); + sb.append(nodeId); + if (loc instanceof Entry){ + sb.append(" and name/value='" + loc.getName().getValue()+"'"); + } + return sb.toString(); } public Set extractRootXPaths(Locatable root) throws Exception { - Set set = new HashSet(); - buildRootPath(root, "", set); - return set; + Set set = new HashSet(); + buildRootPath(root, "", set); + return set; } private void buildRootPath(Object obj, String path, Set paths) throws Exception { - //System.out.println("class: " + obj.getClass().getSimpleName() + ", path: " + path); - - if(obj instanceof List) { - List list = (List) obj; - for(int i = 0, j = list.size(); i attributeMap = inspector.attributeMap(klass); - for(String attributeName : attributeMap.keySet()) { - Attribute attribute = attributeMap.get(attributeName); - - if(attribute.system()) { - continue; // skip system attributes - } - String getterName = "get"+ - attributeName.substring(0, 1).toUpperCase() + - attributeName.substring(1); - Method method = klass.getMethod(getterName, null); - - assert(method != null); - - Object value = method.invoke(obj, null); - if(value != null) { - buildRootPath(value, path + "/" + attributeName, paths); - } - } - } + if(obj instanceof List) { + List list = (List) obj; + for(int i = 0, j = list.size(); i attributeMap = inspector.attributeMap(klass); + for(Map.Entry entry : attributeMap.entrySet()) { + String attributeName = entry.getKey(); + Attribute attribute = entry.getValue(); + + if(attribute.system()) { + continue; // skip system attributes + } + String getterName = "get"+ + attributeName.substring(0, 1).toUpperCase() + + attributeName.substring(1); + Method method = klass.getMethod(getterName, null); + + assert(method != null); + + Object value = method.invoke(obj, null); + if(value != null) { + buildRootPath(value, path + "/" + attributeName, paths); + } + } + } } private RMInspector inspector = RMInspector.getInstance(); diff --git a/dadl-binding/src/test/java/org/openehr/rm/binding/BindRMToDADLTest.java b/dadl-binding/src/test/java/org/openehr/rm/binding/BindRMToDADLTest.java old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/java/org/openehr/rm/binding/DADLBindingTest.java b/dadl-binding/src/test/java/org/openehr/rm/binding/DADLBindingTest.java old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/java/org/openehr/rm/binding/DADLBindingTestBase.java b/dadl-binding/src/test/java/org/openehr/rm/binding/DADLBindingTestBase.java old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/java/org/openehr/rm/binding/DuplicatedCodesTest.java b/dadl-binding/src/test/java/org/openehr/rm/binding/DuplicatedCodesTest.java old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/java/org/openehr/rm/binding/LoadTest.java b/dadl-binding/src/test/java/org/openehr/rm/binding/LoadTest.java old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/java/org/openehr/rm/binding/XPathTest.java b/dadl-binding/src/test/java/org/openehr/rm/binding/XPathTest.java index 700570c8..7a9adca0 100755 --- a/dadl-binding/src/test/java/org/openehr/rm/binding/XPathTest.java +++ b/dadl-binding/src/test/java/org/openehr/rm/binding/XPathTest.java @@ -21,7 +21,7 @@ import org.openehr.rm.support.measurement.MeasurementService; public class XPathTest extends DADLBindingTestBase { - + public void testCreatePathMapWithOrderSet() throws Exception { Composition composition = (Composition) bind("order_set1.dadl"); assertEquals(3, composition.getContent().size()); @@ -34,7 +34,7 @@ public void testGetValue() throws Exception { assertEquals("LDL cholesterol", context.getValue("/items[2]/items[2]/name/value")); } - + public void testAttributeItemsExistsInCluster() throws Exception { RMInspector inspector = RMInspector.getInstance(); Map attributeMap = inspector.attributeMap(Cluster.class); @@ -73,7 +73,7 @@ public void testCreatePathMapWithDefaultTree() throws Exception { assertEquals(1, set.size()); assertEquals("/items[3]", set.toArray()[0]); } - + public void testCreatePathMapWithRepeatedCluster() throws Exception { ItemTree tree = createTreeWithRepeatedCluster(); XPathUtil util = new XPathUtil(); @@ -83,7 +83,7 @@ public void testCreatePathMapWithRepeatedCluster() throws Exception { // first element Set set = actual.get("/items[at0001]"); assertEquals(1, set.size()); - assertTrue(set.contains("/items[1]")); + assertTrue(set.contains("/items[1]")); // second element set = actual.get("/items[at0005]/items[at0002]"); @@ -106,7 +106,7 @@ public void testCreatePathMapWithRepeatedCluster() throws Exception { // fifth element set = actual.get("/items[at0006]"); assertEquals(1, set.size()); - assertTrue(set.contains("/items[4]")); + assertTrue(set.contains("/items[4]")); } public void testCreatePathMapWithRepeatedSampleElement() throws Exception { @@ -140,55 +140,55 @@ public void testCreatePathMapWithRepeatedSampleElement() throws Exception { // fifth element set = actual.get("/items[at0006]"); assertEquals(1, set.size()); - assertTrue(set.contains("/items[4]")); + assertTrue(set.contains("/items[4]")); } - + public void testExtratRootPathWithOneSlot() throws Exception { - ItemTree tree = (ItemTree) bind("tree_slot.dadl"); + ItemTree tree = (ItemTree) bind("tree_slot.dadl"); Set paths = new XPathUtil().extractRootXPaths(tree); assertEquals(1, paths.size()); - assertTrue(paths.contains("/items[4]")); + assertTrue(paths.contains("/items[4]")); } - + public void testExtratRootPathWithTwoSlots() throws Exception { - ItemTree tree = (ItemTree) bind("tree_2_slots.dadl"); + ItemTree tree = (ItemTree) bind("tree_2_slots.dadl"); Set paths = new XPathUtil().extractRootXPaths(tree); assertEquals(2, paths.size()); assertTrue(paths.contains("/items[4]")); assertTrue(paths.contains("/items[5]")); } - + public void testExtracRootPathWithNestedSlot() throws Exception { ItemTree tree = (ItemTree) bind("tree_nested_slot.dadl"); Set paths = new XPathUtil().extractRootXPaths(tree); assertEquals(1, paths.size()); assertTrue(paths.contains("/items[4]")); } - + public void testExtracRootPathWithDoubleNestedSlot() throws Exception { ItemTree tree = (ItemTree) bind("tree_nested_slot2.dadl"); Set paths = new XPathUtil().extractRootXPaths(tree); assertEquals(1, paths.size()); assertTrue(paths.contains("/items[4]")); } - + public void testCreatePathMapWithSlottedCluster() throws Exception { - ItemTree tree = (ItemTree) bind("tree_slot.dadl"); - + ItemTree tree = (ItemTree) bind("tree_slot.dadl"); + XPathUtil util = new XPathUtil(); - Map> actual = util.extractPaths(tree); - - assertEquals(8, actual.size()); + Map> actual = util.extractPaths(tree); + + assertEquals(8, actual.size()); // first element Set set = actual.get("/items[at0001]"); - + assertEquals(1, set.size()); assertTrue(set.contains("/items[1]")); // second element set = actual.get("/items[at0005]/items[at0002]"); - + assertEquals(1, set.size()); assertTrue(set.contains("/items[2]/items[1]")); @@ -205,41 +205,41 @@ public void testCreatePathMapWithSlottedCluster() throws Exception { // fifth element set = actual.get("/items[at0006]"); assertEquals(1, set.size()); - assertTrue(set.contains("/items[3]")); - + assertTrue(set.contains("/items[3]")); + // 6th element set = actual.get("/items[adl-test-CLUSTER.test_cluster.v1]/items[at0002]"); - + assertEquals(1, set.size()); assertTrue(set.contains("/items[4]/items[1]")); - + // 7th element set = actual.get("/items[adl-test-CLUSTER.test_cluster.v1]/items[at0003]"); assertEquals(1, set.size()); assertTrue(set.contains("/items[4]/items[2]")); - + // 8th element set = actual.get("/items[adl-test-CLUSTER.test_cluster.v1]/items[at0004]"); assertEquals(1, set.size()); assertTrue(set.contains("/items[4]/items[3]")); } - + public void testCreatePathMapWithNestedClusters() throws Exception { - ItemTree tree = (ItemTree) bind("tree_nested_slot3.dadl"); - + ItemTree tree = (ItemTree) bind("tree_nested_slot3.dadl"); + XPathUtil util = new XPathUtil(); Map> actual = util.extractPaths(tree); assertEquals(4, actual.size()); // first element Set set = actual.get("/items[at0001]"); - + assertEquals(1, set.size()); assertTrue(set.contains("/items[1]")); // second element set = actual.get("/items[at0005]/items[at0002]"); - + assertEquals(1, set.size()); assertTrue(set.contains("/items[2]/items[1]")); @@ -253,9 +253,9 @@ public void testCreatePathMapWithNestedClusters() throws Exception { assertEquals(1, set.size()); assertTrue(set.contains("/items[3]/items[2]/items[1]")); } - + public void testCreatePathMapDoubleNestedClusters() throws Exception { - ItemTree tree = (ItemTree) bind("tree_nested_slot4.dadl"); + ItemTree tree = (ItemTree) bind("tree_nested_slot4.dadl"); XPathUtil util = new XPathUtil(); Map> actual = util.extractPaths(tree); @@ -263,13 +263,13 @@ public void testCreatePathMapDoubleNestedClusters() throws Exception { // first element Set set = actual.get("/items[at0001]"); - + assertEquals(1, set.size()); assertTrue(set.contains("/items[1]")); // second element set = actual.get("/items[at0005]/items[at0002]"); - + assertEquals(1, set.size()); assertTrue(set.contains("/items[2]/items[1]")); @@ -285,9 +285,9 @@ public void testCreatePathMapDoubleNestedClusters() throws Exception { assertTrue(set.contains("/items[3]/items[2]/items[1]")); assertTrue(set.contains("/items[4]/items[2]/items[1]")); } - + public void testCreatePathMapWithTwoSlottedClusters() throws Exception { - ItemTree tree = createRootTreeWithTwoSlottedClusters(); + ItemTree tree = createRootTreeWithTwoSlottedClusters(); XPathUtil util = new XPathUtil(); Map> actual = util.extractPaths(tree); @@ -295,13 +295,13 @@ public void testCreatePathMapWithTwoSlottedClusters() throws Exception { // first element Set set = actual.get("/items[at0001]"); - + assertEquals(1, set.size()); assertTrue(set.contains("/items[1]")); // second element set = actual.get("/items[at0005]/items[at0002]"); - + assertEquals(1, set.size()); assertTrue(set.contains("/items[2]/items[1]")); @@ -318,21 +318,21 @@ public void testCreatePathMapWithTwoSlottedClusters() throws Exception { // fifth element set = actual.get("/items[at0006]"); assertEquals(1, set.size()); - assertTrue(set.contains("/items[3]")); - + assertTrue(set.contains("/items[3]")); + // 6th element set = actual.get("/items[adl-test-CLUSTER.test_cluster.v1]/items[at0002]"); - + assertEquals(2, set.size()); assertTrue(set.contains("/items[4]/items[1]")); assertTrue(set.contains("/items[5]/items[1]")); - + // 7th element set = actual.get("/items[adl-test-CLUSTER.test_cluster.v1]/items[at0003]"); assertEquals(2, set.size()); assertTrue(set.contains("/items[4]/items[2]")); assertTrue(set.contains("/items[5]/items[2]")); - + // 8th element set = actual.get("/items[adl-test-CLUSTER.test_cluster.v1]/items[at0004]"); assertEquals(2, set.size()); @@ -355,7 +355,7 @@ public void testExtractXPaths() throws Exception { assertTrue(actual.contains("/items[2]/items[3]")); assertTrue(actual.contains("/items[3]")); } - + // the nested structure shouldn't produce more xpath of elements public void testExtractXPathsWithNestedSlot() throws Exception { ItemTree tree = (ItemTree) bind("tree_nested_slot.dadl"); @@ -370,9 +370,9 @@ public void testExtractXPathsWithNestedSlot() throws Exception { } /** - * /sample - * /lipid studies/total cholesterol - * /lipid studies/ldl cholesterol + * /sample + * /lipid studies/total cholesterol + * /lipid studies/ldl cholesterol * /lipid studies/hdl cholesterol * /comment */ @@ -384,11 +384,11 @@ private ItemTree createTree() { return new ItemTree("at0007", new DvText("biochemstry result"), items); } - + /** - * /items[at0001, 'sample'] - * /items[at0005, 'lipid studies']/items[at0002, 'total cholesterol'] - * /items[at0005, 'lipid studies']/items[at0003, 'ldl cholesterol'] + * /items[at0001, 'sample'] + * /items[at0005, 'lipid studies']/items[at0002, 'total cholesterol'] + * /items[at0005, 'lipid studies']/items[at0003, 'ldl cholesterol'] * /items[at0005, 'lipid studies']/items[at0004, 'hdl cholesterol'] * /items[at0006, 'comment'] * /items[adl-test-CLUSTER.test_cluster.v1, 'test cluster']/items[at0002, 'element 1'] @@ -404,15 +404,15 @@ private ItemTree createRootTreeWithTwoSlottedClusters() throws Exception { items.add(slottedCluster()); String aid = "adl-test-ITEM_TREE.test_tree.v1"; Archetyped details = new Archetyped(aid, "1.0.1"); - ItemTree tree = new ItemTree(null, aid, + ItemTree tree = new ItemTree(null, aid, new DvText("biochemstry result"), details, null, null, null, items); - - writeDADL("tree_2_slots.dadl", tree); - + + writeDADL("tree_2_slots.dadl", tree); + return tree; } - - + + private void writeDADL(String name, Object obj) throws Exception { DADLBinding binding = new DADLBinding(); List lines = binding.toDADL(obj); @@ -420,17 +420,17 @@ private void writeDADL(String name, Object obj) throws Exception { } /** - * /sample - * /sample (repeated) - * /lipid studies/total cholesterol - * /lipid studies/ldl cholesterol + * /sample + * /sample (repeated) + * /lipid studies/total cholesterol + * /lipid studies/ldl cholesterol * /lipid studies/hdl cholesterol * /comment */ private ItemTree createTreeWithRepeatedElement() { Element comment = new Element("at0006", new DvText("comment"), new DvText( "high cardiac risk")); - + List items = new ArrayList(); items.add(sampleElement()); @@ -441,33 +441,33 @@ private ItemTree createTreeWithRepeatedElement() { return new ItemTree("at0007", new DvText("biochemstry result"), items); } - + private Element sampleElement() { return new Element("at0001", new DvText("sample"), new DvCodedText( "serum", new CodePhrase("terminology", "111"))); } - + private Element commentElement() { return new Element("at0006", new DvText("comment"), new DvText( "high cardiac risk")); } /** - * /sample - * /lipid studies/total cholesterol - * /lipid studies/ldl cholesterol + * /sample + * /lipid studies/total cholesterol + * /lipid studies/ldl cholesterol * /lipid studies/hdl cholesterol - * /lipid studies (repeated)/total cholesterol - * /lipid studies (repeated)/ldl cholesterol + * /lipid studies (repeated)/total cholesterol + * /lipid studies (repeated)/ldl cholesterol * /lipid studies (repeated)/hdl cholesterol * /comment */ private ItemTree createTreeWithRepeatedCluster() { ItemTree itemTree; - Element sample; + Element sample; Element comment; sample = new Element("at0001", new DvText("sample"), new DvCodedText( - "serum", new CodePhrase("terminology", "111"))); + "serum", new CodePhrase("terminology", "111"))); // comment comment = new Element("at0006", new DvText("comment"), new DvText( "high cardiac risk")); @@ -475,15 +475,15 @@ private ItemTree createTreeWithRepeatedCluster() { List items = new ArrayList(); items.add(sample); items.add(cluster()); - + // repeated cluster - items.add(cluster()); + items.add(cluster()); items.add(comment); itemTree = new ItemTree("at0007", new DvText("biochemstry result"), items); return itemTree; } - + private Cluster cluster() { Element totalCholesterol; Element ldlCholesterol; @@ -502,34 +502,34 @@ private Cluster cluster() { items.add(hdlCholesterol); return new Cluster("at0005", new DvText("lipid studies"), items); } - + private Cluster slottedCluster() { String archetypeId = "adl-test-CLUSTER.test_cluster.v1"; Element e1 = new Element("at0002", new DvText("element 1"), new DvText("element 1")); - Element e2 = new Element("at0003", + Element e2 = new Element("at0003", new DvText("element 2"), new DvText("element 2")); - Element e3 = new Element("at0004", + Element e3 = new Element("at0004", new DvText("element 3"), new DvText("element 3")); List items = new ArrayList(); items.add(e1); items.add(e2); - items.add(e3); + items.add(e3); Archetyped details = new Archetyped("adl-test-CLUSTER.test_cluster.v1", "1.0.1"); - Cluster cluster = new Cluster(null, archetypeId, + Cluster cluster = new Cluster(null, archetypeId, new DvText("test cluster"), details, null, null, null, items); - cluster.setOriginalArchetypeNodeId("at1025"); + cluster.setOriginalArchetypeNodeId("at1025"); return cluster; - } - + } + private static class TestMeasurementService implements MeasurementService { /* fields */ /** * Returns True if the units string according to the HL7 UCUM * specification. - * + * * @param units * @return true if units valid * @throws IllegalArgumentException @@ -542,7 +542,7 @@ public boolean isValidUnitsString(String units) { /** * Return True if two units strings correspond to the same measured * property. - * + * * @param units1 * @param units2 * @return true if two units equal @@ -555,7 +555,7 @@ public boolean unitsEquivalent(String units1, String units2) { /** * Return a new instance of test measurement service - * + * * @return */ public static MeasurementService getInstance() { diff --git a/dadl-binding/src/test/resources/adl-test-CLUSTER.test_cluster.v1.adl b/dadl-binding/src/test/resources/adl-test-CLUSTER.test_cluster.v1.adl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/adl-test-ITEM_TREE.test_tree.v1.adl b/dadl-binding/src/test/resources/adl-test-ITEM_TREE.test_tree.v1.adl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/archetyped.dadl b/dadl-binding/src/test/resources/archetyped.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/body_weight.dadl b/dadl-binding/src/test/resources/body_weight.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/code_phrase.dadl b/dadl-binding/src/test/resources/code_phrase.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/demographics.dadl b/dadl-binding/src/test/resources/demographics.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/duplicated_codes.dadl b/dadl-binding/src/test/resources/duplicated_codes.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/dv_coded_text.dadl b/dadl-binding/src/test/resources/dv_coded_text.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/dv_quantity.dadl b/dadl-binding/src/test/resources/dv_quantity.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/dv_text.dadl b/dadl-binding/src/test/resources/dv_text.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/element.dadl b/dadl-binding/src/test/resources/element.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/element_with_text.dadl b/dadl-binding/src/test/resources/element_with_text.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/empty_element_with_null_flavour.dadl b/dadl-binding/src/test/resources/empty_element_with_null_flavour.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/empty_item_list.dadl b/dadl-binding/src/test/resources/empty_item_list.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/history.dadl b/dadl-binding/src/test/resources/history.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/history2.dadl b/dadl-binding/src/test/resources/history2.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/item_list.dadl b/dadl-binding/src/test/resources/item_list.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/item_tree_bp.dadl b/dadl-binding/src/test/resources/item_tree_bp.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/item_tree_bp2.dadl b/dadl-binding/src/test/resources/item_tree_bp2.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/lab_test.dadl b/dadl-binding/src/test/resources/lab_test.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/log4j.properties b/dadl-binding/src/test/resources/log4j.properties index b67fb578..0b885667 100755 --- a/dadl-binding/src/test/resources/log4j.properties +++ b/dadl-binding/src/test/resources/log4j.properties @@ -1,5 +1,5 @@ # Set root logger level to DEBUG and its only appender to stdout. -log4j.rootLogger=WARN, stdout +log4j.rootLogger=stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout @@ -7,4 +7,4 @@ log4j.appender.stdout.layout.ConversionPattern=%-5p %c %x - %m%n # package logging level log4j.logger.org.openehr.build=ERROR -log4j.logger.org.openehr.binding=DEBUG \ No newline at end of file +log4j.logger.org.openehr.binding=ERROR \ No newline at end of file diff --git a/dadl-binding/src/test/resources/observation.dadl b/dadl-binding/src/test/resources/observation.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/observation2.dadl b/dadl-binding/src/test/resources/observation2.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/observation3.dadl b/dadl-binding/src/test/resources/observation3.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/order_set1.dadl b/dadl-binding/src/test/resources/order_set1.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/point_event.dadl b/dadl-binding/src/test/resources/point_event.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/point_event2.dadl b/dadl-binding/src/test/resources/point_event2.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/tree_2_slots.dadl b/dadl-binding/src/test/resources/tree_2_slots.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/tree_nested_slot.dadl b/dadl-binding/src/test/resources/tree_nested_slot.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/tree_nested_slot2.dadl b/dadl-binding/src/test/resources/tree_nested_slot2.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/tree_nested_slot3.dadl b/dadl-binding/src/test/resources/tree_nested_slot3.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/tree_nested_slot4.dadl b/dadl-binding/src/test/resources/tree_nested_slot4.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/tree_slot.dadl b/dadl-binding/src/test/resources/tree_slot.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/typed_archetype_id.dadl b/dadl-binding/src/test/resources/typed_archetype_id.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/typed_dv_boolean.dadl b/dadl-binding/src/test/resources/typed_dv_boolean.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/typed_dv_ordinal.dadl b/dadl-binding/src/test/resources/typed_dv_ordinal.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/typed_dv_quantity.dadl b/dadl-binding/src/test/resources/typed_dv_quantity.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/typed_dv_quantity2.dadl b/dadl-binding/src/test/resources/typed_dv_quantity2.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/typed_dv_text.dadl b/dadl-binding/src/test/resources/typed_dv_text.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/typed_party_self.dadl b/dadl-binding/src/test/resources/typed_party_self.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/typed_terminology_id.dadl b/dadl-binding/src/test/resources/typed_terminology_id.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/src/test/resources/weight.dadl b/dadl-binding/src/test/resources/weight.dadl old mode 100755 new mode 100644 diff --git a/dadl-binding/tree_2_slots.dadl b/dadl-binding/tree_2_slots.dadl deleted file mode 100755 index 1231ced5..00000000 --- a/dadl-binding/tree_2_slots.dadl +++ /dev/null @@ -1,164 +0,0 @@ -(ITEM_TREE) < - archetype_details = (ARCHETYPED) < - archetype_id = (ARCHETYPE_ID) < - value = <"adl-test-ITEM_TREE.test_tree.v1"> - > - rm_version = <"1.0.1"> - > - archetype_node_id = <"adl-test-ITEM_TREE.test_tree.v1"> - items = < - [1] = (ELEMENT) < - archetype_node_id = <"at0001"> - name = (DV_TEXT) < - value = <"sample"> - > - value = (DV_CODED_TEXT) < - defining_code = (CODE_PHRASE) < - code_string = <"111"> - terminology_id = (TERMINOLOGY_ID) < - value = <"terminology"> - > - > - value = <"serum"> - > - > - [2] = (CLUSTER) < - archetype_node_id = <"at0005"> - items = < - [1] = (ELEMENT) < - archetype_node_id = <"at0002"> - name = (DV_TEXT) < - value = <"total cholesterol"> - > - value = (DV_QUANTITY) < - accuracy = <0.0> - magnitude = <6.1> - precision = <0> - units = <"mmol/L"> - > - > - [2] = (ELEMENT) < - archetype_node_id = <"at0003"> - name = (DV_TEXT) < - value = <"LDL cholesterol"> - > - value = (DV_QUANTITY) < - accuracy = <0.0> - magnitude = <0.9> - precision = <0> - units = <"mmol/L"> - > - > - [3] = (ELEMENT) < - archetype_node_id = <"at0004"> - name = (DV_TEXT) < - value = <"HDL cholesterol"> - > - value = (DV_QUANTITY) < - accuracy = <0.0> - magnitude = <5.2> - precision = <0> - units = <"mmol/L"> - > - > - > - name = (DV_TEXT) < - value = <"lipid studies"> - > - > - [3] = (ELEMENT) < - archetype_node_id = <"at0006"> - name = (DV_TEXT) < - value = <"comment"> - > - value = (DV_TEXT) < - value = <"high cardiac risk"> - > - > - [4] = (CLUSTER) < - archetype_details = (ARCHETYPED) < - archetype_id = (ARCHETYPE_ID) < - value = <"adl-test-CLUSTER.test_cluster.v1"> - > - rm_version = <"1.0.1"> - > - archetype_node_id = <"adl-test-CLUSTER.test_cluster.v1"> - items = < - [1] = (ELEMENT) < - archetype_node_id = <"at0002"> - name = (DV_TEXT) < - value = <"element 1"> - > - value = (DV_TEXT) < - value = <"element 1"> - > - > - [2] = (ELEMENT) < - archetype_node_id = <"at0003"> - name = (DV_TEXT) < - value = <"element 2"> - > - value = (DV_TEXT) < - value = <"element 2"> - > - > - [3] = (ELEMENT) < - archetype_node_id = <"at0004"> - name = (DV_TEXT) < - value = <"element 3"> - > - value = (DV_TEXT) < - value = <"element 3"> - > - > - > - name = (DV_TEXT) < - value = <"test cluster"> - > - > - [5] = (CLUSTER) < - archetype_details = (ARCHETYPED) < - archetype_id = (ARCHETYPE_ID) < - value = <"adl-test-CLUSTER.test_cluster.v1"> - > - rm_version = <"1.0.1"> - > - archetype_node_id = <"adl-test-CLUSTER.test_cluster.v1"> - items = < - [1] = (ELEMENT) < - archetype_node_id = <"at0002"> - name = (DV_TEXT) < - value = <"element 1"> - > - value = (DV_TEXT) < - value = <"element 1"> - > - > - [2] = (ELEMENT) < - archetype_node_id = <"at0003"> - name = (DV_TEXT) < - value = <"element 2"> - > - value = (DV_TEXT) < - value = <"element 2"> - > - > - [3] = (ELEMENT) < - archetype_node_id = <"at0004"> - name = (DV_TEXT) < - value = <"element 3"> - > - value = (DV_TEXT) < - value = <"element 3"> - > - > - > - name = (DV_TEXT) < - value = <"test cluster"> - > - > - > - name = (DV_TEXT) < - value = <"biochemstry result"> - > -> diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 496f33f1..b49fdf4d 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -2,9 +2,9 @@ 4.0.0 - openehr - ref_impl_java - 1.0.5-SNAPSHOT + org.openehr.java-libs + java-libs + 0-SNAPSHOT dadl-parser jar @@ -66,7 +66,7 @@ - openehr + org.openehr.java-libs openehr-rm-core ${project.version} diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/AttributeValue.java b/dadl-parser/src/main/java/org/openehr/am/parser/AttributeValue.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/BooleanValue.java b/dadl-parser/src/main/java/org/openehr/am/parser/BooleanValue.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/CharacterValue.java b/dadl-parser/src/main/java/org/openehr/am/parser/CharacterValue.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/CodeValue.java b/dadl-parser/src/main/java/org/openehr/am/parser/CodeValue.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/ComplexObjectBlock.java b/dadl-parser/src/main/java/org/openehr/am/parser/ComplexObjectBlock.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/ContentObject.java b/dadl-parser/src/main/java/org/openehr/am/parser/ContentObject.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/DateTimeValue.java b/dadl-parser/src/main/java/org/openehr/am/parser/DateTimeValue.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/DateValue.java b/dadl-parser/src/main/java/org/openehr/am/parser/DateValue.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/DurationValue.java b/dadl-parser/src/main/java/org/openehr/am/parser/DurationValue.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/IntegerValue.java b/dadl-parser/src/main/java/org/openehr/am/parser/IntegerValue.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/KeyedObject.java b/dadl-parser/src/main/java/org/openehr/am/parser/KeyedObject.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/MultipleAttributeObjectBlock.java b/dadl-parser/src/main/java/org/openehr/am/parser/MultipleAttributeObjectBlock.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/ObjectBlock.java b/dadl-parser/src/main/java/org/openehr/am/parser/ObjectBlock.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/Parsed.java b/dadl-parser/src/main/java/org/openehr/am/parser/Parsed.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/PrimitiveObjectBlock.java b/dadl-parser/src/main/java/org/openehr/am/parser/PrimitiveObjectBlock.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/RealValue.java b/dadl-parser/src/main/java/org/openehr/am/parser/RealValue.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/SimpleValue.java b/dadl-parser/src/main/java/org/openehr/am/parser/SimpleValue.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/SingleAttributeObjectBlock.java b/dadl-parser/src/main/java/org/openehr/am/parser/SingleAttributeObjectBlock.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/StringValue.java b/dadl-parser/src/main/java/org/openehr/am/parser/StringValue.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/TimeValue.java b/dadl-parser/src/main/java/org/openehr/am/parser/TimeValue.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/java/org/openehr/am/parser/UriValue.java b/dadl-parser/src/main/java/org/openehr/am/parser/UriValue.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/main/javacc/dadl.jj b/dadl-parser/src/main/javacc/dadl.jj old mode 100755 new mode 100644 diff --git a/dadl-parser/src/test/java/org/openehr/am/parser/EmptyAttributeListBlockTest.java b/dadl-parser/src/test/java/org/openehr/am/parser/EmptyAttributeListBlockTest.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/test/java/org/openehr/am/parser/ItemListTest.java b/dadl-parser/src/test/java/org/openehr/am/parser/ItemListTest.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/test/java/org/openehr/am/parser/KeyedObjectTest.java b/dadl-parser/src/test/java/org/openehr/am/parser/KeyedObjectTest.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/test/java/org/openehr/am/parser/ParserTestBase.java b/dadl-parser/src/test/java/org/openehr/am/parser/ParserTestBase.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/test/java/org/openehr/am/parser/SimpleValuesTest.java b/dadl-parser/src/test/java/org/openehr/am/parser/SimpleValuesTest.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/test/java/org/openehr/am/parser/SingleValueListTest.java b/dadl-parser/src/test/java/org/openehr/am/parser/SingleValueListTest.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/test/java/org/openehr/am/parser/StructureTest.java b/dadl-parser/src/test/java/org/openehr/am/parser/StructureTest.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/test/java/org/openehr/am/parser/TypedObjectBlockTest.java b/dadl-parser/src/test/java/org/openehr/am/parser/TypedObjectBlockTest.java old mode 100755 new mode 100644 diff --git a/dadl-parser/src/test/resources/blood_pressure_001.dadl b/dadl-parser/src/test/resources/blood_pressure_001.dadl old mode 100755 new mode 100644 diff --git a/dadl-parser/src/test/resources/empty_attr_list.dadl b/dadl-parser/src/test/resources/empty_attr_list.dadl old mode 100755 new mode 100644 diff --git a/dadl-parser/src/test/resources/empty_attr_list_without_type.dadl b/dadl-parser/src/test/resources/empty_attr_list_without_type.dadl old mode 100755 new mode 100644 diff --git a/dadl-parser/src/test/resources/keyed_objects.dadl b/dadl-parser/src/test/resources/keyed_objects.dadl old mode 100755 new mode 100644 diff --git a/dadl-parser/src/test/resources/keyed_objects2.dadl b/dadl-parser/src/test/resources/keyed_objects2.dadl old mode 100755 new mode 100644 diff --git a/dadl-parser/src/test/resources/person_001.dadl b/dadl-parser/src/test/resources/person_001.dadl old mode 100755 new mode 100644 diff --git a/dadl-parser/src/test/resources/simple_values.dadl b/dadl-parser/src/test/resources/simple_values.dadl old mode 100755 new mode 100644 diff --git a/dadl-parser/src/test/resources/simple_values_list.dadl b/dadl-parser/src/test/resources/simple_values_list.dadl old mode 100755 new mode 100644 diff --git a/dadl-parser/src/test/resources/single_values_list.dadl b/dadl-parser/src/test/resources/single_values_list.dadl old mode 100755 new mode 100644 diff --git a/dadl-parser/src/test/resources/state_item_list.dadl b/dadl-parser/src/test/resources/state_item_list.dadl old mode 100755 new mode 100644 diff --git a/dadl-parser/src/test/resources/typed_dv_quantity.dadl b/dadl-parser/src/test/resources/typed_dv_quantity.dadl old mode 100755 new mode 100644 diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 2efaca6d..79573c53 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -2,9 +2,9 @@ 4.0.0 - openehr - ref_impl_java - 1.0.5-SNAPSHOT + org.openehr.java-libs + java-libs + 0-SNAPSHOT measure-serv jar diff --git a/measure-serv/readme.txt b/measure-serv/readme.txt old mode 100755 new mode 100644 diff --git a/measure-serv/src/main/java/org/openehr/rm/support/measurement/MeasurementService.java b/measure-serv/src/main/java/org/openehr/rm/support/measurement/MeasurementService.java index 4c8aea2a..ff616f08 100755 --- a/measure-serv/src/main/java/org/openehr/rm/support/measurement/MeasurementService.java +++ b/measure-serv/src/main/java/org/openehr/rm/support/measurement/MeasurementService.java @@ -33,7 +33,7 @@ public interface MeasurementService extends Serializable{ * @return true if units valid * @throws IllegalArgumentException if units null */ - public boolean isValidUnitsString(String units); + boolean isValidUnitsString(String units); /** * Return True if two units strings correspond to the same @@ -44,7 +44,7 @@ public interface MeasurementService extends Serializable{ * @return true if two units equal * @throws IllegalArgumentException if units1 or units2 null */ - public boolean unitsEquivalent(String units1, String units2); + boolean unitsEquivalent(String units1, String units2); /** * Return True if two units strings are comparable. @@ -54,7 +54,7 @@ public interface MeasurementService extends Serializable{ * @return true if two units comparable * @throws IllegalArgumentException if units1 or units2 null */ - public boolean unitsComparable(String units1, String units2); + boolean unitsComparable(String units1, String units2); /** * Comparison between two measures. @@ -66,7 +66,7 @@ public interface MeasurementService extends Serializable{ * quantity. * @throws IllegalArgumentException if units1, units2 null or not comparable */ - public int compare(String units1, Double value1, String units2, Double value2); + int compare(String units1, Double value1, String units2, Double value2); } /* * ***** BEGIN LICENSE BLOCK ***** diff --git a/measure-serv/src/main/java/org/openehr/rm/support/measurement/SimpleMeasurementService.java b/measure-serv/src/main/java/org/openehr/rm/support/measurement/SimpleMeasurementService.java old mode 100755 new mode 100644 index b93b9ce0..86578cfc --- a/measure-serv/src/main/java/org/openehr/rm/support/measurement/SimpleMeasurementService.java +++ b/measure-serv/src/main/java/org/openehr/rm/support/measurement/SimpleMeasurementService.java @@ -14,7 +14,12 @@ */ package org.openehr.rm.support.measurement; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + import javax.measure.Measure; +import javax.measure.converter.ConversionException; import javax.measure.unit.Unit; /** @@ -41,20 +46,111 @@ public static MeasurementService getInstance() { private SimpleMeasurementService() { } + + /** This is a list of commonly used UCUM codes in health care. + * Cp. e.g. http://www.hl7.de/download/documents/ucum/ucumdata.html + * and http://unitsofmeasure.org/ucum.html and http://unitsofmeasure.org/ucum-essence.xml + */ + private static Set commonUCUMCodes = new HashSet( Arrays.asList( + "%", "/uL", "[iU]/L", "10*3/uL", "10*6/uL", "fL", "g/dL", "g/L", "g/mL", "kPa", "m[iU]/mL", "meq/L", "mg/dL", "mm[Hg]", "mmol/kg", "mmol/L", "mosm/kg", "ng/mL", + "nmol/L", "pg", "pg/mL", "pmol/L", "U/L", "u[iU]/mL", "ug/dL", "ug/L", "ug/mL", "[lg]", "10*6/{Specimen}", "/{tot}", "10*3", "10*3.{RBC}", "10*5", "10*6", "10*8", "%", + "{Relative}%", "%{Total}", "%{0to3Hours}", "/10*10", "/10*6", "/10*9", "/10*12", "%{Normal}", "%{SpermMotility}", "%{Positive}", "%{FetalErythrocytes}", + "%{OfLymphocytes}", "%{ofBacteria}", "%{OfWBCs}", "%{Abnormal}", "%{EosSeen}", "%{Hemolysis}", "%{Blockade}", "%/100{WBC}", "%{Binding}", + "%{TotalProtein}", "%{Bound}", "%{Hemoglobin}", "%{HemoglobinSaturation}", "%{Carboxyhemoglobin}", "%{HemoglobinA1C}", "%{Excretion}", "%{Uptake}", "ug/ng", + "ng/mg", "ng/mg{Protein}", "ug/mg", "ug/mg{Cre}", "mg/mg", "mg/mg{Cre}", "ng/g", "ng/g{Cre}", "ug/g", "ug/[100]g", "ug/g{DryWeight}", "ug/g{Cre}", "ug/g{Hgb}", + "mg/g", "mg/g{Cre}", "g/g", "ng/kg", "ug/kg", "mg/kg", "g/kg", "g/[100]g", "g/g{Cre}", "pmol/umol", "nmol/mmol", "nmol/mmol{Cre}", "nmol/mol", "umol/mol", "mmol/mol", + "mmol/mol{Cre}", "umol/mol{Cre}", "eq/umol", "eq/mmol", "{BoneCollagen}eq/mmol{Cre}", "{BoneCollagen}eq/umol{Cre}", "%{vol}", "%{Oxygen}", "mL/dL", + "%{NormalPooledPlasma}", "%{Activity}", "%{BasalActivity}", "%{Inhibition}", "/{Entity}", "/100{WBC}", "/100", "/100{Spermatozoa}", "/10*12{rbc}", "deg", "/[arb`U]", + "u[iU]", "[iU]", "10*6.[iU]", "[in_i]", "[ft_i]", "[yd_i]", "[fth_i]", "[mi_i]", "[nmi_i]", "[Ch]", "fm", "pm", "nm", "um", "mm", "cm", "dm", "m", "km", "[gr]", "[oz_av]", "[oz_tr]", + "[lb_av]", "[ston_av]", "[dr_av]", "fg", "pg", "ng", "ug", "ug/{TotalVolume}", "ug/{Specimen}", "mg", "mg/{Volume}", "mg/{TotalVolume}", "g", "g/{TotalWeight}", "dg", "cg", + "kg", "t", "pg/mm", "K", "Cel", "[degF]", "K/W", "ps", "ns", "us", "ms", "s", "ks", "Ms", "min", "h", "d", "wk", "mo", "a", "eq", "ueq", "meq", "meq/{Specimen}", "mol", + "mmol", "mmol/{TotalVolume}", "fmol", "pmol", "umol", "nmol", "mosm", "meq/m2", "mmol/m2", "[sin_i]", "[sft_i]", "[syd_i]", "mm2", "cm2", "m2", "[foz_us]", "[cin_i]", + "[cup_us]", "[pt_us]", "[qt_us]", "[gal_us]", "[fdr_us]", "fL", "pL", "nL", "uL", "mL", "mL/{h`b}", "L", "dL", "cL", "kL", "hL", "L.s2/s", "/mg", "/g", "/g{creat}", "/g{HGB}", + "/g{tot`nit}", "/g{tot`prot}", "/g{wet`tis}", "/kg", "/kg{body`wt}", "fmol/mg", "nmol/mg", "umol/mg", "umol/mg{Cre}", "mol/kg", "fmol/g", "nmol/g", "nmol/g{Cre}", "umol/g", + "umol/g{Cre}", "umol/g{Hgb}", "mmol/g", "mmol/kg", "osm/kg", "mosm/kg", "meq/g", "meq/g{Cre}", "meq/kg", "[iU]/g", "[iU]/g{Hgb}", "{Ehrlich_U}/100g", "[iU]/kg", + "umol/min/g", "mU/g", "mU/g{Hgb}", "U/g", "U/g{Hgb}", "U/g{Cre}", "mU/mg{Cre}", "mU/mg", "kU/g", "kat/kg", "mL/kg", "L/kg", "kCal/[oz_av]", "/m2", "g/m2", "kg/m2", + "ug/m2", "mg/m2", "ng/m2", "g.m", "g.m/{hb}", "g.m/({hb}.m2)", "kg/mol", "/uL", "{Cells}/uL", "{rbc}/uL", "10*3/uL", "10*6/uL", "10*9/uL", "/mL", "{Spermatozoa}/mL", + "{Copies}/mL", "10*3/mL", "10*3{Copies}/mL", "10*6/mL", "10*9/mL", "{cfu}/mL", "/dL", "/L", "10*3/L", "10*6/L", "10*12/L", "10*9/L", "pg/mL", "ng/mL", "ng/mL{rbc}", + "ug/mL", "mg/mL", "g/mL", "pg/dL", "ng/dL", "ug/dL", "ug/dL{rbc}", "mg/dL", "mg{Phenylketones}/dL", "g/dL", "ng/L", "pg/L", "ug/L", "mg/L", "g/L", "kg/L", "mg/m3", + "kg/m3", "fmol/mL", "pmol/mL", "nmol/mL", "umol/mL", "mol/mL", "pmol/dL", "nmol/dL", "umol/dL", "mmol/dL", "mmol/L", "pmol/L", "nmol/L", "umol/L", "mol/L", + "mol/m3", "ueq/mL", "meq/mL", "eq/mL", "{AHG}eq/mL", "10*6.eq/mL", "ueq/L", "meq/L", "eq/L", "meq/dL", "mosm/L", "osm/L", "u[iU]/mL", "m[iU]/mL", + "{IgGPhospholipid}U/mL", "{IgMPhospholipid}U/mL", "{ComplementCh50}U/mL", "{IgAPhospholipid}U/mL", "{Elisa_U}/mL", "[iU]/mL", "k[iU]/mL", "[iU]/dL", + "{Ehrlich_U}/dL", "m[iU]/L", "[iU]/L", "[pH]", + + "osm", "/wk", "ml/wk", "mL/wk", "g/wk", "mg/wk", "B", "dB", "cm[H2O]", "mm[H20]", "10*6/mm3", "U", "mU", + + // both [iU] and [IU] are correct in case-sensitive UCUM variant + "[IU]/L","m[IU]/mL", "u[IU]/mL", "u[IU]", "[IU]", "10*6.[IU]", "[IU]/g", "[IU]/g{Hgb}", "[IU]/kg", "u[iU]/mL", "m[iU]/mL", "[iU]/mL", "k[iU]/mL", "[iU]/dL", "m[iU]/L", "[iU]/L", + + // We also need to add the lower-case variant for L because both l and L are valid for litre in the case-sensitive UCUM variant + "/ul", "[iU]/l", "10*3/ul", "10*6/ul", "fl", "g/dl", "g/l", "g/ml", "m[iU]/ml", "meq/l", "mg/dl", "mmol/l","ng/ml", + "nmol/l","pg/ml", "pmol/l", "U/l", "u[iU]/ml", "ug/dl", "ug/l", "ug/ml", "ml/dl", + "fl", "pl", "nl", "ul", "ml", "ml/{h`b}", "l", "dl", "cl", "kl", "hl", "l.s2/s", + "ml/kg", "l/kg", "/ul", "{Cells}/ul", "{rbc}/ul", "10*3/ul", "10*6/ul", "10*9/ul", "/ml", "{Spermatozoa}/ml", + "{Copies}/ml", "10*3/ml", "10*3{Copies}/ml", "10*6/ml", "10*9/ml", "{cfu}/ml", "/dl", "/l", "10*3/l", "10*6/l", "10*12/l", "10*9/l", "pg/ml", "ng/ml", "ng/ml{rbc}", + "ug/ml", "mg/ml", "g/ml", "pg/dl", "ng/dl", "ug/dl", "ug/dl{rbc}", "mg/dl", "mg{Phenylketones}/dl", "g/dl", "ng/l", "pg/l", "ug/l", "mg/l", "g/l", "kg/l", + "fmol/ml", "pmol/ml", "nmol/ml", "umol/ml", "mol/ml", "pmol/dl", "nmol/dl", "umol/dl", "mmol/dl", "mmol/l", "pmol/l", "nmol/l", "umol/l", "mol/l", + "ueq/ml", "meq/ml", "eq/ml", "{AHG}eq/ml", "10*6.eq/ml", "ueq/l", "meq/l", "eq/l", "meq/dl", "mosm/l", "osm/l", "u[iU]/ml", "m[iU]/ml", + "{IgGPhospholipid}U/ml", "{IgMPhospholipid}U/ml", "{ComplementCh50}U/ml", "{IgAPhospholipid}U/ml", "{Elisa_U}/ml", "[iU]/ml", "k[iU]/ml", "[iU]/dl", + "{Ehrlich_U}/dl", "m[iU]/l", "[iU]/l", + "1/wk", "[oz_av]/wk" + + + )); /** * Returns True if the units string according to * the HL7 UCUM specification. + * Note that this implementation currently assumes case-sensitive UCUM format. * * @param units * @return true if units valid * @throws IllegalArgumentException if units null */ public boolean isValidUnitsString(String units) { - if(units == null) { - throw new IllegalArgumentException("units null"); - } - // TODO fix it - return true; + if(units == null) { + throw new IllegalArgumentException("units null"); + } + + SimpleUCUMValidator ucumVal = new SimpleUCUMValidator(); + if (ucumVal.isValidUnitsString(units)) { + return true; + } else { + return false; + } + + // Unfortunately the UCUM support in the library javax.measure.unit uses a very outdated version of UCUM. + // E.g. mm[Hg], osm, eq are missing in there. Therefore we first check if the unit is a UCUM unit commonly used in health care. +/* if (commonUCUMCodes.contains(units)) { + return true; + } + + // Only if it is not in this list, we continue to check with the provided library if the UCUM unit can be constructed. + Unit unit = null; + try { + // This is equivalent to this UCUMFormat.getCaseSensitiveInstance().parseObject(units, new ParsePosition(0)); + // That means it is the case-sensitive variant of UCUM that is used here. + unit = Unit.valueOf(units); + } catch(java.lang.IllegalArgumentException e) { + + } + */ + // If we want to support the case-insensitive UCUM variant as well, we can do so via this: + // Unit unitCI = UCUMFormat.getCaseInsensitiveInstance().parseObject(units, new ParsePosition(0)); + + + /* System.out.println("==============================="); + if (unit != null) { + System.out.println("Unit parsed CS: "+units +"->"+UCUMFormat.getCaseSensitiveInstance().format(unit)); + } else { + System.out.println("Unit NOT parsed CS: "+ units); + } + if (unitCI != null){ + System.out.println("Unit parsed CI: "+units +"->"+UCUMFormat.getCaseInsensitiveInstance().format(unitCI)); + } else { + System.out.println("Unit NOT parsed CI: "+ units); + } +*/ + // return unit!= null; } /** @@ -71,9 +167,27 @@ public boolean unitsEquivalent(String units1, String units2) { throw new IllegalArgumentException("units1 null"); } if(units2 == null) { - throw new IllegalArgumentException("units2 null"); + throw new IllegalArgumentException("units2 null"); } - return units1.equalsIgnoreCase(units2); + if (units1.equals(units2)) { + return true; + } + + // SG: Not too sure that this is actually correct... + // a) For case-sensitive UCUM, mg and Mg are quite different, but would be accepted as the same (milli vs. mega) + // Also, the upper-case G in the case-sensitive UCUM refers to Gauss' constant + // b) Would a unit be equivalent if they are formally the same, e.g A[mpere] = C[oulomb]/s[econd] are formally equivalent + Unit unit1 = Unit.valueOf(units1); + Unit unit2 = Unit.valueOf(units2); + try { + return (unit1.getConverterToAny(unit2).convert(1) ==1); + } catch (UnsupportedOperationException e) { + return false; + } catch (ConversionException e) { + // Units not even compatible + return false; + } +// return units1.equalsIgnoreCase(units2); } /** @@ -117,7 +231,8 @@ public int compare(String units1, Double value1, String units2, Double value2) { }else{ Unit unit1 = Unit.valueOf(units1); Unit unit2 = Unit.valueOf(units2); - if (!unit1.isCompatible(unit2)){ + + if (!unit1.isCompatible(unit2)){ throw new IllegalArgumentException("units '"+units1+"' is not comparable to '"+units2+"'"); } Measure measure1 = Measure.valueOf(value1, unit1); diff --git a/measure-serv/src/main/java/org/openehr/rm/support/measurement/SimpleUCUMValidator.java b/measure-serv/src/main/java/org/openehr/rm/support/measurement/SimpleUCUMValidator.java new file mode 100644 index 00000000..eeea73c9 --- /dev/null +++ b/measure-serv/src/main/java/org/openehr/rm/support/measurement/SimpleUCUMValidator.java @@ -0,0 +1,207 @@ +package org.openehr.rm.support.measurement; + +import java.nio.charset.Charset; +import java.nio.charset.CharsetEncoder; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** This is a very simple UCUM validator to validate if a given units string is a valid UCUM unit. + * It may not consider all edge cases, although it passes many test cases, including those provided by UCUM. + * See http://unitsofmeasure.org/ucum.html + * @author Sebastian Garde + * + */ +public class SimpleUCUMValidator { + + // These can be easily extracted from the ucum-esence.xml file provided by UCUM (or directly read from the xml file) + public static final String[] ATOMSYMBOL_VALUES = new String[] { + "m", "s", "g", "rad", "K", "C", "cd", "10*", "10^", "[pi]", "%", "[ppth]", "[ppm]", "[ppb]", "[pptr]", "mol", "sr", "Hz", "N", "Pa", + "J", "W", "A", "V", "F", "Ohm", "S", "Wb", "Cel", "T", "H", "lm", "lx", "Bq", "Gy", "Sv", "gon", "deg", "'", "''", "l", "L", "ar", + "min", "h", "d", "a_t", "a_j", "a_g", "a", "wk", "mo_s", "mo_j", "mo_g", "mo", "t", "bar", "u", "eV", "AU", "pc", "[c]", "[h]", + "[k]", "[eps_0]", "[mu_0]", "[e]", "[m_e]", "[m_p]", "[G]", "[g]", "atm", "[ly]", "gf", "[lbf_av]", "Ky", "Gal", "dyn", "erg", "P", + "Bi", "St", "Mx", "G", "Oe", "Gb", "sb", "Lmb", "ph", "Ci", "R", "RAD", "REM", "[in_i]", "[ft_i]", "[yd_i]", "[mi_i]", "[fth_i]", + "[nmi_i]", "[kn_i]", "[sin_i]", "[sft_i]", "[syd_i]", "[cin_i]", "[cft_i]", "[cyd_i]", "[bf_i]", "[cr_i]", "[mil_i]", "[cml_i]", "[hd_i]", + "[ft_us]", "[yd_us]", "[in_us]", "[rd_us]", "[ch_us]", "[lk_us]", "[rch_us]", "[rlk_us]", "[fth_us]", "[fur_us]", "[mi_us]", + "[acr_us]", "[srd_us]", "[smi_us]", "[sct]", "[twp]", "[mil_us]", "[in_br]", "[ft_br]", "[rd_br]", "[ch_br]", "[lk_br]", "[fth_br]", + "[pc_br]", "[yd_br]", "[mi_br]", "[nmi_br]", "[kn_br]", "[acr_br]", "[gal_us]", "[bbl_us]", "[qt_us]", "[pt_us]", "[gil_us]", + "[foz_us]", "[fdr_us]", "[min_us]", "[crd_us]", "[bu_us]", "[gal_wi]", "[pk_us]", "[dqt_us]", "[dpt_us]", "[tbs_us]", "[tsp_us]", + "[cup_us]", "[foz_m]", "[cup_m]", "[tsp_m]", "[tbs_m]", "[gal_br]", "[pk_br]", "[bu_br]", "[qt_br]", "[pt_br]", "[gil_br]", + "[foz_br]", "[fdr_br]", "[min_br]", "[gr]", "[lb_av]", "[oz_av]", "[dr_av]", "[scwt_av]", "[lcwt_av]", "[ston_av]", "[lton_av]", + "[stone_av]", "[pwt_tr]", "[oz_tr]", "[lb_tr]", "[sc_ap]", "[dr_ap]", "[oz_ap]", "[lb_ap]", "[oz_m]", "[lne]", "[pnt]", "[pca]", + "[pnt_pr]", "[pca_pr]", "[pied]", "[pouce]", "[ligne]", "[didot]", "[cicero]", "[degF]", "[degR]", "[degRe]", "cal_[15]", + "cal_[20]", "cal_m", "cal_IT", "cal_th", "cal", "[Cal]", "[Btu_39]", "[Btu_59]", "[Btu_60]", "[Btu_m]", "[Btu_IT]", "[Btu_th]", + "[Btu]", "[HP]", "tex", "[den]", "m[H2O]", "m[Hg]", "[in_i'H2O]", "[in_i'Hg]", "[PRU]", "[wood'U]", "[diop]", "[p'diop]", + "%[slope]", "[mesh_i]", "[Ch]", "[drp]", "[hnsf'U]", "[MET]", "[hp'_X]", "[hp'_C]", "[hp'_M]", "[hp'_Q]", "[hp_X]", "[hp_C]", + "[hp_M]", "[hp_Q]", "[kp_X]", "[kp_C]", "[kp_M]", "[kp_Q]", "eq", "osm", "[pH]", "g%", "[S]", "[HPF]", "[LPF]", "kat", "U", + "[iU]", "[IU]", "[arb'U]", "[USP'U]", "[GPL'U]", "[MPL'U]", "[APL'U]", "[beth'U]", "[anti'Xa'U]", "[todd'U]", "[dye'U]", + "[smgy'U]", "[bdsk'U]", "[ka'U]", "[knk'U]", "[mclg'U]", "[tb'U]", "[CCID_50]", "[TCID_50]", "[EID_50]", "[PFU]", "[FFU]", + "[CFU]", "[IR]", "[BAU]", "[AU]", "[Amb'a'1'U]", "[PNU]", "[Lf]", "[D'ag'U]", "[FEU]", "[ELU]", "[EU]", "Np", "B", "B[SPL]", + "B[V]", "B[mV]", "B[uV]", "B[10.nV]", "B[W]", "B[kW]", "st", "Ao", "b", "att", "mho", "[psi]", "circ", "sph", "[car_m]", + "[car_Au]", "[smoot]", "[m/s2/Hz^(1/2)]", "bit_s", "bit", "By", "Bd" }; + + public static final Set ATOMSYMBOL_SET = new HashSet(Arrays.asList(ATOMSYMBOL_VALUES)); + + public static final String[] PREFIX_VALUES = new String[] { "Y", "Z", "E", "P", "T", "G", "M", "k", "h", "da", "d", "c", "m", "u", "n", "p", "f", "a", "z", "y", "Gi", "Mi", "Gi", "Ti"}; + public static final Set PREFIX_SET = new HashSet(Arrays.asList(PREFIX_VALUES)); + + + public SimpleUCUMValidator() { + + } + + public boolean isValidUnitsString(String units) { + // System.out.print("Unit to test: "+ units + " .... "); + boolean isValid = isMainTerm(units); + // System.out.println(isValid ? "Valid" : " NOT VALID"); + return isValid; + } + + private boolean isMainTerm(String units) { + return units.length()==0 || // empty units is allowed according to the official UCUM test cases (however currently prevented in the specs) + units.equals(" ") || // This is one case where we currently tolerate a unit that only consists of exactly one space (to circumvent the specs constraints that units must not be empty) + isTerm(units) || + (units.startsWith("/") && isTerm(units.substring(1))); + } + + private boolean isTerm(String units) { + + boolean roundBracketsOk = checkRoundBrackets(units); // check for basic consistency, then remove. + if (!roundBracketsOk) { + return false; + } + + // After the basic checks above we cannot properly handle the ( ) constructs in the following. + units = units.replace("(", "").replace(")", ""); + + if (units.startsWith(("/"))) { + units= units.substring(1); // e.g. "/min" is allowed + } + if (units.endsWith("/") || units.endsWith(".") || units.endsWith("/)") || units.endsWith(".)")) { + return false; // min/ or min. are not valid + } + String[] components = units.split("/|\\."); // either / or . + + for (String component : components) { + if (!isComponent(component)) { + return false; + } + } + return true; + } + + private boolean checkRoundBrackets(String units) { + String unitsT = units; + int openingBrackets = unitsT.startsWith("(") ? 1:0; // first letter not considered in forst loop below + int closingBrackets = unitsT.endsWith(")") ? 1:0; // last letter not considered in second loop below + for (int i=1; i + if (component.endsWith("}") && component.indexOf("{") >0) { // = ends with annotation + // check if beginning is an "annotatable" + isComponent = isAnnotatable(component.substring(0, component.indexOf("{"))) && + isAnnotation(component.substring(component.indexOf("{"))); // Required because of ASCII-only check + } + } + + return isComponent; + } + + private boolean isFactor(String component) { + try { + Integer.parseInt(component); + } catch (NumberFormatException e) { + return false; + } + return true; + } + + private boolean isAnnotation(String component) { + //System.out.print("Annotation: "+component); + boolean isAnnotation = component.startsWith("{") && component.endsWith("}") && isPureAscii(component.substring(1, component.length()-1)); + + if (isAnnotation) { + String compExclCurly = component.substring(1, component.length()-1); + isAnnotation = !compExclCurly.contains("{") && !compExclCurly.contains("}"); // cannot have curtly braces in the annotation - this prevents e.g. {a}rad2{b} to be seen as valid + } + return isAnnotation; + } + + private boolean isAnnotatable(String component) { + if (component.equals("1")) { + return true; // It is not quite clear why e.g. 1{c} is supported but the 1 seems to be somewhat treated as a unit. + } + + // Other than that: simple-unit + exponent or simple-unit + + //must first check if it ends with an exponent = (optional sign + digits) + if (component.length() >0) { + boolean hadDigit=false; + while (component.length() >0 && isDigit(component.substring(component.length()-1))) { + component = component.substring(0, component.length()-1); + hadDigit=true; + } + if (hadDigit && component.length() >0 && isSign(component.substring(component.length()-1))) { + component = component.substring(0, component.length()-1); + } + } + // We removed the exponent including the sign, if present, now it must be a simple unit if valid. + return isSimpleUnit(component); + } + + boolean isSign(String str) { + return str.equals("+") || str.equals("-"); + } + + boolean isDigit(String str) { + return isFactor(str); + } + + private boolean isSimpleUnit(String component) { + //System.out.println("isSimpleUnit: " +"___"+ component+"___"); + return isAtomSymbol(component) || + (component.length() >=1 && isPrefixSymbol(component.substring(0,1)) && isAtomSymbol(component.substring(1))) || // prefix with one character + (component.length()>=2 && isPrefixSymbol(component.substring(0,2)) && isAtomSymbol(component.substring(2))); // prefix with two characters + } + + private boolean isAtomSymbol(String component) { + return ATOMSYMBOL_SET.contains(component); + } + + private boolean isPrefixSymbol(String ch) { + return PREFIX_SET.contains(ch); + } + + static CharsetEncoder asciiEncoder = Charset.forName("US-ASCII").newEncoder(); // or "ISO-8859-1" for ISO Latin 1 + private boolean isPureAscii(String v) { + return asciiEncoder.canEncode(v); + } + +} diff --git a/measure-serv/src/test/java/org/openehr/rm/support/measurement/SimpleMeasurementServiceTest.java b/measure-serv/src/test/java/org/openehr/rm/support/measurement/SimpleMeasurementServiceTest.java old mode 100755 new mode 100644 index c5dcf1c8..c9a27940 --- a/measure-serv/src/test/java/org/openehr/rm/support/measurement/SimpleMeasurementServiceTest.java +++ b/measure-serv/src/test/java/org/openehr/rm/support/measurement/SimpleMeasurementServiceTest.java @@ -4,27 +4,616 @@ public class SimpleMeasurementServiceTest extends TestCase { + @Override public void setUp() { - service = SimpleMeasurementService.getInstance(); + service = SimpleMeasurementService.getInstance(); } public void testunitsEquivalent() throws Exception { - assertTrue(service.unitsEquivalent("mg", "MG")); - assertFalse(service.unitsEquivalent("mg", "kg")); + //assertTrue(service.unitsEquivalent("mg", "MG")); + assertFalse(service.unitsEquivalent("mg", "MG")); + assertFalse(service.unitsEquivalent("mg", "mG")); + assertTrue(service.unitsEquivalent("A", "C/s")); + + assertFalse(service.unitsEquivalent("mg", "kg")); } public void testunitsComparable() throws Exception { - assertTrue(service.unitsComparable("mg", "kg")); - assertFalse(service.unitsComparable("mg", "ml")); - assertTrue(service.unitsComparable("cm", "[in_i]")); + assertTrue(service.unitsComparable("mg", "kg")); + assertFalse(service.unitsComparable("mg", "ml")); + assertTrue(service.unitsComparable("cm", "[in_i]")); } public void testunitsComparison() throws Exception { - assertTrue(service.compare("kg", 1.0, "g", 1000.0)==0); - assertTrue(service.compare("l", 1.0, "ml", 100.0)>0); - assertTrue(service.compare("[in_i]", 2.0, "cm", 5.0)>0); - assertFalse(service.compare("[in_i]", 1000.0, "m", 26.0)>0); + assertTrue(service.compare("kg", 1.0, "g", 1000.0)==0); + assertTrue(service.compare("l", 1.0, "ml", 100.0)>0); + assertTrue(service.compare("[in_i]", 2.0, "cm", 5.0)>0); + assertFalse(service.compare("[in_i]", 1000.0, "m", 26.0)>0); + } + + public void testunitsValid() throws Exception { + assertTrue(service.isValidUnitsString("mg")); + assertTrue(service.isValidUnitsString("osm")); + assertTrue(service.isValidUnitsString("mm[Hg]")); + assertTrue(service.isValidUnitsString("ug")); + assertTrue(service.isValidUnitsString("ug/L")); + assertTrue(service.isValidUnitsString("ug/l")); + assertTrue(service.isValidUnitsString("km/h")); + assertTrue(service.isValidUnitsString("[iU]")); + assertTrue(service.isValidUnitsString("[IU]")); + assertTrue(service.isValidUnitsString("a")); // year + + assertTrue(service.isValidUnitsString("wk")); + assertTrue(service.isValidUnitsString("1/wk")); + assertTrue(service.isValidUnitsString("/wk")); + assertTrue(service.isValidUnitsString("[oz_av]/wk")); + + assertTrue(service.isValidUnitsString("eq")); + assertFalse(service.isValidUnitsString("Eq")); + + assertFalse(service.isValidUnitsString("osmole")); + assertFalse(service.isValidUnitsString("iU")); + assertFalse(service.isValidUnitsString("yr")); // year is "a" + assertFalse(service.isValidUnitsString("milligm")); + assertFalse(service.isValidUnitsString("mgm")); + + // White space is not recognized in a a unit term and should generally not occur. + // UCUM implementations may flag whitespace as an error rather than ignore it. + // Whitespace is not used as a separator of otherwise ambiguous parts of a unit term. + //assertFalse(service.isValidUnitsString(" ")); exactly one space is tolerated at the moment, because the openEHR specs prohibit it to be completely empty. + assertFalse(service.isValidUnitsString(" m")); + assertFalse(service.isValidUnitsString("m ")); + assertFalse(service.isValidUnitsString("10*3/ ul")); + assertFalse(service.isValidUnitsString("10* 3/ul")); + assertFalse(service.isValidUnitsString("10 *3/ul")); + assertFalse(service.isValidUnitsString("rad2 {a}")); + assertFalse(service.isValidUnitsString("rad 2{a}")); + + // Official UCUM tests: + + assertTrue(service.isValidUnitsString("m")); + assertFalse(service.isValidUnitsString("m/")); // / is not followed by a term + + //assertFalse(service.isValidUnitsString("")); strictly, "" is not a valid unit expression. But e.g. v3 data types say it is the default to use if not units are provided. + + assertTrue(service.isValidUnitsString("/m")); + assertTrue(service.isValidUnitsString("10*3/ul")); + assertTrue(service.isValidUnitsString("10*-3/ul")); + assertTrue(service.isValidUnitsString("10*+3/ul")); + assertFalse(service.isValidUnitsString("10+3/ul")); // 10 is not a valid unit + assertTrue(service.isValidUnitsString("m")); + assertTrue(service.isValidUnitsString("m[H2O]")); + assertTrue(service.isValidUnitsString("10*23")); + assertTrue(service.isValidUnitsString("rad2")); + assertTrue(service.isValidUnitsString("m3.kg-1.s-2")); + assertTrue(service.isValidUnitsString("4.[pi].10*-7.N/A2")); + /** test that the parser supports both {} inserts, but not unicode characters too, while we're at it */ + assertTrue(service.isValidUnitsString("rad2{a}")); + assertFalse(service.isValidUnitsString("rad2{錠}")); // no unicode chars allowed. + assertTrue(service.isValidUnitsString("{a}.rad2{b}")); + assertFalse(service.isValidUnitsString("{a}rad2{b}")); //Cannot start a symbol with an annodation + assertTrue(service.isValidUnitsString("1{c}")); + assertFalse(service.isValidUnitsString("{|}1")); // Cannot start a symbol with an annotation + assertTrue(service.isValidUnitsString("{e}")); + assertTrue(service.isValidUnitsString("%")); + + /** + These codes are taken from the first draft of a proposed Canadian UCUM subset. + (the subset was subsequently corrected after being tested) */ + + assertTrue(service.isValidUnitsString("[cup_us]")); + assertTrue(service.isValidUnitsString("[foz_br]")); + assertTrue(service.isValidUnitsString("[ft_i]")); + assertTrue(service.isValidUnitsString("[in_i]")); + assertTrue(service.isValidUnitsString("[yd_i]")); + assertTrue(service.isValidUnitsString("[gal_br]")); + assertTrue(service.isValidUnitsString("[lb_av]")); + assertTrue(service.isValidUnitsString("[oz_av]")); + assertTrue(service.isValidUnitsString("[pt_br]")); + assertTrue(service.isValidUnitsString("[qt_br]")); + assertTrue(service.isValidUnitsString("[sft_i]")); + assertTrue(service.isValidUnitsString("[sin_i]")); + assertTrue(service.isValidUnitsString("[syd_i]")); + assertTrue(service.isValidUnitsString("[tbs_us]")); + assertTrue(service.isValidUnitsString("[tsp_us]")); + assertTrue(service.isValidUnitsString("1/d")); + assertTrue(service.isValidUnitsString("1/min")); + assertTrue(service.isValidUnitsString("a")); + assertTrue(service.isValidUnitsString("cm")); + assertTrue(service.isValidUnitsString("cm2")); + assertTrue(service.isValidUnitsString("cm3")); + assertTrue(service.isValidUnitsString("d")); + assertTrue(service.isValidUnitsString("dg")); + assertTrue(service.isValidUnitsString("dl")); + assertTrue(service.isValidUnitsString("g")); + assertTrue(service.isValidUnitsString("g/d")); + assertTrue(service.isValidUnitsString("g/l")); + assertTrue(service.isValidUnitsString("h")); + assertFalse(service.isValidUnitsString("iU")); // iU needs [] around it + assertTrue(service.isValidUnitsString("kg")); + assertTrue(service.isValidUnitsString("l")); + assertTrue(service.isValidUnitsString("m")); + assertTrue(service.isValidUnitsString("mm")); + assertTrue(service.isValidUnitsString("m2")); + assertTrue(service.isValidUnitsString("meq")); + assertTrue(service.isValidUnitsString("mg")); + assertTrue(service.isValidUnitsString("mg")); + assertTrue(service.isValidUnitsString("mg/d")); + assertTrue(service.isValidUnitsString("min")); + assertTrue(service.isValidUnitsString("ml")); + assertTrue(service.isValidUnitsString("ml/s")); + assertTrue(service.isValidUnitsString("mm[Hg]")); + assertTrue(service.isValidUnitsString("mm2")); + assertTrue(service.isValidUnitsString("mm3")); + assertTrue(service.isValidUnitsString("mmol")); + assertTrue(service.isValidUnitsString("mmol/l")); + assertTrue(service.isValidUnitsString("mo")); + assertTrue(service.isValidUnitsString("mol")); + assertTrue(service.isValidUnitsString("ms")); + assertTrue(service.isValidUnitsString("mU")); + assertTrue(service.isValidUnitsString("ng")); + assertTrue(service.isValidUnitsString("ng")); + assertTrue(service.isValidUnitsString("nl")); + assertTrue(service.isValidUnitsString("nl")); + assertTrue(service.isValidUnitsString("pg/ml")); + assertTrue(service.isValidUnitsString("s")); + assertTrue(service.isValidUnitsString("U")); + assertTrue(service.isValidUnitsString("U/l")); + assertTrue(service.isValidUnitsString("ug")); + assertTrue(service.isValidUnitsString("ug/min")); + assertTrue(service.isValidUnitsString("ul")); + assertTrue(service.isValidUnitsString("umol")); + assertTrue(service.isValidUnitsString("umol/l")); + assertTrue(service.isValidUnitsString("wk")); + assertTrue(service.isValidUnitsString("%")); + assertTrue(service.isValidUnitsString("[cup_us]")); + assertTrue(service.isValidUnitsString("[foz_br]")); + assertTrue(service.isValidUnitsString("[gal_br]")); + assertTrue(service.isValidUnitsString("[sft_i]")); + assertTrue(service.isValidUnitsString("[sin_i]")); + assertTrue(service.isValidUnitsString("[lb_av]")); + assertTrue(service.isValidUnitsString("[oz_av]")); + assertTrue(service.isValidUnitsString("[pt_br]")); + assertTrue(service.isValidUnitsString("[qt_br]")); + assertTrue(service.isValidUnitsString("[tbs_us]")); + assertTrue(service.isValidUnitsString("[tsp_us]")); + assertTrue(service.isValidUnitsString("[syd_i]")); + assertTrue(service.isValidUnitsString("cm2")); + assertTrue(service.isValidUnitsString("cm3")); + assertTrue(service.isValidUnitsString("g")); + assertTrue(service.isValidUnitsString("kg")); + assertTrue(service.isValidUnitsString("l")); + assertTrue(service.isValidUnitsString("m2")); + assertTrue(service.isValidUnitsString("meq")); + assertTrue(service.isValidUnitsString("mg")); + assertTrue(service.isValidUnitsString("ml")); + assertTrue(service.isValidUnitsString("mm2")); + assertTrue(service.isValidUnitsString("mm3")); + assertTrue(service.isValidUnitsString("mmol")); + assertFalse(service.isValidUnitsString("molv")); // molv is not a valid unit + assertTrue(service.isValidUnitsString("mU")); + assertTrue(service.isValidUnitsString("ng")); + assertTrue(service.isValidUnitsString("nl")); + assertTrue(service.isValidUnitsString("U")); + assertTrue(service.isValidUnitsString("ug")); + assertTrue(service.isValidUnitsString("ul")); + assertTrue(service.isValidUnitsString("umol")); + assertTrue(service.isValidUnitsString("a")); + assertTrue(service.isValidUnitsString("d")); + assertTrue(service.isValidUnitsString("h")); + assertTrue(service.isValidUnitsString("min")); + assertTrue(service.isValidUnitsString("mo")); + assertTrue(service.isValidUnitsString("s")); + assertTrue(service.isValidUnitsString("wk")); + assertTrue(service.isValidUnitsString("[ft_i]")); + assertTrue(service.isValidUnitsString("[in_i]")); + assertTrue(service.isValidUnitsString("[lb_av]")); + assertTrue(service.isValidUnitsString("[oz_av]")); + assertTrue(service.isValidUnitsString("[yd_i]")); + assertTrue(service.isValidUnitsString("cm")); + assertTrue(service.isValidUnitsString("g")); + assertTrue(service.isValidUnitsString("kg")); + assertTrue(service.isValidUnitsString("m")); + assertTrue(service.isValidUnitsString("mm")); + assertTrue(service.isValidUnitsString("[mi_us]")); + assertTrue(service.isValidUnitsString("[yd_i]")); + assertTrue(service.isValidUnitsString("deg")); + assertTrue(service.isValidUnitsString("km")); + assertTrue(service.isValidUnitsString("m")); + assertTrue(service.isValidUnitsString("%")); + assertTrue(service.isValidUnitsString("/[HPF]")); + assertTrue(service.isValidUnitsString("/[LPF]")); + assertTrue(service.isValidUnitsString("/L")); + assertTrue(service.isValidUnitsString("/mL")); + assertTrue(service.isValidUnitsString("/mmol")); + assertTrue(service.isValidUnitsString("[APL'U]")); + assertFalse(service.isValidUnitsString("[BETH'U]")); // not a valid unit + assertTrue(service.isValidUnitsString("[GPL'U]")); + assertTrue(service.isValidUnitsString("[IU]")); + assertTrue(service.isValidUnitsString("[IU]/d")); + assertTrue(service.isValidUnitsString("[IU]/L")); + assertTrue(service.isValidUnitsString("[IU]/mL")); + assertFalse(service.isValidUnitsString("[iIU]")); // not a valid unit (iIU) + assertFalse(service.isValidUnitsString("[iIU]/d")); // not a valid unit (iIU) + assertFalse(service.isValidUnitsString("[iIU]/L")); // not a valid unit (iIU) + assertFalse(service.isValidUnitsString("[iIU]/mL")); // not a valid unit (iIU) + assertTrue(service.isValidUnitsString("[MPL'U]")); + assertTrue(service.isValidUnitsString("10*12/L")); + assertTrue(service.isValidUnitsString("10*6/L")); + assertTrue(service.isValidUnitsString("10*9/L")); + assertTrue(service.isValidUnitsString("Cel")); + assertTrue(service.isValidUnitsString("cm")); + assertTrue(service.isValidUnitsString("cm/s")); + assertTrue(service.isValidUnitsString("fL")); + assertTrue(service.isValidUnitsString("fmol/L")); + assertTrue(service.isValidUnitsString("g")); + assertFalse(service.isValidUnitsString("g/12h")); // not a valid unit (12h - should be 12.h) + assertFalse(service.isValidUnitsString("g/48h")); // not a valid unit (48h) + assertFalse(service.isValidUnitsString("g/4h")); // not a valid unit (4h) + assertFalse(service.isValidUnitsString("g/6h")); // not a valid unit (6h) + assertFalse(service.isValidUnitsString("g/72h")); // not a valid unit (72h) + assertTrue(service.isValidUnitsString("g/d")); + assertTrue(service.isValidUnitsString("g/g")); + assertTrue(service.isValidUnitsString("g/L")); + assertTrue(service.isValidUnitsString("h")); + assertTrue(service.isValidUnitsString("km")); + assertTrue(service.isValidUnitsString("kU/L")); + assertTrue(service.isValidUnitsString("L/L")); + assertTrue(service.isValidUnitsString("m[IU]/L")); + assertFalse(service.isValidUnitsString("m[iIU]/L")); // not a valid unit (iIU) + assertTrue(service.isValidUnitsString("mg")); + assertFalse(service.isValidUnitsString("mg/12h")); // not a valid unit (12h) + assertTrue(service.isValidUnitsString("mg/d")); + assertTrue(service.isValidUnitsString("mg/g")); + assertTrue(service.isValidUnitsString("mg/L")); + assertTrue(service.isValidUnitsString("mg/mg")); + assertTrue(service.isValidUnitsString("mg/mL")); + assertTrue(service.isValidUnitsString("min")); + assertTrue(service.isValidUnitsString("mL")); + assertFalse(service.isValidUnitsString("mL/10h")); // not a valid unit (10h) + assertFalse(service.isValidUnitsString("mL/12h")); // not a valid unit (12h) + assertFalse(service.isValidUnitsString("mL/2h")); // not a valid unit (2h) + assertFalse(service.isValidUnitsString("mL/4h")); // not a valid unit (4h) + assertFalse(service.isValidUnitsString("mL/5h")); // not a valid unit (5h) + assertFalse(service.isValidUnitsString("mL/6h")); // not a valid unit (6h) + assertFalse(service.isValidUnitsString("mL/72h")); // not a valid unit (72h) + assertFalse(service.isValidUnitsString("mL/8h")); // not a valid unit (8h) + assertTrue(service.isValidUnitsString("mL/d")); + assertTrue(service.isValidUnitsString("mL/min")); + assertTrue(service.isValidUnitsString("mm")); + assertTrue(service.isValidUnitsString("mm/h")); + assertTrue(service.isValidUnitsString("mm[Hg]")); + assertTrue(service.isValidUnitsString("mmol")); + assertFalse(service.isValidUnitsString("mmol/12h")); // not a valid unit (12h) + assertFalse(service.isValidUnitsString("mmol/5h")); // not a valid unit (5h) + assertFalse(service.isValidUnitsString("mmol/6h")); // not a valid unit (6h) + assertTrue(service.isValidUnitsString("mmol/d")); + assertTrue(service.isValidUnitsString("mmol/g")); + assertTrue(service.isValidUnitsString("mmol/kg")); + assertFalse(service.isValidUnitsString("mmol/kg[H20]")); // not a valid unit (kg[H20]) + assertTrue(service.isValidUnitsString("mmol/L")); + assertTrue(service.isValidUnitsString("mmol/mmol")); + assertTrue(service.isValidUnitsString("mU/L")); + assertTrue(service.isValidUnitsString("ng/d")); + assertTrue(service.isValidUnitsString("ng/g")); + assertTrue(service.isValidUnitsString("ng/L")); + assertTrue(service.isValidUnitsString("ng/mL")); + assertTrue(service.isValidUnitsString("nmol/d")); + assertTrue(service.isValidUnitsString("nmol/g")); + assertTrue(service.isValidUnitsString("nmol/h/mL")); + assertTrue(service.isValidUnitsString("nmol/L")); + assertTrue(service.isValidUnitsString("nmol/mmol")); + assertTrue(service.isValidUnitsString("nmol/nmol")); + assertTrue(service.isValidUnitsString("pg")); + assertTrue(service.isValidUnitsString("pg/mL")); + assertTrue(service.isValidUnitsString("pmol/d")); + assertTrue(service.isValidUnitsString("pmol/g")); + assertTrue(service.isValidUnitsString("pmol/h/mg")); + assertTrue(service.isValidUnitsString("pmol/h/mL")); + assertTrue(service.isValidUnitsString("pmol/L")); + assertTrue(service.isValidUnitsString("pmol/mmol")); + assertTrue(service.isValidUnitsString("s")); + assertTrue(service.isValidUnitsString("U")); + assertFalse(service.isValidUnitsString("U/12h")); // not a valid unit (12h) + assertFalse(service.isValidUnitsString("U/1h")); // not a valid unit (1h) + assertFalse(service.isValidUnitsString("U/2h")); // not a valid unit (2h) + assertTrue(service.isValidUnitsString("U/d")); + assertTrue(service.isValidUnitsString("U/g")); + assertTrue(service.isValidUnitsString("U/kg")); + assertTrue(service.isValidUnitsString("U/L")); + assertTrue(service.isValidUnitsString("U/mL")); + assertTrue(service.isValidUnitsString("u[IU]/mL")); + assertFalse(service.isValidUnitsString("u[iIU]/mL")); // not a valid unit (iIU) + assertTrue(service.isValidUnitsString("ug")); + assertTrue(service.isValidUnitsString("ug/d")); + assertTrue(service.isValidUnitsString("ug/g")); + assertTrue(service.isValidUnitsString("ug/L")); + assertTrue(service.isValidUnitsString("ug/mL")); + assertTrue(service.isValidUnitsString("um/s")); + assertTrue(service.isValidUnitsString("umol")); + assertTrue(service.isValidUnitsString("umol/2.h")); + assertTrue(service.isValidUnitsString("umol/d")); + assertTrue(service.isValidUnitsString("umol/g")); + assertTrue(service.isValidUnitsString("umol/L")); + assertTrue(service.isValidUnitsString("umol/mmol")); + assertTrue(service.isValidUnitsString("umol/umol")); + assertTrue(service.isValidUnitsString("wk")); + + /** + These codes are taken from Keith's draft list of ICO/UCUM codes, + at http://motorcycleguy.blogspot.com/2009/11/iso-to-ucum-mapping-table.html + */ + assertTrue(service.isValidUnitsString("[arb'U]")); + assertTrue(service.isValidUnitsString("dyn.s/(cm5.m2)")); + assertTrue(service.isValidUnitsString("[iU]/mL")); + assertTrue(service.isValidUnitsString("mL/h")); + assertTrue(service.isValidUnitsString("[bdsk'U]")); + assertTrue(service.isValidUnitsString("dyn.s/cm5")); + assertTrue(service.isValidUnitsString("K/W")); + assertTrue(service.isValidUnitsString("mm[Hg]")); + assertTrue(service.isValidUnitsString("{bsa}")); + assertTrue(service.isValidUnitsString("cm[H2O]")); + assertFalse(service.isValidUnitsString("cm[H20]")); + assertTrue(service.isValidUnitsString("kg{body_wt}")); + assertTrue(service.isValidUnitsString("mm/h")); + assertTrue(service.isValidUnitsString("cal")); + assertTrue(service.isValidUnitsString("cm[H2O].s/L")); + assertTrue(service.isValidUnitsString("kg/m2")); + assertTrue(service.isValidUnitsString("mmol/(8.h.kg)")); + assertTrue(service.isValidUnitsString("{cfu}")); + assertTrue(service.isValidUnitsString("cm[H2O]/(s.m)")); + assertTrue(service.isValidUnitsString("kg/h")); + assertTrue(service.isValidUnitsString("mmol/(8.h)")); + assertTrue(service.isValidUnitsString("[drp]")); + assertTrue(service.isValidUnitsString("dB[SPL]")); + assertTrue(service.isValidUnitsString("L/(8.h)")); + assertTrue(service.isValidUnitsString("mmol/(kg.h)")); + assertTrue(service.isValidUnitsString("[ka'U]")); + assertTrue(service.isValidUnitsString("REM")); + assertTrue(service.isValidUnitsString("L/h")); + assertTrue(service.isValidUnitsString("mmol/h")); + assertTrue(service.isValidUnitsString("kcal")); + assertTrue(service.isValidUnitsString("g{creat}")); + assertTrue(service.isValidUnitsString("[lb_av]")); + assertTrue(service.isValidUnitsString("ng/(8.h)")); + assertTrue(service.isValidUnitsString("kcal/(8.h)")); + assertTrue(service.isValidUnitsString("g{hgb}")); + assertTrue(service.isValidUnitsString("ng/(8.h.kg)")); + assertTrue(service.isValidUnitsString("kcal/d")); + assertTrue(service.isValidUnitsString("g{tit_nit}")); + assertTrue(service.isValidUnitsString("ms/s")); + assertTrue(service.isValidUnitsString("ng/(kg.h)")); + assertTrue(service.isValidUnitsString("kcal/h")); + assertTrue(service.isValidUnitsString("g{tot_prot}")); + assertTrue(service.isValidUnitsString("Ms")); + assertTrue(service.isValidUnitsString("ng/h")); + assertTrue(service.isValidUnitsString("[knk'U]")); + assertTrue(service.isValidUnitsString("g{wet_tis}")); + assertTrue(service.isValidUnitsString("meq/(8.h)")); + assertTrue(service.isValidUnitsString("osm")); + assertTrue(service.isValidUnitsString("[mclg'U]")); + + assertFalse(service.isValidUnitsString("g.m/{hb}m2")); // This test is set to true in UcumFunctionalTests2.xml, but is later (in UcumFunctionalTests.xml!) corrected to the one below, which is correct. + assertTrue(service.isValidUnitsString("g.m/m2{hb}")); + + assertTrue(service.isValidUnitsString("meq/(8.h.kg)")); + assertTrue(service.isValidUnitsString("osm/kg")); + assertTrue(service.isValidUnitsString("{od}")); + assertTrue(service.isValidUnitsString("g.m/{hb}")); + assertTrue(service.isValidUnitsString("meq/(kg.h)")); + assertTrue(service.isValidUnitsString("osm/L")); + assertTrue(service.isValidUnitsString("pH")); + assertTrue(service.isValidUnitsString("g/(8.h)")); + assertTrue(service.isValidUnitsString("meq/h")); + assertTrue(service.isValidUnitsString("pA")); + assertTrue(service.isValidUnitsString("[ppb]")); + assertTrue(service.isValidUnitsString("g/(8.kg.h)")); + assertTrue(service.isValidUnitsString("mg/(8.h)")); + assertTrue(service.isValidUnitsString("Pa")); + assertTrue(service.isValidUnitsString("[ppm]")); + assertTrue(service.isValidUnitsString("g/(kg.h)")); + assertTrue(service.isValidUnitsString("mg/(8.h.kg)")); + assertTrue(service.isValidUnitsString("[pptr]")); + assertTrue(service.isValidUnitsString("g/h")); + assertTrue(service.isValidUnitsString("mg/(kg.h)")); + assertTrue(service.isValidUnitsString("S")); + assertTrue(service.isValidUnitsString("[ppth]")); + assertTrue(service.isValidUnitsString("[in_us]")); + assertTrue(service.isValidUnitsString("mg/h")); + assertFalse(service.isValidUnitsString("ug(8.h)")); + assertFalse(service.isValidUnitsString("ug(8hr)")); + assertTrue(service.isValidUnitsString("[todd'U]")); + assertTrue(service.isValidUnitsString("[in_i'Hg]")); + assertTrue(service.isValidUnitsString("m[iU]/mL")); + assertTrue(service.isValidUnitsString("ug/(8.h.kg)")); + assertTrue(service.isValidUnitsString("/[arb'U]")); + assertTrue(service.isValidUnitsString("[iU]")); + assertTrue(service.isValidUnitsString("mL/{hb}.m2")); + assertTrue(service.isValidUnitsString("ug/(kg.h)")); + assertTrue(service.isValidUnitsString("[HPF]")); + assertTrue(service.isValidUnitsString("[iU]/d")); + assertTrue(service.isValidUnitsString("mL/(8.h)")); + assertTrue(service.isValidUnitsString("ug/h")); + assertTrue(service.isValidUnitsString("/{tot}")); + assertTrue(service.isValidUnitsString("[iU]/h")); + assertTrue(service.isValidUnitsString("mL/(8.h.kg)")); + + assertTrue(service.isValidUnitsString("u[iU]")); + assertTrue(service.isValidUnitsString("/[iU]")); + assertTrue(service.isValidUnitsString("[iU]/kg")); + assertTrue(service.isValidUnitsString("mL/{hb}")); + assertTrue(service.isValidUnitsString("10*3{rbc}")); + assertTrue(service.isValidUnitsString("[iU]/L")); + assertTrue(service.isValidUnitsString("mL/(kg.h)")); + assertTrue(service.isValidUnitsString("10.L/(min.m2)")); + assertTrue(service.isValidUnitsString("[iU]/min")); + assertTrue(service.isValidUnitsString("mL/cm[H2O]")); + assertTrue(service.isValidUnitsString("%")); + assertTrue(service.isValidUnitsString("bar")); + assertTrue(service.isValidUnitsString("g/L")); + assertTrue(service.isValidUnitsString("L.s")); + assertTrue(service.isValidUnitsString("mg")); + assertTrue(service.isValidUnitsString("mmol/(kg.d)")); + assertTrue(service.isValidUnitsString("ng/L")); + assertTrue(service.isValidUnitsString("ueq")); + assertTrue(service.isValidUnitsString("/kg")); + assertTrue(service.isValidUnitsString("Bq")); + assertTrue(service.isValidUnitsString("g/m2")); + assertTrue(service.isValidUnitsString("L/(min.m2)")); + assertTrue(service.isValidUnitsString("mg/(kg.d)")); + assertTrue(service.isValidUnitsString("mmol/(kg.min)")); + assertTrue(service.isValidUnitsString("ng/m2")); + assertTrue(service.isValidUnitsString("ug")); + assertTrue(service.isValidUnitsString("/L")); + assertTrue(service.isValidUnitsString("Cel")); + assertTrue(service.isValidUnitsString("g/min")); + assertTrue(service.isValidUnitsString("L/d")); + assertTrue(service.isValidUnitsString("mg/(kg.min)")); + assertTrue(service.isValidUnitsString("mmol/kg")); + assertTrue(service.isValidUnitsString("ng/min")); + assertTrue(service.isValidUnitsString("ug/(kg.d)")); + assertTrue(service.isValidUnitsString("/m3")); + assertTrue(service.isValidUnitsString("cm")); + assertTrue(service.isValidUnitsString("Gy")); + assertTrue(service.isValidUnitsString("L/kg")); + assertTrue(service.isValidUnitsString("mg/d")); + assertTrue(service.isValidUnitsString("mmol/L")); + assertTrue(service.isValidUnitsString("ng/mL")); + assertTrue(service.isValidUnitsString("ug/(kg.min)")); + assertTrue(service.isValidUnitsString("/min")); + assertTrue(service.isValidUnitsString("cm2/s")); + assertTrue(service.isValidUnitsString("h")); + assertTrue(service.isValidUnitsString("L/min")); + assertTrue(service.isValidUnitsString("mg/dL")); + assertTrue(service.isValidUnitsString("mmol/m2")); + assertTrue(service.isValidUnitsString("ng/s")); + assertTrue(service.isValidUnitsString("ug/d")); + assertTrue(service.isValidUnitsString("/m3")); + assertTrue(service.isValidUnitsString("d")); + assertTrue(service.isValidUnitsString("hL")); + assertTrue(service.isValidUnitsString("L/s")); + assertTrue(service.isValidUnitsString("mg/kg")); + assertTrue(service.isValidUnitsString("mmol/min")); + assertTrue(service.isValidUnitsString("nkat")); + assertTrue(service.isValidUnitsString("ug/dL")); + assertTrue(service.isValidUnitsString("/min")); + assertTrue(service.isValidUnitsString("dB")); + assertTrue(service.isValidUnitsString("J/L")); + assertTrue(service.isValidUnitsString("lm")); + assertTrue(service.isValidUnitsString("mg/L")); + assertTrue(service.isValidUnitsString("mol/(kg.s)")); + assertTrue(service.isValidUnitsString("nm")); + assertTrue(service.isValidUnitsString("ug/g")); + assertTrue(service.isValidUnitsString("/mL")); + assertTrue(service.isValidUnitsString("deg")); + assertTrue(service.isValidUnitsString("kat")); + assertTrue(service.isValidUnitsString("m")); + assertTrue(service.isValidUnitsString("mg/m2")); + assertTrue(service.isValidUnitsString("mol/kg")); + assertTrue(service.isValidUnitsString("nmol/s")); + assertTrue(service.isValidUnitsString("ug/kg")); + assertTrue(service.isValidUnitsString("1/mL")); + assertTrue(service.isValidUnitsString("eq")); + assertTrue(service.isValidUnitsString("kat/kg")); + assertTrue(service.isValidUnitsString("m/s2")); + assertTrue(service.isValidUnitsString("mg/m3")); + assertTrue(service.isValidUnitsString("mol/L")); + assertTrue(service.isValidUnitsString("ns")); + assertTrue(service.isValidUnitsString("ug/L")); + assertTrue(service.isValidUnitsString("10*12/L")); + assertTrue(service.isValidUnitsString("eV")); + assertTrue(service.isValidUnitsString("kat/L")); + assertTrue(service.isValidUnitsString("m2")); + assertTrue(service.isValidUnitsString("mg/min")); + assertTrue(service.isValidUnitsString("mol/m3")); + assertTrue(service.isValidUnitsString("Ohm")); + assertTrue(service.isValidUnitsString("ug/m2")); + assertTrue(service.isValidUnitsString("10*3/L")); + assertTrue(service.isValidUnitsString("kg")); + assertTrue(service.isValidUnitsString("m2/s")); + assertTrue(service.isValidUnitsString("mL")); + assertTrue(service.isValidUnitsString("mol/s")); + assertTrue(service.isValidUnitsString("Ohm.m")); + assertTrue(service.isValidUnitsString("ug/min")); + assertTrue(service.isValidUnitsString("10*3/mL")); + assertTrue(service.isValidUnitsString("fg")); + assertTrue(service.isValidUnitsString("kg.m/s")); + assertTrue(service.isValidUnitsString("m3/s")); + assertTrue(service.isValidUnitsString("mL/(kg.d)")); + assertTrue(service.isValidUnitsString("mosm/L")); + assertTrue(service.isValidUnitsString("pg")); + assertTrue(service.isValidUnitsString("ukat")); + assertTrue(service.isValidUnitsString("10*3/mm3")); + assertTrue(service.isValidUnitsString("fL")); + assertTrue(service.isValidUnitsString("kg/(s.m2)")); + assertTrue(service.isValidUnitsString("mbar")); + assertTrue(service.isValidUnitsString("mL/(kg.min)")); + assertTrue(service.isValidUnitsString("ms")); + assertTrue(service.isValidUnitsString("pg/L")); + assertTrue(service.isValidUnitsString("um")); + assertTrue(service.isValidUnitsString("10*6/L")); + assertTrue(service.isValidUnitsString("fmol")); + assertTrue(service.isValidUnitsString("kg/L")); + assertTrue(service.isValidUnitsString("mbar.s/L")); + assertTrue(service.isValidUnitsString("mL/(min.m2)")); + assertTrue(service.isValidUnitsString("mV")); + assertTrue(service.isValidUnitsString("pg/mL")); + assertTrue(service.isValidUnitsString("umol")); + assertTrue(service.isValidUnitsString("10*6/mL")); + assertTrue(service.isValidUnitsString("g")); + assertTrue(service.isValidUnitsString("kg/m3")); + assertTrue(service.isValidUnitsString("meq")); + assertTrue(service.isValidUnitsString("mL/d")); + assertTrue(service.isValidUnitsString("pkat")); + assertTrue(service.isValidUnitsString("umol/d")); + assertTrue(service.isValidUnitsString("10*6/mm3")); + assertTrue(service.isValidUnitsString("g.m")); + assertTrue(service.isValidUnitsString("kg/min")); + assertTrue(service.isValidUnitsString("meq/(kg.d)")); + assertTrue(service.isValidUnitsString("mL/kg")); + assertTrue(service.isValidUnitsString("pm")); + assertTrue(service.isValidUnitsString("umol/L")); + assertTrue(service.isValidUnitsString("10*9/L")); + assertTrue(service.isValidUnitsString("g/(kg.d)")); + assertTrue(service.isValidUnitsString("kg/mol")); + assertTrue(service.isValidUnitsString("meq/(kg.min)")); + assertTrue(service.isValidUnitsString("mL/m2")); + assertTrue(service.isValidUnitsString("ng")); + assertTrue(service.isValidUnitsString("pmol")); + assertTrue(service.isValidUnitsString("umol/min")); + assertTrue(service.isValidUnitsString("10*9/mL")); + assertTrue(service.isValidUnitsString("g/(kg.min)")); + assertTrue(service.isValidUnitsString("kg/s")); + assertTrue(service.isValidUnitsString("meq/d")); + assertTrue(service.isValidUnitsString("mL/mbar")); + assertTrue(service.isValidUnitsString("ng/(kg.d)")); + assertTrue(service.isValidUnitsString("ps")); + assertTrue(service.isValidUnitsString("us")); + assertTrue(service.isValidUnitsString("10*9/mm3")); + assertTrue(service.isValidUnitsString("g/d")); + assertTrue(service.isValidUnitsString("kPa")); + assertTrue(service.isValidUnitsString("meq/kg")); + assertTrue(service.isValidUnitsString("mL/min")); + assertTrue(service.isValidUnitsString("ng/(kg.min)")); + assertTrue(service.isValidUnitsString("pt")); + assertTrue(service.isValidUnitsString("uV")); + assertTrue(service.isValidUnitsString("10.L/min")); + assertTrue(service.isValidUnitsString("g/dL")); + assertTrue(service.isValidUnitsString("ks")); + assertTrue(service.isValidUnitsString("meq/L")); + assertTrue(service.isValidUnitsString("mL/s")); + assertTrue(service.isValidUnitsString("ng/d")); + assertTrue(service.isValidUnitsString("Sv")); + assertTrue(service.isValidUnitsString("V")); + assertTrue(service.isValidUnitsString("a/m")); + assertTrue(service.isValidUnitsString("g/kg")); + assertTrue(service.isValidUnitsString("L")); + assertTrue(service.isValidUnitsString("meq/min")); + assertTrue(service.isValidUnitsString("mm")); + assertTrue(service.isValidUnitsString("ng/kg")); + assertTrue(service.isValidUnitsString("t")); + assertTrue(service.isValidUnitsString("Wb")); } - + private MeasurementService service; } diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index bfd23682..b226f4cb 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -2,9 +2,9 @@ 4.0.0 - openehr - ref_impl_java - 1.0.5-SNAPSHOT + org.openehr.java-libs + java-libs + 0-SNAPSHOT mini-termserv jar @@ -21,7 +21,7 @@ - openehr + org.openehr.java-libs openehr-rm-core ${project.version} diff --git a/mini-termserv/src/main/java/org/openehr/terminology/CodeSet.java b/mini-termserv/src/main/java/org/openehr/terminology/CodeSet.java old mode 100755 new mode 100644 diff --git a/mini-termserv/src/main/java/org/openehr/terminology/Concept.java b/mini-termserv/src/main/java/org/openehr/terminology/Concept.java old mode 100755 new mode 100644 diff --git a/mini-termserv/src/main/java/org/openehr/terminology/Group.java b/mini-termserv/src/main/java/org/openehr/terminology/Group.java old mode 100755 new mode 100644 diff --git a/mini-termserv/src/main/java/org/openehr/terminology/SimpleCodeSetAccess.java b/mini-termserv/src/main/java/org/openehr/terminology/SimpleCodeSetAccess.java old mode 100755 new mode 100644 diff --git a/mini-termserv/src/main/java/org/openehr/terminology/SimpleTerminologyAccess.java b/mini-termserv/src/main/java/org/openehr/terminology/SimpleTerminologyAccess.java index ffd6b06a..779d8b16 100755 --- a/mini-termserv/src/main/java/org/openehr/terminology/SimpleTerminologyAccess.java +++ b/mini-termserv/src/main/java/org/openehr/terminology/SimpleTerminologyAccess.java @@ -57,12 +57,13 @@ void addGroup(String groupId, Collection codes, group.add(code); } groups.put(groupId, group); - for(String lang : names.keySet()) { + for(Map.Entry entry : names.entrySet()) { + String lang = entry.getKey(); Map nameToId = groupLangNameToId.get(lang); if(nameToId == null) { nameToId = new HashMap(); } - String name = names.get(lang); + String name = entry.getValue(); nameToId.put(name, groupId); groupLangNameToId.put(lang, nameToId); diff --git a/mini-termserv/src/main/java/org/openehr/terminology/SimpleTerminologyService.java b/mini-termserv/src/main/java/org/openehr/terminology/SimpleTerminologyService.java old mode 100755 new mode 100644 diff --git a/mini-termserv/src/main/java/org/openehr/terminology/TerminologySource.java b/mini-termserv/src/main/java/org/openehr/terminology/TerminologySource.java old mode 100755 new mode 100644 diff --git a/mini-termserv/src/main/java/org/openehr/terminology/TerminologySourceFactory.java b/mini-termserv/src/main/java/org/openehr/terminology/TerminologySourceFactory.java old mode 100755 new mode 100644 diff --git a/mini-termserv/src/main/java/org/openehr/terminology/XMLTerminologySource.java b/mini-termserv/src/main/java/org/openehr/terminology/XMLTerminologySource.java old mode 100755 new mode 100644 diff --git a/mini-termserv/src/main/resources/external_terminologies_en.xml b/mini-termserv/src/main/resources/external_terminologies_en.xml old mode 100755 new mode 100644 index 12bf14f4..844047dc --- a/mini-termserv/src/main/resources/external_terminologies_en.xml +++ b/mini-termserv/src/main/resources/external_terminologies_en.xml @@ -333,14 +333,13 @@ - + - @@ -357,7 +356,8 @@ - + + @@ -389,21 +389,77 @@ + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mini-termserv/src/main/resources/log4j.properties b/mini-termserv/src/main/resources/log4j.properties old mode 100755 new mode 100644 diff --git a/mini-termserv/src/main/resources/openehr_terminology_en.xml b/mini-termserv/src/main/resources/openehr_terminology_en.xml old mode 100755 new mode 100644 index e2ac826b..e8a92193 --- a/mini-termserv/src/main/resources/openehr_terminology_en.xml +++ b/mini-termserv/src/main/resources/openehr_terminology_en.xml @@ -34,6 +34,7 @@ + @@ -233,6 +234,7 @@ + @@ -266,15 +268,15 @@ - - + + - - + + @@ -305,14 +307,14 @@ - - - + + + - - - - + + + + diff --git a/mini-termserv/src/test/java/org/openehr/terminology/OpenEHRTerminologyTest.java b/mini-termserv/src/test/java/org/openehr/terminology/OpenEHRTerminologyTest.java old mode 100755 new mode 100644 diff --git a/mini-termserv/src/test/java/org/openehr/terminology/SimpleCodeSetAccessTest.java b/mini-termserv/src/test/java/org/openehr/terminology/SimpleCodeSetAccessTest.java old mode 100755 new mode 100644 diff --git a/mini-termserv/src/test/java/org/openehr/terminology/SimpleTerminologyAccessTest.java b/mini-termserv/src/test/java/org/openehr/terminology/SimpleTerminologyAccessTest.java old mode 100755 new mode 100644 diff --git a/mini-termserv/src/test/java/org/openehr/terminology/SimpleTerminologyServiceTest.java b/mini-termserv/src/test/java/org/openehr/terminology/SimpleTerminologyServiceTest.java old mode 100755 new mode 100644 diff --git a/mini-termserv/src/test/java/org/openehr/terminology/TranslationDetailsTest.java b/mini-termserv/src/test/java/org/openehr/terminology/TranslationDetailsTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 55f0f184..cd03ff31 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -2,9 +2,9 @@ 4.0.0 - openehr - ref_impl_java - 1.0.5-SNAPSHOT + org.openehr.java-libs + java-libs + 0-SNAPSHOT oet-parser jar @@ -49,22 +49,22 @@ - openehr + org.openehr.java-libs openehr-rm-core ${project.version} - openehr + org.openehr.java-libs openehr-rm-domain ${project.version} - openehr + org.openehr.java-libs openehr-aom ${project.version} - openehr + org.openehr.java-libs adl-parser ${project.version} @@ -79,12 +79,12 @@ 1.0 - openehr + org.openehr.java-libs measure-serv ${project.version} - openehr + org.openehr.java-libs mini-termserv ${project.version} @@ -101,7 +101,7 @@ test - openehr + org.openehr.java-libs adl-serializer ${project.version} diff --git a/oet-parser/src/main/java/org/openehr/am/template/Flattener.java b/oet-parser/src/main/java/org/openehr/am/template/Flattener.java index ec5740b8..a9db2108 100755 --- a/oet-parser/src/main/java/org/openehr/am/template/Flattener.java +++ b/oet-parser/src/main/java/org/openehr/am/template/Flattener.java @@ -104,14 +104,13 @@ public Archetype toFlattenedArchetype(TEMPLATE template, // make a internal copy of archetypeMap this.archetypeMap.clear(); - for(String id : archetypeMap.keySet()) { - Archetype a = archetypeMap.get(id); + for(Map.Entry entry : archetypeMap.entrySet()) { + Archetype a = entry.getValue(); if(a != null) { a = a.copy(); - this.archetypeMap.put(id, a); + this.archetypeMap.put(entry.getKey(), a); } } - // no need to copy templateMap this.templateMap = templateMap; log.debug("Loaded archetype/template maps, total archetypes: " + @@ -182,10 +181,10 @@ private Archetype flattenArchetyped(Archetyped definition) throws FlatteningExce */ private Archetype flattenItem(Archetype parentArchetype, ITEM item) throws FlatteningException { + + String aid = parentArchetype == null ? "null" : parentArchetype.getArchetypeId().toString(); - log.debug("flattening item on parentArchetype " + - parentArchetype.getArchetypeId() + " at path " + - item.getPath()); + log.debug("flattening item on parentArchetype " + aid + " at path " + item.getPath()); Archetype archetype = retrieveArchetype(item.getArchetypeId()); @@ -580,7 +579,6 @@ private Archetype flattenEntry(Archetype parentArchetype, // TODO handle description item ACTION action = (ACTION) definition; - parentArchetype = retrieveArchetype(action.getArchetypeId()); ITEMSTRUCTURE description = action.getDescription(); if(description != null) { flattenItemStructure(archetype, description); @@ -816,11 +814,6 @@ void applyRule(Archetype archetype, Statement rule) applyValueConstraint(archetype, constraint, rule); archetype.updatePathNodeMap((CObject) constraint); - - if(constraint instanceof CObject) { - log.debug("newly set Occurrences: " + ((CObject) constraint).getOccurrences() ); - } - } // TODO @@ -900,7 +893,7 @@ protected void applyDefaultValueConstraint(ArchetypeConstraint constraint, cattr = new CSingleAttribute(ccobj.path() + "/" + VALUE, VALUE, Existence.REQUIRED); - } else if (cattr != null && cattr.getChildren().size() == 1) { + } else if (cattr.getChildren().size() == 1) { CObject child = cattr.getChildren().get(0); if(child instanceof CComplexObject) { @@ -1219,8 +1212,7 @@ protected void applyValueConstraint(Archetype archetype, log.debug("applying value constraint on path: " + constraint.path()); if( ! (constraint instanceof CComplexObject)) { - throw new FlatteningException("Unexpected constraint type: " + - (constraint == null ? "null" : constraint.getClass())); + throw new FlatteningException("Unexpected constraint type: " + constraint.getClass()); } CComplexObject ccobj = (CComplexObject) constraint; @@ -1586,7 +1578,7 @@ private TEMPLATE retrieveTemplate(String templateId) throws FlatteningException { TEMPLATE template = templateMap.get(templateId); if(template == null) { - throw new FlatteningException("Unknown template: " + templateId); + throw new UnknownTemplateException(templateId); } return template; } @@ -1596,7 +1588,7 @@ private Archetype retrieveArchetype(String archetypeId) Archetype archetype = archetypeMap.get(archetypeId); if(archetype == null) { - throw new FlatteningException("Unknown archetype: " + archetypeId); + throw new UnknownArchetypeException(archetypeId); } // make a deep copy archetype = archetype.copy(); @@ -1729,4 +1721,4 @@ public TermMap getTermMap() { * the specific language governing rights and limitations under the License. * * ***** END LICENSE BLOCK ***** - */ \ No newline at end of file + */ diff --git a/oet-parser/src/main/java/org/openehr/am/template/FlatteningException.java b/oet-parser/src/main/java/org/openehr/am/template/FlatteningException.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/main/java/org/openehr/am/template/OETParser.java b/oet-parser/src/main/java/org/openehr/am/template/OETParser.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/main/java/org/openehr/am/template/PathMap.java b/oet-parser/src/main/java/org/openehr/am/template/PathMap.java index e04927be..2d424055 100755 --- a/oet-parser/src/main/java/org/openehr/am/template/PathMap.java +++ b/oet-parser/src/main/java/org/openehr/am/template/PathMap.java @@ -146,8 +146,9 @@ public void writeToFile(String filename) throws IOException { int maxLen = 0; String maxLenKey = null; - for(String key : keyPathMap.keySet()) { - String path = keyPathMap.get(key); + for(Map.Entry entry: keyPathMap.entrySet()) { + String key = entry.getKey(); + String path = entry.getValue(); if(key.length() > maxLen) { maxLen = key.length(); maxLenKey = key; diff --git a/oet-parser/src/main/java/org/openehr/am/template/TermMap.java b/oet-parser/src/main/java/org/openehr/am/template/TermMap.java index 43ff7eb4..da10b53b 100755 --- a/oet-parser/src/main/java/org/openehr/am/template/TermMap.java +++ b/oet-parser/src/main/java/org/openehr/am/template/TermMap.java @@ -198,9 +198,9 @@ public String getText(String terminology, String code, String path) { // TODO temp fix if no direct match if(text == null) { - for(String p : paths.keySet()) { - if(path.endsWith(p)) { - text = paths.get(p); + for(Map.Entry entry : paths.entrySet()) { + if(path.endsWith(entry.getKey())) { + text = entry.getValue(); } } } @@ -277,21 +277,19 @@ public void writeTermMap(String filename) throws IOException { Map texts = null; Map> terms = null; - for(Iterator it = termMap.keySet().iterator(); it.hasNext();) { - terminology = it.next(); - terms = termMap.get(terminology); + for(Map.Entry>> entry : termMap.entrySet()) { + terminology = entry.getKey(); + terms = entry.getValue(); - for(Iterator codes = terms.keySet().iterator(); - codes.hasNext();) { + for(Map.Entry> entry2 : terms.entrySet()) { - code = codes.next(); - texts = terms.get(code); + code = entry2.getKey(); + texts = entry2.getValue(); - for(Iterator paths = texts.keySet().iterator(); - paths.hasNext();) { + for(Map.Entry entry3 : texts.entrySet()) { - path = paths.next(); - text = texts.get(path); + path = entry3.getKey(); + text = entry3.getValue(); buf.append(terminology); buf.append(DELIMITER); buf.append(code); @@ -299,9 +297,7 @@ public void writeTermMap(String filename) throws IOException { buf.append(text); buf.append(DELIMITER); buf.append(path); - if(codes.hasNext() || it.hasNext()) { - buf.append("\r\n"); - } + buf.append("\r\n"); } } } diff --git a/oet-parser/src/main/java/org/openehr/am/template/UnknownArchetypeException.java b/oet-parser/src/main/java/org/openehr/am/template/UnknownArchetypeException.java new file mode 100755 index 00000000..8a852b4d --- /dev/null +++ b/oet-parser/src/main/java/org/openehr/am/template/UnknownArchetypeException.java @@ -0,0 +1,20 @@ +package org.openehr.am.template; + +/** + * User: Iago.Corbal + * Date: 2014-05-27 + * Time: 14:40 + */ +public class UnknownArchetypeException extends FlatteningException { + + private String archetypeId; + + public UnknownArchetypeException(String archetypeId) { + super("Unknown archetype: "+archetypeId); + this.archetypeId = archetypeId; + } + + public String getArchetypeId() { + return archetypeId; + } +} diff --git a/oet-parser/src/main/java/org/openehr/am/template/UnknownTemplateException.java b/oet-parser/src/main/java/org/openehr/am/template/UnknownTemplateException.java new file mode 100755 index 00000000..7d6ac639 --- /dev/null +++ b/oet-parser/src/main/java/org/openehr/am/template/UnknownTemplateException.java @@ -0,0 +1,21 @@ +package org.openehr.am.template; + +/** + * User: Iago.Corbal + * Date: 2014-05-27 + * Time: 14:40 + */ +public class UnknownTemplateException extends FlatteningException { + + private String templateId; + + public UnknownTemplateException(String templateId) { + super("Unknown template: "+templateId); + this.templateId = templateId; + } + + public String getTemplateId() { + return templateId; + } + +} diff --git a/oet-parser/src/main/xsd/Archetype.xsd b/oet-parser/src/main/xsd/Archetype.xsd old mode 100755 new mode 100644 diff --git a/oet-parser/src/main/xsd/BaseTypes.xsd b/oet-parser/src/main/xsd/BaseTypes.xsd old mode 100755 new mode 100644 diff --git a/oet-parser/src/main/xsd/CharacterMapping.xsd b/oet-parser/src/main/xsd/CharacterMapping.xsd old mode 100755 new mode 100644 diff --git a/oet-parser/src/main/xsd/Composition.xsd b/oet-parser/src/main/xsd/Composition.xsd old mode 100755 new mode 100644 diff --git a/oet-parser/src/main/xsd/CompositionTemplate.xsd b/oet-parser/src/main/xsd/CompositionTemplate.xsd old mode 100755 new mode 100644 diff --git a/oet-parser/src/main/xsd/Content.xsd b/oet-parser/src/main/xsd/Content.xsd old mode 100755 new mode 100644 diff --git a/oet-parser/src/main/xsd/Extract.xsd b/oet-parser/src/main/xsd/Extract.xsd old mode 100755 new mode 100644 diff --git a/oet-parser/src/main/xsd/OpenehrProfile.xsd b/oet-parser/src/main/xsd/OpenehrProfile.xsd old mode 100755 new mode 100644 diff --git a/oet-parser/src/main/xsd/Resource.xsd b/oet-parser/src/main/xsd/Resource.xsd old mode 100755 new mode 100644 diff --git a/oet-parser/src/main/xsd/Structure.xsd b/oet-parser/src/main/xsd/Structure.xsd old mode 100755 new mode 100644 diff --git a/oet-parser/src/main/xsd/Template.xsd b/oet-parser/src/main/xsd/Template.xsd old mode 100755 new mode 100644 diff --git a/oet-parser/src/main/xsd/Version.xsd b/oet-parser/src/main/xsd/Version.xsd old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/ActionDescriptionTest.java b/oet-parser/src/test/java/org/openehr/am/template/ActionDescriptionTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/AnnotationTest.java b/oet-parser/src/test/java/org/openehr/am/template/AnnotationTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/ArchetypeSlotTest.java b/oet-parser/src/test/java/org/openehr/am/template/ArchetypeSlotTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/CompositionTemplateTest.java b/oet-parser/src/test/java/org/openehr/am/template/CompositionTemplateTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/MultipleConstraintTest.java b/oet-parser/src/test/java/org/openehr/am/template/MultipleConstraintTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/PathMapTest.java b/oet-parser/src/test/java/org/openehr/am/template/PathMapTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/QuantityConstraintTest.java b/oet-parser/src/test/java/org/openehr/am/template/QuantityConstraintTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/SectionEvaluationTest.java b/oet-parser/src/test/java/org/openehr/am/template/SectionEvaluationTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/SectionInstructionTest.java b/oet-parser/src/test/java/org/openehr/am/template/SectionInstructionTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/SectionTemplateTest.java b/oet-parser/src/test/java/org/openehr/am/template/SectionTemplateTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/SetCardinalityConstraintsTest.java b/oet-parser/src/test/java/org/openehr/am/template/SetCardinalityConstraintsTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/SetConstraintOnNamedNodeWithoutNameTest.java b/oet-parser/src/test/java/org/openehr/am/template/SetConstraintOnNamedNodeWithoutNameTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/SetMaxOccurrencesWithoutMinTest.java b/oet-parser/src/test/java/org/openehr/am/template/SetMaxOccurrencesWithoutMinTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/SetMixedConstraintsTest.java b/oet-parser/src/test/java/org/openehr/am/template/SetMixedConstraintsTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/SetMultipleEvaluationNameTest.java b/oet-parser/src/test/java/org/openehr/am/template/SetMultipleEvaluationNameTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/SetNestedEvaluationNameTest.java b/oet-parser/src/test/java/org/openehr/am/template/SetNestedEvaluationNameTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/SetNodeNameTest.java b/oet-parser/src/test/java/org/openehr/am/template/SetNodeNameTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/SetNodeOccurrencesTest.java b/oet-parser/src/test/java/org/openehr/am/template/SetNodeOccurrencesTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/SetOccurrencesAndNameTest.java b/oet-parser/src/test/java/org/openehr/am/template/SetOccurrencesAndNameTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/TemplateParseTest.java b/oet-parser/src/test/java/org/openehr/am/template/TemplateParseTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/TemplateTestBase.java b/oet-parser/src/test/java/org/openehr/am/template/TemplateTestBase.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/TermMapTest.java b/oet-parser/src/test/java/org/openehr/am/template/TermMapTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/TextConstraintTest.java b/oet-parser/src/test/java/org/openehr/am/template/TextConstraintTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/UTF8EncodingTest.java b/oet-parser/src/test/java/org/openehr/am/template/UTF8EncodingTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/java/org/openehr/am/template/UtilityTest.java b/oet-parser/src/test/java/org/openehr/am/template/UtilityTest.java old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-ACTION.medication.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ACTION.medication.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-ADMIN_ENTRY.heart_failure_contact.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ADMIN_ENTRY.heart_failure_contact.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-COMPOSITION.prescription.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-COMPOSITION.prescription.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-COMPOSITION.prescription_flattened.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-COMPOSITION.prescription_flattened.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-COMPOSITION.test.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-COMPOSITION.test.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-EVALUATION.adjusted_node_ids.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-EVALUATION.adjusted_node_ids.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-EVALUATION.hybrid_path_test.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-EVALUATION.hybrid_path_test.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-EVALUATION.medication_review.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-EVALUATION.medication_review.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-EVALUATION.review_of_procedures.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-EVALUATION.review_of_procedures.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-EVALUATION.structured_summary.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-EVALUATION.structured_summary.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-INSTRUCTION.medication.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-INSTRUCTION.medication.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_mod.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_mod.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_multiple_constraint_expected.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_multiple_constraint_expected.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_multiple_constraint_test.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_multiple_constraint_test.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_multiple_constraint_test2.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_multiple_constraint_test2.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_quantity_test.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_quantity_test.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_quantity_test2.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_quantity_test2.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_one.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_one.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_one.v2.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_one.v2.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_text_default.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_text_default.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_text_name.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_text_name.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_three.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_three.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_two.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_two.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-OBSERVATION.heart_failure_stage.v2.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-OBSERVATION.heart_failure_stage.v2.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-OBSERVATION.lab_test.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-OBSERVATION.lab_test.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-OBSERVATION.waist_hip.v2.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-OBSERVATION.waist_hip.v2.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.ad_hoc_heading.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.ad_hoc_heading.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.find_largest_node_id.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.find_largest_node_id.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.find_largest_node_id_2.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.find_largest_node_id_2.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.medications.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.medications.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.more_nested_sections.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.more_nested_sections.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.nested_sections.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.nested_sections.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.simple_section_name.v1.adl b/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.simple_section_name.v1.adl old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/log4j.properties b/oet-parser/src/test/resources/log4j.properties old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/prescription.oet b/oet-parser/src/test/resources/templates/prescription.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_action_description.oet b/oet-parser/src/test/resources/templates/test_action_description.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_annotation.oet b/oet-parser/src/test/resources/templates/test_annotation.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_composition.oet b/oet-parser/src/test/resources/templates/test_composition.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_composition2.oet b/oet-parser/src/test/resources/templates/test_composition2.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_composition3.oet b/oet-parser/src/test/resources/templates/test_composition3.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_composition4.oet b/oet-parser/src/test/resources/templates/test_composition4.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_composition5.oet b/oet-parser/src/test/resources/templates/test_composition5.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_default_coded_name.oet b/oet-parser/src/test/resources/templates/test_default_coded_name.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_default_coded_text.oet b/oet-parser/src/test/resources/templates/test_default_coded_text.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_default_text.oet b/oet-parser/src/test/resources/templates/test_default_text.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_hybrid_path.oet b/oet-parser/src/test/resources/templates/test_hybrid_path.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_max_value.oet b/oet-parser/src/test/resources/templates/test_max_value.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_min_value.oet b/oet-parser/src/test/resources/templates/test_min_value.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_more_nested_section.oet b/oet-parser/src/test/resources/templates/test_more_nested_section.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_multiple_constraint.oet b/oet-parser/src/test/resources/templates/test_multiple_constraint.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_multiple_constraint2.oet b/oet-parser/src/test/resources/templates/test_multiple_constraint2.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_multiple_constraint3.oet b/oet-parser/src/test/resources/templates/test_multiple_constraint3.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_name_default_coded_text.oet b/oet-parser/src/test/resources/templates/test_name_default_coded_text.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_named_path.oet b/oet-parser/src/test/resources/templates/test_named_path.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_named_path2.oet b/oet-parser/src/test/resources/templates/test_named_path2.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_named_path3.oet b/oet-parser/src/test/resources/templates/test_named_path3.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_nested_section.oet b/oet-parser/src/test/resources/templates/test_nested_section.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_nested_section_evaluation.oet b/oet-parser/src/test/resources/templates/test_nested_section_evaluation.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_quantity_constraint_excluded_units.oet b/oet-parser/src/test/resources/templates/test_quantity_constraint_excluded_units.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_quantity_constraint_included_units.oet b/oet-parser/src/test/resources/templates/test_quantity_constraint_included_units.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_quantity_constraint_included_units2.oet b/oet-parser/src/test/resources/templates/test_quantity_constraint_included_units2.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_quantity_constraint_included_units3.oet b/oet-parser/src/test/resources/templates/test_quantity_constraint_included_units3.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_quantity_constraint_magnitude.oet b/oet-parser/src/test/resources/templates/test_quantity_constraint_magnitude.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_quantity_constraint_mixed.oet b/oet-parser/src/test/resources/templates/test_quantity_constraint_mixed.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_quantity_constraint_precision.oet b/oet-parser/src/test/resources/templates/test_quantity_constraint_precision.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_section_evaluation.oet b/oet-parser/src/test/resources/templates/test_section_evaluation.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_section_evaluation2.oet b/oet-parser/src/test/resources/templates/test_section_evaluation2.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_section_instruction.oet b/oet-parser/src/test/resources/templates/test_section_instruction.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_section_instruction_tree.oet b/oet-parser/src/test/resources/templates/test_section_instruction_tree.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_set_cardinality_with_prohibited_node.oet b/oet-parser/src/test/resources/templates/test_set_cardinality_with_prohibited_node.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_set_cardinality_with_prohibited_node2.oet b/oet-parser/src/test/resources/templates/test_set_cardinality_with_prohibited_node2.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_set_cardinality_with_prohibited_node3.oet b/oet-parser/src/test/resources/templates/test_set_cardinality_with_prohibited_node3.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_set_evaluation_name.oet b/oet-parser/src/test/resources/templates/test_set_evaluation_name.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_set_evaluation_name_.oet b/oet-parser/src/test/resources/templates/test_set_evaluation_name_.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_set_mixed_constraints.oet b/oet-parser/src/test/resources/templates/test_set_mixed_constraints.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_set_multiple_evaluation_name.oet b/oet-parser/src/test/resources/templates/test_set_multiple_evaluation_name.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_set_named_node_constraint_without_name.oet b/oet-parser/src/test/resources/templates/test_set_named_node_constraint_without_name.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_set_occurrences_and_name.oet b/oet-parser/src/test/resources/templates/test_set_occurrences_and_name.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_set_occurrences_without_min.oet b/oet-parser/src/test/resources/templates/test_set_occurrences_without_min.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_set_occurrences_without_min2.oet b/oet-parser/src/test/resources/templates/test_set_occurrences_without_min2.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_simple_section.oet b/oet-parser/src/test/resources/templates/test_simple_section.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_text_constraints.oet b/oet-parser/src/test/resources/templates/test_text_constraints.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_text_name.oet b/oet-parser/src/test/resources/templates/test_text_name.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/templates/test_utf8_encoding.oet b/oet-parser/src/test/resources/templates/test_utf8_encoding.oet old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/terms.txt b/oet-parser/src/test/resources/terms.txt old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/terms_path.txt b/oet-parser/src/test/resources/terms_path.txt old mode 100755 new mode 100644 diff --git a/oet-parser/src/test/resources/test_path_map.txt b/oet-parser/src/test/resources/test_path_map.txt old mode 100755 new mode 100644 diff --git a/openehr-aom/docs/changes.txt b/openehr-aom/docs/changes.txt old mode 100755 new mode 100644 diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 862b9fad..f51b58bc 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -2,9 +2,9 @@ 4.0.0 - openehr - ref_impl_java - 1.0.5-SNAPSHOT + org.openehr.java-libs + java-libs + 0-SNAPSHOT openehr-aom jar @@ -22,12 +22,12 @@ - openehr + org.openehr.java-libs openehr-rm-core ${project.version} - openehr + org.openehr.java-libs openehr-rm-domain ${project.version} diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/Archetype.java b/openehr-aom/src/main/java/org/openehr/am/archetype/Archetype.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/Assertion.java b/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/Assertion.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/AssertionVariable.java b/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/AssertionVariable.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionBinaryOperator.java b/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionBinaryOperator.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionItem.java b/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionItem.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionLeaf.java b/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionLeaf.java index 3236a149..64da1e6c 100755 --- a/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionLeaf.java +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionLeaf.java @@ -45,7 +45,7 @@ public ReferenceType getReferenceType() { * @return */ public static final ExpressionLeaf intConstant(int i) { - return new ExpressionLeaf(ExpressionItem.INTEGER, new Integer(i), + return new ExpressionLeaf(ExpressionItem.INTEGER, Integer.valueOf(i), ExpressionLeaf.ReferenceType.CONSTANT); } @@ -56,7 +56,7 @@ public static final ExpressionLeaf intConstant(int i) { * @return */ public static final ExpressionLeaf realConstant(double d) { - return new ExpressionLeaf(ExpressionItem.REAL, new Double(d), + return new ExpressionLeaf(ExpressionItem.REAL, Double.valueOf(d), ExpressionLeaf.ReferenceType.CONSTANT); } diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionOperator.java b/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionOperator.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionUnaryOperator.java b/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionUnaryOperator.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/OperatorKind.java b/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/OperatorKind.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/ArchetypeConstraint.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/ArchetypeConstraint.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/ArchetypeInternalRef.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/ArchetypeInternalRef.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/ArchetypeSlot.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/ArchetypeSlot.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CAttribute.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CAttribute.java index c1154a8b..39675493 100755 --- a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CAttribute.java +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CAttribute.java @@ -75,8 +75,9 @@ protected List copyChildren() { for(CObject cobj : children) { if(cobj == null) { System.out.println("null cobj while copying c_attr: " + rmAttributeName + ", " + path()); - } - list.add(cobj.copy()); + } else { + list.add(cobj.copy()); + } } return list; } diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CComplexObject.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CComplexObject.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CDefinedObject.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CDefinedObject.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CDomainType.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CDomainType.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CMultipleAttribute.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CMultipleAttribute.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CObject.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CObject.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CPrimitiveObject.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CPrimitiveObject.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CReferenceObject.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CReferenceObject.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CSingleAttribute.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CSingleAttribute.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/Cardinality.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/Cardinality.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/ConstraintRef.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/ConstraintRef.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CBoolean.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CBoolean.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CDate.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CDate.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CDateTime.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CDateTime.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CDuration.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CDuration.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CInteger.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CInteger.java old mode 100755 new mode 100644 index 7d15bd57..24adcb45 --- a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CInteger.java +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CInteger.java @@ -86,9 +86,16 @@ public String getType() { */ @Override public boolean validValue(Object value) { - Integer integer = (Integer) value; - return (interval != null && interval.has(integer) || list != null - && list.contains(integer)); + Integer integer = null; + if ((value instanceof Integer)) + integer = (Integer) value; + else { + String strValue = value.toString(); + if (!strValue.isEmpty()) + integer = Integer.valueOf(strValue); + } + return ((this.interval != null) && (this.interval.has(integer))) + || ((this.list != null) && (this.list.contains(integer))); } /** diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CPrimitive.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CPrimitive.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CReal.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CReal.java index 1530489e..30b260a1 100755 --- a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CReal.java +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CReal.java @@ -14,6 +14,10 @@ */ package org.openehr.am.archetype.constraintmodel.primitive; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.openehr.rm.support.basic.Interval; @@ -47,7 +51,7 @@ public CReal(Interval interval, List list, this.assumedValue = assumedValue; this.defaultValue = defaultValue; } - + public CReal(Interval interval, List list, Double assumedValue) { this(interval, list, assumedValue, null); @@ -67,8 +71,9 @@ public CReal(Interval interval, List list) { * * @return name of the type */ + @Override public String getType() { - return "Double"; + return "Real"; // Note: This must be the RM type name, not the name of the Java datatype (otherwise e.g. the xml output will be wrong) } /** @@ -86,11 +91,12 @@ public List getList() { * @param value * @return true if valid */ + @Override public boolean validValue(Object value) { Double d = (Double) value; return ( interval != null && interval.has(d) || list != null && list.contains(d) ); - } + } /** * Interval of Dates specifying constraint @@ -100,7 +106,7 @@ public boolean validValue(Object value) { public Interval getInterval() { return interval; } - + @Override public boolean hasAssumedValue() { return assumedValue != null; @@ -110,7 +116,7 @@ public boolean hasAssumedValue() { public Object assumedValue() { return assumedValue; } - + @Override public boolean hasDefaultValue() { return defaultValue != null; @@ -127,9 +133,14 @@ public Object defaultValue() { * @param o * @return true if equals */ + @Override public boolean equals(Object o) { - if (this == o) return true; - if (!( o instanceof CReal )) return false; + if (this == o) { + return true; + } + if (!( o instanceof CReal )) { + return false; + } final CReal cobj = (CReal) o; @@ -146,6 +157,7 @@ public boolean equals(Object o) { * * @return hash code */ + @Override public int hashCode() { return new HashCodeBuilder(5, 23) .append(list) diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CString.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CString.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CTime.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CTime.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/ArchetypeOntology.java b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/ArchetypeOntology.java old mode 100755 new mode 100644 index c98a63cf..b5b3d73d --- a/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/ArchetypeOntology.java +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/ArchetypeOntology.java @@ -20,6 +20,7 @@ import org.apache.commons.lang.builder.HashCodeBuilder; import java.io.Serializable; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -34,9 +35,9 @@ public class ArchetypeOntology implements Serializable{ /** * Creates an ArchetypeOntology + * //TODO Can we add param validation? Any param can be null and it makes things brittle. * * @param primaryLanguage - * @param languages * @param terminologies * @param termDefinitionsList * @param constDefinitionsList @@ -44,14 +45,12 @@ public class ArchetypeOntology implements Serializable{ * @param constraintBindingList */ public ArchetypeOntology(String primaryLanguage, - List languages, List terminologies, List termDefinitionsList, List constDefinitionsList, List termBindingList, List constraintBindingList) { this.primaryLanguage = primaryLanguage; - this.languages = languages; this.terminologies = terminologies; this.termDefinitionsList = termDefinitionsList; this.constraintDefinitionsList = constDefinitionsList; @@ -62,6 +61,11 @@ public ArchetypeOntology(String primaryLanguage, termDefinitionMap = new HashMap>(); constraintDefinitionMap = new HashMap>(); loadDefs(termDefinitionMap, termDefinitionsList); + + // make sure the languages list is consistent + this.languages = new ArrayList(); + this.languages.addAll(termDefinitionMap.keySet()); + loadDefs(constraintDefinitionMap, constDefinitionsList); } diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/ArchetypeTerm.java b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/ArchetypeTerm.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/ConstraintBinding.java b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/ConstraintBinding.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/DefinitionItem.java b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/DefinitionItem.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/OntologyBinding.java b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/OntologyBinding.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/OntologyBindingItem.java b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/OntologyBindingItem.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/OntologyDefinitions.java b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/OntologyDefinitions.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/Query.java b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/Query.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/QueryBindingItem.java b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/QueryBindingItem.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/TermBindingItem.java b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/TermBindingItem.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/test/java/org/openehr/am/archetype/ArchetypePathTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/ArchetypePathTest.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/test/java/org/openehr/am/archetype/assertion/AssertionTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/assertion/AssertionTest.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/test/java/org/openehr/am/archetype/assertion/ExpressionToStringTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/assertion/ExpressionToStringTest.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/ArchetypeSlotTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/ArchetypeSlotTest.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/CAttributeTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/CAttributeTest.java old mode 100755 new mode 100644 index 23bae574..5678491b --- a/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/CAttributeTest.java +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/CAttributeTest.java @@ -16,97 +16,103 @@ * CAttributeTest * * @author Rong Chen - * @version 1.0 + * @version 1.0 */ package org.openehr.am.archetype.constraintmodel; +import org.openehr.am.archetype.constraintmodel.CAttribute.Existence; + import junit.framework.TestCase; public class CAttributeTest extends TestCase { - public CAttributeTest(String test) { - super(test); - } - - /** - * The fixture set up called before every test method. - */ - protected void setUp() throws Exception { - } - - /** - * The fixture clean up called after every test method. - */ - protected void tearDown() throws Exception { - } - - public void testParentNodePath() throws Exception { - CAttribute cattr = new TestCAttribute( - "/[at0001]/content[at0003]/items", "items"); - - assertEquals("/[at0001]/content[at0003]", cattr.parentNodePath()); - } - - public void testChildNodePathBase() throws Exception { - CAttribute cattr = new TestCAttribute( - "/[at0001]/content[at0003]/items", "items"); - assertEquals("/[at0001]/content[at0003]/items", - cattr.childNodePathBase()); - } - - - public void testEqualityOfTwoIdenticalAttributes() throws Exception { - CAttribute cattr1 = new TestCAttribute( - "/[at0001]/content[at0003]/items", "items"); - CAttribute cattr2 = new TestCAttribute( - "/[at0001]/content[at0003]/items", "items"); - - assertEquals(cattr1, cattr2); - assertEquals(cattr1.hashCode(), cattr2.hashCode()); - - } - - private static final class TestCAttribute extends CAttribute { - - public CAttribute copy() { - return null; - } - - public TestCAttribute(String path, String rmAttributeName) { - super(path, rmAttributeName, Existence.OPTIONAL, null); - } - - /** - * True if this node is a valid archetype node. - * - * @return ture if valid - */ - public boolean isValid() { - return false; - } - - /** - * True if the relative path exists at this node. - * - * @param path - * @return ture if has - * @throws IllegalArgumentException if path null - */ - public boolean hasPath(String path) { - return false; - } - - /** - * True if constraints represented by other are narrower than this node. - * - * @param constraint - * @return true if subset - * @throws IllegalArgumentException if constraint null - */ - public boolean isSubsetOf(ArchetypeConstraint constraint) { - return false; - } - } + public CAttributeTest(String test) { + super(test); + } + + /** + * The fixture set up called before every test method. + */ + @Override + protected void setUp() throws Exception { + } + + /** + * The fixture clean up called after every test method. + */ + @Override + protected void tearDown() throws Exception { + } + + public void testParentNodePath() throws Exception { + CAttribute cattr = new TestCAttribute( + "/[at0001]/content[at0003]/items", "items"); + + assertEquals("/[at0001]/content[at0003]", cattr.parentNodePath()); + assertEquals(Existence.OPTIONAL, cattr.getExistence().OPTIONAL); + } + + public void testChildNodePathBase() throws Exception { + CAttribute cattr = new TestCAttribute( + "/[at0001]/content[at0003]/items", "items"); + assertEquals("/[at0001]/content[at0003]/items", + cattr.childNodePathBase()); + } + + + public void testEqualityOfTwoIdenticalAttributes() throws Exception { + CAttribute cattr1 = new TestCAttribute( + "/[at0001]/content[at0003]/items", "items"); + CAttribute cattr2 = new TestCAttribute( + "/[at0001]/content[at0003]/items", "items"); + + assertEquals(cattr1, cattr2); + assertEquals(cattr1.hashCode(), cattr2.hashCode()); + + } + + private static final class TestCAttribute extends CAttribute { + + public CAttribute copy() { + return null; + } + + public TestCAttribute(String path, String rmAttributeName) { + super(path, rmAttributeName, Existence.OPTIONAL, null); + } + + /** + * True if this node is a valid archetype node. + * + * @return ture if valid + */ + public boolean isValid() { + return false; + } + + /** + * True if the relative path exists at this node. + * + * @param path + * @return ture if has + * @throws IllegalArgumentException if path null + */ + @Override + public boolean hasPath(String path) { + return false; + } + + /** + * True if constraints represented by other are narrower than this node. + * + * @param constraint + * @return true if subset + * @throws IllegalArgumentException if constraint null + */ + public boolean isSubsetOf(ArchetypeConstraint constraint) { + return false; + } + } } /* diff --git a/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/CObjectTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/CObjectTest.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/CPrimitiveObjectTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/CPrimitiveObjectTest.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CBooleanTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CBooleanTest.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CDateTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CDateTest.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CDateTimeTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CDateTimeTest.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CDurationTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CDurationTest.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CIntegerTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CIntegerTest.java old mode 100755 new mode 100644 index cb32e2cc..7d026246 --- a/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CIntegerTest.java +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CIntegerTest.java @@ -68,6 +68,10 @@ public void testValidValue() { assertTrue(ci.validValue(new Integer(0))); assertTrue(!ci.validValue(new Integer(-1))); assertTrue(!ci.validValue(new Integer(1))); + + assertTrue(ci.validValue("2")); + assertFalse(ci.validValue("")); + assertFalse(ci.validValue("-1")); } } diff --git a/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CRealTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CRealTest.java index 0a7403d7..c31a0048 100755 --- a/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CRealTest.java +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CRealTest.java @@ -50,6 +50,7 @@ public void testValidValue() throws Exception { assertTrue(cr.validValue(new Double(-10))); assertTrue(!cr.validValue(new Double(10))); assertTrue(!cr.validValue(new Double(11))); + assertTrue(cr.getType().equals("Real")); // Must not equal Double beause this is the RM type cr = new CReal(new Interval(new Double(1), null, true, false), null); diff --git a/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CStringTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CStringTest.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CTimeTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CTimeTest.java old mode 100755 new mode 100644 diff --git a/openehr-aom/src/test/java/org/openehr/am/archetype/ontology/ArchetypeOntologyTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/ontology/ArchetypeOntologyTest.java old mode 100755 new mode 100644 index 892dd7fc..3e665365 --- a/openehr-aom/src/test/java/org/openehr/am/archetype/ontology/ArchetypeOntologyTest.java +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/ontology/ArchetypeOntologyTest.java @@ -42,7 +42,7 @@ public void setUp() { items.add(item0002); constDefinitionsList.add(new OntologyDefinitions("sv", items)); - ontology = new ArchetypeOntology(primaryLanguage, languages, + ontology = new ArchetypeOntology(primaryLanguage, terminologies, termDefinitionsList, constDefinitionsList, null, null); } diff --git a/openehr-aom/src/test/java/org/openehr/am/archetype/ontology/ArchetypeTermTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/ontology/ArchetypeTermTest.java old mode 100755 new mode 100644 diff --git a/openehr-ap/docs/changes.txt b/openehr-ap/docs/changes.txt old mode 100755 new mode 100644 diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 5d1d9027..b0a0dd95 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -2,44 +2,43 @@ 4.0.0 - openehr - ref_impl_java - 1.0.5-SNAPSHOT + org.openehr.java-libs + java-libs + 0-SNAPSHOT openehr-ap jar openEHR Archetype Profile - http://www.openehr.org/projects/java.html + http://www.openehr.org/projects/java.html openEHR http://www.openehr.org/ 2004 - + Java implementation of the openEHR Archetype Profile - - + + - openehr + org.openehr.java-libs openehr-rm-core ${project.version} - openehr + org.openehr.java-libs openehr-rm-domain ${project.version} - openehr + org.openehr.java-libs openehr-aom ${project.version} - openehr + org.openehr.java-libs measure-serv ${project.version} - test commons-lang diff --git a/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/CDvState.java b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/CDvState.java old mode 100755 new mode 100644 diff --git a/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/NonTerminalState.java b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/NonTerminalState.java old mode 100755 new mode 100644 diff --git a/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/State.java b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/State.java old mode 100755 new mode 100644 diff --git a/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/StateMachine.java b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/StateMachine.java old mode 100755 new mode 100644 diff --git a/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/TerminalState.java b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/TerminalState.java old mode 100755 new mode 100644 diff --git a/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/Transition.java b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/Transition.java old mode 100755 new mode 100644 diff --git a/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvOrdinal.java b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvOrdinal.java index 23cca8f7..ced92cb4 100755 --- a/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvOrdinal.java +++ b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvOrdinal.java @@ -15,9 +15,7 @@ package org.openehr.am.openehrprofile.datatypes.quantity; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.*; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; @@ -29,7 +27,7 @@ /** * Class specifying constraints on instances of DV_ORDINAL. Custom - * constrainer type for instances of DV_ORDINAL. + * constraint type for instances of DV_ORDINAL. * * @author Rong Chen * @version 1.0 @@ -43,19 +41,16 @@ public class CDvOrdinal extends CDomainType { * @param occurrences * @param nodeID * @param list - * @throws IllegalArgument if list null or empty */ public CDvOrdinal(String path, Interval occurrences, - String nodeID, CAttribute parent, Set list, + String nodeID, CAttribute parent, List list, Ordinal defaultValue, Ordinal assumedValue) { - super(list == null, path, "DV_ORDINAL", occurrences, nodeID, defaultValue, assumedValue, parent); - if (list != null && list.isEmpty()) { throw new IllegalArgumentException("list is empty"); } - this.list = list == null ? null : new LinkedHashSet(list); + this.list = list == null ? null : new ArrayList(list); } @Override @@ -69,12 +64,10 @@ public CDvOrdinal copy() { * * @param path * @param occurrences - * @param nodeID * @param list - * @throws IllegalArgument if list null or empty */ public CDvOrdinal(String path, Interval occurrences, - Set list) { + List list) { this(path, occurrences, null, null, list, null, null); } @@ -101,11 +94,11 @@ public boolean isSubsetOf(ArchetypeConstraint constraint) { * * @return unmodifiable set of Ordinal */ - public Set getList() { + public List getList() { if (list == null) { return null; } - return Collections.unmodifiableSet(list); + return Collections.unmodifiableList(list); } /** @@ -153,7 +146,7 @@ public CComplexObject standardEquivalent() { return null; } - private Set list; + private List list; } /* diff --git a/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvQuantity.java b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvQuantity.java index adea374d..4589b90d 100755 --- a/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvQuantity.java +++ b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvQuantity.java @@ -56,8 +56,9 @@ public CDvQuantity(String path, Interval occurrences, if (list != null && list.isEmpty()) { throw new IllegalArgumentException("empty list"); } - this.list = list == null ? list - : new ArrayList(list); + if(list != null) { + this.list = new ArrayList(list); + } this.property = property; } diff --git a/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvQuantityItem.java b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvQuantityItem.java old mode 100755 new mode 100644 diff --git a/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvScale.java b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvScale.java new file mode 100644 index 00000000..f768ef2a --- /dev/null +++ b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvScale.java @@ -0,0 +1,157 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CDvOrdinal" + * keywords: "openehr archetype profile" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2006 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ + +package org.openehr.am.openehrprofile.datatypes.quantity; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; +import org.openehr.am.archetype.constraintmodel.CAttribute; +import org.openehr.am.archetype.constraintmodel.CComplexObject; +import org.openehr.am.archetype.constraintmodel.CDomainType; +import org.openehr.rm.support.basic.Interval; + +/** Class specifying constraints on instances of DV_SCALE. Custom + * constraint type for instances of DV_SCALE. + * @author Sebastian Garde + * @version 1.0 */ +public class CDvScale extends CDomainType { + + /** Creates a CDvOrdinal + * @param path + * @param occurrences + * @param nodeID + * @param list */ + public CDvScale(String path, Interval occurrences, String nodeID, CAttribute parent, List list, Scale defaultValue, Scale assumedValue) { + super(list == null, path, "DV_SCALE", occurrences, nodeID, defaultValue, assumedValue, parent); + if (list != null && list.isEmpty()) { + throw new IllegalArgumentException("list is empty"); + } + this.list = list == null ? null : new ArrayList(list); + } + + @Override + public CDvScale copy() { + return new CDvScale(path(), getOccurrences(), getNodeId(), getParent(), list, getDefaultValue(), getAssumedValue()); + } + + /** Convenience constructor + * @param path + * @param occurrences + * @param list */ + public CDvScale(String path, Interval occurrences, List list) { + this(path, occurrences, null, null, list, null, null); + } + + @Override + public boolean isValid() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean hasPath(String path) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isSubsetOf(ArchetypeConstraint constraint) { + // TODO Auto-generated method stub + return false; + } + + /** List of allowed DV_ORDINAL values. + * @return unmodifiable set of Ordinal */ + public List getList() { + if (list == null) { + return null; + } + return Collections.unmodifiableList(list); + } + + /** Returns true if fields are the same */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof CDvScale)) { + return false; + } + + final CDvScale scale = (CDvScale) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)).append(list, scale.list) + .isEquals(); + } + + /** Returns the hashcode of this object + * @return hashcode */ + @Override + public int hashCode() { + return new HashCodeBuilder(3, 19) + .appendSuper(super.hashCode()) + .append(list) + .toHashCode(); + } + + @Override + public boolean validValue(Scale arg0) { + // TODO Auto-generated method stub + return true; + } + + @Override + public CComplexObject standardEquivalent() { + // TODO Auto-generated method stub + return null; + } + + private List list; +} + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the 'License'); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is CDvScale.java + * + * The Initial Developer of the Original Code is Sebastian Garde. + * Portions created by the Initial Developer are Copyright (C) 2020 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Rong Chen + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * ***** END LICENSE BLOCK ***** */ \ No newline at end of file diff --git a/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/Ordinal.java b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/Ordinal.java old mode 100755 new mode 100644 diff --git a/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/Scale.java b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/Scale.java new file mode 100644 index 00000000..c94ebfd3 --- /dev/null +++ b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/Scale.java @@ -0,0 +1,159 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Ordinal" + * keywords: "openehr archetype profile" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ + +package org.openehr.am.openehrprofile.datatypes.quantity; + + +import java.io.Serializable; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.datatypes.text.CodePhrase; + +/** Scale item included in the list of a scale constraint. Immutable. + * @author Sebastian Garde + * @version 1.0 */ +public final class Scale implements Comparable, Serializable { + + /** Constructs an scale + * @param value + * @param symbol not null + * @throws IllegalArgumentException if symbol null */ + public Scale(double value, CodePhrase symbol) { + if(symbol == null) { + throw new IllegalArgumentException("symbol null"); + } + this.value = value; + this.display = "" + value; + this.symbol = symbol; + } + + public Scale(String display, CodePhrase symbol) { + if (symbol == null) { + throw new IllegalArgumentException("symbol null"); + } + this.value = Double.parseDouble(display); + this.display = display; + this.symbol = symbol; + } + + /** The integer value of this scale + * @return no less than 0 */ + public double getValue() { + return value; + } + + public String getDisplay() { + return display; + } + + /** The symbol of this scale + * @return symbol */ + public CodePhrase getSymbol() { + return symbol; + } + + /** + * Return string presentation of this ordinal + * + * @return string form + */ + @Override + public String toString() { + return "[" + symbol.getTerminologyId() + "] " + value + + "|" + symbol.getCodeString(); + } + + /** + * Returns true if fields are the same + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Scale)) { + return false; + } + + final Scale scale = (Scale) o; + + return new EqualsBuilder() + .append(value, scale.value).append(symbol, scale.symbol) + .isEquals(); + } + + + /** + * @param o the Object to be compared. + * @return a negative integer, zero, or a positive integer as this object + * is less than, equal to, or greater than the specified object. + * @throws ClassCastException if the specified object's type prevents it + * from being compared to this Object. + */ + public int compareTo(Object o) { + final Scale scale = (Scale) o; + if (value > scale.value) { + return 1; + } + if (value < scale.value) { + return -1; + } + return 0; + } + + @Override + public int hashCode() { + return new HashCodeBuilder(7, 17) + .append(value) + .append(symbol) + .toHashCode(); + } + + /* fields */ + private final double value; + private final String display; // The value as it is to be displayed (i.e. as it wasstated originally, e.g. 2 instead of 2.0 + private final CodePhrase symbol; +} + +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the 'License'); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ordinal.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * ***** END LICENSE BLOCK ***** + */ \ No newline at end of file diff --git a/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/text/CCodePhrase.java b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/text/CCodePhrase.java old mode 100755 new mode 100644 diff --git a/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/basic/CDvStateTest.java b/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/basic/CDvStateTest.java old mode 100755 new mode 100644 diff --git a/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvOrdinalTest.java b/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvOrdinalTest.java index 8e797e54..0e0612e3 100755 --- a/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvOrdinalTest.java +++ b/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvOrdinalTest.java @@ -15,7 +15,7 @@ public void testCreateEmptyCDvOrdinal() { Interval occurrences = new Interval(1,1); String nodeId = "at0010"; CAttribute parent = null; - Set list = null; + List list = null; CDvOrdinal c = new CDvOrdinal(path, occurrences, nodeId, parent, list, null, null); @@ -37,11 +37,11 @@ public void testCreateCDvOrdinalWithAssumedValue() { public void testEqualsWithDifferentOrdinal() { Interval occurrences = new Interval(1,1); - Set set1 = new HashSet(); + List set1 = new ArrayList(); Ordinal ord1 = new Ordinal(1, new CodePhrase("local", "at0001")); set1.add(ord1); - Set set2 = new HashSet(); + List set2 = new ArrayList(); Ordinal ord2 = new Ordinal(1, new CodePhrase("local", "at0003")); set2.add(ord2); @@ -56,11 +56,11 @@ public void testEqualsWithDifferentOrdinal() { public void testEqualsWithSameOrdinal() { Interval occurrences = new Interval(1,1); - Set set1 = new HashSet(); + List set1 = new ArrayList(); Ordinal ord1 = new Ordinal(1, new CodePhrase("local", "at0001")); set1.add(ord1); - Set set2 = new HashSet(); + List set2 = new ArrayList(); Ordinal ord2 = new Ordinal(1, new CodePhrase("local", "at0001")); set2.add(ord2); diff --git a/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvQuantityItemTest.java b/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvQuantityItemTest.java old mode 100755 new mode 100644 diff --git a/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvQuantityTest.java b/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvQuantityTest.java old mode 100755 new mode 100644 diff --git a/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/OrdinalTest.java b/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/OrdinalTest.java old mode 100755 new mode 100644 diff --git a/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/text/CCodePhraseTest.java b/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/text/CCodePhraseTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index d762ed15..adf8bb3b 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -2,9 +2,9 @@ 4.0.0 - openehr - ref_impl_java - 1.0.5-SNAPSHOT + org.openehr.java-libs + java-libs + 0-SNAPSHOT openehr-rm-core jar @@ -28,7 +28,7 @@ joda-time joda-time - 1.3 + 2.2 junit @@ -37,7 +37,7 @@ test - openehr + org.openehr.java-libs measure-serv ${project.version} diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/Attribute.java b/openehr-rm-core/src/main/java/org/openehr/rm/Attribute.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/FullConstructor.java b/openehr-rm-core/src/main/java/org/openehr/rm/FullConstructor.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/RMObject.java b/openehr-rm-core/src/main/java/org/openehr/rm/RMObject.java index 23700ebc..b671a535 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/RMObject.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/RMObject.java @@ -21,7 +21,7 @@ * @version 1.0 */ public abstract class RMObject implements java.io.Serializable { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; } /* diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Archetyped.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Archetyped.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/FeederAudit.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/FeederAudit.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/FeederAuditDetails.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/FeederAuditDetails.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Link.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Link.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Locatable.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Locatable.java index 01d0ec13..f2aa9479 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Locatable.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Locatable.java @@ -46,10 +46,10 @@ public abstract class Locatable extends Pathable implements Settable, Cloneable * or links not null and empty */ protected Locatable(UIDBasedID uid, String archetypeNodeId, DvText name, - Archetyped archetypeDetails,FeederAudit feederAudit, - Set links, Pathable parent) { + Archetyped archetypeDetails,FeederAudit feederAudit, + Set links, Pathable parent) { super(parent); - + if (archetypeNodeId == null) { throw new IllegalArgumentException("null archetypeNodeId"); } @@ -105,7 +105,7 @@ public String getArchetypeNodeId() { public String getOriginalArchetypeNodeId() { return originalArchetypeNodeId; } - + public String setOriginalArchetypeNodeId(String originalArchetypeNodeId) { return this.originalArchetypeNodeId = originalArchetypeNodeId; } @@ -152,8 +152,8 @@ public FeederAudit getFeederAudit() { */ public Set getLinks() { return links; - } - + } + /** * True if this node is the root of an archetyped structure * @@ -172,32 +172,34 @@ public boolean isArchetypeRoot() { */ public abstract String pathOfItem(Pathable item); - + /* * Simple fix doesn't take care of "/" inside predicates * e.g. data/events[at0006 and name/value='any event'] * * OG - 2010-03-15: Added fix that seems to solve this problem. - */ + */ public static List dividePathIntoSegments(String path) { List segments = new ArrayList(); StringTokenizer tokens = new StringTokenizer(path, "/"); while(tokens.hasMoreTokens()) { String next = tokens.nextToken(); + StringBuffer buffer = new StringBuffer(); if (next.matches(".+\\[.+[^\\]]$")) { - do { - next = next + "/" + tokens.nextToken(); - } while (!next.matches(".*]$")); + do { + buffer.append(next + "/" + tokens.nextToken()); + next = buffer.toString(); + } while (!next.matches(".*]$")); } segments.add(next); } return segments; } - + /* * generic path evaluation covers all rmClass - */ + */ private Object genericPathEvaluator(String path, Object object) { if(path == null || object == null) { return null; @@ -205,44 +207,50 @@ private Object genericPathEvaluator(String path, Object object) { List segments = dividePathIntoSegments(path); return evaluatePathSegment(segments, object); } - + /* * Evaluate recursively the path segments */ - private Object evaluatePathSegment(List pathSegments, + private Object evaluatePathSegment(List pathSegments, Object object) { if(pathSegments.isEmpty()) { return object; } String pathSegment = pathSegments.remove(0); Object value = null; - + int index = pathSegment.indexOf("["); String expression = null; String attributeName = null; - + // has [....] predicate expression if(index > 0) { - + assert(pathSegment.indexOf("]") > index); - - attributeName = pathSegment.substring(0, index); - expression = pathSegment.substring(index + 1, - pathSegment.indexOf("]")); + + attributeName = pathSegment.substring(0, index); + expression = pathSegment.substring(index + 1, + pathSegment.indexOf("]")); } else { attributeName = pathSegment; } - + value = getAttributeValue(object, attributeName); if(expression != null && value != null ) { value = processPredicate(expression, value); - } + } + if(expression == null && value instanceof ArrayList && !pathSegments.isEmpty()) { + ArrayList arrayList = ((ArrayList)value); + if (!arrayList.isEmpty()){ + value = arrayList.get(0); + } + } if(value != null) { return evaluatePathSegment(pathSegments, value); } return null; } - + public String toCamelCase(String underscoreSeparated) { if( ! underscoreSeparated.contains("_")) { return underscoreSeparated; @@ -259,24 +267,23 @@ public String toCamelCase(String underscoreSeparated) { } } return buf.toString(); - } - + } + public String toFirstUpperCaseCamelCase(String name) { name = toCamelCase(name); - return name.substring(0, 1).toUpperCase() + return name.substring(0, 1).toUpperCase() + name.substring(1); } - + /** * Processes the predicate expression on given object * 1. if the object is a container, select the _first_ matching one * 2. only return the object if itself meets the predicate - * + * * only shortcut expressions for at0000 and name are supported * for example: [at0001, 'node name'] - * + * * @param expression - * @param value * @return null if there is no match */ Object processPredicate(String expression, Object object) { @@ -284,7 +291,7 @@ Object processPredicate(String expression, Object object) { String archetypeNodeId = null; expression = expression.trim(); int index; - + // shortcut syntax, [at0001, 'standing'] if(expression.contains(",") // avoid [at0001 and/value='status, 2nd'] @@ -293,14 +300,14 @@ Object processPredicate(String expression, Object object) { archetypeNodeId = expression.substring(0, index).trim(); name = expression.substring(expression.indexOf("'") + 1, expression.lastIndexOf("'")); - + // [at0006 and name/value='any event'] // [at0006 AND name/value='any event'] } else if(expression.contains(" AND ") || expression.contains(" and ")) { - + // OG - 20100401: Fixed bug where the name contained 'AND' or 'and', - // i.e. 'MEDICINSK BEHANDLING'. + // i.e. 'MEDICINSK BEHANDLING'. if(expression.contains(" AND ")) { index = expression.indexOf(" AND "); } else { @@ -308,17 +315,17 @@ Object processPredicate(String expression, Object object) { } archetypeNodeId = expression.substring(0, index).trim(); name = expression.substring(expression.indexOf("'") + 1, - expression.lastIndexOf("'")); - // just name, ['standing'] + expression.lastIndexOf("'")); + // just name, ['standing'] } else if (expression.startsWith("'") && expression.endsWith("'")) { name = expression.substring(1, expression.length() - 1); - + // archetyped root node id or at-coded node - // [at0006] or [openEHR-EHR-OBSERVATION.laboratory-lipids.v1] + // [at0006] or [openEHR-EHR-OBSERVATION.laboratory-lipids.v1] } else { archetypeNodeId = expression; } - + Iterable collection = null; if(object instanceof Iterable) { collection = (Iterable) object; @@ -327,24 +334,24 @@ Object processPredicate(String expression, Object object) { list.add(object); collection = list; } - + for(Object item : collection) { if(item instanceof Locatable) { Locatable locatable = (Locatable) item; - if(archetypeNodeId != null + if(archetypeNodeId != null && !locatable.archetypeNodeId.equals(archetypeNodeId)) { continue; } if(name != null && !locatable.name.getValue().equals(name)) { continue; - } + } } // TODO other non-locatable predicates!! // e.g. time > 10:20:15 return item; // found a match! } return null; - } + } /** * The item at a path that is relative to this item. @@ -355,14 +362,14 @@ Object processPredicate(String expression, Object object) { */ public Object itemAtPath(String path) { if (path == null) { - throw new IllegalArgumentException("invalid path: " + path); + throw new IllegalArgumentException("invalid path: null"); } if (Locatable.ROOT.equals(path) || path.equals(whole())) { return this; } return genericPathEvaluator(path, this); } - + /* * Retrieves the value of named attribute of given object */ @@ -371,7 +378,7 @@ private Object getAttributeValue(Object obj, String attribute) { Object value = null; Method getter = null; String getterName = "get" + toFirstUpperCaseCamelCase(attribute); - + try { getter = rmClass.getMethod(getterName, null); value = getter.invoke(obj, null); @@ -382,7 +389,7 @@ private Object getAttributeValue(Object obj, String attribute) { } return value; } - + /* * Sets the value of named attribute of given object */ @@ -395,14 +402,14 @@ private void setAttributeValue(Object obj, String attribute, Object value) { if(setter == null) { throw new IllegalArgumentException("unkown setter method: " + setterName + " for rmClass=" + rmClass); } - setter.invoke(obj, value); - - } catch(Exception e) { + setter.invoke(obj, value); + + } catch(Exception e) { // TODO log as kernel warning - e.printStackTrace(); + e.printStackTrace(); } } - + private Method getMethodByName(Class klass, String method) { Method[] methods = klass.getMethods(); for(Method m : methods) { @@ -412,8 +419,8 @@ private Method getMethodByName(Class klass, String method) { } return null; } - - + + public void set(String path, Object value) { int i = path.lastIndexOf("/"); if(i < 0 || i == path.length()) { @@ -425,17 +432,17 @@ public void set(String path, Object value) { objPath = path.substring(0, i); } String attributeName = path.substring(i + 1); - + Object obj = itemAtPath(objPath); if(obj == null) { throw new IllegalArgumentException("Item not found on path: " + path); } setAttributeValue(obj, attributeName, value); } - + /** * Computes the path of parent object - * + * * @param path * @return */ @@ -455,12 +462,12 @@ public static String parentPath(String path) { } return buf.toString(); } - - public void addChild(String path, Object child) { + + public void addChild(String path, Object child) { List list = dividePathIntoSegments(path); int pathLevel = list.size(); String objPath = PATH_SEPARATOR; - + if(pathLevel > 1) { StringBuffer buf = new StringBuffer(); for(int j = 0; j < pathLevel - 1; j++) { @@ -468,27 +475,27 @@ public void addChild(String path, Object child) { buf.append(list.get(j)); } objPath = buf.toString(); - } - + } + Object obj = itemAtPath(objPath); if(obj == null) { throw new IllegalArgumentException("Item not found on path: " + path); - } - + } + String attributeName = list.get(list.size() - 1); - Object attributeValue = getAttributeValue(obj, attributeName); + Object attributeValue = getAttributeValue(obj, attributeName); if(attributeValue == null) { attributeValue = new ArrayList(); } - if(attributeValue instanceof List) { + if(attributeValue instanceof List) { List parent = (List) attributeValue; - parent.add(child); + parent.add(child); } else { throw new IllegalArgumentException( "non-container parent attribute on path: " + path); - } + } } - + public void removeChild(String path) { int i = path.lastIndexOf(PATH_SEPARATOR); if(i < 0 || i == path.length()) { @@ -506,37 +513,37 @@ public void removeChild(String path) { } objPath = buf.toString(); } - + Object obj = itemAtPath(objPath); if(obj == null) { throw new IllegalArgumentException("Item not found on path: " + path); } - + Object child = itemAtPath(path); if(child == null) { throw new IllegalArgumentException("Unknown child on path: " + path); } - - String attributeName = list.get(list.size() - 1); + + String attributeName = list.get(list.size() - 1); int predicateIndex = attributeName.indexOf("["); if(predicateIndex > 0) { attributeName = attributeName.substring(0, predicateIndex); } Object attributeValue = getAttributeValue(obj, attributeName); - + if(attributeValue == null) { throw new IllegalArgumentException( "parent attribute not found on path: " + path); } if(attributeValue instanceof List) { - + List parent = (List) attributeValue; parent.remove(child); - + } else { throw new IllegalArgumentException( "non-container parent attribute on path: " + path); - } + } } /** @@ -559,7 +566,7 @@ public DvText concept() { * @return string presentation */ public String toString() { - return archetypeNodeId.equals(name) ? + return archetypeNodeId.equals(name.getValue()) ? archetypeNodeId.toString() : archetypeNodeId + ", " + name; } @@ -572,7 +579,7 @@ public String toString() { public boolean equals(Object o) { if (this == o) return true; if (!( o instanceof Locatable )) return false; - + final Locatable loc = (Locatable) o; return new EqualsBuilder() .appendSuper(super.equals(o)) @@ -620,13 +627,13 @@ public String whole() { public String nodeName() { return "[" + getName().getValue() + "]"; } - + public String atNode() { return ROOT + "[" + getArchetypeNodeId() + "]"; } - + // POJO start - protected Locatable() { + protected Locatable() { } protected void setUid(UIDBasedID uid) { @@ -651,7 +658,7 @@ protected void setFeederAudit(FeederAudit feederAudit) { protected void setLinks(Set links) { this.links = links; - } + } // POJO end /** @@ -659,7 +666,7 @@ protected void setLinks(Set links) { */ public static final String PATH_SEPARATOR = "/"; public static final String ROOT = PATH_SEPARATOR; - + /* fields */ private UIDBasedID uid; private String archetypeNodeId; @@ -668,7 +675,7 @@ protected void setLinks(Set links) { private Archetyped archetypeDetails; private FeederAudit feederAudit; private Set links; - + } /* diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Pathable.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Pathable.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Settable.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Settable.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/Contribution.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/Contribution.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/ImportedVersion.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/ImportedVersion.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/OriginalVersion.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/OriginalVersion.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/Version.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/Version.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/VersionedObject.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/VersionedObject.java index 0a2c178c..0495dd61 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/VersionedObject.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/VersionedObject.java @@ -103,7 +103,7 @@ private VersionedObject(HierObjectID uid, ObjectRef ownerID, * @param contribution * @param item */ - public synchronized void commitImportedVersion(OriginalVersion item, AuditDetails commitAudit, + public void commitImportedVersion(OriginalVersion item, AuditDetails commitAudit, ObjectRef contribution, String signature) { commitVersionCheck(item.getUid(), item.getPrecedingVersionUid()); @@ -111,7 +111,7 @@ public synchronized void commitImportedVersion(OriginalVersion item, AuditDet addVersion(version); } - private synchronized void commitVersionCheck(ObjectVersionID vUid, ObjectVersionID precedingVUid) { + private void commitVersionCheck(ObjectVersionID vUid, ObjectVersionID precedingVUid) { if (versionCount() > 0 && !hasVersionID(precedingVUid)) { throw new IllegalArgumentException("precedingVersionID not found"); } @@ -120,7 +120,7 @@ private synchronized void commitVersionCheck(ObjectVersionID vUid, ObjectVersion } } - private synchronized void addVersion(Version version) { + private void addVersion(Version version) { if (!version.getUid().versionTreeID().isBranch()) { int trunkNo = Integer.parseInt(version.getUid().versionTreeID().trunkVersion()); if (trunkNo != trunkCounter + 1) { @@ -144,7 +144,7 @@ private synchronized void addVersion(Version version) { * @param lifecycleState * @param terminologyService */ - public synchronized void commitOriginalVersion(ObjectVersionID versionID, + public void commitOriginalVersion(ObjectVersionID versionID, ObjectVersionID precedingVersionID, T data, AuditDetails commitAudit, ObjectRef contribution, DvCodedText lifecycleState, String signature, TerminologyService terminologyService) { @@ -167,7 +167,7 @@ public synchronized void commitOriginalVersion(ObjectVersionID versionID, * @param lifecycleState * @param terminologyService */ - public synchronized void commitOriginalMergedVersion(ObjectVersionID versionID, + public void commitOriginalMergedVersion(ObjectVersionID versionID, ObjectVersionID precedingVersionID, T data, DvCodedText lifecycleState, AuditDetails commitAudit, ObjectRef contribution, Set otherInputVersionUids, String signature, @@ -215,7 +215,7 @@ public DvDateTime getTimeCreated() { * * @return all versions */ - public synchronized List> allVersions() { + public List> allVersions() { // todo: fix the order of this list return new ArrayList>(idVersionMap.values()); } @@ -225,7 +225,7 @@ public synchronized List> allVersions() { * * @return List */ - public synchronized List allVersionIDs() { + public List allVersionIDs() { // todo: fix the order of list return new ArrayList(idVersionMap.keySet()); } @@ -235,7 +235,7 @@ public synchronized List allVersionIDs() { * * @return version count */ - public synchronized int versionCount() { + public int versionCount() { return idVersionMap.size(); } @@ -246,7 +246,7 @@ public synchronized int versionCount() { * @return true if has * @throws IllegalArgumentException */ - public synchronized boolean hasVersionID(ObjectVersionID id) { + public boolean hasVersionID(ObjectVersionID id) { if (id == null) { throw new IllegalArgumentException("null id"); } @@ -261,7 +261,7 @@ public synchronized boolean hasVersionID(ObjectVersionID id) { * @return true if has version * @throws IllegalArgumentException if time null */ - public synchronized boolean hasVersionAtTime(DvDateTime time) { + public boolean hasVersionAtTime(DvDateTime time) { if (time == null) { throw new IllegalArgumentException("null time"); } @@ -288,7 +288,7 @@ public boolean isOriginalVersion(ObjectVersionID uid) { * @return null if not found * @throws IllegalArgumentException if id null */ - public synchronized Version versionWithID(ObjectVersionID id) { + public Version versionWithID(ObjectVersionID id) { if (id == null) { throw new IllegalArgumentException("null id"); } @@ -302,7 +302,7 @@ public synchronized Version versionWithID(ObjectVersionID id) { * @return null if not found * @throws IllegalArgumentException if time null */ - public synchronized Version versionAtTime(DvDateTime time) { + public Version versionAtTime(DvDateTime time) { if (time == null) { throw new IllegalArgumentException("null time"); } @@ -314,7 +314,7 @@ public synchronized Version versionAtTime(DvDateTime time) { * * @return lastest version */ - public synchronized Version latestVersion() { + public Version latestVersion() { return (Version) timeVersionMap.get(timeVersionMap.lastKey()); } @@ -323,7 +323,7 @@ public synchronized Version latestVersion() { * Return the most recetly added trunk version * */ - public synchronized Version latestTrunkVersion() { + public Version latestTrunkVersion() { return (Version) idVersionMap.get(latestTrunkUid); } @@ -333,7 +333,6 @@ public synchronized Version latestTrunkVersion() { * */ public DvCodedText latestTrunkLifeCycleSate() { - Version trunk = latestTrunkVersion(); return latestTrunkVersion().getLifecycleState(); } @@ -365,7 +364,7 @@ public RevisionHistory revisionHistory() { * @param attestation * @param versionID */ - public synchronized void commitAttestation(Attestation attestation, + public void commitAttestation(Attestation attestation, ObjectVersionID versionID) { if (attestation == null) { throw new IllegalArgumentException("null attestation"); diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/directory/Folder.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/directory/Folder.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/directory/VersionedFolder.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/directory/VersionedFolder.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/Attestation.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/Attestation.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/AuditDetails.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/AuditDetails.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/Participation.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/Participation.java old mode 100755 new mode 100644 index 602fe14a..088621d5 --- a/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/Participation.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/Participation.java @@ -1,218 +1,221 @@ -/* - * component: "openEHR Reference Implementation" - * description: "Class Participation" - * keywords: "common" - * - * author: "Rong Chen " - * support: "Acode HB " - * copyright: "Copyright (c) 2004 Acode HB, Sweden" - * license: "See notice at bottom of class" - * - * file: "$URL: http://svn.openehr.org/ref_impl_java/TRUNK/libraries/src/java/org/openehr/rm/common/generic/Participation.java $" - * revision: "$LastChangedRevision: 2 $" - * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" - */ -package org.openehr.rm.common.generic; - -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.openehr.rm.Attribute; -import org.openehr.rm.FullConstructor; -import org.openehr.rm.RMObject; -import org.openehr.rm.datatypes.quantity.DvInterval; -import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; -import org.openehr.rm.datatypes.text.DvCodedText; -import org.openehr.rm.datatypes.text.DvText; -import org.openehr.rm.support.terminology.TerminologyService; - -/** - * Model of a participation of a Party (any Actor or Role) in an activity. - * Instances of this object are immutable. - * - * @author Rong Chen - * @version 1.0 - */ -public final class Participation extends RMObject { - - /** - * Constructs a Participation - * - * @param performer not null - * @param function not null - * @param mode not null and exists - * @param time - * @param terminologyService not null - * @throws IllegalArgumentException if function null - * or mode invalid or performer null - */ - @FullConstructor - public Participation( - @Attribute(name = "performer", required = true)PartyProxy performer, - @Attribute(name = "function", required = true)DvText function, - @Attribute(name = "mode", required = true)DvCodedText mode, - @Attribute(name = "time")DvInterval time, - @Attribute(name = "terminologyService", system = true)TerminologyService terminologyService) { - if (performer == null) { - throw new IllegalArgumentException("null performer"); - } - if (function == null) { - throw new IllegalArgumentException("null function"); - } - if (mode == null) { - throw new IllegalArgumentException("null mode"); - } - if (terminologyService == null) { - throw new IllegalArgumentException("null terminologyService"); - } - - if (( function instanceof DvCodedText ) - && ( !terminologyService.terminology( - TerminologyService.OPENEHR) - .codesForGroupName("participation function", "en") - .contains(((DvCodedText) function).getDefiningCode()))) { - throw new IllegalArgumentException("unkown function: " + function); - } - - if (!terminologyService.terminology(TerminologyService.OPENEHR) - .codesForGroupName("participation mode", "en") - .contains(mode.getDefiningCode())) { - throw new IllegalArgumentException("unkown mode: " + mode); - } - this.performer = performer; - this.function = function; - this.mode = mode; - this.time = time; - } - - /** - * The party participating in the activity. - * - * @return performer - */ - public PartyProxy getPerformer() { - return performer; - } - - /** - * The function of the Party in this participation - * - * @return function - */ - public DvText getFunction() { - return function; - } - - /** - * The mode of the performer / activity interaction, - * eg present, by telephone, by email etc. - * - * @return mode - */ - public DvCodedText getMode() { - return mode; - } - - /** - * The time interval during which the participation took place, - * if it is used in an observational context (ie recording facts - * about the past); or the intended time interval of the - * participation when used in future contexts, such as EHR - * Instructions. - * - * @return DvInterval - */ - public DvInterval getTime() { - return time; - } - - /** - * Equals if two participations have same values - * - * @param o - * @return true if equals - */ - public boolean equals(Object o) { - if (this == o) return true; - if (!( o instanceof Participation )) return false; - - final Participation p = (Participation) o; - - return new EqualsBuilder() - .append(performer, p.performer) - .append(function, p.function) - .append(mode, p.mode) - .append(time, p.time) - .isEquals(); - } - - /** - * Return a hash code of this object - * - * @return hash code - */ - public int hashCode() { - return new HashCodeBuilder(7, 19) - .append(performer) - .append(function) - .append(mode) - .append(time) - .toHashCode(); - } - - // POJO start - Participation() { - } - - void setPerformer(PartyProxy performer) { - this.performer = performer; - } - - void setFunction(DvText function) { - this.function = function; - } - - void setMode(DvCodedText mode) { - this.mode = mode; - } - - void setTime(DvInterval time) { - this.time = time; - } - // POJO end - - /* fields */ - private PartyProxy performer; - private DvText function; - private DvCodedText mode; - private DvInterval time; -} - -/* - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the 'License'); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an 'AS IS' basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Participation.java - * - * The Initial Developer of the Original Code is Rong Chen. - * Portions created by the Initial Developer are Copyright (C) 2003-2004 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Software distributed under the License is distributed on an 'AS IS' basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * ***** END LICENSE BLOCK ***** +/* + * component: "openEHR Reference Implementation" + * description: "Class Participation" + * keywords: "common" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL: http://svn.openehr.org/ref_impl_java/TRUNK/libraries/src/java/org/openehr/rm/common/generic/Participation.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.common.generic; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.RMObject; +import org.openehr.rm.datatypes.quantity.DvInterval; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * Model of a participation of a Party (any Actor or Role) in an activity. + * Instances of this object are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class Participation extends RMObject { + + /** + * Constructs a Participation + * + * @param performer not null + * @param function not null + * @param mode not null and exists + * @param time + * @param terminologyService not null + * @throws IllegalArgumentException if function null + * or mode invalid or performer null + */ + @FullConstructor + public Participation( + @Attribute(name = "performer", required = true) PartyProxy performer, + @Attribute(name = "function", required = true) DvText function, + @Attribute(name = "mode") DvCodedText mode, /* Optional as of RM 1.0.3 SPECRM-21*/ + @Attribute(name = "time") DvInterval time, + @Attribute(name = "terminologyService", system = true) TerminologyService terminologyService) { + if (performer == null) { + throw new IllegalArgumentException("null performer"); + } + if (function == null) { + throw new IllegalArgumentException("null function"); + } + if (terminologyService == null) { + throw new IllegalArgumentException("null terminologyService"); + } + + if (( function instanceof DvCodedText ) + && ( !terminologyService.terminology( + TerminologyService.OPENEHR) + .codesForGroupName("participation function", "en") + .contains(((DvCodedText) function).getDefiningCode()))) { + throw new IllegalArgumentException("unkown function: " + function); + } + + if (!terminologyService.terminology(TerminologyService.OPENEHR) + .codesForGroupName("participation mode", "en") + .contains(mode.getDefiningCode())) { + throw new IllegalArgumentException("unkown mode: " + mode); + } + this.performer = performer; + this.function = function; + this.mode = mode; + this.time = time; + } + + /** + * The party participating in the activity. + * + * @return performer + */ + public PartyProxy getPerformer() { + return performer; + } + + /** + * The function of the Party in this participation + * + * @return function + */ + public DvText getFunction() { + return function; + } + + /** + * The mode of the performer / activity interaction, + * eg present, by telephone, by email etc. + * + * @return mode + */ + public DvCodedText getMode() { + return mode; + } + + /** + * The time interval during which the participation took place, + * if it is used in an observational context (ie recording facts + * about the past); or the intended time interval of the + * participation when used in future contexts, such as EHR + * Instructions. + * + * @return DvInterval + */ + public DvInterval getTime() { + return time; + } + + /** + * Equals if two participations have same values + * + * @param o + * @return true if equals + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof Participation )) { + return false; + } + + final Participation p = (Participation) o; + + return new EqualsBuilder() + .append(performer, p.performer) + .append(function, p.function) + .append(mode, p.mode) + .append(time, p.time) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + @Override + public int hashCode() { + return new HashCodeBuilder(7, 19) + .append(performer) + .append(function) + .append(mode) + .append(time) + .toHashCode(); + } + + // POJO start + Participation() { + } + + void setPerformer(PartyProxy performer) { + this.performer = performer; + } + + void setFunction(DvText function) { + this.function = function; + } + + void setMode(DvCodedText mode) { + this.mode = mode; + } + + void setTime(DvInterval time) { + this.time = time; + } + // POJO end + + /* fields */ + private PartyProxy performer; + private DvText function; + private DvCodedText mode; + private DvInterval time; +} + +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the 'License'); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Participation.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * ***** END LICENSE BLOCK ***** */ \ No newline at end of file diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/PartyIdentified.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/PartyIdentified.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/PartyProxy.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/PartyProxy.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/PartyRelated.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/PartyRelated.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/PartySelf.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/PartySelf.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/RevisionHistory.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/RevisionHistory.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/RevisionHistoryItem.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/RevisionHistoryItem.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/resource/AuthoredResource.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/resource/AuthoredResource.java old mode 100755 new mode 100644 index 3c462733..c7e7cb46 --- a/openehr-rm-core/src/main/java/org/openehr/rm/common/resource/AuthoredResource.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/resource/AuthoredResource.java @@ -198,11 +198,9 @@ void setDescription(ResourceDescription description) //if (!description.equals(this.description)) { //if(this.description != description) { if (description.getParentResource() != this) { - for (ResourceDescriptionItem rdi : description.getDetails()) { - if (!translations.containsKey(rdi.getLanguage() - .getCodeString()) - && !originalLanguage.getCodeString().equals( - rdi.getLanguage().getCodeString())) { + for (String languageCode : description.getDetails().keySet()) { + if (!translations.containsKey(languageCode) + && !originalLanguage.getCodeString().equals(languageCode)) { throw new IllegalArgumentException( "the language of description details not in translations"); } diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/resource/ResourceDescription.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/resource/ResourceDescription.java old mode 100755 new mode 100644 index 0a58f669..416c203e --- a/openehr-rm-core/src/main/java/org/openehr/rm/common/resource/ResourceDescription.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/resource/ResourceDescription.java @@ -1,301 +1,299 @@ -/* - * component: "openEHR Reference Implementation" - * description: "Class ResourceDescription" - * keywords: "resource" - * - * author: "Yin Su Lim " - * support: "CHIME, UCL" - * copyright: "Copyright (c) 2006 UCL, UK" - * license: "See notice at bottom of class" - * - * file: "$URL: http://svn.openehr.org/ref_impl_java/TRUNK/libraries/src/java/org/openehr/rm/common/resource/ResourceDescription.java $" - * revision: "$LastChangedRevision: 53 $" - * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" - */ -package org.openehr.rm.common.resource; - -import java.io.Serializable; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.lang.StringUtils; -import org.openehr.rm.Attribute; - -/** - * Defines the descriptive meta-data of a resource. - * - * @author Yin Su Lim - * @version 1.0 - */ -public class ResourceDescription implements Serializable{ - - /** - * - */ - private static final long serialVersionUID = 1L; - /** - * Construct ResourceDescription - */ - public ResourceDescription( - @Attribute(name = "originalAuthor", required = true) Map originalAuthor, - @Attribute(name = "otherContributors") List otherContributors, - @Attribute(name = "lifecycleState", required = true) String lifecycleState, - @Attribute(name = "details", required = true) List details, - @Attribute(name = "resourcePackageUri") String resourcePackageUri, - @Attribute(name = "otherDetails") Map otherDetails, - @Attribute(name = "parentResource") AuthoredResource parentResource ){ - if (originalAuthor == null || originalAuthor.size() == 0 ) { - // throw new IllegalArgumentException("null or empty originalAuthor"); - System.out.println("Warning...parsing archetype with null or empty original author"); - } - if (StringUtils.isEmpty(lifecycleState) ) { - throw new IllegalArgumentException("null or empty lifecycleState"); - } - if (details == null || details.size() == 0 ) { - throw new IllegalArgumentException("null or empty details"); - } - this.originalAuthor = originalAuthor; - this.otherContributors = otherContributors; - this.lifecycleState = lifecycleState; - this.details = details; - this.resourcePackageUri = resourcePackageUri; - this.otherDetails = otherDetails; - setParentResource(parentResource); - } - - /** - * Details of all parts of resource description that are natural - * language-dependent - * - * @return details - */ - public List getDetails() { - return details; - } - - /** - * Lifecycle state of the resource, typically including states - * such as: initial, submitted, experimental...etc - * - * @return lifecycleState - */ - public String getLifecycleState() { - return lifecycleState; - } - - /** - * Original author of this resource, with all relevant details, - * including organisation. - * - * @return originalAuthor - */ - public Map getOriginalAuthor() { - return originalAuthor; - } - - /** - * Other contributors to the resource, probably listed - * in "name" form - * - * @return otherContributors - */ - public List getOtherContributors() { - return otherContributors; - } - - /** - * Additional non language-sensitive resource meta-data, - * as a list of name/value pairs - * - * @return otherDetails - */ - public Map getOtherDetails() { - return otherDetails; - } - - /** - * Reference to owning resource - * - * @return parentResource - */ - public AuthoredResource getParentResource() { - return parentResource; - } - - /** - * URI of package to which this resource belongs - * - * @return resourcePackageUri - */ - public String getResourcePackageUri() { - return resourcePackageUri; - } - - //POJO start - public ResourceDescription() { - } - - void setDetails(List details) { - this.details = details; - } - - void setLifecycleState(String lifecycleState) { - this.lifecycleState = lifecycleState; - } - - void setOriginalAuthor(Map originalAuthor) { - this.originalAuthor = originalAuthor; - } - - void setOtherContributors(List otherContributors) { - this.otherContributors = otherContributors; - } - - void setOtherDetails(Map otherDetails) { - this.otherDetails = otherDetails; - } - - void setResourcePackageUri(String resourcePackageUri) { - this.resourcePackageUri = resourcePackageUri; - } - - void setParentResource(AuthoredResource parentResource) { - - boolean parentDesc = (parentResource != null) && - parentResource.getDescription() != this; - if(parentDesc) { - languageValidCheck(parentResource, this.details); - } - this.parentResource = parentResource; - if(parentDesc) { - this.parentResource.setDescription(this); - } - } - - void languageValidCheck(AuthoredResource parent, List details) { - Set languages = parent.languagesAvailable(); - for(ResourceDescriptionItem rdi : details) { - if(!languages.contains(rdi.getLanguage().getCodeString())) { - throw new IllegalArgumentException("breach of language validity"); - } - } - } - - //POJO end - - /* fields */ - private Map originalAuthor; - private List otherContributors; - private String lifecycleState; - private List details; - private String resourcePackageUri; - private Map otherDetails; - private AuthoredResource parentResource; - /* (non-Javadoc) - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((details == null) ? 0 : details.hashCode()); - result = prime * result - + ((lifecycleState == null) ? 0 : lifecycleState.hashCode()); - result = prime * result - + ((originalAuthor == null) ? 0 : originalAuthor.hashCode()); - result = prime - * result - + ((otherContributors == null) ? 0 : otherContributors - .hashCode()); - result = prime * result - + ((otherDetails == null) ? 0 : otherDetails.hashCode()); - result = prime * result - + ((parentResource == null) ? 0 : parentResource.hashCode()); - result = prime - * result - + ((resourcePackageUri == null) ? 0 : resourcePackageUri - .hashCode()); - return result; - } - - /* (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ResourceDescription other = (ResourceDescription) obj; - if (details == null) { - if (other.details != null) - return false; - } else if (!details.equals(other.details)) - return false; - if (lifecycleState == null) { - if (other.lifecycleState != null) - return false; - } else if (!lifecycleState.equals(other.lifecycleState)) - return false; - if (originalAuthor == null) { - if (other.originalAuthor != null) - return false; - } else if (!originalAuthor.equals(other.originalAuthor)) - return false; - if (otherContributors == null) { - if (other.otherContributors != null) - return false; - } else if (!otherContributors.equals(other.otherContributors)) - return false; - if (otherDetails == null) { - if (other.otherDetails != null) - return false; - } else if (!otherDetails.equals(other.otherDetails)) - return false; - if (parentResource == null) { - if (other.parentResource != null) - return false; - } else if (!parentResource.equals(other.parentResource)) - return false; - if (resourcePackageUri == null) { - if (other.resourcePackageUri != null) - return false; - } else if (!resourcePackageUri.equals(other.resourcePackageUri)) - return false; - return true; - } -} - -/* - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the 'License'); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an 'AS IS' basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is ResourceDescription.java - * - * The Initial Developer of the Original Code is Yin Su Lim. - * Portions created by the Initial Developer are Copyright (C) 2003-2004 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Software distributed under the License is distributed on an 'AS IS' basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * ***** END LICENSE BLOCK ***** +/* + * component: "openEHR Reference Implementation" + * description: "Class ResourceDescription" + * keywords: "resource" + * + * author: "Yin Su Lim " + * support: "CHIME, UCL" + * copyright: "Copyright (c) 2006 UCL, UK" + * license: "See notice at bottom of class" + * + * file: "$URL: http://svn.openehr.org/ref_impl_java/TRUNK/libraries/src/java/org/openehr/rm/common/resource/ResourceDescription.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.common.resource; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.openehr.rm.Attribute; + +/** + * Defines the descriptive meta-data of a resource. + * + * @author Yin Su Lim + * @version 1.0 + */ +public class ResourceDescription implements Serializable{ + + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Construct ResourceDescription + */ + public ResourceDescription( + @Attribute(name = "originalAuthor", required = true) Map originalAuthor, + @Attribute(name = "otherContributors") List otherContributors, + @Attribute(name = "lifecycleState", required = true) String lifecycleState, + @Attribute(name = "details", required = true) Map details, + @Attribute(name = "resourcePackageUri") String resourcePackageUri, + @Attribute(name = "otherDetails") Map otherDetails, + @Attribute(name = "parentResource") AuthoredResource parentResource ){ + if (originalAuthor == null || originalAuthor.size() == 0 ) { + // throw new IllegalArgumentException("null or empty originalAuthor"); + System.out.println("Warning...parsing archetype with null or empty original author"); + } + if (StringUtils.isEmpty(lifecycleState) ) { + throw new IllegalArgumentException("null or empty lifecycleState"); + } + if (details == null || details.size() == 0 ) { + throw new IllegalArgumentException("null or empty details"); + } + this.originalAuthor = originalAuthor; + this.otherContributors = otherContributors; + this.lifecycleState = lifecycleState; + this.details = details; + this.resourcePackageUri = resourcePackageUri; + this.otherDetails = otherDetails; + setParentResource(parentResource); + } + + /** + * Details of all parts of resource description that are natural + * language-dependent + * + * @return details + */ + public Map getDetails() { + return details; + } + + /** + * Lifecycle state of the resource, typically including states + * such as: initial, submitted, experimental...etc + * + * @return lifecycleState + */ + public String getLifecycleState() { + return lifecycleState; + } + + /** + * Original author of this resource, with all relevant details, + * including organisation. + * + * @return originalAuthor + */ + public Map getOriginalAuthor() { + return originalAuthor; + } + + /** + * Other contributors to the resource, probably listed + * in "name" form + * + * @return otherContributors + */ + public List getOtherContributors() { + return otherContributors; + } + + /** + * Additional non language-sensitive resource meta-data, + * as a list of name/value pairs + * + * @return otherDetails + */ + public Map getOtherDetails() { + return otherDetails; + } + + /** + * Reference to owning resource + * + * @return parentResource + */ + public AuthoredResource getParentResource() { + return parentResource; + } + + /** + * URI of package to which this resource belongs + * + * @return resourcePackageUri + */ + public String getResourcePackageUri() { + return resourcePackageUri; + } + + //POJO start + public ResourceDescription() { + } + + void setDetails(Map details) { + this.details = details; + } + + void setLifecycleState(String lifecycleState) { + this.lifecycleState = lifecycleState; + } + + void setOriginalAuthor(Map originalAuthor) { + this.originalAuthor = originalAuthor; + } + + void setOtherContributors(List otherContributors) { + this.otherContributors = otherContributors; + } + + public void setOtherDetails(Map otherDetails) { + this.otherDetails = otherDetails; + } + + void setResourcePackageUri(String resourcePackageUri) { + this.resourcePackageUri = resourcePackageUri; + } + + void setParentResource(AuthoredResource parentResource) { + + boolean parentDesc = (parentResource != null) && + parentResource.getDescription() != this; + if(parentDesc) { + languageValidCheck(parentResource, this.details); + } + this.parentResource = parentResource; + if(parentDesc) { + this.parentResource.setDescription(this); + } + } + + void languageValidCheck(AuthoredResource parent, Map details) { + Set languages = parent.languagesAvailable(); + for(String code : details.keySet()) { + if(!languages.contains(code)) { + throw new IllegalArgumentException("breach of language validity"); + } + } + } + + //POJO end + + /* fields */ + private Map originalAuthor; + private List otherContributors; + private String lifecycleState; + private Map details; + private String resourcePackageUri; + private Map otherDetails; + private AuthoredResource parentResource; + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((details == null) ? 0 : details.hashCode()); + result = prime * result + + ((lifecycleState == null) ? 0 : lifecycleState.hashCode()); + result = prime * result + + ((originalAuthor == null) ? 0 : originalAuthor.hashCode()); + result = prime + * result + + ((otherContributors == null) ? 0 : otherContributors + .hashCode()); + result = prime * result + + ((otherDetails == null) ? 0 : otherDetails.hashCode()); + result = prime + * result + + ((resourcePackageUri == null) ? 0 : resourcePackageUri + .hashCode()); + return result; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ResourceDescription other = (ResourceDescription) obj; + if (details == null) { + if (other.details != null) + return false; + } else if (!details.equals(other.details)) + return false; + if (lifecycleState == null) { + if (other.lifecycleState != null) + return false; + } else if (!lifecycleState.equals(other.lifecycleState)) + return false; + if (originalAuthor == null) { + if (other.originalAuthor != null) + return false; + } else if (!originalAuthor.equals(other.originalAuthor)) + return false; + if (otherContributors == null) { + if (other.otherContributors != null) + return false; + } else if (!otherContributors.equals(other.otherContributors)) + return false; + if (otherDetails == null) { + if (other.otherDetails != null) + return false; + } else if (!otherDetails.equals(other.otherDetails)) + return false; + if (parentResource == null) { + if (other.parentResource != null) + return false; + } else if (!parentResource.equals(other.parentResource)) + return false; + if (resourcePackageUri == null) { + if (other.resourcePackageUri != null) + return false; + } else if (!resourcePackageUri.equals(other.resourcePackageUri)) + return false; + return true; + } +} + +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the 'License'); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is ResourceDescription.java + * + * The Initial Developer of the Original Code is Yin Su Lim. + * Portions created by the Initial Developer are Copyright (C) 2003-2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * ***** END LICENSE BLOCK ***** */ \ No newline at end of file diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/resource/ResourceDescriptionItem.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/resource/ResourceDescriptionItem.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/common/resource/TranslationDetails.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/resource/TranslationDetails.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/DataStructure.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/DataStructure.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/history/Event.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/history/Event.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/history/History.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/history/History.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/history/IntervalEvent.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/history/IntervalEvent.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/history/PointEvent.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/history/PointEvent.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemList.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemList.java index a774f0b0..dacbfe42 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemList.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemList.java @@ -23,11 +23,13 @@ import org.openehr.rm.common.archetyped.Link; import org.openehr.rm.common.archetyped.Pathable; import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.util.ItemUtil; import org.openehr.rm.datastructure.itemstructure.representation.Element; import org.openehr.rm.datastructure.itemstructure.representation.Item; import org.openehr.rm.datatypes.text.DvText; import java.util.*; +import java.util.Map.Entry; /** * Logical list data structure, where each item has a value and can @@ -158,26 +160,43 @@ public String pathOfItem(Pathable item) { return null; // todo: implement this method } - /** - * Return true if value equals - * - * @param o - * @return true if equals - */ - public boolean equals(Object obj) { - if (obj == null) { return false; } - if (obj == this) { return true; } - if (obj.getClass() != getClass()) { - return false; - } - ItemList list = (ItemList) obj; - return new EqualsBuilder() - .appendSuper(super.equals(obj)) - .append(items, list.items) - .isEquals(); - } - @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((items == null) ? 0 : items.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if(obj == null) { + return false; + } + if (this == obj) { + return true; + } + if (getClass() != obj.getClass()) { + return false; + } + if (!super.equals(obj)) { + return false; + } + ItemList other = (ItemList) obj; + if (items == null) { + if (other.items != null) { + return false; + } + } else if (other.items == null) { + return false; + } else if (!ItemUtil.getInstance().compareElements(this.items, + other.getItems())) { + return false; + } + return true; + } + + @Override public List itemsAtPath(String path) { // TODO Auto-generated method stub return null; @@ -201,6 +220,8 @@ public Item asHierarchy() { return null; } + + /* calculated field */ private List items; diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemSingle.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemSingle.java index 44eb76ab..b15918df 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemSingle.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemSingle.java @@ -137,6 +137,41 @@ public Item asHierarchy() { return null; } + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((item == null) ? 0 : item.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if(obj == null) { + return false; + } + + if (this == obj) { + return true; + } + if (getClass() != obj.getClass()) { + return false; + } + if (!super.equals(obj)) { + return false; + } + + ItemSingle other = (ItemSingle) obj; + if (item == null) { + if (other.item != null) { + return false; + } + } else if (!item.equals(other.item)) { + return false; + } + return true; + } + private Element item; } diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemStructure.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemStructure.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemTable.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemTable.java index 3afa4a68..d3e56336 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemTable.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemTable.java @@ -354,7 +354,43 @@ public boolean pathUnique(String path) { return false; } - // POJO start + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((names == null) ? 0 : names.hashCode()); + result = prime * result + ((rows == null) ? 0 : rows.hashCode()); + return result; + } + + @Override + //Generated by Eclipse + public boolean equals(Object obj) { + if(obj == null) { + return false; + } + + if (this == obj) + return true; + if (getClass() != obj.getClass()) + return false; + if (!super.equals(obj)) + return false; + ItemTable other = (ItemTable) obj; + if (names == null) { + if (other.names != null) + return false; + } else if (!names.equals(other.names)) + return false; + if (rows == null) { + if (other.rows != null) + return false; + } else if (!rows.equals(other.rows)) + return false; + return true; + } + + // POJO start ItemTable() { } // POJO end diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemTree.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemTree.java index 0cd5d16e..cb7c65ac 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemTree.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemTree.java @@ -14,20 +14,20 @@ */ package org.openehr.rm.datastructure.itemstructure; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; +import java.util.List; +import java.util.Set; + import org.openehr.rm.Attribute; import org.openehr.rm.FullConstructor; import org.openehr.rm.common.archetyped.Archetyped; import org.openehr.rm.common.archetyped.FeederAudit; import org.openehr.rm.common.archetyped.Link; import org.openehr.rm.common.archetyped.Pathable; -import org.openehr.rm.support.identification.UIDBasedID; import org.openehr.rm.datastructure.itemstructure.representation.Element; import org.openehr.rm.datastructure.itemstructure.representation.Item; import org.openehr.rm.datatypes.text.DvText; - -import java.util.*; +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.util.ItemUtil; /** * Logical tree data structure. @@ -122,34 +122,51 @@ public List getItems() { return items; } - /** - * Equals if two item_tree has same values - * - * @param o - * @return equals if true - */ - public boolean equals(Object o) { - if (this == o) return true; - if (!( o instanceof ItemTree )) return false; - - final ItemTree tree = (ItemTree) o; - return new EqualsBuilder() - .appendSuper(super.equals(o)) - .append(items, tree.items) - .isEquals(); - } + /** + * Equals if two item_tree has same values + * + * @param o + * @return equals if true + */ + public boolean equals(Object obj) { + if(obj == null) { + return false; + } - /** - * Return a hash code of this actor - * - * @return hash code - */ - public int hashCode() { - return new HashCodeBuilder(17, 23) - .appendSuper(super.hashCode()) - .append(items) - .toHashCode(); - } + if (this == obj) { + return true; + } + if (getClass() != obj.getClass()) { + return false; + } + if (!super.equals(obj)) { + return false; + } + ItemTree other = (ItemTree) obj; + if (items == null) { + if (other.items != null) { + return false; + } + } else if (other.items == null) { + return false; + } else if (!ItemUtil.getInstance().compareItems(this.items, + other.getItems())) { + return false; + } + return true; + } + + /** + * Return a hash code of this actor + * + * @return hash code + */ + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((items == null) ? 0 : items.hashCode()); + return result; + } /** * Return the path to an item relative to the root of this diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/representation/Cluster.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/representation/Cluster.java index 2413587b..892933bc 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/representation/Cluster.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/representation/Cluster.java @@ -21,9 +21,11 @@ import org.openehr.rm.common.archetyped.Link; import org.openehr.rm.common.archetyped.Pathable; import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.util.ItemUtil; import org.openehr.rm.datatypes.text.DvText; import java.util.*; +import java.util.Map.Entry; /** * The grouping variant of Item, which may contain further instances @@ -144,6 +146,44 @@ public boolean pathUnique(String path) { /* fields */ private List items; + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((items == null) ? 0 : items.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if(obj == null) { + return false; + } + + if (this == obj) { + return true; + } + if (getClass() != obj.getClass()) { + return false; + } + if (!super.equals(obj)) { + return false; + } + Cluster other = (Cluster) obj; + if (items == null) { + if (other.items != null) { + return false; + } + } else if (other.items == null) { + return false; + } else if (!ItemUtil.getInstance() + .compareItems(items, other.getItems())) { + return false; + } + return true; + } + } /* diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/representation/Element.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/representation/Element.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/representation/Item.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/representation/Item.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DataValue.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DataValue.java index b781ecdf..a81fac9e 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DataValue.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DataValue.java @@ -14,23 +14,22 @@ */ package org.openehr.rm.datatypes.basic; -import java.util.HashMap; -import java.util.Map; - import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; import org.openehr.rm.RMObject; -import org.openehr.rm.datatypes.quantity.DvCount; -import org.openehr.rm.datatypes.quantity.DvOrdinal; -import org.openehr.rm.datatypes.quantity.DvProportion; -import org.openehr.rm.datatypes.quantity.DvQuantity; -import org.openehr.rm.datatypes.quantity.ProportionKind; +import org.openehr.rm.datatypes.encapsulated.DvParsable; +import org.openehr.rm.datatypes.quantity.*; +import org.openehr.rm.datatypes.quantity.datetime.DvDate; import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; import org.openehr.rm.datatypes.quantity.datetime.DvDuration; +import org.openehr.rm.datatypes.quantity.datetime.DvTime; import org.openehr.rm.datatypes.text.CodePhrase; import org.openehr.rm.datatypes.text.DvCodedText; import org.openehr.rm.datatypes.text.DvText; +import java.util.HashMap; +import java.util.Map; + /** * Abstract parent type of all concrete data value types * @@ -79,7 +78,7 @@ public static DataValue parseValue(String value) { int i = value.indexOf(","); if(i < 0 || i == value.length()) { - throw new IllegalArgumentException("wrong string format"); + throw new IllegalArgumentException("wrong string format (" + value + ")"); } String rmName = value.substring(0, i); @@ -119,8 +118,11 @@ public DataValue parse(String value) { dataValueMap.put(ReferenceModelName.CODE_PHRASE.getName(), new CodePhrase("tm","cd")); dataValueMap.put(ReferenceModelName.DV_ORDINAL.getName(), new DvOrdinal(0,"text","tm","cd")); dataValueMap.put(ReferenceModelName.DV_DATE_TIME.getName(), new DvDateTime("2001-02-11T00")); - dataValueMap.put(ReferenceModelName.DV_DURATION.getName(), new DvDuration("P10D")); - } + dataValueMap.put(ReferenceModelName.DV_DATE.getName(), new DvDate("2001-02-11")); + dataValueMap.put(ReferenceModelName.DV__TIME.getName(), new DvTime("00:00:00.000Z")); + dataValueMap.put(ReferenceModelName.DV_DURATION.getName(), new DvDuration("P10D")); + dataValueMap.put(ReferenceModelName.DV_PARSABLE.getName(), new DvParsable("text", "txt")); + } } diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvBoolean.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvBoolean.java index dabaae20..7ae54e8d 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvBoolean.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvBoolean.java @@ -27,7 +27,7 @@ public final class DvBoolean extends DataValue { /** - * + * */ private static final long serialVersionUID = -5827013068177253709L; @@ -36,7 +36,8 @@ public final class DvBoolean extends DataValue { * * @param value */ - public DvBoolean(boolean value) { + @FullConstructor public DvBoolean(@Attribute (name = "value", + required = true) boolean value) { this.value = value; } @@ -45,8 +46,7 @@ public DvBoolean(boolean value) { * * @param value */ - @FullConstructor public DvBoolean(@Attribute (name = "value", - required = true) String value) { + public DvBoolean(String value) { this(Boolean.TRUE.toString().equals(value)); } @@ -59,9 +59,11 @@ public boolean getValue() { return value; } + + public DvBoolean parse(String value) throws IllegalArgumentException { - return valueOf(value); - } + return valueOf(value); + } /** * Returns an Boolean object holding the value of @@ -123,18 +125,18 @@ public int hashCode() { } public String toString() { - return value ? Boolean.TRUE.toString() : Boolean.FALSE.toString(); + return value ? Boolean.TRUE.toString() : Boolean.FALSE.toString(); } - + // POJO start private DvBoolean() { } - private void setValue(boolean value) { + public void setValue(boolean value) { this.value = value; } // POJO end - + /* fields */ private boolean value; @@ -148,15 +150,15 @@ private void setValue(boolean value) { */ public static final DvBoolean FALSE = new DvBoolean(false); - @Override - public String getReferenceModelName() { - return ReferenceModelName.DV_BOOLEAN.getName(); - } + @Override + public String getReferenceModelName() { + return ReferenceModelName.DV_BOOLEAN.getName(); + } - @Override - public String serialise() { - return getReferenceModelName() + "," + toString(); - } + @Override + public String serialise() { + return getReferenceModelName() + "," + toString(); + } } /* diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvIdentifier.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvIdentifier.java old mode 100755 new mode 100644 index 6554aa60..6c564ba4 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvIdentifier.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvIdentifier.java @@ -1,202 +1,200 @@ -/* - * component: "openEHR Reference Implementation" - * description: "Class DvIdentifier" - * keywords: "datatypes" - * - * author: "Rong Chen " - * support: "Acode HB " - * copyright: "Copyright (c) 2004 Acode HB, Sweden" - * license: "See notice at bottom of class" - * - * file: "$URL: http://svn.openehr.org/ref_impl_java/TRUNK/libraries/src/java/org/openehr/rm/datatypes/basic/DvIdentifier.java $" - * revision: "$LastChangedRevision: 2 $" - * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" - */ -package org.openehr.rm.datatypes.basic; - -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.openehr.rm.FullConstructor; -import org.openehr.rm.Attribute; - -/** - * Type for representing identifiers of real-world entities. Typical - * identifiers include drivers licence number, social security number, - * vertans affairs number, prescription id, order id, and so on. - * - * @author Rong Chen - * @version 1.0 - */ -public class DvIdentifier extends DataValue { - - /** - * Construct a DvIdentifier - * - * @param issuer - * @param id - * @param type - * @throws IllegalArgumentException if issuer or id or type is null or empty - */ - @FullConstructor - public DvIdentifier(@Attribute(name = "issuer", required=true) String issuer, - @Attribute(name = "assigner", required=true) String assigner, - @Attribute(name = "id", required=true) String id, - @Attribute(name = "type", required=true) String type) { - if (StringUtils.isEmpty(issuer)) { - throw new IllegalArgumentException("empty or null issuer"); - } - if (StringUtils.isEmpty(assigner)) { - throw new IllegalArgumentException("empty or null assigner"); - } - if (StringUtils.isEmpty(id)) { - throw new IllegalArgumentException("empty or null id"); - } - if (StringUtils.isEmpty(type)) { - throw new IllegalArgumentException("empty or null type"); - } - this.issuer = issuer; - this.assigner = assigner; - this.id = id; - this.type = type; - } - - /** - * Issuing agency of these kind of ids - * - * @return issuer - */ - public String getIssuer() { - return issuer; - } - - /** - * Organisation that assigned the id to the item being identified - * - * @return assigner - */ - public String getAssigner() { - return assigner; - } - - /** - * The identifier value. Often structured, according to the definition of - * the issuing authority s rules. - * - * @return id - */ - public String getId() { - return id; - } - - /** - * The identifier type, such as prescription, or SSN. One day a - * controlled vocabulary might be possible for this. - * - * @return type - */ - public String getType() { - return type; - } - - /** - * Equals if two DvIdentifiers have same values - * - * @param o - * @return true if equals - */ - public boolean equals(Object o) { - if (this == o) return true; - if (!( o instanceof DvIdentifier )) return false; - - final DvIdentifier dvid = (DvIdentifier) o; - - return new EqualsBuilder() - .append(issuer, dvid.issuer) - .append(assigner, dvid.assigner) - .append(id, dvid.id) - .append(type, dvid.type) - .isEquals(); - } - - /** - * Return a hash code of this object - * - * @return hash code - */ - public int hashCode() { - return new HashCodeBuilder(3, 17) - .append(issuer) - .append(assigner) - .append(id) - .append(type) - .toHashCode(); - } - - // POJO start - protected DvIdentifier() { - } - - protected void setIssuer(String issuer) { - this.issuer = issuer; - } - - protected void setAssigner(String assigner) { - this.assigner = assigner; - } - - protected void setId(String id) { - this.id = id; - } - - protected void setType(String type) { - this.type = type; - } - // POJO end - - /* fields */ - private String issuer; - private String assigner; - private String id; - private String type; - @Override - public String getReferenceModelName() { - return "DV_IDENTIFIER"; - } - - @Override - public String serialise() { - // TODO Auto-generated method stub - return null; - } -} - -/* - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the 'License'); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an 'AS IS' basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is DvIdentifier.java - * - * The Initial Developer of the Original Code is Rong Chen. - * Portions created by the Initial Developer are Copyright (C) 2003-2004 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Software distributed under the License is distributed on an 'AS IS' basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * ***** END LICENSE BLOCK ***** +/* + * component: "openEHR Reference Implementation" + * description: "Class DvIdentifier" + * keywords: "datatypes" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL: http://svn.openehr.org/ref_impl_java/TRUNK/libraries/src/java/org/openehr/rm/datatypes/basic/DvIdentifier.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datatypes.basic; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; + +/** + * Type for representing identifiers of real-world entities. Typical + * identifiers include drivers licence number, social security number, + * vertans affairs number, prescription id, order id, and so on. + * + * @author Rong Chen + * @version 1.0 + */ +public class DvIdentifier extends DataValue { + + /** + * Construct a DvIdentifier + * + * @param issuer + * @param id + * @param type + * @throws IllegalArgumentException if issuer is null or empty (others are optional as of RM1.0.3, SPECRM-23) + */ + @FullConstructor + public DvIdentifier(@Attribute(name = "issuer") String issuer, + @Attribute(name = "assigner") String assigner, + @Attribute(name = "id", required=true) String id, + @Attribute(name = "type") String type) { + + if (StringUtils.isEmpty(id)) { + throw new IllegalArgumentException("empty or null id"); + } + this.issuer = issuer; + this.assigner = assigner; + this.id = id; + this.type = type; + } + + /** + * Issuing agency of these kind of ids + * + * @return issuer + */ + public String getIssuer() { + return issuer; + } + + /** + * Organisation that assigned the id to the item being identified + * + * @return assigner + */ + public String getAssigner() { + return assigner; + } + + /** + * The identifier value. Often structured, according to the definition of + * the issuing authority s rules. + * + * @return id + */ + public String getId() { + return id; + } + + /** + * The identifier type, such as prescription, or SSN. One day a + * controlled vocabulary might be possible for this. + * + * @return type + */ + public String getType() { + return type; + } + + /** + * Equals if two DvIdentifiers have same values + * + * @param o + * @return true if equals + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof DvIdentifier )) { + return false; + } + + final DvIdentifier dvid = (DvIdentifier) o; + + return new EqualsBuilder() + .append(issuer, dvid.issuer) + .append(assigner, dvid.assigner) + .append(id, dvid.id) + .append(type, dvid.type) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + @Override + public int hashCode() { + return new HashCodeBuilder(3, 17) + .append(issuer) + .append(assigner) + .append(id) + .append(type) + .toHashCode(); + } + + // POJO start + protected DvIdentifier() { + } + + protected void setIssuer(String issuer) { + this.issuer = issuer; + } + + protected void setAssigner(String assigner) { + this.assigner = assigner; + } + + protected void setId(String id) { + this.id = id; + } + + protected void setType(String type) { + this.type = type; + } + // POJO end + + /* fields */ + private String issuer; + private String assigner; + private String id; + private String type; + @Override + public String getReferenceModelName() { + return "DV_IDENTIFIER"; + } + + @Override + public String serialise() { + // TODO Auto-generated method stub + return null; + } +} + +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the 'License'); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is DvIdentifier.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * ***** END LICENSE BLOCK ***** */ \ No newline at end of file diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvState.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvState.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/ReferenceModelName.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/ReferenceModelName.java old mode 100755 new mode 100644 index ca4f924a..5f78bc22 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/ReferenceModelName.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/ReferenceModelName.java @@ -11,8 +11,10 @@ public enum ReferenceModelName { DV_ORDINAL("DV_ORDINAL"), CODE_PHRASE("CODE_PHRASE"), DV_DATE_TIME("DV_DATE_TIME"), - DV_DURATION("DV_DURATION"); - + DV_DATE("DV_DATE"), + DV__TIME("DV_TIME"), + DV_DURATION("DV_DURATION"), + DV_PARSABLE("DV_PARSABLE"); private final String name; diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/encapsulated/DvEncapsulated.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/encapsulated/DvEncapsulated.java old mode 100755 new mode 100644 index 0c48b184..478f6a2e --- a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/encapsulated/DvEncapsulated.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/encapsulated/DvEncapsulated.java @@ -38,18 +38,18 @@ public abstract class DvEncapsulated extends DataValue { * @throws IllegalArgumentException if any argument is invalid */ protected DvEncapsulated(CodePhrase charset, CodePhrase language, - TerminologyService terminologyService) { - - if ((charset != null || language != null) && terminologyService == null) { + TerminologyService terminologyService) { + + if ((charset != null || language != null) && terminologyService == null) { throw new IllegalArgumentException("null terminologyService"); } if (language != null && ( ! terminologyService.codeSetForId( - OpenEHRCodeSetIdentifiers.LANGUAGES).hasCode(language))) { + OpenEHRCodeSetIdentifiers.LANGUAGES).hasCode(language))) { throw new IllegalArgumentException("unknown language: " + language); - + } if (charset != null && ( ! terminologyService.codeSetForId( - OpenEHRCodeSetIdentifiers.CHARACTER_SETS).hasCode(charset))) { + OpenEHRCodeSetIdentifiers.CHARACTER_SETS).hasCode(charset))) { throw new IllegalArgumentException( "unknown character set: " + charset); } @@ -98,7 +98,7 @@ void setLanguage(CodePhrase language) { /* fields */ private CodePhrase charset; - private CodePhrase language; + private CodePhrase language; } /* diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/encapsulated/DvMultimedia.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/encapsulated/DvMultimedia.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/encapsulated/DvParsable.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/encapsulated/DvParsable.java old mode 100755 new mode 100644 index 0333e9b9..fec2fede --- a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/encapsulated/DvParsable.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/encapsulated/DvParsable.java @@ -19,6 +19,7 @@ import org.apache.commons.lang.builder.HashCodeBuilder; import org.openehr.rm.Attribute; import org.openehr.rm.FullConstructor; +import org.openehr.rm.datatypes.basic.DataValue; import org.openehr.rm.datatypes.text.CodePhrase; import org.openehr.rm.support.terminology.TerminologyService; @@ -153,10 +154,18 @@ public String getReferenceModelName() { return "DV_PARSABLE"; } + public DataValue parse(String value) { + if (!value.contains(",")){ + throw new IllegalArgumentException("failed to parse parsable["+ value + "]"); + } + String parsableValue = StringUtils.substringBeforeLast(value, ",").trim(); + String formalism = StringUtils.substringAfterLast(value, ",").trim(); + return new DvParsable(parsableValue, formalism); + } + @Override public String serialise() { - // TODO Auto-generated method stub - return null; + return getReferenceModelName() + "," + value + "," + formalism; } } diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvAbsoluteQuantity.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvAbsoluteQuantity.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvAmount.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvAmount.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvCount.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvCount.java index e0d6b536..9194e6a8 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvCount.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvCount.java @@ -76,7 +76,7 @@ public DvCount(int magnitude) { * @return getMagnitude */ public Integer getMagnitude() { - return new Integer(this.magnitude); + return Integer.valueOf(this.magnitude); } /** @@ -183,6 +183,10 @@ public String toString() { } public DvCount parse(String value) throws IllegalArgumentException { + return valueOf(value); + } + + public static DvCount valueOf(String value) { try { int i = Integer.parseInt(value); return new DvCount(i); diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvInterval.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvInterval.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvOrdered.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvOrdered.java index 00451b23..c8a92d4c 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvOrdered.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvOrdered.java @@ -203,7 +203,7 @@ public void setNormalRange(DvInterval normalRange) { } /** - * @param otherReferenceRanges The otherReferenceRanges to set. + * @param referenceRanges The otherReferenceRanges to set. */ public void setOtherReferenceRanges(List> referenceRanges) { this.otherReferenceRanges = referenceRanges; diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvOrdinal.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvOrdinal.java index f670b5e8..502c9a47 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvOrdinal.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvOrdinal.java @@ -36,9 +36,10 @@ public final class DvOrdinal extends DvOrdered { /** - * + * */ private static final long serialVersionUID = 4901266284988836885L; + /** * Constructs an Ordinal by referenceRanges, value and symbol * @@ -49,11 +50,11 @@ public final class DvOrdinal extends DvOrdered { * @throws IllegalArgumentException */ @FullConstructor - public DvOrdinal( - @Attribute (name = "otherReferenceRanges") List> otherReferenceRanges, - @Attribute (name = "normalRange") DvInterval normalRange, - @Attribute (name = "value", required = true) int value, - @Attribute (name = "symbol", required = true) DvCodedText symbol) { + public DvOrdinal( + @Attribute(name = "otherReferenceRanges") List> otherReferenceRanges, + @Attribute(name = "normalRange") DvInterval normalRange, + @Attribute(name = "value", required = true) int value, + @Attribute(name = "symbol", required = true) DvCodedText symbol) { super(otherReferenceRanges, normalRange); if (symbol == null) { throw new IllegalArgumentException("null symbol"); @@ -93,11 +94,13 @@ public DvOrdinal(int value, DvCodedText symbol) { * Constructs an Ordinal by value and symbol * * @param value - * @param symbol + * @param dvCodedTextValue + * @param dvCodedTextTerminology + * @param dvCodedTextCode * @throws IllegalArgumentException */ - public DvOrdinal(int value, String dvCodedTextvalue, String dvCodedTextTerminology, String dvCodedTextCode) { - this(null, null, value, new DvCodedText(dvCodedTextvalue, dvCodedTextTerminology, dvCodedTextCode)); + public DvOrdinal(int value, String dvCodedTextValue, String dvCodedTextTerminology, String dvCodedTextCode) { + this(null, null, value, new DvCodedText(dvCodedTextValue, dvCodedTextTerminology, dvCodedTextCode)); } /** @@ -106,13 +109,13 @@ public DvOrdinal(int value, String dvCodedTextvalue, String dvCodedTextTerminolo * @return string presentation */ public String toString() { - return value + "|" + symbol.toString(); + return value + "|" + symbol.toString(); } /** * @param o the Object to be compared. * @return a negative integer, zero, or a positive integer as this object - * is less than, equal to, or greater than the specified object. + * is less than, equal to, or greater than the specified object. * @throws ClassCastException if the specified object's type prevents it * from being compared to this Object. */ @@ -153,7 +156,7 @@ public DvCodedText getSymbol() { public ReferenceRange limits() { return getOtherReferenceRanges().get(limitsIndex); } - + /** * Equals if value and symbol equal in value * @@ -162,7 +165,7 @@ public ReferenceRange limits() { */ public boolean equals(Object o) { if (this == o) return true; - if (!( o instanceof DvOrdinal )) return false; + if (!(o instanceof DvOrdinal)) return false; final DvOrdinal ord = (DvOrdinal) o; @@ -191,7 +194,7 @@ public int hashCode() { * @return true if two instances are strictly comparable */ public boolean isStrictlyComparableTo(DvOrdered ordered) { - if (!( ordered instanceof DvOrdinal )) { + if (!(ordered instanceof DvOrdinal)) { return false; } final DvOrdinal dvOrdinal = (DvOrdinal) ordered; @@ -204,27 +207,27 @@ public boolean isStrictlyComparableTo(DvOrdered ordered) { return true; } - public String getTerminologyId(){ - return getSymbol().getTerminologyId(); + public String getTerminologyId() { + return getSymbol().getTerminologyId(); } - public String getCode(){ - return getSymbol().getCode(); + public String getCode() { + return getSymbol().getCode(); } - - public String getSymbolValue(){ - return getSymbol().getValue(); + + public String getSymbolValue() { + return getSymbol().getValue(); } - + // POJO start private DvOrdinal() { } - public void setValue(int value) { + public void setValue(int value) { this.value = value; } - public void setSymbol(DvCodedText symbol) { + public void setSymbol(DvCodedText symbol) { this.symbol = symbol; } @@ -237,32 +240,36 @@ private void setLimitsIndex(int limitsIndex) { private int value; private DvCodedText symbol; private int limitsIndex; + @Override public String getReferenceModelName() { - return "DV_ORDINAL"; + return "DV_ORDINAL"; } - @Override public String serialise() { - return getReferenceModelName() + "," + toString(); + return getReferenceModelName() + "," + toString(); } @Override public DataValue parse(String value) { - int i = value.indexOf("|"); - if (i<0){ - throw new IllegalArgumentException("failed to parse DvOrdinal '"+value+"', wrong number of tokens."); - } - int ordinalValue = 0; - try{ - ordinalValue = Integer.parseInt(value.substring(0,i)); - }catch(NumberFormatException e){ - throw new IllegalArgumentException("failed to parse DvOrdinal '"+value+"', invalid integer value."); - } - String str = ReferenceModelName.DV_CODED_TEXT.getName() + "," + value.substring(i+1); - return new DvOrdinal(ordinalValue, (DvCodedText)DataValue.parseValue(str)); + return valueOf(value); + } + + public static DvOrdinal valueOf(String value) { + int i = value.indexOf("|"); + if (i < 0) { + throw new IllegalArgumentException("failed to parse DvOrdinal '" + value + "', wrong number of tokens."); + } + int ordinalValue = 0; + try { + ordinalValue = Integer.parseInt(value.substring(0, i)); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("failed to parse DvOrdinal '" + value + "', invalid integer value."); + } + String str = ReferenceModelName.DV_CODED_TEXT.getName() + "," + value.substring(i + 1); + return new DvOrdinal(ordinalValue, (DvCodedText) DataValue.parseValue(str)); } } diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvProportion.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvProportion.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvQuantified.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvQuantified.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvQuantity.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvQuantity.java index 9720285c..7996f46b 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvQuantity.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvQuantity.java @@ -26,8 +26,6 @@ import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; -import java.text.NumberFormat; -import java.text.ParseException; import java.util.List; /** @@ -40,6 +38,9 @@ */ public class DvQuantity extends DvAmount { + + private static final long serialVersionUID = 8334654589100981576L; + /** * Constructs a Quantity by all components * @@ -50,32 +51,32 @@ public class DvQuantity extends DvAmount { * @param accuracyPercent * @param units * @param magnitude - * @param precision >= -1 - * @magnitudeStatus - * @param measurementService null if not specified only if units - * not specified as well + * @param precision >= -1 + * @param measurementService null if not specified only if units + * not specified as well * @throws IllegalArgumentException + * @magnitudeStatus */ @FullConstructor - public DvQuantity(@Attribute (name = "otherReferenceRanges") List> otherReferenceRanges, - @Attribute (name = "normalRange") DvInterval normalRange, - @Attribute (name= "normalStatus") CodePhrase normalStatus, - @Attribute (name = "accuracy") double accuracy, - @Attribute (name = "accuracyPercent") boolean accuracyPercent, - @Attribute (name= "magnitudeStatus") String magnitudeStatus, - @Attribute (name = "units", required = true) String units, - @Attribute (name = "magnitude", required = true) double magnitude, - @Attribute (name = "precision") int precision, - @Attribute (name = "measurementService", system = true) MeasurementService measurementService) { - - super(otherReferenceRanges, normalRange, normalStatus, accuracy, - accuracyPercent, magnitudeStatus); + public DvQuantity(@Attribute(name = "otherReferenceRanges") List> otherReferenceRanges, + @Attribute(name = "normalRange") DvInterval normalRange, + @Attribute(name = "normalStatus") CodePhrase normalStatus, + @Attribute(name = "accuracy") double accuracy, + @Attribute(name = "accuracyPercent") boolean accuracyPercent, + @Attribute(name = "magnitudeStatus") String magnitudeStatus, + @Attribute(name = "units", required = true) String units, + @Attribute(name = "magnitude", required = true) double magnitude, + @Attribute(name = "precision") int precision, + @Attribute(name = "measurementService", system = true) MeasurementService measurementService) { + + super(otherReferenceRanges, normalRange, normalStatus, accuracy, + accuracyPercent, magnitudeStatus); if (precision < -1) { throw new IllegalArgumentException("negative precision"); } - - + + /* Relaxed in order to create quantity without measurementService. * One possibility is to use the mixin class ExternalEnvironmentAccess if (StringUtils.isNotEmpty(units) @@ -138,13 +139,13 @@ public DvQuantity(double magnitude, int precision, /** * New construct that does not require a measurementService - * + * * @param units * @param magnitude * @param precision */ public DvQuantity(String units, double magnitude, int precision) { - this(units, magnitude, precision, null); + this(units, magnitude, precision, null); } /** @@ -167,34 +168,40 @@ public Double getMagnitude() { /** * Units of this quantity - * + * * @return units */ public String getUnits() { - return units; + return units; } - + public DvQuantity parse(String value) { - int i = value.indexOf(","); - if(i < 0 || i == value.length()) { - throw new IllegalArgumentException("failed to parse quantity, wrong format [" + value + "]"); - } - String num = value.substring(0, i); - String units = value.substring(i + 1); - int precision = 0; - i = num.indexOf(DECIMAL_SEPARATOR); - if(i >= 0) { - precision = num.length() - i - 1; - } - try { - double magnitude = Double.parseDouble(num); - return new DvQuantity(units, magnitude, precision); - } catch(NumberFormatException nfe) { - throw new IllegalArgumentException("failed to parse quantity[" - + num + "]", nfe); - } + return valueOf(value); + } + + public static DvQuantity valueOf(String value) { + int i = value.indexOf(","); + String num = value; + String units = ""; + + if (i >= 0) { + num = value.substring(0, i); + units = value.substring(i + 1); + } + int precision = 0; + i = num.indexOf(DECIMAL_SEPARATOR); + if (i >= 0) { + precision = num.length() - i - 1; + } + try { + double magnitude = Double.parseDouble(num); + return new DvQuantity(units, magnitude, precision); + } catch (NumberFormatException nfe) { + throw new IllegalArgumentException("failed to parse quantity[" + + num + "]", nfe); + } } - + /** * Sum of this quantity and another whose formal type must be the * difference type of this quantity. @@ -207,9 +214,9 @@ public DvQuantity parse(String value) { public DvQuantified add(DvQuantified q) { DvQuantity qt = (DvQuantity) q; return new DvQuantity(getOtherReferenceRanges(), getNormalRange(), - getNormalStatus(), getAccuracy(), isAccuracyPercent(), - getMagnitudeStatus(), getUnits(), magnitude + qt.magnitude, - precision, measurementService); + getNormalStatus(), getAccuracy(), isAccuracyPercent(), + getMagnitudeStatus(), getUnits(), magnitude + qt.magnitude, + precision, measurementService); } /** @@ -224,9 +231,9 @@ public DvQuantified add(DvQuantified q) { public DvQuantified subtract(DvQuantified q) { DvQuantity qt = (DvQuantity) q; return new DvQuantity(getOtherReferenceRanges(), getNormalRange(), - getNormalStatus(), getAccuracy(), isAccuracyPercent(), - getMagnitudeStatus(), getUnits(), magnitude - qt.magnitude, - precision, measurementService); + getNormalStatus(), getAccuracy(), isAccuracyPercent(), + getMagnitudeStatus(), getUnits(), magnitude - qt.magnitude, + precision, measurementService); } /** @@ -247,9 +254,9 @@ public Class getDiffType() { * @return negated version */ public DvQuantity negate() { - return new DvQuantity(getOtherReferenceRanges(), getNormalRange(), - getNormalStatus(), getAccuracy(), isAccuracyPercent(), - getMagnitudeStatus(), getUnits(), -magnitude, + return new DvQuantity(getOtherReferenceRanges(), getNormalRange(), + getNormalStatus(), getAccuracy(), isAccuracyPercent(), + getMagnitudeStatus(), getUnits(), -magnitude, precision, measurementService); } @@ -275,8 +282,8 @@ public String toString() { dfs.setDecimalSeparator(DECIMAL_SEPARATOR); format.setDecimalFormatSymbols(dfs); format.setGroupingUsed(false); - String tmp = format.format(magnitude) + ( StringUtils.isEmpty(getUnits()) ? "" : "," + - getUnits() ); + String tmp = format.format(magnitude) + (StringUtils.isEmpty(getUnits()) ? "" : "," + + getUnits()); return tmp; } @@ -284,8 +291,8 @@ public String toString() { * Compares this object with the specified object for order. * * @return a negative integer, zero, or a positive integer as - * this object is less than, equal to, or greater than - * the specified object + * this object is less than, equal to, or greater than + * the specified object * @throws ClassCastException if the specified object's type * prevents it from being compared to this Object. */ @@ -302,7 +309,7 @@ public int compareTo(DvOrdered o) { * @throws IllegalArgumentException if other null or wrong type */ public boolean isStrictlyComparableTo(DvOrdered other) { - if (!( other instanceof DvQuantity )) { + if (!(other instanceof DvQuantity)) { throw new IllegalArgumentException("other not Quantity"); } final DvQuantity dvQuantity = (DvQuantity) other; @@ -317,7 +324,7 @@ public boolean isStrictlyComparableTo(DvOrdered other) { */ public boolean equals(Object o) { if (this == o) return true; - if (!( o instanceof DvQuantity )) return false; + if (!(o instanceof DvQuantity)) return false; final DvQuantity dvQuantity = (DvQuantity) o; @@ -345,28 +352,32 @@ public void setMagnitude(double magnitude) { this.magnitude = magnitude; } + public void setUnits(String units) { + this.units = units; + } + public void setPrecision(int precision) { this.precision = precision; - } + } // POJO end /* fields */ private double magnitude; // add final private int precision; // add final - private final String units; + private String units; private MeasurementService measurementService; // add final - + public static final char DECIMAL_SEPARATOR = '.'; - - @Override - public String getReferenceModelName() { - return ReferenceModelName.DV_QUANTITY.getName(); - } - - @Override - public String serialise() { - return getReferenceModelName() + "," + toString(); - } + + @Override + public String getReferenceModelName() { + return ReferenceModelName.DV_QUANTITY.getName(); + } + + @Override + public String serialise() { + return getReferenceModelName() + "," + toString(); + } } /* @@ -397,4 +408,4 @@ public String serialise() { * License. * * ***** END LICENSE BLOCK ***** - */ \ No newline at end of file + */ diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvScale.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvScale.java new file mode 100644 index 00000000..4d569084 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvScale.java @@ -0,0 +1,310 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvOrdinal" + * keywords: "datatypes" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL: http://svn.openehr.org/ref_impl_java/TRUNK/libraries/src/java/org/openehr/rm/datatypes/quantity/DvOrdinal.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datatypes.quantity; + +import java.util.List; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.datatypes.basic.DataValue; +import org.openehr.rm.datatypes.basic.ReferenceModelName; +import org.openehr.rm.datatypes.text.DvCodedText; + +/** Purpose Models rankings and scores, like Borg score , etc, + * where there is a) implied ordering, b) no implication that the + * distance between each value is constant, and c) the total number + * of values is finite. Instead of Integer uses Real. + * @author Sebastian Garde + * @version 1.0 */ +public final class DvScale extends DvOrdered { + + /** + * + */ + private static final long serialVersionUID = 4901266284988836885L; + + /** + * Constructs an Ordinal by referenceRanges, value and symbol + * + * @param otherReferenceRanges + * @param normalRange + * @param value + * @param symbol + * @throws IllegalArgumentException + */ + @FullConstructor + public DvScale( + @Attribute(name = "otherReferenceRanges") List> otherReferenceRanges, + @Attribute(name = "normalRange") DvInterval normalRange, + @Attribute(name = "value", required = true) double value, + @Attribute(name = "symbol", required = true) DvCodedText symbol) { + super(otherReferenceRanges, normalRange); + if (symbol == null) { + throw new IllegalArgumentException("null symbol"); + } + int index = -1; + if (otherReferenceRanges != null) { + for (int i = 0, j = otherReferenceRanges.size(); i < j; i++) { + ReferenceRange range = otherReferenceRanges.get(i); + if ("limits".equals(range.getMeaning().getValue())) { + index = i; + break; + } + } + if (index < 0) { + throw new IllegalArgumentException( + "no limits in otherReferenceRanges"); + } + } + this.limitsIndex = index; + this.value = value; + this.symbol = symbol; + } + + /** + * Constructs an Ordinal by value and symbol + * + * @param value + * @param symbol + * @throws IllegalArgumentException + */ + public DvScale(double value, DvCodedText symbol) { + this(null, null, value, symbol); + } + + /** + * Constructs an Ordinal by value and symbol + * + * @param value + * @param dvCodedTextValue + * @param dvCodedTextTerminology + * @param dvCodedTextCode + * @throws IllegalArgumentException + */ + public DvScale(double value, String dvCodedTextValue, String dvCodedTextTerminology, String dvCodedTextCode) { + this(null, null, value, new DvCodedText(dvCodedTextValue, dvCodedTextTerminology, dvCodedTextCode)); + } + + /** + * string form displayable for humans + * + * @return string presentation + */ + @Override + public String toString() { + return value + "|" + symbol.toString(); + } + + /** + * @param o the Object to be compared. + * @return a negative integer, zero, or a positive integer as this object + * is less than, equal to, or greater than the specified object. + * @throws ClassCastException if the specified object's type prevents it + * from being compared to this Object. + */ + public int compareTo(DvOrdered o) { + final DvScale dvOrdinal = (DvScale) o; + if (value > dvOrdinal.value) { + return 1; + } + if (value < dvOrdinal.value) { + return -1; + } + return 0; + } + + /** + * Ordinal position in enumeration of values + * + * @return value + */ + public double getValue() { + return value; + } + + /** + * Coded textual representation of this value in the enumeration, + * which may be strings made from + symbols, or other + * enumerations of terms such as "mild", "moderate", "severe", + * or even the same number series as the values. + * + * @return ssymbol + */ + public DvCodedText getSymbol() { + return symbol; + } + + /** + * Limits of the ordinal enumeration, to allow comparison of an + * ordinal value to its limits. + * + * @return reference range + */ + public ReferenceRange limits() { + return getOtherReferenceRanges().get(limitsIndex); + } + + /** + * Equals if value and symbol equal in value + * + * @param o + * @return true if equals + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof DvScale)) { + return false; + } + + final DvScale ord = (DvScale) o; + + return new EqualsBuilder() + .append(value, ord.value) + .append(symbol, ord.symbol) + .isEquals(); + } + + /** + * Return hash code of this DvOrdinal + * + * @return hash code + */ + @Override + public int hashCode() { + return new HashCodeBuilder(3, 31) + .append(value) + .append(symbol) + .toHashCode(); + } + + /** + * Tests if two instances are strictly comparable. + * + * @param ordered + * @return true if two instances are strictly comparable + */ + @Override + public boolean isStrictlyComparableTo(DvOrdered ordered) { + if (!(ordered instanceof DvScale)) { + return false; + } + final DvScale dvOrdinal = (DvScale) ordered; + + if (!symbol.getDefiningCode().getTerminologyId().equals( + dvOrdinal.symbol.getDefiningCode().getTerminologyId())) { + return false; + } + // todo: check if symbols are from same subset or value range in the same vocabulary + return true; + } + + public String getTerminologyId() { + return getSymbol().getTerminologyId(); + } + + public String getCode() { + return getSymbol().getCode(); + } + + public String getSymbolValue() { + return getSymbol().getValue(); + } + + // POJO start + private DvScale() { + } + + public void setValue(int value) { + this.value = value; + } + + public void setSymbol(DvCodedText symbol) { + this.symbol = symbol; + } + + private void setLimitsIndex(int limitsIndex) { + this.limitsIndex = limitsIndex; + } + // POJO end + + /* fields */ + private double value; + private DvCodedText symbol; + private int limitsIndex; + + @Override + public String getReferenceModelName() { + return "DV_SCALE"; + } + + + @Override + public String serialise() { + return getReferenceModelName() + "," + toString(); + } + + @Override + public DataValue parse(String value) { + return valueOf(value); + } + + public static DvScale valueOf(String value) { + int i = value.indexOf("|"); + if (i < 0) { + throw new IllegalArgumentException("failed to parse DvScale '" + value + "', wrong number of tokens."); + } + double ordinalValue = 0; + try { + ordinalValue = Double.parseDouble(value.substring(0, i)); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("failed to parse DvScale '" + value + "', invalid double/real value."); + } + String str = ReferenceModelName.DV_CODED_TEXT.getName() + "," + value.substring(i + 1); + return new DvScale(ordinalValue, (DvCodedText) DataValue.parseValue(str)); + } +} + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the 'License'); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is DvScale.java + * + * The Initial Developer of the Original Code is Sebastian Garde. + * Portions created by the Initial Developer are Copyright (C) 2020 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Rong Chen (for DvOrdinal) + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * ***** END LICENSE BLOCK ***** */ diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/ProportionKind.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/ProportionKind.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/ReferenceRange.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/ReferenceRange.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDate.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDate.java index b39c28b7..1795378b 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDate.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDate.java @@ -16,6 +16,7 @@ import java.util.List; import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; import org.joda.time.DateTime; import org.joda.time.MutableDateTime; import org.joda.time.format.DateTimeFormat; @@ -202,6 +203,14 @@ DateTime parseStringValue(String value) { return DvDateTimeParser.parseDate(value); } + /** + * Parses a string value and return a DvDate + */ + public DvDate parse(String value) { + DateTime date = DvDateTimeParser.parseDate(value); + return new DvDate(date.getYear(), date.getMonthOfYear(), date.getDayOfMonth()); + } + @Override public Double getMagnitude() { // TODO @@ -214,6 +223,7 @@ public boolean isStrictlyComparableTo(DvOrdered ordered) { return false; } + @Override public boolean equals(Object o) { if (!super.equals(o)) return false; @@ -227,20 +237,24 @@ public boolean equals(Object o) { .isEquals(); } + @Override + public int hashCode() { + return new HashCodeBuilder() + .append(isPartial) + .append(monthKnown) + .append(dayKnown).hashCode(); + } + /** * Output DvDate in extended date format if a DvDate is not constructed * via the single String constructor. */ public String toString(boolean isExtended) { String date = super.toString(); - if (date == null) { - date = ""; + if (isExtended) { + date = DvDateTimeParser.basicToExtendedDate(date); } else { - if (isExtended) { - date = DvDateTimeParser.basicToExtendedDate(date); - } else { - date = date.replace("-", ""); - } + date = date.replace("-", ""); } return date; } diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTime.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTime.java index efdee72c..8dbf26a8 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTime.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTime.java @@ -18,6 +18,7 @@ import java.util.List; import java.util.TimeZone; import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; import org.joda.time.DateTime; import org.joda.time.MutableDateTime; import org.joda.time.format.DateTimeFormatter; @@ -172,6 +173,10 @@ DateTime parseStringValue(String value) { * Parses a string value and return a DvDateTime */ public DvDateTime parse(String value) { + return valueOf(value); + } + + public static DvDateTime valueOf(String value) { DateTime datetime = DvDateTimeParser.parseDateTime(value); return new DvDateTime(datetime); } @@ -290,9 +295,6 @@ public boolean isStrictlyComparableTo(DvOrdered ordered) { /** * If date is valid ISO8601 format * - * @param year - * @param month - * @param day * @return true if valid */ public static boolean isValidISO8601Time(String value) { @@ -305,12 +307,7 @@ public static boolean isValidISO8601Time(String value) { return dt != null; } - /** - * Two DvDateTime equal if both have same year, month, day and timezone - * - * @param o - * @return true if equals - */ + @Override public boolean equals(Object o) { if (!super.equals(o)) return false; @@ -325,16 +322,21 @@ public boolean equals(Object o) { dt.fractionalSecKnown).isEquals(); } + @Override + public int hashCode() { + return new HashCodeBuilder() + .append(isPartial) + .append(minuteKnown) + .append(secondKnown) + .append(fractionalSecKnown).hashCode(); + } + public String toString(boolean isExtended) { String dt = super.toString(); - if (dt == null) { - dt = ""; + if (isExtended) { + dt = DvDateTimeParser.basicToExtendedDateTime(dt); } else { - if (isExtended) { - dt = DvDateTimeParser.basicToExtendedDateTime(dt); - } else { - dt = dt.replace(":", "").replace("-", ""); - } + dt = dt.replace(":", "").replace("-", ""); } return dt; } diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeParser.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeParser.java index 15d24129..2c6052e9 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeParser.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeParser.java @@ -122,11 +122,12 @@ public static DateTime parseDate(String value) { } } else { int size = analyseDateString(value); - DateTimeFormatter formatter = null; + DateTimeFormatter formatter; switch (size) { case 1: formatter = ISODateTimeFormat.year().withOffsetParsed(); break; case 2: formatter = DateTimeFormat.forPattern("yyyyMM").withOffsetParsed(); break; case 3: formatter = ISODateTimeFormat.basicDate().withOffsetParsed();break; + default: formatter = ISODateTimeFormat.basicDate().withOffsetParsed();break; } try { dt = formatter.parseDateTime(value); diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDuration.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDuration.java index ff24c5f6..2ebfe369 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDuration.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDuration.java @@ -38,20 +38,20 @@ * Represents a period of time with respect to a notional point in time, which * is not specified. A sign may be used to indicate the duration is "backwards" * in time rather than forwards. - * + * * @author Rong Chen * @version 1.0 */ public final class DvDuration extends DvAmount { /** - * + * */ private static final long serialVersionUID = -8172997416937095330L; /** * Constructs a Duration with referenceRange and accuracy - * + * * @param otherReferenceRanges * @param normalRange * @param normalStatus @@ -84,7 +84,7 @@ public DvDuration(@Attribute(name = "otherReferenceRanges") /** * Creates a simple DvDuration with string value - * + * * @param value */ public DvDuration(String value) { @@ -93,7 +93,7 @@ public DvDuration(String value) { /** * Constructs a Duration with referenceRange and accuracy - * + * * @param referenceRanges * @param accuracy * @param accuracyPercent @@ -129,7 +129,7 @@ public DvDuration(List> referenceRanges, /** * Constructs a Duration without referenceRange and accuracy - * + * * @param days * @param hours * @param minutes @@ -154,13 +154,12 @@ protected DvDuration(List> referenceRanges, /** * Create a Duration from two instances of DvWorldTime - * + * * @param start * @param end */ public static DvDuration getDifference(DvTemporal start, DvTemporal end) { Duration d = new Duration(start.getDateTime(), end.getDateTime()); - DvDateTime dt = (DvDateTime) end; return new DvDuration(null, null, null, 0.0, false, null, d.toPeriodFrom(start.getDateTime())); } @@ -172,7 +171,7 @@ public String getReferenceModelName() { /** * Create a Duration from a ISO8601 string presentation - * + * * @param value * @throws IllegalArgumentException * if value null or wrong format @@ -187,6 +186,8 @@ public static DvDuration getInstance(String value) { + value); } Period period = null; + final String suppliedValue = value; + if (value.startsWith("-")) { value = value.substring(1, value.length()); // skip '-' period = ISOPeriodFormat.standard().parsePeriod(value); @@ -195,7 +196,9 @@ public static DvDuration getInstance(String value) { period = ISOPeriodFormat.standard().parsePeriod(value); } - return new DvDuration(null, null, null, 0.0, false, null, period); + DvDuration duration = new DvDuration(null, null, null, 0.0, false, null, period); + duration.setValue(suppliedValue); // If we don't set this we cannot reconstruct the original constraint if 0s or 0h etc if all the same period, but the constraint in the ADL / XML serialisation still looks different + return duration; } @Override diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvTemporal.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvTemporal.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvTime.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvTime.java index a04ab818..bd4294da 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvTime.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvTime.java @@ -14,9 +14,8 @@ */ package org.openehr.rm.datatypes.quantity.datetime; -import java.util.List; -import java.util.TimeZone; - +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; import org.joda.time.DateTime; import org.joda.time.MutableDateTime; import org.openehr.rm.Attribute; @@ -25,7 +24,9 @@ import org.openehr.rm.datatypes.quantity.DvOrdered; import org.openehr.rm.datatypes.quantity.ReferenceRange; import org.openehr.rm.datatypes.text.CodePhrase; -import org.apache.commons.lang.builder.EqualsBuilder; + +import java.util.List; +import java.util.TimeZone; /** * Represents an absolute point in time from an origin usually @@ -269,23 +270,12 @@ public boolean isStrictlyComparableTo(DvOrdered ordered) { return false; } - /** - * Two DvTime equal if both have same value for hour, minute, second - * and timezone - * - * @param o - * @return true if equals - */ + @Override public boolean equals(Object o) { if (!super.equals(o)) return false; final DvTime dtime = (DvTime) o; - //TODO: check if the following line still necessary - //if(this.getDateTime().getZone().hashCode()!= this.getDateTime().getZone().hashCode()) { - // return false; - //} - return new EqualsBuilder().append( this.getDateTime().getZone().hashCode(), this.getDateTime().getZone().hashCode()).append(isPartial, @@ -294,16 +284,21 @@ public boolean equals(Object o) { dtime.fractionalSecKnown).isEquals(); } + @Override + public int hashCode() { + return new HashCodeBuilder() + .append(isPartial) + .append(minuteKnown) + .append(secondKnown) + .append(fractionalSecKnown).hashCode(); + } + public String toString(boolean isExtended) { String time = super.toString(); - if (time == null) { - time = ""; + if (isExtended) { + time = DvDateTimeParser.basicToExtendedTime(time); } else { - if (isExtended) { - time = DvDateTimeParser.basicToExtendedTime(time); - } else { - time = time.replace(":", ""); - } + time = time.replace(":", ""); } return time; } @@ -326,6 +321,14 @@ DateTime parseStringValue(String value) { return DvDateTimeParser.parseTime(value); } + /** + * Parses a string value and return a DvTime + */ + public DvTime parse(String value) { + DateTime time = DvDateTimeParser.parseTime(value); + return new DvTime(time.getHourOfDay(), time.getMinuteOfHour(), time.getSecondOfMinute(), time.getMillisOfSecond(), time.getZone().toTimeZone()); + } + void setBooleans(String value) { int ele = DvDateTimeParser.analyseTimeString(value); //isPartial, minuteKnown, secKnown diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/CodePhrase.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/CodePhrase.java index 752bd1c2..f54ec256 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/CodePhrase.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/CodePhrase.java @@ -33,6 +33,8 @@ */ public final class CodePhrase extends DataValue { + private static final long serialVersionUID = 1L; + /** * Constructs a CodePhrase by terminologyId and codeString * diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvCodedText.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvCodedText.java index a83bc762..553c7f7b 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvCodedText.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvCodedText.java @@ -162,15 +162,19 @@ public String serialise() { } public DvCodedText parse(String value){ - String[] tokens = value.split("::"); - if (tokens.length!=2){ - throw new IllegalArgumentException("failed to parse DvCodedText '"+value+"', wrong number of tokens."); - } - String[] tokens2 = tokens[1].split("\\|"); - if (tokens2.length!=2){ - throw new IllegalArgumentException("failed to parse DvCodedText '"+value+"', wrong number of tokens."); - } - return new DvCodedText(tokens2[1], tokens[0], tokens2[0]); + return valueOf(value); + } + + public static DvCodedText valueOf(String value) { + String[] tokens = value.split("::"); + if (tokens.length!=2){ + throw new IllegalArgumentException("failed to parse DvCodedText '"+value+"', wrong number of tokens."); + } + String[] tokens2 = tokens[1].split("\\|"); + if (tokens2.length!=2){ + throw new IllegalArgumentException("failed to parse DvCodedText '"+value+"', wrong number of tokens."); + } + return new DvCodedText(tokens2[1], tokens[0], tokens2[0]); } public String getTerminologyId(){ diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvParagraph.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvParagraph.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvText.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvText.java index 370cd952..acbf5e16 100755 --- a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvText.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvText.java @@ -50,7 +50,7 @@ public class DvText extends DataValue { * @param formatting null if unspecified * @param hyperlink null if unspecified * @param language not null and valid language code - * @param encoding not null and valid encoding code + * @param charset not null and valid encoding code * @param terminologyService not null * @throws IllegalArgumentException if any of the components * is invalid @@ -101,7 +101,6 @@ public class DvText extends DataValue { * * @param value * @param language - * @param encoding * @param terminologyService * @throws IllegalArgumentException if value, language or encoding * are empty or invalid @@ -130,6 +129,10 @@ public DvText parse(String value) { return new DvText(value); } + public static DvText valueOf(String value) { + return new DvText(value); + } + /** * string form displayable for humans * diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/Match.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/Match.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/TermMapping.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/TermMapping.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/timespec/DvGeneralTimeSpecification.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/timespec/DvGeneralTimeSpecification.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/timespec/DvPeriodicTimeSpecification.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/timespec/DvPeriodicTimeSpecification.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/timespec/DvTimeSpecification.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/timespec/DvTimeSpecification.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/uri/DvEHRURI.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/uri/DvEHRURI.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/uri/DvURI.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/uri/DvURI.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/security/AccessControlSettings.java b/openehr-rm-core/src/main/java/org/openehr/rm/security/AccessControlSettings.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/ExternalEnvironment.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/ExternalEnvironment.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/basic/Interval.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/basic/Interval.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/definition/OpenehrDefinitions.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/definition/OpenehrDefinitions.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/AccessGroupRef.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/AccessGroupRef.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ArchetypeID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ArchetypeID.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/GenericID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/GenericID.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/HierObjectID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/HierObjectID.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ISO_OID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ISO_OID.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/InternetID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/InternetID.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/LocatableRef.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/LocatableRef.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ObjectID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ObjectID.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ObjectRef.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ObjectRef.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ObjectVersionID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ObjectVersionID.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/PartyRef.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/PartyRef.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/TemplateID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/TemplateID.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/TerminologyID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/TerminologyID.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/UID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/UID.java old mode 100755 new mode 100644 index 68d6d428..12e1b142 --- a/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/UID.java +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/UID.java @@ -17,11 +17,11 @@ import org.apache.commons.lang.StringUtils; /** - * Purpose Anstract parent of classes representing unique identifiers + * Purpose Abstract parent of classes representing unique identifiers * which identify information entities in a durable way. UIDs only * ever identify one IE in time or space and are never re-used. * - * Instances of this class are immutalbe + * Instances of this class are immutable * * @author Rong Chen * @version 1.0 @@ -55,6 +55,7 @@ public String getValue() { * * @return string presentation */ + @Override public String toString() { return value; } @@ -65,9 +66,14 @@ public String toString() { * @param o * @return true if equals */ + @Override public boolean equals(Object o) { - if (this == o) return true; - if (!( o instanceof UID )) return false; + if (this == o) { + return true; + } + if (!( o instanceof UID )) { + return false; + } final UID uid = (UID) o; @@ -79,6 +85,7 @@ public boolean equals(Object o) { * * @return hash code */ + @Override public int hashCode() { return value.hashCode(); } diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/UIDBasedID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/UIDBasedID.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/UUID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/UUID.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/VersionTreeID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/VersionTreeID.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/CodeSetAccess.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/CodeSetAccess.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/OpenEHRCodeSetIdentifiers.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/OpenEHRCodeSetIdentifiers.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/OpenEHRTerminologyGroupIdentifiers.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/OpenEHRTerminologyGroupIdentifiers.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/TerminologyAccess.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/TerminologyAccess.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/TerminologyService.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/TerminologyService.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/main/java/org/openehr/rm/util/ItemUtil.java b/openehr-rm-core/src/main/java/org/openehr/rm/util/ItemUtil.java new file mode 100644 index 00000000..9d6bad9f --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/util/ItemUtil.java @@ -0,0 +1,56 @@ +package org.openehr.rm.util; + +import java.util.List; + +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datastructure.itemstructure.representation.Item; + +/** + * Performs utility operations on {@link Item} + * @author Malik.Firose + * + */ +public class ItemUtil { + + private static ItemUtil instance; + + private ItemUtil() { + + } + + public static ItemUtil getInstance() { + if (instance == null) { + instance = new ItemUtil(); + } + return instance; + } + + public boolean compareItems(final List thisItem, + final List otherItem) { + + // Since the order of these two item lists cannot be assured following + // approach is used + boolean equal = true; + for (final Item element : thisItem) { + equal = otherItem.contains(element); + if (!equal) { + break; + } + } + return equal; + } + + public boolean compareElements(final List thisElement, + final List otherElement) { + // Since the order of these two element list cannot be assured following + // approach is used + boolean equal = true; + for (final Element element : thisElement) { + equal = otherElement.contains(element); + if (!equal) { + break; + } + } + return equal; + } +} diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/AddChildTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/AddChildTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/ArchetypedTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/ArchetypedTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/FeederAuditDetailsTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/FeederAuditDetailsTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/LocatableTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/LocatableTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/PathBasedQueryTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/PathBasedQueryTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/PathBasedValueSettingTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/PathBasedValueSettingTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/PathUtilTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/PathUtilTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/RemoveChildTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/RemoveChildTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/common/changecontrol/ChangeControlTestBase.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/changecontrol/ChangeControlTestBase.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/common/changecontrol/ImportedVersionTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/changecontrol/ImportedVersionTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/common/changecontrol/OriginalVersionTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/changecontrol/OriginalVersionTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/common/changecontrol/VersionedObjectTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/changecontrol/VersionedObjectTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/common/directory/FolderTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/directory/FolderTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/common/generic/AuditDetailsCreateTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/generic/AuditDetailsCreateTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/common/generic/PartyIdentifiedTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/generic/PartyIdentifiedTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/common/generic/RevisionHistoryTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/generic/RevisionHistoryTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/common/resource/AuthoredResourceTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/resource/AuthoredResourceTest.java old mode 100755 new mode 100644 index b1222f3c..0d524878 --- a/openehr-rm-core/src/test/java/org/openehr/rm/common/resource/AuthoredResourceTest.java +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/resource/AuthoredResourceTest.java @@ -1,136 +1,142 @@ -/* - * component: "openEHR Reference Implementation" - * description: "Class AuthoredResourceTest" - * keywords: "unit test" - * - * author: "Yin Su Lim " - * support: "CHIME, UCL" - * copyright: "Copyright (c) 2006 UCL, UK" - * license: "See notice at bottom of class" - * - * file: "$URL: http://svn.openehr.org/ref_impl_java/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/common/resource/AuthoredResourceTest.java $" - * revision: "$LastChangedRevision: 50 $" - * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" - */ - -/** - * AuthoredResourceTest - * - * @author Yin Su Lim - * @version 1.0 - */ - -package org.openehr.rm.common.resource; - -import junit.framework.*; -import java.util.HashMap; -import java.util.HashSet; -import org.openehr.rm.common.generic.RevisionHistory; -import org.openehr.rm.datatypes.text.CodePhrase; -import org.openehr.rm.support.identification.TestTerminologyID; -import org.openehr.rm.support.terminology.TerminologyService; -import org.openehr.rm.support.terminology.TestTerminologyService; - -public class AuthoredResourceTest extends ResourceTestBase { - - public AuthoredResourceTest(String testName) { - super(testName); - } - - protected void setUp() throws Exception { - } - - protected void tearDown() throws Exception { - } - - public static Test suite() { - TestSuite suite = new TestSuite(AuthoredResourceTest.class); - - return suite; - } - - public void test() { - CodePhrase orgLang = new CodePhrase(TestTerminologyID.LANGUAGE, "en"); - - String[] fr = {"fr"}; - String[] languages = {"en", "fr"}; - String[] purposes = {"purpose", "but"}; - ResourceDescription rd = new ResourceDescription(hashMap("Sam Heard", "Dr. Sam Heard"), - null, "initial", details(languages, purposes), null, null, null); - AuthoredResource ar = new AuthoredResourceImpl(orgLang, translations(fr), rd, null, false, - TestTerminologyService.getInstance()); - assertEquals(ar, rd.getParentResource()); - assertEquals("uncontrolled", ar.currentRevision()); - HashSet lAvailable = new HashSet(); - lAvailable.add("en"); - lAvailable.add("fr"); - assertEquals(lAvailable, ar.languagesAvailable()); - - } - - - - public void testFails() { - - CodePhrase orgLang = new CodePhrase(TestTerminologyID.LANGUAGE, "en"); - String[] languages = {"en", "fr"}; - String[] fr = {"fr"}; - - failConstructor(null, null, null, null, false, TestTerminologyService.getInstance(), - "original language missing"); - failConstructor(orgLang, null, null, null, true, TestTerminologyService.getInstance(), - "revision history missing"); - failConstructor(orgLang, translations(languages), null, null, true, TestTerminologyService.getInstance(), - "translations contain org language"); - - String[] languages2 = {"en", "fr", "us"}; - String[] purposes = {"purpose", "but", "purpose"}; - ResourceDescription rd = new ResourceDescription(hashMap("Sam Heard", "Dr. Sam Heard"), - null, "initial", details(languages2, purposes), null, null, null); - failConstructor(orgLang, translations(fr), rd, null, false, TestTerminologyService.getInstance(), - "description contains more languages than translations"); - } - - private void failConstructor(CodePhrase orgLang, HashMap translations, ResourceDescription rd, - RevisionHistory revisionHistory, boolean isControlled, - TerminologyService terminologyService, String reason) { - try { - AuthoredResource ar = new AuthoredResourceImpl(orgLang, translations, rd, revisionHistory, - isControlled, terminologyService); - fail(reason); - } catch (IllegalArgumentException iae) { - //System.out.println(iae.getMessage()); - } - } -} - -/* - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the 'License'); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an 'AS IS' basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is AuthoredResourceTest.java - * - * The Initial Developer of the Original Code is Rong Chen. - * Portions created by the Initial Developer are Copyright (C) 2003-2004 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Software distributed under the License is distributed on an 'AS IS' basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * ***** END LICENSE BLOCK ***** +/* + * component: "openEHR Reference Implementation" + * description: "Class AuthoredResourceTest" + * keywords: "unit test" + * + * author: "Yin Su Lim " + * support: "CHIME, UCL" + * copyright: "Copyright (c) 2006 UCL, UK" + * license: "See notice at bottom of class" + * + * file: "$URL: http://svn.openehr.org/ref_impl_java/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/common/resource/AuthoredResourceTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" + */ + +/** + * AuthoredResourceTest + * + * @author Yin Su Lim + * @version 1.0 + */ + +package org.openehr.rm.common.resource; + +import junit.framework.*; +import java.util.HashMap; +import java.util.HashSet; +import org.openehr.rm.common.generic.RevisionHistory; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.identification.TestTerminologyID; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.rm.support.terminology.TestTerminologyService; + +public class AuthoredResourceTest extends ResourceTestBase { + + public AuthoredResourceTest(String testName) { + super(testName); + } + + @Override + protected void setUp() throws Exception { + } + + @Override + protected void tearDown() throws Exception { + } + + public static Test suite() { + TestSuite suite = new TestSuite(AuthoredResourceTest.class); + + return suite; + } + + public void test() { + CodePhrase orgLang = new CodePhrase(TestTerminologyID.LANGUAGE, "en"); + + String[] fr = {"fr"}; + String[] languages = {"en", "fr"}; + String[] purposes = {"purpose", "but"}; + ResourceDescription rd = new ResourceDescription(hashMap("Sam Heard", "Dr. Sam Heard"), + null, "initial", details(languages, purposes), null, null, null); + AuthoredResource ar = new AuthoredResourceImpl(orgLang, translations(fr), rd, null, false, + TestTerminologyService.getInstance()); + assertEquals(ar, rd.getParentResource()); + assertEquals("uncontrolled", ar.currentRevision()); + HashSet lAvailable = new HashSet(); + lAvailable.add("en"); + lAvailable.add("fr"); + assertEquals(lAvailable, ar.languagesAvailable()); + + // This may look like a stupid test, but since a ResourceDescription is explicitly referencing its own parentResource, we + // must ensure that this comparison does not run into problems: + rd.setParentResource(ar); + assertEquals(ar, ar); + } + + + + public void testFails() { + + CodePhrase orgLang = new CodePhrase(TestTerminologyID.LANGUAGE, "en"); + String[] languages = {"en", "fr"}; + String[] fr = {"fr"}; + + failConstructor(null, null, null, null, false, TestTerminologyService.getInstance(), + "original language missing"); + failConstructor(orgLang, null, null, null, true, TestTerminologyService.getInstance(), + "revision history missing"); + failConstructor(orgLang, translations(languages), null, null, true, TestTerminologyService.getInstance(), + "translations contain org language"); + + String[] languages2 = {"en", "fr", "us"}; + String[] purposes = {"purpose", "but", "purpose"}; + ResourceDescription rd = new ResourceDescription(hashMap("Sam Heard", "Dr. Sam Heard"), + null, "initial", details(languages2, purposes), null, null, null); + failConstructor(orgLang, translations(fr), rd, null, false, TestTerminologyService.getInstance(), + "description contains more languages than translations"); + } + + private void failConstructor(CodePhrase orgLang, HashMap translations, ResourceDescription rd, + RevisionHistory revisionHistory, boolean isControlled, + TerminologyService terminologyService, String reason) { + try { + AuthoredResource ar = new AuthoredResourceImpl(orgLang, translations, rd, revisionHistory, + isControlled, terminologyService); + fail(reason); + } catch (IllegalArgumentException iae) { + //System.out.println(iae.getMessage()); + } + } +} + +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the 'License'); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is AuthoredResourceTest.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * ***** END LICENSE BLOCK ***** */ \ No newline at end of file diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/common/resource/ResourceDescriptionTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/resource/ResourceDescriptionTest.java old mode 100755 new mode 100644 index b0f2792a..97ddd72b --- a/openehr-rm-core/src/test/java/org/openehr/rm/common/resource/ResourceDescriptionTest.java +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/resource/ResourceDescriptionTest.java @@ -24,6 +24,8 @@ import junit.framework.*; import java.util.HashMap; import java.util.List; +import java.util.Map; + import org.openehr.rm.datatypes.text.CodePhrase; import org.openehr.rm.support.identification.TestTerminologyID; import org.openehr.rm.support.terminology.TestTerminologyService; @@ -90,7 +92,7 @@ public void testFails() { } private void failConstructor(HashMap orgAuthor, List - otherContr, String lifeCycleState, List details, + otherContr, String lifeCycleState, Map details, String resourcePackageUri, HashMap otherDetails, AuthoredResource parentResource, String reason) { try { diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/common/resource/ResourceTestBase.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/resource/ResourceTestBase.java old mode 100755 new mode 100644 index 2a7ee53d..17c92297 --- a/openehr-rm-core/src/test/java/org/openehr/rm/common/resource/ResourceTestBase.java +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/resource/ResourceTestBase.java @@ -24,6 +24,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; + import junit.framework.TestCase; import org.openehr.rm.common.generic.RevisionHistory; import org.openehr.rm.datatypes.text.CodePhrase; @@ -38,13 +40,14 @@ public ResourceTestBase(String name) { super(name); } - protected List details(String[] languages, String[] purposes) { - List rdiList = new ArrayList(); + protected Map details(String[] languages, String[] purposes) { + Map rdiList = new HashMap(); for(int i = 0; i < languages.length; i++) { - CodePhrase orgLang = new CodePhrase(TestTerminologyID.LANGUAGE, languages[i]); + String languageCode = languages[i]; + CodePhrase orgLang = new CodePhrase(TestTerminologyID.LANGUAGE, languageCode); ResourceDescriptionItem rdi = new ResourceDescriptionItem(orgLang, purposes[i], TestTerminologyService.getInstance()); - rdiList.add(rdi); + rdiList.put(languageCode, rdi); } return rdiList; } diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/DataStructureTestBase.java b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/DataStructureTestBase.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/history/HistoryTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/history/HistoryTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/history/IntervalEventTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/history/IntervalEventTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/history/PointEventTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/history/PointEventTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemListTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemListTest.java old mode 100755 new mode 100644 index aaf3a35d..22c0e6ff --- a/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemListTest.java +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemListTest.java @@ -75,6 +75,93 @@ public void testIthItem() throws Exception { } assertTrue(itemList.namedItem("unknown name") == null); } + + public void testEquals() { + List elementsOne = new ArrayList(); + + elementsOne.add(element(NAMES[0], VALUES[0])); + elementsOne.add(element(NAMES[1], VALUES[1])); + elementsOne.add(element(NAMES[2], VALUES[2])); + + ItemList itemListOne = new ItemList(null, "at001", text(NAME), null, + null, null, null, elementsOne); + + List elementsTwo = new ArrayList(); + + elementsTwo.add(element(NAMES[0], VALUES[0])); + elementsTwo.add(element(NAMES[1], VALUES[1])); + elementsTwo.add(element(NAMES[2], VALUES[2])); + + ItemList itemListTwo = new ItemList(null, "at001", text(NAME), null, + null, null, null, elementsTwo); + + assertTrue(itemListOne.equals(itemListTwo)); + } + + public void testEqualsElementsInMixedOrder() { + List elementsOne = new ArrayList(); + + elementsOne.add(element(NAMES[0], VALUES[0])); + elementsOne.add(element(NAMES[1], VALUES[1])); + elementsOne.add(element(NAMES[2], VALUES[2])); + + ItemList itemListOne = new ItemList(null, "at001", text(NAME), null, + null, null, null, elementsOne); + + List elementsTwo = new ArrayList(); + + elementsTwo.add(element(NAMES[0], VALUES[0])); + elementsTwo.add(element(NAMES[2], VALUES[2])); + elementsTwo.add(element(NAMES[1], VALUES[1])); + + ItemList itemListTwo = new ItemList(null, "at001", text(NAME), null, + null, null, null, elementsTwo); + + assertTrue(itemListOne.equals(itemListTwo)); + } + + public void testNotEqualSize() { + List elementsOne = new ArrayList(); + + elementsOne.add(element(NAMES[0], VALUES[0])); + elementsOne.add(element(NAMES[1], VALUES[1])); + elementsOne.add(element(NAMES[2], VALUES[2])); + + ItemList itemListOne = new ItemList(null, "at001", text(NAME), null, + null, null, null, elementsOne); + + List elementsTwo = new ArrayList(); + + elementsTwo.add(element(NAMES[0], VALUES[0])); + elementsTwo.add(element(NAMES[1], VALUES[1])); + + ItemList itemListTwo = new ItemList(null, "at001", text(NAME), null, + null, null, null, elementsTwo); + + assertFalse(itemListOne.equals(itemListTwo)); + } + + public void testNotEqual() { + List elementsOne = new ArrayList(); + + elementsOne.add(element(NAMES[0], VALUES[0])); + elementsOne.add(element(NAMES[1], VALUES[1])); + elementsOne.add(element(NAMES[2], VALUES[2])); + + ItemList itemListOne = new ItemList(null, "at001", text(NAME), null, + null, null, null, elementsOne); + + List elementsTwo = new ArrayList(); + + elementsTwo.add(element(NAMES[0], VALUES[0])); + elementsTwo.add(element(NAMES[1], VALUES[1])); + elementsTwo.add(element("Location", "LocationValue")); + + ItemList itemListTwo = new ItemList(null, "at001", text(NAME), null, + null, null, null, elementsTwo); + + assertFalse(itemListOne.equals(itemListTwo)); + } // create a itemList as the example in the spec doc private ItemList init() { diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemSingleTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemSingleTest.java old mode 100755 new mode 100644 index 0a584e25..1b437473 --- a/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemSingleTest.java +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemSingleTest.java @@ -129,6 +129,36 @@ public void testItemAtPathOnWhole() throws Exception { assertEquals("unexpected whole", itemSingle, value); } + public void testEquals() { + Element elementOne = new Element("at0002", new DvText("test element"), + new DvText("text value")); + ItemSingle itemSingleOne = new ItemSingle(null, "at0001", + text("single item"), null, null, null, null, elementOne); + + Element elementTwo = new Element("at0002", new DvText("test element"), + new DvText("text value")); + ItemSingle itemSingleTwo = new ItemSingle(null, "at0001", + text("single item"), null, null, null, null, elementTwo); + + assertTrue(itemSingleOne.equals(itemSingleTwo)); + } + + public void testNotEquals() { + Element elementOne = new Element("at0002", new DvText("test element"), + new DvText("text value")); + ItemSingle itemSingleOne = new ItemSingle(null, "at0001", + text("single item"), null, null, null, null, elementOne); + + Element elementTwo = new Element("at0003", new DvText("test element"), + new DvText("text value")); + ItemSingle itemSingleTwo = new ItemSingle(null, "at0001", + text("single item"), null, null, null, null, elementTwo); + + assertFalse(itemSingleOne.equals(itemSingleTwo)); + } + + + private String path; private Object value; private Element element; diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemTableTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemTableTest.java old mode 100755 new mode 100644 index fa58991e..b9a35fae --- a/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemTableTest.java +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemTableTest.java @@ -301,6 +301,68 @@ public void testItemAtPathRow3Column2Name() throws Exception { itemTable.itemAtPath("/rows['3']/items['visual acuity']")); } + public void testEquals() { + List rows = new ArrayList(); + + // 1st row + Element eyes = new Element("at0001", new DvText("eye(s)"), new DvText( + "right")); + Element acuity = new Element("at0002", new DvText("visual acuity"), + new DvProportion(6, 6, ProportionKind.RATIO, 0)); + List itemsOne = new ArrayList(); + itemsOne.add(eyes); + itemsOne.add(acuity); + + // 2nd row + eyes = new Element("at0004", new DvText("eye(s)"), new DvText("left")); + acuity = new Element("at0005", new DvText("visual acuity"), + new DvProportion(6, 18, ProportionKind.RATIO, 0)); + List itemsTwo = new ArrayList(); + itemsTwo.add(eyes); + itemsTwo.add(acuity); + + rows.add(new Cluster("at0003", new DvText("1"), itemsOne)); + rows.add(new Cluster("at0006", new DvText("2"), itemsTwo)); + + ItemTable itemTableOne = new ItemTable("at0010", new DvText("vision"), + rows); + ItemTable itemTableTwo = new ItemTable("at0010", new DvText("vision"), + rows); + + assertTrue(itemTableOne.equals(itemTableTwo)); + } + + public void testNotEqualsDifferentNodeId() { + List rows = new ArrayList(); + + // 1st row + Element eyes = new Element("at0001", new DvText("eye(s)"), new DvText( + "right")); + Element acuity = new Element("at0002", new DvText("visual acuity"), + new DvProportion(6, 6, ProportionKind.RATIO, 0)); + List itemsOne = new ArrayList(); + itemsOne.add(eyes); + itemsOne.add(acuity); + + // 2nd row + eyes = new Element("at0004", new DvText("eye(s)"), new DvText("left")); + acuity = new Element("at0005", new DvText("visual acuity"), + new DvProportion(6, 18, ProportionKind.RATIO, 0)); + List itemsTwo = new ArrayList(); + itemsTwo.add(eyes); + itemsTwo.add(acuity); + + rows.add(new Cluster("at0003", new DvText("1"), itemsOne)); + rows.add(new Cluster("at0006", new DvText("2"), itemsTwo)); + + ItemTable itemTableOne = new ItemTable("at0010", new DvText("vision"), + rows); + ItemTable itemTableTwo = new ItemTable("at0011", new DvText("vision"), + rows); + + assertFalse(itemTableOne.equals(itemTableTwo)); + } + /* field */ private List rows; private ItemTable itemTable; diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemTreeTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemTreeTest.java old mode 100755 new mode 100644 index 49f1371a..d1ae0257 --- a/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemTreeTest.java +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemTreeTest.java @@ -185,6 +185,86 @@ public void testCreateEmptyTree() { ItemTree empty = new ItemTree("at0001", new DvText("tree"), null); assertNotNull(empty); } + + public void testEquals() { + assertTrue(getItemTreeOne().equals(getItemTreeOne())); + } + + public void testEqualsMixedItemOrder() { + assertTrue(getItemTreeOne().equals(getItemTreeOneMixedOrder())); + } + + public void testNotEquals() { + assertFalse(getItemTreeOne().equals(getItemTreeTwo())); + } + + private ItemTree getItemTreeOne() { + List itemsOne = new ArrayList(); + itemsOne.add(totalCholesterol); + itemsOne.add(ldlCholesterol); + itemsOne.add(hdlCholesterol); + lipidStudies = new Cluster("at0005", new DvText("lipid studies"), + itemsOne); + // comment + comment = new Element("at0006", new DvText("comment"), new DvText( + "high cardiac risk")); + + itemsOne = new ArrayList(); + itemsOne.add(sample); + itemsOne.add(lipidStudies); + itemsOne.add(comment); + ItemTree itemTreeOne = new ItemTree("at0007", new DvText( + "biochemstry result"), itemsOne); + return itemTreeOne; + } + + private ItemTree getItemTreeOneMixedOrder() { + // Item list contains the same as the item tree one but added to the + // list in different order + + List itemsOne = new ArrayList(); + itemsOne.add(totalCholesterol); + itemsOne.add(ldlCholesterol); + itemsOne.add(hdlCholesterol); + lipidStudies = new Cluster("at0005", new DvText("lipid studies"), + itemsOne); + + // comment + comment = new Element("at0006", new DvText("comment"), new DvText( + "high cardiac risk")); + + itemsOne = new ArrayList(); + itemsOne.add(lipidStudies); + itemsOne.add(sample); + itemsOne.add(comment); + ItemTree itemTreeOne = new ItemTree("at0007", new DvText( + "biochemstry result"), itemsOne); + return itemTreeOne; + } + + private ItemTree getItemTreeTwo() { + // same as the item tree one but sample is removed from the item list + + List itemsTwo = new ArrayList(); + itemsTwo.add(totalCholesterol); + itemsTwo.add(ldlCholesterol); + itemsTwo.add(hdlCholesterol); + lipidStudies = new Cluster("at0005", new DvText("lipid studies"), + itemsTwo); + + // comment + comment = new Element("at0006", new DvText("commentingng"), new DvText( + "high cardiac risk")); + + itemsTwo = new ArrayList(); + + itemsTwo.add(lipidStudies); + itemsTwo.add(sample); + itemsTwo.add(comment); + ItemTree itemTreeTwo = new ItemTree("at0007", new DvText( + "biochemstry result"), itemsTwo); + return itemTreeTwo; + } /* fields */ private ItemTree itemTree; diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/representation/CreateEmptyElementTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/representation/CreateEmptyElementTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/basic/DvBooleanTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/basic/DvBooleanTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/basic/DvStateTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/basic/DvStateTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/basic/ParseDataValueTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/basic/ParseDataValueTest.java old mode 100755 new mode 100644 index 50cfa8ad..814bc4e5 --- a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/basic/ParseDataValueTest.java +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/basic/ParseDataValueTest.java @@ -1,5 +1,6 @@ package org.openehr.rm.datatypes.basic; +import org.openehr.rm.datatypes.encapsulated.DvParsable; import org.openehr.rm.datatypes.quantity.DvCount; import org.openehr.rm.datatypes.quantity.DvQuantity; import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; @@ -88,6 +89,12 @@ public void testCodedTextRoundTrip() { assertEquals("DvCodedText round trip failed", coded, DataValue.parseValue(s)); } + public void testParsableRoundTrip() { + DvParsable parsable = new DvParsable("text", "txt"); + String s = parsable.serialise(); + assertEquals("DvCodedText round trip failed", parsable, DataValue.parseValue(s)); + } + // test instance private DataValue dv; } diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/encapsulated/DvMultimediaTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/encapsulated/DvMultimediaTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvCountTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvCountTest.java index 972ec277..8ac206ab 100755 --- a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvCountTest.java +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvCountTest.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Map; +import org.openehr.rm.datatypes.text.DvCodedText; import org.openehr.rm.datatypes.text.DvText; import junit.framework.TestCase; @@ -90,6 +91,11 @@ public void testGetOtherReferenceRanges() throws Exception { assertEquals("otherReferenceRanges wrong", otherReferenceRanges, count.getOtherReferenceRanges()); } + + public void testValueOf() { + DvCount dvCount = DvCount.valueOf("5"); + assertEquals(5, dvCount.getMagnitude().intValue()); + } } /* * ***** BEGIN LICENSE BLOCK ***** diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvOrderedTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvOrderedTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvOrdinalTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvOrdinalTest.java index ca711db6..756ce276 100755 --- a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvOrdinalTest.java +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvOrdinalTest.java @@ -8,12 +8,7 @@ public class DvOrdinalTest extends TestCase { - /** - * Tests creating a dvOrdinal with negative value - * - * @throws Exception - */ - public void testCreateDvOrdinalWithNegativeValue() { + public void testCreateDvOrdinalWithNegativeValue() { CodePhrase definingCode = new CodePhrase("test", "123"); DvCodedText coded = new DvCodedText("coded text", definingCode); @@ -30,6 +25,14 @@ public void testParseDvOrdinal() throws Exception { DataValue dv = DataValue.parseValue(value); assertTrue(dv instanceof DvOrdinal); } + + public void testValueOf() throws Exception { + DvOrdinal dvOrdinal = DvOrdinal.valueOf("1|SNOMED-CT::313267000|Stroke|"); + assertEquals(1, dvOrdinal.getValue()); + assertEquals("SNOMED-CT", dvOrdinal.getTerminologyId()); + assertEquals("313267000", dvOrdinal.getCode()); + assertEquals("Stroke", dvOrdinal.getSymbolValue()); + } public void testEquals() { DvOrdinal ord1 = new DvOrdinal(1, new DvCodedText("text", diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvProportionTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvProportionTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvQuantityTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvQuantityTest.java index e315fa13..e27b858a 100755 --- a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvQuantityTest.java +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvQuantityTest.java @@ -16,7 +16,7 @@ * QuantityTest * * @author Rong Chen - * @version 1.0 + * @version 1.0 */ package org.openehr.rm.datatypes.quantity; @@ -103,36 +103,56 @@ public void testToString() throws Exception { expected = "78.500"; assertEquals(expected, q.toString()); } - + public void testParseQuantityWithPrecision() throws Exception { String value = "78.500,kg"; DvQuantity expected = new DvQuantity("kg", 78.5, 3); DvQuantity q = expected.parse(value); assertEquals("failed to parse quantity with precision", expected, q); } - + + public void testValueOfWithIntegerValue() { + DvQuantity dvQuantity = DvQuantity.valueOf("113,min/wk"); + assertEquals(113.0, dvQuantity.getMagnitude()); + assertEquals("min/wk", dvQuantity.getUnits()); + } + + public void testValueOfWithDecimalValue() { + DvQuantity dvQuantity = DvQuantity.valueOf("78.500,kg"); + assertEquals(78.5, dvQuantity.getMagnitude()); + assertEquals("kg", dvQuantity.getUnits()); + assertEquals(3, dvQuantity.getPrecision()); + } + public void testParseQuantityWithoutPrecision() throws Exception { String value = "78,kg"; DvQuantity expected = new DvQuantity("kg", 78, 0); DvQuantity q = expected.parse(value); - assertEquals("failed to parse quantity with precision", expected, q); + assertEquals("failed to parse quantity without precision", expected, q); } - + + public void testParseQuantityWithoutUnit() throws Exception { + String value = "78"; + DvQuantity expected = new DvQuantity(78); + DataValue q = expected.parse(value); + assertEquals("failed to parse quantity without unit", expected, q); + } + public void testDataValueParseQuantityWithoutPrecision() throws Exception { String value = "78,kg"; DvQuantity expected = new DvQuantity("kg", 78, 0); DataValue q = DataValue.parseValue("DV_QUANTITY," + value); - assertEquals("failed to parse quantity with precision", expected, q); + assertEquals("failed to parse quantity as DataValue without precision", expected, q); } - + public void testCreateWithUnlimitedPrecision() { - try { + try { new DvQuantity("mg", 12, -1, ms); } catch(Exception e) { fail("failed to create DvQuantity with unlimited precision"); } } - + private MeasurementService ms = new TestMeasurementService(); } /* diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/ProportionKindTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/ProportionKindTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeParserTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeParserTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeParserTimeZoneTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeParserTimeZoneTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeTest.java index 2948f908..1494d208 100755 --- a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeTest.java +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeTest.java @@ -122,6 +122,16 @@ public void testSubtract() throws Exception { DvDateTime datetime = new DvDateTime("2003-12-15T09:30:00Z"); assertEquals(new DvDateTime("2002-12-13T18:45:00Z"), datetime.subtract(new DvDuration("P1Y1DT14H45m"))); } + + public void testValueOf() { + DvDateTime datetime = DvDateTime.valueOf("2014-07-09T12:13:05"); + assertEquals("year", 2014, datetime.getYear()); + assertEquals("month", 7, datetime.getMonth()); + assertEquals("day", 9, datetime.getDay()); + assertEquals("hour", 12, datetime.getHour()); + assertEquals("minute", 13, datetime.getMinute()); + assertEquals("second", 05, datetime.getSecond()); + } } /* * ***** BEGIN LICENSE BLOCK ***** diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDurationTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDurationTest.java index 8f8fc340..1a9b6d2d 100755 --- a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDurationTest.java +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDurationTest.java @@ -31,17 +31,19 @@ public DvDurationTest(String test) { /** * The fixture set up called before every test method. */ + @Override protected void setUp() throws Exception { } /** * The fixture clean up called after every test method. */ + @Override protected void tearDown() throws Exception { } public void testConstructorTakesString() throws Exception { - + // test with wrong format String[] value = { null, "P10D9H8m7s", "10", "", "P10D11WT9h8M7s", "P10a8m7s", "T9H8m0,000s", @@ -64,10 +66,10 @@ public void testConstructorTakesString() throws Exception { }; int[][] data = { {0, 12, 32, 10, 9, 8, 7, 898}, {0, 0, 0, 10, 9, 8, 7, 0}, - {0, 0, 0, 10, 0, 0, 0, 0}, {0, 0, 0, 0, 9, 0, 0, 0}, {0, 0, 0, 0, 0, 8, 0, 0}, + {0, 0, 0, 10, 0, 0, 0, 0}, {0, 0, 0, 0, 9, 0, 0, 0}, {0, 0, 0, 0, 0, 8, 0, 0}, {0, 0, 0, 0, 0, 0, 7, 0}, {0, 0, 0, 10, 9, 0, 0, 0}, - {0, 0, 0, 0, 9, 8, 0, 0}, {0, 0, 0, 0, 0, 8, 7, 0}, - {0, 0, 0, 10, 0, 0, 7, 0}, {0, 0, 0, 10, 9, 0, 7, 0}, + {0, 0, 0, 0, 9, 8, 0, 0}, {0, 0, 0, 0, 0, 8, 7, 0}, + {0, 0, 0, 10, 0, 0, 7, 0}, {0, 0, 0, 10, 9, 0, 7, 0}, {0, 0, 0, 0, 9, 0, 8, 0}, {1, 2, 3, 4, 0, 0, 0, 0}, {9, 0, 0, 6, 0, 0, 2, 990}, {0, 0, 35, 0, 45, 0, 0, 0}, {0, 20, 0, 33, 0, 79, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 190}, @@ -105,7 +107,7 @@ private void assertDuration(String value, int[] data) { public void testConstructorTakesIntegers() throws Exception { int[][] data = { {0, 10, 3, 1, 19, 8, 37, 857}, {0, 0, 0, 1, 0, 14, 2, 0}, - {0, 13, 56, 33, 25, 67, 77, 0}, {0, -1, -2, 0, -9, 0, 0, 0}, + {0, 13, 56, 33, 25, 67, 77, 0}, {0, -1, -2, 0, -9, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 10, 9, 0, 0, 0}, }; for(int i = 0; i < data.length; i++) { @@ -120,7 +122,7 @@ public void testConstructorTakesIntegers() throws Exception { assertEquals("fseconds", data[i][ 7 ], (int)(d.getFractionalSeconds()*1000.0)); } int[][] fData = { - {0, 0, 3, 1, 0, 8, 37, 1857}, {0, 0, 0, -1, 0, 14, 2, 0}, + {0, 0, 3, 1, 0, 8, 37, 1857}, {0, 0, 0, -1, 0, 14, 2, 0}, }; for(int i = 0; i < fData.length; i++) { try { @@ -136,7 +138,7 @@ public void testAdd() throws Exception { DvDuration one = new DvDuration(0, 0, 0, 10, 20, 30, 40, .5); DvDuration two = new DvDuration(0, 0, 1, 1, 2, 3, 4, .05); DvDuration d = (DvDuration) one.add(two); - + assertEquals("years", 0, d.getYears()); assertEquals("months", 0, d.getMonths()); assertEquals("weeks", 2, d.getWeeks()); //10d + 1W1d = 18d @@ -146,7 +148,7 @@ public void testAdd() throws Exception { assertEquals("seconds", 44, d.getSeconds()); assertEquals("fractionalSeconds", .55, d.getFractionalSeconds()); - + DvDuration three = new DvDuration("P1y2WT2H10m1,60S"); d = (DvDuration)d.add(three); assertEquals("years", 1, d.getYears()); @@ -195,7 +197,7 @@ public void testToString() throws Exception { //TODO!!! int[][] data = { {0, 0, 0, 10, 20, 30, 40, 0}, {0, 0, 0, 1, 0, 14, 2, 0}, - {0, 13, 56, 33, 25, 67, 77, 0}, {0, -1, -2, 0, -9, 0, 0, 0}, + {0, 13, 56, 33, 25, 67, 77, 0}, {0, -1, -2, 0, -9, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 11, 23, 10, 9, 5, 0, 123} }; String[] strings = { @@ -206,14 +208,17 @@ public void testToString() throws Exception { DvDuration d = toDuration(data[i]); assertEquals(strings[i], d.toString()); } - + String[] strValues = { "P10DT20H30M40.66S", "P16M45DT60M2S", "P13M56W33DT2H6M5.0S", - "-P1M2WT9H", "PT0S", "P11M23W10DT9H5M0,123S", "P" + "-P1M2WT9H", "PT0S", "P11M23W10DT9H5M0,123S", "P", "P0Y" }; for(int i = 0; i < strValues.length; i++) { DvDuration d = new DvDuration(strValues[i]); assertEquals(strValues[i], d.toString()); + + DvDuration fromInstanceD = DvDuration.getInstance(strValues[i]); // This may be slightly different therefore we should test this as well. + assertEquals(strValues[i], fromInstanceD.toString()); } } diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvTimeTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvTimeTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/text/DvCodedTextTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/text/DvCodedTextTest.java index a03962b1..c059dc5d 100755 --- a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/text/DvCodedTextTest.java +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/text/DvCodedTextTest.java @@ -42,4 +42,10 @@ public void testEquals() throws Exception { assertEquals(t1, t2); } + public void testValueOf() { + DvCodedText dvCodedText = DvCodedText.valueOf("ATC::B01AC05|ticlopidine|"); + assertEquals("ATC", dvCodedText.getTerminologyId()); + assertEquals("B01AC05", dvCodedText.getCode()); + assertEquals("ticlopidine", dvCodedText.getValue()); + } } \ No newline at end of file diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/text/DvTextTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/text/DvTextTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/text/TestCodePhrase.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/text/TestCodePhrase.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/support/basic/IntervalTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/basic/IntervalTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/ArchetypeIDTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/ArchetypeIDTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/HierObjectIDTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/HierObjectIDTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/ISO_OIDTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/ISO_OIDTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/InternetIDTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/InternetIDTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/ObjectRefTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/ObjectRefTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/ObjectVersionIDTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/ObjectVersionIDTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/TerminologyIDTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/TerminologyIDTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/TestTerminologyID.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/TestTerminologyID.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/UUIDTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/UUIDTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/VersionTreeIDTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/VersionTreeIDTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/support/measurement/TestMeasurementService.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/measurement/TestMeasurementService.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/OpenEHRCodeSetIdentifiersTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/OpenEHRCodeSetIdentifiersTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/OpenEHRTerminologyGroupIdentifiersTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/OpenEHRTerminologyGroupIdentifiersTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/TestCodeSetAccess.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/TestCodeSetAccess.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/TestTerminologyAccess.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/TestTerminologyAccess.java old mode 100755 new mode 100644 diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/TestTerminologyService.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/TestTerminologyService.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index e0cb2e57..7a88620e 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -2,9 +2,9 @@ 4.0.0 - openehr - ref_impl_java - 1.0.5-SNAPSHOT + org.openehr.java-libs + java-libs + 0-SNAPSHOT openehr-rm-domain jar @@ -21,12 +21,12 @@ - openehr + org.openehr.java-libs openehr-rm-core ${project.version} - openehr + org.openehr.java-libs mini-termserv ${project.version} test diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/Composition.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/Composition.java index 2854eda6..b0e63b86 100755 --- a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/Composition.java +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/Composition.java @@ -1,314 +1,320 @@ -/* - * component: "openEHR Reference Implementation" - * description: "Class Composition" - * keywords: "composition" - * - * author: "Rong Chen " - * support: "Acode HB " - * copyright: "Copyright (c) 2004 Acode HB, Sweden" - * license: "See notice at bottom of class" - * - * file: "$URL: http://svn.openehr.org/ref_impl_java/TRUNK/libraries/src/java/org/openehr/rm/composition/Composition.java $" - * revision: "$LastChangedRevision: 2 $" - * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" - */ -package org.openehr.rm.composition; - -import org.openehr.rm.Attribute; -import org.openehr.rm.FullConstructor; -import org.openehr.rm.common.archetyped.*; -import org.openehr.rm.common.generic.PartyProxy; -import org.openehr.rm.support.identification.UIDBasedID; -import org.openehr.rm.composition.content.ContentItem; -import org.openehr.rm.datatypes.text.CodePhrase; -import org.openehr.rm.datatypes.text.DvText; -import org.openehr.rm.datatypes.text.DvCodedText; -import org.openehr.rm.support.terminology.OpenEHRCodeSetIdentifiers; -import org.openehr.rm.support.terminology.TerminologyService; - -import java.util.*; - -/** - * A composition is considered the unit of modification of the - * record, the unit of transmission in record extracts, and the unit - * of attestation by authorising clinicians. In this latter sense, - * it may be considered equivalent to a signed document. - *

- * - * @author Rong Chen - * @version 1.0 - */ -public final class Composition extends Locatable { - - /** - * Constructs a Locatable - * - * @param uid null if not specified - * @param archetypeNodeId - * @param name - * @param archetypeDetails null if not specified - * @param feederAudit null if not specified - * @param links null if not specified - * @param content null if not specified - * @param context - * @param category - * @param territory - * @throws IllegalArgumentException if name null or archetypeNodeId null - * or links not null and empty - */ - @FullConstructor - public Composition(@Attribute(name = "uid") UIDBasedID uid, - @Attribute(name = "archetypeNodeId", required = true) String archetypeNodeId, - @Attribute(name = "name", required = true) DvText name, - @Attribute(name = "archetypeDetails", required = true) Archetyped archetypeDetails, - @Attribute(name = "feederAudit") FeederAudit feederAudit, - @Attribute(name = "links") Set links, - @Attribute(name = "parent") Pathable parent, - @Attribute(name = "content") List content, - @Attribute(name = "language", required = true) CodePhrase language, - @Attribute(name = "context") EventContext context, - @Attribute(name = "composer", required = true) PartyProxy composer, - @Attribute(name = "category", required = true) DvCodedText category, - @Attribute(name = "territory", required = true) CodePhrase territory, - @Attribute(name = "terminologyService", system = true) TerminologyService terminologyService) { - - super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, - links, parent); - - if (!isArchetypeRoot()) { - throw new IllegalArgumentException("not archetype root"); - } - - if (content != null && content.isEmpty()) { - throw new IllegalArgumentException("empty content"); - } - - if (isPersistent(category) && context != null) { - throw new IllegalArgumentException("invalid persistent category"); - } - if (composer == null) { - throw new IllegalArgumentException("null composer"); - } - if (language == null) { - throw new IllegalArgumentException("null language"); - } - if (parent != null) { - throw new IllegalArgumentException("parent must be null"); - } - - // Is_persistent_validity: is_persistent implies context = Void - if (category == null) { - throw new IllegalArgumentException("null cateogry"); - } - - // todo: implement this invariant check - // name_value: not is_persistent implies name.value.is_equal( - // context. health_care_facility.as_string + context.start_time.as_string) - - if (territory == null) { - throw new IllegalArgumentException("null territory"); - } - if (terminologyService == null) { - throw new IllegalArgumentException("null terminologyService"); - } - - if (!terminologyService.terminology(TerminologyService.OPENEHR) - .codesForGroupName("composition category", "en") - .contains(category.getDefiningCode())) { - throw new IllegalArgumentException( - "unknown category: " + category.getDefiningCode()); - } - if (!terminologyService.codeSetForId( - OpenEHRCodeSetIdentifiers.COUNTRIES).hasCode(territory)) { - throw new IllegalArgumentException( - "unknown territory: " + territory); - } - if (!terminologyService.codeSetForId( - OpenEHRCodeSetIdentifiers.LANGUAGES).hasCode(language)) { - throw new IllegalArgumentException("unknown language:" + language); - } - - this.content = content; - this.context = context; - this.language = language; - this.composer = composer; - this.category = category; - this.territory = territory; - } - - // check is given category indicates persistent type - private static boolean isPersistent(DvCodedText category) { - return category.getDefiningCode().getCodeString().equals("persistent"); - } - - public CodePhrase getLanguage() { - return language; - } - - /** - * The clinical session content of this Composition, ie the - * information generated in the clinical session. - * - * @return list of section or null if not present - */ - public List getContent() { - return content; - } - - /** - * The clinical session context of this Composition, ie the - * contextual attributes of the clinical session. - * - * @return context - */ - public EventContext getContext() { - return context; - } - - /** - * Indicates what broad category this Composition is belogs to, - * eg "persistent" - of longitudinal validity, "event", "process" etc - * - * @return category - */ - public DvCodedText getCategory() { - return category; - } - - - /** - * The person primarily responsible for the content of the Composition - * (but not necessarily its committal). This is the identifier which should - * appear on the screen. When it is the patient, the special "self" instance - * of the PartyProxy will be used. - * - * @return composer - */ - public PartyProxy getComposer() { - return composer; - } - - /** - * True if category is a "persistent" type, False otherwise. Useful for - * finding Compositions in an EHR which are guaranteed to be of interest - * to most users. - * - * @return true if persistent - */ - public boolean isPersistent() { - return isPersistent(category); - } - - /** - * Name of territory in which this Composition was written. - * Coded from openEHR "countries" code set, which is an - * expression of the ISO 3166 standard. - * - * @return territory - */ - public CodePhrase getTerritory() { - return territory; - } - - /** - * String The path to an item relative to the root of this - * archetyped structure. - * - * @param item - * @return string path - */ - public String pathOfItem(Locatable item) { - return null; // todo: implement this method - } - - @Override - public String pathOfItem(Pathable arg0) { - // TODO Auto-generated method stub - return null; - } - - @Override - public List itemsAtPath(String arg0) { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean pathExists(String arg0) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean pathUnique(String arg0) { - // TODO Auto-generated method stub - return false; - } - - // POJO start - Composition() { - } - - void setLanguage(CodePhrase language) { - this.language = language; - } - - void setContent(List content) { - this.content = content; - } - - void setContext(EventContext context) { - this.context = context; - } - - void setCategory(DvCodedText category) { - this.category = category; - } - - void setTerritory(CodePhrase territory) { - this.territory = territory; - } - - void setComposer(PartyProxy composer) { - this.composer = composer; - } - // POJO end - - /* fields */ - private List content; - private EventContext context; - private PartyProxy composer; - private DvCodedText category; - private CodePhrase territory; - private CodePhrase language; -} - -/* - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the 'License'); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an 'AS IS' basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Composition.java - * - * The Initial Developer of the Original Code is Rong Chen. - * Portions created by the Initial Developer are Copyright (C) 2003-2004 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Software distributed under the License is distributed on an 'AS IS' basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * ***** END LICENSE BLOCK ***** +/* + * component: "openEHR Reference Implementation" + * description: "Class Composition" + * keywords: "composition" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL: http://svn.openehr.org/ref_impl_java/TRUNK/libraries/src/java/org/openehr/rm/composition/Composition.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.composition; + +import java.util.List; +import java.util.Set; + +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.common.archetyped.Archetyped; +import org.openehr.rm.common.archetyped.FeederAudit; +import org.openehr.rm.common.archetyped.Link; +import org.openehr.rm.common.archetyped.Locatable; +import org.openehr.rm.common.archetyped.Pathable; +import org.openehr.rm.common.generic.PartyProxy; +import org.openehr.rm.composition.content.ContentItem; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.support.terminology.OpenEHRCodeSetIdentifiers; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * A composition is considered the unit of modification of the + * record, the unit of transmission in record extracts, and the unit + * of attestation by authorising clinicians. In this latter sense, + * it may be considered equivalent to a signed document. + *

+ * + * @author Rong Chen + * @version 1.0 + */ +public final class Composition extends Locatable { + + /** + * Constructs a Locatable + * + * @param uid null if not specified + * @param archetypeNodeId + * @param name + * @param archetypeDetails null if not specified + * @param feederAudit null if not specified + * @param links null if not specified + * @param content null if not specified + * @param context + * @param category + * @param territory + * @throws IllegalArgumentException if name null or archetypeNodeId null + * or links not null and empty + */ + @FullConstructor + public Composition(@Attribute(name = "uid") UIDBasedID uid, + @Attribute(name = "archetypeNodeId", required = true) String archetypeNodeId, + @Attribute(name = "name", required = true) DvText name, + @Attribute(name = "archetypeDetails", required = true) Archetyped archetypeDetails, + @Attribute(name = "feederAudit") FeederAudit feederAudit, + @Attribute(name = "links") Set links, + @Attribute(name = "parent") Pathable parent, + @Attribute(name = "content") List content, + @Attribute(name = "language", required = true) CodePhrase language, + @Attribute(name = "context") EventContext context, + @Attribute(name = "composer", required = true) PartyProxy composer, + @Attribute(name = "category", required = true) DvCodedText category, + @Attribute(name = "territory", required = true) CodePhrase territory, + @Attribute(name = "terminologyService", system = true) TerminologyService terminologyService) { + + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, + links, parent); + + if (!isArchetypeRoot()) { + throw new IllegalArgumentException("not archetype root"); + } + + if (content != null && content.isEmpty()) { + throw new IllegalArgumentException("empty content"); + } + + if (category == null) { + throw new IllegalArgumentException("null category"); + } + + // Is_persistent_validity: is_persistent implies context = Void + // As per SPEC-RM-26 this is no longer required (1.0.4) + //if (isPersistent(category) && context != null) { + // throw new IllegalArgumentException("invalid persistent category"); + //} + if (composer == null) { + throw new IllegalArgumentException("null composer"); + } + if (language == null) { + throw new IllegalArgumentException("null language"); + } + if (parent != null) { + throw new IllegalArgumentException("parent must be null"); + } + + // todo: implement this invariant check + // name_value: not is_persistent implies name.value.is_equal( + // context. health_care_facility.as_string + context.start_time.as_string) + + if (territory == null) { + throw new IllegalArgumentException("null territory"); + } + if (terminologyService == null) { + throw new IllegalArgumentException("null terminologyService"); + } + + if (!terminologyService.terminology(TerminologyService.OPENEHR) + .codesForGroupName("composition category", "en") + .contains(category.getDefiningCode())) { + throw new IllegalArgumentException( + "unknown category: " + category.getDefiningCode()); + } + if (!terminologyService.codeSetForId( + OpenEHRCodeSetIdentifiers.COUNTRIES).hasCode(territory)) { + throw new IllegalArgumentException( + "unknown territory: " + territory); + } + if (!terminologyService.codeSetForId( + OpenEHRCodeSetIdentifiers.LANGUAGES).hasCode(language)) { + throw new IllegalArgumentException("unknown language:" + language); + } + + this.content = content; + this.context = context; + this.language = language; + this.composer = composer; + this.category = category; + this.territory = territory; + } + + // check is given category indicates persistent type + private static boolean isPersistent(DvCodedText category) { + return category.getDefiningCode().getCodeString().equals("persistent"); + } + + public CodePhrase getLanguage() { + return language; + } + + /** + * The clinical session content of this Composition, ie the + * information generated in the clinical session. + * + * @return list of section or null if not present + */ + public List getContent() { + return content; + } + + /** + * The clinical session context of this Composition, ie the + * contextual attributes of the clinical session. + * + * @return context + */ + public EventContext getContext() { + return context; + } + + /** + * Indicates what broad category this Composition is belogs to, + * eg "persistent" - of longitudinal validity, "event", "process" etc + * + * @return category + */ + public DvCodedText getCategory() { + return category; + } + + + /** + * The person primarily responsible for the content of the Composition + * (but not necessarily its committal). This is the identifier which should + * appear on the screen. When it is the patient, the special "self" instance + * of the PartyProxy will be used. + * + * @return composer + */ + public PartyProxy getComposer() { + return composer; + } + + /** + * True if category is a "persistent" type, False otherwise. Useful for + * finding Compositions in an EHR which are guaranteed to be of interest + * to most users. + * + * @return true if persistent + */ + public boolean isPersistent() { + return isPersistent(category); + } + + /** + * Name of territory in which this Composition was written. + * Coded from openEHR "countries" code set, which is an + * expression of the ISO 3166 standard. + * + * @return territory + */ + public CodePhrase getTerritory() { + return territory; + } + + /** + * String The path to an item relative to the root of this + * archetyped structure. + * + * @param item + * @return string path + */ + public String pathOfItem(Locatable item) { + return null; // todo: implement this method + } + + @Override + public String pathOfItem(Pathable arg0) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List itemsAtPath(String arg0) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean pathExists(String arg0) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean pathUnique(String arg0) { + // TODO Auto-generated method stub + return false; + } + + // POJO start + Composition() { + } + + void setLanguage(CodePhrase language) { + this.language = language; + } + + void setContent(List content) { + this.content = content; + } + + void setContext(EventContext context) { + this.context = context; + } + + void setCategory(DvCodedText category) { + this.category = category; + } + + void setTerritory(CodePhrase territory) { + this.territory = territory; + } + + void setComposer(PartyProxy composer) { + this.composer = composer; + } + // POJO end + + /* fields */ + private List content; + private EventContext context; + private PartyProxy composer; + private DvCodedText category; + private CodePhrase territory; + private CodePhrase language; +} + +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the 'License'); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Composition.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * ***** END LICENSE BLOCK ***** */ \ No newline at end of file diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/EventContext.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/EventContext.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/ContentItem.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/ContentItem.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Action.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Action.java old mode 100755 new mode 100644 index dd881646..1c703c3a --- a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Action.java +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Action.java @@ -32,7 +32,6 @@ import org.openehr.rm.support.identification.UIDBasedID; import org.openehr.rm.support.identification.ObjectRef; import org.openehr.rm.support.terminology.TerminologyService; - import org.openehr.rm.common.archetyped.Locatable; /** @@ -187,6 +186,75 @@ void setTime(DvDateTime time) { } //POJO end + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + + ((description == null) ? 0 : description.hashCode()); + result = prime + * result + + ((instructionDetails == null) ? 0 : instructionDetails + .hashCode()); + result = prime * result + + ((ismTransition == null) ? 0 : ismTransition.hashCode()); + result = prime * result + ((time == null) ? 0 : time.hashCode()); + return result; + } + + @Override + // Generated by Eclipse + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Action other = (Action) obj; + if (description == null) { + if (other.description != null) { + return false; + } + } else if (!description.equals(other.description)) { + return false; + } + if (instructionDetails == null) { + if (other.instructionDetails != null) { + return false; + } + } else if (!instructionDetails.equals(other.instructionDetails)) { + return false; + } + if (ismTransition == null) { + if (other.ismTransition != null) { + return false; + } + } else if (!ismTransition.equals(other.ismTransition)) { + return false; + } + if (time == null) { + if (other.time != null) { + return false; + } + } else if (!time.equals(other.time)) { + return false; + } + if (getProtocol() == null) { + if (other.getProtocol() != null) { + return false; + } + } else if (other.getProtocol() == null) { + return false; + } else if (!getProtocol().equals(other.getProtocol())) { + return false; + } + return true; + } + /* fields */ private DvDateTime time; private ItemStructure description; diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Activity.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Activity.java old mode 100755 new mode 100644 index 68225226..ef85c004 --- a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Activity.java +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Activity.java @@ -1,191 +1,243 @@ -/* - * component: "openEHR Reference Implementation" - * description: "Class Activity" - * keywords: "composition" - * - * author: "Yin Su Lim " - * support: "CHIME, UCL" - * copyright: "Copyright (c) 2006 UCL, UK" - * license: "See notice at bottom of class" - * - * file: "$URL: http://svn.openehr.org/ref_impl_java/TRUNK/libraries/src/java/org/openehr/rm/composition/content/entry/Activity.java $" - * revision: "$LastChangedRevision: 53 $" - * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" - */ -package org.openehr.rm.composition.content.entry; - -import java.util.List; -import java.util.Set; - -import org.apache.commons.lang.StringUtils; -import org.openehr.rm.Attribute; -import org.openehr.rm.FullConstructor; -import org.openehr.rm.common.archetyped.*; -import org.openehr.rm.datatypes.text.DvText; -import org.openehr.rm.datatypes.encapsulated.DvParsable; -import org.openehr.rm.datastructure.itemstructure.ItemStructure; -import org.openehr.rm.support.identification.UIDBasedID; - -/** - * Defines a single activity within an Instruction, such as a medication administration. - * - * @author Yin Su Lim - * @version 1.0 - */ -public class Activity extends Locatable { - - /** - * Creates an Activity - * - * @param uit - * @param archetypeNodeId - * @param name - * @param archetypeDetails - * @param feederAudit - * @param links - * @param parent - * @param description required - * @param timing - * @param actionArchetypeId - * - * @throws IllegalArgumentExeption if required parameters missing - */ - @FullConstructor - public Activity( - @Attribute(name = "uid") UIDBasedID uid, - @Attribute(name = "archetypeNodeId", required = true) String archetypeNodeId, - @Attribute(name = "name", required = true) DvText name, - @Attribute(name = "archetypeDetails") Archetyped archetypeDetails, - @Attribute(name = "feederAudit") FeederAudit feederAudit, - @Attribute(name = "links") Set links, - @Attribute(name = "parent") Pathable parent, - @Attribute(name = "description", required = true) ItemStructure description, - @Attribute(name = "timing", required = true) DvParsable timing, - @Attribute(name = "actionArchetypeId", required = true) String actionArchetypeId) { - - super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, - parent); - if (description == null) { - throw new IllegalArgumentException("null description"); - } - if (timing == null) { - throw new IllegalArgumentException("null timing"); - } - if(StringUtils.isEmpty(actionArchetypeId)) { - throw new IllegalArgumentException("empty actionArchetypeId"); - } - - this.description = description; - this.timing = timing; - this.actionArchetypeId = actionArchetypeId; - } - - public Activity(String archetypeNodeId, DvText name, - ItemStructure description, DvParsable timing, - String actionArchetypeId) { - this(null, archetypeNodeId, name, null, null, null, null, description, - timing, actionArchetypeId); - } - - /** - * Description of the activity, in the form of an archetyped structure. - * - * @return description - */ - public ItemStructure getDescription() { - return description; - } - - /** - * Timing of the activity, in the form of a parsable string, such as - * GTS or iCal string - * - * @return timing - */ - public DvParsable getTiming() { - return timing; - } - - public String getActionArchetypeId() { - return actionArchetypeId; - } - - @Override - public String pathOfItem(Pathable item) { - // TODO Auto-generated method stub - return null; - } - - @Override - public List itemsAtPath(String arg0) { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean pathExists(String arg0) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean pathUnique(String arg0) { - // TODO Auto-generated method stub - return false; - } - - //POJO start - Activity() { - }; - - void setDescription(ItemStructure description) { - this.description = description; - } - - void setTiming(DvParsable timing) { - this.timing = timing; - } - public void setActionArchetypeId(String actionArchetypeId){ - this.actionArchetypeId = actionArchetypeId; - } - - //POJO end - - /* fields */ - private ItemStructure description; - private DvParsable timing; - private String actionArchetypeId; - - /* static fields */ - public static final String DESCRIPTION = "description"; -} - -/* - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the 'License'); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an 'AS IS' basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Activity.java - * - * The Initial Developer of the Original Code is Yin Su Lim. - * Portions created by the Initial Developer are Copyright (C) 2003-2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): Rong Chen - * - * Software distributed under the License is distributed on an 'AS IS' basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * ***** END LICENSE BLOCK ***** +/* + * component: "openEHR Reference Implementation" + * description: "Class Activity" + * keywords: "composition" + * + * author: "Yin Su Lim " + * support: "CHIME, UCL" + * copyright: "Copyright (c) 2006 UCL, UK" + * license: "See notice at bottom of class" + * + * file: "$URL: http://svn.openehr.org/ref_impl_java/TRUNK/libraries/src/java/org/openehr/rm/composition/content/entry/Activity.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.composition.content.entry; + +import java.util.List; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.common.archetyped.Archetyped; +import org.openehr.rm.common.archetyped.FeederAudit; +import org.openehr.rm.common.archetyped.Link; +import org.openehr.rm.common.archetyped.Locatable; +import org.openehr.rm.common.archetyped.Pathable; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datatypes.encapsulated.DvParsable; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.identification.UIDBasedID; + +/** + * Defines a single activity within an Instruction, such as a medication administration. + * + * @author Yin Su Lim + * @version 1.0 + */ +public class Activity extends Locatable { + + /** + * Creates an Activity + * + * @param uit + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @param parent + * @param description required + * @param timing + * @param actionArchetypeId + * + * @throws IllegalArgumentExeption if required parameters missing + */ + @FullConstructor + public Activity( + @Attribute(name = "uid") UIDBasedID uid, + @Attribute(name = "archetypeNodeId", required = true) String archetypeNodeId, + @Attribute(name = "name", required = true) DvText name, + @Attribute(name = "archetypeDetails") Archetyped archetypeDetails, + @Attribute(name = "feederAudit") FeederAudit feederAudit, + @Attribute(name = "links") Set links, + @Attribute(name = "parent") Pathable parent, + @Attribute(name = "description", required = true) ItemStructure description, + @Attribute(name = "timing") DvParsable timing, /* SPECRM-71 Optional from RM 1.0.4 on */ + @Attribute(name = "actionArchetypeId", required = true) String actionArchetypeId) { + + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, + parent); + if (description == null) { + throw new IllegalArgumentException("null description"); + } + if(StringUtils.isEmpty(actionArchetypeId)) { + throw new IllegalArgumentException("empty actionArchetypeId"); + } + + this.description = description; + this.timing = timing; + this.actionArchetypeId = actionArchetypeId; + } + + public Activity(String archetypeNodeId, DvText name, + ItemStructure description, DvParsable timing, + String actionArchetypeId) { + this(null, archetypeNodeId, name, null, null, null, null, description, + timing, actionArchetypeId); + } + + /** + * Description of the activity, in the form of an archetyped structure. + * + * @return description + */ + public ItemStructure getDescription() { + return description; + } + + /** + * Timing of the activity, in the form of a parsable string, such as + * GTS or iCal string + * + * @return timing + */ + public DvParsable getTiming() { + return timing; + } + + public String getActionArchetypeId() { + return actionArchetypeId; + } + + @Override + public String pathOfItem(Pathable item) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List itemsAtPath(String arg0) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean pathExists(String arg0) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean pathUnique(String arg0) { + // TODO Auto-generated method stub + return false; + } + + //POJO start + Activity() { + }; + + void setDescription(ItemStructure description) { + this.description = description; + } + + void setTiming(DvParsable timing) { + this.timing = timing; + } + public void setActionArchetypeId(String actionArchetypeId){ + this.actionArchetypeId = actionArchetypeId; + } + + // POJO end + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime + * result + + ((actionArchetypeId == null) ? 0 : actionArchetypeId + .hashCode()); + result = prime * result + + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((timing == null) ? 0 : timing.hashCode()); + return result; + } + + @Override + // Generated by Eclipse + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Activity other = (Activity) obj; + if (actionArchetypeId == null) { + if (other.actionArchetypeId != null) { + return false; + } + } else if (!actionArchetypeId.equals(other.actionArchetypeId)) { + return false; + } + if (description == null) { + if (other.description != null) { + return false; + } + } else if (!description.equals(other.description)) { + return false; + } + if (timing == null) { + if (other.timing != null) { + return false; + } + } else if (!timing.equals(other.timing)) { + return false; + } + return true; + } + + /* fields */ + private ItemStructure description; + private DvParsable timing; + private String actionArchetypeId; + + /* static fields */ + public static final String DESCRIPTION = "description"; +} + +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the 'License'); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Activity.java + * + * The Initial Developer of the Original Code is Yin Su Lim. + * Portions created by the Initial Developer are Copyright (C) 2003-2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Rong Chen + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * ***** END LICENSE BLOCK ***** */ \ No newline at end of file diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/AdminEntry.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/AdminEntry.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/CareEntry.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/CareEntry.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Entry.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Entry.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Evaluation.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Evaluation.java index 768cfdf2..6d8711b3 100755 --- a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Evaluation.java +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Evaluation.java @@ -138,6 +138,54 @@ void setData(ItemStructure data) { } // POJO end + + @Override + public boolean equals(Object obj) { + if(obj == null) { + return false; + } + if (this == obj) { + return true; + } + if (getClass() != obj.getClass()) { + return false; + } + if (!super.equals(obj)) { + return false; + } + Evaluation other = (Evaluation) obj; + if (data == null) { + if (other.data != null) { + return false; + } + } else if (other.data == null) { + return false; + } else if (!data.equals(other.data)) { + return false; + } + if (getProtocol() == null) { + if (other.getProtocol() != null) { + return false; + } + } else if (other.getProtocol() == null) { + return false; + } else if (!getProtocol().equals(other.getProtocol())) { + return false; + } + return true; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((data == null) ? 0 : data.hashCode()); + result = prime * result + + ((getProtocol() == null) ? 0 : getProtocol().hashCode()); + return result; + } + + /* fields */ private ItemStructure data; diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/ISMTransition.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/ISMTransition.java old mode 100755 new mode 100644 index 5b112c2b..67edd55a --- a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/ISMTransition.java +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/ISMTransition.java @@ -1,153 +1,222 @@ -/* - * component: "openEHR Reference Implementation" - * description: "Class ISMTransition" - * keywords: "composition" - * - * author: "Yin Su Lim " - * support: "CHIME, UCL" - * copyright: "Copyright (c) 2006 UCL, UK" - * license: "See notice at bottom of class" - * - * file: "$URL: http://svn.openehr.org/ref_impl_java/TRUNK/libraries/src/java/org/openehr/rm/composition/content/entry/ISMTransition.java $" - * revision: "$LastChangedRevision: 53 $" - * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" - */ -package org.openehr.rm.composition.content.entry; - -import org.openehr.rm.Attribute; -import org.openehr.rm.FullConstructor; -import org.openehr.rm.RMObject; -import org.openehr.rm.datatypes.text.DvCodedText; -import org.openehr.rm.support.terminology.*; - -/** - * Model of a transition in the Instruction State machine, caused by a careflow step. - * The attributes document the careflow step as well as the ISM transition. - * - * @author Yin Su Lim - * @version 1.0 - */ -public final class ISMTransition extends RMObject { - - /** - * @param uid - * @param archetypeNodeId - * @param name - * @param archetypeDetails - * @param feederAudit - * @param links - * @param parent - */ - @FullConstructor - public ISMTransition( - @Attribute(name = "currentState", required = true) DvCodedText currentState, - @Attribute(name = "transition") DvCodedText transition, - @Attribute(name = "careflowStep") DvCodedText careflowStep, - @Attribute(name = "terminologyService", system = true) TerminologyService terminologyService) { - if (currentState == null) { - throw new IllegalArgumentException("null currentState"); - } - if (terminologyService == null) { - throw new IllegalArgumentException("null terminologyService"); - } - if (!terminologyService.terminology(TerminologyService.OPENEHR) - .codesForGroupName(OpenEHRTerminologyGroupIdentifiers - .INSTRUCTION_STATES.getValue(), "en") - .contains(currentState.getDefiningCode())) { - throw new IllegalArgumentException("unknown currentState:" + currentState); - } - if (transition != null && !terminologyService.terminology(TerminologyService.OPENEHR) - .codesForGroupName(OpenEHRTerminologyGroupIdentifiers - .INSTRUCTION_TRANSITIONS.getValue(), "en") - .contains(transition.getDefiningCode())) { - throw new IllegalArgumentException("unknown transition:" + transition); - } - this.currentState = currentState; - this.transition = transition; - this.careflowStep = careflowStep; - } - - /** - * The step in the careflow process which occurred as part of generating - * this action, e.g. "dispense", "start_administration". This attribute - * represents the clinical label for the activity, as opposed to - * currentState which represents the state machine computable form. - * - * @return careflowStep - */ - public DvCodedText getCareflowStep() { - return careflowStep; - } - - /** - * The ISM current state. Coded by openEHR terminology group "ISM states" - * - * @return currentState - */ - public DvCodedText getCurrentState() { - return currentState; - } - - /** - * The ISM transition which occurred to arrive in the currentState. Coded by - * openEHR terminology group "ISM transitions" - * - * @return transition - */ - public DvCodedText getTransition() { - return transition; - } - - //POJO start - ISMTransition() { - } - - void setCareflowStep(DvCodedText careflowStep) { - this.careflowStep = careflowStep; - } - - void setCurrentState(DvCodedText currentState) { - this.currentState = currentState; - } - - void setTransition(DvCodedText transition) { - this.transition = transition; - } - //POJO end - - /* fields */ - private DvCodedText currentState; - private DvCodedText transition; - private DvCodedText careflowStep; - -} - -/* - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the 'License'); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an 'AS IS' basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is ISMTransition.java - * - * The Initial Developer of the Original Code is Yin Su Lim. - * Portions created by the Initial Developer are Copyright (C) 2003-2004 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Software distributed under the License is distributed on an 'AS IS' basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * ***** END LICENSE BLOCK ***** +/* + * component: "openEHR Reference Implementation" + * description: "Class ISMTransition" + * keywords: "composition" + * + * author: "Yin Su Lim " + * support: "CHIME, UCL" + * copyright: "Copyright (c) 2006 UCL, UK" + * license: "See notice at bottom of class" + * + * file: "$URL: http://svn.openehr.org/ref_impl_java/TRUNK/libraries/src/java/org/openehr/rm/composition/content/entry/ISMTransition.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.composition.content.entry; + +import java.util.List; + +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.RMObject; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.terminology.OpenEHRTerminologyGroupIdentifiers; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * Model of a transition in the Instruction State machine, caused by a careflow step. + * The attributes document the careflow step as well as the ISM transition. + * + * @author Yin Su Lim + * @version 1.0 + */ +public final class ISMTransition extends RMObject { + + /** + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @param parent + */ + @FullConstructor + public ISMTransition( + @Attribute(name = "currentState", required = true) DvCodedText currentState, + @Attribute(name = "transition") DvCodedText transition, + @Attribute(name = "careflowStep") DvCodedText careflowStep, + @Attribute(name = "reason") List reason, // SPECRM-37, RM 1.0.3 + @Attribute(name = "terminologyService", system = true) TerminologyService terminologyService) { + if (currentState == null) { + throw new IllegalArgumentException("null currentState"); + } + if (terminologyService == null) { + throw new IllegalArgumentException("null terminologyService"); + } + if (!terminologyService.terminology(TerminologyService.OPENEHR) + .codesForGroupName(OpenEHRTerminologyGroupIdentifiers + .INSTRUCTION_STATES.getValue(), "en") + .contains(currentState.getDefiningCode())) { + throw new IllegalArgumentException("unknown currentState:" + currentState); + } + if (transition != null && !terminologyService.terminology(TerminologyService.OPENEHR) + .codesForGroupName(OpenEHRTerminologyGroupIdentifiers + .INSTRUCTION_TRANSITIONS.getValue(), "en") + .contains(transition.getDefiningCode())) { + throw new IllegalArgumentException("unknown transition:" + transition); + } + this.currentState = currentState; + this.transition = transition; + this.careflowStep = careflowStep; + this.reason = reason; + } + + /** + * The step in the careflow process which occurred as part of generating + * this action, e.g. "dispense", "start_administration". This attribute + * represents the clinical label for the activity, as opposed to + * currentState which represents the state machine computable form. + * + * @return careflowStep + */ + public DvCodedText getCareflowStep() { + return careflowStep; + } + + /** + * The ISM current state. Coded by openEHR terminology group "ISM states" + * + * @return currentState + */ + public DvCodedText getCurrentState() { + return currentState; + } + + /** + * The ISM transition which occurred to arrive in the currentState. Coded by + * openEHR terminology group "ISM transitions" + * + * @return transition + */ + public DvCodedText getTransition() { + return transition; + } + + //POJO start + ISMTransition() { + } + + void setCareflowStep(DvCodedText careflowStep) { + this.careflowStep = careflowStep; + } + + void setCurrentState(DvCodedText currentState) { + this.currentState = currentState; + } + + void setTransition(DvCodedText transition) { + this.transition = transition; + } + + List getReason() { + return reason; + } + + void setReason(List reason) { + this.reason = reason; + } + //POJO end + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((careflowStep == null) ? 0 : careflowStep.hashCode()); + result = prime * result + + ((currentState == null) ? 0 : currentState.hashCode()); + result = prime * result + + ((transition == null) ? 0 : transition.hashCode()); + result = prime * result + + ((reason == null) ? 0 : reason.hashCode()); + return result; + } + + @Override + // Generated by Eclipse + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ISMTransition other = (ISMTransition) obj; + if (careflowStep == null) { + if (other.careflowStep != null) { + return false; + } + } else if (!careflowStep.equals(other.careflowStep)) { + return false; + } + if (currentState == null) { + if (other.currentState != null) { + return false; + } + } else if (!currentState.equals(other.currentState)) { + return false; + } + if (transition == null) { + if (other.transition != null) { + return false; + } + } else if (!transition.equals(other.transition)) { + return false; + } else if (!reason.equals(other.reason)) { + return false; + } + return true; + } + + /* fields */ + private DvCodedText currentState; + private DvCodedText transition; + private DvCodedText careflowStep; + private List reason; + +} + +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the 'License'); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is ISMTransition.java + * + * The Initial Developer of the Original Code is Yin Su Lim. + * Portions created by the Initial Developer are Copyright (C) 2003-2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * ***** END LICENSE BLOCK ***** */ \ No newline at end of file diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Instruction.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Instruction.java old mode 100755 new mode 100644 index 1fa0c606..f905c427 --- a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Instruction.java +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Instruction.java @@ -220,8 +220,76 @@ void setNarrative(DvText narrative) { void setWfDefinition(DvParsable wfDefinition) { this.wfDefinition = wfDefinition; - } + } + // POJO end + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + + ((activities == null) ? 0 : activities.hashCode()); + result = prime * result + + ((expiryTime == null) ? 0 : expiryTime.hashCode()); + result = prime * result + + ((narrative == null) ? 0 : narrative.hashCode()); + result = prime * result + + ((wfDefinition == null) ? 0 : wfDefinition.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Instruction other = (Instruction) obj; + if (activities == null) { + if (other.activities != null) { + return false; + } + } else if (!activities.equals(other.activities)) { + return false; + } + if (expiryTime == null) { + if (other.expiryTime != null) { + return false; + } + } else if (!expiryTime.equals(other.expiryTime)) { + return false; + } + if (narrative == null) { + if (other.narrative != null) { + return false; + } + } else if (!narrative.equals(other.narrative)) { + return false; + } + if (wfDefinition == null) { + if (other.wfDefinition != null) { + return false; + } + } else if (!wfDefinition.equals(other.wfDefinition)) { + return false; + } + if (getProtocol() == null) { + if (other.getProtocol() != null) { + return false; + } + } else if (other.getProtocol() == null) { + return false; + } else if (!getProtocol().equals(other.getProtocol())) { + return false; + } + return true; + } /* fields */ private DvText narrative; diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/InstructionDetails.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/InstructionDetails.java old mode 100755 new mode 100644 index 91c4b3d6..6b4264f0 --- a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/InstructionDetails.java +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/InstructionDetails.java @@ -101,6 +101,56 @@ void setWfDetails(ItemStructure wfDetails) { this.wfDetails = wfDetails; } //POJO end + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((activityId == null) ? 0 : activityId.hashCode()); + result = prime * result + + ((instructionId == null) ? 0 : instructionId.hashCode()); + result = prime * result + + ((wfDetails == null) ? 0 : wfDetails.hashCode()); + return result; + } + + @Override + // Generated by Eclipse + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + InstructionDetails other = (InstructionDetails) obj; + if (activityId == null) { + if (other.activityId != null) { + return false; + } + } else if (!activityId.equals(other.activityId)) { + return false; + } + if (instructionId == null) { + if (other.instructionId != null) { + return false; + } + } else if (!instructionId.equals(other.instructionId)) { + return false; + } + if (wfDetails == null) { + if (other.wfDetails != null) { + return false; + } + } else if (!wfDetails.equals(other.wfDetails)) { + return false; + } + return true; + } /* fields */ private LocatableRef instructionId; diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Observation.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Observation.java index e16c815d..59e8190c 100755 --- a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Observation.java +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Observation.java @@ -186,6 +186,63 @@ void setState(History state) { private History data; private History state; + @Override + public boolean equals(Object obj) { + if(obj == null) { + return false; + } + if (this == obj) { + return true; + } + if (getClass() != obj.getClass()) { + return false; + } + if (!super.equals(obj)) { + return false; + } + + Observation other = (Observation) obj; + if (data == null) { + if (other.data != null) { + return false; + } + } else if (other.data == null) { + return false; + } else if (!data.equals(other.data)) { + return false; + } + if (state == null) { + if (other.state != null) { + return false; + } + } else if (other.state == null) { + return false; + } else if (!state.equals(other.state)) { + return false; + } + if (getProtocol() == null) { + if (other.getProtocol() != null) { + return false; + } + } else if (other.getProtocol() == null) { + return false; + } else if (!getProtocol().equals(other.getProtocol())) { + return false; + } + return true; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((data == null) ? 0 : data.hashCode()); + result = prime * result + ((state == null) ? 0 : state.hashCode()); + result = prime * result + + ((getProtocol() == null) ? 0 : getProtocol().hashCode()); + return result; + } + /* static fields */ public static final String DATA = "data"; public static final String STATE = "state"; diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/navigation/Section.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/navigation/Section.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Actor.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Actor.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Address.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Address.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Agent.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Agent.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Capability.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Capability.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Contact.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Contact.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Group.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Group.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Organisation.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Organisation.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Party.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Party.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/PartyIdentity.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/PartyIdentity.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/PartyRelationship.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/PartyRelationship.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Person.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Person.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Role.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Role.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/VersionedParty.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/VersionedParty.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/EHR.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/EHR.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/EHRAccess.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/EHRAccess.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/EHRStatus.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/EHRStatus.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/VersionedComposition.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/VersionedComposition.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/VersionedEHRAccess.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/VersionedEHRAccess.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/VersionedEHRStatus.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/VersionedEHRStatus.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/EHRExtract.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/EHRExtract.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XAccessControl.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XAccessControl.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XComposition.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XComposition.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XDemographics.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XDemographics.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XFolder.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XFolder.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XTerminology.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XTerminology.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/integration/GenericEntry.java b/openehr-rm-domain/src/main/java/org/openehr/rm/integration/GenericEntry.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/message/Message.java b/openehr-rm-domain/src/main/java/org/openehr/rm/message/Message.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/main/java/org/openehr/rm/message/MessageContent.java b/openehr-rm-domain/src/main/java/org/openehr/rm/message/MessageContent.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/composition/CompositionTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/CompositionTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/composition/CompositionTestBase.java b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/CompositionTestBase.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/composition/EventContextTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/EventContextTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ActionTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ActionTest.java index d1d8016f..fb5b123a 100755 --- a/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ActionTest.java +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ActionTest.java @@ -1,131 +1,196 @@ -/* - * component: "openEHR Reference Implementation" - * description: "Class ActionTest" - * keywords: "unit test" - * - * author: "Yin Su Lim " - * support: "CHIME, UCL" - * copyright: "Copyright (c) 2006 UCL, UK" - * license: "See notice at bottom of class" - * - * file: "$URL: http://svn.openehr.org/ref_impl_java/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/composition/content/entry/ActionTest.java $" - * revision: "$LastChangedRevision: 50 $" - * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" - */ - -/** - * ActionTest - * - * @author Yin Su Lim - * @version 1.0 - */ -package org.openehr.rm.composition.content.entry; - -import junit.framework.*; -import org.openehr.rm.common.archetyped.Archetyped; -import org.openehr.rm.composition.CompositionTestBase; -import org.openehr.rm.composition.content.entry.ISMTransition; -import org.openehr.rm.datastructure.itemstructure.ItemStructure; -import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; -import org.openehr.rm.datatypes.text.DvText; -import org.openehr.rm.support.identification.ArchetypeID; -import org.openehr.rm.support.terminology.TestCodeSetAccess; - -public class ActionTest extends CompositionTestBase { - - public ActionTest(String testName) { - super(testName); - } - - protected void setUp() throws Exception { - ItemStructure description = list("list description"); - ItemStructure protocol = list("list protocol"); - Archetyped arch = new Archetyped( - new ArchetypeID("openehr-ehr_rm-action.XYZ.v2"), - "1.1"); - ISMTransition ismT = new ISMTransition(TestCodeSetAccess.ISM_ACTIVE, - null, null, ts); - action = new Action(null, "at0001", new DvText("action"), - arch, null, null, null, lang, encoding, subject(), provider(), - null, null, protocol, null, new DvDateTime(), description, - ismT, null, ts); - } - - protected void tearDown() throws Exception { - } - - public static Test suite() { - TestSuite suite = new TestSuite(ActionTest.class); - - return suite; - } - - public void testItemAtPathWhole() { - path = "/"; - value = action.itemAtPath(path); - assertEquals(action, value); - } - - public void testItemAtPathSubject() { - path = "/subject"; - value = action.itemAtPath(path); - assertEquals(action.getSubject(), value); - } - - public void testItemAtPathProvider() { - path = "/provider"; - value = action.itemAtPath(path); - assertEquals(action.getProvider(), value); - } - - public void testItemAtPathProtocol() { - path = "/protocol"; - value = action.itemAtPath(path); - assertEquals(action.getProtocol(), value); - } - - public void testItemAtPathDescription() { - path = "/description"; - value = action.itemAtPath(path); - assertEquals(action.getDescription(), value); - } - - public void testItemAtPathTime() { - path = "/time"; - value = action.itemAtPath(path); - assertEquals(action.getTime(), value); - } - - /* fields */ - private static Action action; -} - -/* - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the 'License'); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an 'AS IS' basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is ActionTest.java - * - * The Initial Developer of the Original Code is Rong Chen. - * Portions created by the Initial Developer are Copyright (C) 2003-2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Software distributed under the License is distributed on an 'AS IS' basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * ***** END LICENSE BLOCK ***** +/* + * component: "openEHR Reference Implementation" + * description: "Class ActionTest" + * keywords: "unit test" + * + * author: "Yin Su Lim " + * support: "CHIME, UCL" + * copyright: "Copyright (c) 2006 UCL, UK" + * license: "See notice at bottom of class" + * + * file: "$URL: http://svn.openehr.org/ref_impl_java/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/composition/content/entry/ActionTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" + */ + +/** + * ActionTest + * + * @author Yin Su Lim + * @version 1.0 + */ +package org.openehr.rm.composition.content.entry; + +import org.openehr.rm.common.archetyped.Archetyped; +import org.openehr.rm.composition.CompositionTestBase; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.identification.ArchetypeID; +import org.openehr.rm.support.terminology.TestCodeSetAccess; + +import junit.framework.Test; +import junit.framework.TestSuite; + +public class ActionTest extends CompositionTestBase { + + public ActionTest(String testName) { + super(testName); + } + + @Override + protected void setUp() throws Exception { + ItemStructure description = list("list description"); + ItemStructure protocol = list("list protocol"); + Archetyped arch = new Archetyped( + new ArchetypeID("openehr-ehr_rm-action.XYZ.v2"), + "1.1"); + ISMTransition ismT = new ISMTransition(TestCodeSetAccess.ISM_ACTIVE, + null, null, null, ts); + action = new Action(null, "at0001", new DvText("action"), + arch, null, null, null, lang, encoding, subject(), provider(), + null, null, protocol, null, new DvDateTime(), description, + ismT, null, ts); + } + + @Override + protected void tearDown() throws Exception { + } + + public static Test suite() { + TestSuite suite = new TestSuite(ActionTest.class); + + return suite; + } + + public void testItemAtPathWhole() { + path = "/"; + value = action.itemAtPath(path); + assertEquals(action, value); + } + + public void testItemAtPathSubject() { + path = "/subject"; + value = action.itemAtPath(path); + assertEquals(action.getSubject(), value); + } + + public void testItemAtPathProvider() { + path = "/provider"; + value = action.itemAtPath(path); + assertEquals(action.getProvider(), value); + } + + public void testItemAtPathProtocol() { + path = "/protocol"; + value = action.itemAtPath(path); + assertEquals(action.getProtocol(), value); + } + + public void testItemAtPathDescription() { + path = "/description"; + value = action.itemAtPath(path); + assertEquals(action.getDescription(), value); + } + + public void testItemAtPathTime() { + path = "/time"; + value = action.itemAtPath(path); + assertEquals(action.getTime(), value); + } + + public void testEquals() throws Exception { + ItemStructure description = list("list description"); + ItemStructure protocol = list("list protocol"); + Archetyped arch = new Archetyped(new ArchetypeID( + "openehr-ehr_rm-action.XYZ.v2"), "1.1"); + ISMTransition ismT = new ISMTransition(TestCodeSetAccess.ISM_ACTIVE, + null, null, null, ts); + DvDateTime time = new DvDateTime(); + Action action = new Action(null, "at0001", new DvText("action"), arch, + null, null, null, lang, encoding, subject(), provider(), null, + null, protocol, null, time, description, ismT, + null, ts); + + Action action2 = new Action(null, "at0001", new DvText("action"), arch, + null, null, null, lang, encoding, subject(), provider(), null, + null, protocol, null, time, description, ismT, + null, ts); + assertTrue(action.equals(action2)); + } + + public void testNotEquals() throws Exception { + ItemStructure description = list("list description"); + ItemStructure protocol = list("list protocol"); + Archetyped arch = new Archetyped(new ArchetypeID( + "openehr-ehr_rm-action.XYZ.v2"), "1.1"); + ISMTransition ismT = new ISMTransition(TestCodeSetAccess.ISM_ACTIVE, + null, null, null, ts); + Action action = new Action(null, "at0001", new DvText("action"), arch, + null, null, null, lang, encoding, subject(), provider(), null, + null, protocol, null, new DvDateTime(), description, ismT, + null, ts); + + ItemStructure description2 = list("list description 2"); + Action action2 = new Action(null, "at0001", new DvText("action"), arch, + null, null, null, lang, encoding, subject(), provider(), null, + null, protocol, null, new DvDateTime(), description2, ismT, + null, ts); + + assertFalse(action.equals(action2)); + } + + public void testNotEqualsProtocol() throws Exception { + ItemStructure description = list("list description"); + ItemStructure protocol = list("list protocol"); + Archetyped arch = new Archetyped(new ArchetypeID( + "openehr-ehr_rm-action.XYZ.v2"), "1.1"); + ISMTransition ismT = new ISMTransition(TestCodeSetAccess.ISM_ACTIVE, + null, null, null, ts); + Action action = new Action(null, "at0001", new DvText("action"), arch, + null, null, null, lang, encoding, subject(), provider(), null, + null, protocol, null, new DvDateTime(), description, ismT, + null, ts); + + ItemStructure protocol2 = list("list protocol 2"); + Action action2 = new Action(null, "at0001", new DvText("action"), arch, + null, null, null, lang, encoding, subject(), provider(), null, + null, protocol2, null, new DvDateTime(), description, ismT, + null, ts); + + assertFalse(action.equals(action2)); + } + + /* fields */ + private static Action action; +} + +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the 'License'); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is ActionTest.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Software distributed under the License is distributed on an 'AS IS' basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * ***** END LICENSE BLOCK ***** */ \ No newline at end of file diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ActivityTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ActivityTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/AdminEntryTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/AdminEntryTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/EvaluationTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/EvaluationTest.java old mode 100755 new mode 100644 index ee62520b..4734470c --- a/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/EvaluationTest.java +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/EvaluationTest.java @@ -20,9 +20,14 @@ */ package org.openehr.rm.composition.content.entry; +import java.util.ArrayList; +import java.util.List; + import org.openehr.rm.common.archetyped.Archetyped; import org.openehr.rm.composition.CompositionTestBase; +import org.openehr.rm.datastructure.itemstructure.ItemList; import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datastructure.itemstructure.representation.Element; import org.openehr.rm.support.identification.ArchetypeID; public class EvaluationTest extends CompositionTestBase { @@ -57,7 +62,105 @@ public void testItemAtPath() { value = evaluation.itemAtPath(path); assertEquals(evaluation, value); } + + public void testEquals() throws Exception { + ItemStructure protocolOne = list("list protocol"); + ItemStructure dataOne = list("list data"); + Archetyped archOne = new Archetyped(new ArchetypeID( + "openehr-ehr_rm-evaluation.physical_examination.v3"), "1.1"); + Evaluation evaluationOne = new Evaluation(null, "at000", + text("evaluation"), archOne, null, null, null, language("en"), + language("en"), subject(), provider(), null, null, protocolOne, + null, dataOne, ts); + + Evaluation evaluationTwo = new Evaluation(null, "at000", + text("evaluation"), archOne, null, null, null, language("en"), + language("en"), subject(), provider(), null, null, protocolOne, + null, dataOne, ts); + + assertTrue(evaluationOne.equals(evaluationTwo)); + } + + public void testNotEqualsProtocol() throws Exception { + ItemStructure protocolOne = list("list protocol"); + ItemStructure dataOne = list("list data"); + Archetyped archOne = new Archetyped(new ArchetypeID( + "openehr-ehr_rm-evaluation.physical_examination.v3"), "1.1"); + Evaluation evaluationOne = new Evaluation(null, "at000", + text("evaluation"), archOne, null, null, null, language("en"), + language("en"), subject(), provider(), null, null, protocolOne, + null, dataOne, ts); + + ItemStructure protocolTwo = buildItem("list protocol"); + + Evaluation evaluationTwo = new Evaluation(null, "at000", + text("evaluation"), archOne, null, null, null, language("en"), + language("en"), subject(), provider(), null, null, protocolTwo, + null, dataOne, ts); + + assertFalse(evaluationOne.equals(evaluationTwo)); + } + + public void testNotEqualsData() throws Exception { + ItemStructure protocolOne = list("list protocol"); + ItemStructure dataOne = list("list data"); + Archetyped archOne = new Archetyped(new ArchetypeID( + "openehr-ehr_rm-evaluation.physical_examination.v3"), "1.1"); + Evaluation evaluationOne = new Evaluation(null, "at000", + text("evaluation"), archOne, null, null, null, language("en"), + language("en"), subject(), provider(), null, null, protocolOne, + null, dataOne, ts); + + ItemStructure dataTwo = buildItem("list protocol"); + + Evaluation evaluationTwo = new Evaluation(null, "at000", + text("evaluation"), archOne, null, null, null, language("en"), + language("en"), subject(), provider(), null, null, protocolOne, + null, dataTwo, ts); + + assertFalse(evaluationOne.equals(evaluationTwo)); + } + + public void testEqualsMixedData() throws Exception { + ItemStructure protocolOne = list("list protocol"); + ItemStructure dataOne = list("list data"); + Archetyped archOne = new Archetyped(new ArchetypeID( + "openehr-ehr_rm-evaluation.physical_examination.v3"), "1.1"); + Evaluation evaluationOne = new Evaluation(null, "at000", + text("evaluation"), archOne, null, null, null, language("en"), + language("en"), subject(), provider(), null, null, protocolOne, + null, dataOne, ts); + + ItemStructure dataTwo = buildMixedItem("list data"); + + Evaluation evaluationTwo = new Evaluation(null, "at000", + text("evaluation"), archOne, null, null, null, language("en"), + language("en"), subject(), provider(), null, null, protocolOne, + null, dataTwo, ts); + + assertTrue(evaluationOne.equals(evaluationTwo)); + } + + private ItemList buildItem(String name) { + String[] names = { "field 1" }; + String[] values = { "value 1" }; + List items = new ArrayList(); + for (int i = 0; i < names.length; i++) { + items.add(element(names[i], values[i])); + } + return new ItemList("at0100", text(name), items); + } + private ItemList buildMixedItem(String name) { + String[] names = { "field 2", "field 1", "field 3" }; + String[] values = { "value 2", "value 1", "value 3" }; + List items = new ArrayList(); + for (int i = 0; i < names.length; i++) { + items.add(element(names[i], values[i])); + } + return new ItemList("at0100", text(name), items); + } + /* field */ private Evaluation evaluation; diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ISMTransitionTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ISMTransitionTest.java old mode 100755 new mode 100644 index 62569b87..d4143e79 --- a/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ISMTransitionTest.java +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ISMTransitionTest.java @@ -1,49 +1,57 @@ package org.openehr.rm.composition.content.entry; -import junit.framework.TestCase; +import java.util.ArrayList; +import java.util.List; import org.openehr.rm.datatypes.text.CodePhrase; import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.datatypes.text.DvText; import org.openehr.rm.support.terminology.TerminologyService; import org.openehr.rm.support.terminology.TestTerminologyAccess; import org.openehr.rm.support.terminology.TestTerminologyService; import org.openehr.terminology.SimpleTerminologyService; +import junit.framework.TestCase; + public class ISMTransitionTest extends TestCase { - /** - * Verifies a bug fix in the constructor of ISMTransition - * - * @throws Exception - */ - public void testConstructor() throws Exception { - DvCodedText currentState = new DvCodedText("current state", - TestTerminologyAccess.SOME_STATE); - - DvCodedText transition = new DvCodedText("transition", - TestTerminologyAccess.SOME_TRANSITION); - + /** + * Verifies a bug fix in the constructor of ISMTransition + * + * @throws Exception + */ + public void testConstructor() throws Exception { + DvCodedText currentState = new DvCodedText("current state", + TestTerminologyAccess.SOME_STATE); + + DvCodedText transition = new DvCodedText("transition", + TestTerminologyAccess.SOME_TRANSITION); + CodePhrase definingCode = new CodePhrase("test", "124"); - DvCodedText careflowStep = new DvCodedText("care flow Step", - definingCode); - + DvCodedText careflowStep = new DvCodedText("care flow Step", + definingCode); + + List reason = new ArrayList(); + reason.add(new DvText("test reason 1")); + reason.add(new DvText("test reason 2")); TerminologyService ts = TestTerminologyService.getInstance(); - - ISMTransition ismt = new ISMTransition(currentState, transition, - careflowStep, ts); - + + ISMTransition ismt = new ISMTransition(currentState, transition, + careflowStep, reason, ts); + assertEquals("currentState wrong", currentState, ismt.getCurrentState()); assertEquals("transition wrong", transition, ismt.getTransition()); assertEquals("careflowStep wrong", careflowStep, ismt.getCareflowStep()); - } - - public void testWithOpenEHRTerminology() throws Exception { - TerminologyService ts = SimpleTerminologyService.getInstance(); - CodePhrase lang = new CodePhrase("ISO_639-1", "en"); - CodePhrase encoding = new CodePhrase("IANA_character-sets", "UTF-8"); - DvCodedText planned = new DvCodedText("planned", lang, encoding, - new CodePhrase("openehr", "526"), ts); - - new ISMTransition(planned, null, null, ts); - } + assertEquals("reason wrong", reason, ismt.getReason()); + } + + public void testWithOpenEHRTerminology() throws Exception { + TerminologyService ts = SimpleTerminologyService.getInstance(); + CodePhrase lang = new CodePhrase("ISO_639-1", "en"); + CodePhrase encoding = new CodePhrase("IANA_character-sets", "UTF-8"); + DvCodedText planned = new DvCodedText("planned", lang, encoding, + new CodePhrase("openehr", "526"), ts); + + new ISMTransition(planned, null, null, null, ts); + } } diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/InstructionTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/InstructionTest.java old mode 100755 new mode 100644 index d3e77c48..51b5773d --- a/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/InstructionTest.java +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/InstructionTest.java @@ -53,6 +53,148 @@ public void setUp() throws Exception { arch, null, null, null, language("en"), language("en"), subject(), provider(), null, null, protocol, null, text("narrative"), activities, null, null, ts); } + + public void testEquals() throws Exception { + ItemStructure protocol = list("list protocol"); + Archetyped arch = new Archetyped(new ArchetypeID( + "openehr-ehr_rm-instruction.physical_examination.v3"), "1.1"); + DvParsable timing = new DvParsable("timing value", "fomalism"); + Activity activity = new Activity("at0004", text("activity 1"), + list("list activity"), timing, + "openEHR-EHR-ITEM_TREE.intravenous_fluids.v1draft"); + List activities = new ArrayList(); + activities.add(activity); + Instruction instruction1 = new Instruction(null, "at0001", + text("instruction"), arch, null, null, null, language("en"), + language("en"), subject(), provider(), null, null, protocol, + null, text("narrative"), activities, null, null, ts); + + Instruction instruction2 = new Instruction(null, "at0001", + text("instruction"), arch, null, null, null, language("en"), + language("en"), subject(), provider(), null, null, protocol, + null, text("narrative"), activities, null, null, ts); + + assertTrue(instruction1.equals(instruction2)); + } + + public void testNotEqualActivity() throws Exception { + ItemStructure protocol = list("list protocol"); + Archetyped arch = new Archetyped(new ArchetypeID( + "openehr-ehr_rm-instruction.physical_examination.v3"), "1.1"); + + DvParsable timing = new DvParsable("timing value", "fomalism"); + Activity activity = new Activity("at0004", text("activity 1"), + list("list activity"), timing, + "openEHR-EHR-ITEM_TREE.intravenous_fluids.v1draft"); + List activities = new ArrayList(); + activities.add(activity); + + Activity activity2 = new Activity("at0004", text("activity 2"), + list("list activity"), timing, + "openEHR-EHR-ITEM_TREE.intravenous_fluids.v1draft"); + List activities2 = new ArrayList(); + activities2.add(activity2); + + Instruction instruction1 = new Instruction(null, "at0001", + text("instruction"), arch, null, null, null, language("en"), + language("en"), subject(), provider(), null, null, protocol, + null, text("narrative"), activities, null, null, ts); + + Instruction instruction2 = new Instruction(null, "at0001", + text("instruction"), arch, null, null, null, language("en"), + language("en"), subject(), provider(), null, null, protocol, + null, text("narrative"), activities2, null, null, ts); + + assertFalse(instruction1.equals(instruction2)); + } + + public void testNotEqualProtocol() throws Exception { + ItemStructure protocol = list("list protocol"); + Archetyped arch = new Archetyped(new ArchetypeID( + "openehr-ehr_rm-instruction.physical_examination.v3"), "1.1"); + DvParsable timing = new DvParsable("timing value", "fomalism"); + Activity activity = new Activity("at0004", text("activity 1"), + list("list activity"), timing, + "openEHR-EHR-ITEM_TREE.intravenous_fluids.v1draft"); + List activities = new ArrayList(); + activities.add(activity); + Instruction instruction1 = new Instruction(null, "at0001", + text("instruction"), arch, null, null, null, language("en"), + language("en"), subject(), provider(), null, null, protocol, + null, text("narrative"), activities, null, null, ts); + + ItemStructure protocol2 = list("list protocol2"); + Instruction instruction2 = new Instruction(null, "at0001", + text("instruction"), arch, null, null, null, language("en"), + language("en"), subject(), provider(), null, null, protocol2, + null, text("narrative"), activities, null, null, ts); + + assertFalse(instruction1.equals(instruction2)); + } + + public void testNotEqualTiming() throws Exception { + ItemStructure protocol = list("list protocol"); + Archetyped arch = new Archetyped(new ArchetypeID( + "openehr-ehr_rm-instruction.physical_examination.v3"), "1.1"); + + DvParsable timing = new DvParsable("timing value", "fomalism"); + Activity activity = new Activity("at0004", text("activity 1"), + list("list activity"), timing, + "openEHR-EHR-ITEM_TREE.intravenous_fluids.v1draft"); + List activities = new ArrayList(); + activities.add(activity); + + DvParsable timing2 = new DvParsable("timing valuess", "fomalism"); + Activity activity2 = new Activity("at0004", text("activity "), + list("list activity"), timing2, + "openEHR-EHR-ITEM_TREE.intravenous_fluids.v1draft"); + List activities2 = new ArrayList(); + activities2.add(activity2); + + Instruction instruction1 = new Instruction(null, "at0001", + text("instruction"), arch, null, null, null, language("en"), + language("en"), subject(), provider(), null, null, protocol, + null, text("narrative"), activities, null, null, ts); + + Instruction instruction2 = new Instruction(null, "at0001", + text("instruction"), arch, null, null, null, language("en"), + language("en"), subject(), provider(), null, null, protocol, + null, text("narrative"), activities2, null, null, ts); + + assertFalse(instruction1.equals(instruction2)); + } + + public void testNotEqualActivitySize() throws Exception { + ItemStructure protocol = list("list protocol"); + Archetyped arch = new Archetyped(new ArchetypeID( + "openehr-ehr_rm-instruction.physical_examination.v3"), "1.1"); + + DvParsable timing = new DvParsable("timing value", "fomalism"); + Activity activity = new Activity("at0004", text("activity 1"), + list("list activity"), timing, + "openEHR-EHR-ITEM_TREE.intravenous_fluids.v1draft"); + List activities = new ArrayList(); + activities.add(activity); + + Activity activity2 = new Activity("at0004", text("activity 1"), + list("list activity"), timing, + "openEHR-EHR-ITEM_TREE.intravenous_fluids.v1draft"); + List activities2 = new ArrayList(); + activities2.add(activity2); + activities2.add(activity); + + Instruction instruction1 = new Instruction(null, "at0001", + text("instruction"), arch, null, null, null, language("en"), + language("en"), subject(), provider(), null, null, protocol, + null, text("narrative"), activities, null, null, ts); + + Instruction instruction2 = new Instruction(null, "at0001", + text("instruction"), arch, null, null, null, language("en"), + language("en"), subject(), provider(), null, null, protocol, + null, text("narrative"), activities2, null, null, ts); + + assertFalse(instruction1.equals(instruction2)); + } public void testItemAtPath() { path = "/"; diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ObservationTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ObservationTest.java old mode 100755 new mode 100644 index e527d37f..940cbf68 --- a/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ObservationTest.java +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ObservationTest.java @@ -21,10 +21,12 @@ import org.openehr.rm.datastructure.history.History; import org.openehr.rm.datastructure.history.PointEvent; import org.openehr.rm.datastructure.itemstructure.ItemList; +import org.openehr.rm.datastructure.itemstructure.ItemSingle; import org.openehr.rm.datastructure.itemstructure.ItemStructure; import org.openehr.rm.datastructure.itemstructure.representation.Element; import org.openehr.rm.datatypes.quantity.datetime.DvDate; import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.quantity.datetime.DvDuration; import org.openehr.rm.datatypes.text.CodePhrase; import org.openehr.rm.datatypes.text.DvText; import org.openehr.rm.composition.CompositionTestBase; @@ -221,6 +223,148 @@ public void testItemAtPathProtocol() throws Exception { observation.getProtocol(), value); } + public void testEquals() throws Exception + { + ItemStructure protocol = list("list protocol"); + History data = event("data"); + History state = event("state"); + Archetyped arch = new Archetyped( + new ArchetypeID("openehr-ehr_rm-observation.physical_examination.v3"), + "1.1"); + TerminologyService termServ = SimpleTerminologyService.getInstance(); + + CodePhrase language = new CodePhrase("ISO_639-1", "en"); + CodePhrase encoding = new CodePhrase("IANA_character-sets", "UTF-8"); + + Observation observationOne = new Observation(null, "at000", text("observation"), + arch, null, null, null, language, encoding, subject(), + provider(), null, null, protocol, null, data, state, termServ); + + Observation observationTwo = new Observation(null, "at000", text("observation"), + arch, null, null, null, language, encoding, subject(), + provider(), null, null, protocol, null, data, state, termServ); + + assertTrue(observationOne.equals(observationTwo)); + } + + public void testNotEquals() throws Exception + { + ItemStructure protocol = list("list protocol"); + History data = event("data"); + History state = event("state"); + Archetyped arch = new Archetyped( + new ArchetypeID("openehr-ehr_rm-observation.physical_examination.v3"), + "1.1"); + TerminologyService termServ = SimpleTerminologyService.getInstance(); + + CodePhrase language = new CodePhrase("ISO_639-1", "en"); + CodePhrase encoding = new CodePhrase("IANA_character-sets", "UTF-8"); + + Observation observationOne = new Observation(null, "at001", text("observation"), + arch, null, null, null, language, encoding, subject(), + provider(), null, null, protocol, null, data, state, termServ); + + Observation observationTwo = new Observation(null, "at000", text("observation"), + arch, null, null, null, language, encoding, subject(), + provider(), null, null, protocol, null, data, state, termServ); + + assertFalse(observationOne.equals(observationTwo)); + } + + public void testNotEqualsProtocol() throws Exception + { + ItemStructure protocol = list("list protocol"); + History data = event("data"); + History state = event("state"); + Archetyped arch = new Archetyped( + new ArchetypeID("openehr-ehr_rm-observation.physical_examination.v3"), + "1.1"); + TerminologyService termServ = SimpleTerminologyService.getInstance(); + + CodePhrase language = new CodePhrase("ISO_639-1", "en"); + CodePhrase encoding = new CodePhrase("IANA_character-sets", "UTF-8"); + + Observation observationOne = new Observation(null, "at001", text("observation"), + arch, null, null, null, language, encoding, subject(), + provider(), null, null, protocol, null, data, state, termServ); + + Observation observationTwo = new Observation(null, "at000", text("observation"), + arch, null, null, null, language, encoding, subject(), + provider(), null, null, null, null, data, state, termServ); + + assertFalse(observationOne.equals(observationTwo)); + } + + public void testNotEqualsState() throws Exception + { + ItemStructure protocol = list("list protocol"); + History data = event("data"); + History state = event("state"); + Archetyped arch = new Archetyped( + new ArchetypeID("openehr-ehr_rm-observation.physical_examination.v3"), + "1.1"); + TerminologyService termServ = SimpleTerminologyService.getInstance(); + + CodePhrase language = new CodePhrase("ISO_639-1", "en"); + CodePhrase encoding = new CodePhrase("IANA_character-sets", "UTF-8"); + + Observation observationOne = new Observation(null, "at001", text("observation"), + arch, null, null, null, language, encoding, subject(), + provider(), null, null, protocol, null, data, state, termServ); + + Observation observationTwo = new Observation(null, "at000", text("observation"), + arch, null, null, null, language, encoding, subject(), + provider(), null, null, protocol, null, data, null, termServ); + + assertFalse(observationOne.equals(observationTwo)); + } + + public void testNotEqualsData() throws Exception + { + ItemStructure protocol = list("list protocol"); + History data = event("data"); + History state = event("state"); + Archetyped arch = new Archetyped( + new ArchetypeID("openehr-ehr_rm-observation.physical_examination.v3"), + "1.1"); + TerminologyService termServ = SimpleTerminologyService.getInstance(); + + CodePhrase language = new CodePhrase("ISO_639-1", "en"); + CodePhrase encoding = new CodePhrase("IANA_character-sets", "UTF-8"); + + Observation observationOne = new Observation(null, "at001", text("observation"), + arch, null, null, null, language, encoding, subject(), + provider(), null, null, protocol, null, data, state, termServ); + + Observation observationTwo = new Observation(null, "at000", text("observation"), + arch, null, null, null, language, encoding, subject(), + provider(), null, null, protocol, null, eventDiff("data"), state, termServ); + + assertFalse(observationOne.equals(observationTwo)); + } + + + protected History eventDiff(String name) { + // element = element("element name", "value"); + String[] ITEMS = { "event one" }; + String[] CODES = { "code one" }; + List> items = new ArrayList>(); + for (int i = 0; i < ITEMS.length; i++) { + Element element = element("element " + i, CODES[i]); + ItemSingle item = new ItemSingle(null, "at0001", text(ITEMS[i]), + null, null, null, null, element); + items.add(new PointEvent(null, "at0003", + text("point event"), null, null, null, null, + new DvDateTime("2006-06-25T23:11:11"), item, null)); + // uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, + // parent, time, data, state + } + return new History(null, "at0002", text("history"), + null, null, null, null, new DvDateTime("2006-06-25T23:11:11"), + items, DvDuration.getInstance("PT1h"), DvDuration + .getInstance("PT3h"), null); + } + /* field */ private ItemList itemList; private PointEvent event; diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/navigation/SectionTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/navigation/SectionTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/datastructure/DataStructureTestBase.java b/openehr-rm-domain/src/test/java/org/openehr/rm/datastructure/DataStructureTestBase.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/datastructure/DataStructureTestBase2.java b/openehr-rm-domain/src/test/java/org/openehr/rm/datastructure/DataStructureTestBase2.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/AddressTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/AddressTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/CapabilityTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/CapabilityTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/ContactTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/ContactTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/DemographicTestBase.java b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/DemographicTestBase.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/PartyIdentityTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/PartyIdentityTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/PartyRelationshipTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/PartyRelationshipTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/PartyTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/PartyTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/PersonTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/PersonTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/VersionedPartyTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/VersionedPartyTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/ehr/EHRStatusTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/ehr/EHRStatusTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/ehr/VersionedCompositionTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/ehr/VersionedCompositionTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/integration/GenericEntryCreationTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/integration/GenericEntryCreationTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/integration/GenericEntryPathTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/integration/GenericEntryPathTest.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/support/measurement/TestMeasurementService.java b/openehr-rm-domain/src/test/java/org/openehr/rm/support/measurement/TestMeasurementService.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/support/terminology/TestCodeSetAccess.java b/openehr-rm-domain/src/test/java/org/openehr/rm/support/terminology/TestCodeSetAccess.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/support/terminology/TestTerminologyAccess.java b/openehr-rm-domain/src/test/java/org/openehr/rm/support/terminology/TestTerminologyAccess.java old mode 100755 new mode 100644 diff --git a/openehr-rm-domain/src/test/java/org/openehr/rm/support/terminology/TestTerminologyService.java b/openehr-rm-domain/src/test/java/org/openehr/rm/support/terminology/TestTerminologyService.java old mode 100755 new mode 100644 diff --git a/pom.xml b/pom.xml index 8dc877a8..32adfd68 100755 --- a/pom.xml +++ b/pom.xml @@ -1,82 +1,163 @@ - - 4.0.0 - openehr - ref_impl_java - pom - 1.0.5-SNAPSHOT - The openEHR Reference Java Implementation - - The openEHR Foundation - - - UTF-8 - - - scm:git:git@github.com:openEHR/java-libs.git - scm:git:git@github.com:openEHR/java-libs.git - scm:git:git@github.com:openEHR/java-libs.git - - - + + + 4.0.0 + org.openehr.java-libs + java-libs + pom + 0-SNAPSHOT + The openEHR Reference Java Implementation + Standard Java libraries for Java implementations of openEHR + https://github.com/openEHR/java-libs + + The openEHR Foundation + + + UTF-8 + UTF-8 + + + scm:git:git://github.com/openEHR/java-libs.git + scm:git:ssh://github.com:openEHR/java-libs.git + http://github.com/openEHR/java-libs/tree/master + + + + org.codehaus.mojo + versions-maven-plugin + 2.1 + + + org.apache.maven.plugins maven-compiler-plugin - 2.3.2 + 3.5.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.0 + + + attach-sources + + jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.3 + + + attach-javadocs + + jar + + + - 1.6 - 1.6 - + false - - org.apache.maven.plugins - maven-javadoc-plugin - 2.9 - - org.umlgraph.doclet.UmlGraphDoc - - - org.umlgraph - umlgraph - 5.6 - - - -inferrel -inferdep -quiet -hide java.* - -collpackages java.util.* -qualify - -postfixpackage -nodefontsize 9 - -nodefontpackagesize 7 - -edgefontname "Trebuchet MS" - -nodefontabstractname "Trebuchet MS" - -nodefontclassabstractname - "Trebuchet MS" - -nodefontclassname "Trebuchet MS" - -nodefontname - "Trebuchet MS" - -nodefontpackagename "Trebuchet MS" - -nodefonttagname - "Trebuchet MS" - - true - - - - - - - - openehr-rm-core - openehr-rm-domain - openehr-aom - openehr-ap - adl-parser - dadl-parser - oet-parser - adl-serializer - xml-serializer - measure-serv - mini-termserv - rm-builder - xml-binding - dadl-binding - rm-skeleton - - \ No newline at end of file + + + + + MPL License + http://www.mozilla.org/MPL/ + + + + + Rong Chen + rong.chen@cambio.se + Cambio Healthcare Systems + http://www.cambio.se + + + + openehr-rm-core + openehr-rm-domain + openehr-aom + openehr-ap + adl-parser + dadl-parser + oet-parser + adl-serializer + xml-serializer + measure-serv + mini-termserv + rm-builder + xml-binding + dadl-binding + rm-skeleton + archetype-validator + + + + cambio + + true + + + + repo.cambio.se_releases + releases + https://nexus.cambiocds.com/repository/maven-releases/ + + + repo.cambio.se_snapshots + snapshots + https://nexus.cambiocds.com/repository/maven-snapshots/ + false + + + + + ossrh + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + release-sign-artifacts + + + performRelease + true + + + + + + org.apache.maven.plugins + maven-gpg-plugin + + + sign-artifacts + verify + + sign + + + + + + + + + diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 9c61b917..033fa6f6 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -2,9 +2,9 @@ 4.0.0 - openehr - ref_impl_java - 1.0.5-SNAPSHOT + org.openehr.java-libs + java-libs + 0-SNAPSHOT rm-builder jar @@ -21,22 +21,22 @@ - openehr + org.openehr.java-libs openehr-rm-core ${project.version} - openehr + org.openehr.java-libs openehr-rm-domain ${project.version} - openehr + org.openehr.java-libs mini-termserv ${project.version} - openehr + org.openehr.java-libs measure-serv ${project.version} diff --git a/rm-builder/src/main/java/org/openehr/build/AttributeFormatException.java b/rm-builder/src/main/java/org/openehr/build/AttributeFormatException.java old mode 100755 new mode 100644 diff --git a/rm-builder/src/main/java/org/openehr/build/AttributeMissingException.java b/rm-builder/src/main/java/org/openehr/build/AttributeMissingException.java old mode 100755 new mode 100644 diff --git a/rm-builder/src/main/java/org/openehr/build/ErrorType.java b/rm-builder/src/main/java/org/openehr/build/ErrorType.java old mode 100755 new mode 100644 diff --git a/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java b/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java index d539ce10..8b571928 100755 --- a/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java +++ b/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java @@ -15,26 +15,62 @@ import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; -import org.openehr.rm.*; -import org.openehr.rm.common.archetyped.*; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.RMObject; +import org.openehr.rm.common.archetyped.Archetyped; import org.openehr.rm.common.changecontrol.Contribution; import org.openehr.rm.common.changecontrol.OriginalVersion; -import org.openehr.rm.common.generic.*; +import org.openehr.rm.common.generic.Attestation; +import org.openehr.rm.common.generic.AuditDetails; +import org.openehr.rm.common.generic.Participation; +import org.openehr.rm.common.generic.PartyIdentified; +import org.openehr.rm.common.generic.PartyRelated; +import org.openehr.rm.common.generic.PartySelf; import org.openehr.rm.composition.Composition; import org.openehr.rm.composition.EventContext; -import org.openehr.rm.composition.content.entry.*; -import org.openehr.rm.composition.content.navigation.*; -import org.openehr.rm.datastructure.history.*; -import org.openehr.rm.datastructure.itemstructure.*; -import org.openehr.rm.datastructure.itemstructure.representation.*; -import org.openehr.rm.datatypes.basic.*; -import org.openehr.rm.datatypes.encapsulated.*; -import org.openehr.rm.datatypes.quantity.*; -import org.openehr.rm.datatypes.quantity.datetime.*; -import org.openehr.rm.datatypes.text.*; -import org.openehr.rm.datatypes.uri.*; +import org.openehr.rm.composition.content.entry.Action; +import org.openehr.rm.composition.content.entry.Activity; +import org.openehr.rm.composition.content.entry.AdminEntry; +import org.openehr.rm.composition.content.entry.Evaluation; +import org.openehr.rm.composition.content.entry.ISMTransition; +import org.openehr.rm.composition.content.entry.Instruction; +import org.openehr.rm.composition.content.entry.InstructionDetails; +import org.openehr.rm.composition.content.entry.Observation; +import org.openehr.rm.composition.content.navigation.Section; +import org.openehr.rm.datastructure.history.History; +import org.openehr.rm.datastructure.history.IntervalEvent; +import org.openehr.rm.datastructure.history.PointEvent; +import org.openehr.rm.datastructure.itemstructure.ItemList; +import org.openehr.rm.datastructure.itemstructure.ItemSingle; +import org.openehr.rm.datastructure.itemstructure.ItemTable; +import org.openehr.rm.datastructure.itemstructure.ItemTree; +import org.openehr.rm.datastructure.itemstructure.representation.Cluster; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datatypes.basic.DvBoolean; +import org.openehr.rm.datatypes.basic.DvIdentifier; +import org.openehr.rm.datatypes.basic.DvState; +import org.openehr.rm.datatypes.encapsulated.DvMultimedia; +import org.openehr.rm.datatypes.encapsulated.DvParsable; +import org.openehr.rm.datatypes.quantity.DvCount; +import org.openehr.rm.datatypes.quantity.DvInterval; +import org.openehr.rm.datatypes.quantity.DvOrdinal; +import org.openehr.rm.datatypes.quantity.DvProportion; +import org.openehr.rm.datatypes.quantity.DvQuantity; +import org.openehr.rm.datatypes.quantity.ProportionKind; +import org.openehr.rm.datatypes.quantity.datetime.DvDate; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.quantity.datetime.DvDuration; +import org.openehr.rm.datatypes.quantity.datetime.DvTime; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.datatypes.text.DvParagraph; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.datatypes.uri.DvEHRURI; +import org.openehr.rm.datatypes.uri.DvURI; import org.openehr.rm.demographic.*; import org.openehr.rm.support.identification.*; +import org.openehr.rm.support.identification.UUID; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; @@ -42,646 +78,660 @@ /** * Reference model class instances builder - * + * * @author Rong Chen * @version 1.0 */ public class RMObjectBuilder { - - /** - * Factory method to create an instance of the RM builder - * - * @param systemValues - * @return - */ - public static RMObjectBuilder getInstance(Map systemValues) { - return new RMObjectBuilder(systemValues); - } - - /** - * Create a RMObjectBuilder - * - * @param systemValues - */ - public RMObjectBuilder(Map systemValues) { - - this(); - - if (systemValues == null) { - throw new IllegalArgumentException("systemValues null"); - } - this.systemValues = systemValues; - } - - // for testing purpose - RMObjectBuilder() { - try { - loadTypeMap(); - } catch (ClassNotFoundException e) { - throw new RuntimeException("failed to load class, " + e - + " when starting rmObjectBuilder.."); - } - } - - // load all reference types that are possible to instantiate - // using FullConstructor annotation - private Map loadTypeMap() throws ClassNotFoundException { - Class[] classes = { - - // common classes - PartySelf.class, - Archetyped.class, - Attestation.class, - AuditDetails.class, - Participation.class, - PartyIdentified.class, - PartyRelated.class, - PartySelf.class, - OriginalVersion.class, - Contribution.class, - - // support classes - TerminologyID.class, - ArchetypeID.class, - HierObjectID.class, - AccessGroupRef.class, - GenericID.class, - InternetID.class, - ISO_OID.class, - LocatableRef.class, - ObjectVersionID.class, - ObjectRef.class, - PartyRef.class, - TemplateID.class, - TerminologyID.class, - org.openehr.rm.support.identification.UUID.class, - //VersionTreeID.class, - - // datatypes classes - DvBoolean.class, - DvState.class, - DvIdentifier.class, - DvText.class, - DvCodedText.class, - DvParagraph.class, - CodePhrase.class, - DvCount.class, - DvOrdinal.class, - DvQuantity.class, - DvInterval.class, - DvProportion.class, - DvDate.class, - DvDateTime.class, - DvTime.class, - DvDuration.class, - DvParsable.class, - DvURI.class, - DvEHRURI.class, - DvMultimedia.class, - - // datastructure classes - Element.class, - Cluster.class, - ItemSingle.class, - ItemList.class, - ItemTable.class, - ItemTree.class, - //ItemStructure.class, - History.class, - IntervalEvent.class, - PointEvent.class, - - // ehr classes - Action.class, Activity.class, Evaluation.class, ISMTransition.class, - Instruction.class, InstructionDetails.class, Observation.class, AdminEntry.class, - Section.class, Composition.class, - EventContext.class, ISMTransition.class, - - // demographic classes - Address.class, PartyIdentity.class, Agent.class, Group.class, - Organisation.class, Person.class, Contact.class, - PartyRelationship.class, Role.class, Capability.class }; - - typeMap = new HashMap(); - upperCaseMap = new HashMap(); - for (Class klass : classes) { - String name = klass.getSimpleName(); - typeMap.put(name, klass); - upperCaseMap.put(name.toUpperCase(), klass); - } - - return typeMap; - } - - /* - * Return a map with name as the key and index of position as the value for - * required parameters of the full constructor in the RMObject - * - * @param rmClass @return - */ - private Map attributeType(Class rmClass) { - - Map map = new HashMap(); - Constructor constructor = fullConstructor(rmClass); - if (constructor == null) { - throw new IllegalArgumentException("no annotated constructor of " - + rmClass + ">"); - } - Annotation[][] annotations = constructor.getParameterAnnotations(); - Class[] types = constructor.getParameterTypes(); - - if (annotations.length != types.length) { - throw new IllegalArgumentException("less annotations"); - } - for (int i = 0; i < types.length; i++) { - if (annotations[i].length == 0) { - throw new IllegalArgumentException( - "missing annotations of attribute " + i); - } - Attribute attribute = (Attribute) annotations[i][0]; - map.put(attribute.name(), types[i]); - } - return map; - } - - /** - * Return a map with name as the key and index of position as the value for - * all parameters of the full constructor in the RMObject - * - * @param rmClass - * @return - */ - private Map attributeIndex(Class rmClass) { - Map map = new HashMap(); - Constructor constructor = fullConstructor(rmClass); - Annotation[][] annotations = constructor.getParameterAnnotations(); - - for (int i = 0; i < annotations.length; i++) { - if (annotations[i].length == 0) { - throw new IllegalArgumentException( - "missing annotation at position " + i); - } - Attribute attribute = (Attribute) annotations[i][0]; - map.put(attribute.name(), i); - } - return map; - } - - /** - * Return a map with name as the key and index of position as the value for - * all parameters of the full constructor in the RMObject - * - * @param rmClass - * @return - */ - private Map attributeMap(Class rmClass) { - Map map = new HashMap(); - Constructor constructor = fullConstructor(rmClass); - Annotation[][] annotations = constructor.getParameterAnnotations(); - - for (int i = 0; i < annotations.length; i++) { - if (annotations[i].length == 0) { - throw new IllegalArgumentException( - "missing annotation at position " + i); - } - Attribute attribute = (Attribute) annotations[i][0]; - map.put(attribute.name(), attribute); - } - return map; - } - - private static Constructor fullConstructor(Class klass) { - Constructor[] array = klass.getConstructors(); - for (Constructor constructor : array) { - if (constructor.isAnnotationPresent(FullConstructor.class)) { - return constructor; - } - } - return null; - } - - /** - * Return system value for given id - * - * @param id - * @return null if not there - */ - public Object getSystemValue(SystemValue id) { - return systemValues.get(id); - } - - /** - * Construct an instance of RM class of given name and values.

If the - * input is a string, and the required attribute is some other types - * (integer, double etc), it will be converted into right type. if there is - * any error during conversion, AttributeFormatException will be thrown. - * - * @param rmClassName - * @param valueMap - * @return created instance - * @throws RMObjectBuildingException - */ - public RMObject construct(String rmClassName, Map valueMap) - throws RMObjectBuildingException { - - Class rmClass = retrieveRMType(rmClassName); - - // replace underscore separated names with camel case - Map filteredMap = new HashMap(); - for (String name : valueMap.keySet()) { - filteredMap.put(toCamelCase(name), valueMap.get(name)); - } - Constructor constructor = fullConstructor(rmClass); - Map typeMap = attributeType(rmClass); - Map indexMap = attributeIndex(rmClass); - Map attributeMap = attributeMap(rmClass); - Object[] valueArray = new Object[indexMap.size()]; - - for (String name : typeMap.keySet()) { - - Object value = filteredMap.get(name); - - if (!typeMap.containsKey(name) || !attributeMap.containsKey(name)) { - throw new RMObjectBuildingException("unknown attribute " + name); - } - - Class type = typeMap.get(name); - Integer index = indexMap.get(name); - - Attribute attribute = attributeMap.get(name); - if (index == null || type == null) { - throw new RMObjectBuildingException("unknown attribute \"" - + name + "\""); - } - - // system supplied value - if (attribute.system()) { - SystemValue sysvalue = SystemValue.fromId(name); - if (sysvalue == null) { - throw new RMObjectBuildingException("unknonw system value" - + "\"" + name + "\""); - } - value = systemValues.get(sysvalue); - if (value == null) { - throw new AttributeMissingException("missing value for " - + "system attribute \"" + name + "\" in class: " - + rmClass + ", with valueMap: " + valueMap); - } - } - - // check required attributes - if (value == null && attribute.required()) { - log.info(attribute); - throw new AttributeMissingException("missing value for " - + "required attribute \"" + name + "\" of type " + type - + " while constructing " + rmClass + " with valueMap: " + valueMap); - } - - // enum - else if (type.isEnum() && !value.getClass().isEnum()) { - // OG added - if (type.equals(ProportionKind.class)) - value = ProportionKind.fromValue(Integer.parseInt(value.toString())); - else - value = Enum.valueOf(type, value.toString()); - } - - // in case of null, create a default value - else if (value == null) { - value = defaultValue(type); - } - - // in case of string value, convert to right type if necessary - else if (value instanceof String) { - String str = (String) value; - try { - - // for DvCount - if (type.equals(int.class)) { - value = Integer.parseInt(str); - - // for DvQuantity - } else if (type.equals(double.class)) { - value = Double.parseDouble(str); - - // for DvProportion.precision - } else if (type.equals(Integer.class)) { - value = new Integer(str); - } - - } catch (NumberFormatException e) { - throw new AttributeFormatException("wrong format of " - + "attribute " + name + ", expect " + type); - } - - // deal with mismatch between array and list - } else if (type.isAssignableFrom(List.class) - && value.getClass().isArray()) { - - Object[] array = (Object[]) value; - List list = new ArrayList(); - for (Object o : array) { - list.add(o); - } - value = list; - - // deal with mismatch between array and set - } else if (type.isAssignableFrom(Set.class) - && value.getClass().isArray()) { - - Object[] array = (Object[]) value; - Set set = new HashSet(); - for (Object o : array) { - set.add(o); - } - value = set; - } - // check type - else if (value != null && !type.isPrimitive()) { - try { - type.cast(value); - } catch (ClassCastException e) { - throw new RMObjectBuildingException("Failed to construct: " - + rmClassName + ", value for attribute '" - + name + "' has wrong type, expected \"" + type - + "\", but got \"" + value.getClass() + "\""); - } - } - valueArray[index] = value; - } - - Object ret = null; - - try { - // OG added hack - if (rmClassName.equalsIgnoreCase("DVCOUNT")) { - log.debug("Fixing DVCOUNT..."); - for (int i = 0; i < valueArray.length; i++) { - Object value = valueArray[i]; - if (value != null && value.getClass().equals(Float.class)) - valueArray[i] = Double.parseDouble(value.toString()); - else if (value != null && value.getClass().equals(Long.class)) - valueArray[i] = Integer.parseInt(value.toString()); - } - } - ret = constructor.newInstance(valueArray); - } catch (Exception e) { - - if (log.isDebugEnabled()) { - e.printStackTrace(); - } - - log.debug("failed in constructor.newInstance()", e); - - if (stringParsingTypes.contains(rmClassName)) { - throw new AttributeFormatException("wrong format for type " - + rmClassName); - } - - throw new RMObjectBuildingException( - "failed to create new instance of " + rmClassName - + " with valueMap: " + toString(valueMap) + ", cause: " - + e.getMessage()); - } - return (RMObject) ret; - } - - private String toString(Map map) { - StringBuffer buf = new StringBuffer(); - for(String key : map.keySet()) { - buf.append(key); - buf.append("="); - Object value = map.get(key); - if(value != null) { - buf.append(value.getClass().getName()); - buf.append(":"); - buf.append(value.toString()); - } else { - buf.append("null"); - } - buf.append(", "); - } - return buf.toString(); - } - - /** - * Retrieves RM type using given name try both the CamelCase and - * Underscore-separated ways - * - * @param rmClassName - * @return - * @throws Exception - */ - public Class retrieveRMType(String rmClassName) - throws RMObjectBuildingException { - int index = rmClassName.indexOf("<"); - if (index>0){ - rmClassName = rmClassName.substring(0,index); - } - Class rmClass = typeMap.get(rmClassName); - if (rmClass == null) { - rmClass = upperCaseMap.get(rmClassName.replace("_", "")); - } - if (rmClass == null) { - throw new RMObjectBuildingException("RM type unknown: \"" - + rmClassName + "\""); - } - return rmClass; - } - - /** - * Retrieves list of attribute names of given class - * - * @param rmClassName - * @return - * @throws RMObjectBuildingException - */ - public Map retrieveAttribute(String rmClassName) - throws RMObjectBuildingException { - Class rmClass = retrieveRMType(rmClassName); - Map map = attributeType(rmClass); - return map; - } - - private String toCamelCase(String underscoreSeparated) { - StringTokenizer tokens = new StringTokenizer(underscoreSeparated, "_"); - StringBuffer buf = new StringBuffer(); - while (tokens.hasMoreTokens()) { - String word = tokens.nextToken(); - if (buf.length() == 0) { - buf.append(word); - } else { - buf.append(word.substring(0, 1).toUpperCase()); - buf.append(word.substring(1)); - } - } - return buf.toString(); - } - - private String toUnderscoreSeparated(String camelCase) { - String[] array = StringUtils.splitByCharacterTypeCamelCase(camelCase); - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < array.length; i++) { - String s = array[i]; - buf.append(s.substring(0, 1).toLowerCase()); - buf.append(s.substring(1)); - if (i != array.length - 1) { - buf.append("_"); - } - } - return buf.toString(); - } - - /** - * Finds the matching RM class that can be used to create RM object for - * given value map - * - * @param valueMap - * @return null if no match RM class is found - */ - public String findMatchingRMClass(Map valueMap) { - List simpleTypes = Arrays.asList(SKIPPED_TYPES_IN_MATCHING); - - for (Class rmClass : typeMap.values()) { - - log.debug("matching rmClass: " + rmClass.getName()); - - if (simpleTypes.contains(rmClass.getSimpleName())) { - continue; // skip simple value types - } - - // replace underscore separated names with camel case - Map filteredMap = new HashMap(); - for (String name : valueMap.keySet()) { - filteredMap.put(toCamelCase(name), valueMap.get(name)); - } - - Constructor constructor = fullConstructor(rmClass); - if (constructor == null) { - throw new RuntimeException("annotated constructor missing for " - + rmClass); - } - Annotation[][] annotations = constructor.getParameterAnnotations(); - if (annotations == null || annotations.length == 0) { - throw new RuntimeException("attribute annotations missing for " - + rmClass); - } - Class[] types = constructor.getParameterTypes(); - boolean matched = true; - Set attributes = new HashSet(); - - for (int i = 0; i < types.length; i++) { - if (annotations[i].length == 0) { - throw new RuntimeException( - "attribute annotation missing for" + rmClass); - } - Attribute attribute = (Attribute) annotations[i][0]; - attributes.add(attribute.name()); - - log.debug("checking attribute: " + attribute.name()); - - String attrName = attribute.name(); - Object attrValue = filteredMap.get(attrName); - - if (attribute.required() && attrValue == null) { - - log.debug("missing required attribute.."); - - matched = false; - break; - - } else if (attrValue != null) { - if (((attrValue instanceof Boolean) && types[i] != boolean.class) - || ((attrValue instanceof Integer) && types[i] != Integer.class) - || ((attrValue instanceof Double) && types[i] != double.class)) { - - log.debug("wrong primitive value type for attribute.."); - matched = false; - break; - - } else if (!types[i].isPrimitive() - && !types[i].isInstance(attrValue)) { - log.debug("wrong value type for attribute.."); - matched = false; - break; - - } - } - } - - for (String attr : filteredMap.keySet()) { - if (!attributes.contains(attr)) { - - log.debug("unknown attribute: " + attr); - - matched = false; - } - } - - // matching found - if (matched) { - String className = rmClass.getSimpleName(); - - log.debug(">>> MATCHING FOUND: " + className); - - return className; - } - } - return null; - } - - // todo: isn't there any support from java api on this? - private Object defaultValue(Class type) { - if (type == boolean.class) { - return Boolean.FALSE; - } else if (type == double.class) { - return new Double(0); - } else if (type == float.class) { - return new Float(0); - } else if (type == int.class) { - return new Integer(0); - } else if (type == short.class) { - return new Short((short) 0); - } else if (type == long.class) { - return new Long(0); - } else if (type == char.class) { - return new Character((char) 0); - } else if (type == byte.class) { - return new Byte((byte) 0); - } - return null; - } - - /* - * Skipped types during matching: 1. Simple value types in DADL 2. Cluster - * due to clash with ItemList - */ - private static final String[] SKIPPED_TYPES_IN_MATCHING = { "DvDateTime", - "DvDate", "DvTime", "DvDuration", "Cluster", - // due to clash with DvText - "TerminologyID", "ArchetypeID", "TemplateID", "ISO_OID", - "HierObjectID", "DvBoolean", "InternetID", "UUID", - "ObjectVersionID", "DvURI", "DvEHRURI" - }; - - /* logger */ - private static final Logger log = Logger.getLogger(RMObjectBuilder.class); - - /* fields */ - private Map systemValues; - - // loaded rm type map - private Map typeMap; - private Map upperCaseMap; - private static final Set stringParsingTypes; // These should be rm_type_names not Java class names. - - static { - // so far only types from quantity.datetime - stringParsingTypes = new HashSet(); - //String[] types = { "DvDate", "DvDateTime", "DvTime", "DvDuration", "DvPartialDate", "DvPartialTime" }; - String[] types = { "DV_DATE", "DV_DATE_TIME", "DV_TIME", "DV_DURATION", "DV_PARTIAL_DATE", "DV_PARTIAL_TIME" }; - stringParsingTypes.addAll(Arrays.asList(types)); - } + + /** + * Factory method to create an instance of the RM builder + * + * @param systemValues + * @return + */ + public static RMObjectBuilder getInstance(Map systemValues) { + return new RMObjectBuilder(systemValues); + } + + /** + * Create a RMObjectBuilder + * + * @param systemValues + */ + public RMObjectBuilder(Map systemValues) { + + this(); + + if (systemValues == null) { + throw new IllegalArgumentException("systemValues null"); + } + this.systemValues = systemValues; + } + + // for testing purpose + RMObjectBuilder() { + try { + loadTypeMap(); + } catch (ClassNotFoundException e) { + throw new RuntimeException("failed to load class, " + e + + " when starting rmObjectBuilder.."); + } + } + + // load all reference types that are possible to instantiate + // using FullConstructor annotation + private Map loadTypeMap() throws ClassNotFoundException { + Class[] classes = { + + // common classes + PartySelf.class, + Archetyped.class, + Attestation.class, + AuditDetails.class, + Participation.class, + PartyIdentified.class, + PartyRelated.class, + PartySelf.class, + OriginalVersion.class, + Contribution.class, + + // support classes + TerminologyID.class, + ArchetypeID.class, + HierObjectID.class, + AccessGroupRef.class, + GenericID.class, + InternetID.class, + ISO_OID.class, + LocatableRef.class, + ObjectVersionID.class, + ObjectRef.class, + PartyRef.class, + TemplateID.class, + TerminologyID.class, + org.openehr.rm.support.identification.UUID.class, + //VersionTreeID.class, + + // datatypes classes + DvBoolean.class, + DvState.class, + DvIdentifier.class, + DvText.class, + DvCodedText.class, + DvParagraph.class, + CodePhrase.class, + DvCount.class, + DvOrdinal.class, + DvQuantity.class, + DvInterval.class, + DvProportion.class, + DvDate.class, + DvDateTime.class, + DvTime.class, + DvDuration.class, + DvParsable.class, + DvURI.class, + DvEHRURI.class, + DvMultimedia.class, + + // datastructure classes + Element.class, + Cluster.class, + ItemSingle.class, + ItemList.class, + ItemTable.class, + ItemTree.class, + //ItemStructure.class, + History.class, + IntervalEvent.class, + PointEvent.class, + + // ehr classes + Action.class, Activity.class, Evaluation.class, ISMTransition.class, + Instruction.class, InstructionDetails.class, Observation.class, AdminEntry.class, + Section.class, Composition.class, + EventContext.class, ISMTransition.class, + + // demographic classes + Address.class, PartyIdentity.class, Agent.class, Group.class, + Organisation.class, Person.class, Contact.class, + PartyRelationship.class, Role.class, Capability.class}; + + typeMap = new LinkedHashMap<>(); + upperCaseMap = new LinkedHashMap<>(); + for (Class klass : classes) { + String name = klass.getSimpleName(); + typeMap.put(name, klass); + upperCaseMap.put(name.toUpperCase(), klass); + } + + return typeMap; + } + + /* + * Return a map with name as the key and index of position as the value for + * required parameters of the full constructor in the RMObject + * + * @param rmClass @return + */ + private Map attributeType(Class rmClass) { + + Map map = new HashMap(); + Constructor constructor = fullConstructor(rmClass); + if (constructor == null) { + throw new IllegalArgumentException("no annotated constructor of " + + rmClass + ">"); + } + Annotation[][] annotations = constructor.getParameterAnnotations(); + Class[] types = constructor.getParameterTypes(); + + if (annotations.length != types.length) { + throw new IllegalArgumentException("less annotations"); + } + for (int i = 0; i < types.length; i++) { + if (annotations[i].length == 0) { + throw new IllegalArgumentException( + "missing annotations of attribute " + i); + } + Attribute attribute = (Attribute) annotations[i][0]; + map.put(attribute.name(), types[i]); + } + return map; + } + + /** + * Return a map with name as the key and index of position as the value for + * all parameters of the full constructor in the RMObject + * + * @param rmClass + * @return + */ + private Map attributeIndex(Class rmClass) { + Map map = new HashMap(); + Constructor constructor = fullConstructor(rmClass); + Annotation[][] annotations = constructor.getParameterAnnotations(); + + for (int i = 0; i < annotations.length; i++) { + if (annotations[i].length == 0) { + throw new IllegalArgumentException( + "missing annotation at position " + i); + } + Attribute attribute = (Attribute) annotations[i][0]; + map.put(attribute.name(), i); + } + return map; + } + + /** + * Return a map with name as the key and index of position as the value for + * all parameters of the full constructor in the RMObject + * + * @param rmClass + * @return + */ + private Map attributeMap(Class rmClass) { + Map map = new HashMap(); + Constructor constructor = fullConstructor(rmClass); + Annotation[][] annotations = constructor.getParameterAnnotations(); + + for (int i = 0; i < annotations.length; i++) { + if (annotations[i].length == 0) { + throw new IllegalArgumentException( + "missing annotation at position " + i); + } + Attribute attribute = (Attribute) annotations[i][0]; + map.put(attribute.name(), attribute); + } + return map; + } + + private Constructor fullConstructor(Class klass) { + Constructor constructor = constructorMap.get(klass); + if (constructor == null) { + Constructor[] array = klass.getConstructors(); + int i = 0; + boolean found = false; + while (i < array.length && !found) { + Constructor constructorAux = array[i++]; + if (constructorAux.isAnnotationPresent(FullConstructor.class)) { + constructor = constructorAux; + constructorMap.put(klass, constructor); + found = true; + } + } + } + return constructor; + } + + /** + * Return system value for given id + * + * @param id + * @return null if not there + */ + public Object getSystemValue(SystemValue id) { + return systemValues.get(id); + } + + /** + * Construct an instance of RM class of given name and values.

If the + * input is a string, and the required attribute is some other types + * (integer, double etc), it will be converted into right type. if there is + * any error during conversion, AttributeFormatException will be thrown. + * + * @param rmClassName + * @param valueMap + * @return created instance + * @throws RMObjectBuildingException + */ + public RMObject construct(String rmClassName, Map valueMap) + throws RMObjectBuildingException { + + Class rmClass = retrieveRMType(rmClassName); + + // replace underscore separated names with camel case + Map filteredMap = new HashMap(); + for (Map.Entry entry : valueMap.entrySet()) { + filteredMap.put(toCamelCase(entry.getKey()), entry.getValue()); + } + Constructor constructor = fullConstructor(rmClass); + Map typeMap = attributeType(rmClass); + Map indexMap = attributeIndex(rmClass); + Map attributeMap = attributeMap(rmClass); + Object[] valueArray = new Object[indexMap.size()]; + + for (Map.Entry entry : typeMap.entrySet()) { + String name = entry.getKey(); + + Object value = filteredMap.get(name); + + if (!typeMap.containsKey(name) || !attributeMap.containsKey(name)) { + throw new RMObjectBuildingException("unknown attribute " + name); + } + + Class type = entry.getValue(); + Integer index = indexMap.get(name); + + Attribute attribute = attributeMap.get(name); + if (index == null || type == null) { + throw new RMObjectBuildingException("unknown attribute \"" + + name + "\""); + } + + // system supplied value + if (attribute.system()) { + SystemValue sysvalue = SystemValue.fromId(name); + if (sysvalue == null) { + throw new RMObjectBuildingException("unknonw system value" + + "\"" + name + "\""); + } + value = systemValues.get(sysvalue); + if (value == null) { + throw new AttributeMissingException("missing value for " + + "system attribute \"" + name + "\" in class: " + + rmClass + ", with valueMap: " + valueMap); + } + } + + // check required attributes + if (value == null && attribute.required()) { + log.info(attribute); + throw new AttributeMissingException("missing value for " + + "required attribute \"" + name + "\" of type " + type + + " while constructing " + rmClass + " with valueMap: " + valueMap); + } + + // enum + else if (type.isEnum() && !value.getClass().isEnum()) { + // OG added + if (type.equals(ProportionKind.class)) + value = ProportionKind.fromValue(Integer.parseInt(value.toString())); + else + value = Enum.valueOf(type, value.toString()); + } + + // in case of null, create a default value + else if (value == null) { + value = defaultValue(type); + } + + // in case of string value, convert to right type if necessary + else if (value instanceof String) { + String str = (String) value; + try { + + // for DvCount + if (type.equals(int.class)) { + value = Integer.parseInt(str); + + // for DvQuantity + } else if (type.equals(double.class)) { + value = Double.parseDouble(str); + + // for DvProportion.precision + } else if (type.equals(Integer.class)) { + value = Integer.valueOf(str); + + // for DvBoolean.value + } else if (type.equals(boolean.class)) { + value = new Boolean(str).booleanValue(); + } + } catch (NumberFormatException e) { + throw new AttributeFormatException("wrong format of " + + "attribute " + name + ", expect " + type); + } + + // deal with mismatch between array and list + } else if (type.isAssignableFrom(List.class) + && value.getClass().isArray()) { + + Object[] array = (Object[]) value; + List list = new ArrayList(); + for (Object o : array) { + list.add(o); + } + value = list; + + // deal with mismatch between array and set + } else if (type.isAssignableFrom(Set.class) + && value.getClass().isArray()) { + + Object[] array = (Object[]) value; + Set set = new HashSet(); + for (Object o : array) { + set.add(o); + } + value = set; + } + // check type + else if (!type.isPrimitive()) { + try { + type.cast(value); + } catch (ClassCastException e) { + throw new RMObjectBuildingException("Failed to construct: " + + rmClassName + ", value for attribute '" + + name + "' has wrong type, expected \"" + type + + "\", but got \"" + value.getClass() + "\""); + } + } + valueArray[index] = value; + } + + Object ret = null; + + try { + // OG added hack + if (rmClassName.equalsIgnoreCase("DVCOUNT")) { + log.debug("Fixing DVCOUNT..."); + for (int i = 0; i < valueArray.length; i++) { + Object value = valueArray[i]; + if (value != null && value.getClass().equals(Float.class)) + valueArray[i] = Double.parseDouble(value.toString()); + else if (value != null && value.getClass().equals(Long.class)) + valueArray[i] = Integer.parseInt(value.toString()); + } + } + ret = constructor.newInstance(valueArray); + } catch (Exception e) { + + if (log.isDebugEnabled()) { + e.printStackTrace(); + } + + log.debug("failed in constructor.newInstance()", e); + + if (stringParsingTypes.contains(rmClassName)) { + throw new AttributeFormatException("wrong format for type " + + rmClassName); + } + + throw new RMObjectBuildingException( + "failed to create new instance of " + rmClassName + + " with valueMap: " + toString(valueMap) + ", cause: " + + e.getMessage()); + } + return (RMObject) ret; + } + + + private String toString(Map map) { + StringBuffer buf = new StringBuffer(); + for (Map.Entry entry : map.entrySet()) { + buf.append(entry.getKey()); + buf.append("="); + Object value = entry.getValue(); + if (value != null) { + buf.append(value.getClass().getName()); + buf.append(":"); + buf.append(value.toString()); + } else { + buf.append("null"); + } + buf.append(", "); + } + return buf.toString(); + } + + /** + * Retrieves RM type using given name try both the CamelCase and + * Underscore-separated ways + * + * @param rmClassName + * @return + * @throws Exception + */ + public Class retrieveRMType(String rmClassName) + throws RMObjectBuildingException { + int index = rmClassName.indexOf("<"); + if (index > 0) { + rmClassName = rmClassName.substring(0, index); + } + Class rmClass = typeMap.get(rmClassName); + if (rmClass == null) { + rmClass = upperCaseMap.get(rmClassName.replace("_", "")); + } + if (rmClass == null) { + throw new RMObjectBuildingException("RM type unknown: \"" + + rmClassName + "\""); + } + return rmClass; + } + + /** + * Retrieves list of attribute names of given class + * + * @param rmClassName + * @return + * @throws RMObjectBuildingException + */ + public Map retrieveAttribute(String rmClassName) + throws RMObjectBuildingException { + Class rmClass = retrieveRMType(rmClassName); + Map map = attributeType(rmClass); + return map; + } + + private String toCamelCase(String underscoreSeparated) { + StringTokenizer tokens = new StringTokenizer(underscoreSeparated, "_"); + StringBuffer buf = new StringBuffer(); + while (tokens.hasMoreTokens()) { + String word = tokens.nextToken(); + if (buf.length() == 0) { + buf.append(word); + } else { + buf.append(word.substring(0, 1).toUpperCase()); + buf.append(word.substring(1)); + } + } + return buf.toString(); + } + + private String toUnderscoreSeparated(String camelCase) { + String[] array = StringUtils.splitByCharacterTypeCamelCase(camelCase); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < array.length; i++) { + String s = array[i]; + buf.append(s.substring(0, 1).toLowerCase()); + buf.append(s.substring(1)); + if (i != array.length - 1) { + buf.append("_"); + } + } + return buf.toString(); + } + + /** + * Finds the matching RM class that can be used to create RM object for + * given value map + * + * @param valueMap + * @return null if no match RM class is found + */ + public String findMatchingRMClass(Map valueMap) { + List simpleTypes = Arrays.asList(SKIPPED_TYPES_IN_MATCHING); + + for (Class rmClass : typeMap.values()) { + + log.debug("matching rmClass: " + rmClass.getName()); + + if (simpleTypes.contains(rmClass.getSimpleName())) { + continue; // skip simple value types + } + + // replace underscore separated names with camel case + Map filteredMap = new HashMap(); + for (Map.Entry entry : valueMap.entrySet()) { + filteredMap.put(toCamelCase(entry.getKey()), entry.getValue()); + } + + Constructor constructor = fullConstructor(rmClass); + if (constructor == null) { + throw new RuntimeException("annotated constructor missing for " + + rmClass); + } + Annotation[][] annotations = constructor.getParameterAnnotations(); + if (annotations == null || annotations.length == 0) { + throw new RuntimeException("attribute annotations missing for " + + rmClass); + } + Class[] types = constructor.getParameterTypes(); + boolean matched = true; + Set attributes = new HashSet(); + + for (int i = 0; i < types.length; i++) { + if (annotations[i].length == 0) { + throw new RuntimeException( + "attribute annotation missing for" + rmClass); + } + Attribute attribute = (Attribute) annotations[i][0]; + attributes.add(attribute.name()); + + log.debug("checking attribute: " + attribute.name()); + + String attrName = attribute.name(); + Object attrValue = filteredMap.get(attrName); + + if (attribute.required() && attrValue == null) { + + log.debug("missing required attribute.."); + + matched = false; + break; + + } else if (attrValue != null) { + if (((attrValue instanceof Boolean) && types[i] != boolean.class) + || ((attrValue instanceof Integer) && types[i] != Integer.class) + || ((attrValue instanceof Double) && types[i] != double.class)) { + + log.debug("wrong primitive value type for attribute.."); + matched = false; + break; + + } else if (!types[i].isPrimitive() + && !types[i].isInstance(attrValue)) { + log.debug("wrong value type for attribute.."); + matched = false; + break; + + } + } + } + + for (String attr : filteredMap.keySet()) { + if (!attributes.contains(attr)) { + + log.debug("unknown attribute: " + attr); + + matched = false; + } + } + + // matching found + if (matched) { + String className = rmClass.getSimpleName(); + + log.debug(">>> MATCHING FOUND: " + className); + + return className; + } + } + return null; + } + + // todo: isn't there any support from java api on this? + private Object defaultValue(Class type) { + if (type == boolean.class) { + return Boolean.FALSE; + } else if (type == double.class) { + return new Double(0); + } else if (type == float.class) { + return new Float(0); + } else if (type == int.class) { + return Integer.valueOf(0); + } else if (type == short.class) { + return Short.valueOf((short) 0); + } else if (type == long.class) { + return Long.valueOf(0); + } else if (type == char.class) { + return Character.valueOf((char) 0); + } else if (type == byte.class) { + return Byte.valueOf((byte) 0); + } + return null; + } + + /* + * Skipped types during matching: 1. Simple value types in DADL 2. Cluster + * due to clash with ItemList + */ + private static final String[] SKIPPED_TYPES_IN_MATCHING = {"DvDateTime", + "DvDate", "DvTime", "DvDuration", "Cluster", + // due to clash with DvText + "TerminologyID", "ArchetypeID", "TemplateID", "ISO_OID", + "HierObjectID", "DvBoolean", "InternetID", "UUID", + "ObjectVersionID", "DvURI", "DvEHRURI" + }; + + /* logger */ + private static final Logger log = Logger.getLogger(RMObjectBuilder.class); + + /* fields */ + private Map systemValues; + + // loaded rm type map + private Map typeMap; + private Map upperCaseMap; + private static final Set stringParsingTypes; // These should be rm_type_names not Java class names. + private final Map constructorMap = Collections.synchronizedMap(new HashMap()); + + static { + // so far only types from quantity.datetime + stringParsingTypes = new HashSet(); + //String[] types = { "DvDate", "DvDateTime", "DvTime", "DvDuration", "DvPartialDate", "DvPartialTime" }; + String[] types = {"DV_DATE", "DV_DATE_TIME", "DV_TIME", "DV_DURATION", "DV_PARTIAL_DATE", "DV_PARTIAL_TIME"}; + stringParsingTypes.addAll(Arrays.asList(types)); + } } /* diff --git a/rm-builder/src/main/java/org/openehr/build/RMObjectBuildingException.java b/rm-builder/src/main/java/org/openehr/build/RMObjectBuildingException.java old mode 100755 new mode 100644 diff --git a/rm-builder/src/main/java/org/openehr/build/SystemValue.java b/rm-builder/src/main/java/org/openehr/build/SystemValue.java old mode 100755 new mode 100644 diff --git a/rm-builder/src/main/resources/log4j.properties b/rm-builder/src/main/resources/log4j.properties index ebb694fb..969642f8 100755 --- a/rm-builder/src/main/resources/log4j.properties +++ b/rm-builder/src/main/resources/log4j.properties @@ -1,9 +1,9 @@ # Set root logger level to DEBUG and its only appender to stdout. -log4j.rootLogger=INFO, stdout +log4j.rootLogger=stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%-5p %c %x - %m%n # package logging level -log4j.logger.org.openehr.build= \ No newline at end of file +log4j.logger.org.openehr.build=ERROR \ No newline at end of file diff --git a/rm-builder/src/test/java/org/openehr/build/BuildDvCountTest.java b/rm-builder/src/test/java/org/openehr/build/BuildDvCountTest.java old mode 100755 new mode 100644 diff --git a/rm-builder/src/test/java/org/openehr/build/BuildTestBase.java b/rm-builder/src/test/java/org/openehr/build/BuildTestBase.java old mode 100755 new mode 100644 diff --git a/rm-builder/src/test/java/org/openehr/build/CommonSupportBuildTest.java b/rm-builder/src/test/java/org/openehr/build/CommonSupportBuildTest.java old mode 100755 new mode 100644 diff --git a/rm-builder/src/test/java/org/openehr/build/CreateDvMultimediaTest.java b/rm-builder/src/test/java/org/openehr/build/CreateDvMultimediaTest.java old mode 100755 new mode 100644 diff --git a/rm-builder/src/test/java/org/openehr/build/DataStructuresBuildTest.java b/rm-builder/src/test/java/org/openehr/build/DataStructuresBuildTest.java old mode 100755 new mode 100644 diff --git a/rm-builder/src/test/java/org/openehr/build/DataTypesBuildTest.java b/rm-builder/src/test/java/org/openehr/build/DataTypesBuildTest.java index ff14d505..f8e905e9 100755 --- a/rm-builder/src/test/java/org/openehr/build/DataTypesBuildTest.java +++ b/rm-builder/src/test/java/org/openehr/build/DataTypesBuildTest.java @@ -15,8 +15,6 @@ package org.openehr.build; -import java.util.*; - import org.openehr.rm.RMObject; import org.openehr.rm.datatypes.basic.DvBoolean; import org.openehr.rm.datatypes.basic.DvState; @@ -33,6 +31,11 @@ import org.openehr.rm.datatypes.text.DvText; import org.openehr.rm.support.identification.TerminologyID; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + public class DataTypesBuildTest extends BuildTestBase { // test classes from datatypes.basic package @@ -54,6 +57,21 @@ public void testBuildDvBoolean() throws Exception { assertTrue(obj instanceof DvBoolean); booleanObj = (DvBoolean) obj; assertEquals("value", false, booleanObj.getValue()); + + // true value + values.put("value", true); + obj = builder.construct(type, values); + assertTrue(obj instanceof DvBoolean); + booleanObj = (DvBoolean) obj; + assertEquals("value", true, booleanObj.getValue()); + + // false value + values.clear(); + values.put("value", false); + obj = builder.construct(type, values); + assertTrue(obj instanceof DvBoolean); + booleanObj = (DvBoolean) obj; + assertEquals("value", false, booleanObj.getValue()); } public void testBuildDvState() throws Exception { @@ -163,7 +181,7 @@ public void testBuildQuantity() throws Exception { String type = "DV_QUANTITY"; Map values = new HashMap(); values.put("units", "kg/L"); - values.put("magnitude", new Double(100.0)); + values.put("magnitude", 100.0); RMObject obj = builder.construct(type, values); assertTrue(obj instanceof DvQuantity); DvQuantity quantity = (DvQuantity) obj; @@ -181,7 +199,7 @@ public void testBuildQuantity() throws Exception { values.put("units", "mg"); values.put("magnitude", "wrong type"); try { - obj = builder.construct(type, values); + builder.construct(type, values); fail("attribute format exception should be thrown here"); } catch (Exception e) { assertTrue(e instanceof AttributeFormatException); @@ -208,19 +226,16 @@ public void testBuildDvDate() throws Exception { values.clear(); values.put("value", "bad values"); try { - obj = builder.construct(type, values); + builder.construct(type, values); fail("attribute format exception should be thrown here"); } catch (Exception e) { - - System.err.println("testBuildDvDate exception: "+ e.getClass().toString() +" "+ e.getMessage()); - assertTrue(e instanceof AttributeFormatException); } // with missing required value values.clear(); try { - obj = builder.construct(type, values); + builder.construct(type, values); fail("attribute missing exception should be thrown here"); } catch (Exception e) { assertTrue(e instanceof AttributeMissingException); diff --git a/rm-builder/src/test/java/org/openehr/build/DemographicBuildTest.java b/rm-builder/src/test/java/org/openehr/build/DemographicBuildTest.java old mode 100755 new mode 100644 diff --git a/rm-builder/src/test/java/org/openehr/build/EHRBuildTest.java b/rm-builder/src/test/java/org/openehr/build/EHRBuildTest.java old mode 100755 new mode 100644 index cadb7686..cdc52646 --- a/rm-builder/src/test/java/org/openehr/build/EHRBuildTest.java +++ b/rm-builder/src/test/java/org/openehr/build/EHRBuildTest.java @@ -14,48 +14,49 @@ */ package org.openehr.build; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import org.openehr.rm.RMObject; import org.openehr.rm.common.archetyped.Archetyped; import org.openehr.rm.common.generic.PartyProxy; -import org.openehr.rm.composition.content.entry.Action; -import org.openehr.rm.composition.content.entry.ISMTransition; -import org.openehr.rm.support.identification.ArchetypeID; import org.openehr.rm.composition.Composition; import org.openehr.rm.composition.EventContext; import org.openehr.rm.composition.content.ContentItem; +import org.openehr.rm.composition.content.entry.Action; import org.openehr.rm.composition.content.entry.Evaluation; +import org.openehr.rm.composition.content.entry.ISMTransition; import org.openehr.rm.composition.content.entry.Instruction; import org.openehr.rm.composition.content.entry.Observation; import org.openehr.rm.composition.content.navigation.Section; +import org.openehr.rm.datastructure.history.Event; import org.openehr.rm.datastructure.history.History; +import org.openehr.rm.datastructure.history.PointEvent; import org.openehr.rm.datastructure.itemstructure.ItemStructure; import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.quantity.datetime.DvDuration; import org.openehr.rm.datatypes.text.CodePhrase; import org.openehr.rm.datatypes.text.DvCodedText; import org.openehr.rm.datatypes.text.DvText; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.openehr.rm.datastructure.history.Event; -import org.openehr.rm.datastructure.history.PointEvent; -import org.openehr.rm.datatypes.quantity.datetime.DvDuration; +import org.openehr.rm.support.identification.ArchetypeID; /** * Test case for EHR objects building * * @author Rong Chen - * @version 1.0 + * @version 1.0 */ public class EHRBuildTest extends BuildTestBase { - - private static CodePhrase EVENT = new CodePhrase("openehr", "433"); + + private static CodePhrase EVENT = new CodePhrase("openehr", "433"); /** * The fixture set up called before every test method. */ + @Override protected void setUp() throws Exception { Map values = new HashMap(); values.put(SystemValue.LANGUAGE, lang); @@ -64,19 +65,19 @@ protected void setUp() throws Exception { values.put(SystemValue.SUBJECT, subject()); values.put(SystemValue.PROVIDER, provider()); values.put(SystemValue.COMPOSER, provider()); - + CodePhrase territory = new CodePhrase("ISO_3166-1", "SE"); values.put(SystemValue.TERRITORY, territory); values.put(SystemValue.CONTEXT, context()); - - DvCodedText category = new DvCodedText("event", lang, charset, EVENT, - ts); + + DvCodedText category = new DvCodedText("event", lang, charset, EVENT, + ts); values.put(SystemValue.CATEGORY, category); builder = new RMObjectBuilder(values); } - + public void testBuildObservation() throws Exception { Map values = new HashMap(); DvText name = new DvText("test observation", lang, charset, ts); @@ -114,7 +115,7 @@ public void testBuildEvaluation() throws Exception { DvText name = new DvText("test evlauation", lang, charset, ts); String node = "at0001"; Archetyped archetypeDetails = new Archetyped( - new ArchetypeID("openehr-ehr_rm-evaluation.physical_examination.v3"), "v1.0"); + new ArchetypeID("openehr-ehr_rm-evaluation.physical_examination.v3"), "v1.0"); ItemStructure data = itemSingle(); values.put("archetypeNodeId", node); values.put("archetypeDetails", archetypeDetails); @@ -145,9 +146,9 @@ public void testBuildInstruction() throws Exception { String node = "at0001"; DvText name = new DvText("test instruction", lang, charset, ts); Archetyped archetypeDetails = new Archetyped( - new ArchetypeID("openehr-ehr_rm-evaluation.physical_examination.v3"), "v1.0"); + new ArchetypeID("openehr-ehr_rm-evaluation.physical_examination.v3"), "v1.0"); DvText narrative = new DvText("medication instruction", lang, charset, ts); - + values.put("archetypeNodeId", node); values.put("archetypeDetails", archetypeDetails); values.put("name", name); @@ -171,11 +172,11 @@ public void testBuildInstruction() throws Exception { assertEquals("protocol", null, instruction.getProtocol()); assertEquals("guidelineID", null, instruction.getGuidelineId()); assertEquals("expiryTime", null, instruction.getExpiryTime()); - + // test with class name in upper case builder.construct("INSTRUCTION", values); } - + public void testBuildAction() throws Exception { Map values = new HashMap(); String node = "at0001"; @@ -184,8 +185,8 @@ public void testBuildAction() throws Exception { ISMTransition ismTransition = ismTransition(); DvDateTime time = new DvDateTime("2006-07-23T23:00:00"); Archetyped archetypeDetails = new Archetyped( - new ArchetypeID("openehr-ehr_rm-evaluation.physical_examination.v3"), "v1.0"); - + new ArchetypeID("openehr-ehr_rm-evaluation.physical_examination.v3"), "v1.0"); + values.put("archetypeNodeId", node); values.put("archetypeDetails", archetypeDetails); values.put("name", name); @@ -213,7 +214,7 @@ public void testBuildAction() throws Exception { assertEquals("description", description, action.getDescription()); assertEquals("ismTransition", ismTransition, action.getIsmTransition()); assertEquals("instructionDetails", null, action.getInstructionDetails()); - + // test with class name in upper case builder.construct("ACTION", values); } @@ -245,10 +246,10 @@ public void testBuildComposition() throws Exception { PartyProxy composer = provider(); Archetyped archetypeDetails = new Archetyped(new ArchetypeID( "openehr-ehr_rm-Composition.physical_exam.v2"), "1.0"); - DvCodedText category = new DvCodedText("event", lang, charset, EVENT, - ts); + DvCodedText category = new DvCodedText("event", lang, charset, EVENT, + ts); CodePhrase territory = new CodePhrase("ISO_3166-1", "SE"); - + values.put("archetypeNodeId", node); values.put("archetypeDetails", archetypeDetails); values.put("name", name); @@ -273,10 +274,10 @@ public void testBuildComposition() throws Exception { } private EventContext context() throws Exception { - CodePhrase home = new CodePhrase("openehr", "225"); + CodePhrase home = new CodePhrase("openehr", "225"); DvCodedText homeSetting = new DvCodedText("home setting", lang, charset, home, ts); - return new EventContext(null, new DvDateTime("2006-02-01T12:00:09"), null, null, + return new EventContext(null, new DvDateTime("2006-02-01T12:00:09"), null, null, null, homeSetting, null, ts); } @@ -290,29 +291,29 @@ private Section section() throws Exception { private Observation observation() throws Exception { DvText name = new DvText("test observation", lang, charset, ts); Archetyped archetypeDetails = new Archetyped( - new ArchetypeID("openehr-ehr_rm-observation.physical_examination.v3"), "v1.0"); + new ArchetypeID("openehr-ehr_rm-observation.physical_examination.v3"), "v1.0"); return new Observation("at0001", name, archetypeDetails, lang, charset, subject(), provider(), event(), ts); } private ISMTransition ismTransition() throws Exception { - DvCodedText planned = new DvCodedText("planned e state", lang, charset, - new CodePhrase("openehr", "526"), ts); - return new ISMTransition(planned, null, null, ts); + DvCodedText planned = new DvCodedText("planned e state", lang, charset, + new CodePhrase("openehr", "526"), ts); + return new ISMTransition(planned, null, null, null, ts); } - - private History event() throws Exception { + + private History event() throws Exception { List> items = new ArrayList>(); items.add(pointEvent()); return new History(null, "at0002", text("history"), - null, null, null, null, new DvDateTime("2006-07-12T09:22:00"), - items, DvDuration.getInstance("PT1h"), + null, null, null, null, new DvDateTime("2006-07-12T09:22:00"), + items, DvDuration.getInstance("PT1h"), DvDuration.getInstance("PT3h"), null); } private Event pointEvent() throws Exception { - return new PointEvent(null, "at0003", text("point event"), - null, null, null, null, new DvDateTime("2006-07-12T08:00:00"), + return new PointEvent(null, "at0003", text("point event"), + null, null, null, null, new DvDateTime("2006-07-12T08:00:00"), itemSingle(), null); } } diff --git a/rm-builder/src/test/java/org/openehr/build/FindMatchingRMClassTest.java b/rm-builder/src/test/java/org/openehr/build/FindMatchingRMClassTest.java old mode 100755 new mode 100644 diff --git a/rm-skeleton/hypersensitivity_drug.dadl b/rm-skeleton/hypersensitivity_drug.dadl old mode 100755 new mode 100644 diff --git a/rm-skeleton/hypersensitivity_drug_sulfa.dadl b/rm-skeleton/hypersensitivity_drug_sulfa.dadl old mode 100755 new mode 100644 diff --git a/rm-skeleton/hypersensitivity_food_milk.dadl b/rm-skeleton/hypersensitivity_food_milk.dadl old mode 100755 new mode 100644 diff --git a/rm-skeleton/hypersensitivity_max.dadl b/rm-skeleton/hypersensitivity_max.dadl deleted file mode 100755 index 0694390f..00000000 --- a/rm-skeleton/hypersensitivity_max.dadl +++ /dev/null @@ -1,136 +0,0 @@ -(EVALUATION) < - archetype_details = (ARCHETYPED) < - archetype_id = (ARCHETYPE_ID) < - value = <"openEHR-EHR-EVALUATION.hypersensitivity.v1"> - > - rm_version = <"1.0.1"> - > - archetype_node_id = <"openEHR-EHR-EVALUATION.hypersensitivity.v1"> - data = (ITEM_TREE) < - archetype_node_id = <"at0001"> - items = < - [1] = (ELEMENT) < - archetype_node_id = <"at0002"> - name = (DV_TEXT) < - value = <"Type"> - > - value = (DV_CODED_TEXT) < - defining_code = (CODE_PHRASE) < - code_string = <"at0004"> - terminology_id = (TERMINOLOGY_ID) < - value = <"local"> - > - > - value = <"Drug"> - > - > - [2] = (ELEMENT) < - archetype_node_id = <"at0003"> - name = (DV_TEXT) < - value = <"Heading"> - > - value = (DV_TEXT) < - value = <"text value"> - > - > - [3] = (ELEMENT) < - archetype_node_id = <"at0009"> - name = (DV_TEXT) < - value = <"Agent"> - > - value = (DV_TEXT) < - value = <"text value"> - > - > - [4] = (ELEMENT) < - archetype_node_id = <"at0010"> - name = (DV_TEXT) < - value = <"Comment"> - > - value = (DV_TEXT) < - value = <"text value"> - > - > - [5] = (ELEMENT) < - archetype_node_id = <"at0011"> - name = (DV_TEXT) < - value = <"Severity level"> - > - value = (DV_ORDINAL) < - symbol = (DV_CODED_TEXT) < - defining_code = (CODE_PHRASE) < - code_string = <"at0012"> - terminology_id = (TERMINOLOGY_ID) < - value = <"local"> - > - > - value = <"Life threatening"> - > - value = <1> - > - > - [6] = (ELEMENT) < - archetype_node_id = <"at0015"> - name = (DV_TEXT) < - value = <"Assertion level"> - > - value = (DV_ORDINAL) < - symbol = (DV_CODED_TEXT) < - defining_code = (CODE_PHRASE) < - code_string = <"at0016"> - terminology_id = (TERMINOLOGY_ID) < - value = <"local"> - > - > - value = <"Confirmed"> - > - value = <1> - > - > - [7] = (ELEMENT) < - archetype_node_id = <"at0019"> - name = (DV_TEXT) < - value = <"Is reassessment required"> - > - value = (DV_BOOLEAN) < - value = <"true"> - > - > - [8] = (ELEMENT) < - archetype_node_id = <"at0020"> - name = (DV_TEXT) < - value = <"Reassessment date"> - > - value = (DV_DATE_TIME) < - value = <"2010-01-01T10:00:00"> - > - > - > - name = (DV_TEXT) < - value = <"Träd"> - > - > - encoding = (CODE_PHRASE) < - code_string = <"UTF-8"> - terminology_id = (TERMINOLOGY_ID) < - value = <"IANA_character-sets"> - > - > - language = (CODE_PHRASE) < - code_string = <"en"> - terminology_id = (TERMINOLOGY_ID) < - value = <"ISO_639-1"> - > - > - name = (DV_TEXT) < - value = <"Hypersensitivity"> - > - subject = (PARTY_SELF) < - external_ref = (PARTY_REF) < - id = (HIER_OBJECT_ID) < - value = <"1.2.4.5.6.12.1"> - > - type = <"PARTY"> - > - > -> diff --git a/rm-skeleton/hypersensitivity_maximum.dadl b/rm-skeleton/hypersensitivity_maximum.dadl old mode 100755 new mode 100644 diff --git a/rm-skeleton/hypersensitivity_min.dadl b/rm-skeleton/hypersensitivity_min.dadl deleted file mode 100755 index 0694390f..00000000 --- a/rm-skeleton/hypersensitivity_min.dadl +++ /dev/null @@ -1,136 +0,0 @@ -(EVALUATION) < - archetype_details = (ARCHETYPED) < - archetype_id = (ARCHETYPE_ID) < - value = <"openEHR-EHR-EVALUATION.hypersensitivity.v1"> - > - rm_version = <"1.0.1"> - > - archetype_node_id = <"openEHR-EHR-EVALUATION.hypersensitivity.v1"> - data = (ITEM_TREE) < - archetype_node_id = <"at0001"> - items = < - [1] = (ELEMENT) < - archetype_node_id = <"at0002"> - name = (DV_TEXT) < - value = <"Type"> - > - value = (DV_CODED_TEXT) < - defining_code = (CODE_PHRASE) < - code_string = <"at0004"> - terminology_id = (TERMINOLOGY_ID) < - value = <"local"> - > - > - value = <"Drug"> - > - > - [2] = (ELEMENT) < - archetype_node_id = <"at0003"> - name = (DV_TEXT) < - value = <"Heading"> - > - value = (DV_TEXT) < - value = <"text value"> - > - > - [3] = (ELEMENT) < - archetype_node_id = <"at0009"> - name = (DV_TEXT) < - value = <"Agent"> - > - value = (DV_TEXT) < - value = <"text value"> - > - > - [4] = (ELEMENT) < - archetype_node_id = <"at0010"> - name = (DV_TEXT) < - value = <"Comment"> - > - value = (DV_TEXT) < - value = <"text value"> - > - > - [5] = (ELEMENT) < - archetype_node_id = <"at0011"> - name = (DV_TEXT) < - value = <"Severity level"> - > - value = (DV_ORDINAL) < - symbol = (DV_CODED_TEXT) < - defining_code = (CODE_PHRASE) < - code_string = <"at0012"> - terminology_id = (TERMINOLOGY_ID) < - value = <"local"> - > - > - value = <"Life threatening"> - > - value = <1> - > - > - [6] = (ELEMENT) < - archetype_node_id = <"at0015"> - name = (DV_TEXT) < - value = <"Assertion level"> - > - value = (DV_ORDINAL) < - symbol = (DV_CODED_TEXT) < - defining_code = (CODE_PHRASE) < - code_string = <"at0016"> - terminology_id = (TERMINOLOGY_ID) < - value = <"local"> - > - > - value = <"Confirmed"> - > - value = <1> - > - > - [7] = (ELEMENT) < - archetype_node_id = <"at0019"> - name = (DV_TEXT) < - value = <"Is reassessment required"> - > - value = (DV_BOOLEAN) < - value = <"true"> - > - > - [8] = (ELEMENT) < - archetype_node_id = <"at0020"> - name = (DV_TEXT) < - value = <"Reassessment date"> - > - value = (DV_DATE_TIME) < - value = <"2010-01-01T10:00:00"> - > - > - > - name = (DV_TEXT) < - value = <"Träd"> - > - > - encoding = (CODE_PHRASE) < - code_string = <"UTF-8"> - terminology_id = (TERMINOLOGY_ID) < - value = <"IANA_character-sets"> - > - > - language = (CODE_PHRASE) < - code_string = <"en"> - terminology_id = (TERMINOLOGY_ID) < - value = <"ISO_639-1"> - > - > - name = (DV_TEXT) < - value = <"Hypersensitivity"> - > - subject = (PARTY_SELF) < - external_ref = (PARTY_REF) < - id = (HIER_OBJECT_ID) < - value = <"1.2.4.5.6.12.1"> - > - type = <"PARTY"> - > - > -> diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index ab0b199f..cbf0d405 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -2,9 +2,9 @@ 4.0.0 - openehr - ref_impl_java - 1.0.5-SNAPSHOT + org.openehr.java-libs + java-libs + 0-SNAPSHOT rm-skeleton jar @@ -12,52 +12,52 @@ - openehr + org.openehr.java-libs openehr-rm-core ${project.version} - openehr + org.openehr.java-libs openehr-rm-domain ${project.version} - openehr + org.openehr.java-libs openehr-aom ${project.version} - openehr + org.openehr.java-libs adl-parser ${project.version} - openehr + org.openehr.java-libs dadl-parser ${project.version} - openehr + org.openehr.java-libs oet-parser ${project.version} - openehr + org.openehr.java-libs measure-serv ${project.version} - openehr + org.openehr.java-libs mini-termserv ${project.version} - openehr + org.openehr.java-libs dadl-binding ${project.version} - openehr + org.openehr.java-libs xml-binding ${project.version} @@ -74,7 +74,7 @@ test - openehr + org.openehr.java-libs adl-serializer ${project.version} test diff --git a/rm-skeleton/src/main/java/org/openehr/rm/util/GenerationStrategy.java b/rm-skeleton/src/main/java/org/openehr/rm/util/GenerationStrategy.java old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/main/java/org/openehr/rm/util/RMUtil.java b/rm-skeleton/src/main/java/org/openehr/rm/util/RMUtil.java old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/main/java/org/openehr/rm/util/SkeletonGenerator.java b/rm-skeleton/src/main/java/org/openehr/rm/util/SkeletonGenerator.java index a47c20f4..8f3be898 100755 --- a/rm-skeleton/src/main/java/org/openehr/rm/util/SkeletonGenerator.java +++ b/rm-skeleton/src/main/java/org/openehr/rm/util/SkeletonGenerator.java @@ -571,14 +571,7 @@ public Object createAttribute(CAttribute cattribute, Archetype archetype, log.debug("multiple attribute.."); CMultipleAttribute cma = (CMultipleAttribute) cattribute; - Collection container; - if(cma.getCardinality().isList()) { - container = new ArrayList(); - - } else { - // default container type - container = new ArrayList(); - } + Collection container = new ArrayList(); for(CObject cobj : children) { log.debug("looping children, required: " + cobj.isRequired()); @@ -645,6 +638,11 @@ public Object createObject(CObject cobj, Archetype archetype, } else if(cobj instanceof CDomainType) { return createDomainTypeObject((CDomainType) cobj, archetype); + + } else if(cobj instanceof ArchetypeInternalRef){ + //fix for multiple events where the data attribute of the events is an InternalRef to the first event described + return createArchetypeInternalRefObject((ArchetypeInternalRef) cobj, archetype, + archetypeMap,extraValues, strategy); } else { // TODO skip archetype_slot etc, log.warn? @@ -652,6 +650,16 @@ public Object createObject(CObject cobj, Archetype archetype, } } + //fix for multiple events where the data attribute of the events is an InternalRef to the first event described + private Object createArchetypeInternalRefObject(ArchetypeInternalRef cobj, Archetype archetype, + Map archetypeMap, Map extraValues, + GenerationStrategy strategy) throws Exception{ + + CObject cobjRef = (CObject) archetype.node(cobj.getTargetPath()); + + return createObject(cobjRef, archetype,archetypeMap, extraValues, strategy) ; + } + private Object createPrimitiveTypeObject(CPrimitiveObject cpo, Archetype archetype) throws Exception { @@ -686,11 +694,11 @@ private Object createPrimitiveTypeObject(CPrimitiveObject cpo, Archetype archety } else if(cp instanceof CInteger) { - return new Integer(0); + return Integer.valueOf(0); } else if(cp instanceof CReal) { - return new Double(0); + return Double.valueOf(0); } else if(cp instanceof CDuration) { @@ -769,7 +777,7 @@ private DvOrdinal createDvOrdinal(CDvOrdinal cdo, Archetype archetype) return new DvOrdinal(o.getValue(), new DvCodedText(DEFAULT_CODED_TEXT, o.getSymbol())); } - Set list = cdo.getList(); + List list = cdo.getList(); if(list == null || list.size() == 0) { throw new Exception("empty list of ordinal"); } diff --git a/rm-skeleton/src/test/java/org/openehr/rm/util/CodedTextTest.java b/rm-skeleton/src/test/java/org/openehr/rm/util/CodedTextTest.java old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/java/org/openehr/rm/util/GenerateHypersensitivityTest.java b/rm-skeleton/src/test/java/org/openehr/rm/util/GenerateHypersensitivityTest.java old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/java/org/openehr/rm/util/GenerateNestedSectionsTest.java b/rm-skeleton/src/test/java/org/openehr/rm/util/GenerateNestedSectionsTest.java old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/java/org/openehr/rm/util/OrdinalTest.java b/rm-skeleton/src/test/java/org/openehr/rm/util/OrdinalTest.java old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/java/org/openehr/rm/util/RMUtilTest.java b/rm-skeleton/src/test/java/org/openehr/rm/util/RMUtilTest.java old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/java/org/openehr/rm/util/RootNodeNameTest.java b/rm-skeleton/src/test/java/org/openehr/rm/util/RootNodeNameTest.java old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/java/org/openehr/rm/util/SimpleDvMultimediaTest.java b/rm-skeleton/src/test/java/org/openehr/rm/util/SimpleDvMultimediaTest.java old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/java/org/openehr/rm/util/SkeletonGeneratorTestBase.java b/rm-skeleton/src/test/java/org/openehr/rm/util/SkeletonGeneratorTestBase.java old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/java/org/openehr/rm/util/TemplateIdTest.java b/rm-skeleton/src/test/java/org/openehr/rm/util/TemplateIdTest.java old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/java/org/openehr/rm/util/TestActions.java b/rm-skeleton/src/test/java/org/openehr/rm/util/TestActions.java old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/java/org/openehr/rm/util/TestEvents.java b/rm-skeleton/src/test/java/org/openehr/rm/util/TestEvents.java new file mode 100644 index 00000000..1aea7112 --- /dev/null +++ b/rm-skeleton/src/test/java/org/openehr/rm/util/TestEvents.java @@ -0,0 +1,25 @@ +package org.openehr.rm.util; + +import org.openehr.rm.composition.content.entry.Observation; + +public class TestEvents extends SkeletonGeneratorTestBase { + + public TestEvents() throws Exception { + + } + + public void testWithApgarScoreArchetype_PointEvent() throws Exception { + archetype = loadArchetype("openEHR-EHR-OBSERVATION.apgar.v1.adl"); + instance = generator.create(archetype, GenerationStrategy.MAXIMUM); + assertTrue("failed to create Action instance", instance instanceof Observation); + } + + /* + public void testWithBloodPressureArchetype_Interval() throws Exception { + archetype = loadArchetype("openEHR-EHR-OBSERVATION.blood_pressure.v1.adl"); + instance = generator.create(archetype, GenerationStrategy.MAXIMUM); + assertTrue("failed to create Action instance", instance instanceof Observation); + } + */ + +} \ No newline at end of file diff --git a/rm-skeleton/src/test/java/org/openehr/rm/util/TestFlattenedTemplate.java b/rm-skeleton/src/test/java/org/openehr/rm/util/TestFlattenedTemplate.java old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/java/org/openehr/rm/util/TestItemTreeGeneration.java b/rm-skeleton/src/test/java/org/openehr/rm/util/TestItemTreeGeneration.java old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/java/org/openehr/rm/util/TestObservations.java b/rm-skeleton/src/test/java/org/openehr/rm/util/TestObservations.java old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/java/org/openehr/rm/util/TestStrategy.java b/rm-skeleton/src/test/java/org/openehr/rm/util/TestStrategy.java old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/java/org/openehr/rm/util/UtilityTest.java b/rm-skeleton/src/test/java/org/openehr/rm/util/UtilityTest.java old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-ACTION.medication.v1.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ACTION.medication.v1.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-EVALUATION.hypersensitivity.v1.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-EVALUATION.hypersensitivity.v1.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-INSTRUCTION.medication.v1.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-INSTRUCTION.medication.v1.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.blood_pressure.v1.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.blood_pressure.v1.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication.v1.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication.v1.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_eight.v1.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_eight.v1.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_five.v1.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_five.v1.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_four.v1.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_four.v1.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_nine.v1.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_nine.v1.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_one.v1.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_one.v1.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_seven.v1.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_seven.v1.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_six.v1.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_six.v1.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_three.v1.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_three.v1.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_two.v1.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_two.v1.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.apgar.v1.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.apgar.v1.adl new file mode 100644 index 00000000..64a5a7d5 --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.apgar.v1.adl @@ -0,0 +1,1422 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.apgar.v1 + +concept + [at0000] -- Apgar score +language + original_language = <[ISO_639-1::en]> + translations = < + ["fa"] = < + language = <[ISO_639-1::fa]> + author = < + ["name"] = <"Shahla Foozonkhah"> + ["organisation"] = <"Ocean Informatics"> + ["email"] = <"Shahla.foozonkhah@oceanInformatics.com"> + > + > + ["de"] = < + language = <[ISO_639-1::de]> + author = < + ["name"] = <"Jasmin Buck, Sebastian Garde, Thilo Schuler"> + ["organisation"] = <"University of Heidelberg, Central Queensland University, Ocean Informatics"> + > + > + ["nl"] = < + language = <[ISO_639-1::nl]> + author = < + ["name"] = <"Marja Buur"> + ["organisation"] = <"Medisch Centrum Alkmaar"> + ["email"] = <"m.buur-krom@mca.nl"> + > + accreditation = <"Erna Vreeke"> + > + ["pt-br"] = < + language = <[ISO_639-1::pt-br]> + author = < + ["name"] = <"Jussara Rötzsch"> + ["organisation"] = <"OpenEHR Foundation"> + > + accreditation = <"Medical Doctor, Psychiatrist, Clinical Modeler, OpenEHR Director, Coordinator of WG ehealth infostructure of brazilian e-health program"> + > + ["es-cl"] = < + language = <[ISO_639-1::es-cl]> + author = < + ["name"] = <"Sergio Carmona"> + > + > + ["ar-sy"] = < + language = <[ISO_639-1::ar-sy]> + author = < + ["name"] = <"Mona Saleh"> + > + > + ["ru"] = < + language = <[ISO_639-1::ru]> + author = < + ["name"] = <"Igor Lizunov"> + ["email"] = <"i.lizunov@infinnity.ru"> + > + > + > +description + original_author = < + ["name"] = <"Sam Heard"> + ["organisation"] = <"Ocean Informatics"> + ["email"] = <"sam.heard@oceaninformatics.com"> + ["date"] = <"2004-05-18"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"Records the Apgar score as a simple, repeatable method to document the state of the newborn infant immediately after birth. +The root time of the event series is always birth."> + use = <"Allows recording of an assessment of the state of a neonate explicitly as 1, 2, 3, 5 and/or 10 minute events after birth, plus additional events as required. +Usual practice is to document the Apgar score at 1 and 5 minutes; further scores can be recorded as clinically indicated. It is possible to record the Apgar score at any time after birth using this archetype. +Common clinical practice is to record all 5 parameters plus the total, however this archetype allows any partial information to be recorded, if that is all that is available eg from historical data. +If the total is to be calculated, it is necessary for all 5 ordinal values to be recorded. The total is the sum of the five ordinal values (min 0, max 10). + +It is recognised that mnemonic learning aid for APGAR is commonly taught. For example, in English: A for Appearance (skin color), P for Pulse (heart rate), G for Grimace (reflex irritability), A for Activity (muscle tone), and R for Respiration. As this is not universally applicable for all languages, it is suggested that this mnemonic can be applied by renaming the data elements within templates if desired for a specific clinical scenario."> + keywords = <"newborn", "index", "score", "birth", "infant", "neonate", "assessment"> + misuse = <"Partially complete score and add the 5 to give the total values​​."> + copyright = <"© openEHR Foundation"> + > + ["es-cl"] = < + language = <[ISO_639-1::es-cl]> + purpose = <"Registrar el índice del Apgar o la valoración del recién nacido. El tiempo inicial de medida de la serie de eventos es siempre la hora de nacimiento."> + use = <"Permite registrar el bienestar del neonato al 1,2,5 y o 10 minutos después del nacimiento. Se puede registrar sólo el total - si es todo lo que está disponible - aúnque se deben completar los cinco valores númericos para que pueda ser calculado el total. El total es la suma de los cinco valores númericos (el mínimo 0, el máximo 10)."> + keywords = <"score", "apgar", "index", "recién nacido"> + misuse = <"Completar el score parcialmente y no sumar los 5 valores para dar el total."> + copyright = <"© openEHR Foundation"> + > + ["de"] = < + language = <[ISO_639-1::de]> + purpose = <"Zur Dokumentation des Apgar Wertes als eine einfache, nachvollziehbare Methode zur Dokumentation des Status eines Neugeborenen direkt nach der Geburt. Der zu Grunde liegende Zeitpunkt der Ereignisreihe ist immer die Geburt."> + use = <"Ermöglicht die Dokumentation des Wohlergehens des Säuglings 1, 2, 3, 5 und/oder 10 Minuten nach der Geburt, sowie zu anderen Zeitpunkten bei Bedarf. +Normale Praxis ist es, den Apgar Wert 1 und 5 Minuten nach der Geburt zu dokumentieren, weitere Werte können je nach klinischer Indikation ergänzt werden. Mit diesem Archetype ist es möglich, den Apgar Wert zu jedem Zeitpunkt nach der Geburt zu dokumentieren. +Normale klinische Praxis ist es, alle 5 Parameter und den Gesamtwert zu dokumentieren, jedoch erlaubt dieser Archetyp die Dokumentation einer beliebigen Untermenge, wenn z.B. aus Altdaten nicht mehr verfügbar ist. +Wenn der Gesamtwert errechnet werden soll, müssen Werte für alle 5 Komponenten dokumentiert werden. Der Geamtwert ergibt sich dann aus der Summe der fünf Einzelwerte (minimal: 0, maximal: 10), + +Häufig werden mnemonische Merkhilfen für APGAR gelehrt. Z.B. in Englisch: A für Appearance (Hautfarbe), P für Pulse (Herzfrequenz), G für Grimace (Reflexauslösbarkeit), A für Activity (Muskeltonus), und R für Respiration (Atmung). Da dies nicht generell in allen Sprachen anwendbar ist, wird empfohlen, dass solche Merkhilfen durch Umbenennung innerhalb von Templates erstellt werden können, wenn dies für ein bestimmtes klinisches Szenario erwünscht ist."> + keywords = <"Neugeborenes", "Index", "Score", "Geburt", "Säugling", "neonatal", "Beurteilung"> + misuse = <"Completar el score parcialmente y no sumar los 5 valores para dar el total."> + copyright = <"© openEHR Foundation"> + > + ["fa"] = < + language = <[ISO_639-1::fa]> + purpose = <"برای ثبت نمره آپگار به عنوان روشی ساده و قابل تکرار در اسناد حالت نوزاد بلافاصله بعد از تولد بکار می رود +زمان اصلی سری رویدادها همیشه زمان تولد است "> + use = <" ثبت ارزیابی حالت نوزاد را بطور آشکار در دقایق یک ، دو ، سه و پنج و یا ده بعد تولد بعلاوه رویدادهای بیشتر در صورت نیاز را امکان پذیر می کند +عملکرد معمول ثبت نمره آپگار در دقایق یک و پنج است ، نمرات بیشتر را می توان در صورت نیاز بالینی می توان ثبت نمود با این الگو ساز ثبت نمره آپگار در عر لحظه بعد از تولد امگان پذیر است +عملکرد مشترک بالینی ثبت کلیه پنج پارامتر به علاوه کل است اما در صورتی که همه اطلاعات در دسترس باشند، این الگو ساز امکان ثبت هر گونه اطلاعات جزیی را امکان پذیر می کند به عنوان مثال داد های بیمارستانی +در صورتی که کل نمره باید محاسبه شود باید کلیه ارزشها ی ترتیبی ثبت شوند . کل مجموع پنج ارزش ترتیبی حداقل صفرو حداکثر ده می باشد +مشحص شده است که یادگیری حافظه ای آپکار معمولا تدریس می شودبرای مثال در انگلیس حرف \"ا\" برای ظاهر (رنگ پوست)و حرف \"پ\" برای نبض (میزان قلبی) ، حرف \"جی \" برای شکلک(رفلکس تحریک پذیری) ، حرف \"ا\" برای فعالیت (تون عضلانی ) و حرف \"ر\" برای تنفس استفاده می شود.گرچه این مورد برای تمام زبانها و بطور کلی قابل کاربرد نیست ، پیشنهاد می شود که در صورت تمایل در سناریوهای بالینی خاص ،یادگیری حافظه ای می تواند با نامگذاری مجدد عناصر داده ای در داخل الگو بکار رود"> + keywords = <"تازه بدنیا آمده", "شاخص", "نمره", "تولد", "شیر خوار", "نوزاد", "ارزیابی"> + misuse = <"Completar el score parcialmente y no sumar los 5 valores para dar el total."> + copyright = <"© openEHR Foundation"> + > + ["ar-sy"] = < + language = <[ISO_639-1::ar-sy]> + purpose = <"تسجيل حرز أبغار كطريقة بسيطة متكررة لتوثيق حالة الرضيع حديث الولادة بعد الولادة/ الوضع مباشرة. +الوقت الجذري لهذه السلسة من الوقائع هي دائما الولادة/الوضع"> + use = <"يسمح بتسجيل تقييم حالة حديث الولادة بشكل صريح عند وقائع زمنية بالتحديد هي 1, 2, 3, 5 و/أو 10 دقائق بعد الولادة/الوضع, بالإضافة إلى أي وقائع إضافية حسب الحاجة. + +تتضمن الممارسة المعتادة تسجيل حرز أبغار عند 1 و 5 دقائق, و يمكن تسجيل أحراز أخرى حسب الحاجة السريرية. و من الممكن تسجيل حرز أبغار عند أي نقطة زمنية بعد الولادة باستخدام هذا النموذج. + +تقتضي الممارسة السريرية المعتادة تسجيل الـ 5 معايير بالإضافة إلى الإجمالي, إلا أن هذا النموذج يسمح بتسجيل أي معلمات جزئية, إذا كان هذا هو المتاح, مثل التسجيل من بيانات تاريخية. + +إذا كان لابد من حساب الإجمالي, فإنه من الضروري لجميع الـ 5 قيم أن يتم تسجيلها. الإجمالي هو مجموع القيم المنفردة الخمسة - الحد الأدنى هو 0 و الحد الأقصى هو 10 + +و من المعروف أن كلمة أبغار تضم الأحرف الأولى للمعايير التي يتم قياسها - باللغة الإنجليزية. و هي تكافئ المظهر (لون الجلد/البشرة), و النبض (معدل القلب), و التكشيرة (التوتر الانعكاسي) و النشاط (توتر العضلات) و التنفس. +و حيث إن ذلك ليس قابلا للتطبيق حرفيا على اللغات الأخرى, فينبغي تطبيق هذا الاختصار بإعادة تسمية العناصر في داخل القوالب إذا كان من المرغوب في سيناريو سريري مُعيَّن. +"> + keywords = <"حديث الولادة", "معامل", "الحرز", "الولادة/الوضع", "الرضيع", "حديث الولادة", "تقييم"> + misuse = <"Completar el score parcialmente y no sumar los 5 valores para dar el total."> + copyright = <"© openEHR Foundation"> + > + ["ru"] = < + language = <[ISO_639-1::ru]> + purpose = <"Запись оценки по шкале Апгар - простой, повторяемый метод оценки состояния новорожденного сразу после рождения. +Первая оценка производится сразу после рождения, далее может быть серия повторных."> + use = <"Позволяет записывать состояние новорожденного по шкале Апгар на 1, 2, 3, 4, 5 и / или 10 минуту после рождения, плюс дополнительно в более поздние сроки, если требуется +Обычно практикуется документирование состояния новорожденного по Апгар на 1 и 5 минуте, друге оценки могут быть записаны по клиническим показаниям. +Этот архетип позволяет записывать оценку по шкале Апгар в любое время после рождения. +В общеклинической практике записывают 5 параметров плюс общую оценку, однако этот архетип позволяет вносить информацию частичное, если требуется, для формирования истории данных. +Если общая оценка считается, то необходимо записать все 5 обычно используемых признаков. Общая оценка получается суммированием 5 обычных значений (мин 0, макс 10)."> + keywords = <"новорожденный", "оценка", "балл", "младенец", "оценка состояния"> + misuse = <"Completar el score parcialmente y no sumar los 5 valores para dar el total."> + copyright = <"© openEHR Foundation"> + > + ["nl"] = < + language = <[ISO_639-1::nl]> + purpose = <"Registreren van de Apgar score; een eenvoudige, te herhalen score, om de toestand van de pasgeborene onmiddelijk na de geboorte te documenteren."> + use = <"Staat registratie toe van de beoordeling van de toestand van een pasgeborene, op 1, 2, 3, 5, en/of 10 minuten na de geboorte, plus toegevoegde gebeurtenissen, indien gewenst. +Gewoonlijk wordt de Apgar score na 1 en 5 minuten gedaan, meerdere scores kunnen geregistreerd worden als dat klinisch geïndiceerd is. Het is bij gebruik van dit archetype mogelijk de Apgar score op ieder gewenst moment na de geboorte te registreren. +Algemeen klinische praktijk is om alle 5 parameters plus het totaal te registreren, maar in dit archtype kan iedere gedeeltelijke informatie opgeslagen worden, dat beschikbaar is in b.v. historische data. Als het totaal berekend wordt, is het noodzakelijk dat alle 5 parameters als waarde geregistreerd worden. Het totaal is de som van de 5 waardes (min 0, max 10). +Erkend wordt dat er gewoonlijk een ezelsbruggetje word gebruikt bij het aanleren van de Apgar score. Bijvoorbeeld: Appearance (kleur), Pulse (hartslag), Grimace (reactie op prikkels), Activity (spiertonus) en Respiration (ademhaling). Dit is niet universeel bruikbaar voor alle talen, gesuggereerd wordt dat dit geheugensteuntje kan worden toegepast door het hernoemen van de data elementen binnen templates, indien gewenst voor een specifiek klinisch scenario."> + keywords = <"pasgeborene", "index", "score", "geboorte", "kind", "neonaat", "beoordeling", "baby"> + misuse = <"Completar el score parcialmente y no sumar los 5 valores para dar el total."> + copyright = <"© openEHR Foundation"> + > + ["pt-br"] = < + language = <[ISO_639-1::pt-br]> + purpose = <"Registra a escala de Apgar como um método simples e reproduzível de documentar o estado de saúde do recém-nato imediatamente após o nascimento"> + use = <"Permite o registro de uma avaliação do estado de saúde de um recém-nascido explicitamente em eventos a 1, 2, 3, 5 e/ou 10 minutos depois do nascimento, e outros eventos adicionais se requeridos. +Geralmente se documenta os escores obtidos nos primeiro e quinto minutos na escala de Apgar, os demais podem ser registrados se tiver indicação clínica. É possível registrar o escore Apgar a qualquer tempo após o nascimento usando esse arquétipo. +A prática clínica comum é registrar todos os cinco parâmetros, mais o resultado global, entretanto esse arquétipo permite que qualquer informação parcial seja registrada, se for essa a única informação disponível, por exemplo, no histórico do paciente. +O total só pode ser calculado se os cinco valores ordinais forem registrados. O total é a soma dos cinco valores ordinais (min0, max 10). + +Se reconhece que uma ajuda mnemônica para aprender a interpretar o escore Apgar é comumente ensinada. Em Português, por exemplo: A para Aparência (cor da pele), P para pulso ( frequência cardíaca), G para Contração do rosto (grimace-fr); A para atividade (tônus muscular) e R pra Respiração. Embora não seja aplicável em todas as línguas, se sugere que se possa utilizar esse mnemônico para renomear os elementos de dados dentro dos templates se desejado para um cenário clínico específico."> + keywords = <"*recém-nascido(s), recém-nato(s)", "*índice", "*escore, escala", "*nascimento(s),", "*bebê(s)", "*neonato(s)", "*avaliação(ões)"> + misuse = <"Escore parcialmente completado e adicionar o 5 para obter o valor total."> + copyright = <"© openEHR Foundation"> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <"Paul Donaldson, Nursing Informatics Australia, Australia", "Sebastian Garde, Ocean Informatics, Germany (Editor)", "Anneke Goossen, Results 4 Care, Netherlands", "Anne Harbison, CPCER, Australia", "Sam Heard, Ocean Informatics, Australia", "Omer Hotomaroglu, Turkey", "Pieter Hummel, Medisch Centrum Alkmaar, Netherlands", "Andrew James, University of Toronto, Canada", "Heather Leslie, Ocean Informatics, Australia (Editor)", "Ian McNicoll, Ocean Informatics, United Kingdom (Editor)"> + other_details = < + ["references"] = <"Apgar V. A proposal of a New Method of Evaluation of the Newborn Infant. Curr Res Anesth Analg. 1953 Jul-Aug;32(4):260-7. + +Apgar V, Holaday DA, James LS, Weisbrod IM, and Berrien C. Evaluation of the newborn infant; second report. J Am Med Assoc. 1958 Dec 13;168(15):1985-8. + +Apgar V. The newborn (Apgar) scoring system. Pediatr Clin North Am. 1966 Aug;13(3):645-50. + +Whaley LF, Wong DL (1979). Nursing Care of Infants and Children. St. Louis, Toronto, London, The C.V. Mosby Company. + +http://en.wikipedia.org/wiki/Apgar_score"> + ["MD5-CAM-1.0.1"] = <"372512F41A8EE08D313FA66BA2AF3039"> + > + +definition + OBSERVATION[at0000] matches { -- Apgar score + data matches { + HISTORY[at0002] matches { -- history + events cardinality matches {1..*; unordered} matches { + POINT_EVENT[at0003] occurrences matches {0..1} matches { -- 1 minute + offset matches { + DV_DURATION matches { + value matches {|PT1M|} + } + } + data matches { + ITEM_LIST[at0001] matches { -- structure + items cardinality matches {1..6; ordered} matches { + ELEMENT[at0009] occurrences matches {0..1} matches { -- Respiratory effort + value matches { + 0|[local::at0010], -- Absent + 1|[local::at0011], -- Weak or irregular + 2|[local::at0012] -- Normal + } + } + ELEMENT[at0005] occurrences matches {0..1} matches { -- Heart Rate + value matches { + 0|[local::at0006], -- Absent + 1|[local::at0007], -- <100 beats per minute + 2|[local::at0008] -- ≥100 beats per minute + } + } + ELEMENT[at0013] occurrences matches {0..1} matches { -- Muscle tone + value matches { + 0|[local::at0014], -- Limp or flaccid + 1|[local::at0015], -- Reduced tone + 2|[local::at0016] -- Normal tone + } + } + ELEMENT[at0017] occurrences matches {0..1} matches { -- Reflex irritability + value matches { + 0|[local::at0018], -- No response + 1|[local::at0019], -- Reduced response + 2|[local::at0020] -- Normal response + } + } + ELEMENT[at0021] occurrences matches {0..1} matches { -- Skin colour + value matches { + 0|[local::at0022], -- Completely blue + 1|[local::at0023], -- Body pink; extremities blue + 2|[local::at0024] -- Completely pink + } + } + ELEMENT[at0025] occurrences matches {0..1} matches { -- Total + value matches { + DV_COUNT matches { + magnitude matches {|0..10|} + } + } + } + } + } + } + } + POINT_EVENT[at0026] occurrences matches {0..1} matches { -- 2 minute + offset matches { + DV_DURATION matches { + value matches {|PT2M|} + } + } + data matches { + use_node ITEM_LIST /data[at0002]/events[at0003]/data[at0001] -- /data[history]/events[1 minute]/data[structure] + } + } + POINT_EVENT[at0027] occurrences matches {0..1} matches { -- 3 minute + offset matches { + DV_DURATION matches { + value matches {|PT3M|} + } + } + data matches { + use_node ITEM_LIST /data[at0002]/events[at0003]/data[at0001] -- /data[history]/events[1 minute]/data[structure] + } + } + POINT_EVENT[at0028] occurrences matches {0..1} matches { -- 5 minute + offset matches { + DV_DURATION matches { + value matches {|PT5M|} + } + } + data matches { + use_node ITEM_LIST /data[at0002]/events[at0003]/data[at0001] -- /data[history]/events[1 minute]/data[structure] + } + } + POINT_EVENT[at0031] occurrences matches {0..1} matches { -- 10 minute + offset matches { + DV_DURATION matches { + value matches {|PT10M|} + } + } + data matches { + use_node ITEM_LIST /data[at0002]/events[at0003]/data[at0001] -- /data[history]/events[1 minute]/data[structure] + } + } + EVENT[at0037] occurrences matches {0..*} matches { -- Any event + data matches { + use_node ITEM_LIST /data[at0002]/events[at0003]/data[at0001] -- /data[history]/events[1 minute]/data[structure] + } + } + } + } + } + protocol matches { + ITEM_LIST[at0029] matches { -- List + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0030] occurrences matches {0..1} matches { -- Notes on measurement + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + + +ontology + terminologies_available = <"SNOMED-CT", "LOINC"> + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Apgar score"> + description = <"Clinical score derived from assessment of respiratory effort, heart rate, reflex irritability, muscle tone and skin colour."> + > + ["at0001"] = < + text = <"structure"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"history"> + description = <"@ internal @"> + > + ["at0003"] = < + text = <"1 minute"> + description = <"Apgar score 1 minute after birth."> + > + ["at0005"] = < + text = <"Heart Rate"> + description = <"Recording of the infant's heart rate."> + > + ["at0006"] = < + text = <"Absent"> + description = <"No heart beat is seen, felt or heard."> + > + ["at0007"] = < + text = <"<100 beats per minute"> + description = <"Heart rate less than 100 beats per minute."> + > + ["at0008"] = < + text = <"≥100 beats per minute"> + description = <"Heart rate greater than or equal to 100 beats per minute."> + > + ["at0009"] = < + text = <"Respiratory effort"> + description = <"Observation of the infant's respiratory effort."> + > + ["at0010"] = < + text = <"Absent"> + description = <"No effort to breath."> + > + ["at0011"] = < + text = <"Weak or irregular"> + description = <"Some effort to breath, moving chest."> + > + ["at0012"] = < + text = <"Normal"> + description = <"Breathing normally or crying."> + > + ["at0013"] = < + text = <"Muscle tone"> + description = <"Observation of the infant's muscle tone."> + > + ["at0014"] = < + text = <"Limp or flaccid"> + description = <"No spontaneous movement."> + > + ["at0015"] = < + text = <"Reduced tone"> + description = <"Some flexion of extremities."> + > + ["at0016"] = < + text = <"Normal tone"> + description = <"Normal, vigorous movements."> + > + ["at0017"] = < + text = <"Reflex irritability"> + description = <"Observation of the response of the infant to an irritant stimulation, for example, suctioning the oropharynx and nares with a soft rubber catheter."> + > + ["at0018"] = < + text = <"No response"> + description = <"No response to stimulation."> + > + ["at0019"] = < + text = <"Reduced response"> + description = <"Grimace or feeble cry when stimulated."> + > + ["at0020"] = < + text = <"Normal response"> + description = <"Grimace, sneeze, cough or pulls away when stimulated."> + > + ["at0021"] = < + text = <"Skin colour"> + description = <"Observation of the skin colour of the infant."> + > + ["at0022"] = < + text = <"Completely blue"> + description = <"Body and extremities are blue."> + > + ["at0023"] = < + text = <"Body pink; extremities blue"> + description = <"Body is pink; extremities are blue."> + > + ["at0024"] = < + text = <"Completely pink"> + description = <"Body and extremities are pink; no cyanosis."> + > + ["at0025"] = < + text = <"Total"> + description = <"The sum of the 5 ordinal scores for each component parameter."> + > + ["at0026"] = < + text = <"2 minute"> + description = <"Apgar score 2 minutes after birth."> + > + ["at0027"] = < + text = <"3 minute"> + description = <"Apgar score 3 minutes after birth."> + > + ["at0028"] = < + text = <"5 minute"> + description = <"Apgar score 5 minutes after birth."> + > + ["at0029"] = < + text = <"List"> + description = <"@ internal @"> + > + ["at0030"] = < + text = <"Notes on measurement"> + description = <"Notes on measurement of the Apgar score."> + > + ["at0031"] = < + text = <"10 minute"> + description = <"Apgar score 10 minutes after birth."> + > + ["at0037"] = < + text = <"Any event"> + description = <"Apgar score at any additional time, as required."> + > + > + > + ["es-cl"] = < + items = < + ["at0000"] = < + text = <"*Apgar score(en)"> + description = <"*Clinical score derived from assessment of respiratory effort, heart rate, reflex irritability, muscle tone and skin colour.(en)"> + > + ["at0001"] = < + text = <"Estructura "> + description = <"*@ internal @"> + > + ["at0002"] = < + text = <"Historia"> + description = <"*@ internal @"> + > + ["at0003"] = < + text = <"*1 minute(en)"> + description = <"*Apgar score 1 minute after birth(en)"> + > + ["at0005"] = < + text = <"Frecuencia cardíaca"> + description = <"Valoración de la función cardíaca en el recién nacido."> + > + ["at0006"] = < + text = <"Sin latido cardíaco"> + description = <"No presenta latidos cardíacos (palpación en la base del cordón umbilical)."> + > + ["at0007"] = < + text = <"Menos de 100 latidos por minuto"> + description = <"Frecuencia cardíaca menor a 100 latidos por minuto."> + > + ["at0008"] = < + text = <"Mayor o igual a 100 latidos por minutos"> + description = <"Frecuencia cardíaca mayor o igual a 100 latidos por minuto."> + > + ["at0009"] = < + text = <"Respiración"> + description = <"Valoración del esfuerzo respiratorio del neonato."> + > + ["at0010"] = < + text = <"Sin esfuerzo"> + description = <"Sin esfuerzo respiratorio."> + > + ["at0011"] = < + text = <"Esfuerzo moderado"> + description = <"Esfuerzo respiratorio debil e irregular."> + > + ["at0012"] = < + text = <"Llorando"> + description = <"Llorando o respirando normalmente."> + > + ["at0013"] = < + text = <"*Muscle tone(en)"> + description = <"*Observation of the infant's muscle tone(en)"> + > + ["at0014"] = < + text = <"Flacido"> + description = <"Flacido y sin movimientos espontáneos."> + > + ["at0015"] = < + text = <"*Reduced tone(en)"> + description = <"*Some flexion of extremities(en)"> + > + ["at0016"] = < + text = <"*Normal tone(en)"> + description = <"*Normal, vigorous movements(en)"> + > + ["at0017"] = < + text = <"*Reflex irritability(en)"> + description = <"*Observation of the response of the infant to an irritant stimulation, for example, suctioning the oropharynx and nares with a soft rubber catheter.(en)"> + > + ["at0018"] = < + text = <"Ninguna respuesta a la aspiración de la vía aérea "> + description = <"Ninguna mueca o respuesta a la aspiración de la vía aérea."> + > + ["at0019"] = < + text = <"Mueca durante aspiración de la vía aérea"> + description = <"Sólo mueca como reacción a la aspiración de la vía aérea."> + > + ["at0020"] = < + text = <"Mueca y tos/estornudo durante la aspiración de la vía aérea"> + description = <"Mueca y tos, estornudo o gag como respuesta a la aspiración de la vía aérea."> + > + ["at0021"] = < + text = <"*Skin colour(en)"> + description = <"*Observation of the skin colour of the infant(en)"> + > + ["at0022"] = < + text = <"*Completely blue(en)"> + description = <"*Body and extremities are blue(en)"> + > + ["at0023"] = < + text = <"*Body pink; extremities blue(en)"> + description = <"*Body is pink; extremities are blue(en)"> + > + ["at0024"] = < + text = <"*Completely pink(en)"> + description = <"*Body and extremities are pink; no cyanosis(en)"> + > + ["at0025"] = < + text = <"Total"> + description = <"El total es la suma de los puntajes de cada parámetro."> + > + ["at0026"] = < + text = <"*2 minute(en)"> + description = <"*Apgar score 2 minutes after birth(en)"> + > + ["at0027"] = < + text = <"*3 minute(en)"> + description = <"*Apgar score 3 minutes after birth(en)"> + > + ["at0028"] = < + text = <"*5 minute(en)"> + description = <"*Apgar score 5 minutes after birth(en)"> + > + ["at0029"] = < + text = <"Lista"> + description = <"*@ internal @"> + > + ["at0030"] = < + text = <"Notas de medición "> + description = <"Notas sobre la medida del Apgar."> + > + ["at0031"] = < + text = <"*10 minute(en)"> + description = <"*Apgar score 10 minutes after birth(en)"> + > + ["at0037"] = < + text = <"*Any event(en)"> + description = <"*Apgar score at any additional time, as required.(en)"> + > + > + > + ["de"] = < + items = < + ["at0000"] = < + text = <"Apgar-Score"> + description = <"Klinischer Score, abgeleitet von der Beurteilung des Atemantriebs, Herzfrequenz, Reflexauslösbarkeit, Muskeltonus und Hautfarbe."> + > + ["at0001"] = < + text = <"Structure"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"History"> + description = <"@ internal @"> + > + ["at0003"] = < + text = <"1 Minute"> + description = <"Apgar-Score 1 Minute nach Geburt."> + > + ["at0005"] = < + text = <"Herzfrequenz"> + description = <"Beurteilung der Herzfrequenz des Neubegorenen."> + > + ["at0006"] = < + text = <"Kein Herzschlag"> + description = <"Kein Herzschlag gesehen, gefühlt oder gehört."> + > + ["at0007"] = < + text = <"<100 Schläge pro Minute"> + description = <"Herzfrequenz von weniger als 100 Schlägen pro Minute."> + > + ["at0008"] = < + text = <"≥100 Schläge pro Minute"> + description = <"Herzfrequenz von mehr als oder genau 100 Schlägen pro Minute."> + > + ["at0009"] = < + text = <"Atemantrieb"> + description = <"Beurteilung des Atemantriebs des Neugeborenen."> + > + ["at0010"] = < + text = <"Kein Bestreben"> + description = <"Kein Bestreben zu atmen."> + > + ["at0011"] = < + text = <"Schwaches oder unregelmäßiges Bestreben"> + description = <"Etwas bestrebt zu atmen, Brustkorb bewegt sich."> + > + ["at0012"] = < + text = <"Normal"> + description = <"Normale Atmung oder Schreien."> + > + ["at0013"] = < + text = <"Muskeltonus"> + description = <"Beobachtung des Musketonus des Neugeborenen."> + > + ["at0014"] = < + text = <"Schlaff"> + description = <"Keine spontane Bewegung."> + > + ["at0015"] = < + text = <"Reduzierter Tonus"> + description = <"Geringe Flexion der Extremitäten."> + > + ["at0016"] = < + text = <"Normaler Tonus"> + description = <"Normale, kraftvolle Bewegung der Extremitäten."> + > + ["at0017"] = < + text = <"Reflexauslösbarkeit"> + description = <"Beobachtung der Antwort des Neugeborens auf eine Reizstimulation, z.B. Absaugen des Oropharynxs und der Nasenlöcher mit einem weichem Gummikatheter."> + > + ["at0018"] = < + text = <"Keine Reaktion"> + description = <"Keine Reaktion auf die Stimulation."> + > + ["at0019"] = < + text = <"Reduzierte Reaktion"> + description = <"Grimassieren oder schwaches Schreien als Reaktion auf die Stimulation."> + > + ["at0020"] = < + text = <"Normale Reaktion"> + description = <"Grimassieren, Niesen, Husten oder Wegziehen als Reaktion auf die Stimulation."> + > + ["at0021"] = < + text = <"Hautfarbe"> + description = <"Beobachtung der Hautfarbe des Neugeborenen."> + > + ["at0022"] = < + text = <"Komplett blau"> + description = <"Körper und Extremitäten sind blau."> + > + ["at0023"] = < + text = <"Akrozyanotisch"> + description = <"Stamm ist rosig, Extremitäten sind blau."> + > + ["at0024"] = < + text = <"Komplett rosig"> + description = <"Stamm und Extremitäten sind rosig; keine Zyanose."> + > + ["at0025"] = < + text = <"Gesamtwert"> + description = <"Die Summe der Zahlenwerte aller 5 Komponenten."> + > + ["at0026"] = < + text = <"2 Minuten"> + description = <"Apgar-Score 2 Minuten nach der Geburt."> + > + ["at0027"] = < + text = <"3 Minuten"> + description = <"Apgar-Score 3 Minuten nach der Geburt."> + > + ["at0028"] = < + text = <"5 Minuten"> + description = <"Apgar-Score 5 Minuten nach der Geburt."> + > + ["at0029"] = < + text = <"List"> + description = <"@ internal @"> + > + ["at0030"] = < + text = <"Anmerkungen zur Messung"> + description = <"Anmerkungen zur Messung des Apgar-Scores."> + > + ["at0031"] = < + text = <"10 Minuten"> + description = <"Apgar-Score 10 Minuten nach der Geburt"> + > + ["at0037"] = < + text = <"Beliebiges Ereignis"> + description = <"Apgar-Score zu beliebigen Zeitpunkten, je nach Bedarf."> + > + > + > + ["fa"] = < + items = < + ["at0000"] = < + text = <"نمره آپگار"> + description = <"نمره بالینی استخراج شده از ارزیابی تلاش تنفسی ، ضربان قلب ، رفلکس تحریک پذیری ، تون عضلانی و رنگ پوست"> + > + ["at0001"] = < + text = <"*structure(en)"> + description = <"*@ internal @(en)"> + > + ["at0002"] = < + text = <"*history(en)"> + description = <"*@ internal @(en)"> + > + ["at0003"] = < + text = <"دقیقه اول"> + description = <"نمره آپگار یک دقیقه بعد از تولد"> + > + ["at0005"] = < + text = <"ضربان قلب"> + description = <"ثبت ضربان قلب نوزاد"> + > + ["at0006"] = < + text = <"عدم وجود"> + description = <"ضربان قلبی مشاهده ، احساس یا شنیده نمی شود"> + > + ["at0007"] = < + text = <"ضربان کمتر از 100 در هر دقیقه"> + description = <"ضربان قلب کمتر از 100 ضربه در هر دقیقه است"> + > + ["at0008"] = < + text = <"ضربان بیشتر یا مساوی 100 در هر دقیقه"> + description = <"ضربان قلب بیشتریا برابر 100 ضربه در هر دقیقه است"> + > + ["at0009"] = < + text = <"تلاش تنفسی"> + description = <"مشاهده تلاش تنفسی نوزاد"> + > + ["at0010"] = < + text = <"غیر موجود"> + description = <"برای تنفس تلاش نمی کند"> + > + ["at0011"] = < + text = <"ضعیف یا نا منظم"> + description = <" برای تنفس تلاش می کند ، سینه حرکت می کند"> + > + ["at0012"] = < + text = <"ظبیعی"> + description = <"تنفس طبیعی یا گریه کردن"> + > + ["at0013"] = < + text = <"تون عضلانی"> + description = <"مشاهده تلون عضلانی نوزاد"> + > + ["at0014"] = < + text = <"مشاهده تلون عضلانی نوزاد"> + description = <"حرکات خودبخودی وجود ندارد"> + > + ["at0015"] = < + text = <"تون کاهش یافته"> + description = <"برخی رفلکسها یا خمیدگی ها وجود دارد"> + > + ["at0016"] = < + text = <"تون طبیعی"> + description = <"طبیعی ، حرکات نیرومند"> + > + ["at0017"] = < + text = <"رفلکس تحریک پذیری"> + description = <"مشاهده پاسخ نوزاد به تحریکات محرک به عنوان مثال مکش دهانی حلقی و سوراخ بینی با کاتتر لاستیکی نرم "> + > + ["at0018"] = < + text = <"پاسخ نمی دهد"> + description = <"عدم پاسخ به تحریکات"> + > + ["at0019"] = < + text = <"کاهش پاسخ"> + description = <"گریه شکلکی یا ضعیف در زمان تحریک"> + > + ["at0020"] = < + text = <"پاسخ طبیعی"> + description = <"شکلک ، عطسه ف سرفه یا عقب کشیدن در زمان تحریک"> + > + ["at0021"] = < + text = <"رنگ پوست"> + description = <"مشاهده رنگ پوست نوزاد"> + > + ["at0022"] = < + text = <"کاملا آبی"> + description = <"دن و دستها و پاها آبی هستند"> + > + ["at0023"] = < + text = <"بدن صورتی ، دستها و پاها آبی"> + description = <"بدن صورتی ، دستها و پاها آبی هستند"> + > + ["at0024"] = < + text = <"کاملا صورتی"> + description = <"دن و دستها و پاها کاملا صورتی هستند هیچ سیانوزی وجود ندارد"> + > + ["at0025"] = < + text = <"مجموع"> + description = <"مجموع پنج نمره ترتیبی برای هر پارامتر جز "> + > + ["at0026"] = < + text = <"دقیقه دو"> + description = <"نمره آپگار دودقیقه بعد از تولد"> + > + ["at0027"] = < + text = <"دقیقه سه"> + description = <"نمره آپگار سه دقیقه بعد از تولد"> + > + ["at0028"] = < + text = <"دقیقه پنج"> + description = <"نمره آپگار پنج دقیقه بعد از تولد"> + > + ["at0029"] = < + text = <"*List(en)"> + description = <"*@ internal @(en)"> + > + ["at0030"] = < + text = <"یادداشتهایی در مورد اندازه گیری"> + description = <"یادداشتهایی در مورد اندازه گیری نمره آپگار"> + > + ["at0031"] = < + text = <"دقیقه ده"> + description = <"نمره آپگار ده دقیقه بعد از تولد"> + > + ["at0037"] = < + text = <"هر رویداد"> + description = <"نمره آپگار در هر زمان ممکن و در صورت نیاز"> + > + > + > + ["ar-sy"] = < + items = < + ["at0000"] = < + text = <"حرز أبغار"> + description = <"الحرز السريري المشتق من تقييم المجهود التنفسي, معدل القلب, التوتر المنعكس, توتر العضلة و لون الجلد"> + > + ["at0001"] = < + text = <"*structure(en)"> + description = <"*@ internal @(en)"> + > + ["at0002"] = < + text = <"*history(en)"> + description = <"*@ internal @(en)"> + > + ["at0003"] = < + text = <"دقيقة واحدة"> + description = <"حرز أبغار بعد دقيقة واحدة من الولادة/الوضع"> + > + ["at0005"] = < + text = <"معدل القلب"> + description = <"تسجيل معدل قلب الرضيع"> + > + ["at0006"] = < + text = <"غائب"> + description = <"لا يمكن سماع, رؤية أو الشعور بضربات القلب"> + > + ["at0007"] = < + text = <"أقل من 100 ضربة في الدقيقة"> + description = <"معدل القلب أقل من 100 ضربة في الدقيقة"> + > + ["at0008"] = < + text = <"أكثر من أو يساوي 100 ضربة في الدقيقة"> + description = <"معدل القلب أكبر من أو يساوي 100 ضربة في الدقيقة"> + > + ["at0009"] = < + text = <"المجهود التنفسي"> + description = <"ملاحظة المجهود التنفسي لدى الرضيع"> + > + ["at0010"] = < + text = <"غائب"> + description = <"لا يوجد بذل مجهود للتنفس"> + > + ["at0011"] = < + text = <"ضعيف أو غير منتظم"> + description = <"يوجد بعض المجهود للتنفس, الصدر يتحرك"> + > + ["at0012"] = < + text = <"طبيعي"> + description = <"يتنفس بشكل طبيعي أو يبكي"> + > + ["at0013"] = < + text = <"توتر العضلة"> + description = <"ملاحظة توتر عضلات الرضيع"> + > + ["at0014"] = < + text = <"مرتخٍ/أعرج"> + description = <"لا يوجد حركة تلقائية"> + > + ["at0015"] = < + text = <"توتر منخفض"> + description = <"يوجد بعض الثني للأطراف"> + > + ["at0016"] = < + text = <"توتر طبيعي"> + description = <"حركات طبيعية قوية"> + > + ["at0017"] = < + text = <"التوتر الانعكاسي"> + description = <"ملاحظة استجابة الرضيع لتحفيز مُهَيَّج, مثلا, مص محتويات البلعوم الفمي و فتحات الأنف باستخدام قثطار مطاطي ناعم."> + > + ["at0018"] = < + text = <"لا توجد استجابة"> + description = <"لا يوجد استجابة للتحفيز"> + > + ["at0019"] = < + text = <"استجابة منخفضة"> + description = <"تكشيرة أو بكاء ضعيف عند التحفيز"> + > + ["at0020"] = < + text = <"استجابة طبيعية"> + description = <"تكشيرة, عُطاس, سعال, أو يتعبد عند تحفيزه"> + > + ["at0021"] = < + text = <"لون الجلد/البشرة"> + description = <"ملاحظة لون بشرة/جلد الرضيع"> + > + ["at0022"] = < + text = <"أزرق تماما"> + description = <"الجسم و الأطراف زرقاء اللون"> + > + ["at0023"] = < + text = <"الجسم متورد و الأطراف زرقاء"> + description = <"الجسم متورد و الأطراف زرقاء"> + > + ["at0024"] = < + text = <"متورد تماما"> + description = <"الجسم و الأطراف متوردة, لا يوجد ازرقاق"> + > + ["at0025"] = < + text = <"الإجمالي"> + description = <"مجموع الأحراز الخمسة المنفردة "> + > + ["at0026"] = < + text = <"عند دقيقتين"> + description = <"حرز أبغار عند دقيقتين من الولادة/الوضع"> + > + ["at0027"] = < + text = <"عند ثلاث دقائق"> + description = <"حرز أبغار بعد ثلاث دقائق من الولادة/الوضع"> + > + ["at0028"] = < + text = <"بعد خمس دقائق"> + description = <"حرز أبغار بعد 5 دقائق من الولادة/الوضع"> + > + ["at0029"] = < + text = <"*List(en)"> + description = <"*@ internal @(en)"> + > + ["at0030"] = < + text = <"ملاحظات حول القياس"> + description = <"ملاحظات حول قياس حرز أبغار"> + > + ["at0031"] = < + text = <"بعد 10 دقائق"> + description = <"حرز أبغار بعد 10 دقائق من الولادة/الوضع"> + > + ["at0037"] = < + text = <"إحدى الوقائع"> + description = <"حرز أبغار عند أي وقت إضافي, حسب الحاجة"> + > + > + > + ["ru"] = < + items = < + ["at0000"] = < + text = <"Шкала Апгар"> + description = <"Клиническая оценка полученная из оценки дыхания, частоты сердечных сокращений, рефлекторной возбудимости, мышечного тонуса и цвета кожи."> + > + ["at0001"] = < + text = <"*structure(en)"> + description = <"*@ internal @(en)"> + > + ["at0002"] = < + text = <"*history(en)"> + description = <"*@ internal @(en)"> + > + ["at0003"] = < + text = <"1 минута"> + description = <"Оценка по Апгар в 1 минуту после рождения."> + > + ["at0005"] = < + text = <"Сердцебиение"> + description = <"Запись о ЧСС младенца."> + > + ["at0006"] = < + text = <"Отсутствует"> + description = <"Нет дыхательных движений."> + > + ["at0007"] = < + text = <"<100 ударов в минуту"> + description = <"ЧСС меньше 100 ударов в минуту."> + > + ["at0008"] = < + text = <"≥100 ударов в минуту"> + description = <"ЧСС более 100 ударов в минуту."> + > + ["at0009"] = < + text = <"Дыхание"> + description = <"Наблюдается за дыханием."> + > + ["at0010"] = < + text = <"Отсутствует"> + description = <"Сердцебиение не видно, не слышно и не ощутимо."> + > + ["at0011"] = < + text = <"Слабое или нерегулярное"> + description = <"Некоторые дыхательные движения, движения грудной клетки."> + > + ["at0012"] = < + text = <"Нормальное."> + description = <"Дыхание нормальное или крик."> + > + ["at0013"] = < + text = <"Мышечный тонус"> + description = <"Оценка мышечного тонуса младенца."> + > + ["at0014"] = < + text = <"Вялый"> + description = <"Нет спонтанных движений."> + > + ["at0015"] = < + text = <"Тонус ослаблен"> + description = <"Слабое сгибание конечностей."> + > + ["at0016"] = < + text = <"Нормальный тонус"> + description = <"Нормальные, энергичные движения."> + > + ["at0017"] = < + text = <"Рефлексы на раздражение"> + description = <"Наблюдение за реакцией ребенка на раздражающее стимуляции, например, очищения ротоглотки и носовых отверстий мягким резиновым катетером."> + > + ["at0018"] = < + text = <"Нет реакции"> + description = <"Нет реакци на стимуляцию."> + > + ["at0019"] = < + text = <"Реакция ослаблена"> + description = <"Гримаса или слабый крик при стимуляции."> + > + ["at0020"] = < + text = <"Нормальная реакция"> + description = <"Гримаса, чихание, кашель или отстранение при стимуляции."> + > + ["at0021"] = < + text = <"Цвет кожи"> + description = <"Оценка цвета кожи младенца."> + > + ["at0022"] = < + text = <"Общий цианоз"> + description = <"Цианоз туловища и конечностей."> + > + ["at0023"] = < + text = <"Акрозианоз, цианоз конечностей"> + description = <"Туловище розовое, цианоз конечностей."> + > + ["at0024"] = < + text = <"Цианоза нет"> + description = <"Туловище и конечности розовые. Цианоза нет"> + > + ["at0025"] = < + text = <"Общая оценка"> + description = <"Сумма баллов по 5 параметрам."> + > + ["at0026"] = < + text = <"2 минута"> + description = <"Оценка по Апгар во 2 минуту после рождения."> + > + ["at0027"] = < + text = <"3 минута"> + description = <"Оценка по Апгар в 3 минуту после рождения."> + > + ["at0028"] = < + text = <"5 минута"> + description = <"Оценка по Апгар на 5 минуту после рождения."> + > + ["at0029"] = < + text = <"*List(en)"> + description = <"*@ internal @(en)"> + > + ["at0030"] = < + text = <"Примечания по измерению"> + description = <"Примечания по измерению по шкале Апгар."> + > + ["at0031"] = < + text = <"10 минута"> + description = <"Оценка по Апгар в 10 минуту после рождения."> + > + ["at0037"] = < + text = <"Любое время"> + description = <"Оценка по Апгар в дополнительное время, если требуется."> + > + > + > + ["nl"] = < + items = < + ["at0000"] = < + text = <"Apgar score"> + description = <"Score die bereikt wordt door beoordeling van ademhalingsinspanning, hartslag, reflexen, spiertonus en kleur."> + > + ["at0001"] = < + text = <"*structure(en)"> + description = <"*@ internal @(en)"> + > + ["at0002"] = < + text = <"*history(en)"> + description = <"*@ internal @(en)"> + > + ["at0003"] = < + text = <"1 minuut"> + description = <"Apgar score 1 minuut na de geboorte."> + > + ["at0005"] = < + text = <"Hartslag"> + description = <"Opnemen van de hartslag van het kind."> + > + ["at0006"] = < + text = <"Afwezig"> + description = <"Er is geen hartslag te zien, voelen of horen."> + > + ["at0007"] = < + text = <"<100 slagen per minuut"> + description = <"Hartfrequentie minder dan 100 slagen per minuut."> + > + ["at0008"] = < + text = <"≥100 slagen per minuut"> + description = <"Hartslag hoger of gelijk aan 100 slagen per minuut."> + > + ["at0009"] = < + text = <"Ademhalingsinspanning"> + description = <"Observatie van de ademhalingsinspanning van het kind."> + > + ["at0010"] = < + text = <"Afwezig"> + description = <"Geen ademhalingsinspanning."> + > + ["at0011"] = < + text = <"Matig of onregelmatig"> + description = <"Enige ademhalingsinspanning, beweging van de borst."> + > + ["at0012"] = < + text = <"Normaal"> + description = <"Normale ademhaling of huilend."> + > + ["at0013"] = < + text = <"Spiertonus"> + description = <"Observatie van de spiertonus van het kind."> + > + ["at0014"] = < + text = <"Slap"> + description = <"Geen spontane bewegingen."> + > + ["at0015"] = < + text = <"Verminderde tonus"> + description = <"Enige flexie van de ledematen."> + > + ["at0016"] = < + text = <"Normale tonus"> + description = <"Normale, krachtige bewegingen."> + > + ["at0017"] = < + text = <"Reactie op prikkels"> + description = <"Observatie van de reactie van het kind op een irritante prikkeling, bijvoorbeeld het uitzuigen van de keel en neus met een zachte rubberen katheter."> + > + ["at0018"] = < + text = <"Geen reactie"> + description = <"Geen reactie op prikkeling."> + > + ["at0019"] = < + text = <"Verminderde reactie"> + description = <"Grimas of zwak huilen bij prikkeling."> + > + ["at0020"] = < + text = <"Normale reactie"> + description = <"Grimas en niezen, hoesten of terugtrekken bij prikkeling."> + > + ["at0021"] = < + text = <"Huidskleur"> + description = <"Observatie van de huidskleur van het kind."> + > + ["at0022"] = < + text = <"Helemaal blauw"> + description = <"Lichaam en extremiteiten zijn blauw."> + > + ["at0023"] = < + text = <"Lichaam is roze, extremiteiten blauw"> + description = <"Het lichaam van het kind is roze, de extremiteiten zijn blauw."> + > + ["at0024"] = < + text = <"Helemaal roze"> + description = <"Lichaam en eztremiteiten zijn roze, geen cyanose."> + > + ["at0025"] = < + text = <"Totaal"> + description = <"De som van de 5 afzonderlijke scores van iedere observatie."> + > + ["at0026"] = < + text = <"2 minuten"> + description = <"Apgar score 2 minuten na de geboorte."> + > + ["at0027"] = < + text = <"3 minuten"> + description = <"Apgar score 3 minuten na de geboorte."> + > + ["at0028"] = < + text = <"5 minuten"> + description = <"Apgar score 5 minuten na de geboorte."> + > + ["at0029"] = < + text = <"*List(en)"> + description = <"*@ internal @(en)"> + > + ["at0030"] = < + text = <"Opmerkingen over de meting"> + description = <"Opmerkingen over de meting van de Apgar score."> + > + ["at0031"] = < + text = <"10 minuten"> + description = <"Apgar score 10 minuten na de geboorte."> + > + ["at0037"] = < + text = <"Any event"> + description = <"Apgar score op elk toe te voegen tijdstip, indien nodig"> + > + > + > + ["pt-br"] = < + items = < + ["at0000"] = < + text = <"Escala Apgar"> + description = <"Escala clínica derivada da avaliação do esforço respiratório, frequência cardíaca, reflexo de irritabilidade, tônus muscular e cor da pele."> + > + ["at0001"] = < + text = <"*structure(en)"> + description = <"*@ internal @(en)"> + > + ["at0002"] = < + text = <"*history(en)"> + description = <"*@ internal @(en)"> + > + ["at0003"] = < + text = <"1 minuto"> + description = <"Escore Apgar obtido 1 minuto apóss o nascimento."> + > + ["at0005"] = < + text = <"Frequência cardíaca"> + description = <"Registro da frequência cardíaca do recém-nascido."> + > + ["at0006"] = < + text = <"Ausente"> + description = <"Nenhum batimento cardíaco é visto, sentido ou escutado."> + > + ["at0007"] = < + text = <"<100 batimentos por minuto"> + description = <"Frequência cardíaca inferior a 100 batimentos por minuto."> + > + ["at0008"] = < + text = <"≥100 batimentos por minuto"> + description = <"Frequência cardíaca superior a 100 batimentos por minuto."> + > + ["at0009"] = < + text = <"Esforço respiratório"> + description = <"Observação do esforço respiratório do recém-nascido."> + > + ["at0010"] = < + text = <"Ausente"> + description = <"Nenhum esforço para respirar."> + > + ["at0011"] = < + text = <"Fraco ou irregular"> + description = <"Algum esforço para respirar, movimento do peito."> + > + ["at0012"] = < + text = <"Normal"> + description = <"Respirando normalmente ou chorando."> + > + ["at0013"] = < + text = <"Tônus muscular"> + description = <"Observação do tônus muscular do recém-nascido."> + > + ["at0014"] = < + text = <"Atônico ou flácido"> + description = <"Sem movimento espontâneo."> + > + ["at0015"] = < + text = <"Tônus reduzido"> + description = <"Alguma flexão de extremidades."> + > + ["at0016"] = < + text = <"Tônus normal"> + description = <"Movimentos normais, vigorosos."> + > + ["at0017"] = < + text = <"Reflexo de irritabilidade"> + description = <"Observação da resposta a um estímulo irritativo, por exemplo, sucção da orofaringe e narinas com um cateter de borracha macia."> + > + ["at0018"] = < + text = <"Nenhuma resposta"> + description = <"Nenhuma resposta ao estímulo."> + > + ["at0019"] = < + text = <"Resposta reduzida"> + description = <"Careta ou choro débil quando estimulado."> + > + ["at0020"] = < + text = <"Resposta normal"> + description = <"Careta, espirro, tosse ou tenta se afastar quando estimulado."> + > + ["at0021"] = < + text = <"Cor da pele"> + description = <"Observação da cor da pele do recém-nascido."> + > + ["at0022"] = < + text = <"Completamente azul"> + description = <"Corpo e extremidades estão azuis"> + > + ["at0023"] = < + text = <"Corpo cor de rosa; extremiddades azuis"> + description = <"Corpo está cor de rosa, extremidades estão azuis."> + > + ["at0024"] = < + text = <"Completamente cor de rosa"> + description = <"Corpo e extremidade estão cor de rosa, ausência de cianose."> + > + ["at0025"] = < + text = <"Total"> + description = <"A soma dos 5 escores ordinais para cada parâmetro componente."> + > + ["at0026"] = < + text = <"2 minutos"> + description = <"Escore Apgar 2 minutos após o nascimento."> + > + ["at0027"] = < + text = <"3 minutos"> + description = <"escore Apgar 3 minutos após o nascimento."> + > + ["at0028"] = < + text = <"5 minutos"> + description = <"Escore Apgar 5 minutos após o nascimento."> + > + ["at0029"] = < + text = <"*List(en)"> + description = <"*@ internal @(en)"> + > + ["at0030"] = < + text = <"Notas sobre a medida"> + description = <"Notas sobre a medida da Escala Apgar."> + > + ["at0031"] = < + text = <"10 minutos"> + description = <"escore Apgar 10 minutos após o nascimento"> + > + ["at0037"] = < + text = <"Qualquer evento"> + description = <"Escore Apgar em qualquer tempo adicional, se requerido."> + > + > + > + > + term_bindings = < + ["SNOMED-CT"] = < + items = < + ["/data[at0002]/events[at0003]/data[at0001]/items[at0025]"] = <[SNOMED-CT::169895004]> + ["/data[at0002]/events[at0028]/data[at0001]/items[at0025]"] = <[SNOMED-CT::169909004]> + ["/data[at0002]/events[at0031]/data[at0001]/items[at0025]"] = <[SNOMED-CT::169922007]> + ["/data[at0002]/events[at0037]/data[at0001]/items[at0025]"] = <[SNOMED-CT::364592005]> + ["at0025"] = <[SNOMED-CT::249228009]> + > + > + ["LOINC"] = < + items = < + ["/data[at0002]/events[at0003]"] = <[LOINC::48334-7]> + ["/data[at0002]/events[at0003]/data[at0001]/items[at0005]"] = <[LOINC::32407-9]> + ["/data[at0002]/events[at0003]/data[at0001]/items[at0009]"] = <[LOINC::32410-3]> + ["/data[at0002]/events[at0003]/data[at0001]/items[at0013]"] = <[LOINC::32408-7]> + ["/data[at0002]/events[at0003]/data[at0001]/items[at0017]"] = <[LOINC::32409-5]> + ["/data[at0002]/events[at0003]/data[at0001]/items[at0021]"] = <[LOINC::32406-1]> + ["/data[at0002]/events[at0003]/data[at0001]/items[at0025]"] = <[LOINC::9272-6]> + ["/data[at0002]/events[at0026]/data[at0001]/items[at0025]"] = <[LOINC::9273-4]> + ["/data[at0002]/events[at0028]"] = <[LOINC::48333-9]> + ["/data[at0002]/events[at0028]/data[at0001]/items[at0005]"] = <[LOINC::32412-9]> + ["/data[at0002]/events[at0028]/data[at0001]/items[at0009]"] = <[LOINC::32415-2]> + ["/data[at0002]/events[at0028]/data[at0001]/items[at0013]"] = <[LOINC::32413-7]> + ["/data[at0002]/events[at0028]/data[at0001]/items[at0017]"] = <[LOINC::32414-5]> + ["/data[at0002]/events[at0028]/data[at0001]/items[at0021]"] = <[LOINC::32411-1]> + ["/data[at0002]/events[at0028]/data[at0001]/items[at0025]"] = <[LOINC::9274-2]> + ["/data[at0002]/events[at0031]"] = <[LOINC::48332-1]> + ["/data[at0002]/events[at0031]/data[at0001]/items[at0005]"] = <[LOINC::32402-0]> + ["/data[at0002]/events[at0031]/data[at0001]/items[at0009]"] = <[LOINC::32405-3]> + ["/data[at0002]/events[at0031]/data[at0001]/items[at0013]"] = <[LOINC::32403-8]> + ["/data[at0002]/events[at0031]/data[at0001]/items[at0017]"] = <[LOINC::32404-6]> + ["/data[at0002]/events[at0031]/data[at0001]/items[at0021]"] = <[LOINC::32401-2]> + ["/data[at0002]/events[at0031]/data[at0001]/items[at0025]"] = <[LOINC::9271-8]> + ["at0006"] = <[LOINC::LA6716]> + ["at0007"] = <[LOINC::LA6717]> + ["at0008"] = <[LOINC::LA6718]> + ["at0010"] = <[LOINC::LA6725]> + ["at0011"] = <[LOINC::LA6726]> + ["at0012"] = <[LOINC::LA6727]> + ["at0014"] = <[LOINC::LA6713]> + ["at0015"] = <[LOINC::LA6714]> + ["at0016"] = <[LOINC::LA6715]> + ["at0018"] = <[LOINC::LA6719]> + ["at0019"] = <[LOINC::LA6720]> + ["at0020"] = <[LOINC::LA6721]> + ["at0022"] = <[LOINC::LA6722]> + ["at0023"] = <[LOINC::LA6723]> + ["at0024"] = <[LOINC::LA6724]> + > + > + > diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.blood_pressure.v2.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.blood_pressure.v2.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.body_weight.v2.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.body_weight.v2.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.heart_rate.v2.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.heart_rate.v2.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.height.v2.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.height.v2.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.lab_test.v1.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.lab_test.v1.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.waist_hip.v2.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.waist_hip.v2.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-SECTION.ad_hoc_heading.v1.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-SECTION.ad_hoc_heading.v1.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/adl/openEHR-EHR-SECTION.medications.v1.adl b/rm-skeleton/src/test/resources/adl/openEHR-EHR-SECTION.medications.v1.adl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/dadl/item_tree_blood_pressure_1.dadl b/rm-skeleton/src/test/resources/dadl/item_tree_blood_pressure_1.dadl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_1.dadl b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_1.dadl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_10.dadl b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_10.dadl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_11.dadl b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_11.dadl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_12.dadl b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_12.dadl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_2.dadl b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_2.dadl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_3.dadl b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_3.dadl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_4.dadl b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_4.dadl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_5.dadl b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_5.dadl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_6.dadl b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_6.dadl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_7.dadl b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_7.dadl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_8.dadl b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_8.dadl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_9.dadl b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_9.dadl old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/log4j.properties b/rm-skeleton/src/test/resources/log4j.properties old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/oet/test_nested_sections_with_optional_children.oet b/rm-skeleton/src/test/resources/oet/test_nested_sections_with_optional_children.oet old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/oet/test_section_instruction_tree.oet b/rm-skeleton/src/test/resources/oet/test_section_instruction_tree.oet old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/oet/test_text_name.oet b/rm-skeleton/src/test/resources/oet/test_text_name.oet old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/terms.txt b/rm-skeleton/src/test/resources/terms.txt old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/xml/purged.xml b/rm-skeleton/src/test/resources/xml/purged.xml old mode 100755 new mode 100644 diff --git a/rm-skeleton/src/test/resources/xml/to_purge.xml b/rm-skeleton/src/test/resources/xml/to_purge.xml old mode 100755 new mode 100644 diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index e9d040f4..f025b218 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -1,128 +1,133 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.5-SNAPSHOT - - xml-binding - jar - openEHR RM XML Data Binding Component - http://www.openehr.org/svn/ref_impl_java/TRUNK/project_page.htm - - - - rong.chen - Rong Chen - rong.acode@gmail.com - - - - openEHR - http://www.openehr.org/ - - 2007 - - Java implementation of openEHR RM XML Data Binding Component - - - - - org.codehaus.mojo - xmlbeans-maven-plugin - 2.3.3 - - - - xmlbeans - - - - true - - src/main/xsd - - - - - - - - openehr - openehr-rm-core - ${project.version} - - - openehr - openehr-rm-domain - ${project.version} - - - org.apache.xmlbeans - xmlbeans - 2.3.0 - - - openehr - measure-serv - ${project.version} - - - openehr - mini-termserv - ${project.version} - - - openehr - ${project.version} - rm-builder - - - junit - junit - 3.8.1 - test - - - log4j - log4j - 1.2.13 - - - commons-io - commons-io - 1.2 - test - - - com.thoughtworks.xstream - xstream - 1.3.1 - test - - - stax - stax - 1.1.1-dev - compile - - - xmlbeans-jsr173-api - xmlbeans - - - - - org.apache.xmlbeans - xmlbeans-xpath - 2.3.0 - test - - - openehr - oet-parser - ${project.version} - - - + + + 4.0.0 + + org.openehr.java-libs + java-libs + 0-SNAPSHOT + + xml-binding + jar + openEHR RM XML Data Binding Component + http://www.openehr.org/svn/ref_impl_java/TRUNK/project_page.htm + + + + rong.chen + Rong Chen + rong.acode@gmail.com + + + + openEHR + http://www.openehr.org/ + + 2007 + + Java implementation of openEHR RM XML Data Binding Component + + + + + + org.codehaus.mojo + xmlbeans-maven-plugin + 2.3.3 + + + + xmlbeans + + + + true + + src/main/xsd + + 1.8 + 1.8 + + + + + + + + + org.openehr.java-libs + openehr-rm-core + ${project.version} + + + org.openehr.java-libs + openehr-rm-domain + ${project.version} + + + org.apache.xmlbeans + xmlbeans + 3.1.0 + + + org.openehr.java-libs + measure-serv + ${project.version} + + + org.openehr.java-libs + mini-termserv + ${project.version} + + + org.openehr.java-libs + ${project.version} + rm-builder + + + junit + junit + 3.8.1 + test + + + log4j + log4j + 1.2.13 + + + commons-io + commons-io + 1.2 + test + + + com.thoughtworks.xstream + xstream + 1.3.1 + test + + + stax + stax + 1.1.1-dev + compile + + + xmlbeans-jsr173-api + xmlbeans + + + + + org.apache.xmlbeans + xmlbeans-xpath + 2.3.0 + test + + + org.openehr.java-libs + oet-parser + ${project.version} + + + diff --git a/xml-binding/src/main/groovy/load-observation.groovy b/xml-binding/src/main/groovy/load-observation.groovy old mode 100755 new mode 100644 diff --git a/xml-binding/src/main/java/org/openehr/binding/RMInspector.java b/xml-binding/src/main/java/org/openehr/binding/RMInspector.java index 8bfdb086..95c9a884 100755 --- a/xml-binding/src/main/java/org/openehr/binding/RMInspector.java +++ b/xml-binding/src/main/java/org/openehr/binding/RMInspector.java @@ -300,7 +300,6 @@ public Class retrieveRMType(String rmClassName) { * * @param rmClassName * @return - * @throws RMObjectBuildingException */ public Map retrieveRMAttributes(String rmClassName) { Class rmClass = retrieveRMType(rmClassName); @@ -311,9 +310,9 @@ public Map retrieveRMAttributes(String rmClassName) { Map map = attributeType(rmClass); Map ret = new HashMap(); - for(String name : map.keySet()) { + for(Map.Entry entry: map.entrySet()) { + String name = entry.getKey(); ret.put(toUnderscoreSeparated(name), map.get(name)); - log.debug("rmattribute: " +name +": "+ map.get(name)); } return ret; @@ -325,7 +324,6 @@ public Map retrieveRMAttributes(String rmClassName) { * * @param rmClassName * @return - * @throws RMObjectBuildingException */ public Set retrieveRMAttributeNames(String rmClassName) { Class rmClass = retrieveRMType(rmClassName); @@ -392,10 +390,9 @@ public String findMatchingRMClass(Map valueMap) { // replace underscore separated names with camel case Map filteredMap = new HashMap(); - for (String name : valueMap.keySet()) { - filteredMap.put(toCamelCase(name), valueMap.get(name)); + for(Map.Entry entry: valueMap.entrySet()) { + filteredMap.put(toCamelCase(entry.getKey()), valueMap.get(entry.getValue())); } - Constructor constructor = fullConstructor(rmClass); if (constructor == null) { throw new RuntimeException("annotated constructor missing for " @@ -470,28 +467,6 @@ public String findMatchingRMClass(Map valueMap) { return null; } - // todo: isn't there any support from java api on this? - private Object defaultValue(Class type) { - if (type == boolean.class) { - return Boolean.FALSE; - } else if (type == double.class) { - return new Double(0); - } else if (type == float.class) { - return new Float(0); - } else if (type == int.class) { - return new Integer(0); - } else if (type == short.class) { - return new Short((short) 0); - } else if (type == long.class) { - return new Long(0); - } else if (type == char.class) { - return new Character((char) 0); - } else if (type == byte.class) { - return new Byte((byte) 0); - } - return null; - } - /* * Skipped types during matching: 1. Simple value types in DADL 2. Cluster * due to clash with ItemList diff --git a/xml-binding/src/main/java/org/openehr/binding/XMLBinding.java b/xml-binding/src/main/java/org/openehr/binding/XMLBinding.java index d78105c2..7d7a640f 100755 --- a/xml-binding/src/main/java/org/openehr/binding/XMLBinding.java +++ b/xml-binding/src/main/java/org/openehr/binding/XMLBinding.java @@ -38,6 +38,8 @@ */ public class XMLBinding { + private final Map> classAttributeMap = new HashMap>(); + /** * Constructor allowing use of a custom SystemValue Map */ @@ -123,7 +125,7 @@ public Object bindToXML(Object obj) throws XMLBindingException { // Previous code was: Object xmlObj = factoryMethod.invoke(null, null); Object xmlObj = factoryMethod.invoke(null, xopt); - Map attributes = builder.retrieveAttribute(className); + Map attributes = getClassAttributes(className); Set attributeNames = attributes.keySet(); Object attributeValue = null; Method setterMethod = null; @@ -197,7 +199,7 @@ public Object bindToXML(Object obj) throws XMLBindingException { addNew.invoke(xmlObj, null); - array[0] = new Integer(i); + array[0] = Integer.valueOf(i); array[1] = bindToXML(value); setterMethod.invoke(xmlObj, array); @@ -314,6 +316,15 @@ Class findXMLAbstractClass(Class xmlClass) throws ClassNotFoundException { return abstractClass; } + private Map getClassAttributes(final String className) + throws Exception { + Map classMap = classAttributeMap.get(className); + if (classMap == null) { + classMap = builder.retrieveAttribute(className); + classAttributeMap.put(className, classMap); + } + return classMap; + } /** * Binds data from XML binding classes to RM classes using reflection @@ -332,7 +343,7 @@ public Object bindToRM(Object object) throws Exception { className = className.substring(0, className.length() - 4); } - Map attributes = builder.retrieveAttribute(className); + Map attributes = getClassAttributes(className); Set attributeNames = attributes.keySet(); log.debug("attributeNames: " + attributeNames); diff --git a/xml-binding/src/main/java/org/openehr/binding/XMLBindingException.java b/xml-binding/src/main/java/org/openehr/binding/XMLBindingException.java old mode 100755 new mode 100644 diff --git a/xml-binding/src/main/xsd/Archetype.xsd b/xml-binding/src/main/xsd/Archetype.xsd old mode 100755 new mode 100644 diff --git a/xml-binding/src/main/xsd/BaseTypes.xsd b/xml-binding/src/main/xsd/BaseTypes.xsd old mode 100755 new mode 100644 diff --git a/xml-binding/src/main/xsd/Composition.xsd b/xml-binding/src/main/xsd/Composition.xsd old mode 100755 new mode 100644 diff --git a/xml-binding/src/main/xsd/Content.xsd b/xml-binding/src/main/xsd/Content.xsd old mode 100755 new mode 100644 diff --git a/xml-binding/src/main/xsd/Extract.xsd b/xml-binding/src/main/xsd/Extract.xsd old mode 100755 new mode 100644 diff --git a/xml-binding/src/main/xsd/OpenehrProfile.xsd b/xml-binding/src/main/xsd/OpenehrProfile.xsd old mode 100755 new mode 100644 diff --git a/xml-binding/src/main/xsd/Resource.xsd b/xml-binding/src/main/xsd/Resource.xsd old mode 100755 new mode 100644 diff --git a/xml-binding/src/main/xsd/Structure.xsd b/xml-binding/src/main/xsd/Structure.xsd old mode 100755 new mode 100644 diff --git a/xml-binding/src/main/xsd/Version.xsd b/xml-binding/src/main/xsd/Version.xsd old mode 100755 new mode 100644 diff --git a/xml-binding/src/test/java/org/openehr/binding/BindDataTypesTest.java b/xml-binding/src/test/java/org/openehr/binding/BindDataTypesTest.java old mode 100755 new mode 100644 index 6e01cb23..b80ff06f --- a/xml-binding/src/test/java/org/openehr/binding/BindDataTypesTest.java +++ b/xml-binding/src/test/java/org/openehr/binding/BindDataTypesTest.java @@ -15,6 +15,18 @@ public void testBindDvProportionToXML() throws Exception { assertTrue("XML class wrong", obj instanceof DVPROPORTION); } + public void testBindtoXMLMultipleClassAtribute() throws Exception { + + //Validates it uses the map to when calling getClassAttributes(final String className) in XMLBinding + DvProportion bp = new DvProportion(0.5, 1.0, ProportionKind.RATIO, null); + Object obj = binding.bindToXML(bp); + assertTrue("XML class wrong", obj instanceof DVPROPORTION); + Object obj1 = binding.bindToXML(bp); + assertTrue("XML class wrong", obj instanceof DVPROPORTION); + } + + + public void testBindXMLDvProportionToRM() throws Exception { DVPROPORTION xobj = DVPROPORTION.Factory.parse( fromClasspath("dv_proportion.xml")); diff --git a/xml-binding/src/test/java/org/openehr/binding/BindEmptyItemTreeTest.java b/xml-binding/src/test/java/org/openehr/binding/BindEmptyItemTreeTest.java old mode 100755 new mode 100644 diff --git a/xml-binding/src/test/java/org/openehr/binding/BindItemTreeWithDvProportionTest.java b/xml-binding/src/test/java/org/openehr/binding/BindItemTreeWithDvProportionTest.java old mode 100755 new mode 100644 diff --git a/xml-binding/src/test/java/org/openehr/binding/BindStructureToXMLTest.java b/xml-binding/src/test/java/org/openehr/binding/BindStructureToXMLTest.java old mode 100755 new mode 100644 diff --git a/xml-binding/src/test/java/org/openehr/binding/CreateXMLObjectTest.java b/xml-binding/src/test/java/org/openehr/binding/CreateXMLObjectTest.java old mode 100755 new mode 100644 diff --git a/xml-binding/src/test/java/org/openehr/binding/RMBindingTest.java b/xml-binding/src/test/java/org/openehr/binding/RMBindingTest.java old mode 100755 new mode 100644 diff --git a/xml-binding/src/test/java/org/openehr/binding/VersionedDocumentTest.java b/xml-binding/src/test/java/org/openehr/binding/VersionedDocumentTest.java old mode 100755 new mode 100644 diff --git a/xml-binding/src/test/java/org/openehr/binding/XMLBindingTestBase.java b/xml-binding/src/test/java/org/openehr/binding/XMLBindingTestBase.java old mode 100755 new mode 100644 diff --git a/xml-binding/src/test/java/org/openehr/binding/XMLParsingTest.java b/xml-binding/src/test/java/org/openehr/binding/XMLParsingTest.java old mode 100755 new mode 100644 diff --git a/xml-binding/src/test/resources/composition-discharge.xml b/xml-binding/src/test/resources/composition-discharge.xml old mode 100755 new mode 100644 diff --git a/xml-binding/src/test/resources/composition-prescription.xml b/xml-binding/src/test/resources/composition-prescription.xml old mode 100755 new mode 100644 diff --git a/xml-binding/src/test/resources/composition.xml b/xml-binding/src/test/resources/composition.xml old mode 100755 new mode 100644 diff --git a/xml-binding/src/test/resources/dv_proportion.xml b/xml-binding/src/test/resources/dv_proportion.xml old mode 100755 new mode 100644 diff --git a/xml-binding/src/test/resources/empty_item_tree.xml b/xml-binding/src/test/resources/empty_item_tree.xml old mode 100755 new mode 100644 diff --git a/xml-binding/src/test/resources/item_tree.xml b/xml-binding/src/test/resources/item_tree.xml old mode 100755 new mode 100644 diff --git a/xml-binding/src/test/resources/item_tree_002.xml b/xml-binding/src/test/resources/item_tree_002.xml old mode 100755 new mode 100644 diff --git a/xml-binding/src/test/resources/item_tree_003.xml b/xml-binding/src/test/resources/item_tree_003.xml old mode 100755 new mode 100644 diff --git a/xml-binding/src/test/resources/log4j.properties b/xml-binding/src/test/resources/log4j.properties old mode 100755 new mode 100644 diff --git a/xml-binding/src/test/resources/original_version_001.xml b/xml-binding/src/test/resources/original_version_001.xml old mode 100755 new mode 100644 diff --git a/xml-binding/src/test/resources/original_version_002.xml b/xml-binding/src/test/resources/original_version_002.xml old mode 100755 new mode 100644 diff --git a/xml-binding/src/test/resources/simple_composition.xml b/xml-binding/src/test/resources/simple_composition.xml old mode 100755 new mode 100644 diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index db1119c4..7de958c9 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -1,41 +1,41 @@ 4.0.0 - openehr - ref_impl_java - 1.0.5-SNAPSHOT + org.openehr.java-libs + java-libs + 0-SNAPSHOT xml-serializer jar XML Serializer - http://www.openehr.org/projects/java.html + http://www.openehr.org/projects/java.html openEHR http://www.openehr.org/ 2004 - + Java XML Serializer of the Archetype Object Model - + - openehr + org.openehr.java-libs openehr-rm-core ${project.version} - openehr + org.openehr.java-libs openehr-rm-domain ${project.version} - openehr + org.openehr.java-libs openehr-aom ${project.version} - openehr + org.openehr.java-libs openehr-ap ${project.version} @@ -63,4 +63,4 @@ test - \ No newline at end of file + diff --git a/xml-serializer/readme.txt b/xml-serializer/readme.txt old mode 100755 new mode 100644 diff --git a/xml-serializer/src/main/java/org/openehr/am/serialize/XMLSerializer.java b/xml-serializer/src/main/java/org/openehr/am/serialize/XMLSerializer.java index 986b42a8..4bc7be0c 100755 --- a/xml-serializer/src/main/java/org/openehr/am/serialize/XMLSerializer.java +++ b/xml-serializer/src/main/java/org/openehr/am/serialize/XMLSerializer.java @@ -1,1091 +1,1215 @@ -package org.openehr.am.serialize; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.charset.Charset; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.jdom.Document; -import org.jdom.Element; -import org.jdom.Namespace; -import org.jdom.output.Format; -import org.jdom.output.XMLOutputter; -import org.openehr.am.archetype.Archetype; -import org.openehr.am.archetype.assertion.Assertion; -import org.openehr.am.archetype.assertion.AssertionVariable; -import org.openehr.am.archetype.assertion.ExpressionBinaryOperator; -import org.openehr.am.archetype.assertion.ExpressionItem; -import org.openehr.am.archetype.assertion.ExpressionLeaf; -import org.openehr.am.archetype.assertion.ExpressionOperator; -import org.openehr.am.archetype.assertion.ExpressionUnaryOperator; -import org.openehr.am.archetype.constraintmodel.ArchetypeInternalRef; -import org.openehr.am.archetype.constraintmodel.ArchetypeSlot; -import org.openehr.am.archetype.constraintmodel.CAttribute; -import org.openehr.am.archetype.constraintmodel.CComplexObject; -import org.openehr.am.archetype.constraintmodel.CDomainType; -import org.openehr.am.archetype.constraintmodel.CMultipleAttribute; -import org.openehr.am.archetype.constraintmodel.CObject; -import org.openehr.am.archetype.constraintmodel.CPrimitiveObject; -import org.openehr.am.archetype.constraintmodel.Cardinality; -import org.openehr.am.archetype.constraintmodel.ConstraintRef; -import org.openehr.am.archetype.constraintmodel.primitive.CBoolean; -import org.openehr.am.archetype.constraintmodel.primitive.CDate; -import org.openehr.am.archetype.constraintmodel.primitive.CDateTime; -import org.openehr.am.archetype.constraintmodel.primitive.CDuration; -import org.openehr.am.archetype.constraintmodel.primitive.CInteger; -import org.openehr.am.archetype.constraintmodel.primitive.CPrimitive; -import org.openehr.am.archetype.constraintmodel.primitive.CReal; -import org.openehr.am.archetype.constraintmodel.primitive.CString; -import org.openehr.am.archetype.constraintmodel.primitive.CTime; -import org.openehr.am.archetype.ontology.ArchetypeOntology; -import org.openehr.am.archetype.ontology.ArchetypeTerm; -import org.openehr.am.archetype.ontology.OntologyBinding; -import org.openehr.am.archetype.ontology.OntologyBindingItem; -import org.openehr.am.archetype.ontology.OntologyDefinitions; -import org.openehr.am.archetype.ontology.QueryBindingItem; -import org.openehr.am.archetype.ontology.TermBindingItem; -import org.openehr.am.openehrprofile.datatypes.quantity.CDvOrdinal; -import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantity; -import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantityItem; -import org.openehr.am.openehrprofile.datatypes.quantity.Ordinal; -import org.openehr.am.openehrprofile.datatypes.text.CCodePhrase; -import org.openehr.rm.common.resource.ResourceDescription; -import org.openehr.rm.common.resource.ResourceDescriptionItem; -import org.openehr.rm.datatypes.text.CodePhrase; -import org.openehr.rm.support.basic.Interval; -import org.openehr.rm.support.identification.ArchetypeID; - - -/** - * XML serializer of the openEHR Archetype Object Model. - * - * @author Mattias Forss - */ -public class XMLSerializer { - - /** - * Create an outputter with default encoding, indent and lineSeparator - */ - public XMLSerializer() { - this.encoding = UTF8; - outputter = new XMLOutputter(); - outputter.setFormat(Format.getPrettyFormat().setEncoding(encoding.name())); - } - - /** - * Create an outputter which can use a JDOM formatter of choice, e.g. - * Format.getPrettyFormat().setEncoding(encoding.name()).setTextMode(TextMode.PRESERVE) - */ - public XMLSerializer(Format format) { - this.encoding = UTF8; - outputter = new XMLOutputter(); - outputter.setFormat(format); - } - - - /** - * Output given archetype as string in XML format - * - * @param archetype - * @return a string in XML format - * @throws IOException - */ - public String output(Archetype archetype) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - output(archetype, baos); - return baos.toString(encoding.name()); - } - - /** - * Output given archetype to outputStream - * - * @param archetype - * @param out - * @throws IOException - */ - public void output(Archetype archetype, OutputStream out) throws IOException { - Document document = new Document(); - output(archetype, document); - outputter.output(document, out); - } - - /** - * Output given archetype to Document - * - * @param archetype - * @param out - * @throws IOException - */ - public void output(Archetype archetype, Document out) { - Element rootElement = new Element("archetype", defaultNamespace); - rootElement.addNamespaceDeclaration(xsiNamespace); - rootElement.addNamespaceDeclaration(xsdNamespace); - - out.setRootElement(rootElement); - output(archetype, rootElement); - } - - /** - * Output given archetype to writer - * - * @param archetype - * @param out - * @throws IOException - */ - public void output(Archetype archetype, Element out) { - printHeader(archetype, out); - printDefinition(archetype.getDefinition(), out); - printOntology(archetype.getOntology(), archetype.getConcept(), out); - } - - protected void printHeader(Archetype archetype, Element out) { - Element originalLanguage = new Element("original_language", defaultNamespace); - out.getChildren().add(originalLanguage); - printCodePhrase(archetype.getOriginalLanguage(), originalLanguage); - printString("is_controlled", archetype.isControlled() ? "true" : "false", out); - - printDescription(archetype.getDescription(), out); - - //TODO printTranslations - - Element archetypeId = new Element("archetype_id", defaultNamespace); - out.getChildren().add(archetypeId); - printString("value", archetype.getArchetypeId().toString(), archetypeId); - - printString("adl_version", archetype.getAdlVersion(), out); - if (archetype.getUid() != null) { - printString("uid", archetype.getUid().toString(), out); - } - - printString("concept", archetype.getConcept(), out); - - final ArchetypeID parentID = archetype.getParentArchetypeId(); - if(parentID != null) { - Element parentArchetypeId = new Element("parent_archetype_id", defaultNamespace); - out.getChildren().add(parentArchetypeId); - printString("value", parentID.toString(), parentArchetypeId); - } - - } - - protected void printDescription(ResourceDescription description, Element out) { - - if (description == null) { - return; - } - - Element des = new Element("description", defaultNamespace); - out.getChildren().add(des); - printStringMap("original_author", description.getOriginalAuthor(), des); - printStringList("other_contributors", description.getOtherContributors(), des); - printString("lifecycle_state", description.getLifecycleState(), des); - - if (description.getResourcePackageUri() != null && description.getResourcePackageUri().length() >0) { // only add this tag if non-empty - printString("resource_package_uri", description.getResourcePackageUri(), des); - } - printStringMap("other_details", description.getOtherDetails(), des); - - for (ResourceDescriptionItem item : description.getDetails()) { - Element details = new Element("details", defaultNamespace); - des.getChildren().add(details); - printDescriptionItem(item, details); - } - - } - - protected void printDescriptionItem(ResourceDescriptionItem item, Element out) { - Element language = new Element("language", defaultNamespace); - out.getChildren().add(language); - printCodePhrase(item.getLanguage(), language); - - printString("purpose", item.getPurpose(), out); // Mandatory - printStringList("keywords", item.getKeywords(), out); - printString("use", item.getUse(), out); // Mandatory - printString("misuse", item.getMisuse(), out); // Mandatory - printString("copyright", item.getCopyright(), out); - printStringMap("original_resource_uri", - item.getOriginalResourceUri(), out); - - printStringMap("other_details", item.getOtherDetails(), out); - } - - private void printCodePhrase(CodePhrase cp, Element out) { - if (cp == null) { - return; - } - - Element terminologyId = new Element("terminology_id", defaultNamespace); - out.getChildren().add(terminologyId); - printString("value", cp.getTerminologyId().getValue(), terminologyId); - - printString("code_string", cp.getCodeString(), out); - } - - - private void printStringMap(String label, Map map, Element out) { - - if(map != null && !map.isEmpty()) { - for(String key : map.keySet()) { - Element elm = new Element(label, defaultNamespace); - out.getChildren().add(elm); - elm.setAttribute("id", key); - if (map.get(key) != null) { - elm.setText(map.get(key)); - } - } - } - } - - - private void printString(String label, String value, Element out) { - printString(label, value, out, false); - } - - private void printString(String label, String value, Element out, boolean addXSDStringType) { - Element elm = new Element(label, defaultNamespace); - if (addXSDStringType) { - elm.setAttribute("type", "xsd:string", xsiNamespace); // the type is expected here. - } - out.getChildren().add(elm); - if (value != null) { - elm.setText(value); - } - } - - private void printStringList(String label, List list, Element out) { - - if (list == null || list.isEmpty()) { - return; - } - - for(int i = 0, j = list.size(); i < j; i++) { - Element elm = new Element(label, defaultNamespace); - out.getChildren().add(elm); - elm.setText(list.get(i)); - } - } - - protected void printDefinition(CComplexObject definition, Element out) { - - if (definition == null) { - return; - } - - Element def = new Element("definition", defaultNamespace); - out.getChildren().add(def); - printCComplexObjectTop(definition, def); - } - - protected void printCComplexObjectTop(CComplexObject ccobj, Element out) { - - printCObjectElements(ccobj, out); - - // print all attributes - if(!ccobj.isAnyAllowed()) { - for (CAttribute cattribute : ccobj.getAttributes()) { - printCAttribute(cattribute, out); - } - } - } - - protected void printCComplexObject(CComplexObject ccobj, Element out) { - - Element children = new Element("children", defaultNamespace); - out.getChildren().add(children); - children.setAttribute("type", "C_COMPLEX_OBJECT", xsiNamespace); - printCObjectElements(ccobj, children); - - // print all attributes - if(!ccobj.isAnyAllowed()) { - for (CAttribute cattribute : ccobj.getAttributes()) { - printCAttribute(cattribute, children); - } - } - - } - - protected void printConstraintRef(ConstraintRef ref, Element out) { - Element children = new Element("children", defaultNamespace); - out.getChildren().add(children); - children.setAttribute("type", "CONSTRAINT_REF", xsiNamespace); - printCObjectElements(ref, children); - printString("reference", ref.getReference(), children); - } - - protected void printArchetypeInternalRef(ArchetypeInternalRef ref, Element out) { - - Element children = new Element("children", defaultNamespace); - out.getChildren().add(children); - children.setAttribute("type", "ARCHETYPE_INTERNAL_REF", xsiNamespace); - - printCObjectElements(ref, children); - printString("target_path", ref.getTargetPath(), children); - } - - protected void printArchetypeSlot(ArchetypeSlot slot, Element out) { - - Element children = new Element("children", defaultNamespace); - out.getChildren().add(children); - children.setAttribute("type", "ARCHETYPE_SLOT", xsiNamespace); - - printCObjectElements(slot, children); - - // print all attributes - if (!slot.isAnyAllowed()) { - if (slot.getIncludes() != null) { - for (Assertion include : slot.getIncludes()) { - Element includes = new Element("includes", defaultNamespace); - children.getChildren().add(includes); - printAssertion(include, includes); - } - } - - if (slot.getExcludes() != null) { - for (Assertion exclude : slot.getExcludes()) { - Element excludes = new Element("excludes", defaultNamespace); - children.getChildren().add(excludes); - printAssertion(exclude, excludes); - } - } - } - } - - protected void printAssertion(Assertion assertion, Element out) { - - if (assertion.getTag() != null) { // must not be displayed at all if null according to spec. - printString("tag", assertion.getTag(), out); - } - printString("string_expression", assertion.getStringExpression(), out); - printExpressionItem("expression", assertion.getExpression(), out); - - if(assertion.getVariables() != null) { - List variables = assertion.getVariables(); - - for(AssertionVariable var : variables) { - Element vars = new Element("variables", defaultNamespace); - out.getChildren().add(vars); - printString("name", var.getName(), vars); - printString("definition", var.getDefinition(), vars); - } - } - } - - protected void printExpressionItem(String label, ExpressionItem expItem, Element out) { - - if(expItem instanceof ExpressionLeaf) { - printExpressionLeaf(label, (ExpressionLeaf) expItem, out); - } else if(expItem instanceof ExpressionOperator) { - printExpressionOperator(label, (ExpressionOperator) expItem, out); - } else { - // unknown ExpressionItem - Element elm = new Element(label, defaultNamespace); - out.getChildren().add(elm); - elm.setAttribute("type", "EXPR_ITEM", xsiNamespace); - - printString("type", expItem.getType(), elm); - } - } - - protected void printExpressionLeaf(String label, ExpressionLeaf expLeaf, Element out) { - - Element elm = new Element(label, defaultNamespace); - out.getChildren().add(elm); - elm.setAttribute("type", "EXPR_LEAF", xsiNamespace); - - printString("type", expLeaf.getType(), elm); - if (expLeaf.getItem() instanceof CPrimitive) { - Element item = new Element("item", defaultNamespace); - elm.getChildren().add(item); - printCPrimitive((CPrimitive) expLeaf.getItem(), item); - } else { - //EXPR_LEAF.item is defined as xs:any in the AM schema (the reason for which is unclear) - //and consequently of type object in C# land. - // That's why having the XSD type explicitly set to string fixes the problem when deserialising to a C# string instead of XmlText. - printString("item", expLeaf.getItem().toString(), elm, true); - } - printString("reference_type", expLeaf.getReferenceType().name().toLowerCase(), elm); // the Reference type is expected in lower case here as per spec examples - } - - protected void printExpressionOperator(String label, ExpressionOperator expOperator, Element out) { - Element elm = new Element(label, defaultNamespace); - out.getChildren().add(elm); - if(expOperator instanceof ExpressionUnaryOperator) { - elm.setAttribute("type", "EXPR_UNARY_OPERATOR", xsiNamespace); - printExpressionOperatorElements(expOperator, elm); - printExpressionItem("operand", ((ExpressionUnaryOperator)expOperator).getOperand(), elm); - } else if(expOperator instanceof ExpressionBinaryOperator) { - final ExpressionBinaryOperator expBinaryOperator = (ExpressionBinaryOperator)expOperator; - elm.setAttribute("type", "EXPR_BINARY_OPERATOR", xsiNamespace); - printExpressionOperatorElements(expOperator, elm); - printExpressionItem("left_operand", expBinaryOperator.getLeftOperand(), elm); - printExpressionItem("right_operand", expBinaryOperator.getRightOperand(), elm); - } else { - // unknown ExpressionOperator - elm.setAttribute("type", "EXPR_OPERATOR", xsiNamespace); - printExpressionOperatorElements(expOperator, elm); - } - } - - protected void printExpressionOperatorElements(ExpressionOperator expOperator, Element out) { - - printString("type", expOperator.getType(), out); - printString("operator", String.valueOf(expOperator.getOperator().getValue()), out); - printString("precedence_overridden", - expOperator.isPrecedenceOverridden() == true ? "true" : "false", out); - } - - protected void printCAttribute(CAttribute cattribute, Element out) { - - final boolean isMultipleAttribute; - - if (cattribute instanceof CMultipleAttribute) { - isMultipleAttribute = true; - } else { - isMultipleAttribute = false; - } - - Element attributes = new Element("attributes", defaultNamespace); - out.getChildren().add(attributes); - if(isMultipleAttribute) { - attributes.setAttribute("type", "C_MULTIPLE_ATTRIBUTE", xsiNamespace); - } else { - attributes.setAttribute("type", "C_SINGLE_ATTRIBUTE", xsiNamespace); - } - - // FIXME: AOM XML schema spec is wrong. Has 'unbounded' attribute for C_ATTRIBUTE and element with name - // 'rm_type_name' instead of 'rm_attribute_name'. - printString("rm_attribute_name", cattribute.getRmAttributeName(), attributes); - - Element existence = new Element("existence", defaultNamespace); - attributes.getChildren().add(existence); - - printString("lower_included", "true", existence); - printString("upper_included", "true", existence); - - printString("lower_unbounded", "false", existence); - printString("upper_unbounded", "false", existence); - - int lower = 0, upper = 0; - - if(cattribute.getExistence().equals(CAttribute.Existence.REQUIRED)) { - lower = 1; - upper = 1; - } else if(cattribute.getExistence().equals(CAttribute.Existence.OPTIONAL)) { - lower = 0; - upper = 1; - } - printString("lower", Integer.toString(lower), existence); - printString("upper", Integer.toString(upper), existence); - - if(!cattribute.isAnyAllowed()) { - List children = cattribute.getChildren(); - - if (children.size() > 1 - || !(children.get(0) instanceof CPrimitiveObject)) { - for (CObject cobject : cattribute.getChildren()) { - printCObject(cobject, attributes); - } - } else { - CObject child = children.get(0); - printCPrimitiveObject((CPrimitiveObject) child, attributes); - } - } - - if(isMultipleAttribute) { - Element cardinality = new Element("cardinality", defaultNamespace); - attributes.getChildren().add(cardinality); - printCardinality( - ((CMultipleAttribute) cattribute).getCardinality(), cardinality); - } - - } - - protected void printCObject(CObject cobj, Element out) { - - // print specialised types - if (cobj instanceof CDomainType) { - printCDomainType((CDomainType) cobj, out); - } else if (cobj instanceof CPrimitiveObject) { - printCPrimitiveObject((CPrimitiveObject) cobj, out); - } else if (cobj instanceof CComplexObject) { - printCComplexObject((CComplexObject) cobj, out); - } else if (cobj instanceof ArchetypeInternalRef) { - printArchetypeInternalRef((ArchetypeInternalRef) cobj, out); - } else if (cobj instanceof ConstraintRef) { // FIXME: Add in ADLSerializer as well - printConstraintRef((ConstraintRef) cobj, out); - } else if (cobj instanceof ArchetypeSlot) { - printArchetypeSlot((ArchetypeSlot) cobj, out); - } - } - - protected void printCObjectElements(CObject cobj, Element out) { - - // we always need the upper case with underscore notation for the rm type name - printString("rm_type_name", getUpperCaseWithUnderscoreFromCamelCase(cobj.getRmTypeName()), out); - printOccurrences(cobj.getOccurrences(), out); - printString("node_id", cobj.getNodeId(), out); - } - - protected void printOccurrences(Interval occurrences, Element out) { - - if (occurrences == null) { - return; - } - - Element occurs = new Element("occurrences", defaultNamespace); - out.getChildren().add(occurs); - printInterval(occurrences, occurs); - } - - protected void printCardinality(Cardinality cardinality, Element out) { - - if (cardinality.isOrdered()) { - printString("is_ordered", "true", out); - } else { - printString("is_ordered", "false", out); - } - - if (cardinality.isUnique()) { - printString("is_unique", "true", out); - } else { - printString("is_unique", "false", out); - } - - Element interval = new Element("interval", defaultNamespace); - out.getChildren().add(interval); - printInterval(cardinality.getInterval(), interval); - } - - protected void printCDomainType(CDomainType cdomain, Element out) { - - if (cdomain instanceof CCodePhrase) { - printCCodePhrase((CCodePhrase) cdomain, out); - } else if (cdomain instanceof CDvOrdinal) { - printCDvOrdinal((CDvOrdinal) cdomain, out); - } else if (cdomain instanceof CDvQuantity) { - printCDvQuantity((CDvQuantity) cdomain, out); - } else { - // unknown CDomainType - System.err.println("Cannot serialize CDomainType of type '" + cdomain.getClass().getName() + "'!"); - } - } - - protected void printCCodePhrase(CCodePhrase ccp, Element out) { - - Element children = new Element("children", defaultNamespace); - out.getChildren().add(children); - children.setAttribute("type", "C_CODE_PHRASE", xsiNamespace); - - printCObjectElements(ccp, children); - - if(ccp.getTerminologyId() != null) { - Element terminologyId = new Element("terminology_id", defaultNamespace); - children.getChildren().add(terminologyId); - printString("value", ccp.getTerminologyId().getValue(), terminologyId); - } - - if (ccp.getCodeList() != null) { - final List codeList = ccp.getCodeList(); - - for (int i = 0, j = codeList.size(); i < j; i++) { - printString("code_list", codeList.get(i), children); - } - } - - } - - protected void printCDvOrdinal(CDvOrdinal cordinal, Element out) { - - Element children = new Element("children", defaultNamespace); - out.getChildren().add(children); - children.setAttribute("type", "C_DV_ORDINAL", xsiNamespace); - - printCObjectElements(cordinal, children); - - if(cordinal.getList() != null) { - final Set ordinals = cordinal.getList(); - - Ordinal ordinal; - for (Iterator it = ordinals.iterator(); it.hasNext();) { - ordinal = it.next(); - Element list = new Element("list", defaultNamespace); - children.getChildren().add(list); - printString("value", String.valueOf(ordinal.getValue()), list); - Element symbol = new Element("symbol", defaultNamespace); - list.getChildren().add(symbol); - Element definingCode = new Element("defining_code", defaultNamespace); - symbol.getChildren().add(definingCode); - printCodePhrase(ordinal.getSymbol(), definingCode); - } - } - } - - protected void printCDvQuantity(CDvQuantity cquantity, Element out) { - - Element children = new Element("children", defaultNamespace); - out.getChildren().add(children); - children.setAttribute("type", "C_DV_QUANTITY", xsiNamespace); - - printCObjectElements(cquantity, children); - - - CodePhrase property = cquantity.getProperty(); - if (property != null) { - Element prop = new Element("property", defaultNamespace); - children.getChildren().add(prop); - printCodePhrase(property, prop); - } - - if (cquantity.getList() != null) { - final List list = cquantity.getList(); - - for (CDvQuantityItem item : list) { - Element lst = new Element("list", defaultNamespace); - children.getChildren().add(lst); - - if(item.getMagnitude() != null) { - Element magnitude = new Element("magnitude", defaultNamespace); - lst.getChildren().add(magnitude); - printInterval(item.getMagnitude(), magnitude); - } - - printString("units", item.getUnits(), lst); - } - } - } - - protected void printOntology(ArchetypeOntology ontology, String concept, Element out) { - - if(ontology == null) { - return; - } - - Element onto = new Element("ontology", defaultNamespace); - out.getChildren().add(onto); - - - // TODO: Check why this is not in the XML schema specification of the AOM. - //printString("primary_language", ontology.getPrimaryLanguage(), 2, out); - // TODO: Check why this is not in the XML schema specification of the AOM. - //printStringList("languages_available", ontology.getLanguages(), 2, out); - //printStringList("terminologies_available", ontology.getTerminologies(), 2, out); - //final int specDepth = StringUtils.countMatches(".", concept); - //printString("specialisation_depth", String.valueOf(specDepth), 2, out); - - - if(ontology.getTermDefinitionsList() != null) { - final List termDefinitions = ontology.getTermDefinitionsList(); - - for (OntologyDefinitions defs : termDefinitions) { - Element trmDefinitions = new Element("term_definitions", defaultNamespace); - onto.getChildren().add(trmDefinitions); - trmDefinitions.setAttribute("language", defs.getLanguage()); - - for (ArchetypeTerm term : defs.getDefinitions()) { - Element items = new Element("items", defaultNamespace); - trmDefinitions.getChildren().add(items); - items.setAttribute("code", term.getCode()); - - printStringMap("items", term.getItems(), items); - } - - } - } - - if(ontology.getConstraintDefinitionsList() != null) { - final List constraintDefinitions = ontology.getConstraintDefinitionsList(); - - for (OntologyDefinitions defs : constraintDefinitions) { - Element consDefinitions = new Element("constraint_definitions", defaultNamespace); - onto.getChildren().add(consDefinitions); - consDefinitions.setAttribute("language", defs.getLanguage()); - - for (ArchetypeTerm term : defs.getDefinitions()) { - Element items = new Element("items", defaultNamespace); - consDefinitions.getChildren().add(items); - items.setAttribute("code", term.getCode()); - - printStringMap("items", term.getItems(), items); - } - } - } - - if (ontology.getTermBindingList() != null) { - final List termBindings = ontology.getTermBindingList(); - - TermBindingItem item; - for (OntologyBinding bind : termBindings) { - Element trmBindings = new Element("term_bindings", defaultNamespace); - onto.getChildren().add(trmBindings); - trmBindings.setAttribute("terminology", bind.getTerminology()); - - for (OntologyBindingItem bindItem : bind.getBindingList()) { - item = (TermBindingItem) bindItem; - - for(String value : item.getTerms()) { - Element items = new Element("items", defaultNamespace); - trmBindings.getChildren().add(items); - items.setAttribute("code", item.getCode()); - Element vl = new Element("value", defaultNamespace); - items.getChildren().add(vl); - - String terminologyId = value.substring(1, value.lastIndexOf("::")); - String codeString = value.substring(value.lastIndexOf("::") + 2, value.length() - 1); - Element termId = new Element("terminology_id", defaultNamespace); - vl.getChildren().add(termId); - printString("value", terminologyId, termId); - printString("code_string", codeString, vl); - } - } - } - } - - if (ontology.getConstraintBindingList() != null) { - final List constraintBindings = ontology.getConstraintBindingList(); - - QueryBindingItem item; - for (OntologyBinding bind : constraintBindings) { - Element consBindings = new Element("constraint_bindings", defaultNamespace); - onto.getChildren().add(consBindings); - consBindings.setAttribute("terminology", bind.getTerminology()); - - for (OntologyBindingItem bindItem : bind.getBindingList()) { - item = (QueryBindingItem) bindItem; - Element items = new Element("items", defaultNamespace); - consBindings.getChildren().add(items); - items.setAttribute("code", item.getCode()); - printString("value", item.getQuery().getUrl(), items); - } - - } - } - } - - protected void printCPrimitiveObject(CPrimitiveObject cpo, Element out) { - CPrimitive cp = cpo.getItem(); - if (cp == null) { - return; - } - - Element children = new Element("children", defaultNamespace); - out.getChildren().add(children); - children.setAttribute("type", "C_PRIMITIVE_OBJECT", xsiNamespace); - - printCObjectElements(cpo, children); - - Element item = new Element("item", defaultNamespace); - children.getChildren().add(item); - printCPrimitive(cp, item); - } - - protected void printCPrimitive(CPrimitive cp, Element out) { - - if (cp instanceof CBoolean) { - out.setAttribute("type", "C_BOOLEAN", xsiNamespace); - printCBoolean((CBoolean) cp, out); - } else if (cp instanceof CDate) { - out.setAttribute("type", "C_DATE", xsiNamespace); - printCDate((CDate) cp, out); - } else if (cp instanceof CDateTime) { - out.setAttribute("type", "C_DATE_TIME", xsiNamespace); - printCDateTime((CDateTime) cp, out); - } else if (cp instanceof CTime) { - out.setAttribute("type", "C_TIME", xsiNamespace); - printCTime((CTime) cp, out); - } else if (cp instanceof CDuration) { - out.setAttribute("type", "C_DURATION", xsiNamespace); - printCDuration((CDuration) cp, out); - } else if (cp instanceof CInteger) { - out.setAttribute("type", "C_INTEGER", xsiNamespace); - printCInteger((CInteger) cp, out); - } else if (cp instanceof CReal) { - out.setAttribute("type", "C_REAL", xsiNamespace); - printCReal((CReal) cp, out); - } else if (cp instanceof CString) { - out.setAttribute("type", "C_STRING", xsiNamespace); - printCString((CString) cp, out); - } else { - out.setAttribute("type", "C_PRIMITIVE", xsiNamespace); - System.err.println("Cannot serialize CPrimitive of type '" + cp.getClass().getName() + "'!"); - } - - } - - protected void printCBoolean(CBoolean cboolean, Element out) { - - printString("true_valid", cboolean.isTrueValid() == true ? - "true" : "false", out); - printString("false_valid", cboolean.isFalseValid() == true ? - "true" : "false", out); - - if(cboolean.hasAssumedValue()) { - printString("assumed_value", cboolean.assumedValue().booleanValue() == true ? - "true" : "false", out); - } - } - - protected void printCDate(CDate cdate, Element out) { - - if (cdate.getPattern() != null) { - printString("pattern", cdate.getPattern(), out); - } - - if(cdate.getInterval() != null) { - Element range = new Element("range", defaultNamespace); - out.getChildren().add(range); - printInterval(cdate.getInterval(), range); - } - - if(cdate.hasAssumedValue()) { - printString("assumed_value", cdate.assumedValue().toString(), out); - } - } - - protected void printCDateTime(CDateTime cdatetime, Element out) { - - if (cdatetime.getPattern() != null) { - printString("pattern", cdatetime.getPattern(), out); - } - - // FIXME: Output timezone_validity. CDateTime seem to be missing this function. - - if(cdatetime.getInterval() != null) { - Element range = new Element("range", defaultNamespace); - out.getChildren().add(range); - printInterval(cdatetime.getInterval(), range); - } - - if(cdatetime.hasAssumedValue()) { - printString("assumed_value", cdatetime.assumedValue().toString(), out); - } - } - - protected void printCTime(CTime ctime, Element out) { - - if (ctime.getPattern() != null) { - printString("pattern", ctime.getPattern(), out); - } - - // FIXME: Output timezone_validity. CTime seem to be missing this function. - - if(ctime.getInterval() != null) { - Element range = new Element("range", defaultNamespace); - out.getChildren().add(range); - printInterval(ctime.getInterval(), range); - } - - if(ctime.hasAssumedValue()) { - printString("assumed_value", ctime.assumedValue().toString(), out); - } - } - - protected void printCDuration(CDuration cduration, Element out) { - - if (cduration.getValue() != null) { - printString("pattern", cduration.getValue().toString(), out); - } - - if(cduration.getInterval() != null) { - Element range = new Element("range", defaultNamespace); - out.getChildren().add(range); - printInterval(cduration.getInterval(), range); - } - - if(cduration.hasAssumedValue()) { - printString("assumed_value", cduration.assumedValue().toString(), out); - } - } - - protected void printCInteger(CInteger cinteger, Element out) { - - if(cinteger.getList() != null) { - printList(cinteger.getList(), out); - } - - if(cinteger.getInterval() != null) { - Element range = new Element("range", defaultNamespace); - out.getChildren().add(range); - printInterval(cinteger.getInterval(), range); - } - - // TODO: Write 'list_open' element... xs:boolean [0..1] - - if(cinteger.hasAssumedValue()) { - printString("assumed_value", cinteger.assumedValue().toString(), out); - } - } - - protected void printCReal(CReal creal, Element out) { - - if (creal.getList() != null) { - printList(creal.getList(), out); - } - - if(creal.getInterval() != null) { - Element range = new Element("range", defaultNamespace); - out.getChildren().add(range); - printInterval(creal.getInterval(), range); - } - - if(creal.hasAssumedValue()) { - printString("assumed_value", creal.assumedValue().toString(), out); - } - } - - protected void printCString(CString cstring, Element out) { - - if(cstring.getPattern() != null) { - printString("pattern", cstring.getPattern(), out); - } - - if(cstring.getList() != null){ - printList(cstring.getList(), out); - } - - // TODO: Write 'list_open' element... xs:boolean [0..1] - - if(cstring.hasAssumedValue()) { - printString("assumed_value", cstring.assumedValue().toString(), out); - } - } - - protected void printList(List list, Element out) { - - if(list == null) { - return; - } - - for(int i = 0, j = list.size(); i < j; i++) { - printString("list", list.get(i).toString(), out); - } - } - - @SuppressWarnings("unchecked") - protected void printInterval(Interval interval, Element out) { - if(interval == null) { - return; - } - - final Comparable lower = interval.getLower(); - final Comparable upper = interval.getUpper(); - - if (! interval.isLowerUnbounded()) { // not included is implied if unbounded - printString("lower_included", - interval.isLowerIncluded() == true ? "true" : "false", - out); - } - if (! interval.isUpperUnbounded()) { // not included is implied if unbounded - printString("upper_included", - interval.isUpperIncluded() == true ? "true" : "false", - out); - } - - - printString("lower_unbounded", - interval.isLowerUnbounded() ? "true" : "false", out); - - printString("upper_unbounded", - interval.isUpperUnbounded() ? "true" : "false", out); - - if(lower != null) { - printString("lower", lower.toString(), out); - } - - if(upper != null) { - printString("upper", upper.toString(), out); - } - - } - - private String getUpperCaseWithUnderscoreFromCamelCase(String str) { - if( str == null || str.length() == 0 ) { - return str; - } - - StringBuffer result = new StringBuffer(); - - char prevChar = 'A'; // init with an upper case letter - /* - * Change underscore to space, insert space before capitals - */ - for( int i = 0; i < str.length(); i++ ) { - char c = str.charAt( i ); - if(! Character.isUpperCase(prevChar) && - !(prevChar=='_') && - Character.isLetter(c) && - Character.isUpperCase(c)) - { - result.append("_"); - result.append( Character.toUpperCase( c ) ); - } - else { - result.append( Character.toUpperCase( c ) ); - } - prevChar = c; - } - - return result.toString(); - - - - } - - /* charset encodings */ - public static final Charset UTF8 = Charset.forName("UTF-8"); - - public static final Charset LATIN1 = Charset.forName("ISO-8859-1"); - - public static final Namespace defaultNamespace = Namespace.getNamespace("http://schemas.openehr.org/v1"); - - public static final Namespace xsiNamespace = Namespace.getNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"); - - public static final Namespace xsdNamespace = Namespace.getNamespace("xsd", "http://www.w3.org/2001/XMLSchema"); - - /* fields */ - private Charset encoding; - - private XMLOutputter outputter; -} - -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is XMLSerializer. - * - * The Initial Developer of the Original Code is - * Link�pings universitet, Sweden. - * Portions created by the Initial Developer are Copyright (C) 2005-2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): Mattias Forss - * Rong Chen - * Erik Sundvall - * Humberto Naves - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * +package org.openehr.am.serialize; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.Charset; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.Namespace; +import org.jdom.output.Format; +import org.jdom.output.XMLOutputter; +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.assertion.Assertion; +import org.openehr.am.archetype.assertion.AssertionVariable; +import org.openehr.am.archetype.assertion.ExpressionBinaryOperator; +import org.openehr.am.archetype.assertion.ExpressionItem; +import org.openehr.am.archetype.assertion.ExpressionLeaf; +import org.openehr.am.archetype.assertion.ExpressionOperator; +import org.openehr.am.archetype.assertion.ExpressionUnaryOperator; +import org.openehr.am.archetype.constraintmodel.ArchetypeInternalRef; +import org.openehr.am.archetype.constraintmodel.ArchetypeSlot; +import org.openehr.am.archetype.constraintmodel.CAttribute; +import org.openehr.am.archetype.constraintmodel.CComplexObject; +import org.openehr.am.archetype.constraintmodel.CDomainType; +import org.openehr.am.archetype.constraintmodel.CMultipleAttribute; +import org.openehr.am.archetype.constraintmodel.CObject; +import org.openehr.am.archetype.constraintmodel.CPrimitiveObject; +import org.openehr.am.archetype.constraintmodel.Cardinality; +import org.openehr.am.archetype.constraintmodel.ConstraintRef; +import org.openehr.am.archetype.constraintmodel.primitive.CBoolean; +import org.openehr.am.archetype.constraintmodel.primitive.CDate; +import org.openehr.am.archetype.constraintmodel.primitive.CDateTime; +import org.openehr.am.archetype.constraintmodel.primitive.CDuration; +import org.openehr.am.archetype.constraintmodel.primitive.CInteger; +import org.openehr.am.archetype.constraintmodel.primitive.CPrimitive; +import org.openehr.am.archetype.constraintmodel.primitive.CReal; +import org.openehr.am.archetype.constraintmodel.primitive.CString; +import org.openehr.am.archetype.constraintmodel.primitive.CTime; +import org.openehr.am.archetype.ontology.ArchetypeOntology; +import org.openehr.am.archetype.ontology.ArchetypeTerm; +import org.openehr.am.archetype.ontology.OntologyBinding; +import org.openehr.am.archetype.ontology.OntologyBindingItem; +import org.openehr.am.archetype.ontology.OntologyDefinitions; +import org.openehr.am.archetype.ontology.QueryBindingItem; +import org.openehr.am.archetype.ontology.TermBindingItem; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvOrdinal; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantity; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantityItem; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvScale; +import org.openehr.am.openehrprofile.datatypes.quantity.Ordinal; +import org.openehr.am.openehrprofile.datatypes.quantity.Scale; +import org.openehr.am.openehrprofile.datatypes.text.CCodePhrase; +import org.openehr.rm.common.resource.ResourceDescription; +import org.openehr.rm.common.resource.ResourceDescriptionItem; +import org.openehr.rm.common.resource.TranslationDetails; +import org.openehr.rm.datatypes.quantity.DvQuantity; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.basic.Interval; +import org.openehr.rm.support.identification.ArchetypeID; + + +/** + * XML serializer of the openEHR Archetype Object Model. + * + * @author Mattias Forss + */ +public class XMLSerializer { + + /** + * Create an outputter with default encoding, indent and lineSeparator + */ + public XMLSerializer() { + this.encoding = UTF8; + outputter = new XMLOutputter(); + outputter.setFormat(Format.getPrettyFormat().setEncoding(encoding.name())); + } + + /** + * Create an outputter which can use a JDOM formatter of choice, e.g. + * Format.getPrettyFormat().setEncoding(encoding.name()).setTextMode(TextMode.PRESERVE) + * @param format the format + */ + public XMLSerializer(Format format) { + this.encoding = UTF8; + outputter = new XMLOutputter(); + outputter.setFormat(format); + } + + + /** + * Output given archetype as string in XML format + * + * @param archetype + * @return a string in XML format + */ + public String output(Archetype archetype) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + output(archetype, baos); + return baos.toString(encoding.name()); + } + + /** + * Output given archetype to outputStream + * + * @param archetype + * @param out + * @throws IOException + */ + public void output(Archetype archetype, OutputStream out) throws IOException { + Document document = new Document(); + output(archetype, document); + outputter.output(document, out); + } + + /** + * Output given archetype to Document + * + * @param archetype the archetype + * @param out the out document + */ + public void output(Archetype archetype, Document out) { + Element rootElement = new Element("archetype", defaultNamespace); + rootElement.addNamespaceDeclaration(xsiNamespace); + rootElement.addNamespaceDeclaration(xsdNamespace); + + out.setRootElement(rootElement); + output(archetype, rootElement); + } + + /** + * Output given archetype to writer + * + * @param archetype + * @param out + */ + public void output(Archetype archetype, Element out) { + printHeader(archetype, out); + printDefinition(archetype.getDefinition(), out); + printOntology(archetype.getOntology(), archetype.getConcept(), out); + } + + protected void printHeader(Archetype archetype, Element out) { + Element originalLanguage = new Element("original_language", defaultNamespace); + out.getChildren().add(originalLanguage); + printCodePhrase(archetype.getOriginalLanguage(), originalLanguage); + printString("is_controlled", archetype.isControlled() ? "true" : "false", out); + + printDescription(archetype.getDescription(), out); + + printTranslations(archetype.getTranslations(), out); + + if (archetype.getUid() != null) { + Element uid = new Element("uid", defaultNamespace); + out.getChildren().add(uid); + printString("value", archetype.getUid().toString(), uid); + } + + Element archetypeId = new Element("archetype_id", defaultNamespace); + out.getChildren().add(archetypeId); + printString("value", archetype.getArchetypeId().toString(), archetypeId); + + printString("adl_version", archetype.getAdlVersion(), out); + + + printString("concept", archetype.getConcept(), out); + + final ArchetypeID parentID = archetype.getParentArchetypeId(); + if(parentID != null) { + Element parentArchetypeId = new Element("parent_archetype_id", defaultNamespace); + out.getChildren().add(parentArchetypeId); + printString("value", parentID.toString(), parentArchetypeId); + } + + } + + private void printTranslations(Map translations, Element out) { + if (translations == null) { + return; + } + + for (Entry translation : translations.entrySet()) { + // Note that each translation is serialised to one translations (note the plural!) element + Element translationsElement = new Element("translations", defaultNamespace); + out.getChildren().add(translationsElement); + + Element languageElement = new Element("language", defaultNamespace); + translationsElement.getChildren().add(languageElement); + + printCodePhrase(translation.getValue().getLanguage(), languageElement); + + TranslationDetails transDetails = translation.getValue(); + printStringMap("author", transDetails.getAuthor(), translationsElement); + + + if (transDetails.getAccreditation() != null) { + printString("accreditation", transDetails.getAccreditation(), translationsElement); + } + + printStringMap("other_details", transDetails.getOtherDetails(), translationsElement); + } + } + + protected void printDescription(ResourceDescription description, Element out) { + + if (description == null) { + return; + } + + Element des = new Element("description", defaultNamespace); + out.getChildren().add(des); + printStringMap("original_author", description.getOriginalAuthor(), des); + printStringList("other_contributors", description.getOtherContributors(), des); + printString("lifecycle_state", description.getLifecycleState(), des); + + if (description.getResourcePackageUri() != null && description.getResourcePackageUri().length() >0) { // only add this tag if non-empty + printString("resource_package_uri", description.getResourcePackageUri(), des); + } + printStringMap("other_details", description.getOtherDetails(), des); + + for (ResourceDescriptionItem item : description.getDetails().values()) { + Element details = new Element("details", defaultNamespace); + des.getChildren().add(details); + printDescriptionItem(item, details); + } + + } + + protected void printDescriptionItem(ResourceDescriptionItem item, Element out) { + Element language = new Element("language", defaultNamespace); + out.getChildren().add(language); + printCodePhrase(item.getLanguage(), language); + + printString("purpose", item.getPurpose(), out); // Mandatory + printStringList("keywords", item.getKeywords(), out); + printString("use", item.getUse(), out); // Mandatory + printString("misuse", item.getMisuse(), out); // Mandatory + printString("copyright", item.getCopyright(), out); + printStringMap("original_resource_uri", + item.getOriginalResourceUri(), out); + + printStringMap("other_details", item.getOtherDetails(), out); + } + + private void printCodePhrase(CodePhrase cp, Element out) { + if (cp == null) { + return; + } + + Element terminologyId = new Element("terminology_id", defaultNamespace); + out.getChildren().add(terminologyId); + printString("value", cp.getTerminologyId().getValue(), terminologyId); + + printString("code_string", cp.getCodeString(), out); + } + + + private void printStringMap(String label, Map map, Element out) { + + if(map != null && !map.isEmpty()) { + for(Map.Entry entry : map.entrySet()) { + Element elm = new Element(label, defaultNamespace); + out.getChildren().add(elm); + elm.setAttribute("id", entry.getKey()); + if (entry.getValue() != null) { + elm.setText(entry.getValue()); + } + } + } + } + + + private void printString(String label, String value, Element out) { + printString(label, value, out, false); + } + + private void printString(String label, String value, Element out, boolean addXSDStringType) { + Element elm = new Element(label, defaultNamespace); + if (addXSDStringType) { + elm.setAttribute("type", "xsd:string", xsiNamespace); // the type is expected here. + } + out.getChildren().add(elm); + if (value != null) { + elm.setText(value); + } + } + + private void printStringList(String label, List list, Element out) { + + if (list == null || list.isEmpty()) { + return; + } + + for(int i = 0, j = list.size(); i < j; i++) { + Element elm = new Element(label, defaultNamespace); + out.getChildren().add(elm); + elm.setText(list.get(i)); + } + } + + protected void printDefinition(CComplexObject definition, Element out) { + + if (definition == null) { + return; + } + + Element def = new Element("definition", defaultNamespace); + out.getChildren().add(def); + printCComplexObjectTop(definition, def); + } + + protected void printCComplexObjectTop(CComplexObject ccobj, Element out) { + + printCObjectElements(ccobj, out); + + // print all attributes + if(!ccobj.isAnyAllowed()) { + for (CAttribute cattribute : ccobj.getAttributes()) { + printCAttribute(cattribute, out); + } + } + } + + protected void printCComplexObject(CComplexObject ccobj, Element out) { + + Element children = new Element("children", defaultNamespace); + out.getChildren().add(children); + children.setAttribute("type", "C_COMPLEX_OBJECT", xsiNamespace); + printCObjectElements(ccobj, children); + + // print all attributes + if(!ccobj.isAnyAllowed()) { + for (CAttribute cattribute : ccobj.getAttributes()) { + printCAttribute(cattribute, children); + } + } + + } + + protected void printConstraintRef(ConstraintRef ref, Element out) { + Element children = new Element("children", defaultNamespace); + out.getChildren().add(children); + children.setAttribute("type", "CONSTRAINT_REF", xsiNamespace); + printCObjectElements(ref, children); + printString("reference", ref.getReference(), children); + } + + protected void printArchetypeInternalRef(ArchetypeInternalRef ref, Element out) { + + Element children = new Element("children", defaultNamespace); + out.getChildren().add(children); + children.setAttribute("type", "ARCHETYPE_INTERNAL_REF", xsiNamespace); + + printCObjectElements(ref, children); + printString("target_path", ref.getTargetPath(), children); + } + + protected void printArchetypeSlot(ArchetypeSlot slot, Element out) { + + Element children = new Element("children", defaultNamespace); + out.getChildren().add(children); + children.setAttribute("type", "ARCHETYPE_SLOT", xsiNamespace); + + printCObjectElements(slot, children); + + // print all attributes + if (!slot.isAnyAllowed()) { + if (slot.getIncludes() != null) { + for (Assertion include : slot.getIncludes()) { + Element includes = new Element("includes", defaultNamespace); + children.getChildren().add(includes); + printAssertion(include, includes); + } + } + + if (slot.getExcludes() != null) { + for (Assertion exclude : slot.getExcludes()) { + Element excludes = new Element("excludes", defaultNamespace); + children.getChildren().add(excludes); + printAssertion(exclude, excludes); + } + } + } + } + + protected void printAssertion(Assertion assertion, Element out) { + + if (assertion.getTag() != null) { // must not be displayed at all if null according to spec. + printString("tag", assertion.getTag(), out); + } + printString("string_expression", assertion.getStringExpression(), out); + printExpressionItem("expression", assertion.getExpression(), out); + + if(assertion.getVariables() != null) { + List variables = assertion.getVariables(); + + for(AssertionVariable var : variables) { + Element vars = new Element("variables", defaultNamespace); + out.getChildren().add(vars); + printString("name", var.getName(), vars); + printString("definition", var.getDefinition(), vars); + } + } + } + + protected void printExpressionItem(String label, ExpressionItem expItem, Element out) { + + if(expItem instanceof ExpressionLeaf) { + printExpressionLeaf(label, (ExpressionLeaf) expItem, out); + } else if(expItem instanceof ExpressionOperator) { + printExpressionOperator(label, (ExpressionOperator) expItem, out); + } else { + // unknown ExpressionItem + Element elm = new Element(label, defaultNamespace); + out.getChildren().add(elm); + elm.setAttribute("type", "EXPR_ITEM", xsiNamespace); + + printString("type", expItem.getType(), elm); + } + } + + protected void printExpressionLeaf(String label, ExpressionLeaf expLeaf, Element out) { + + Element elm = new Element(label, defaultNamespace); + out.getChildren().add(elm); + elm.setAttribute("type", "EXPR_LEAF", xsiNamespace); + + printString("type", expLeaf.getType(), elm); + if (expLeaf.getItem() instanceof CPrimitive) { + Element item = new Element("item", defaultNamespace); + elm.getChildren().add(item); + printCPrimitive((CPrimitive) expLeaf.getItem(), item); + } else { + //EXPR_LEAF.item is defined as xs:any in the AM schema (the reason for which is unclear) + //and consequently of type object in C# land. + // That's why having the XSD type explicitly set to string fixes the problem when deserialising to a C# string instead of XmlText. + printString("item", expLeaf.getItem().toString(), elm, true); + } + printString("reference_type", expLeaf.getReferenceType().name().toLowerCase(), elm); // the Reference type is expected in lower case here as per spec examples + } + + protected void printExpressionOperator(String label, ExpressionOperator expOperator, Element out) { + Element elm = new Element(label, defaultNamespace); + out.getChildren().add(elm); + if(expOperator instanceof ExpressionUnaryOperator) { + elm.setAttribute("type", "EXPR_UNARY_OPERATOR", xsiNamespace); + printExpressionOperatorElements(expOperator, elm); + printExpressionItem("operand", ((ExpressionUnaryOperator)expOperator).getOperand(), elm); + } else if(expOperator instanceof ExpressionBinaryOperator) { + final ExpressionBinaryOperator expBinaryOperator = (ExpressionBinaryOperator)expOperator; + elm.setAttribute("type", "EXPR_BINARY_OPERATOR", xsiNamespace); + printExpressionOperatorElements(expOperator, elm); + printExpressionItem("left_operand", expBinaryOperator.getLeftOperand(), elm); + printExpressionItem("right_operand", expBinaryOperator.getRightOperand(), elm); + } else { + // unknown ExpressionOperator + elm.setAttribute("type", "EXPR_OPERATOR", xsiNamespace); + printExpressionOperatorElements(expOperator, elm); + } + } + + protected void printExpressionOperatorElements(ExpressionOperator expOperator, Element out) { + + printString("type", expOperator.getType(), out); + printString("operator", String.valueOf(expOperator.getOperator().getValue()), out); + printString("precedence_overridden", + expOperator.isPrecedenceOverridden() == true ? "true" : "false", out); + } + + protected void printCAttribute(CAttribute cattribute, Element out) { + + final boolean isMultipleAttribute; + + if (cattribute instanceof CMultipleAttribute) { + isMultipleAttribute = true; + } else { + isMultipleAttribute = false; + } + + Element attributes = new Element("attributes", defaultNamespace); + out.getChildren().add(attributes); + if(isMultipleAttribute) { + attributes.setAttribute("type", "C_MULTIPLE_ATTRIBUTE", xsiNamespace); + } else { + attributes.setAttribute("type", "C_SINGLE_ATTRIBUTE", xsiNamespace); + } + + // FIXME: AOM XML schema spec is wrong. Has 'unbounded' attribute for C_ATTRIBUTE and element with name + // 'rm_type_name' instead of 'rm_attribute_name'. + printString("rm_attribute_name", cattribute.getRmAttributeName(), attributes); + + Element existence = new Element("existence", defaultNamespace); + attributes.getChildren().add(existence); + + printString("lower_included", "true", existence); + printString("upper_included", "true", existence); + + printString("lower_unbounded", "false", existence); + printString("upper_unbounded", "false", existence); + + int lower = 0, upper = 0; + + if(cattribute.getExistence().equals(CAttribute.Existence.REQUIRED)) { + lower = 1; + upper = 1; + } else if(cattribute.getExistence().equals(CAttribute.Existence.OPTIONAL)) { + lower = 0; + upper = 1; + } + printString("lower", Integer.toString(lower), existence); + printString("upper", Integer.toString(upper), existence); + + if(!cattribute.isAnyAllowed()) { + List children = cattribute.getChildren(); + + if (children.size() > 1 + || !(children.get(0) instanceof CPrimitiveObject)) { + for (CObject cobject : cattribute.getChildren()) { + printCObject(cobject, attributes); + } + } else { + CObject child = children.get(0); + printCPrimitiveObject((CPrimitiveObject) child, attributes); + } + } + + if(isMultipleAttribute) { + Element cardinality = new Element("cardinality", defaultNamespace); + attributes.getChildren().add(cardinality); + printCardinality( + ((CMultipleAttribute) cattribute).getCardinality(), cardinality); + } + + } + + protected void printCObject(CObject cobj, Element out) { + + // print specialised types + if (cobj instanceof CDomainType) { + printCDomainType((CDomainType) cobj, out); + } else if (cobj instanceof CPrimitiveObject) { + printCPrimitiveObject((CPrimitiveObject) cobj, out); + } else if (cobj instanceof CComplexObject) { + printCComplexObject((CComplexObject) cobj, out); + } else if (cobj instanceof ArchetypeInternalRef) { + printArchetypeInternalRef((ArchetypeInternalRef) cobj, out); + } else if (cobj instanceof ConstraintRef) { // FIXME: Add in ADLSerializer as well + printConstraintRef((ConstraintRef) cobj, out); + } else if (cobj instanceof ArchetypeSlot) { + printArchetypeSlot((ArchetypeSlot) cobj, out); + } + } + + protected void printCObjectElements(CObject cobj, Element out) { + + // we always need the upper case with underscore notation for the rm type name + printString("rm_type_name", getUpperCaseWithUnderscoreFromCamelCase(cobj.getRmTypeName()), out); + printOccurrences(cobj.getOccurrences(), out); + printString("node_id", cobj.getNodeId(), out); + } + + protected void printOccurrences(Interval occurrences, Element out) { + + if (occurrences == null) { + return; + } + + Element occurs = new Element("occurrences", defaultNamespace); + out.getChildren().add(occurs); + printInterval(occurrences, occurs); + } + + protected void printCardinality(Cardinality cardinality, Element out) { + + if (cardinality.isOrdered()) { + printString("is_ordered", "true", out); + } else { + printString("is_ordered", "false", out); + } + + if (cardinality.isUnique()) { + printString("is_unique", "true", out); + } else { + printString("is_unique", "false", out); + } + + Element interval = new Element("interval", defaultNamespace); + out.getChildren().add(interval); + printInterval(cardinality.getInterval(), interval); + } + + protected void printCDomainType(CDomainType cdomain, Element out) { + + if (cdomain instanceof CCodePhrase) { + printCCodePhrase((CCodePhrase) cdomain, out); + } else if (cdomain instanceof CDvOrdinal) { + printCDvOrdinal((CDvOrdinal) cdomain, out); + } else if (cdomain instanceof CDvScale) { + printCDvScale((CDvScale) cdomain, out); + } else if (cdomain instanceof CDvQuantity) { + printCDvQuantity((CDvQuantity) cdomain, out); + } else { + // unknown CDomainType + System.err.println("Cannot serialize CDomainType of type '" + cdomain.getClass().getName() + "'!"); + } + } + + protected void printCCodePhrase(CCodePhrase ccp, Element out) { + + Element children = new Element("children", defaultNamespace); + out.getChildren().add(children); + children.setAttribute("type", "C_CODE_PHRASE", xsiNamespace); + + printCObjectElements(ccp, children); + + if (ccp.hasAssumedValue()) { + CodePhrase assumedValue= ccp.getAssumedValue(); + + Element assumedValueEl = new Element("assumed_value", defaultNamespace); + children.getChildren().add(assumedValueEl); + printCodePhrase(assumedValue, assumedValueEl); + } + + if(ccp.getTerminologyId() != null) { + Element terminologyId = new Element("terminology_id", defaultNamespace); + children.getChildren().add(terminologyId); + printString("value", ccp.getTerminologyId().getValue(), terminologyId); + } + + if (ccp.getCodeList() != null) { + final List codeList = ccp.getCodeList(); + + for (int i = 0, j = codeList.size(); i < j; i++) { + printString("code_list", codeList.get(i), children); + } + } + + } + + protected void printCDvOrdinal(CDvOrdinal cordinal, Element out) { + Element children = new Element("children", defaultNamespace); + out.getChildren().add(children); + children.setAttribute("type", "C_DV_ORDINAL", xsiNamespace); + + printCObjectElements(cordinal, children); + if (cordinal.hasAssumedValue()) { + Ordinal assumedValue = cordinal.getAssumedValue(); + Element assumedValueEl = new Element("assumed_value", defaultNamespace); + children.getChildren().add(assumedValueEl); + printString("value", String.valueOf(assumedValue.getValue()), assumedValueEl); + printSymbolOfOrdinal(assumedValue, assumedValueEl); + + } + if(cordinal.getList() != null) { + final List ordinals = cordinal.getList(); + + Ordinal ordinal; + for (Iterator it = ordinals.iterator(); it.hasNext();) { + ordinal = it.next(); + Element list = new Element("list", defaultNamespace); + children.getChildren().add(list); + printString("value", String.valueOf(ordinal.getValue()), list); + printSymbolOfOrdinal(ordinal, list); + } + } + } + + private void printSymbolOfOrdinal(Ordinal ordinal, Element list) { + Element symbol = new Element("symbol", defaultNamespace); + list.getChildren().add(symbol); + + printString("value", null, symbol); // this is the mandatory(!) value of a DV_CODED_TEXT symbol. + Element definingCode = new Element("defining_code", defaultNamespace); + symbol.getChildren().add(definingCode); + + printCodePhrase(ordinal.getSymbol(), definingCode); + } + + protected void printCDvScale(CDvScale cscale, Element out) { + Element children = new Element("children", defaultNamespace); + out.getChildren().add(children); + children.setAttribute("type", "C_DV_SCALE", xsiNamespace); + + printCObjectElements(cscale, children); + if (cscale.hasAssumedValue()) { + Scale assumedValue = cscale.getAssumedValue(); + Element assumedValueEl = new Element("assumed_value", defaultNamespace); + children.getChildren().add(assumedValueEl); + printString("value", assumedValue.getDisplay(), assumedValueEl); + printSymbolOfScale(assumedValue, assumedValueEl); + + } + if (cscale.getList() != null) { + final List scales = cscale.getList(); + + Scale scale; + for (Iterator it = scales.iterator(); it.hasNext();) { + scale = it.next(); + Element list = new Element("list", defaultNamespace); + children.getChildren().add(list); + printString("value", scale.getDisplay(), list); // we need to use display here, so that we can preserve the the difference between 2 and 2.0 + printSymbolOfScale(scale, list); + } + } + } + + private void printSymbolOfScale(Scale scale, Element list) { + Element symbol = new Element("symbol", defaultNamespace); + list.getChildren().add(symbol); + + printString("value", null, symbol); // this is the mandatory(!) value of a DV_CODED_TEXT symbol. + Element definingCode = new Element("defining_code", defaultNamespace); + symbol.getChildren().add(definingCode); + + printCodePhrase(scale.getSymbol(), definingCode); + } + + protected void printCDvQuantity(CDvQuantity cquantity, Element out) { + Element children = new Element("children", defaultNamespace); + out.getChildren().add(children); + children.setAttribute("type", "C_DV_QUANTITY", xsiNamespace); + + printCObjectElements(cquantity, children); + + if (cquantity.hasAssumedValue()) { + + Element assumedValueEl = new Element("assumed_value", defaultNamespace); + children.getChildren().add(assumedValueEl); + + DvQuantity assumedValue = cquantity.getAssumedValue(); + + if(assumedValue.getMagnitude() != null) { + printString("magnitude", ""+assumedValue.getMagnitude(), assumedValueEl); + } + if(assumedValue.getUnits() != null) { + printString("units", assumedValue.getUnits(), assumedValueEl); + } + printString("precision", ""+assumedValue.getPrecision(), assumedValueEl); + + + } + + CodePhrase property = cquantity.getProperty(); + if (property != null) { + Element prop = new Element("property", defaultNamespace); + children.getChildren().add(prop); + printCodePhrase(property, prop); + } + + if (cquantity.getList() != null) { + final List list = cquantity.getList(); + + for (CDvQuantityItem item : list) { + Element lst = new Element("list", defaultNamespace); + children.getChildren().add(lst); + + printMagnitudePrecisionUnitsOfCDVQuantityItem(item, lst); + } + } + } + + private void printMagnitudePrecisionUnitsOfCDVQuantityItem(CDvQuantityItem item, Element lst) { + if(item.getMagnitude() != null) { + Element magnitude = new Element("magnitude", defaultNamespace); + lst.getChildren().add(magnitude); + printInterval(item.getMagnitude(), magnitude); + } + if(item.getPrecision() != null) { + Element precision = new Element("precision", defaultNamespace); + lst.getChildren().add(precision); + printInterval(item.getPrecision(), precision); + } + + printString("units", item.getUnits(), lst); + } + + protected void printOntology(ArchetypeOntology ontology, String concept, Element out) { + + if(ontology == null) { + return; + } + + Element onto = new Element("ontology", defaultNamespace); + out.getChildren().add(onto); + + + // TODO: Check why this is not in the XML schema specification of the AOM. + //printString("primary_language", ontology.getPrimaryLanguage(), 2, out); + // TODO: Check why this is not in the XML schema specification of the AOM. + //printStringList("languages_available", ontology.getLanguages(), 2, out); + //printStringList("terminologies_available", ontology.getTerminologies(), 2, out); + //final int specDepth = StringUtils.countMatches(".", concept); + //printString("specialisation_depth", String.valueOf(specDepth), 2, out); + + + if(ontology.getTermDefinitionsList() != null) { + final List termDefinitions = ontology.getTermDefinitionsList(); + + for (OntologyDefinitions defs : termDefinitions) { + Element trmDefinitions = new Element("term_definitions", defaultNamespace); + onto.getChildren().add(trmDefinitions); + trmDefinitions.setAttribute("language", defs.getLanguage()); + + for (ArchetypeTerm term : defs.getDefinitions()) { + Element items = new Element("items", defaultNamespace); + trmDefinitions.getChildren().add(items); + items.setAttribute("code", term.getCode()); + + printStringMap("items", term.getItems(), items); + } + + } + } + + if(ontology.getConstraintDefinitionsList() != null) { + final List constraintDefinitions = ontology.getConstraintDefinitionsList(); + + for (OntologyDefinitions defs : constraintDefinitions) { + Element consDefinitions = new Element("constraint_definitions", defaultNamespace); + onto.getChildren().add(consDefinitions); + consDefinitions.setAttribute("language", defs.getLanguage()); + + for (ArchetypeTerm term : defs.getDefinitions()) { + Element items = new Element("items", defaultNamespace); + consDefinitions.getChildren().add(items); + items.setAttribute("code", term.getCode()); + + printStringMap("items", term.getItems(), items); + } + } + } + + if (ontology.getTermBindingList() != null) { + final List termBindings = ontology.getTermBindingList(); + + TermBindingItem item; + for (OntologyBinding bind : termBindings) { + Element trmBindings = new Element("term_bindings", defaultNamespace); + onto.getChildren().add(trmBindings); + trmBindings.setAttribute("terminology", bind.getTerminology()); + + for (OntologyBindingItem bindItem : bind.getBindingList()) { + item = (TermBindingItem) bindItem; + + for(String value : item.getTerms()) { + Element items = new Element("items", defaultNamespace); + trmBindings.getChildren().add(items); + items.setAttribute("code", item.getCode()); + Element vl = new Element("value", defaultNamespace); + items.getChildren().add(vl); + + String terminologyId = value.substring(1, value.lastIndexOf("::")); + String codeString = value.substring(value.lastIndexOf("::") + 2, value.length() - 1); + Element termId = new Element("terminology_id", defaultNamespace); + vl.getChildren().add(termId); + printString("value", terminologyId, termId); + printString("code_string", codeString, vl); + } + } + } + } + + if (ontology.getConstraintBindingList() != null) { + final List constraintBindings = ontology.getConstraintBindingList(); + + QueryBindingItem item; + for (OntologyBinding bind : constraintBindings) { + Element consBindings = new Element("constraint_bindings", defaultNamespace); + onto.getChildren().add(consBindings); + consBindings.setAttribute("terminology", bind.getTerminology()); + + for (OntologyBindingItem bindItem : bind.getBindingList()) { + item = (QueryBindingItem) bindItem; + Element items = new Element("items", defaultNamespace); + consBindings.getChildren().add(items); + items.setAttribute("code", item.getCode()); + printString("value", item.getQuery().getUrl(), items); + } + + } + } + } + + protected void printCPrimitiveObject(CPrimitiveObject cpo, Element out) { + CPrimitive cp = cpo.getItem(); + if (cp == null) { + return; + } + + Element children = new Element("children", defaultNamespace); + out.getChildren().add(children); + children.setAttribute("type", "C_PRIMITIVE_OBJECT", xsiNamespace); + + printCObjectElements(cpo, children); + + Element item = new Element("item", defaultNamespace); + children.getChildren().add(item); + printCPrimitive(cp, item); + } + + protected void printCPrimitive(CPrimitive cp, Element out) { + + if (cp instanceof CBoolean) { + out.setAttribute("type", "C_BOOLEAN", xsiNamespace); + printCBoolean((CBoolean) cp, out); + } else if (cp instanceof CDate) { + out.setAttribute("type", "C_DATE", xsiNamespace); + printCDate((CDate) cp, out); + } else if (cp instanceof CDateTime) { + out.setAttribute("type", "C_DATE_TIME", xsiNamespace); + printCDateTime((CDateTime) cp, out); + } else if (cp instanceof CTime) { + out.setAttribute("type", "C_TIME", xsiNamespace); + printCTime((CTime) cp, out); + } else if (cp instanceof CDuration) { + out.setAttribute("type", "C_DURATION", xsiNamespace); + printCDuration((CDuration) cp, out); + } else if (cp instanceof CInteger) { + out.setAttribute("type", "C_INTEGER", xsiNamespace); + printCInteger((CInteger) cp, out); + } else if (cp instanceof CReal) { + out.setAttribute("type", "C_REAL", xsiNamespace); + printCReal((CReal) cp, out); + } else if (cp instanceof CString) { + out.setAttribute("type", "C_STRING", xsiNamespace); + printCString((CString) cp, out); + } else { + out.setAttribute("type", "C_PRIMITIVE", xsiNamespace); + System.err.println("Cannot serialize CPrimitive of type '" + cp.getClass().getName() + "'!"); + } + + } + + protected void printCBoolean(CBoolean cboolean, Element out) { + + printString("true_valid", cboolean.isTrueValid() == true ? + "true" : "false", out); + printString("false_valid", cboolean.isFalseValid() == true ? + "true" : "false", out); + + if(cboolean.hasAssumedValue()) { + printString("assumed_value", cboolean.assumedValue().booleanValue() == true ? + "true" : "false", out); + } + } + + protected void printCDate(CDate cdate, Element out) { + + if (cdate.getPattern() != null) { + printString("pattern", cdate.getPattern(), out); + } + + if(cdate.getInterval() != null) { + Element range = new Element("range", defaultNamespace); + out.getChildren().add(range); + printInterval(cdate.getInterval(), range); + } + + if(cdate.hasAssumedValue()) { + printString("assumed_value", cdate.assumedValue().toString(), out); + } + } + + protected void printCDateTime(CDateTime cdatetime, Element out) { + + if (cdatetime.getPattern() != null) { + printString("pattern", cdatetime.getPattern(), out); + } + + // FIXME: Output timezone_validity. CDateTime seem to be missing this function. + + if(cdatetime.getInterval() != null) { + Element range = new Element("range", defaultNamespace); + out.getChildren().add(range); + printInterval(cdatetime.getInterval(), range); + } + + if(cdatetime.hasAssumedValue()) { + printString("assumed_value", cdatetime.assumedValue().toString(), out); + } + } + + protected void printCTime(CTime ctime, Element out) { + + if (ctime.getPattern() != null) { + printString("pattern", ctime.getPattern(), out); + } + + // FIXME: Output timezone_validity. CTime seem to be missing this function. + + if(ctime.getInterval() != null) { + Element range = new Element("range", defaultNamespace); + out.getChildren().add(range); + printInterval(ctime.getInterval(), range); + } + + if(ctime.hasAssumedValue()) { + printString("assumed_value", ctime.assumedValue().toString(), out); + } + } + + protected void printCDuration(CDuration cduration, Element out) { + + if (cduration.getPattern() != null) { + printString("pattern", cduration.getPattern().toString(), out); + } + Element range = new Element("range", defaultNamespace); + out.getChildren().add(range); + if(cduration.getInterval() != null) { + printInterval(cduration.getInterval(), range); + } else { + // these should be supplied even for a null range + printString("lower_unbounded", "true", range); + printString("upper_unbounded", "true", range); + } + + if(cduration.hasAssumedValue()) { + printString("assumed_value", cduration.assumedValue().toString(), out); + } + } + + protected void printCInteger(CInteger cinteger, Element out) { + + if(cinteger.getList() != null) { + printList(cinteger.getList(), out); + } + + if(cinteger.getInterval() != null) { + Element range = new Element("range", defaultNamespace); + out.getChildren().add(range); + printInterval(cinteger.getInterval(), range); + } + + // TODO: Write 'list_open' element... xs:boolean [0..1] + + if(cinteger.hasAssumedValue()) { + printString("assumed_value", cinteger.assumedValue().toString(), out); + } + } + + protected void printCReal(CReal creal, Element out) { + + if (creal.getList() != null) { + printList(creal.getList(), out); + } + + if(creal.getInterval() != null) { + Element range = new Element("range", defaultNamespace); + out.getChildren().add(range); + printInterval(creal.getInterval(), range); + } + + if(creal.hasAssumedValue()) { + printString("assumed_value", creal.assumedValue().toString(), out); + } + } + + protected void printCString(CString cstring, Element out) { + + if(cstring.getPattern() != null) { + printString("pattern", cstring.getPattern(), out); + } + + if(cstring.getList() != null){ + printList(cstring.getList(), out); + } + + // TODO: Write 'list_open' element... xs:boolean [0..1] + + if(cstring.hasAssumedValue()) { + printString("assumed_value", cstring.assumedValue().toString(), out); + } + } + + protected void printList(List list, Element out) { + + if(list == null) { + return; + } + + for(int i = 0, j = list.size(); i < j; i++) { + printString("list", list.get(i).toString(), out); + } + } + + @SuppressWarnings("unchecked") + protected void printInterval(Interval interval, Element out) { + if(interval == null) { + return; + } + + final Comparable lower = interval.getLower(); + final Comparable upper = interval.getUpper(); + + if (! interval.isLowerUnbounded()) { // not included is implied if unbounded + printString("lower_included", + interval.isLowerIncluded() == true ? "true" : "false", + out); + } + if (! interval.isUpperUnbounded()) { // not included is implied if unbounded + printString("upper_included", + interval.isUpperIncluded() == true ? "true" : "false", + out); + } + + + printString("lower_unbounded", + interval.isLowerUnbounded() ? "true" : "false", out); + + printString("upper_unbounded", + interval.isUpperUnbounded() ? "true" : "false", out); + + if(lower != null) { + printString("lower", lower.toString(), out); + } + + if(upper != null) { + printString("upper", upper.toString(), out); + } + + } + + private String getUpperCaseWithUnderscoreFromCamelCase(String str) { + if( str == null || str.length() == 0 ) { + return str; + } + + StringBuffer result = new StringBuffer(); + + char prevChar = 'A'; // init with an upper case letter + /* + * Change underscore to space, insert space before capitals + */ + for( int i = 0; i < str.length(); i++ ) { + char c = str.charAt( i ); + if(! Character.isUpperCase(prevChar) && + !(prevChar=='<') && // without this DV_INTERVAL --> DV_INTERVAL<_DV_QUANTITY> + !(prevChar=='_') && + Character.isLetter(c) && + Character.isUpperCase(c)) + { + result.append("_"); + result.append( Character.toUpperCase( c ) ); + } + else { + result.append( Character.toUpperCase( c ) ); + } + prevChar = c; + } + + return result.toString(); + + + + } + + /* charset encodings */ + public static final Charset UTF8 = Charset.forName("UTF-8"); + + public static final Charset LATIN1 = Charset.forName("ISO-8859-1"); + + public static final Namespace defaultNamespace = Namespace.getNamespace("http://schemas.openehr.org/v1"); + + public static final Namespace xsiNamespace = Namespace.getNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"); + + public static final Namespace xsdNamespace = Namespace.getNamespace("xsd", "http://www.w3.org/2001/XMLSchema"); + + /* fields */ + private Charset encoding; + + private XMLOutputter outputter; +} + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is XMLSerializer. + * + * The Initial Developer of the Original Code is + * Link�pings universitet, Sweden. + * Portions created by the Initial Developer are Copyright (C) 2005-2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Mattias Forss + * Rong Chen + * Erik Sundvall + * Humberto Naves + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * * ***** END LICENSE BLOCK ***** */ \ No newline at end of file