From 0d34816e5057e7597f1f6d56978f20da174d33dc Mon Sep 17 00:00:00 2001 From: Bert Verhees Date: Tue, 3 Sep 2013 10:37:30 +0200 Subject: [PATCH 001/213] repaired: 1) use of PQ units in EN13606 archetypes. 2) use of atCode at archetype_internal_ref, for use with LinkEHR-edited archetypes. --- adl-parser/src/main/javacc/adl.jj | 34 +++++++++++-------- ...test-entry.archetype_internal_ref.test.adl | 4 +++ 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/adl-parser/src/main/javacc/adl.jj b/adl-parser/src/main/javacc/adl.jj index cc12c25d..5d672872 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"> } @@ -2317,20 +2316,23 @@ ConstraintRef constraint_ref_obj(String path, CAttribute parent) : } } -ArchetypeInternalRef archetype_internal_ref(String path, CAttribute parent) : +ArchetypeInternalRef archetype_internal_ref(String path, CAttribute +parent) : { - String type; - Interval occurrences = new Interval(1, 1); - String target; + 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() ] + target = absolute_path() + { + return new ArchetypeInternalRef(path, type, occurrences, nodeID, parent, + target); + } } ArchetypeSlot archetype_slot(String path, CAttribute parent) : @@ -2988,7 +2990,7 @@ CDvQuantityItem c_dv_quantity_item() : { "[" string_value() "]" "<" - (|) "<" + () "<" units = string_value() ">" @@ -3217,9 +3219,11 @@ CDuration c_duration() : } String duration_pattern() : -{ Token t = null; +{ + Token t = null; } -{ t = +{ + t = { return t.image; } } 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 index da16b430..c7bc6d86 100755 --- 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 From a52e4bcc0f46f22ec3e6b22c3696a1c5a002bc1d Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Mon, 16 Sep 2013 10:29:30 +0200 Subject: [PATCH 002/213] * joda time dependency update --- INSTALL.txt | 4 +++ openehr-rm-core/pom.xml | 2 +- pom.xml | 1 - .../openehr/rm/util/SkeletonGenerator.java | 26 ++++++++++++------- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/INSTALL.txt b/INSTALL.txt index a5e4b9be..4589e0b7 100755 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -1,3 +1,7 @@ +REQUIREMENTS: + +Java 1.6 or higher +Maven 3.0.4 or higher INSTALATION INSTRUCTIONS: diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index d762ed15..50bba5b4 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -28,7 +28,7 @@ joda-time joda-time - 1.3 + 2.2 junit diff --git a/pom.xml b/pom.xml index 8dc877a8..a41965e2 100755 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,6 @@ true - 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..17cedaf5 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 @@ -13,16 +13,15 @@ */ package org.openehr.rm.util; -import java.io.FileInputStream; -import java.io.InputStream; -import java.util.*; - import org.apache.log4j.Logger; import org.openehr.am.archetype.Archetype; import org.openehr.am.archetype.constraintmodel.*; import org.openehr.am.archetype.constraintmodel.primitive.*; import org.openehr.am.archetype.ontology.ArchetypeTerm; -import org.openehr.am.openehrprofile.datatypes.quantity.*; +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.am.template.TermMap; import org.openehr.build.RMObjectBuilder; @@ -36,17 +35,26 @@ import org.openehr.rm.datatypes.quantity.DvOrdinal; import org.openehr.rm.datatypes.quantity.DvQuantity; import org.openehr.rm.datatypes.quantity.ProportionKind; -import org.openehr.rm.datatypes.quantity.datetime.*; +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 org.openehr.rm.datatypes.uri.DvURI; -import org.openehr.rm.support.identification.*; -import org.openehr.rm.support.measurement.*; +import org.openehr.rm.support.identification.HierObjectID; +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.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; +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.*; + public class SkeletonGenerator { /** @@ -645,7 +653,7 @@ public Object createObject(CObject cobj, Archetype archetype, } else if(cobj instanceof CDomainType) { return createDomainTypeObject((CDomainType) cobj, archetype); - + } else { // TODO skip archetype_slot etc, log.warn? return null; From 6a36debc8d0f792979ed7dcd79facb0715958bbc Mon Sep 17 00:00:00 2001 From: Samuel Frade Date: Mon, 23 Sep 2013 15:28:16 +0100 Subject: [PATCH 003/213] RM-Skeleton multiple events fix fix for multiple events where the data attribute of the events is an InternalRef to the first event described --- .../openehr/rm/util/SkeletonGenerator.java | 41 +- .../java/org/openehr/rm/util/TestEvents.java | 25 + .../adl/openEHR-EHR-OBSERVATION.apgar.v1.adl | 1422 +++++++++++++++++ 3 files changed, 1471 insertions(+), 17 deletions(-) create mode 100644 rm-skeleton/src/test/java/org/openehr/rm/util/TestEvents.java create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.apgar.v1.adl 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 17cedaf5..999f1ee8 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 @@ -13,15 +13,16 @@ */ package org.openehr.rm.util; +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.*; + import org.apache.log4j.Logger; import org.openehr.am.archetype.Archetype; import org.openehr.am.archetype.constraintmodel.*; import org.openehr.am.archetype.constraintmodel.primitive.*; import org.openehr.am.archetype.ontology.ArchetypeTerm; -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.quantity.*; import org.openehr.am.openehrprofile.datatypes.text.CCodePhrase; import org.openehr.am.template.TermMap; import org.openehr.build.RMObjectBuilder; @@ -35,26 +36,17 @@ import org.openehr.rm.datatypes.quantity.DvOrdinal; import org.openehr.rm.datatypes.quantity.DvQuantity; import org.openehr.rm.datatypes.quantity.ProportionKind; -import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; -import org.openehr.rm.datatypes.quantity.datetime.DvDuration; +import org.openehr.rm.datatypes.quantity.datetime.*; 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.datatypes.uri.DvURI; -import org.openehr.rm.support.identification.HierObjectID; -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.measurement.MeasurementService; -import org.openehr.rm.support.measurement.SimpleMeasurementService; +import org.openehr.rm.support.identification.*; +import org.openehr.rm.support.measurement.*; import org.openehr.rm.support.terminology.TerminologyAccess; import org.openehr.rm.support.terminology.TerminologyService; import org.openehr.terminology.SimpleTerminologyService; -import java.io.FileInputStream; -import java.io.InputStream; -import java.util.*; - public class SkeletonGenerator { /** @@ -653,13 +645,28 @@ 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? return null; } } + //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 { 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/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]> + > + > + > From 741236de87375f0fa6d3fc3d7a5c2c4c2c145ecb Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Wed, 25 Sep 2013 12:46:34 +0200 Subject: [PATCH 004/213] * Archetype validator --- .../am/validation/ArchetypeValidator.java | 1526 +++++++++++++++++ .../org/openehr/am/validation/ErrorType.java | 79 + .../am/validation/RMInspectionException.java | 11 + .../openehr/am/validation/RMInspector.java | 583 +++++++ .../SpecialisedArchetypeValidator.java | 755 ++++++++ .../openehr/am/validation/UTF8Control.java | 61 + .../am/validation/ValidationError.java | 139 ++ .../src/main/resources/log4j.properties | 9 + .../src/main/resources/validations.properties | 111 ++ .../src/main/resources/validations.txt | 34 + .../main/resources/validations_de.properties | 111 ++ .../main/resources/validations_en.properties | 2 + .../main/resources/validations_ru.properties | 111 ++ .../ArchetypeDefinitionCodeCheckTest.java | 20 + .../ArchetypeInternalRefCheckTest.java | 58 + .../am/validation/ArchetypeSlotCheckTest.java | 24 + .../validation/ArchetypeTermValidityTest.java | 68 + .../ArchetypeValidationTestBase.java | 94 + .../am/validation/AssumedValueTest.java | 27 + .../am/validation/AttributeNameCheckTest.java | 48 + .../CodeConstraintValidityTest.java | 48 + .../DefinitionTypenameCheckTest.java | 24 + ...alueAttributeChildIdentifierCheckTest.java | 31 + ...MultipleValueAttributeCardinalityTest.java | 56 + .../OntologyCodeSpecialisationCheckTest.java | 37 + .../OntologyTranslationCheckTest.java | 53 + .../am/validation/RMInspectorTest.java | 78 + ...alueAttributeChildIdentifierCheckTest.java | 21 + ...lueAttributeChildOccurrencesCheckTest.java | 26 + ...alueAttributeChildUniquenessCheckTest.java | 27 + .../SpecialisedArchetypeCardinalityTest.java | 22 + .../SpecialisedArchetypeExistenceTest.java | 18 + .../SpecialisedArchetypeMultiplicityTest.java | 18 + ...ialisedArchetypeNodeIdConformanceTest.java | 17 + ...rchetypeNodeSpecialisedAsRequiredTest.java | 18 + ...ialisedArchetypeNonCComplexObjectTest.java | 20 + .../SpecialisedArchetypeOccurrencesTest.java | 18 + .../SpecialisedArchetypeTermExistsTest.java | 34 + ...pecialisedArchetypeValidationTestBase.java | 68 + .../SpecialisedArchetypeWrongRMTypeTest.java | 29 + .../SpecializationArchetypeIdTest.java | 32 + .../SpecializationDepthCheckTest.java | 63 + .../validation/TermBindingsValidityTest.java | 27 + .../am/validation/TypeNameCheckTest.java | 137 ++ .../UniqueSiblingAttributesCheckTest.java | 25 + .../ValidateOpenEHRTerminologyCodesTest.java | 15 + .../am/validation/ValidatorUtilityTest.java | 52 + ...ised-EVALUATION.cardinality-specialised.v1 | 63 + ...ised-EVALUATION.cardinality-specialised.v2 | 63 + .../adl-specialised-EVALUATION.cardinality.v1 | 55 + ...alised-EVALUATION.existence-specialised.v1 | 67 + .../adl-specialised-EVALUATION.existence.v1 | 55 + ...sed-EVALUATION.multiplicity-specialised.v1 | 63 + ...adl-specialised-EVALUATION.multiplicity.v1 | 55 + ...N.node_id_conformance-specialised-again.v1 | 67 + ...LUATION.node_id_conformance-specialised.v1 | 59 + ...ode_specialised_as_required-specialised.v1 | 59 + ...EVALUATION.node_specialised_as_required.v1 | 55 + ...ised-EVALUATION.occurrences-specialised.v1 | 67 + .../adl-specialised-EVALUATION.occurrences.v1 | 55 + ...d-EVALUATION.term_existence-specialised.v1 | 59 + ...d-EVALUATION.term_existence-specialised.v2 | 59 + ...l-specialised-EVALUATION.term_existence.v1 | 64 + ...l-specialised-EVALUATION.term_existence.v2 | 51 + ...ised-EVALUATION.wrongrmtype-specialised.v1 | 110 ++ ...ised-EVALUATION.wrongrmtype-specialised.v2 | 65 + ...ised-EVALUATION.wrongrmtype-specialised.v3 | 61 + .../adl-specialised-EVALUATION.wrongrmtype.v1 | 92 + .../adl-specialised-EVALUATION.wrongrmtype.v2 | 55 + .../adl-specialised-EVALUATION.wrongrmtype.v3 | 58 + ...-test-ELEMENT.assumed_value_boolean.v1.adl | 29 + ...dl-test-ELEMENT.assumed_value_count.v1.adl | 29 + ...test-ELEMENT.assumed_value_quantity.v1.adl | 40 + ...-ELEMENT.specialization-archetypeid.v1.adl | 32 + ...-ELEMENT.specialization-archetypeid.v2.adl | 32 + ...-ELEMENT.specialization-archetypeid.v3.adl | 32 + ...l-test-ELEMENT.specialization-depth.v1.adl | 32 + ...l-test-ELEMENT.specialization-depth.v2.adl | 32 + ...l-test-ELEMENT.specialization-depth.v3.adl | 32 + ...l-test-ELEMENT.specialization-depth.v4.adl | 36 + ...l-test-ELEMENT.specialization-depth.v5.adl | 42 + .../adl-test-ELEMENT.specialization.v1.adl | 25 + .../adl-test-ELEMENT.type_boolean.v1.adl | 29 + .../adl-test-ELEMENT.type_count.v1.adl | 29 + .../adl-test-ELEMENT.type_date.v1.adl | 29 + .../adl-test-ELEMENT.type_date.v2.adl | 25 + .../adl-test-ELEMENT.type_datetime.v1.adl | 29 + .../adl-test-ELEMENT.type_duration.v1.adl | 29 + .../adl-test-ELEMENT.type_ehr_uri.v1.adl | 27 + .../adl-test-ELEMENT.type_interval.v1.adl | 27 + .../adl-test-ELEMENT.type_interval.v2.adl | 37 + .../adl-test-ELEMENT.type_interval.v3.adl | 37 + .../adl-test-ELEMENT.type_interval.v4.adl | 30 + .../adl-test-ELEMENT.type_interval.v5.adl | 30 + .../adl-test-ELEMENT.type_interval.v6.adl | 37 + .../adl-test-ELEMENT.type_multimedia.v1.adl | 36 + .../adl-test-ELEMENT.type_multimedia.v2.adl | 36 + .../resources/adl-test-ELEMENT.type_name.v1 | 29 + .../resources/adl-test-ELEMENT.type_name.v2 | 29 + .../resources/adl-test-ELEMENT.type_name.v3 | 29 + .../adl-test-ELEMENT.type_proportion.v1.adl | 31 + .../adl-test-ELEMENT.type_uri.v1.adl | 27 + .../adl-test-ENTRY.attribute_name.v1 | 39 + .../adl-test-ENTRY.attribute_name.v2 | 39 + .../adl-test-ENTRY.attribute_name.v3 | 36 + .../adl-test-ENTRY.code_constraint.v1 | 35 + .../adl-test-ENTRY.code_constraint.v2 | 25 + .../adl-test-ENTRY.code_constraint.v3 | 56 + .../adl-test-ENTRY.definition_code.v1 | 39 + .../adl-test-ENTRY.definition_code.v2 | 39 + .../adl-test-ENTRY.definition_typename.v1 | 23 + .../adl-test-ENTRY.definition_typename.v2 | 23 + .../adl-test-ENTRY.definition_typename.v3 | 23 + ...-test-ENTRY.ontology-specialisation.v1.adl | 39 + ...-test-ENTRY.ontology-specialisation.v2.adl | 42 + ...-test-ENTRY.ontology-specialisation.v3.adl | 42 + ...-test-ENTRY.ontology-specialisation.v4.adl | 42 + ...-test-ENTRY.ontology-specialisation.v5.adl | 42 + ...adl-test-ENTRY.ontology-unusedcodes.v1.adl | 43 + ...adl-test-ENTRY.ontology-unusedcodes.v2.adl | 51 + .../adl-test-ENTRY.ontology_translation.v1 | 25 + .../adl-test-ENTRY.ontology_translation.v2 | 48 + .../adl-test-ENTRY.ontology_translation.v3 | 56 + .../adl-test-ENTRY.ontology_translation.v4 | 56 + .../adl-test-ENTRY.ontology_translation.v5 | 64 + .../adl-test-ENTRY.ontology_translation.v6 | 71 + .../adl-test-ENTRY.ontology_translation.v7 | 46 + .../resources/adl-test-ENTRY.sibling_nodes.v1 | 38 + .../resources/adl-test-ENTRY.sibling_nodes.v2 | 39 + ...ENTRY.single_attribute_child_identifier.v1 | 54 + ...ENTRY.single_attribute_child_identifier.v2 | 54 + ...NTRY.single_attribute_child_occurrences.v1 | 39 + ...NTRY.single_attribute_child_occurrences.v2 | 39 + ...NTRY.single_attribute_child_occurrences.v3 | 39 + ...ENTRY.single_attribute_child_uniqueness.v1 | 54 + ...ENTRY.single_attribute_child_uniqueness.v2 | 46 + ...ENTRY.single_attribute_child_uniqueness.v3 | 39 + .../resources/adl-test-ENTRY.term_bindings.v1 | 73 + .../resources/adl-test-ENTRY.term_bindings.v2 | 76 + .../adl-test-ENTRY.term_definition.v1 | 19 + .../adl-test-ENTRY.term_definition.v2 | 23 + .../adl-test-ENTRY.term_definition.v3 | 23 + .../adl-test-ENTRY.term_definition.v4 | 36 + ...dl-test-ITEM_TREE.attribute_cardinality.v1 | 36 + ...dl-test-ITEM_TREE.attribute_cardinality.v2 | 45 + ...dl-test-ITEM_TREE.attribute_cardinality.v3 | 40 + ...M_TREE.multi_attribute_child_identifier.v1 | 52 + ...M_TREE.multi_attribute_child_identifier.v2 | 52 + ...M_TREE.multi_attribute_child_identifier.v3 | 52 + .../adl-test-PARTY_PROXY.type_name.v1 | 25 + .../openEHR-EHR-ACTION.follow_up.v1.adl | 46 + ...EHR-CLUSTER.cardinality_occurrences.v1.adl | 69 + ...HR-CLUSTER.cardinality_occurrences2.v1.adl | 69 + ...HR-CLUSTER.cardinality_occurrences3.v1.adl | 69 + ...nEHR-EHR-CLUSTER.internal_reference.v1.adl | 60 + ...HR-CLUSTER.testNonUniqueInternalRef.v1.adl | 54 + ...HR-CLUSTER.testNonUniqueInternalRef.v2.adl | 63 + ...LUSTER.test_non_ccomplexobject-spec.v1.adl | 97 ++ ...EHR-CLUSTER.test_non_ccomplexobject.v1.adl | 61 + ...nEHR-EHR-ELEMENT.doubleontologycode.v1.adl | 48 + .../openEHR-EHR-EVALUATION.adverse.v1.adl | 411 +++++ .../openEHR-EHR-EVALUATION.null_flavor.v1.adl | 90 + ...openEHR-EHR-EVALUATION.null_flavour.v1.adl | 90 + ...HR-EHR-EVALUATION.problem-diagnosis.v1.adl | 897 ++++++++++ ...-EHR-OBSERVATION.internal_reference.v1.adl | 70 + ...-EHR-OBSERVATION.internal_reference.v2.adl | 70 + ...-EHR-OBSERVATION.internal_reference.v3.adl | 70 + ...-EHR-OBSERVATION.internal_reference.v4.adl | 70 + ...-EHR-OBSERVATION.internal_reference.v5.adl | 70 + ...-EHR-OBSERVATION.internal_reference.v6.adl | 150 ++ ...HR-OBSERVATION.order1-order2-order3.v1.adl | 112 ++ ...R-OBSERVATION.order1-order2-order3a.v1.adl | 112 ++ ...enEHR-EHR-OBSERVATION.order1-order2.v1.adl | 99 ++ .../openEHR-EHR-OBSERVATION.slot.v1.adl | 57 + .../openEHR-EHR-OBSERVATION.slot.v2.adl | 57 + .../openEHR-EHR-OBSERVATION.type_name.v4.adl | 43 + pom.xml | 1 + 177 files changed, 12489 insertions(+) create mode 100644 archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java create mode 100644 archetype-validator/src/main/java/org/openehr/am/validation/ErrorType.java create mode 100644 archetype-validator/src/main/java/org/openehr/am/validation/RMInspectionException.java create mode 100644 archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java create mode 100755 archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java create mode 100644 archetype-validator/src/main/java/org/openehr/am/validation/UTF8Control.java create mode 100644 archetype-validator/src/main/java/org/openehr/am/validation/ValidationError.java create mode 100644 archetype-validator/src/main/resources/log4j.properties create mode 100644 archetype-validator/src/main/resources/validations.properties create mode 100644 archetype-validator/src/main/resources/validations.txt create mode 100644 archetype-validator/src/main/resources/validations_de.properties create mode 100644 archetype-validator/src/main/resources/validations_en.properties create mode 100644 archetype-validator/src/main/resources/validations_ru.properties create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeDefinitionCodeCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeInternalRefCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeSlotCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeTermValidityTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeValidationTestBase.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/AssumedValueTest.java create mode 100755 archetype-validator/src/test/java/org/openehr/am/validation/AttributeNameCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/CodeConstraintValidityTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/DefinitionTypenameCheckTest.java create mode 100755 archetype-validator/src/test/java/org/openehr/am/validation/MultiValueAttributeChildIdentifierCheckTest.java create mode 100755 archetype-validator/src/test/java/org/openehr/am/validation/MultipleValueAttributeCardinalityTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/OntologyCodeSpecialisationCheckTest.java create mode 100755 archetype-validator/src/test/java/org/openehr/am/validation/OntologyTranslationCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/RMInspectorTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SingleValueAttributeChildIdentifierCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SingleValueAttributeChildOccurrencesCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SingleValueAttributeChildUniquenessCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeCardinalityTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeExistenceTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeMultiplicityTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeNodeIdConformanceTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeNodeSpecialisedAsRequiredTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeNonCComplexObjectTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeOccurrencesTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeTermExistsTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeValidationTestBase.java create mode 100755 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeWrongRMTypeTest.java create mode 100755 archetype-validator/src/test/java/org/openehr/am/validation/SpecializationArchetypeIdTest.java create mode 100755 archetype-validator/src/test/java/org/openehr/am/validation/SpecializationDepthCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/TermBindingsValidityTest.java create mode 100755 archetype-validator/src/test/java/org/openehr/am/validation/TypeNameCheckTest.java create mode 100755 archetype-validator/src/test/java/org/openehr/am/validation/UniqueSiblingAttributesCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ValidateOpenEHRTerminologyCodesTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ValidatorUtilityTest.java create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.cardinality-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.cardinality-specialised.v2 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.cardinality.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.existence-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.existence.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.multiplicity-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.multiplicity.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_id_conformance-specialised-again.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_id_conformance-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_specialised_as_required-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_specialised_as_required.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.occurrences-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.occurrences.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence-specialised.v2 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence.v2 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype-specialised.v2 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype-specialised.v3 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype.v2 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.assumed_value_boolean.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.assumed_value_count.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.assumed_value_quantity.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-archetypeid.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-archetypeid.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-archetypeid.v3.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v3.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v4.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v5.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_boolean.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_count.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_date.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_date.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_datetime.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_duration.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_ehr_uri.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v3.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v4.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v5.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v6.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_multimedia.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_multimedia.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_name.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_name.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_name.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_proportion.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_uri.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.attribute_name.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.attribute_name.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.attribute_name.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.code_constraint.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.code_constraint.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.code_constraint.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.definition_code.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.definition_code.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.definition_typename.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.definition_typename.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.definition_typename.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v3.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v4.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v5.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-unusedcodes.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-unusedcodes.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v4 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v5 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v6 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v7 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.sibling_nodes.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.sibling_nodes.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_identifier.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_identifier.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_occurrences.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_occurrences.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_occurrences.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_uniqueness.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_uniqueness.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_uniqueness.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_bindings.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_bindings.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v4 create mode 100644 archetype-validator/src/test/resources/adl-test-ITEM_TREE.attribute_cardinality.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ITEM_TREE.attribute_cardinality.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ITEM_TREE.attribute_cardinality.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ITEM_TREE.multi_attribute_child_identifier.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ITEM_TREE.multi_attribute_child_identifier.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ITEM_TREE.multi_attribute_child_identifier.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-PARTY_PROXY.type_name.v1 create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-ACTION.follow_up.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.cardinality_occurrences.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.cardinality_occurrences2.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.cardinality_occurrences3.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.internal_reference.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.testNonUniqueInternalRef.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.testNonUniqueInternalRef.v2.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.test_non_ccomplexobject-spec.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.test_non_ccomplexobject.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-ELEMENT.doubleontologycode.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.adverse.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.null_flavor.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.null_flavour.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.problem-diagnosis.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v2.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v3.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v4.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v5.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v6.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.order1-order2-order3.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.order1-order2-order3a.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.order1-order2.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v2.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.type_name.v4.adl 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 100644 index 00000000..2e98b852 --- /dev/null +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java @@ -0,0 +1,1526 @@ +/* + * 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 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.Ordinal; +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.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 reportConstraintsOnFunctionalPropertiesAsInfo 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; + } + + // check purpose in each available language + for (ResourceDescriptionItem detail : archetype.getDescription().getDetails()) { + 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); + } + } + + /** + * 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) { + 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 (TBD) + 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 cobj + * @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); + } + } + } + + /** 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(); + if (!pattern.equals(".*")) { + // make readability modifications for the pattern + while (pattern.indexOf("(-[a-zA-Z0-9_]+)*\\") >0) { + int i = pattern.indexOf("(-[a-zA-Z0-9_]+)*\\"); + 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("\\.", "."); + } + while (pattern.indexOf("|") >0) { + String oneId = pattern.substring(0,pattern.indexOf("|") ); + pattern = pattern.substring(pattern.indexOf("|")+1); + 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 + boolean containsCorrectNumberOfDots = (StringUtils.countMatches(oneId, ".") == 2); + + // check that the id ends with .v[0..9]* + boolean endsWithDotVNumber =true; // assume it is ok, until proven false + if (oneId.lastIndexOf(".v")== -1) { + endsWithDotVNumber = false; + } else { + String tail = oneId.substring(oneId.lastIndexOf(".v")+2); + log.debug("tail: "+ tail); + if (tail.length() == 0 || !StringUtils.isNumeric(tail)) { + endsWithDotVNumber = false; + } + } + + // check that the first part of the id (the qualified RM Entity) contains the right number of hyphens + boolean containsCorrectNumberOfHyphensInQualifiedRMEntity = true; // assume it is ok, until proven wrong + String qualifiedRMEntity = oneId.substring(0, oneId.indexOf(".")); + if (StringUtils.countMatches(qualifiedRMEntity, "-") != 2) { + containsCorrectNumberOfHyphensInQualifiedRMEntity = false; + } + + // add all the errors + if (!containsCorrectNumberOfDots) { + ValidationError error = new ValidationError(ErrorType.VDFAI, "NUMBEROFDOTS", oneId, slot.path()); + errors.add(error); + + } + if (!endsWithDotVNumber) { + ValidationError error = new ValidationError(ErrorType.VDFAI, "DOTVNUMBER", oneId, slot.path()); + errors.add(error); + + } + if (!containsCorrectNumberOfHyphensInQualifiedRMEntity) { + 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 cobj + * @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); + } + } + + /* + * 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; + } + String codes = ""; + for(String code : ccodephrase.getCodeList()) { + if( ! openEHRTerminology.allCodes().contains( + new CodePhrase(TerminologyService.OPENEHR, code))) { + codes += code + ", "; + } + } + if(codes.length() != 0) { + ValidationError error = new ValidationError(ErrorType.VOTC, null, + codes, ccodephrase.path()); + errors.add(error); + } + } + + /** + * @param cobj + * @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 + * + * 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(); + List constraintDefList = + archetype.getOntology().getConstraintDefinitionsList(); + Set termDefLangs = retrieveLanguageSet(termDefList); + Set constraintDefLangs = retrieveLanguageSet(constraintDefList); + ValidationError error = null; + for(String lang : languages) { + 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 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; + Set 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 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 = new Integer(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..0d06e7f5 --- /dev/null +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ErrorType.java @@ -0,0 +1,79 @@ +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 + 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 100644 index 00000000..8e172fb7 --- /dev/null +++ b/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java @@ -0,0 +1,583 @@ +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.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.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, + + // 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, + 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 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 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") || + parentObj.getRmTypeName().equalsIgnoreCase("SECTION")) { + 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")) { + if (parentObj.getRmTypeName().equalsIgnoreCase("INSTRUCTION")) { + log.debug("--> >=1"); + return new Interval(1,null); + } + } else if (cattr.getRmAttributeName().equals("events")) { + 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 100755 index 00000000..7ccf46df --- /dev/null +++ b/archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java @@ -0,0 +1,755 @@ +package org.openehr.am.validation; + +import org.apache.commons.lang.StringUtils; +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.constraintmodel.*; +import org.openehr.am.archetype.constraintmodel.CAttribute.Existence; +import org.openehr.am.archetype.ontology.ArchetypeTerm; +import org.openehr.am.archetype.ontology.OntologyDefinitions; +import org.openehr.rm.common.resource.TranslationDetails; + +import java.util.*; +import java.util.Map.Entry; + + +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, + 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..10b178a8 --- /dev/null +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ValidationError.java @@ -0,0 +1,139 @@ +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) { + // this(type, null); + // } + + 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 errorText = ResourceBundle.getBundle("validations", locale, UTF8Control.getInstance()).getString(getTextKey()); + if (params != null) { + errorText= MessageFormat.format(errorText, params); + } + return errorText; + } + + protected String getTextKey() { + if (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..07ed47a6 --- /dev/null +++ b/archetype-validator/src/main/resources/validations.properties @@ -0,0 +1,111 @@ +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. + +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}. +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[0..9]*. +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. +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}). \ No newline at end of file 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..a56268cb --- /dev/null +++ b/archetype-validator/src/main/resources/validations_de.properties @@ -0,0 +1,111 @@ +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. + +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}. +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[0..9]*. +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. +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}). \ No newline at end of file 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..afeb486d --- /dev/null +++ b/archetype-validator/src/main/resources/validations_ru.properties @@ -0,0 +1,111 @@ +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 должен быть уникальным; к примеру, код в онтологии присутствует более одного раза для того или иного языка. + +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}. +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[0..9]*. +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. +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}). 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..188d58d0 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeSlotCheckTest.java @@ -0,0 +1,24 @@ +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); + } + + + 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..b6a03919 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeTermValidityTest.java @@ -0,0 +1,68 @@ +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()); + } + } + + 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 100755 index 00000000..686cd8f1 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/AttributeNameCheckTest.java @@ -0,0 +1,48 @@ +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); + } + + /*TODO 1.0.5-SNAPSHOT + 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/MultiValueAttributeChildIdentifierCheckTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/MultiValueAttributeChildIdentifierCheckTest.java new file mode 100755 index 00000000..bf22e4b8 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/MultiValueAttributeChildIdentifierCheckTest.java @@ -0,0 +1,31 @@ +package org.openehr.am.validation; + +public class MultiValueAttributeChildIdentifierCheckTest + extends ArchetypeValidationTestBase { + //TODO 1.0.5-SNAPSHOT - REMOVE + public void testDummy(){ } + + /* TODO 1.0.5-SNAPSHOT + 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 100755 index 00000000..f7f99b0e --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/MultipleValueAttributeCardinalityTest.java @@ -0,0 +1,56 @@ +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); + } + /* TODO 1.0.5-SNAPSHOT + 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 100755 index 00000000..24f72592 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/OntologyTranslationCheckTest.java @@ -0,0 +1,53 @@ +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()); + } + /*TODO 1.0.5-SNAPSHOT + 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); + } + + 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/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 100755 index 00000000..86dbba73 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeWrongRMTypeTest.java @@ -0,0 +1,29 @@ +package org.openehr.am.validation; + +public class SpecialisedArchetypeWrongRMTypeTest extends SpecialisedArchetypeValidationTestBase{ + + /*TODO 1.0.5-SNAPSHOT + 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 100755 index 00000000..dd3156a3 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/SpecializationArchetypeIdTest.java @@ -0,0 +1,32 @@ +package org.openehr.am.validation; + +public class SpecializationArchetypeIdTest extends ArchetypeValidationTestBase{ + + /*TODO 1.0.5-SNAPSHOT + 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 100755 index 00000000..d34b8d31 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/SpecializationDepthCheckTest.java @@ -0,0 +1,63 @@ +package org.openehr.am.validation; + +import org.openehr.am.archetype.Archetype; + +public class SpecializationDepthCheckTest extends ArchetypeValidationTestBase{ + //TODO 1.0.5-SNAPSHOT - REMOVE + public void testDummy(){ } + + /*TODO 1.0.5-SNAPSHOT + 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 100755 index 00000000..532af6a9 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/TypeNameCheckTest.java @@ -0,0 +1,137 @@ +package org.openehr.am.validation; + +public class TypeNameCheckTest extends ArchetypeValidationTestBase { + /*TODO 1.0.5-SNAPSHOT + 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()); + } + /*TODO 1.0.5-SNAPSHOT + 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()); + } + /*TODO 1.0.5-SNAPSHOT + 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 100755 index 00000000..f33ce3f8 --- /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()); + } + /* TODO 1.0.5-SNAPSHOT + 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..ea0e0368 --- /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.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-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-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..8c2be792 --- /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.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/pom.xml b/pom.xml index a41965e2..d0f576e6 100755 --- a/pom.xml +++ b/pom.xml @@ -77,5 +77,6 @@ xml-binding dadl-binding rm-skeleton + archetype-validator \ No newline at end of file From a891606b157c284a16001a87e52c5a134a8050ca Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Wed, 25 Sep 2013 13:36:18 +0200 Subject: [PATCH 005/213] Add archetype validator again Was removed Aug 27 from SANDBOX --- archetype-validator/pom.xml | 86 + .../am/validation/ArchetypeValidator.java | 1526 +++++++++++++++++ .../org/openehr/am/validation/ErrorType.java | 79 + .../am/validation/RMInspectionException.java | 11 + .../openehr/am/validation/RMInspector.java | 583 +++++++ .../SpecialisedArchetypeValidator.java | 767 +++++++++ .../openehr/am/validation/UTF8Control.java | 61 + .../am/validation/ValidationError.java | 139 ++ .../src/main/resources/log4j.properties | 9 + .../src/main/resources/validations.properties | 111 ++ .../src/main/resources/validations.txt | 34 + .../main/resources/validations_de.properties | 111 ++ .../main/resources/validations_en.properties | 2 + .../main/resources/validations_ru.properties | 111 ++ .../ArchetypeDefinitionCodeCheckTest.java | 20 + .../ArchetypeInternalRefCheckTest.java | 58 + .../am/validation/ArchetypeSlotCheckTest.java | 24 + .../validation/ArchetypeTermValidityTest.java | 68 + .../ArchetypeValidationTestBase.java | 94 + .../am/validation/AssumedValueTest.java | 27 + .../am/validation/AttributeNameCheckTest.java | 46 + .../CodeConstraintValidityTest.java | 48 + .../DefinitionTypenameCheckTest.java | 24 + ...alueAttributeChildIdentifierCheckTest.java | 28 + ...MultipleValueAttributeCardinalityTest.java | 55 + .../OntologyCodeSpecialisationCheckTest.java | 37 + .../OntologyTranslationCheckTest.java | 53 + .../am/validation/RMInspectorTest.java | 78 + ...alueAttributeChildIdentifierCheckTest.java | 21 + ...lueAttributeChildOccurrencesCheckTest.java | 26 + ...alueAttributeChildUniquenessCheckTest.java | 27 + .../SpecialisedArchetypeCardinalityTest.java | 22 + .../SpecialisedArchetypeExistenceTest.java | 18 + .../SpecialisedArchetypeMultiplicityTest.java | 18 + ...ialisedArchetypeNodeIdConformanceTest.java | 17 + ...rchetypeNodeSpecialisedAsRequiredTest.java | 18 + ...ialisedArchetypeNonCComplexObjectTest.java | 20 + .../SpecialisedArchetypeOccurrencesTest.java | 18 + .../SpecialisedArchetypeTermExistsTest.java | 34 + ...pecialisedArchetypeValidationTestBase.java | 68 + .../SpecialisedArchetypeWrongRMTypeTest.java | 30 + .../SpecializationArchetypeIdTest.java | 31 + .../SpecializationDepthCheckTest.java | 60 + .../validation/TermBindingsValidityTest.java | 27 + .../am/validation/TypeNameCheckTest.java | 141 ++ .../UniqueSiblingAttributesCheckTest.java | 25 + .../ValidateOpenEHRTerminologyCodesTest.java | 15 + .../am/validation/ValidatorUtilityTest.java | 52 + ...ised-EVALUATION.cardinality-specialised.v1 | 63 + ...ised-EVALUATION.cardinality-specialised.v2 | 63 + .../adl-specialised-EVALUATION.cardinality.v1 | 55 + ...alised-EVALUATION.existence-specialised.v1 | 67 + .../adl-specialised-EVALUATION.existence.v1 | 55 + ...sed-EVALUATION.multiplicity-specialised.v1 | 63 + ...adl-specialised-EVALUATION.multiplicity.v1 | 55 + ...N.node_id_conformance-specialised-again.v1 | 67 + ...LUATION.node_id_conformance-specialised.v1 | 59 + ...ode_specialised_as_required-specialised.v1 | 59 + ...EVALUATION.node_specialised_as_required.v1 | 55 + ...ised-EVALUATION.occurrences-specialised.v1 | 67 + .../adl-specialised-EVALUATION.occurrences.v1 | 55 + ...d-EVALUATION.term_existence-specialised.v1 | 59 + ...d-EVALUATION.term_existence-specialised.v2 | 59 + ...l-specialised-EVALUATION.term_existence.v1 | 64 + ...l-specialised-EVALUATION.term_existence.v2 | 51 + ...ised-EVALUATION.wrongrmtype-specialised.v1 | 110 ++ ...ised-EVALUATION.wrongrmtype-specialised.v2 | 65 + ...ised-EVALUATION.wrongrmtype-specialised.v3 | 61 + .../adl-specialised-EVALUATION.wrongrmtype.v1 | 92 + .../adl-specialised-EVALUATION.wrongrmtype.v2 | 55 + .../adl-specialised-EVALUATION.wrongrmtype.v3 | 58 + ...-test-ELEMENT.assumed_value_boolean.v1.adl | 29 + ...dl-test-ELEMENT.assumed_value_count.v1.adl | 29 + ...test-ELEMENT.assumed_value_quantity.v1.adl | 40 + ...-ELEMENT.specialization-archetypeid.v1.adl | 32 + ...-ELEMENT.specialization-archetypeid.v2.adl | 32 + ...-ELEMENT.specialization-archetypeid.v3.adl | 32 + ...l-test-ELEMENT.specialization-depth.v1.adl | 32 + ...l-test-ELEMENT.specialization-depth.v2.adl | 32 + ...l-test-ELEMENT.specialization-depth.v3.adl | 32 + ...l-test-ELEMENT.specialization-depth.v4.adl | 36 + ...l-test-ELEMENT.specialization-depth.v5.adl | 42 + .../adl-test-ELEMENT.specialization.v1.adl | 25 + .../adl-test-ELEMENT.type_boolean.v1.adl | 29 + .../adl-test-ELEMENT.type_count.v1.adl | 29 + .../adl-test-ELEMENT.type_date.v1.adl | 29 + .../adl-test-ELEMENT.type_date.v2.adl | 25 + .../adl-test-ELEMENT.type_datetime.v1.adl | 29 + .../adl-test-ELEMENT.type_duration.v1.adl | 29 + .../adl-test-ELEMENT.type_ehr_uri.v1.adl | 27 + .../adl-test-ELEMENT.type_interval.v1.adl | 27 + .../adl-test-ELEMENT.type_interval.v2.adl | 37 + .../adl-test-ELEMENT.type_interval.v3.adl | 37 + .../adl-test-ELEMENT.type_interval.v4.adl | 30 + .../adl-test-ELEMENT.type_interval.v5.adl | 30 + .../adl-test-ELEMENT.type_interval.v6.adl | 37 + .../adl-test-ELEMENT.type_multimedia.v1.adl | 36 + .../adl-test-ELEMENT.type_multimedia.v2.adl | 36 + .../resources/adl-test-ELEMENT.type_name.v1 | 29 + .../resources/adl-test-ELEMENT.type_name.v2 | 29 + .../resources/adl-test-ELEMENT.type_name.v3 | 29 + .../adl-test-ELEMENT.type_proportion.v1.adl | 31 + .../adl-test-ELEMENT.type_uri.v1.adl | 27 + .../adl-test-ENTRY.attribute_name.v1 | 39 + .../adl-test-ENTRY.attribute_name.v2 | 39 + .../adl-test-ENTRY.attribute_name.v3 | 36 + .../adl-test-ENTRY.code_constraint.v1 | 35 + .../adl-test-ENTRY.code_constraint.v2 | 25 + .../adl-test-ENTRY.code_constraint.v3 | 56 + .../adl-test-ENTRY.definition_code.v1 | 39 + .../adl-test-ENTRY.definition_code.v2 | 39 + .../adl-test-ENTRY.definition_typename.v1 | 23 + .../adl-test-ENTRY.definition_typename.v2 | 23 + .../adl-test-ENTRY.definition_typename.v3 | 23 + ...-test-ENTRY.ontology-specialisation.v1.adl | 39 + ...-test-ENTRY.ontology-specialisation.v2.adl | 42 + ...-test-ENTRY.ontology-specialisation.v3.adl | 42 + ...-test-ENTRY.ontology-specialisation.v4.adl | 42 + ...-test-ENTRY.ontology-specialisation.v5.adl | 42 + ...adl-test-ENTRY.ontology-unusedcodes.v1.adl | 43 + ...adl-test-ENTRY.ontology-unusedcodes.v2.adl | 51 + .../adl-test-ENTRY.ontology_translation.v1 | 25 + .../adl-test-ENTRY.ontology_translation.v2 | 48 + .../adl-test-ENTRY.ontology_translation.v3 | 56 + .../adl-test-ENTRY.ontology_translation.v4 | 56 + .../adl-test-ENTRY.ontology_translation.v5 | 64 + .../adl-test-ENTRY.ontology_translation.v6 | 71 + .../adl-test-ENTRY.ontology_translation.v7 | 46 + .../resources/adl-test-ENTRY.sibling_nodes.v1 | 38 + .../resources/adl-test-ENTRY.sibling_nodes.v2 | 39 + ...ENTRY.single_attribute_child_identifier.v1 | 54 + ...ENTRY.single_attribute_child_identifier.v2 | 54 + ...NTRY.single_attribute_child_occurrences.v1 | 39 + ...NTRY.single_attribute_child_occurrences.v2 | 39 + ...NTRY.single_attribute_child_occurrences.v3 | 39 + ...ENTRY.single_attribute_child_uniqueness.v1 | 54 + ...ENTRY.single_attribute_child_uniqueness.v2 | 46 + ...ENTRY.single_attribute_child_uniqueness.v3 | 39 + .../resources/adl-test-ENTRY.term_bindings.v1 | 73 + .../resources/adl-test-ENTRY.term_bindings.v2 | 76 + .../adl-test-ENTRY.term_definition.v1 | 19 + .../adl-test-ENTRY.term_definition.v2 | 23 + .../adl-test-ENTRY.term_definition.v3 | 23 + .../adl-test-ENTRY.term_definition.v4 | 36 + ...dl-test-ITEM_TREE.attribute_cardinality.v1 | 36 + ...dl-test-ITEM_TREE.attribute_cardinality.v2 | 45 + ...dl-test-ITEM_TREE.attribute_cardinality.v3 | 40 + ...M_TREE.multi_attribute_child_identifier.v1 | 52 + ...M_TREE.multi_attribute_child_identifier.v2 | 52 + ...M_TREE.multi_attribute_child_identifier.v3 | 52 + .../adl-test-PARTY_PROXY.type_name.v1 | 25 + .../openEHR-EHR-ACTION.follow_up.v1.adl | 46 + ...EHR-CLUSTER.cardinality_occurrences.v1.adl | 69 + ...HR-CLUSTER.cardinality_occurrences2.v1.adl | 69 + ...HR-CLUSTER.cardinality_occurrences3.v1.adl | 69 + ...nEHR-EHR-CLUSTER.internal_reference.v1.adl | 60 + ...HR-CLUSTER.testNonUniqueInternalRef.v1.adl | 54 + ...HR-CLUSTER.testNonUniqueInternalRef.v2.adl | 63 + ...LUSTER.test_non_ccomplexobject-spec.v1.adl | 97 ++ ...EHR-CLUSTER.test_non_ccomplexobject.v1.adl | 61 + ...nEHR-EHR-ELEMENT.doubleontologycode.v1.adl | 48 + .../openEHR-EHR-EVALUATION.adverse.v1.adl | 411 +++++ .../openEHR-EHR-EVALUATION.null_flavor.v1.adl | 90 + ...openEHR-EHR-EVALUATION.null_flavour.v1.adl | 90 + ...HR-EHR-EVALUATION.problem-diagnosis.v1.adl | 897 ++++++++++ ...-EHR-OBSERVATION.internal_reference.v1.adl | 70 + ...-EHR-OBSERVATION.internal_reference.v2.adl | 70 + ...-EHR-OBSERVATION.internal_reference.v3.adl | 70 + ...-EHR-OBSERVATION.internal_reference.v4.adl | 70 + ...-EHR-OBSERVATION.internal_reference.v5.adl | 70 + ...-EHR-OBSERVATION.internal_reference.v6.adl | 150 ++ ...HR-OBSERVATION.order1-order2-order3.v1.adl | 112 ++ ...R-OBSERVATION.order1-order2-order3a.v1.adl | 112 ++ ...enEHR-EHR-OBSERVATION.order1-order2.v1.adl | 99 ++ .../openEHR-EHR-OBSERVATION.slot.v1.adl | 57 + .../openEHR-EHR-OBSERVATION.slot.v2.adl | 57 + .../openEHR-EHR-OBSERVATION.type_name.v4.adl | 43 + 177 files changed, 12581 insertions(+) create mode 100644 archetype-validator/pom.xml create mode 100644 archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java create mode 100644 archetype-validator/src/main/java/org/openehr/am/validation/ErrorType.java create mode 100644 archetype-validator/src/main/java/org/openehr/am/validation/RMInspectionException.java create mode 100644 archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java create mode 100644 archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java create mode 100644 archetype-validator/src/main/java/org/openehr/am/validation/UTF8Control.java create mode 100644 archetype-validator/src/main/java/org/openehr/am/validation/ValidationError.java create mode 100644 archetype-validator/src/main/resources/log4j.properties create mode 100644 archetype-validator/src/main/resources/validations.properties create mode 100644 archetype-validator/src/main/resources/validations.txt create mode 100644 archetype-validator/src/main/resources/validations_de.properties create mode 100644 archetype-validator/src/main/resources/validations_en.properties create mode 100644 archetype-validator/src/main/resources/validations_ru.properties create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeDefinitionCodeCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeInternalRefCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeSlotCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeTermValidityTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeValidationTestBase.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/AssumedValueTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/AttributeNameCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/CodeConstraintValidityTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/DefinitionTypenameCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/MultiValueAttributeChildIdentifierCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/MultipleValueAttributeCardinalityTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/OntologyCodeSpecialisationCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/OntologyTranslationCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/RMInspectorTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SingleValueAttributeChildIdentifierCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SingleValueAttributeChildOccurrencesCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SingleValueAttributeChildUniquenessCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeCardinalityTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeExistenceTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeMultiplicityTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeNodeIdConformanceTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeNodeSpecialisedAsRequiredTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeNonCComplexObjectTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeOccurrencesTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeTermExistsTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeValidationTestBase.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeWrongRMTypeTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecializationArchetypeIdTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecializationDepthCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/TermBindingsValidityTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/TypeNameCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/UniqueSiblingAttributesCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ValidateOpenEHRTerminologyCodesTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ValidatorUtilityTest.java create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.cardinality-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.cardinality-specialised.v2 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.cardinality.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.existence-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.existence.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.multiplicity-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.multiplicity.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_id_conformance-specialised-again.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_id_conformance-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_specialised_as_required-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_specialised_as_required.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.occurrences-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.occurrences.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence-specialised.v2 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence.v2 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype-specialised.v2 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype-specialised.v3 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype.v2 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.assumed_value_boolean.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.assumed_value_count.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.assumed_value_quantity.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-archetypeid.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-archetypeid.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-archetypeid.v3.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v3.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v4.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v5.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_boolean.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_count.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_date.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_date.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_datetime.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_duration.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_ehr_uri.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v3.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v4.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v5.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v6.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_multimedia.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_multimedia.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_name.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_name.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_name.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_proportion.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_uri.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.attribute_name.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.attribute_name.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.attribute_name.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.code_constraint.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.code_constraint.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.code_constraint.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.definition_code.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.definition_code.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.definition_typename.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.definition_typename.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.definition_typename.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v3.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v4.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v5.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-unusedcodes.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-unusedcodes.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v4 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v5 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v6 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v7 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.sibling_nodes.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.sibling_nodes.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_identifier.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_identifier.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_occurrences.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_occurrences.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_occurrences.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_uniqueness.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_uniqueness.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_uniqueness.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_bindings.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_bindings.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v4 create mode 100644 archetype-validator/src/test/resources/adl-test-ITEM_TREE.attribute_cardinality.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ITEM_TREE.attribute_cardinality.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ITEM_TREE.attribute_cardinality.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ITEM_TREE.multi_attribute_child_identifier.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ITEM_TREE.multi_attribute_child_identifier.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ITEM_TREE.multi_attribute_child_identifier.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-PARTY_PROXY.type_name.v1 create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-ACTION.follow_up.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.cardinality_occurrences.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.cardinality_occurrences2.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.cardinality_occurrences3.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.internal_reference.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.testNonUniqueInternalRef.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.testNonUniqueInternalRef.v2.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.test_non_ccomplexobject-spec.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.test_non_ccomplexobject.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-ELEMENT.doubleontologycode.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.adverse.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.null_flavor.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.null_flavour.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.problem-diagnosis.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v2.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v3.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v4.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v5.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v6.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.order1-order2-order3.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.order1-order2-order3a.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.order1-order2.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v2.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.type_name.v4.adl diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml new file mode 100644 index 00000000..7a5c57e8 --- /dev/null +++ b/archetype-validator/pom.xml @@ -0,0 +1,86 @@ + + + 4.0.0 + org.openehr + archetype-validator + jar + 0.1-SNAPSHOT + 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.5 + 1.5 + + + + + + + + commons-lang + commons-lang + 2.4 + + + log4j + log4j + 1.2.13 + + + openehr + openehr-rm-core + 1.0.3-SNAPSHOT + + + openehr + openehr-rm-domain + 1.0.3-SNAPSHOT + + + openehr + openehr-aom + 1.0.3-SNAPSHOT + + + openehr + openehr-ap + 1.0.3-SNAPSHOT + + + openehr + mini-termserv + 1.0.3-SNAPSHOT + + + openehr + measure-serv + 1.0.3-SNAPSHOT + + + openehr + adl-parser + 1.0.3-SNAPSHOT + 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 100644 index 00000000..2e98b852 --- /dev/null +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java @@ -0,0 +1,1526 @@ +/* + * 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 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.Ordinal; +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.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 reportConstraintsOnFunctionalPropertiesAsInfo 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; + } + + // check purpose in each available language + for (ResourceDescriptionItem detail : archetype.getDescription().getDetails()) { + 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); + } + } + + /** + * 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) { + 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 (TBD) + 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 cobj + * @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); + } + } + } + + /** 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(); + if (!pattern.equals(".*")) { + // make readability modifications for the pattern + while (pattern.indexOf("(-[a-zA-Z0-9_]+)*\\") >0) { + int i = pattern.indexOf("(-[a-zA-Z0-9_]+)*\\"); + 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("\\.", "."); + } + while (pattern.indexOf("|") >0) { + String oneId = pattern.substring(0,pattern.indexOf("|") ); + pattern = pattern.substring(pattern.indexOf("|")+1); + 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 + boolean containsCorrectNumberOfDots = (StringUtils.countMatches(oneId, ".") == 2); + + // check that the id ends with .v[0..9]* + boolean endsWithDotVNumber =true; // assume it is ok, until proven false + if (oneId.lastIndexOf(".v")== -1) { + endsWithDotVNumber = false; + } else { + String tail = oneId.substring(oneId.lastIndexOf(".v")+2); + log.debug("tail: "+ tail); + if (tail.length() == 0 || !StringUtils.isNumeric(tail)) { + endsWithDotVNumber = false; + } + } + + // check that the first part of the id (the qualified RM Entity) contains the right number of hyphens + boolean containsCorrectNumberOfHyphensInQualifiedRMEntity = true; // assume it is ok, until proven wrong + String qualifiedRMEntity = oneId.substring(0, oneId.indexOf(".")); + if (StringUtils.countMatches(qualifiedRMEntity, "-") != 2) { + containsCorrectNumberOfHyphensInQualifiedRMEntity = false; + } + + // add all the errors + if (!containsCorrectNumberOfDots) { + ValidationError error = new ValidationError(ErrorType.VDFAI, "NUMBEROFDOTS", oneId, slot.path()); + errors.add(error); + + } + if (!endsWithDotVNumber) { + ValidationError error = new ValidationError(ErrorType.VDFAI, "DOTVNUMBER", oneId, slot.path()); + errors.add(error); + + } + if (!containsCorrectNumberOfHyphensInQualifiedRMEntity) { + 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 cobj + * @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); + } + } + + /* + * 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; + } + String codes = ""; + for(String code : ccodephrase.getCodeList()) { + if( ! openEHRTerminology.allCodes().contains( + new CodePhrase(TerminologyService.OPENEHR, code))) { + codes += code + ", "; + } + } + if(codes.length() != 0) { + ValidationError error = new ValidationError(ErrorType.VOTC, null, + codes, ccodephrase.path()); + errors.add(error); + } + } + + /** + * @param cobj + * @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 + * + * 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(); + List constraintDefList = + archetype.getOntology().getConstraintDefinitionsList(); + Set termDefLangs = retrieveLanguageSet(termDefList); + Set constraintDefLangs = retrieveLanguageSet(constraintDefList); + ValidationError error = null; + for(String lang : languages) { + 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 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; + Set 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 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 = new Integer(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..0d06e7f5 --- /dev/null +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ErrorType.java @@ -0,0 +1,79 @@ +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 + 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 100644 index 00000000..377f71f5 --- /dev/null +++ b/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java @@ -0,0 +1,583 @@ +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.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.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, + + // 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, + 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 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 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") || + parentObj.getRmTypeName().equalsIgnoreCase("SECTION")) { + 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")) { + 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..e7aa9dfb --- /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, + 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..10b178a8 --- /dev/null +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ValidationError.java @@ -0,0 +1,139 @@ +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) { + // this(type, null); + // } + + 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 errorText = ResourceBundle.getBundle("validations", locale, UTF8Control.getInstance()).getString(getTextKey()); + if (params != null) { + errorText= MessageFormat.format(errorText, params); + } + return errorText; + } + + protected String getTextKey() { + if (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..07ed47a6 --- /dev/null +++ b/archetype-validator/src/main/resources/validations.properties @@ -0,0 +1,111 @@ +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. + +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}. +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[0..9]*. +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. +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}). \ No newline at end of file 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..a56268cb --- /dev/null +++ b/archetype-validator/src/main/resources/validations_de.properties @@ -0,0 +1,111 @@ +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. + +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}. +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[0..9]*. +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. +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}). \ No newline at end of file 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..fb225d03 --- /dev/null +++ b/archetype-validator/src/main/resources/validations_ru.properties @@ -0,0 +1,111 @@ +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 должен быть уникальным; к примеру, код в онтологии присутствует более одного раза для того или иного языка. + +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}. +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[0..9]*. +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. +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}). 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..188d58d0 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeSlotCheckTest.java @@ -0,0 +1,24 @@ +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); + } + + + 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..b6a03919 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeTermValidityTest.java @@ -0,0 +1,68 @@ +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()); + } + } + + 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/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..068740ae --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/OntologyTranslationCheckTest.java @@ -0,0 +1,53 @@ +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); + } + + 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/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..ea0e0368 --- /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.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-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-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..8c2be792 --- /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.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 From 9ea5f1f98cd5cd0854ae693ea6acc9dce0bc6e49 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Thu, 26 Sep 2013 12:19:25 +0200 Subject: [PATCH 006/213] * Archetype validator references updated * Fix on adl parser to check for null children --- adl-parser/src/main/javacc/adl.jj | 8 +++++--- archetype-validator/pom.xml | 21 ++++++++++++--------- 2 files changed, 17 insertions(+), 12 deletions(-) mode change 100644 => 100755 archetype-validator/pom.xml diff --git a/adl-parser/src/main/javacc/adl.jj b/adl-parser/src/main/javacc/adl.jj index 5d672872..3b63327d 100755 --- a/adl-parser/src/main/javacc/adl.jj +++ b/adl-parser/src/main/javacc/adl.jj @@ -2447,9 +2447,11 @@ CAttribute c_attribute(String path) : } // 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; diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml old mode 100644 new mode 100755 index 7a5c57e8..2992000a --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -3,10 +3,13 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 - org.openehr + + openehr + ref_impl_java + 1.0.5-SNAPSHOT + archetype-validator jar - 0.1-SNAPSHOT Archetype Validator http://svn.openehr.org/ref_impl_java/TRUNK/project_page.htm @@ -44,37 +47,37 @@ openehr openehr-rm-core - 1.0.3-SNAPSHOT + ${project.version} openehr openehr-rm-domain - 1.0.3-SNAPSHOT + ${project.version} openehr openehr-aom - 1.0.3-SNAPSHOT + ${project.version} openehr openehr-ap - 1.0.3-SNAPSHOT + ${project.version} openehr mini-termserv - 1.0.3-SNAPSHOT + ${project.version} openehr measure-serv - 1.0.3-SNAPSHOT + ${project.version} openehr adl-parser - 1.0.3-SNAPSHOT + ${project.version} test From 3cdcb75ea8a38c2dc4d3b8131c3e4bb594d289ad Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Tue, 17 Dec 2013 15:28:29 +0100 Subject: [PATCH 007/213] Validate DV_QUANTITY units for (case-sensitive) UCUM format --- adl-parser/pom.xml | 260 +- .../am/validation/ArchetypeValidator.java | 3071 +++++++++-------- .../org/openehr/am/validation/ErrorType.java | 159 +- .../src/main/resources/validations.properties | 224 +- .../main/resources/validations_de.properties | 224 +- .../main/resources/validations_ru.properties | 224 +- .../am/validation/DvQuantityUnitsTest.java | 17 + ...test-ELEMENT.assumed_value_quantity.v1.adl | 78 +- .../openEHR-EHR-CLUSTER.units_test.v1.adl | 152 + .../measurement/SimpleMeasurementService.java | 122 +- .../SimpleMeasurementServiceTest.java | 31 +- 11 files changed, 2445 insertions(+), 2117 deletions(-) create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/DvQuantityUnitsTest.java create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.units_test.v1.adl diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index ce1d0a96..1a2efa4e 100755 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -1,130 +1,130 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.5-SNAPSHOT - - adl-parser - jar - java ADL Parser - http://www.openehr.org/projects/java.html - - openEHR - http://www.openehr.org/ - - 2004 - - java ADL Parser - - - - - org.codehaus.mojo - javacc-maven-plugin - 2.6 - - se.acode.openehr.parser - - - - - javacc - - - - - - - maven-assembly-plugin - - - jar-with-dependencies - - - - se.acode.openehr.parser.ADLParser - - - - - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.codehaus.mojo - javacc-maven-plugin - [2.1,) - - javacc - - - - - - - - - - - - - - - - - openehr - openehr-rm-core - ${project.version} - - - openehr - openehr-rm-domain - ${project.version} - - - openehr - openehr-aom - ${project.version} - - - openehr - openehr-ap - ${project.version} - - - openehr - measure-serv - ${project.version} - - - openehr - mini-termserv - ${project.version} - - - junit - junit - 3.8.1 - test - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5-SNAPSHOT + + adl-parser + jar + java ADL Parser + http://www.openehr.org/projects/java.html + + openEHR + http://www.openehr.org/ + + 2004 + + java ADL Parser + + + + + org.codehaus.mojo + javacc-maven-plugin + 2.6 + + se.acode.openehr.parser + + + + + javacc + + + + + + + maven-assembly-plugin + + + jar-with-dependencies + + + + se.acode.openehr.parser.ADLParser + + + + + + package + + assembly + + + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.codehaus.mojo + javacc-maven-plugin + [2.1,) + + javacc + + + + + + + + + + + + + + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + openehr-aom + ${project.version} + + + openehr + openehr-ap + ${project.version} + + + openehr + measure-serv + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + junit + junit + 3.8.1 + test + + + 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 index 2e98b852..79e749c5 100644 --- a/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java @@ -1,1526 +1,1545 @@ -/* - * 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 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.Ordinal; -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.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 reportConstraintsOnFunctionalPropertiesAsInfo 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; - } - - // check purpose in each available language - for (ResourceDescriptionItem detail : archetype.getDescription().getDetails()) { - 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); - } - } - - /** - * 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) { - 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 (TBD) - 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 cobj - * @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); - } - } - } - - /** 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(); - if (!pattern.equals(".*")) { - // make readability modifications for the pattern - while (pattern.indexOf("(-[a-zA-Z0-9_]+)*\\") >0) { - int i = pattern.indexOf("(-[a-zA-Z0-9_]+)*\\"); - 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("\\.", "."); - } - while (pattern.indexOf("|") >0) { - String oneId = pattern.substring(0,pattern.indexOf("|") ); - pattern = pattern.substring(pattern.indexOf("|")+1); - 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 - boolean containsCorrectNumberOfDots = (StringUtils.countMatches(oneId, ".") == 2); - - // check that the id ends with .v[0..9]* - boolean endsWithDotVNumber =true; // assume it is ok, until proven false - if (oneId.lastIndexOf(".v")== -1) { - endsWithDotVNumber = false; - } else { - String tail = oneId.substring(oneId.lastIndexOf(".v")+2); - log.debug("tail: "+ tail); - if (tail.length() == 0 || !StringUtils.isNumeric(tail)) { - endsWithDotVNumber = false; - } - } - - // check that the first part of the id (the qualified RM Entity) contains the right number of hyphens - boolean containsCorrectNumberOfHyphensInQualifiedRMEntity = true; // assume it is ok, until proven wrong - String qualifiedRMEntity = oneId.substring(0, oneId.indexOf(".")); - if (StringUtils.countMatches(qualifiedRMEntity, "-") != 2) { - containsCorrectNumberOfHyphensInQualifiedRMEntity = false; - } - - // add all the errors - if (!containsCorrectNumberOfDots) { - ValidationError error = new ValidationError(ErrorType.VDFAI, "NUMBEROFDOTS", oneId, slot.path()); - errors.add(error); - - } - if (!endsWithDotVNumber) { - ValidationError error = new ValidationError(ErrorType.VDFAI, "DOTVNUMBER", oneId, slot.path()); - errors.add(error); - - } - if (!containsCorrectNumberOfHyphensInQualifiedRMEntity) { - 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 cobj - * @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); - } - } - - /* - * 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; - } - String codes = ""; - for(String code : ccodephrase.getCodeList()) { - if( ! openEHRTerminology.allCodes().contains( - new CodePhrase(TerminologyService.OPENEHR, code))) { - codes += code + ", "; - } - } - if(codes.length() != 0) { - ValidationError error = new ValidationError(ErrorType.VOTC, null, - codes, ccodephrase.path()); - errors.add(error); - } - } - - /** - * @param cobj - * @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 - * - * 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(); - List constraintDefList = - archetype.getOntology().getConstraintDefinitionsList(); - Set termDefLangs = retrieveLanguageSet(termDefList); - Set constraintDefLangs = retrieveLanguageSet(constraintDefList); - ValidationError error = null; - for(String lang : languages) { - 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 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; - Set 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 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 = new Integer(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 ***** - */ +/* + * 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 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.Ordinal; +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 reportConstraintsOnFunctionalPropertiesAsInfo 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; + } + + // check purpose in each available language + for (ResourceDescriptionItem detail : archetype.getDescription().getDetails()) { + 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 (TBD) + 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 cobj + * @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); + } + } + } + + /** 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(); + if (!pattern.equals(".*")) { + // make readability modifications for the pattern + while (pattern.indexOf("(-[a-zA-Z0-9_]+)*\\") >0) { + int i = pattern.indexOf("(-[a-zA-Z0-9_]+)*\\"); + 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("\\.", "."); + } + while (pattern.indexOf("|") >0) { + String oneId = pattern.substring(0,pattern.indexOf("|") ); + pattern = pattern.substring(pattern.indexOf("|")+1); + 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 + boolean containsCorrectNumberOfDots = (StringUtils.countMatches(oneId, ".") == 2); + + // check that the id ends with .v[0..9]* + boolean endsWithDotVNumber =true; // assume it is ok, until proven false + if (oneId.lastIndexOf(".v")== -1) { + endsWithDotVNumber = false; + } else { + String tail = oneId.substring(oneId.lastIndexOf(".v")+2); + log.debug("tail: "+ tail); + if (tail.length() == 0 || !StringUtils.isNumeric(tail)) { + endsWithDotVNumber = false; + } + } + + // check that the first part of the id (the qualified RM Entity) contains the right number of hyphens + boolean containsCorrectNumberOfHyphensInQualifiedRMEntity = true; // assume it is ok, until proven wrong + String qualifiedRMEntity = oneId.substring(0, oneId.indexOf(".")); + if (StringUtils.countMatches(qualifiedRMEntity, "-") != 2) { + containsCorrectNumberOfHyphensInQualifiedRMEntity = false; + } + + // add all the errors + if (!containsCorrectNumberOfDots) { + ValidationError error = new ValidationError(ErrorType.VDFAI, "NUMBEROFDOTS", oneId, slot.path()); + errors.add(error); + + } + if (!endsWithDotVNumber) { + ValidationError error = new ValidationError(ErrorType.VDFAI, "DOTVNUMBER", oneId, slot.path()); + errors.add(error); + + } + if (!containsCorrectNumberOfHyphensInQualifiedRMEntity) { + 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 cobj + * @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; + } + String codes = ""; + for(String code : ccodephrase.getCodeList()) { + if( ! openEHRTerminology.allCodes().contains( + new CodePhrase(TerminologyService.OPENEHR, code))) { + codes += code + ", "; + } + } + if(codes.length() != 0) { + ValidationError error = new ValidationError(ErrorType.VOTC, null, + codes, ccodephrase.path()); + errors.add(error); + } + } + + /** + * @param cobj + * @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 + * + * 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(); + List constraintDefList = + archetype.getOntology().getConstraintDefinitionsList(); + Set termDefLangs = retrieveLanguageSet(termDefList); + Set constraintDefLangs = retrieveLanguageSet(constraintDefList); + ValidationError error = null; + for(String lang : languages) { + 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 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; + Set 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 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 = new Integer(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 index 0d06e7f5..161d9d18 100644 --- a/archetype-validator/src/main/java/org/openehr/am/validation/ErrorType.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ErrorType.java @@ -1,79 +1,80 @@ -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 - 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). - */ -} +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 + 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/resources/validations.properties b/archetype-validator/src/main/resources/validations.properties index 07ed47a6..81381f48 100644 --- a/archetype-validator/src/main/resources/validations.properties +++ b/archetype-validator/src/main/resources/validations.properties @@ -1,111 +1,113 @@ -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. - -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}. -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[0..9]*. -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. -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}). \ No newline at end of file +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 + +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}. +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[0..9]*. +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. +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. \ No newline at end of file diff --git a/archetype-validator/src/main/resources/validations_de.properties b/archetype-validator/src/main/resources/validations_de.properties index a56268cb..75d1c2f6 100644 --- a/archetype-validator/src/main/resources/validations_de.properties +++ b/archetype-validator/src/main/resources/validations_de.properties @@ -1,111 +1,113 @@ -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. - -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}. -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[0..9]*. -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. -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}). \ No newline at end of file +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. + +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}. +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[0..9]*. +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. +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. \ 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 index d6f62ce1..e4b648d1 100644 --- a/archetype-validator/src/main/resources/validations_ru.properties +++ b/archetype-validator/src/main/resources/validations_ru.properties @@ -1,111 +1,113 @@ -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 должен быть уникальным; к примеру, код в онтологии присутствует более одного раза для того или иного языка. - -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}. -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[0..9]*. -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. -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}). +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 + +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}. +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[0..9]*. +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. +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. \ No newline at end of file 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/resources/adl-test-ELEMENT.assumed_value_quantity.v1.adl b/archetype-validator/src/test/resources/adl-test-ELEMENT.assumed_value_quantity.v1.adl index ea0e0368..303ab4d8 100644 --- 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 @@ -1,40 +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"> - > - > - > +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/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/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 index b93b9ce0..4e294532 100755 --- 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,102 @@ 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" + + )); /** * Returns True if the units string according to * the HL7 UCUM specification. + * Note that this implementation currrently 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"); + } + + // 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 +158,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 +222,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/test/java/org/openehr/rm/support/measurement/SimpleMeasurementServiceTest.java b/measure-serv/src/test/java/org/openehr/rm/support/measurement/SimpleMeasurementServiceTest.java index c5dcf1c8..e5d26eed 100755 --- 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,13 +4,18 @@ public class SimpleMeasurementServiceTest extends TestCase { + @Override public void setUp() { 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 { @@ -26,5 +31,27 @@ public void testunitsComparison() throws Exception { 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("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")); + + } + private MeasurementService service; } From e357d9ceae491eae97d002a24370b97386d49a2a Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Fri, 7 Feb 2014 09:44:09 +0100 Subject: [PATCH 008/213] * Added prototipe data values for date and time * Parsing functions for DvDate and DvTime --- .../openehr/rm/datatypes/basic/DataValue.java | 16 ++++++++-------- .../rm/datatypes/basic/ReferenceModelName.java | 4 +++- .../rm/datatypes/quantity/datetime/DvDate.java | 8 ++++++++ .../rm/datatypes/quantity/datetime/DvTime.java | 16 ++++++++++++---- 4 files changed, 31 insertions(+), 13 deletions(-) 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..3d5504dd 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,21 @@ */ 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.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 * @@ -119,6 +117,8 @@ 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_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")); } 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 index ca4f924a..ac0dc98b 100755 --- 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,7 +11,9 @@ 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"); private final String name; 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..a498086a 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 @@ -202,6 +202,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 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..3545ed07 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,7 @@ */ package org.openehr.rm.datatypes.quantity.datetime; -import java.util.List; -import java.util.TimeZone; - +import org.apache.commons.lang.builder.EqualsBuilder; import org.joda.time.DateTime; import org.joda.time.MutableDateTime; import org.openehr.rm.Attribute; @@ -25,7 +23,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 @@ -326,6 +326,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 From 3130dc40f9ed63e8260ad80ea5c9feed845d639b Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Fri, 7 Feb 2014 09:22:34 +0000 Subject: [PATCH 009/213] (CDS) CDS-130 Added all files from github without modifications. git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk@471759 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- INSTALL.txt | 10 + LICENSE.txt | 12 + README.txt | 5 + adl-parser/docs/changes.txt | 99 + adl-parser/pom.xml | 130 + adl-parser/readme.txt | 13 + .../openehr/parser/ArchetypeValidator.java | 113 + .../acode/openehr/parser/AttributeValue.java | 30 + .../acode/openehr/parser/ContentObject.java | 32 + .../se/acode/openehr/parser/Invariant.java | 27 + .../java/se/acode/openehr/parser/Parsed.java | 36 + adl-parser/src/main/javacc/adl.jj | 3408 +++++++++++++++++ .../parser/ArchetypeDescriptionTest.java | 124 + .../parser/ArchetypeIdentificationTest.java | 52 + .../parser/ArchetypeInternalRefTest.java | 55 + .../openehr/parser/ArchetypeLanguageTest.java | 134 + .../openehr/parser/ArchetypeOntologyTest.java | 49 + .../openehr/parser/ArchetypeSlotTest.java | 127 + .../parser/ArchetypeUncommonTermKeysTest.java | 38 + .../parser/ArchetypeValidatorTest.java | 47 + .../openehr/parser/BasicGenericTypeTest.java | 12 + .../acode/openehr/parser/BasicTypesTest.java | 578 +++ .../acode/openehr/parser/CCodePhraseTest.java | 109 + .../acode/openehr/parser/CDurationTest.java | 124 + .../acode/openehr/parser/CDvOrdinalTest.java | 96 + .../acode/openehr/parser/CDvQuantityTest.java | 130 + .../openehr/parser/ConstraintBindingTest.java | 63 + .../openehr/parser/ConstraintRefTest.java | 25 + .../se/acode/openehr/parser/DateTimeTest.java | 403 ++ .../acode/openehr/parser/DvCodedTextTest.java | 23 + .../parser/EmptyOtherContributorsTest.java | 32 + .../openehr/parser/MissingLanguageTest.java | 25 + .../openehr/parser/MissingPurposeTest.java | 18 + .../openehr/parser/MixedNodeTypesTest.java | 19 + .../openehr/parser/MostMinimalADLTest.java | 35 + .../openehr/parser/MultiLanguageTest.java | 91 + .../acode/openehr/parser/ParserTestBase.java | 283 ++ .../se/acode/openehr/parser/PathTest.java | 114 + .../openehr/parser/RegularExpressionTest.java | 14 + .../openehr/parser/SpecialStringTest.java | 33 + .../acode/openehr/parser/StructureTest.java | 96 + .../acode/openehr/parser/TermBindingTest.java | 106 + .../openehr/parser/UnicodeBOMSupportTest.java | 54 + .../openehr/parser/UnicodeSupportTest.java | 78 + ...est-SOME_TYPE.generic_type_basic.draft.adl | 56 + ...-SOME_TYPE.generic_type_use_node.draft.adl | 63 + .../resources/adl-test-car.paths.test.adl | 80 + .../resources/adl-test-car.use_node.test.adl | 87 + ...dl-test-composition.dv_coded_text.test.adl | 29 + ...adl-test-entry.archetype_bindings.test.adl | 47 + ...ry.archetype_desc_missing_purpose.test.adl | 45 + ...-test-entry.archetype_description.test.adl | 61 + ...test-entry.archetype_description2.test.adl | 45 + ...st-entry.archetype_identification.test.adl | 26 + ...test-entry.archetype_internal_ref.test.adl | 40 + ...est-entry.archetype_internal_ref2.test.adl | 36 + ...adl-test-entry.archetype_language.test.adl | 47 + ...chetype_language_no_accreditation.test.adl | 38 + ...uage_order_of_translation_details.test.adl | 40 + ...adl-test-entry.archetype_ontology.test.adl | 25 + .../adl-test-entry.archetype_slot.test.adl | 40 + .../adl-test-entry.archetype_slot.test2.adl | 37 + ...test-entry.archetype_uncommonkeys.test.adl | 29 + .../adl-test-entry.basic_types.test.adl | 275 ++ .../adl-test-entry.c_code_phrase.test.adl | 77 + .../adl-test-entry.c_dv_ordinal.test.adl | 66 + ...dl-test-entry.c_dv_quantity_empty.test.adl | 46 + ...adl-test-entry.c_dv_quantity_full.test.adl | 64 + ...dl-test-entry.c_dv_quantity_full2.test.adl | 64 + ...dl-test-entry.c_dv_quantity_full3.test.adl | 64 + ...try.c_dv_quantity_item_units_only.test.adl | 55 + ...adl-test-entry.c_dv_quantity_list.test.adl | 58 + ...test-entry.c_dv_quantity_property.test.adl | 47 + ...test-entry.c_dv_quantity_reversed.test.adl | 59 + ...adl-test-entry.constraint_binding.test.adl | 37 + .../adl-test-entry.constraint_ref.test.adl | 43 + .../adl-test-entry.datetime.test.adl | 183 + .../adl-test-entry.domain_types.test.adl | 97 + .../adl-test-entry.durations.test.adl | 111 + ...st-entry.empty_other_contributors.test.adl | 42 + .../adl-test-entry.missing_language.test.adl | 23 + .../adl-test-entry.mixed_node_types.draft.adl | 61 + .../adl-test-entry.most_minimal.test.adl | 23 + .../adl-test-entry.multi_language.test.adl | 52 + ...adl-test-entry.regular_expression.test.adl | 45 + .../adl-test-entry.special_string.test.adl | 88 + .../adl-test-entry.structure_test1.test.adl | 45 + .../adl-test-entry.structure_test2.test.adl | 45 + .../adl-test-entry.term_binding.test.adl | 37 + .../adl-test-entry.term_binding2.test.adl | 32 + .../adl-test-entry.testtranslations.test.adl | 83 + ...ntry.translations_author_language.test.adl | 34 + ...ntry.translations_language_author.test.adl | 34 + ...dl-test-entry.unicode_BOM_support.test.adl | 41 + .../adl-test-entry.unicode_support.test.adl | 41 + .../openEHR-EHR-CLUSTER.auscultation.v1.adl | 48 + .../openEHR-EHR-ELEMENT.uid_test.v1.adl | 44 + .../openEHR-EHR-ELEMENT.uid_test.v2.adl | 44 + ...HR-EHR-EVALUATION.columna_vertebral.v1.adl | 85 + ...SERVATION.test_internal_ref_binding.v1.adl | 94 + ...HR-EHR-OBSERVATION.testassumedvalue.v1.adl | 99 + adl-serializer/docs/changes.txt | 28 + adl-serializer/pom.xml | 78 + adl-serializer/readme.txt | 1 + .../openehr/am/serialize/ADLSerializer.java | 1290 +++++++ .../adl/adl-test-entry.most_minimal.test.adl | 19 + .../test/adl/archetype-internal-ref-test.adl | 1 + .../src/test/adl/archetype-language.adl | 16 + .../adl/archetype-slot-any-allowed-test.adl | 1 + .../archetype-slot-empty-excludes-test.adl | 5 + .../archetype-slot-empty-includes-test.adl | 4 + .../src/test/adl/archetype-slot-test.adl | 7 + .../src/test/adl/c-code-phrase-test-empty.adl | 2 + .../src/test/adl/c-code-phrase-test.adl | 5 + .../src/test/adl/c-dv-ordinal-test-empty.adl | 2 + .../src/test/adl/c-dv-ordinal-test.adl | 5 + .../src/test/adl/c-dv-ordinal-test2.adl | 4 + .../src/test/adl/c-dv-quantity-test-empty.adl | 2 + .../src/test/adl/c-dv-quantity-test.adl | 14 + adl-serializer/src/test/adl/c-string-test.adl | 1 + .../test/adl/empty-attribute-list-test.adl | 1 + .../src/test/adl/empty-children-list-test.adl | 1 + .../src/test/adl/multi-language.adl | 53 + .../src/test/adl/multi-terminology.adl | 36 + adl-serializer/src/test/adl/ontology.adl | 45 + ...openEHR-EHR-EVALUATION.test_concept.v1.adl | 47 + .../serialize/ArchetypeInternalRefTest.java | 22 + .../am/serialize/ArchetypeLanguageTest.java | 51 + .../am/serialize/ArchetypeSlotTest.java | 173 + .../openehr/am/serialize/CCodePhraseTest.java | 92 + .../openehr/am/serialize/CDurationTest.java | 64 + .../openehr/am/serialize/CDvOrdinalTest.java | 53 + .../openehr/am/serialize/CDvQuantityTest.java | 84 + .../org/openehr/am/serialize/CommonTest.java | 139 + .../openehr/am/serialize/DescriptionTest.java | 126 + .../am/serialize/EmptyAttributeListTest.java | 29 + .../am/serialize/MultipleLanguageTest.java | 143 + .../am/serialize/MultipleTerminologyTest.java | 125 + .../openehr/am/serialize/OntologyTest.java | 129 + .../am/serialize/PrimitiveTypesTest.java | 76 + .../openehr/am/serialize/RoundTripTest.java | 46 + .../am/serialize/SerializerTestBase.java | 226 ++ .../am/serialize/SimpleArchetypeTest.java | 83 + archetype-validator/pom.xml | 89 + .../am/validation/ArchetypeValidator.java | 1545 ++++++++ .../org/openehr/am/validation/ErrorType.java | 80 + .../am/validation/RMInspectionException.java | 11 + .../openehr/am/validation/RMInspector.java | 583 +++ .../SpecialisedArchetypeValidator.java | 767 ++++ .../openehr/am/validation/UTF8Control.java | 61 + .../am/validation/ValidationError.java | 139 + .../src/main/resources/log4j.properties | 9 + .../src/main/resources/validations.properties | 113 + .../src/main/resources/validations.txt | 34 + .../main/resources/validations_de.properties | 113 + .../main/resources/validations_en.properties | 2 + .../main/resources/validations_ru.properties | 113 + .../ArchetypeDefinitionCodeCheckTest.java | 20 + .../ArchetypeInternalRefCheckTest.java | 58 + .../am/validation/ArchetypeSlotCheckTest.java | 24 + .../validation/ArchetypeTermValidityTest.java | 68 + .../ArchetypeValidationTestBase.java | 94 + .../am/validation/AssumedValueTest.java | 27 + .../am/validation/AttributeNameCheckTest.java | 46 + .../CodeConstraintValidityTest.java | 48 + .../DefinitionTypenameCheckTest.java | 24 + .../am/validation/DvQuantityUnitsTest.java | 17 + ...alueAttributeChildIdentifierCheckTest.java | 28 + ...MultipleValueAttributeCardinalityTest.java | 55 + .../OntologyCodeSpecialisationCheckTest.java | 37 + .../OntologyTranslationCheckTest.java | 53 + .../am/validation/RMInspectorTest.java | 78 + ...alueAttributeChildIdentifierCheckTest.java | 21 + ...lueAttributeChildOccurrencesCheckTest.java | 26 + ...alueAttributeChildUniquenessCheckTest.java | 27 + .../SpecialisedArchetypeCardinalityTest.java | 22 + .../SpecialisedArchetypeExistenceTest.java | 18 + .../SpecialisedArchetypeMultiplicityTest.java | 18 + ...ialisedArchetypeNodeIdConformanceTest.java | 17 + ...rchetypeNodeSpecialisedAsRequiredTest.java | 18 + ...ialisedArchetypeNonCComplexObjectTest.java | 20 + .../SpecialisedArchetypeOccurrencesTest.java | 18 + .../SpecialisedArchetypeTermExistsTest.java | 34 + ...pecialisedArchetypeValidationTestBase.java | 68 + .../SpecialisedArchetypeWrongRMTypeTest.java | 30 + .../SpecializationArchetypeIdTest.java | 31 + .../SpecializationDepthCheckTest.java | 60 + .../validation/TermBindingsValidityTest.java | 27 + .../am/validation/TypeNameCheckTest.java | 141 + .../UniqueSiblingAttributesCheckTest.java | 25 + .../ValidateOpenEHRTerminologyCodesTest.java | 15 + .../am/validation/ValidatorUtilityTest.java | 52 + ...ised-EVALUATION.cardinality-specialised.v1 | 63 + ...ised-EVALUATION.cardinality-specialised.v2 | 63 + .../adl-specialised-EVALUATION.cardinality.v1 | 55 + ...alised-EVALUATION.existence-specialised.v1 | 67 + .../adl-specialised-EVALUATION.existence.v1 | 55 + ...sed-EVALUATION.multiplicity-specialised.v1 | 63 + ...adl-specialised-EVALUATION.multiplicity.v1 | 55 + ...N.node_id_conformance-specialised-again.v1 | 67 + ...LUATION.node_id_conformance-specialised.v1 | 59 + ...ode_specialised_as_required-specialised.v1 | 59 + ...EVALUATION.node_specialised_as_required.v1 | 55 + ...ised-EVALUATION.occurrences-specialised.v1 | 67 + .../adl-specialised-EVALUATION.occurrences.v1 | 55 + ...d-EVALUATION.term_existence-specialised.v1 | 59 + ...d-EVALUATION.term_existence-specialised.v2 | 59 + ...l-specialised-EVALUATION.term_existence.v1 | 64 + ...l-specialised-EVALUATION.term_existence.v2 | 51 + ...ised-EVALUATION.wrongrmtype-specialised.v1 | 110 + ...ised-EVALUATION.wrongrmtype-specialised.v2 | 65 + ...ised-EVALUATION.wrongrmtype-specialised.v3 | 61 + .../adl-specialised-EVALUATION.wrongrmtype.v1 | 92 + .../adl-specialised-EVALUATION.wrongrmtype.v2 | 55 + .../adl-specialised-EVALUATION.wrongrmtype.v3 | 58 + ...-test-ELEMENT.assumed_value_boolean.v1.adl | 29 + ...dl-test-ELEMENT.assumed_value_count.v1.adl | 29 + ...test-ELEMENT.assumed_value_quantity.v1.adl | 40 + ...-ELEMENT.specialization-archetypeid.v1.adl | 32 + ...-ELEMENT.specialization-archetypeid.v2.adl | 32 + ...-ELEMENT.specialization-archetypeid.v3.adl | 32 + ...l-test-ELEMENT.specialization-depth.v1.adl | 32 + ...l-test-ELEMENT.specialization-depth.v2.adl | 32 + ...l-test-ELEMENT.specialization-depth.v3.adl | 32 + ...l-test-ELEMENT.specialization-depth.v4.adl | 36 + ...l-test-ELEMENT.specialization-depth.v5.adl | 42 + .../adl-test-ELEMENT.specialization.v1.adl | 25 + .../adl-test-ELEMENT.type_boolean.v1.adl | 29 + .../adl-test-ELEMENT.type_count.v1.adl | 29 + .../adl-test-ELEMENT.type_date.v1.adl | 29 + .../adl-test-ELEMENT.type_date.v2.adl | 25 + .../adl-test-ELEMENT.type_datetime.v1.adl | 29 + .../adl-test-ELEMENT.type_duration.v1.adl | 29 + .../adl-test-ELEMENT.type_ehr_uri.v1.adl | 27 + .../adl-test-ELEMENT.type_interval.v1.adl | 27 + .../adl-test-ELEMENT.type_interval.v2.adl | 37 + .../adl-test-ELEMENT.type_interval.v3.adl | 37 + .../adl-test-ELEMENT.type_interval.v4.adl | 30 + .../adl-test-ELEMENT.type_interval.v5.adl | 30 + .../adl-test-ELEMENT.type_interval.v6.adl | 37 + .../adl-test-ELEMENT.type_multimedia.v1.adl | 36 + .../adl-test-ELEMENT.type_multimedia.v2.adl | 36 + .../resources/adl-test-ELEMENT.type_name.v1 | 29 + .../resources/adl-test-ELEMENT.type_name.v2 | 29 + .../resources/adl-test-ELEMENT.type_name.v3 | 29 + .../adl-test-ELEMENT.type_proportion.v1.adl | 31 + .../adl-test-ELEMENT.type_uri.v1.adl | 27 + .../adl-test-ENTRY.attribute_name.v1 | 39 + .../adl-test-ENTRY.attribute_name.v2 | 39 + .../adl-test-ENTRY.attribute_name.v3 | 36 + .../adl-test-ENTRY.code_constraint.v1 | 35 + .../adl-test-ENTRY.code_constraint.v2 | 25 + .../adl-test-ENTRY.code_constraint.v3 | 56 + .../adl-test-ENTRY.definition_code.v1 | 39 + .../adl-test-ENTRY.definition_code.v2 | 39 + .../adl-test-ENTRY.definition_typename.v1 | 23 + .../adl-test-ENTRY.definition_typename.v2 | 23 + .../adl-test-ENTRY.definition_typename.v3 | 23 + ...-test-ENTRY.ontology-specialisation.v1.adl | 39 + ...-test-ENTRY.ontology-specialisation.v2.adl | 42 + ...-test-ENTRY.ontology-specialisation.v3.adl | 42 + ...-test-ENTRY.ontology-specialisation.v4.adl | 42 + ...-test-ENTRY.ontology-specialisation.v5.adl | 42 + ...adl-test-ENTRY.ontology-unusedcodes.v1.adl | 43 + ...adl-test-ENTRY.ontology-unusedcodes.v2.adl | 51 + .../adl-test-ENTRY.ontology_translation.v1 | 25 + .../adl-test-ENTRY.ontology_translation.v2 | 48 + .../adl-test-ENTRY.ontology_translation.v3 | 56 + .../adl-test-ENTRY.ontology_translation.v4 | 56 + .../adl-test-ENTRY.ontology_translation.v5 | 64 + .../adl-test-ENTRY.ontology_translation.v6 | 71 + .../adl-test-ENTRY.ontology_translation.v7 | 46 + .../resources/adl-test-ENTRY.sibling_nodes.v1 | 38 + .../resources/adl-test-ENTRY.sibling_nodes.v2 | 39 + ...ENTRY.single_attribute_child_identifier.v1 | 54 + ...ENTRY.single_attribute_child_identifier.v2 | 54 + ...NTRY.single_attribute_child_occurrences.v1 | 39 + ...NTRY.single_attribute_child_occurrences.v2 | 39 + ...NTRY.single_attribute_child_occurrences.v3 | 39 + ...ENTRY.single_attribute_child_uniqueness.v1 | 54 + ...ENTRY.single_attribute_child_uniqueness.v2 | 46 + ...ENTRY.single_attribute_child_uniqueness.v3 | 39 + .../resources/adl-test-ENTRY.term_bindings.v1 | 73 + .../resources/adl-test-ENTRY.term_bindings.v2 | 76 + .../adl-test-ENTRY.term_definition.v1 | 19 + .../adl-test-ENTRY.term_definition.v2 | 23 + .../adl-test-ENTRY.term_definition.v3 | 23 + .../adl-test-ENTRY.term_definition.v4 | 36 + ...dl-test-ITEM_TREE.attribute_cardinality.v1 | 36 + ...dl-test-ITEM_TREE.attribute_cardinality.v2 | 45 + ...dl-test-ITEM_TREE.attribute_cardinality.v3 | 40 + ...M_TREE.multi_attribute_child_identifier.v1 | 52 + ...M_TREE.multi_attribute_child_identifier.v2 | 52 + ...M_TREE.multi_attribute_child_identifier.v3 | 52 + .../adl-test-PARTY_PROXY.type_name.v1 | 25 + .../openEHR-EHR-ACTION.follow_up.v1.adl | 46 + ...EHR-CLUSTER.cardinality_occurrences.v1.adl | 69 + ...HR-CLUSTER.cardinality_occurrences2.v1.adl | 69 + ...HR-CLUSTER.cardinality_occurrences3.v1.adl | 69 + ...nEHR-EHR-CLUSTER.internal_reference.v1.adl | 60 + ...HR-CLUSTER.testNonUniqueInternalRef.v1.adl | 54 + ...HR-CLUSTER.testNonUniqueInternalRef.v2.adl | 63 + ...LUSTER.test_non_ccomplexobject-spec.v1.adl | 97 + ...EHR-CLUSTER.test_non_ccomplexobject.v1.adl | 61 + .../openEHR-EHR-CLUSTER.units_test.v1.adl | 152 + ...nEHR-EHR-ELEMENT.doubleontologycode.v1.adl | 48 + .../openEHR-EHR-EVALUATION.adverse.v1.adl | 411 ++ .../openEHR-EHR-EVALUATION.null_flavor.v1.adl | 90 + ...openEHR-EHR-EVALUATION.null_flavour.v1.adl | 90 + ...HR-EHR-EVALUATION.problem-diagnosis.v1.adl | 897 +++++ ...-EHR-OBSERVATION.internal_reference.v1.adl | 70 + ...-EHR-OBSERVATION.internal_reference.v2.adl | 70 + ...-EHR-OBSERVATION.internal_reference.v3.adl | 70 + ...-EHR-OBSERVATION.internal_reference.v4.adl | 70 + ...-EHR-OBSERVATION.internal_reference.v5.adl | 70 + ...-EHR-OBSERVATION.internal_reference.v6.adl | 150 + ...HR-OBSERVATION.order1-order2-order3.v1.adl | 112 + ...R-OBSERVATION.order1-order2-order3a.v1.adl | 112 + ...enEHR-EHR-OBSERVATION.order1-order2.v1.adl | 99 + .../openEHR-EHR-OBSERVATION.slot.v1.adl | 57 + .../openEHR-EHR-OBSERVATION.slot.v2.adl | 57 + .../openEHR-EHR-OBSERVATION.type_name.v4.adl | 43 + dadl-binding/pom.xml | 84 + .../org/openehr/rm/binding/DADLBinding.java | 407 ++ .../rm/binding/DADLBindingException.java | 54 + .../org/openehr/rm/binding/RMInspector.java | 528 +++ .../org/openehr/rm/binding/XPathUtil.java | 206 + .../openehr/rm/binding/BindRMToDADLTest.java | 165 + .../openehr/rm/binding/DADLBindingTest.java | 371 ++ .../rm/binding/DADLBindingTestBase.java | 47 + .../rm/binding/DuplicatedCodesTest.java | 15 + .../java/org/openehr/rm/binding/LoadTest.java | 27 + .../org/openehr/rm/binding/XPathTest.java | 576 +++ .../adl-test-CLUSTER.test_cluster.v1.adl | 88 + .../adl-test-ITEM_TREE.test_tree.v1.adl | 110 + .../src/test/resources/archetyped.dadl | 6 + .../src/test/resources/body_weight.dadl | 59 + .../src/test/resources/code_phrase.dadl | 6 + .../src/test/resources/demographics.dadl | 68 + .../src/test/resources/duplicated_codes.dadl | 5 + .../src/test/resources/dv_coded_text.dadl | 9 + .../src/test/resources/dv_quantity.dadl | 4 + dadl-binding/src/test/resources/dv_text.dadl | 3 + dadl-binding/src/test/resources/element.dadl | 10 + .../src/test/resources/element_with_text.dadl | 9 + .../empty_element_with_null_flavour.dadl | 15 + .../src/test/resources/empty_item_list.dadl | 7 + dadl-binding/src/test/resources/history.dadl | 44 + dadl-binding/src/test/resources/history2.dadl | 52 + .../src/test/resources/item_list.dadl | 28 + .../src/test/resources/item_tree_bp.dadl | 46 + .../src/test/resources/item_tree_bp2.dadl | 28 + dadl-binding/src/test/resources/lab_test.dadl | 59 + .../src/test/resources/log4j.properties | 10 + .../src/test/resources/observation.dadl | 69 + .../src/test/resources/observation2.dadl | 92 + .../src/test/resources/observation3.dadl | 69 + .../src/test/resources/order_set1.dadl | 826 ++++ .../src/test/resources/point_event.dadl | 35 + .../src/test/resources/point_event2.dadl | 41 + .../src/test/resources/tree_2_slots.dadl | 164 + .../src/test/resources/tree_nested_slot.dadl | 146 + .../src/test/resources/tree_nested_slot2.dadl | 172 + .../src/test/resources/tree_nested_slot3.dadl | 95 + .../src/test/resources/tree_nested_slot4.dadl | 141 + .../src/test/resources/tree_slot.dadl | 123 + .../test/resources/typed_archetype_id.dadl | 3 + .../src/test/resources/typed_dv_boolean.dadl | 3 + .../src/test/resources/typed_dv_ordinal.dadl | 12 + .../src/test/resources/typed_dv_quantity.dadl | 4 + .../test/resources/typed_dv_quantity2.dadl | 6 + .../src/test/resources/typed_dv_text.dadl | 3 + .../src/test/resources/typed_party_self.dadl | 1 + .../test/resources/typed_terminology_id.dadl | 3 + dadl-binding/src/test/resources/weight.dadl | 0 dadl-binding/tree_2_slots.dadl | 164 + dadl-parser/pom.xml | 80 + .../org/openehr/am/parser/AttributeValue.java | 46 + .../org/openehr/am/parser/BooleanValue.java | 26 + .../org/openehr/am/parser/CharacterValue.java | 26 + .../java/org/openehr/am/parser/CodeValue.java | 9 + .../openehr/am/parser/ComplexObjectBlock.java | 26 + .../org/openehr/am/parser/ContentObject.java | 50 + .../org/openehr/am/parser/DateTimeValue.java | 28 + .../java/org/openehr/am/parser/DateValue.java | 28 + .../org/openehr/am/parser/DurationValue.java | 28 + .../org/openehr/am/parser/IntegerValue.java | 26 + .../org/openehr/am/parser/KeyedObject.java | 39 + .../parser/MultipleAttributeObjectBlock.java | 37 + .../org/openehr/am/parser/ObjectBlock.java | 38 + .../java/org/openehr/am/parser/Parsed.java | 40 + .../am/parser/PrimitiveObjectBlock.java | 65 + .../java/org/openehr/am/parser/RealValue.java | 26 + .../org/openehr/am/parser/SimpleValue.java | 34 + .../am/parser/SingleAttributeObjectBlock.java | 37 + .../org/openehr/am/parser/StringValue.java | 26 + .../java/org/openehr/am/parser/TimeValue.java | 28 + .../java/org/openehr/am/parser/UriValue.java | 28 + dadl-parser/src/main/javacc/dadl.jj | 32 + .../parser/EmptyAttributeListBlockTest.java | 28 + .../org/openehr/am/parser/ItemListTest.java | 27 + .../openehr/am/parser/KeyedObjectTest.java | 72 + .../org/openehr/am/parser/ParserTestBase.java | 49 + .../openehr/am/parser/SimpleValuesTest.java | 158 + .../am/parser/SingleValueListTest.java | 30 + .../org/openehr/am/parser/StructureTest.java | 20 + .../am/parser/TypedObjectBlockTest.java | 15 + .../test/resources/blood_pressure_001.dadl | 44 + .../src/test/resources/empty_attr_list.dadl | 1 + .../empty_attr_list_without_type.dadl | 1 + .../src/test/resources/keyed_objects.dadl | 8 + .../src/test/resources/keyed_objects2.dadl | 8 + .../src/test/resources/person_001.dadl | 14 + .../src/test/resources/simple_values.dadl | 12 + .../test/resources/simple_values_list.dadl | 13 + .../test/resources/single_values_list.dadl | 12 + .../src/test/resources/state_item_list.dadl | 7 + .../src/test/resources/typed_dv_quantity.dadl | 4 + measure-serv/pom.xml | 40 + measure-serv/readme.txt | 1 + .../measurement/MeasurementService.java | 99 + .../measurement/SimpleMeasurementService.java | 263 ++ .../SimpleMeasurementServiceTest.java | 57 + mini-termserv/pom.xml | 45 + .../java/org/openehr/terminology/CodeSet.java | 63 + .../java/org/openehr/terminology/Concept.java | 49 + .../java/org/openehr/terminology/Group.java | 60 + .../terminology/SimpleCodeSetAccess.java | 117 + .../terminology/SimpleTerminologyAccess.java | 182 + .../terminology/SimpleTerminologyService.java | 183 + .../terminology/TerminologySource.java | 58 + .../terminology/TerminologySourceFactory.java | 72 + .../terminology/XMLTerminologySource.java | 147 + .../resources/external_terminologies_en.xml | 409 ++ .../src/main/resources/log4j.properties | 9 + .../main/resources/openehr_terminology_en.xml | 320 ++ .../terminology/OpenEHRTerminologyTest.java | 85 + .../terminology/SimpleCodeSetAccessTest.java | 57 + .../SimpleTerminologyAccessTest.java | 154 + .../SimpleTerminologyServiceTest.java | 102 + .../terminology/TranslationDetailsTest.java | 25 + oet-parser/pom.xml | 119 + .../org/openehr/am/template/Flattener.java | 1732 +++++++++ .../am/template/FlatteningException.java | 47 + .../org/openehr/am/template/OETParser.java | 58 + .../java/org/openehr/am/template/PathMap.java | 196 + .../java/org/openehr/am/template/TermMap.java | 342 ++ oet-parser/src/main/xsd/Archetype.xsd | 394 ++ oet-parser/src/main/xsd/BaseTypes.xsd | 594 +++ oet-parser/src/main/xsd/CharacterMapping.xsd | 11 + oet-parser/src/main/xsd/Composition.xsd | 36 + .../src/main/xsd/CompositionTemplate.xsd | 487 +++ oet-parser/src/main/xsd/Content.xsd | 136 + oet-parser/src/main/xsd/Extract.xsd | 140 + oet-parser/src/main/xsd/OpenehrProfile.xsd | 96 + oet-parser/src/main/xsd/Resource.xsd | 63 + oet-parser/src/main/xsd/Structure.xsd | 151 + oet-parser/src/main/xsd/Template.xsd | 164 + oet-parser/src/main/xsd/Version.xsd | 41 + .../am/template/ActionDescriptionTest.java | 21 + .../openehr/am/template/AnnotationTest.java | 13 + .../am/template/ArchetypeSlotTest.java | 50 + .../am/template/CompositionTemplateTest.java | 111 + .../am/template/MultipleConstraintTest.java | 79 + .../org/openehr/am/template/PathMapTest.java | 28 + .../am/template/QuantityConstraintTest.java | 113 + .../am/template/SectionEvaluationTest.java | 178 + .../am/template/SectionInstructionTest.java | 75 + .../am/template/SectionTemplateTest.java | 114 + .../SetCardinalityConstraintsTest.java | 52 + ...tConstraintOnNamedNodeWithoutNameTest.java | 25 + .../SetMaxOccurrencesWithoutMinTest.java | 36 + .../am/template/SetMixedConstraintsTest.java | 36 + .../SetMultipleEvaluationNameTest.java | 29 + .../template/SetNestedEvaluationNameTest.java | 24 + .../openehr/am/template/SetNodeNameTest.java | 60 + .../am/template/SetNodeOccurrencesTest.java | 190 + .../template/SetOccurrencesAndNameTest.java | 22 + .../am/template/TemplateParseTest.java | 69 + .../openehr/am/template/TemplateTestBase.java | 652 ++++ .../org/openehr/am/template/TermMapTest.java | 31 + .../am/template/TextConstraintTest.java | 187 + .../openehr/am/template/UTF8EncodingTest.java | 30 + .../org/openehr/am/template/UtilityTest.java | 49 + .../openEHR-EHR-ACTION.medication.v1.adl | 319 ++ ...R-ADMIN_ENTRY.heart_failure_contact.v1.adl | 281 ++ ...penEHR-EHR-COMPOSITION.prescription.v1.adl | 97 + ...-COMPOSITION.prescription_flattened.v1.adl | 713 ++++ .../openEHR-EHR-COMPOSITION.test.v1.adl | 31 + ...HR-EHR-EVALUATION.adjusted_node_ids.v1.adl | 61 + ...EHR-EHR-EVALUATION.hybrid_path_test.v1.adl | 89 + ...HR-EHR-EVALUATION.medication_review.v1.adl | 136 + ...EHR-EVALUATION.review_of_procedures.v1.adl | 88 + ...R-EHR-EVALUATION.structured_summary.v1.adl | 81 + .../openEHR-EHR-INSTRUCTION.medication.v1.adl | 90 + .../openEHR-EHR-ITEM_TREE.medication.v1.adl | 919 +++++ ...penEHR-EHR-ITEM_TREE.medication_mod.v1.adl | 921 +++++ ...cation_multiple_constraint_expected.v1.adl | 33 + ...medication_multiple_constraint_test.v1.adl | 50 + ...edication_multiple_constraint_test2.v1.adl | 27 + ...-ITEM_TREE.medication_quantity_test.v1.adl | 31 + ...ITEM_TREE.medication_quantity_test2.v1.adl | 47 + ...R-EHR-ITEM_TREE.medication_test_one.v1.adl | 31 + ...R-EHR-ITEM_TREE.medication_test_one.v2.adl | 32 + ...M_TREE.medication_test_text_default.v1.adl | 29 + ...ITEM_TREE.medication_test_text_name.v1.adl | 32 + ...EHR-ITEM_TREE.medication_test_three.v1.adl | 31 + ...R-EHR-ITEM_TREE.medication_test_two.v1.adl | 31 + ...EHR-OBSERVATION.heart_failure_stage.v2.adl | 173 + .../openEHR-EHR-OBSERVATION.lab_test.v1.adl | 250 ++ .../openEHR-EHR-OBSERVATION.waist_hip.v2.adl | 129 + .../openEHR-EHR-SECTION.ad_hoc_heading.v1.adl | 40 + ...HR-EHR-SECTION.find_largest_node_id.v1.adl | 62 + ...-EHR-SECTION.find_largest_node_id_2.v1.adl | 62 + .../openEHR-EHR-SECTION.medications.v1.adl | 52 + ...HR-EHR-SECTION.more_nested_sections.v1.adl | 62 + ...openEHR-EHR-SECTION.nested_sections.v1.adl | 48 + ...EHR-EHR-SECTION.simple_section_name.v1.adl | 46 + .../src/test/resources/log4j.properties | 11 + .../test/resources/templates/prescription.oet | 12 + .../templates/test_action_description.oet | 8 + .../resources/templates/test_annotation.oet | 8 + .../resources/templates/test_composition.oet | 9 + .../resources/templates/test_composition2.oet | 9 + .../resources/templates/test_composition3.oet | 11 + .../resources/templates/test_composition4.oet | 9 + .../resources/templates/test_composition5.oet | 12 + .../templates/test_default_coded_name.oet | 8 + .../templates/test_default_coded_text.oet | 8 + .../resources/templates/test_default_text.oet | 8 + .../resources/templates/test_hybrid_path.oet | 12 + .../resources/templates/test_max_value.oet | 8 + .../resources/templates/test_min_value.oet | 8 + .../templates/test_more_nested_section.oet | 14 + .../templates/test_multiple_constraint.oet | 12 + .../templates/test_multiple_constraint2.oet | 14 + .../templates/test_multiple_constraint3.oet | 12 + .../test_name_default_coded_text.oet | 8 + .../resources/templates/test_named_path.oet | 8 + .../resources/templates/test_named_path2.oet | 9 + .../resources/templates/test_named_path3.oet | 9 + .../templates/test_nested_section.oet | 8 + .../test_nested_section_evaluation.oet | 10 + ...est_quantity_constraint_excluded_units.oet | 12 + ...est_quantity_constraint_included_units.oet | 12 + ...st_quantity_constraint_included_units2.oet | 12 + ...st_quantity_constraint_included_units3.oet | 12 + .../test_quantity_constraint_magnitude.oet | 18 + .../test_quantity_constraint_mixed.oet | 21 + .../test_quantity_constraint_precision.oet | 16 + .../templates/test_section_evaluation.oet | 8 + .../templates/test_section_evaluation2.oet | 9 + .../templates/test_section_instruction.oet | 8 + .../test_section_instruction_tree.oet | 10 + ...t_set_cardinality_with_prohibited_node.oet | 12 + ..._set_cardinality_with_prohibited_node2.oet | 15 + ..._set_cardinality_with_prohibited_node3.oet | 12 + .../templates/test_set_evaluation_name.oet | 8 + .../templates/test_set_evaluation_name_.oet | 8 + .../templates/test_set_mixed_constraints.oet | 28 + .../test_set_multiple_evaluation_name.oet | 10 + ...set_named_node_constraint_without_name.oet | 15 + .../test_set_occurrences_and_name.oet | 15 + .../test_set_occurrences_without_min.oet | 8 + .../test_set_occurrences_without_min2.oet | 8 + .../templates/test_simple_section.oet | 8 + .../templates/test_text_constraints.oet | 14 + .../resources/templates/test_text_name.oet | 8 + .../templates/test_utf8_encoding.oet | 8 + oet-parser/src/test/resources/terms.txt | 7 + oet-parser/src/test/resources/terms_path.txt | 7 + .../src/test/resources/test_path_map.txt | 3 + openehr-aom/docs/changes.txt | 25 + openehr-aom/pom.xml | 46 + .../org/openehr/am/archetype/Archetype.java | 521 +++ .../am/archetype/assertion/Assertion.java | 164 + .../assertion/AssertionVariable.java | 97 + .../assertion/ExpressionBinaryOperator.java | 121 + .../archetype/assertion/ExpressionItem.java | 123 + .../archetype/assertion/ExpressionLeaf.java | 179 + .../assertion/ExpressionOperator.java | 97 + .../assertion/ExpressionUnaryOperator.java | 102 + .../am/archetype/assertion/OperatorKind.java | 158 + .../constraintmodel/ArchetypeConstraint.java | 216 ++ .../constraintmodel/ArchetypeInternalRef.java | 138 + .../constraintmodel/ArchetypeSlot.java | 193 + .../archetype/constraintmodel/CAttribute.java | 282 ++ .../constraintmodel/CComplexObject.java | 254 ++ .../constraintmodel/CDefinedObject.java | 153 + .../constraintmodel/CDomainType.java | 169 + .../constraintmodel/CMultipleAttribute.java | 134 + .../am/archetype/constraintmodel/CObject.java | 255 ++ .../constraintmodel/CPrimitiveObject.java | 188 + .../constraintmodel/CReferenceObject.java | 71 + .../constraintmodel/CSingleAttribute.java | 144 + .../constraintmodel/Cardinality.java | 190 + .../constraintmodel/ConstraintRef.java | 171 + .../constraintmodel/primitive/CBoolean.java | 223 ++ .../constraintmodel/primitive/CDate.java | 280 ++ .../constraintmodel/primitive/CDateTime.java | 252 ++ .../constraintmodel/primitive/CDuration.java | 217 ++ .../constraintmodel/primitive/CInteger.java | 228 ++ .../constraintmodel/primitive/CPrimitive.java | 129 + .../constraintmodel/primitive/CReal.java | 205 + .../constraintmodel/primitive/CString.java | 246 ++ .../constraintmodel/primitive/CTime.java | 247 ++ .../archetype/ontology/ArchetypeOntology.java | 257 ++ .../am/archetype/ontology/ArchetypeTerm.java | 187 + .../archetype/ontology/ConstraintBinding.java | 96 + .../am/archetype/ontology/DefinitionItem.java | 126 + .../archetype/ontology/OntologyBinding.java | 133 + .../ontology/OntologyBindingItem.java | 126 + .../ontology/OntologyDefinitions.java | 126 + .../openehr/am/archetype/ontology/Query.java | 134 + .../archetype/ontology/QueryBindingItem.java | 118 + .../archetype/ontology/TermBindingItem.java | 119 + .../am/archetype/ArchetypePathTest.java | 5 + .../am/archetype/assertion/AssertionTest.java | 72 + .../assertion/ExpressionToStringTest.java | 73 + .../constraintmodel/ArchetypeSlotTest.java | 75 + .../constraintmodel/CAttributeTest.java | 140 + .../constraintmodel/CObjectTest.java | 101 + .../constraintmodel/CPrimitiveObjectTest.java | 15 + .../primitive/CBooleanTest.java | 101 + .../constraintmodel/primitive/CDateTest.java | 129 + .../primitive/CDateTimeTest.java | 164 + .../primitive/CDurationTest.java | 94 + .../primitive/CIntegerTest.java | 102 + .../constraintmodel/primitive/CRealTest.java | 99 + .../primitive/CStringTest.java | 120 + .../constraintmodel/primitive/CTimeTest.java | 151 + .../ontology/ArchetypeOntologyTest.java | 103 + .../archetype/ontology/ArchetypeTermTest.java | 28 + openehr-ap/docs/changes.txt | 15 + openehr-ap/pom.xml | 56 + .../datatypes/basic/CDvState.java | 168 + .../datatypes/basic/NonTerminalState.java | 91 + .../openehrprofile/datatypes/basic/State.java | 113 + .../datatypes/basic/StateMachine.java | 117 + .../datatypes/basic/TerminalState.java | 65 + .../datatypes/basic/Transition.java | 139 + .../datatypes/quantity/CDvOrdinal.java | 187 + .../datatypes/quantity/CDvQuantity.java | 289 ++ .../datatypes/quantity/CDvQuantityItem.java | 169 + .../datatypes/quantity/Ordinal.java | 146 + .../datatypes/text/CCodePhrase.java | 237 ++ .../datatypes/basic/CDvStateTest.java | 61 + .../datatypes/quantity/CDvOrdinalTest.java | 75 + .../quantity/CDvQuantityItemTest.java | 26 + .../datatypes/quantity/CDvQuantityTest.java | 152 + .../datatypes/quantity/OrdinalTest.java | 22 + .../datatypes/text/CCodePhraseTest.java | 114 + openehr-rm-core/pom.xml | 45 + .../main/java/org/openehr/rm/Attribute.java | 65 + .../java/org/openehr/rm/FullConstructor.java | 63 + .../main/java/org/openehr/rm/RMObject.java | 55 + .../rm/common/archetyped/Archetyped.java | 200 + .../rm/common/archetyped/FeederAudit.java | 210 + .../common/archetyped/FeederAuditDetails.java | 218 ++ .../openehr/rm/common/archetyped/Link.java | 183 + .../rm/common/archetyped/Locatable.java | 702 ++++ .../rm/common/archetyped/Pathable.java | 163 + .../rm/common/archetyped/Settable.java | 76 + .../rm/common/changecontrol/Contribution.java | 179 + .../common/changecontrol/ImportedVersion.java | 109 + .../common/changecontrol/OriginalVersion.java | 157 + .../rm/common/changecontrol/Version.java | 252 ++ .../common/changecontrol/VersionedObject.java | 460 +++ .../openehr/rm/common/directory/Folder.java | 175 + .../rm/common/directory/VersionedFolder.java | 104 + .../rm/common/generic/Attestation.java | 193 + .../rm/common/generic/AuditDetails.java | 228 ++ .../rm/common/generic/Participation.java | 218 ++ .../rm/common/generic/PartyIdentified.java | 167 + .../openehr/rm/common/generic/PartyProxy.java | 127 + .../rm/common/generic/PartyRelated.java | 145 + .../openehr/rm/common/generic/PartySelf.java | 70 + .../rm/common/generic/RevisionHistory.java | 147 + .../common/generic/RevisionHistoryItem.java | 145 + .../rm/common/resource/AuthoredResource.java | 277 ++ .../common/resource/ResourceDescription.java | 301 ++ .../resource/ResourceDescriptionItem.java | 312 ++ .../common/resource/TranslationDetails.java | 189 + .../rm/datastructure/DataStructure.java | 115 + .../rm/datastructure/history/Event.java | 252 ++ .../rm/datastructure/history/History.java | 318 ++ .../datastructure/history/IntervalEvent.java | 198 + .../rm/datastructure/history/PointEvent.java | 136 + .../datastructure/itemstructure/ItemList.java | 241 ++ .../itemstructure/ItemSingle.java | 171 + .../itemstructure/ItemStructure.java | 87 + .../itemstructure/ItemTable.java | 399 ++ .../datastructure/itemstructure/ItemTree.java | 225 ++ .../itemstructure/representation/Cluster.java | 177 + .../itemstructure/representation/Element.java | 268 ++ .../itemstructure/representation/Item.java | 98 + .../openehr/rm/datatypes/basic/DataValue.java | 155 + .../openehr/rm/datatypes/basic/DvBoolean.java | 190 + .../rm/datatypes/basic/DvIdentifier.java | 202 + .../openehr/rm/datatypes/basic/DvState.java | 170 + .../datatypes/basic/ReferenceModelName.java | 32 + .../encapsulated/DvEncapsulated.java | 132 + .../datatypes/encapsulated/DvMultimedia.java | 327 ++ .../rm/datatypes/encapsulated/DvParsable.java | 191 + .../quantity/DvAbsoluteQuantity.java | 115 + .../rm/datatypes/quantity/DvAmount.java | 155 + .../rm/datatypes/quantity/DvCount.java | 246 ++ .../rm/datatypes/quantity/DvInterval.java | 204 + .../rm/datatypes/quantity/DvOrdered.java | 254 ++ .../rm/datatypes/quantity/DvOrdinal.java | 297 ++ .../rm/datatypes/quantity/DvProportion.java | 315 ++ .../rm/datatypes/quantity/DvQuantified.java | 144 + .../rm/datatypes/quantity/DvQuantity.java | 400 ++ .../rm/datatypes/quantity/ProportionKind.java | 140 + .../rm/datatypes/quantity/ReferenceRange.java | 184 + .../datatypes/quantity/datetime/DvDate.java | 359 ++ .../quantity/datetime/DvDateTime.java | 447 +++ .../quantity/datetime/DvDateTimeParser.java | 506 +++ .../quantity/datetime/DvDuration.java | 622 +++ .../quantity/datetime/DvTemporal.java | 234 ++ .../datatypes/quantity/datetime/DvTime.java | 418 ++ .../openehr/rm/datatypes/text/CodePhrase.java | 209 + .../rm/datatypes/text/DvCodedText.java | 225 ++ .../rm/datatypes/text/DvParagraph.java | 120 + .../org/openehr/rm/datatypes/text/DvText.java | 310 ++ .../org/openehr/rm/datatypes/text/Match.java | 77 + .../rm/datatypes/text/TermMapping.java | 215 ++ .../timespec/DvGeneralTimeSpecification.java | 118 + .../timespec/DvPeriodicTimeSpecification.java | 135 + .../timespec/DvTimeSpecification.java | 111 + .../openehr/rm/datatypes/uri/DvEHRURI.java | 86 + .../org/openehr/rm/datatypes/uri/DvURI.java | 201 + .../rm/security/AccessControlSettings.java | 58 + .../rm/support/ExternalEnvironment.java | 73 + .../openehr/rm/support/basic/Interval.java | 243 ++ .../definition/OpenehrDefinitions.java | 61 + .../identification/AccessGroupRef.java | 65 + .../support/identification/ArchetypeID.java | 419 ++ .../rm/support/identification/GenericID.java | 118 + .../support/identification/HierObjectID.java | 176 + .../rm/support/identification/ISO_OID.java | 82 + .../rm/support/identification/InternetID.java | 79 + .../support/identification/LocatableRef.java | 143 + .../rm/support/identification/ObjectID.java | 129 + .../rm/support/identification/ObjectRef.java | 214 ++ .../identification/ObjectVersionID.java | 184 + .../rm/support/identification/PartyRef.java | 77 + .../rm/support/identification/TemplateID.java | 60 + .../support/identification/TerminologyID.java | 139 + .../rm/support/identification/UID.java | 118 + .../rm/support/identification/UIDBasedID.java | 95 + .../rm/support/identification/UUID.java | 77 + .../support/identification/VersionTreeID.java | 257 ++ .../rm/support/terminology/CodeSetAccess.java | 87 + .../OpenEHRCodeSetIdentifiers.java | 98 + .../OpenEHRTerminologyGroupIdentifiers.java | 114 + .../terminology/TerminologyAccess.java | 113 + .../terminology/TerminologyService.java | 131 + .../rm/common/archetyped/AddChildTest.java | 40 + .../rm/common/archetyped/ArchetypedTest.java | 126 + .../archetyped/FeederAuditDetailsTest.java | 129 + .../rm/common/archetyped/LocatableTest.java | 282 ++ .../common/archetyped/PathBasedQueryTest.java | 115 + .../archetyped/PathBasedValueSettingTest.java | 161 + .../rm/common/archetyped/PathUtilTest.java | 33 + .../rm/common/archetyped/RemoveChildTest.java | 77 + .../changecontrol/ChangeControlTestBase.java | 155 + .../changecontrol/ImportedVersionTest.java | 102 + .../changecontrol/OriginalVersionTest.java | 106 + .../changecontrol/VersionedObjectTest.java | 333 ++ .../rm/common/directory/FolderTest.java | 90 + .../generic/AuditDetailsCreateTest.java | 34 + .../common/generic/PartyIdentifiedTest.java | 89 + .../common/generic/RevisionHistoryTest.java | 121 + .../common/resource/AuthoredResourceTest.java | 136 + .../resource/ResourceDescriptionTest.java | 134 + .../rm/common/resource/ResourceTestBase.java | 113 + .../datastructure/DataStructureTestBase.java | 154 + .../rm/datastructure/history/HistoryTest.java | 319 ++ .../history/IntervalEventTest.java | 116 + .../datastructure/history/PointEventTest.java | 122 + .../itemstructure/ItemListTest.java | 134 + .../itemstructure/ItemSingleTest.java | 165 + .../itemstructure/ItemTableTest.java | 337 ++ .../itemstructure/ItemTreeTest.java | 227 ++ .../CreateEmptyElementTest.java | 21 + .../rm/datatypes/basic/DvBooleanTest.java | 85 + .../rm/datatypes/basic/DvStateTest.java | 98 + .../datatypes/basic/ParseDataValueTest.java | 93 + .../encapsulated/DvMultimediaTest.java | 30 + .../rm/datatypes/quantity/DvCountTest.java | 122 + .../rm/datatypes/quantity/DvOrderedTest.java | 146 + .../rm/datatypes/quantity/DvOrdinalTest.java | 44 + .../datatypes/quantity/DvProportionTest.java | 146 + .../rm/datatypes/quantity/DvQuantityTest.java | 166 + .../quantity/ProportionKindTest.java | 78 + .../quantity/datetime/DvDateTest.java | 205 + .../datetime/DvDateTimeParserTest.java | 426 +++ .../DvDateTimeParserTimeZoneTest.java | 30 + .../quantity/datetime/DvDateTimeTest.java | 154 + .../quantity/datetime/DvDurationTest.java | 287 ++ .../quantity/datetime/DvTimeTest.java | 304 ++ .../rm/datatypes/text/DvCodedTextTest.java | 45 + .../openehr/rm/datatypes/text/DvTextTest.java | 110 + .../rm/datatypes/text/TestCodePhrase.java | 65 + .../rm/support/basic/IntervalTest.java | 160 + .../identification/ArchetypeIDTest.java | 254 ++ .../identification/HierObjectIDTest.java | 115 + .../support/identification/ISO_OIDTest.java | 83 + .../identification/InternetIDTest.java | 101 + .../support/identification/ObjectRefTest.java | 115 + .../identification/ObjectVersionIDTest.java | 81 + .../identification/TerminologyIDTest.java | 106 + .../identification/TestTerminologyID.java | 68 + .../rm/support/identification/UUIDTest.java | 37 + .../identification/VersionTreeIDTest.java | 185 + .../measurement/TestMeasurementService.java | 100 + .../OpenEHRCodeSetIdentifiersTest.java | 18 + ...penEHRTerminologyGroupIdentifiersTest.java | 19 + .../terminology/TestCodeSetAccess.java | 130 + .../terminology/TestTerminologyAccess.java | 184 + .../terminology/TestTerminologyService.java | 136 + openehr-rm-domain/pom.xml | 46 + .../openehr/rm/composition/Composition.java | 314 ++ .../openehr/rm/composition/EventContext.java | 297 ++ .../rm/composition/content/ContentItem.java | 85 + .../rm/composition/content/entry/Action.java | 228 ++ .../composition/content/entry/Activity.java | 191 + .../composition/content/entry/AdminEntry.java | 161 + .../composition/content/entry/CareEntry.java | 139 + .../rm/composition/content/entry/Entry.java | 255 ++ .../composition/content/entry/Evaluation.java | 176 + .../content/entry/ISMTransition.java | 153 + .../content/entry/Instruction.java | 261 ++ .../content/entry/InstructionDetails.java | 140 + .../content/entry/Observation.java | 222 ++ .../content/navigation/Section.java | 167 + .../org/openehr/rm/demographic/Actor.java | 228 ++ .../org/openehr/rm/demographic/Address.java | 201 + .../org/openehr/rm/demographic/Agent.java | 114 + .../openehr/rm/demographic/Capability.java | 210 + .../org/openehr/rm/demographic/Contact.java | 211 + .../org/openehr/rm/demographic/Group.java | 109 + .../openehr/rm/demographic/Organisation.java | 114 + .../org/openehr/rm/demographic/Party.java | 266 ++ .../openehr/rm/demographic/PartyIdentity.java | 200 + .../rm/demographic/PartyRelationship.java | 245 ++ .../org/openehr/rm/demographic/Person.java | 114 + .../java/org/openehr/rm/demographic/Role.java | 196 + .../rm/demographic/VersionedParty.java | 111 + .../src/main/java/org/openehr/rm/ehr/EHR.java | 245 ++ .../java/org/openehr/rm/ehr/EHRAccess.java | 164 + .../java/org/openehr/rm/ehr/EHRStatus.java | 206 + .../openehr/rm/ehr/VersionedComposition.java | 172 + .../openehr/rm/ehr/VersionedEHRAccess.java | 108 + .../openehr/rm/ehr/VersionedEHRStatus.java | 109 + .../org/openehr/rm/ehrextract/EHRExtract.java | 153 + .../openehr/rm/ehrextract/XAccessControl.java | 105 + .../openehr/rm/ehrextract/XComposition.java | 114 + .../openehr/rm/ehrextract/XDemographics.java | 104 + .../org/openehr/rm/ehrextract/XFolder.java | 155 + .../openehr/rm/ehrextract/XTerminology.java | 78 + .../openehr/rm/integration/GenericEntry.java | 150 + .../java/org/openehr/rm/message/Message.java | 255 ++ .../openehr/rm/message/MessageContent.java | 62 + .../rm/composition/CompositionTest.java | 258 ++ .../rm/composition/CompositionTestBase.java | 162 + .../rm/composition/EventContextTest.java | 74 + .../composition/content/entry/ActionTest.java | 131 + .../content/entry/ActivityTest.java | 90 + .../content/entry/AdminEntryTest.java | 172 + .../content/entry/EvaluationTest.java | 95 + .../content/entry/ISMTransitionTest.java | 49 + .../content/entry/InstructionTest.java | 65 + .../content/entry/ObservationTest.java | 231 ++ .../content/navigation/SectionTest.java | 93 + .../datastructure/DataStructureTestBase.java | 147 + .../datastructure/DataStructureTestBase2.java | 147 + .../openehr/rm/demographic/AddressTest.java | 82 + .../rm/demographic/CapabilityTest.java | 87 + .../openehr/rm/demographic/ContactTest.java | 91 + .../rm/demographic/DemographicTestBase.java | 294 ++ .../rm/demographic/PartyIdentityTest.java | 76 + .../rm/demographic/PartyRelationshipTest.java | 104 + .../org/openehr/rm/demographic/PartyTest.java | 128 + .../openehr/rm/demographic/PersonTest.java | 155 + .../rm/demographic/VersionedPartyTest.java | 167 + .../org/openehr/rm/ehr/EHRStatusTest.java | 92 + .../rm/ehr/VersionedCompositionTest.java | 191 + .../integration/GenericEntryCreationTest.java | 69 + .../rm/integration/GenericEntryPathTest.java | 152 + .../measurement/TestMeasurementService.java | 100 + .../terminology/TestCodeSetAccess.java | 134 + .../terminology/TestTerminologyAccess.java | 212 + .../terminology/TestTerminologyService.java | 135 + pom.xml | 82 + rm-builder/pom.xml | 60 + .../build/AttributeFormatException.java | 60 + .../build/AttributeMissingException.java | 61 + .../java/org/openehr/build/ErrorType.java | 56 + .../org/openehr/build/RMObjectBuilder.java | 711 ++++ .../build/RMObjectBuildingException.java | 71 + .../java/org/openehr/build/SystemValue.java | 107 + .../src/main/resources/log4j.properties | 9 + .../org/openehr/build/BuildDvCountTest.java | 82 + .../java/org/openehr/build/BuildTestBase.java | 205 + .../openehr/build/CommonSupportBuildTest.java | 65 + .../openehr/build/CreateDvMultimediaTest.java | 48 + .../build/DataStructuresBuildTest.java | 276 ++ .../org/openehr/build/DataTypesBuildTest.java | 324 ++ .../openehr/build/DemographicBuildTest.java | 264 ++ .../java/org/openehr/build/EHRBuildTest.java | 347 ++ .../build/FindMatchingRMClassTest.java | 203 + rm-skeleton/hypersensitivity_drug.dadl | 136 + rm-skeleton/hypersensitivity_drug_sulfa.dadl | 157 + rm-skeleton/hypersensitivity_food_milk.dadl | 118 + rm-skeleton/hypersensitivity_max.dadl | 136 + rm-skeleton/hypersensitivity_maximum.dadl | 136 + rm-skeleton/hypersensitivity_min.dadl | 136 + rm-skeleton/pom.xml | 94 + .../openehr/rm/util/GenerationStrategy.java | 58 + .../main/java/org/openehr/rm/util/RMUtil.java | 236 ++ .../openehr/rm/util/SkeletonGenerator.java | 939 +++++ .../org/openehr/rm/util/CodedTextTest.java | 63 + .../rm/util/GenerateHypersensitivityTest.java | 33 + .../rm/util/GenerateNestedSectionsTest.java | 25 + .../java/org/openehr/rm/util/OrdinalTest.java | 42 + .../java/org/openehr/rm/util/RMUtilTest.java | 34 + .../org/openehr/rm/util/RootNodeNameTest.java | 18 + .../rm/util/SimpleDvMultimediaTest.java | 31 + .../rm/util/SkeletonGeneratorTestBase.java | 178 + .../org/openehr/rm/util/TemplateIdTest.java | 27 + .../java/org/openehr/rm/util/TestActions.java | 15 + .../java/org/openehr/rm/util/TestEvents.java | 25 + .../rm/util/TestFlattenedTemplate.java | 36 + .../rm/util/TestItemTreeGeneration.java | 42 + .../org/openehr/rm/util/TestObservations.java | 38 + .../org/openehr/rm/util/TestStrategy.java | 47 + .../java/org/openehr/rm/util/UtilityTest.java | 27 + .../adl/openEHR-EHR-ACTION.medication.v1.adl | 319 ++ ...EHR-EHR-EVALUATION.hypersensitivity.v1.adl | 184 + .../openEHR-EHR-INSTRUCTION.medication.v1.adl | 90 + ...penEHR-EHR-ITEM_TREE.blood_pressure.v1.adl | 63 + .../openEHR-EHR-ITEM_TREE.medication.v1.adl | 921 +++++ ...EHR-ITEM_TREE.medication_test_eight.v1.adl | 38 + ...-EHR-ITEM_TREE.medication_test_five.v1.adl | 36 + ...-EHR-ITEM_TREE.medication_test_four.v1.adl | 54 + ...-EHR-ITEM_TREE.medication_test_nine.v1.adl | 50 + ...R-EHR-ITEM_TREE.medication_test_one.v1.adl | 36 + ...EHR-ITEM_TREE.medication_test_seven.v1.adl | 50 + ...R-EHR-ITEM_TREE.medication_test_six.v1.adl | 36 + ...EHR-ITEM_TREE.medication_test_three.v1.adl | 40 + ...R-EHR-ITEM_TREE.medication_test_two.v1.adl | 44 + .../adl/openEHR-EHR-OBSERVATION.apgar.v1.adl | 1422 +++++++ ...nEHR-EHR-OBSERVATION.blood_pressure.v2.adl | 1254 ++++++ ...openEHR-EHR-OBSERVATION.body_weight.v2.adl | 268 ++ .../openEHR-EHR-OBSERVATION.heart_rate.v2.adl | 393 ++ .../adl/openEHR-EHR-OBSERVATION.height.v2.adl | 252 ++ .../openEHR-EHR-OBSERVATION.lab_test.v1.adl | 376 ++ .../openEHR-EHR-OBSERVATION.waist_hip.v2.adl | 129 + .../openEHR-EHR-SECTION.ad_hoc_heading.v1.adl | 40 + .../openEHR-EHR-SECTION.medications.v1.adl | 52 + .../dadl/item_tree_blood_pressure_1.dadl | 28 + .../dadl/item_tree_medicataion_1.dadl | 17 + .../dadl/item_tree_medicataion_10.dadl | 26 + .../dadl/item_tree_medicataion_11.dadl | 23 + .../dadl/item_tree_medicataion_12.dadl | 38 + .../dadl/item_tree_medicataion_2.dadl | 23 + .../dadl/item_tree_medicataion_3.dadl | 23 + .../dadl/item_tree_medicataion_4.dadl | 17 + .../dadl/item_tree_medicataion_5.dadl | 26 + .../dadl/item_tree_medicataion_6.dadl | 17 + .../dadl/item_tree_medicataion_7.dadl | 20 + .../dadl/item_tree_medicataion_8.dadl | 23 + .../dadl/item_tree_medicataion_9.dadl | 26 + .../src/test/resources/log4j.properties | 13 + ...nested_sections_with_optional_children.oet | 12 + .../oet/test_section_instruction_tree.oet | 10 + .../src/test/resources/oet/test_text_name.oet | 8 + rm-skeleton/src/test/resources/terms.txt | 3 + rm-skeleton/src/test/resources/xml/purged.xml | 110 + .../src/test/resources/xml/to_purge.xml | 271 ++ xml-binding/pom.xml | 128 + .../src/main/groovy/load-observation.groovy | 12 + .../java/org/openehr/binding/RMInspector.java | 523 +++ .../java/org/openehr/binding/XMLBinding.java | 509 +++ .../openehr/binding/XMLBindingException.java | 48 + xml-binding/src/main/xsd/Archetype.xsd | 394 ++ xml-binding/src/main/xsd/BaseTypes.xsd | 594 +++ xml-binding/src/main/xsd/Composition.xsd | 36 + xml-binding/src/main/xsd/Content.xsd | 132 + xml-binding/src/main/xsd/Extract.xsd | 140 + xml-binding/src/main/xsd/OpenehrProfile.xsd | 94 + xml-binding/src/main/xsd/Resource.xsd | 63 + xml-binding/src/main/xsd/Structure.xsd | 151 + xml-binding/src/main/xsd/Version.xsd | 41 + .../openehr/binding/BindDataTypesTest.java | 39 + .../binding/BindEmptyItemTreeTest.java | 27 + .../BindItemTreeWithDvProportionTest.java | 32 + .../binding/BindStructureToXMLTest.java | 196 + .../openehr/binding/CreateXMLObjectTest.java | 176 + .../org/openehr/binding/RMBindingTest.java | 117 + .../binding/VersionedDocumentTest.java | 12 + .../openehr/binding/XMLBindingTestBase.java | 30 + .../org/openehr/binding/XMLParsingTest.java | 145 + .../test/resources/composition-discharge.xml | 185 + .../resources/composition-prescription.xml | 313 ++ .../src/test/resources/composition.xml | 162 + .../src/test/resources/dv_proportion.xml | 7 + .../src/test/resources/empty_item_tree.xml | 8 + xml-binding/src/test/resources/item_tree.xml | 17 + .../src/test/resources/item_tree_002.xml | 56 + .../src/test/resources/item_tree_003.xml | 18 + .../src/test/resources/log4j.properties | 9 + .../test/resources/original_version_001.xml | 192 + .../test/resources/original_version_002.xml | 201 + .../src/test/resources/simple_composition.xml | 122 + xml-serializer/pom.xml | 66 + xml-serializer/readme.txt | 1 + .../openehr/am/serialize/XMLSerializer.java | 1091 ++++++ 1020 files changed, 118960 insertions(+) create mode 100644 INSTALL.txt create mode 100644 LICENSE.txt create mode 100644 README.txt create mode 100644 adl-parser/docs/changes.txt create mode 100644 adl-parser/pom.xml create mode 100644 adl-parser/readme.txt create mode 100644 adl-parser/src/main/java/se/acode/openehr/parser/ArchetypeValidator.java create mode 100644 adl-parser/src/main/java/se/acode/openehr/parser/AttributeValue.java create mode 100644 adl-parser/src/main/java/se/acode/openehr/parser/ContentObject.java create mode 100644 adl-parser/src/main/java/se/acode/openehr/parser/Invariant.java create mode 100644 adl-parser/src/main/java/se/acode/openehr/parser/Parsed.java create mode 100644 adl-parser/src/main/javacc/adl.jj create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeDescriptionTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeIdentificationTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeInternalRefTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeLanguageTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeOntologyTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeSlotTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeUncommonTermKeysTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeValidatorTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/BasicGenericTypeTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/BasicTypesTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/CCodePhraseTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/CDurationTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/CDvOrdinalTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/CDvQuantityTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/ConstraintBindingTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/ConstraintRefTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/DateTimeTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/DvCodedTextTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/EmptyOtherContributorsTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/MissingLanguageTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/MissingPurposeTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/MixedNodeTypesTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/MostMinimalADLTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/MultiLanguageTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/ParserTestBase.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/PathTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/RegularExpressionTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/SpecialStringTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/StructureTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/TermBindingTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/UnicodeBOMSupportTest.java create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/UnicodeSupportTest.java create mode 100644 adl-parser/src/test/resources/adl-test-SOME_TYPE.generic_type_basic.draft.adl create mode 100644 adl-parser/src/test/resources/adl-test-SOME_TYPE.generic_type_use_node.draft.adl create mode 100644 adl-parser/src/test/resources/adl-test-car.paths.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-car.use_node.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-composition.dv_coded_text.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.archetype_bindings.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.archetype_desc_missing_purpose.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.archetype_description.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.archetype_description2.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.archetype_identification.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.archetype_internal_ref.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.archetype_internal_ref2.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.archetype_language.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.archetype_language_no_accreditation.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.archetype_language_order_of_translation_details.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.archetype_ontology.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.archetype_slot.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.archetype_slot.test2.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.archetype_uncommonkeys.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.basic_types.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.c_code_phrase.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.c_dv_ordinal.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_empty.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_full.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_full2.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_full3.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_item_units_only.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_list.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_property.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_reversed.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.constraint_binding.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.constraint_ref.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.datetime.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.domain_types.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.durations.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.empty_other_contributors.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.missing_language.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.mixed_node_types.draft.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.most_minimal.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.multi_language.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.regular_expression.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.special_string.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.structure_test1.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.structure_test2.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.term_binding.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.term_binding2.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.testtranslations.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.translations_author_language.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.translations_language_author.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.unicode_BOM_support.test.adl create mode 100644 adl-parser/src/test/resources/adl-test-entry.unicode_support.test.adl create mode 100644 adl-parser/src/test/resources/openEHR-EHR-CLUSTER.auscultation.v1.adl create mode 100644 adl-parser/src/test/resources/openEHR-EHR-ELEMENT.uid_test.v1.adl create mode 100644 adl-parser/src/test/resources/openEHR-EHR-ELEMENT.uid_test.v2.adl create mode 100644 adl-parser/src/test/resources/openEHR-EHR-EVALUATION.columna_vertebral.v1.adl create mode 100644 adl-parser/src/test/resources/openEHR-EHR-OBSERVATION.test_internal_ref_binding.v1.adl create mode 100644 adl-parser/src/test/resources/openEHR-EHR-OBSERVATION.testassumedvalue.v1.adl create mode 100644 adl-serializer/docs/changes.txt create mode 100644 adl-serializer/pom.xml create mode 100644 adl-serializer/readme.txt create mode 100644 adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java create mode 100644 adl-serializer/src/test/adl/adl-test-entry.most_minimal.test.adl create mode 100644 adl-serializer/src/test/adl/archetype-internal-ref-test.adl create mode 100644 adl-serializer/src/test/adl/archetype-language.adl create mode 100644 adl-serializer/src/test/adl/archetype-slot-any-allowed-test.adl create mode 100644 adl-serializer/src/test/adl/archetype-slot-empty-excludes-test.adl create mode 100644 adl-serializer/src/test/adl/archetype-slot-empty-includes-test.adl create mode 100644 adl-serializer/src/test/adl/archetype-slot-test.adl create mode 100644 adl-serializer/src/test/adl/c-code-phrase-test-empty.adl create mode 100644 adl-serializer/src/test/adl/c-code-phrase-test.adl create mode 100644 adl-serializer/src/test/adl/c-dv-ordinal-test-empty.adl create mode 100644 adl-serializer/src/test/adl/c-dv-ordinal-test.adl create mode 100644 adl-serializer/src/test/adl/c-dv-ordinal-test2.adl create mode 100644 adl-serializer/src/test/adl/c-dv-quantity-test-empty.adl create mode 100644 adl-serializer/src/test/adl/c-dv-quantity-test.adl create mode 100644 adl-serializer/src/test/adl/c-string-test.adl create mode 100644 adl-serializer/src/test/adl/empty-attribute-list-test.adl create mode 100644 adl-serializer/src/test/adl/empty-children-list-test.adl create mode 100644 adl-serializer/src/test/adl/multi-language.adl create mode 100644 adl-serializer/src/test/adl/multi-terminology.adl create mode 100644 adl-serializer/src/test/adl/ontology.adl create mode 100644 adl-serializer/src/test/adl/openEHR-EHR-EVALUATION.test_concept.v1.adl create mode 100644 adl-serializer/src/test/java/org/openehr/am/serialize/ArchetypeInternalRefTest.java create mode 100644 adl-serializer/src/test/java/org/openehr/am/serialize/ArchetypeLanguageTest.java create mode 100644 adl-serializer/src/test/java/org/openehr/am/serialize/ArchetypeSlotTest.java create mode 100644 adl-serializer/src/test/java/org/openehr/am/serialize/CCodePhraseTest.java create mode 100644 adl-serializer/src/test/java/org/openehr/am/serialize/CDurationTest.java create mode 100644 adl-serializer/src/test/java/org/openehr/am/serialize/CDvOrdinalTest.java create mode 100644 adl-serializer/src/test/java/org/openehr/am/serialize/CDvQuantityTest.java create mode 100644 adl-serializer/src/test/java/org/openehr/am/serialize/CommonTest.java create mode 100644 adl-serializer/src/test/java/org/openehr/am/serialize/DescriptionTest.java create mode 100644 adl-serializer/src/test/java/org/openehr/am/serialize/EmptyAttributeListTest.java create mode 100644 adl-serializer/src/test/java/org/openehr/am/serialize/MultipleLanguageTest.java create mode 100644 adl-serializer/src/test/java/org/openehr/am/serialize/MultipleTerminologyTest.java create mode 100644 adl-serializer/src/test/java/org/openehr/am/serialize/OntologyTest.java create mode 100644 adl-serializer/src/test/java/org/openehr/am/serialize/PrimitiveTypesTest.java create mode 100644 adl-serializer/src/test/java/org/openehr/am/serialize/RoundTripTest.java create mode 100644 adl-serializer/src/test/java/org/openehr/am/serialize/SerializerTestBase.java create mode 100644 adl-serializer/src/test/java/org/openehr/am/serialize/SimpleArchetypeTest.java create mode 100644 archetype-validator/pom.xml create mode 100644 archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java create mode 100644 archetype-validator/src/main/java/org/openehr/am/validation/ErrorType.java create mode 100644 archetype-validator/src/main/java/org/openehr/am/validation/RMInspectionException.java create mode 100644 archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java create mode 100644 archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java create mode 100644 archetype-validator/src/main/java/org/openehr/am/validation/UTF8Control.java create mode 100644 archetype-validator/src/main/java/org/openehr/am/validation/ValidationError.java create mode 100644 archetype-validator/src/main/resources/log4j.properties create mode 100644 archetype-validator/src/main/resources/validations.properties create mode 100644 archetype-validator/src/main/resources/validations.txt create mode 100644 archetype-validator/src/main/resources/validations_de.properties create mode 100644 archetype-validator/src/main/resources/validations_en.properties create mode 100644 archetype-validator/src/main/resources/validations_ru.properties create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeDefinitionCodeCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeInternalRefCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeSlotCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeTermValidityTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeValidationTestBase.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/AssumedValueTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/AttributeNameCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/CodeConstraintValidityTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/DefinitionTypenameCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/DvQuantityUnitsTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/MultiValueAttributeChildIdentifierCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/MultipleValueAttributeCardinalityTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/OntologyCodeSpecialisationCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/OntologyTranslationCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/RMInspectorTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SingleValueAttributeChildIdentifierCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SingleValueAttributeChildOccurrencesCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SingleValueAttributeChildUniquenessCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeCardinalityTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeExistenceTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeMultiplicityTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeNodeIdConformanceTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeNodeSpecialisedAsRequiredTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeNonCComplexObjectTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeOccurrencesTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeTermExistsTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeValidationTestBase.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecialisedArchetypeWrongRMTypeTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecializationArchetypeIdTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SpecializationDepthCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/TermBindingsValidityTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/TypeNameCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/UniqueSiblingAttributesCheckTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ValidateOpenEHRTerminologyCodesTest.java create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/ValidatorUtilityTest.java create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.cardinality-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.cardinality-specialised.v2 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.cardinality.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.existence-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.existence.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.multiplicity-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.multiplicity.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_id_conformance-specialised-again.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_id_conformance-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_specialised_as_required-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.node_specialised_as_required.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.occurrences-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.occurrences.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence-specialised.v2 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.term_existence.v2 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype-specialised.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype-specialised.v2 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype-specialised.v3 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype.v1 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype.v2 create mode 100644 archetype-validator/src/test/resources/adl-specialised-EVALUATION.wrongrmtype.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.assumed_value_boolean.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.assumed_value_count.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.assumed_value_quantity.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-archetypeid.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-archetypeid.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-archetypeid.v3.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v3.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v4.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization-depth.v5.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.specialization.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_boolean.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_count.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_date.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_date.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_datetime.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_duration.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_ehr_uri.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v3.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v4.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v5.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_interval.v6.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_multimedia.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_multimedia.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_name.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_name.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_name.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_proportion.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ELEMENT.type_uri.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.attribute_name.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.attribute_name.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.attribute_name.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.code_constraint.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.code_constraint.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.code_constraint.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.definition_code.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.definition_code.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.definition_typename.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.definition_typename.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.definition_typename.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v3.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v4.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-specialisation.v5.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-unusedcodes.v1.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology-unusedcodes.v2.adl create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v4 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v5 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v6 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v7 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.sibling_nodes.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.sibling_nodes.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_identifier.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_identifier.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_occurrences.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_occurrences.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_occurrences.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_uniqueness.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_uniqueness.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.single_attribute_child_uniqueness.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_bindings.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_bindings.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v4 create mode 100644 archetype-validator/src/test/resources/adl-test-ITEM_TREE.attribute_cardinality.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ITEM_TREE.attribute_cardinality.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ITEM_TREE.attribute_cardinality.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-ITEM_TREE.multi_attribute_child_identifier.v1 create mode 100644 archetype-validator/src/test/resources/adl-test-ITEM_TREE.multi_attribute_child_identifier.v2 create mode 100644 archetype-validator/src/test/resources/adl-test-ITEM_TREE.multi_attribute_child_identifier.v3 create mode 100644 archetype-validator/src/test/resources/adl-test-PARTY_PROXY.type_name.v1 create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-ACTION.follow_up.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.cardinality_occurrences.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.cardinality_occurrences2.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.cardinality_occurrences3.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.internal_reference.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.testNonUniqueInternalRef.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.testNonUniqueInternalRef.v2.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.test_non_ccomplexobject-spec.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.test_non_ccomplexobject.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-CLUSTER.units_test.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-ELEMENT.doubleontologycode.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.adverse.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.null_flavor.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.null_flavour.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-EVALUATION.problem-diagnosis.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v2.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v3.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v4.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v5.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.internal_reference.v6.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.order1-order2-order3.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.order1-order2-order3a.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.order1-order2.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v1.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v2.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.type_name.v4.adl create mode 100644 dadl-binding/pom.xml create mode 100644 dadl-binding/src/main/java/org/openehr/rm/binding/DADLBinding.java create mode 100644 dadl-binding/src/main/java/org/openehr/rm/binding/DADLBindingException.java create mode 100644 dadl-binding/src/main/java/org/openehr/rm/binding/RMInspector.java create mode 100644 dadl-binding/src/main/java/org/openehr/rm/binding/XPathUtil.java create mode 100644 dadl-binding/src/test/java/org/openehr/rm/binding/BindRMToDADLTest.java create mode 100644 dadl-binding/src/test/java/org/openehr/rm/binding/DADLBindingTest.java create mode 100644 dadl-binding/src/test/java/org/openehr/rm/binding/DADLBindingTestBase.java create mode 100644 dadl-binding/src/test/java/org/openehr/rm/binding/DuplicatedCodesTest.java create mode 100644 dadl-binding/src/test/java/org/openehr/rm/binding/LoadTest.java create mode 100644 dadl-binding/src/test/java/org/openehr/rm/binding/XPathTest.java create mode 100644 dadl-binding/src/test/resources/adl-test-CLUSTER.test_cluster.v1.adl create mode 100644 dadl-binding/src/test/resources/adl-test-ITEM_TREE.test_tree.v1.adl create mode 100644 dadl-binding/src/test/resources/archetyped.dadl create mode 100644 dadl-binding/src/test/resources/body_weight.dadl create mode 100644 dadl-binding/src/test/resources/code_phrase.dadl create mode 100644 dadl-binding/src/test/resources/demographics.dadl create mode 100644 dadl-binding/src/test/resources/duplicated_codes.dadl create mode 100644 dadl-binding/src/test/resources/dv_coded_text.dadl create mode 100644 dadl-binding/src/test/resources/dv_quantity.dadl create mode 100644 dadl-binding/src/test/resources/dv_text.dadl create mode 100644 dadl-binding/src/test/resources/element.dadl create mode 100644 dadl-binding/src/test/resources/element_with_text.dadl create mode 100644 dadl-binding/src/test/resources/empty_element_with_null_flavour.dadl create mode 100644 dadl-binding/src/test/resources/empty_item_list.dadl create mode 100644 dadl-binding/src/test/resources/history.dadl create mode 100644 dadl-binding/src/test/resources/history2.dadl create mode 100644 dadl-binding/src/test/resources/item_list.dadl create mode 100644 dadl-binding/src/test/resources/item_tree_bp.dadl create mode 100644 dadl-binding/src/test/resources/item_tree_bp2.dadl create mode 100644 dadl-binding/src/test/resources/lab_test.dadl create mode 100644 dadl-binding/src/test/resources/log4j.properties create mode 100644 dadl-binding/src/test/resources/observation.dadl create mode 100644 dadl-binding/src/test/resources/observation2.dadl create mode 100644 dadl-binding/src/test/resources/observation3.dadl create mode 100644 dadl-binding/src/test/resources/order_set1.dadl create mode 100644 dadl-binding/src/test/resources/point_event.dadl create mode 100644 dadl-binding/src/test/resources/point_event2.dadl create mode 100644 dadl-binding/src/test/resources/tree_2_slots.dadl create mode 100644 dadl-binding/src/test/resources/tree_nested_slot.dadl create mode 100644 dadl-binding/src/test/resources/tree_nested_slot2.dadl create mode 100644 dadl-binding/src/test/resources/tree_nested_slot3.dadl create mode 100644 dadl-binding/src/test/resources/tree_nested_slot4.dadl create mode 100644 dadl-binding/src/test/resources/tree_slot.dadl create mode 100644 dadl-binding/src/test/resources/typed_archetype_id.dadl create mode 100644 dadl-binding/src/test/resources/typed_dv_boolean.dadl create mode 100644 dadl-binding/src/test/resources/typed_dv_ordinal.dadl create mode 100644 dadl-binding/src/test/resources/typed_dv_quantity.dadl create mode 100644 dadl-binding/src/test/resources/typed_dv_quantity2.dadl create mode 100644 dadl-binding/src/test/resources/typed_dv_text.dadl create mode 100644 dadl-binding/src/test/resources/typed_party_self.dadl create mode 100644 dadl-binding/src/test/resources/typed_terminology_id.dadl create mode 100644 dadl-binding/src/test/resources/weight.dadl create mode 100644 dadl-binding/tree_2_slots.dadl create mode 100644 dadl-parser/pom.xml create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/AttributeValue.java create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/BooleanValue.java create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/CharacterValue.java create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/CodeValue.java create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/ComplexObjectBlock.java create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/ContentObject.java create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/DateTimeValue.java create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/DateValue.java create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/DurationValue.java create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/IntegerValue.java create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/KeyedObject.java create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/MultipleAttributeObjectBlock.java create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/ObjectBlock.java create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/Parsed.java create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/PrimitiveObjectBlock.java create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/RealValue.java create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/SimpleValue.java create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/SingleAttributeObjectBlock.java create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/StringValue.java create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/TimeValue.java create mode 100644 dadl-parser/src/main/java/org/openehr/am/parser/UriValue.java create mode 100644 dadl-parser/src/main/javacc/dadl.jj create mode 100644 dadl-parser/src/test/java/org/openehr/am/parser/EmptyAttributeListBlockTest.java create mode 100644 dadl-parser/src/test/java/org/openehr/am/parser/ItemListTest.java create mode 100644 dadl-parser/src/test/java/org/openehr/am/parser/KeyedObjectTest.java create mode 100644 dadl-parser/src/test/java/org/openehr/am/parser/ParserTestBase.java create mode 100644 dadl-parser/src/test/java/org/openehr/am/parser/SimpleValuesTest.java create mode 100644 dadl-parser/src/test/java/org/openehr/am/parser/SingleValueListTest.java create mode 100644 dadl-parser/src/test/java/org/openehr/am/parser/StructureTest.java create mode 100644 dadl-parser/src/test/java/org/openehr/am/parser/TypedObjectBlockTest.java create mode 100644 dadl-parser/src/test/resources/blood_pressure_001.dadl create mode 100644 dadl-parser/src/test/resources/empty_attr_list.dadl create mode 100644 dadl-parser/src/test/resources/empty_attr_list_without_type.dadl create mode 100644 dadl-parser/src/test/resources/keyed_objects.dadl create mode 100644 dadl-parser/src/test/resources/keyed_objects2.dadl create mode 100644 dadl-parser/src/test/resources/person_001.dadl create mode 100644 dadl-parser/src/test/resources/simple_values.dadl create mode 100644 dadl-parser/src/test/resources/simple_values_list.dadl create mode 100644 dadl-parser/src/test/resources/single_values_list.dadl create mode 100644 dadl-parser/src/test/resources/state_item_list.dadl create mode 100644 dadl-parser/src/test/resources/typed_dv_quantity.dadl create mode 100644 measure-serv/pom.xml create mode 100644 measure-serv/readme.txt create mode 100644 measure-serv/src/main/java/org/openehr/rm/support/measurement/MeasurementService.java create mode 100644 measure-serv/src/main/java/org/openehr/rm/support/measurement/SimpleMeasurementService.java create mode 100644 measure-serv/src/test/java/org/openehr/rm/support/measurement/SimpleMeasurementServiceTest.java create mode 100644 mini-termserv/pom.xml create mode 100644 mini-termserv/src/main/java/org/openehr/terminology/CodeSet.java create mode 100644 mini-termserv/src/main/java/org/openehr/terminology/Concept.java create mode 100644 mini-termserv/src/main/java/org/openehr/terminology/Group.java create mode 100644 mini-termserv/src/main/java/org/openehr/terminology/SimpleCodeSetAccess.java create mode 100644 mini-termserv/src/main/java/org/openehr/terminology/SimpleTerminologyAccess.java create mode 100644 mini-termserv/src/main/java/org/openehr/terminology/SimpleTerminologyService.java create mode 100644 mini-termserv/src/main/java/org/openehr/terminology/TerminologySource.java create mode 100644 mini-termserv/src/main/java/org/openehr/terminology/TerminologySourceFactory.java create mode 100644 mini-termserv/src/main/java/org/openehr/terminology/XMLTerminologySource.java create mode 100644 mini-termserv/src/main/resources/external_terminologies_en.xml create mode 100644 mini-termserv/src/main/resources/log4j.properties create mode 100644 mini-termserv/src/main/resources/openehr_terminology_en.xml create mode 100644 mini-termserv/src/test/java/org/openehr/terminology/OpenEHRTerminologyTest.java create mode 100644 mini-termserv/src/test/java/org/openehr/terminology/SimpleCodeSetAccessTest.java create mode 100644 mini-termserv/src/test/java/org/openehr/terminology/SimpleTerminologyAccessTest.java create mode 100644 mini-termserv/src/test/java/org/openehr/terminology/SimpleTerminologyServiceTest.java create mode 100644 mini-termserv/src/test/java/org/openehr/terminology/TranslationDetailsTest.java create mode 100644 oet-parser/pom.xml create mode 100644 oet-parser/src/main/java/org/openehr/am/template/Flattener.java create mode 100644 oet-parser/src/main/java/org/openehr/am/template/FlatteningException.java create mode 100644 oet-parser/src/main/java/org/openehr/am/template/OETParser.java create mode 100644 oet-parser/src/main/java/org/openehr/am/template/PathMap.java create mode 100644 oet-parser/src/main/java/org/openehr/am/template/TermMap.java create mode 100644 oet-parser/src/main/xsd/Archetype.xsd create mode 100644 oet-parser/src/main/xsd/BaseTypes.xsd create mode 100644 oet-parser/src/main/xsd/CharacterMapping.xsd create mode 100644 oet-parser/src/main/xsd/Composition.xsd create mode 100644 oet-parser/src/main/xsd/CompositionTemplate.xsd create mode 100644 oet-parser/src/main/xsd/Content.xsd create mode 100644 oet-parser/src/main/xsd/Extract.xsd create mode 100644 oet-parser/src/main/xsd/OpenehrProfile.xsd create mode 100644 oet-parser/src/main/xsd/Resource.xsd create mode 100644 oet-parser/src/main/xsd/Structure.xsd create mode 100644 oet-parser/src/main/xsd/Template.xsd create mode 100644 oet-parser/src/main/xsd/Version.xsd create mode 100644 oet-parser/src/test/java/org/openehr/am/template/ActionDescriptionTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/AnnotationTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/ArchetypeSlotTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/CompositionTemplateTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/MultipleConstraintTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/PathMapTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/QuantityConstraintTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/SectionEvaluationTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/SectionInstructionTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/SectionTemplateTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/SetCardinalityConstraintsTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/SetConstraintOnNamedNodeWithoutNameTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/SetMaxOccurrencesWithoutMinTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/SetMixedConstraintsTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/SetMultipleEvaluationNameTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/SetNestedEvaluationNameTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/SetNodeNameTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/SetNodeOccurrencesTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/SetOccurrencesAndNameTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/TemplateParseTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/TemplateTestBase.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/TermMapTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/TextConstraintTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/UTF8EncodingTest.java create mode 100644 oet-parser/src/test/java/org/openehr/am/template/UtilityTest.java create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-ACTION.medication.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-ADMIN_ENTRY.heart_failure_contact.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-COMPOSITION.prescription.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-COMPOSITION.prescription_flattened.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-COMPOSITION.test.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-EVALUATION.adjusted_node_ids.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-EVALUATION.hybrid_path_test.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-EVALUATION.medication_review.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-EVALUATION.review_of_procedures.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-EVALUATION.structured_summary.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-INSTRUCTION.medication.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_mod.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_multiple_constraint_expected.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_multiple_constraint_test.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_multiple_constraint_test2.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_quantity_test.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_quantity_test2.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_one.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_one.v2.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_text_default.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_text_name.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_three.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_two.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-OBSERVATION.heart_failure_stage.v2.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-OBSERVATION.lab_test.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-OBSERVATION.waist_hip.v2.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.ad_hoc_heading.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.find_largest_node_id.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.find_largest_node_id_2.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.medications.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.more_nested_sections.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.nested_sections.v1.adl create mode 100644 oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.simple_section_name.v1.adl create mode 100644 oet-parser/src/test/resources/log4j.properties create mode 100644 oet-parser/src/test/resources/templates/prescription.oet create mode 100644 oet-parser/src/test/resources/templates/test_action_description.oet create mode 100644 oet-parser/src/test/resources/templates/test_annotation.oet create mode 100644 oet-parser/src/test/resources/templates/test_composition.oet create mode 100644 oet-parser/src/test/resources/templates/test_composition2.oet create mode 100644 oet-parser/src/test/resources/templates/test_composition3.oet create mode 100644 oet-parser/src/test/resources/templates/test_composition4.oet create mode 100644 oet-parser/src/test/resources/templates/test_composition5.oet create mode 100644 oet-parser/src/test/resources/templates/test_default_coded_name.oet create mode 100644 oet-parser/src/test/resources/templates/test_default_coded_text.oet create mode 100644 oet-parser/src/test/resources/templates/test_default_text.oet create mode 100644 oet-parser/src/test/resources/templates/test_hybrid_path.oet create mode 100644 oet-parser/src/test/resources/templates/test_max_value.oet create mode 100644 oet-parser/src/test/resources/templates/test_min_value.oet create mode 100644 oet-parser/src/test/resources/templates/test_more_nested_section.oet create mode 100644 oet-parser/src/test/resources/templates/test_multiple_constraint.oet create mode 100644 oet-parser/src/test/resources/templates/test_multiple_constraint2.oet create mode 100644 oet-parser/src/test/resources/templates/test_multiple_constraint3.oet create mode 100644 oet-parser/src/test/resources/templates/test_name_default_coded_text.oet create mode 100644 oet-parser/src/test/resources/templates/test_named_path.oet create mode 100644 oet-parser/src/test/resources/templates/test_named_path2.oet create mode 100644 oet-parser/src/test/resources/templates/test_named_path3.oet create mode 100644 oet-parser/src/test/resources/templates/test_nested_section.oet create mode 100644 oet-parser/src/test/resources/templates/test_nested_section_evaluation.oet create mode 100644 oet-parser/src/test/resources/templates/test_quantity_constraint_excluded_units.oet create mode 100644 oet-parser/src/test/resources/templates/test_quantity_constraint_included_units.oet create mode 100644 oet-parser/src/test/resources/templates/test_quantity_constraint_included_units2.oet create mode 100644 oet-parser/src/test/resources/templates/test_quantity_constraint_included_units3.oet create mode 100644 oet-parser/src/test/resources/templates/test_quantity_constraint_magnitude.oet create mode 100644 oet-parser/src/test/resources/templates/test_quantity_constraint_mixed.oet create mode 100644 oet-parser/src/test/resources/templates/test_quantity_constraint_precision.oet create mode 100644 oet-parser/src/test/resources/templates/test_section_evaluation.oet create mode 100644 oet-parser/src/test/resources/templates/test_section_evaluation2.oet create mode 100644 oet-parser/src/test/resources/templates/test_section_instruction.oet create mode 100644 oet-parser/src/test/resources/templates/test_section_instruction_tree.oet create mode 100644 oet-parser/src/test/resources/templates/test_set_cardinality_with_prohibited_node.oet create mode 100644 oet-parser/src/test/resources/templates/test_set_cardinality_with_prohibited_node2.oet create mode 100644 oet-parser/src/test/resources/templates/test_set_cardinality_with_prohibited_node3.oet create mode 100644 oet-parser/src/test/resources/templates/test_set_evaluation_name.oet create mode 100644 oet-parser/src/test/resources/templates/test_set_evaluation_name_.oet create mode 100644 oet-parser/src/test/resources/templates/test_set_mixed_constraints.oet create mode 100644 oet-parser/src/test/resources/templates/test_set_multiple_evaluation_name.oet create mode 100644 oet-parser/src/test/resources/templates/test_set_named_node_constraint_without_name.oet create mode 100644 oet-parser/src/test/resources/templates/test_set_occurrences_and_name.oet create mode 100644 oet-parser/src/test/resources/templates/test_set_occurrences_without_min.oet create mode 100644 oet-parser/src/test/resources/templates/test_set_occurrences_without_min2.oet create mode 100644 oet-parser/src/test/resources/templates/test_simple_section.oet create mode 100644 oet-parser/src/test/resources/templates/test_text_constraints.oet create mode 100644 oet-parser/src/test/resources/templates/test_text_name.oet create mode 100644 oet-parser/src/test/resources/templates/test_utf8_encoding.oet create mode 100644 oet-parser/src/test/resources/terms.txt create mode 100644 oet-parser/src/test/resources/terms_path.txt create mode 100644 oet-parser/src/test/resources/test_path_map.txt create mode 100644 openehr-aom/docs/changes.txt create mode 100644 openehr-aom/pom.xml create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/Archetype.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/assertion/Assertion.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/assertion/AssertionVariable.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionBinaryOperator.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionItem.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionLeaf.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionOperator.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionUnaryOperator.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/assertion/OperatorKind.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/ArchetypeConstraint.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/ArchetypeInternalRef.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/ArchetypeSlot.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CAttribute.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CComplexObject.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CDefinedObject.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CDomainType.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CMultipleAttribute.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CObject.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CPrimitiveObject.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CReferenceObject.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CSingleAttribute.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/Cardinality.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/ConstraintRef.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CBoolean.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CDate.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CDateTime.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CDuration.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CInteger.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CPrimitive.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CReal.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CString.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CTime.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/ontology/ArchetypeOntology.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/ontology/ArchetypeTerm.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/ontology/ConstraintBinding.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/ontology/DefinitionItem.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/ontology/OntologyBinding.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/ontology/OntologyBindingItem.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/ontology/OntologyDefinitions.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/ontology/Query.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/ontology/QueryBindingItem.java create mode 100644 openehr-aom/src/main/java/org/openehr/am/archetype/ontology/TermBindingItem.java create mode 100644 openehr-aom/src/test/java/org/openehr/am/archetype/ArchetypePathTest.java create mode 100644 openehr-aom/src/test/java/org/openehr/am/archetype/assertion/AssertionTest.java create mode 100644 openehr-aom/src/test/java/org/openehr/am/archetype/assertion/ExpressionToStringTest.java create mode 100644 openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/ArchetypeSlotTest.java create mode 100644 openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/CAttributeTest.java create mode 100644 openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/CObjectTest.java create mode 100644 openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/CPrimitiveObjectTest.java create mode 100644 openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CBooleanTest.java create mode 100644 openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CDateTest.java create mode 100644 openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CDateTimeTest.java create mode 100644 openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CDurationTest.java create mode 100644 openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CIntegerTest.java create mode 100644 openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CRealTest.java create mode 100644 openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CStringTest.java create mode 100644 openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CTimeTest.java create mode 100644 openehr-aom/src/test/java/org/openehr/am/archetype/ontology/ArchetypeOntologyTest.java create mode 100644 openehr-aom/src/test/java/org/openehr/am/archetype/ontology/ArchetypeTermTest.java create mode 100644 openehr-ap/docs/changes.txt create mode 100644 openehr-ap/pom.xml create mode 100644 openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/CDvState.java create mode 100644 openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/NonTerminalState.java create mode 100644 openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/State.java create mode 100644 openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/StateMachine.java create mode 100644 openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/TerminalState.java create mode 100644 openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/Transition.java create mode 100644 openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvOrdinal.java create mode 100644 openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvQuantity.java create mode 100644 openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvQuantityItem.java create mode 100644 openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/Ordinal.java create mode 100644 openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/text/CCodePhrase.java create mode 100644 openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/basic/CDvStateTest.java create mode 100644 openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvOrdinalTest.java create mode 100644 openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvQuantityItemTest.java create mode 100644 openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvQuantityTest.java create mode 100644 openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/OrdinalTest.java create mode 100644 openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/text/CCodePhraseTest.java create mode 100644 openehr-rm-core/pom.xml create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/Attribute.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/FullConstructor.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/RMObject.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Archetyped.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/FeederAudit.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/FeederAuditDetails.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Link.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Locatable.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Pathable.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Settable.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/Contribution.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/ImportedVersion.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/OriginalVersion.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/Version.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/VersionedObject.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/directory/Folder.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/directory/VersionedFolder.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/generic/Attestation.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/generic/AuditDetails.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/generic/Participation.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/generic/PartyIdentified.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/generic/PartyProxy.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/generic/PartyRelated.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/generic/PartySelf.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/generic/RevisionHistory.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/generic/RevisionHistoryItem.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/resource/AuthoredResource.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/resource/ResourceDescription.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/resource/ResourceDescriptionItem.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/common/resource/TranslationDetails.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/DataStructure.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/history/Event.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/history/History.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/history/IntervalEvent.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/history/PointEvent.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemList.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemSingle.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemStructure.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemTable.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemTree.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/representation/Cluster.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/representation/Element.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/representation/Item.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DataValue.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvBoolean.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvIdentifier.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvState.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/ReferenceModelName.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/encapsulated/DvEncapsulated.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/encapsulated/DvMultimedia.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/encapsulated/DvParsable.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvAbsoluteQuantity.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvAmount.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvCount.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvInterval.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvOrdered.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvOrdinal.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvProportion.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvQuantified.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvQuantity.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/ProportionKind.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/ReferenceRange.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDate.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTime.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeParser.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDuration.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvTemporal.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvTime.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/CodePhrase.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvCodedText.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvParagraph.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvText.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/Match.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/TermMapping.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/timespec/DvGeneralTimeSpecification.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/timespec/DvPeriodicTimeSpecification.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/timespec/DvTimeSpecification.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/uri/DvEHRURI.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/uri/DvURI.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/security/AccessControlSettings.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/ExternalEnvironment.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/basic/Interval.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/definition/OpenehrDefinitions.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/identification/AccessGroupRef.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ArchetypeID.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/identification/GenericID.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/identification/HierObjectID.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ISO_OID.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/identification/InternetID.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/identification/LocatableRef.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ObjectID.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ObjectRef.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ObjectVersionID.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/identification/PartyRef.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/identification/TemplateID.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/identification/TerminologyID.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/identification/UID.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/identification/UIDBasedID.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/identification/UUID.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/identification/VersionTreeID.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/CodeSetAccess.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/OpenEHRCodeSetIdentifiers.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/OpenEHRTerminologyGroupIdentifiers.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/TerminologyAccess.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/TerminologyService.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/AddChildTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/ArchetypedTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/FeederAuditDetailsTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/LocatableTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/PathBasedQueryTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/PathBasedValueSettingTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/PathUtilTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/RemoveChildTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/common/changecontrol/ChangeControlTestBase.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/common/changecontrol/ImportedVersionTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/common/changecontrol/OriginalVersionTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/common/changecontrol/VersionedObjectTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/common/directory/FolderTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/common/generic/AuditDetailsCreateTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/common/generic/PartyIdentifiedTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/common/generic/RevisionHistoryTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/common/resource/AuthoredResourceTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/common/resource/ResourceDescriptionTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/common/resource/ResourceTestBase.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datastructure/DataStructureTestBase.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datastructure/history/HistoryTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datastructure/history/IntervalEventTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datastructure/history/PointEventTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemListTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemSingleTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemTableTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemTreeTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/representation/CreateEmptyElementTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/basic/DvBooleanTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/basic/DvStateTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/basic/ParseDataValueTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/encapsulated/DvMultimediaTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvCountTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvOrderedTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvOrdinalTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvProportionTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvQuantityTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/ProportionKindTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeParserTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeParserTimeZoneTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDurationTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvTimeTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/text/DvCodedTextTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/text/DvTextTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/text/TestCodePhrase.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/support/basic/IntervalTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/support/identification/ArchetypeIDTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/support/identification/HierObjectIDTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/support/identification/ISO_OIDTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/support/identification/InternetIDTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/support/identification/ObjectRefTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/support/identification/ObjectVersionIDTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/support/identification/TerminologyIDTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/support/identification/TestTerminologyID.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/support/identification/UUIDTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/support/identification/VersionTreeIDTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/support/measurement/TestMeasurementService.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/OpenEHRCodeSetIdentifiersTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/OpenEHRTerminologyGroupIdentifiersTest.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/TestCodeSetAccess.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/TestTerminologyAccess.java create mode 100644 openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/TestTerminologyService.java create mode 100644 openehr-rm-domain/pom.xml create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/composition/Composition.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/composition/EventContext.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/ContentItem.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Action.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Activity.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/AdminEntry.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/CareEntry.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Entry.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Evaluation.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/ISMTransition.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Instruction.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/InstructionDetails.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Observation.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/navigation/Section.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Actor.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Address.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Agent.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Capability.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Contact.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Group.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Organisation.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Party.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/demographic/PartyIdentity.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/demographic/PartyRelationship.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Person.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Role.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/demographic/VersionedParty.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/ehr/EHR.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/ehr/EHRAccess.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/ehr/EHRStatus.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/ehr/VersionedComposition.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/ehr/VersionedEHRAccess.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/ehr/VersionedEHRStatus.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/EHRExtract.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XAccessControl.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XComposition.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XDemographics.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XFolder.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XTerminology.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/integration/GenericEntry.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/message/Message.java create mode 100644 openehr-rm-domain/src/main/java/org/openehr/rm/message/MessageContent.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/composition/CompositionTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/composition/CompositionTestBase.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/composition/EventContextTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ActionTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ActivityTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/AdminEntryTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/EvaluationTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ISMTransitionTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/InstructionTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ObservationTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/navigation/SectionTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/datastructure/DataStructureTestBase.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/datastructure/DataStructureTestBase2.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/demographic/AddressTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/demographic/CapabilityTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/demographic/ContactTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/demographic/DemographicTestBase.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/demographic/PartyIdentityTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/demographic/PartyRelationshipTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/demographic/PartyTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/demographic/PersonTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/demographic/VersionedPartyTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/ehr/EHRStatusTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/ehr/VersionedCompositionTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/integration/GenericEntryCreationTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/integration/GenericEntryPathTest.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/support/measurement/TestMeasurementService.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/support/terminology/TestCodeSetAccess.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/support/terminology/TestTerminologyAccess.java create mode 100644 openehr-rm-domain/src/test/java/org/openehr/rm/support/terminology/TestTerminologyService.java create mode 100644 pom.xml create mode 100644 rm-builder/pom.xml create mode 100644 rm-builder/src/main/java/org/openehr/build/AttributeFormatException.java create mode 100644 rm-builder/src/main/java/org/openehr/build/AttributeMissingException.java create mode 100644 rm-builder/src/main/java/org/openehr/build/ErrorType.java create mode 100644 rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java create mode 100644 rm-builder/src/main/java/org/openehr/build/RMObjectBuildingException.java create mode 100644 rm-builder/src/main/java/org/openehr/build/SystemValue.java create mode 100644 rm-builder/src/main/resources/log4j.properties create mode 100644 rm-builder/src/test/java/org/openehr/build/BuildDvCountTest.java create mode 100644 rm-builder/src/test/java/org/openehr/build/BuildTestBase.java create mode 100644 rm-builder/src/test/java/org/openehr/build/CommonSupportBuildTest.java create mode 100644 rm-builder/src/test/java/org/openehr/build/CreateDvMultimediaTest.java create mode 100644 rm-builder/src/test/java/org/openehr/build/DataStructuresBuildTest.java create mode 100644 rm-builder/src/test/java/org/openehr/build/DataTypesBuildTest.java create mode 100644 rm-builder/src/test/java/org/openehr/build/DemographicBuildTest.java create mode 100644 rm-builder/src/test/java/org/openehr/build/EHRBuildTest.java create mode 100644 rm-builder/src/test/java/org/openehr/build/FindMatchingRMClassTest.java create mode 100644 rm-skeleton/hypersensitivity_drug.dadl create mode 100644 rm-skeleton/hypersensitivity_drug_sulfa.dadl create mode 100644 rm-skeleton/hypersensitivity_food_milk.dadl create mode 100644 rm-skeleton/hypersensitivity_max.dadl create mode 100644 rm-skeleton/hypersensitivity_maximum.dadl create mode 100644 rm-skeleton/hypersensitivity_min.dadl create mode 100644 rm-skeleton/pom.xml create mode 100644 rm-skeleton/src/main/java/org/openehr/rm/util/GenerationStrategy.java create mode 100644 rm-skeleton/src/main/java/org/openehr/rm/util/RMUtil.java create mode 100644 rm-skeleton/src/main/java/org/openehr/rm/util/SkeletonGenerator.java create mode 100644 rm-skeleton/src/test/java/org/openehr/rm/util/CodedTextTest.java create mode 100644 rm-skeleton/src/test/java/org/openehr/rm/util/GenerateHypersensitivityTest.java create mode 100644 rm-skeleton/src/test/java/org/openehr/rm/util/GenerateNestedSectionsTest.java create mode 100644 rm-skeleton/src/test/java/org/openehr/rm/util/OrdinalTest.java create mode 100644 rm-skeleton/src/test/java/org/openehr/rm/util/RMUtilTest.java create mode 100644 rm-skeleton/src/test/java/org/openehr/rm/util/RootNodeNameTest.java create mode 100644 rm-skeleton/src/test/java/org/openehr/rm/util/SimpleDvMultimediaTest.java create mode 100644 rm-skeleton/src/test/java/org/openehr/rm/util/SkeletonGeneratorTestBase.java create mode 100644 rm-skeleton/src/test/java/org/openehr/rm/util/TemplateIdTest.java create mode 100644 rm-skeleton/src/test/java/org/openehr/rm/util/TestActions.java create mode 100644 rm-skeleton/src/test/java/org/openehr/rm/util/TestEvents.java create mode 100644 rm-skeleton/src/test/java/org/openehr/rm/util/TestFlattenedTemplate.java create mode 100644 rm-skeleton/src/test/java/org/openehr/rm/util/TestItemTreeGeneration.java create mode 100644 rm-skeleton/src/test/java/org/openehr/rm/util/TestObservations.java create mode 100644 rm-skeleton/src/test/java/org/openehr/rm/util/TestStrategy.java create mode 100644 rm-skeleton/src/test/java/org/openehr/rm/util/UtilityTest.java create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-ACTION.medication.v1.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-EVALUATION.hypersensitivity.v1.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-INSTRUCTION.medication.v1.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.blood_pressure.v1.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication.v1.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_eight.v1.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_five.v1.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_four.v1.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_nine.v1.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_one.v1.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_seven.v1.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_six.v1.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_three.v1.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_two.v1.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.apgar.v1.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.blood_pressure.v2.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.body_weight.v2.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.heart_rate.v2.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.height.v2.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.lab_test.v1.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.waist_hip.v2.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-SECTION.ad_hoc_heading.v1.adl create mode 100644 rm-skeleton/src/test/resources/adl/openEHR-EHR-SECTION.medications.v1.adl create mode 100644 rm-skeleton/src/test/resources/dadl/item_tree_blood_pressure_1.dadl create mode 100644 rm-skeleton/src/test/resources/dadl/item_tree_medicataion_1.dadl create mode 100644 rm-skeleton/src/test/resources/dadl/item_tree_medicataion_10.dadl create mode 100644 rm-skeleton/src/test/resources/dadl/item_tree_medicataion_11.dadl create mode 100644 rm-skeleton/src/test/resources/dadl/item_tree_medicataion_12.dadl create mode 100644 rm-skeleton/src/test/resources/dadl/item_tree_medicataion_2.dadl create mode 100644 rm-skeleton/src/test/resources/dadl/item_tree_medicataion_3.dadl create mode 100644 rm-skeleton/src/test/resources/dadl/item_tree_medicataion_4.dadl create mode 100644 rm-skeleton/src/test/resources/dadl/item_tree_medicataion_5.dadl create mode 100644 rm-skeleton/src/test/resources/dadl/item_tree_medicataion_6.dadl create mode 100644 rm-skeleton/src/test/resources/dadl/item_tree_medicataion_7.dadl create mode 100644 rm-skeleton/src/test/resources/dadl/item_tree_medicataion_8.dadl create mode 100644 rm-skeleton/src/test/resources/dadl/item_tree_medicataion_9.dadl create mode 100644 rm-skeleton/src/test/resources/log4j.properties create mode 100644 rm-skeleton/src/test/resources/oet/test_nested_sections_with_optional_children.oet create mode 100644 rm-skeleton/src/test/resources/oet/test_section_instruction_tree.oet create mode 100644 rm-skeleton/src/test/resources/oet/test_text_name.oet create mode 100644 rm-skeleton/src/test/resources/terms.txt create mode 100644 rm-skeleton/src/test/resources/xml/purged.xml create mode 100644 rm-skeleton/src/test/resources/xml/to_purge.xml create mode 100644 xml-binding/pom.xml create mode 100644 xml-binding/src/main/groovy/load-observation.groovy create mode 100644 xml-binding/src/main/java/org/openehr/binding/RMInspector.java create mode 100644 xml-binding/src/main/java/org/openehr/binding/XMLBinding.java create mode 100644 xml-binding/src/main/java/org/openehr/binding/XMLBindingException.java create mode 100644 xml-binding/src/main/xsd/Archetype.xsd create mode 100644 xml-binding/src/main/xsd/BaseTypes.xsd create mode 100644 xml-binding/src/main/xsd/Composition.xsd create mode 100644 xml-binding/src/main/xsd/Content.xsd create mode 100644 xml-binding/src/main/xsd/Extract.xsd create mode 100644 xml-binding/src/main/xsd/OpenehrProfile.xsd create mode 100644 xml-binding/src/main/xsd/Resource.xsd create mode 100644 xml-binding/src/main/xsd/Structure.xsd create mode 100644 xml-binding/src/main/xsd/Version.xsd create mode 100644 xml-binding/src/test/java/org/openehr/binding/BindDataTypesTest.java create mode 100644 xml-binding/src/test/java/org/openehr/binding/BindEmptyItemTreeTest.java create mode 100644 xml-binding/src/test/java/org/openehr/binding/BindItemTreeWithDvProportionTest.java create mode 100644 xml-binding/src/test/java/org/openehr/binding/BindStructureToXMLTest.java create mode 100644 xml-binding/src/test/java/org/openehr/binding/CreateXMLObjectTest.java create mode 100644 xml-binding/src/test/java/org/openehr/binding/RMBindingTest.java create mode 100644 xml-binding/src/test/java/org/openehr/binding/VersionedDocumentTest.java create mode 100644 xml-binding/src/test/java/org/openehr/binding/XMLBindingTestBase.java create mode 100644 xml-binding/src/test/java/org/openehr/binding/XMLParsingTest.java create mode 100644 xml-binding/src/test/resources/composition-discharge.xml create mode 100644 xml-binding/src/test/resources/composition-prescription.xml create mode 100644 xml-binding/src/test/resources/composition.xml create mode 100644 xml-binding/src/test/resources/dv_proportion.xml create mode 100644 xml-binding/src/test/resources/empty_item_tree.xml create mode 100644 xml-binding/src/test/resources/item_tree.xml create mode 100644 xml-binding/src/test/resources/item_tree_002.xml create mode 100644 xml-binding/src/test/resources/item_tree_003.xml create mode 100644 xml-binding/src/test/resources/log4j.properties create mode 100644 xml-binding/src/test/resources/original_version_001.xml create mode 100644 xml-binding/src/test/resources/original_version_002.xml create mode 100644 xml-binding/src/test/resources/simple_composition.xml create mode 100644 xml-serializer/pom.xml create mode 100644 xml-serializer/readme.txt create mode 100644 xml-serializer/src/main/java/org/openehr/am/serialize/XMLSerializer.java diff --git a/INSTALL.txt b/INSTALL.txt new file mode 100644 index 00000000..4589e0b7 --- /dev/null +++ b/INSTALL.txt @@ -0,0 +1,10 @@ +REQUIREMENTS: + +Java 1.6 or higher +Maven 3.0.4 or higher + +INSTALATION INSTRUCTIONS: + +INSTALLATION: + +java-libs/mvn clean install \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..ed6c070e --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,12 @@ +Version: MPL 2.0/GPL 2.0/LGPL 2.1 + +The contents of this file are subject to the Mozilla Public License Version 2.0 (the 'License'); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.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 Initial Developer of the Original Code is Rong Chen. Portions created by the Initial Developer are Copyright (C) 2013 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. diff --git a/README.txt b/README.txt new file mode 100644 index 00000000..64f89611 --- /dev/null +++ b/README.txt @@ -0,0 +1,5 @@ +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 new file mode 100644 index 00000000..16402292 --- /dev/null +++ b/adl-parser/docs/changes.txt @@ -0,0 +1,99 @@ +2007/04/28 +.fixed the issue with parsing units with slash, e.g. "/min" + +2007/04/26 +.updated parsing path-based term binding + +2007/04/18 +.added support for comment in term/constraint definitions +.updated parser due to AOM changes +.added support for empty C_DV_ORDINAL + +2007/03/18 +.non-inclusive integer and real interval parsing + +2007/03/16 +.fixed missing upper bound for duration interval + +2007/02/26 +.improved special string parsing + +2007/02/23 +.updated assumed value parsing for CDvQuantity +.added support for CDvQuantity starts with assumed value +.added support for generics in type_identifier + +2007/02/20 +.added support for empty purpose +.fixed parsing c_code_phrase with single code +.fixed parsing other_details, original_resource_uri, other_contributors +.fixed parsing c_dv_quantity_item only with units +.fixed parsing generic types +.fixed c_duration pattern + +2007/02/19 +.made ontology primary_language and languages optional +.use code_phrase for language parsing in translations and descriptions + +2007/02/18 +.improved assertion and archetype_slot parsing + +2007/02/15 +.fixed parsing translations without accreditation + +2007/02/14 +.improved c_dv_quantity parsing + +2007/02/10 +.corrected parsing constraint_ref + +2007/02/08 +.added support for assumed_value in c_dv_quantity +.the command line parser is created with missingLanguageCompatible falg set +.added support for single value interval for primitive types +.updated C_DV_QUANTITY parsing + +2007/02/07 +.fixed parsing issue caused by the order of description attributes + +2007/02/03 +.testcase verifies node paths after parsing +.backwards compatibility of archetypes without language section + +2007/02/02 +.added missing language attribute in translation details + +2007/02/01 +.added support for translations in language part + +2007/01/24 +.added support for assumedValue parsing in CDvOrdinal + +2007/01/20 +.added overwritting occurrences for ArchetypeInternalRef +.improved ArchetypeSlotTest +.added support for assumedValue in CCodePhrase + +2007/01/14 +.removed RoundTripTest and adl-serializer dependency + +2007/01/07 +.added archetype language part parsing +.AuthoredResource is used for archetype description + +2006/12/30 +.updated other CDomainTypes support +.replaced CDvCodedText with CCodePhrase + +2006/12/16 +.updated CDvCodedText support regarding query + +2006/12/18 +.separated CDurationTest from BasicTypesTest +.updated CDuration parsing regarding months and weeks in ISO8601 DURATION format + +2006/12/20 +.added support for CDuration string pattern + +2006/12/24 +.added support for duration interval in CDuration parsing \ No newline at end of file diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml new file mode 100644 index 00000000..1a2efa4e --- /dev/null +++ b/adl-parser/pom.xml @@ -0,0 +1,130 @@ + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5-SNAPSHOT + + adl-parser + jar + java ADL Parser + http://www.openehr.org/projects/java.html + + openEHR + http://www.openehr.org/ + + 2004 + + java ADL Parser + + + + + org.codehaus.mojo + javacc-maven-plugin + 2.6 + + se.acode.openehr.parser + + + + + javacc + + + + + + + maven-assembly-plugin + + + jar-with-dependencies + + + + se.acode.openehr.parser.ADLParser + + + + + + package + + assembly + + + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.codehaus.mojo + javacc-maven-plugin + [2.1,) + + javacc + + + + + + + + + + + + + + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + openehr-aom + ${project.version} + + + openehr + openehr-ap + ${project.version} + + + openehr + measure-serv + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + junit + junit + 3.8.1 + test + + + diff --git a/adl-parser/readme.txt b/adl-parser/readme.txt new file mode 100644 index 00000000..78c90591 --- /dev/null +++ b/adl-parser/readme.txt @@ -0,0 +1,13 @@ +Java ADL Parser +=============== + +DESCRIPTION + This is a Java implementation of a parser that can read openEHR + archetypes in Archetype Definition Language (ADL) format and + output a object tree in the form of Archetype Object Model (AOM). + It also provides some validation of archetypes after parsing. + +STATUS + Based on Archetype Definition Language (ADL) 1.4 and Archetype + Object Model and other related Information Models from openEHR + release 1.0.1. \ No newline at end of file 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 new file mode 100644 index 00000000..c6b609b1 --- /dev/null +++ b/adl-parser/src/main/java/se/acode/openehr/parser/ArchetypeValidator.java @@ -0,0 +1,113 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Java ADL Parser" + * keywords: "binding" + * + * author: "Rong Chen " + * copyright: "Copyright (C) 2005,2006,2007 ACODE HB, Sweden" + * copyright: "Copyright (C) 2008,2009 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ + +package se.acode.openehr.parser; + +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; +import org.openehr.am.archetype.constraintmodel.CComplexObject; +import org.openehr.am.archetype.constraintmodel.CAttribute; +import org.openehr.am.archetype.constraintmodel.CObject; +import org.openehr.am.archetype.constraintmodel.ArchetypeInternalRef; + +import java.util.Map; +import java.util.HashMap; + +/** + * Validator for archetype parsed from ADL files + *

+ * It checks + * .Existence of class and atribute + * .Use node by object path in cADL + * .Decomposed date with dADL + * .Term definition and binding checking + * + * @author Rong Chen + * @version 1.0 + */ +public class ArchetypeValidator { + + /** + * Constructs an ArchetypeValidator + * + * @param archetype The Archetype to be validated + */ + public ArchetypeValidator(Archetype archetype) { + this.archetype = archetype; + } + + /** + * Check if information model entity referenced by archetype + * has right name or type + * + * @return true if valid + */ + // todo: check class, attribute name etc + private boolean checkInformationModelEntity() { + return true; + } + + // todo: fix it + private boolean checkObjectPatch() { + return true; + } + + // todo: check if node occurrences allowed and valid + + // todo: check if archetypeSlot has cyclical reference + + // todo: check if archetypeInternalRef has valid target, cyclical reference + + /** + * Check internal references + * + * @return map of node path, target path if any wrong internal references + */ + Map checkInternalReferences() { + 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; + ArchetypeConstraint target = archetype.node(ref.getTargetPath()); + + if (target == null + || (! (target instanceof CObject)) + || (!((CObject) 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; + } + + + /* fields */ + private Archetype archetype; +} 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 new file mode 100644 index 00000000..3e63d27e --- /dev/null +++ b/adl-parser/src/main/java/se/acode/openehr/parser/AttributeValue.java @@ -0,0 +1,30 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Java ADL Parser" + * keywords: "binding" + * + * author: "Rong Chen " + * copyright: "Copyright (C) 2005,2006,2007 ACODE HB, Sweden" + * copyright: "Copyright (C) 2008,2009 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ + +package se.acode.openehr.parser; + +/** + * AttributeValue + * + * @author Rong Chen + * @version 1.0 + */ +public class AttributeValue extends Parsed { + + /* fields */ + String id; + Object qualifier; + Object value; +} 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 new file mode 100644 index 00000000..02881fdd --- /dev/null +++ b/adl-parser/src/main/java/se/acode/openehr/parser/ContentObject.java @@ -0,0 +1,32 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Java ADL Parser" + * keywords: "binding" + * + * author: "Rong Chen " + * copyright: "Copyright (C) 2005,2006,2007 ACODE HB, Sweden" + * copyright: "Copyright (C) 2008,2009 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ + +package se.acode.openehr.parser; + +import java.util.List; + +/** + * IdentifiedObject + * + * @author Rong Chen + * @version 1.0 + */ +public class ContentObject extends Parsed { + + /* fields */ + String id; // null for anonymous object + String constraint; // null for anonymous object + List attributes; +} 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 new file mode 100644 index 00000000..4bba371b --- /dev/null +++ b/adl-parser/src/main/java/se/acode/openehr/parser/Invariant.java @@ -0,0 +1,27 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Java ADL Parser" + * keywords: "binding" + * + * author: "Rong Chen " + * copyright: "Copyright (C) 2005,2006,2007 ACODE HB, Sweden" + * copyright: "Copyright (C) 2008,2009 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ + +package se.acode.openehr.parser; + +/** + * Invariant + * + * @author Rong Chen + * @version 1.0 + */ +public class Invariant extends Parsed { + + // todo: implement it +} 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 new file mode 100644 index 00000000..c33f0737 --- /dev/null +++ b/adl-parser/src/main/java/se/acode/openehr/parser/Parsed.java @@ -0,0 +1,36 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Java ADL Parser" + * keywords: "binding" + * + * author: "Rong Chen " + * copyright: "Copyright (C) 2005,2006,2007 ACODE HB, Sweden" + * copyright: "Copyright (C) 2008,2009 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ + +package se.acode.openehr.parser; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; + +/** + * Super class of all parsed archetype items. It provides basic functions for + * all parsed items. + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class Parsed { + + public String toString() { + + return ToStringBuilder.reflectionToString(this, style); + } + + private static final ToStringStyle style = ToStringStyle.MULTI_LINE_STYLE; +} diff --git a/adl-parser/src/main/javacc/adl.jj b/adl-parser/src/main/javacc/adl.jj new file mode 100644 index 00000000..c82bde0e --- /dev/null +++ b/adl-parser/src/main/javacc/adl.jj @@ -0,0 +1,3408 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Java ADL Parser" + * keywords: "binding" + * + * author: "Rong Chen " + * copyright: "Copyright (C) 2005,2006,2007 ACODE HB, Sweden" + * copyright: "Copyright (C) 2008,2009 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ + +options { + STATIC = false; + DEBUG_PARSER = false; + DEBUG_TOKEN_MANAGER = false; + DEBUG_LOOKAHEAD = false; + LOOKAHEAD = 1; + UNICODE_INPUT = true; +} + +PARSER_BEGIN(ADLParser) + +package se.acode.openehr.parser; + +import java.io.*; +import java.util.*; +import java.text.*; + +import org.openehr.rm.support.basic.Interval; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.quantity.datetime.*; +import org.openehr.rm.datatypes.text.*; +import org.openehr.rm.datatypes.quantity.*; +import org.openehr.rm.common.resource.*; +import org.openehr.rm.common.generic.RevisionHistory; +import org.openehr.rm.support.identification.*; +import org.openehr.rm.support.terminology.*; +import org.openehr.rm.support.measurement.*; + +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.assertion.*; +import org.openehr.am.archetype.constraintmodel.*; +import org.openehr.am.archetype.constraintmodel.primitive.*; +import org.openehr.am.archetype.ontology.*; +import org.openehr.am.openehrprofile.datatypes.quantity.*; +import org.openehr.am.openehrprofile.datatypes.text.CCodePhrase; +import org.openehr.terminology.SimpleTerminologyService; + +/** + * JavaCC grammer file for Archetype Definition Language (ADL) + * + * Targeted ADL revision 1.4 + * + * Included uriGrammarFragment.txt from Gregory Kick + * + * @author Rong Chen (rong.acode@gmail.com) + * @version 1.4 + */ + +public class ADLParser { + + /* static fields */ + private static final String CHARSET = "UTF-8"; + private static final String ATTRIBUTE_UNKNOWN = "__unknown__"; + + /* member flags for backwards compatibility */ + private boolean missingLanguageCompatible = false; + private boolean emptyPurposeCompatible = false; + + /* member fields */ + private MeasurementService measureServ = + SimpleMeasurementService.getInstance(); + + /* ======================= public constructors ======================== */ + + /* Constructor that takes file as input */ + public ADLParser(File file) throws IOException { + this(new FileInputStream(file), CHARSET); + } + + /* Constructor that takes string as input */ + public ADLParser(String value) { + this(new BufferedReader(new StringReader(value))); + } + + /* Constructor that takes file as input */ + public ADLParser(File file, boolean missingLanguageCompatible, + boolean emptyPurposeCompatible) throws IOException { + this(new FileInputStream(file), CHARSET); + this.missingLanguageCompatible = missingLanguageCompatible; + this.emptyPurposeCompatible = emptyPurposeCompatible; + } + + /* Constructor that takes string as input */ + public ADLParser(String value, boolean missingLanguageCompatible, + boolean emptyPurposeCompatible) { + this(new BufferedReader(new StringReader(value))); + this.missingLanguageCompatible = missingLanguageCompatible; + this.emptyPurposeCompatible = emptyPurposeCompatible; + } + + /* Constructor that takes Reader as input */ + public ADLParser(Reader reader, boolean missingLanguageCompatible, + boolean emptyPurposeCompatible) { + this(reader); + this.missingLanguageCompatible = missingLanguageCompatible; + this.emptyPurposeCompatible = emptyPurposeCompatible; + } + + /* Constructor that takes InputStream as input */ + public ADLParser(InputStream input, boolean missingLanguageCompatible, + boolean emptyPurposeCompatible) { + this(input); + this.missingLanguageCompatible = missingLanguageCompatible; + this.emptyPurposeCompatible = emptyPurposeCompatible; + } + + /* ========================= public interface ======================== */ + + /* execute the parsing */ + public Archetype parse() throws ParseException, Exception { + return archetype(); + } + + /* re-initial the parser */ + public void reInit(File file) throws IOException { + ReInit(new FileInputStream(file), CHARSET); + } + + /* re-initial the parser */ + public void reInit(InputStream input) throws IOException { + ReInit(new BufferedInputStream(input)); + } + + /* =================== entry point from command-line ================ */ + public static void main(String args[]) throws IOException { + ADLParser parser = null; + String title = "ADL 1.4 Parser: "; + +// read from stdin disabled +// if (args.length == 0) { +// System.out.println(title + " Reading from standard input . . ."); +// parser = new ADLParser(System.in); +// } + + if (args.length == 1) { + System.out.println(title + " Reading from file " + args[0] + " . . ."); + try { + // be permissive in console mode + parser = new ADLParser(new File(args[0]), true, true); + } catch (IOException e) { + System.out.println(title + " File " + args[0] + " not found."); + return; + } + } else if(args.length == 2 && "-d".equals(args[0])) { + System.out.println(title + " Reading from directory " + args[1] + " . . ."); + File dir = new File(args[1]); + if( ! dir.isDirectory()) { + System.out.println(args[1] + " not a directory.. aborted"); + return; + } + File[] files = dir.listFiles(); + if(files == null || files.length == 0) { + System.out.println(args[1] + " has no file.. aborted"); + return; + } + int passed = 0; + int total = 0; + for(int i = 0; i < files.length; i++) { + if( ! files[i].getName().endsWith(".adl")) { + continue; + } + if(parser == null) { + parser = new ADLParser(files[i], true, true); + } else { + parser.reInit(files[i]); + } + total++; + try { + Archetype a = parser.archetype(); + System.out.println(files[i] + " parsed successfully"); + passed ++; + } catch (Throwable e) { + e.printStackTrace(); + System.out.println(files[i] + " failed in parsing"); + } + } + System.out.println("Total files parsed: " + total); + System.out.println("Parsed successfully: " + passed); + System.out.println("Failed in parsing: " + (total - passed)); + + return; + } else { + System.out.println(title + " Usage is one of:"); + System.out.println(" java ADLParser < inputfile"); + System.out.println("OR"); + System.out.println(" java ADLParser inputfile"); + System.out.println("OR"); + System.out.println(" java ADLParser -d directory"); + return; + } + try { + Archetype a = parser.archetype(); + // System.out.println(a.toString()); + System.out.println(title + " ADL file parsed successfully."); + } catch (Throwable e) { + e.printStackTrace(); + System.out.println(title + " Encountered errors during parsing " + args[0]); + } + } + +} + +PARSER_END(ADLParser) + +< * > SKIP : /* WHITE SPACE */ +{ + " " +| "\t" +| "\n" +| "\r" +| "\f" +| "\u00ef\u00bb\u00bf" /* UTF-8 Byte Order Mark */ +| "\ufeff" /* UTF-16 Byte Order Mark */ +} + +< * > SPECIAL_TOKEN : /* COMMENTS */ +{ + +} + +< * > TOKEN [IGNORE_CASE]: /* RESERVED WORDS AND LITERALS - ADL */ +{ + : DEFAULT +| : DEFAULT +| : HIER_OBJECT +| : DEFAULT +| : DEFAULT +| : DEFAULT +| : DEFAULT +| : LANGUAGE +| : CADL +| : DESCRIPTION +| : ONTOLOGY +} + +< LANGUAGE > TOKEN [IGNORE_CASE]: /* KEYWORDS - archetype language */ +{ + < SYM_ORIGINAL_LANGUAGE: "original_language"> +| < SYM_TRANSLATIONS: "translations"> +| < SYM_LANG_LANGUAGE: "language"> +| < SYM_AUTHOR: "author"> +| < SYM_ACCREDITATION: "accreditation"> +| < SYM_LANG_OTHER_DETAILS: "other_details"> +} + + +< DESCRIPTION > TOKEN [IGNORE_CASE]: /* KEYWORDS - ADL description */ +{ + < SYM_ORIGINAL_AUTHOR: "original_author"> +| < SYM_LIFECYCLE_STATE: "lifecycle_state"> +| < SYM_RESOURCE_PACKAGE_URI: "resource_package_uri"> +| < SYM_DETAILS: "details"> +| < SYM_ORIGINAL_RESOURCE_URI: "original_resource_uri"> +| < SYM_OTHER_DETAILS: "other_details"> +| < SYM_OTHER_CONTRIBUTORS: "other_contributors"> +| < SYM_SUBMISSION: "submission"> +| < SYM_ORGANISATION: "organisation"> +| < SYM_DATE: "date"> +| < SYM_VERSION: "version"> +| < SYM_STATUS: "status"> +| < SYM_REVISION: "revision"> +| < SYM_PURPOSE: "purpose"> +| < SYM_USE: "use"> +| < SYM_MISUSE: "misuse"> +| < SYM_COPYRIGHT: "copyright"> +| < SYM_KEYWORDS: "keywords"> +| < SYM_RIGHTS: "rights"> +| < SYM_LANGUAGE_WORD: "language"> +} + +< DESCRIPTION, ONTOLOGY > TOKEN [IGNORE_CASE]: /* KEYWORDS - ADL description & ONTOLOGY */ +{ + < SYM_DESCRIPTION_WORD: "description"> +| < SYM_COMMENT: "comment"> +} + +< * > TOKEN [IGNORE_CASE]: /* KEYWORDS - dADL */ +{ + < SYM_TRUE: "true"> +| < SYM_FALSE: "false"> +| < SYM_INFINITY: "infinity"> +| < SYM_QUERY_FUNC: "query"> +} + +< ONTOLOGY > TOKEN [IGNORE_CASE]: /* KEYWORDS - ontology */ +{ + < SYM_PRIMARY_LANGUAGE: "primary_language"> +| < SYM_LANGUAGES_AVAILABLE: "languages_available"> +| < SYM_TERMINOLOGIES_AVAILABLE: "terminologies_available"> +| < SYM_TERM_DEFINITIONS: "term_definitions"> +| < SYM_TERM_BINDING: "term_binding"("s")?> +| < SYM_CONSTRAINT_DEFINITIONS: "constraint_definitions"> +| < SYM_CONSTRAINT_BINDING: "constraint_binding"("s")?> +| < SYM_ITEMS: "items"> +| < SYM_TEXT: "text"> +| < SYM_TRANSLATION: "translation"> +| < V_ABSOLUTE_PATH_WQ: "\"/" ( "/" )* "\"" > + +} + +< CADL, USE_NODE > TOKEN [IGNORE_CASE]: /* KEYWORDS - cADL */ +{ + < SYM_THEN: "then"> +| < SYM_ELSE: "else"> +| < SYM_AND: "and"> +| < SYM_OR: "or"> +| < SYM_XOR: "xor"> +| < SYM_NOT: "not"> +| < SYM_IMPLIES: "implies"> +| < SYM_FORALL: "forall"> +| < SYM_EXISTS: "exists"> +| < SYM_EXISTENCE: "existence"> +| < SYM_OCCURRENCES: "occurrences"> +| < SYM_CARDINALITY: "cardinality"> +| < SYM_ORDERED: "ordered"> +| < SYM_UNORDERED: "unordered"> +| < SYM_UNIQUE: "unique"> +| < SYM_MATCHES: "matches" | "is_in"> +| < SYM_INVARIANT: "invariant"> +| < SYM_USE_NODE: "use_node"> : USE_NODE +| < SYM_ALLOW_ARCHETYPE: "allow_archetype" | "use_archetype"> +| < SYM_INCLUDE: "include"> +| < SYM_EXCLUDE: "exclude"> +| < SYM_START_CBLOCK: "{"> +| < SYM_END_CBLOCK: "}"> +| < SYM_C_DV_QUANTITY: "c_dv_quantity" >: DOMAIN_TYPE_C_QUANTITY +| < SYM_ASSUMED_VALUE: "assumed_value"> +} + +< DOMAIN_TYPE_C_QUANTITY > TOKEN [IGNORE_CASE]: +{ + < SYM_PROPERTY: "property"> +| < SYM_LIST: "list"> +| < SYM_C_QUANTITY_UNITS: "units"> +| < SYM_PRECISION: "precision"> +| < SYM_MAGNITUDE: "magnitude"> +| < SYM_C_QUANTITY_ASSUMED_VALUE: "assumed_value"> +} + +< * > TOKEN: /* SYMBOLS - common */ +{ + < SYM_MINUS: "-"> +| < SYM_PLUS: "+"> +| < SYM_STAR: "*"> +| < SYM_SLASH: "/"> +| < SYM_CARET: "^"> +| < SYM_DOT: "."> +| < SYM_SEMICOLON: ";"> +| < SYM_COMMA: ","> +| < SYM_TWO_COLONS: "::"> +| < SYM_COLON: ":"> +| < SYM_EXCLAMATION: "!"> +| < SYM_L_PARENTHESIS: "("> +| < SYM_R_PARENTHESIS: ")"> +| < SYM_DOLLAR: "$"> +| < SYM_QUESTION: "?"> +| < SYM_L_BRACKET: "["> +| < SYM_R_BRACKET: "]"> /* : CADL /* !!! cause problems with description_item !!! */ +| < SYM_INTERVAL_DELIM: "|"> +| < SYM_EQ: "="> +| < SYM_GE: ">="> +| < SYM_LE: "<="> +| < SYM_LT: "<"> +| < SYM_GT: ">"> +| < SYM_NE: "!="> +| < SYM_MODULO: "\\"> +| < SYM_DIV: "//"> +| < SYM_ELLIPSIS: ".."> +| < SYM_LIST_CONTINUE: "..."> +| < SYM_C_DV_ORDINAL: "C_DV_ORDINAL" > +} + +< * > TOKEN : /* LOCAL TOKENS */ +{ + < #DIG: ["0"-"9"]> +| + < #LET_DIG: ["a"-"z","A"-"Z","0"-"9"] > +| + < #LET_DIG_DD: | "." | "-" > +| + < #LET_DIG_U: | "_" > +| + < #LET_DIG_DU: | "-" > +| + < #LET_DIG_DUDS: | "." | "\\" > +| + < #LET_DIG_DUDSLR: | "(" | ")" > +} + +< * > TOKEN : /* IDENTIFIERS - ADL */ +{ + ()+"."()+ + "."()+> +} + +/* ----------------------- TOKEN - HIER_OBJECT ---------------------------- */ + +< HIER_OBJECT > TOKEN: /* VALUES - HIER_OBJECT */ +{ + | "::" )+ > +} + + +/* ----------------------- TOKEN - TERM_CODE ---------------------------- */ + +< TERM_CODE > TOKEN: /* VALUES - TERM_CODE */ +{ + < V_TERM_CODE: ()+ > +} + +/* -------------------- TOKEN - dADL & cADL ------------------------- */ + +< * > TOKEN: /* VALUES - dADL & cADL */ +{ + < #V_LOCAL_CODE_CORE: "a"["c","t"](["0"-"9","."])+> +| + < V_LOCAL_CODE: "\"""\""> +| + < V_INTEGER: ()+ + | (){1,3}(","(){3})+> +| < V_REAL: ()+"./"~[".","0"-"9"] + | ()+"."()*["e","E"](["+","-"])?()+ + | ()*"."()+(["e","E"](["+","-"])?()+)? + | (){1,3}("_"(){3})+"./"~[".","0"-"9"] + | (){1,3}("_"(){3})*"."((){1,3} + ("_"(){3})*)?["e","E"](["+","-"])?(){1,3} + ("_"(){3})* + | ((){1,3}("_"(){3})*)?"."(){1,3} + ("_"(){3})*(["e","E"](["+","-"])?(){1,3} + ("_"(){3})*)?> +| + < V_STRING: + "\"" + ( + ("\\\"" (~["\"","\n", "\\"])* ) + | + ("\\\\" (~["\"","\n", "\\"])* ) + | + ("\n" (["\r", " ", "\t"])* ) + | + (~["\\","\n","\""])* + )* + "\"" + > +| + < V_LOCAL_CODE_PATH: "\"[""]/" + (("/")*"[""]/")*"\""> +| + < V_CHARACTER: "'"~["\\","\n","'"]"'" | > +| + < V_ISO8601_DURATION: ("-")? "P"(()+["y","Y"])?(()+["m","M"])?(()+["w","W"])? + (()+["d","D"])?("T"(()+["h","H"])?(()+["m","M"])? + (()+("."()*)?["s","S"])?)?> +| + < V_ISO8601_DURATION_CONSTRAINT_PATTERN: "P"(["y","Y"])?(["m","M"])? + (["w","W"])?(["d","D"])?"T"(["h","H"])?(["m","M"])?(["s","S"])? + |"P"(["y","Y"])?(["m","M"])?(["w","W"])?(["d","D"])?> +| + < V_DATE: (["0"-"9"]){4} "-" ["0"-"1"]["0"-"9"] "-" ["0"-"3"]["0"-"9"] | + (["0"-"9"]){4} "-" ["0"-"1"]["0"-"9"] > +| + < V_HHMM_TIME: > +| + < V_HHMMSS_TIME: < HOUR_MINUTE> > +| + < V_HHMMSSss_TIME: < HOUR_MINUTE> > +| + < V_HHMMSSZ_TIME: < HOUR_MINUTE> > +| + < V_HHMMSSssZ_TIME: < HOUR_MINUTE> > +| + < V_DATE_TIME: "T" (":"()?)? > +| + < V_DATE_TIME_MS: > +| + < V_DATE_TIME_Z: > +| + < V_DATE_TIME_MSZ: > +| + < #TIME_ZONE: ["-","+"](["0"-"9"]){4} | "Z" > +| + < #SECOND: ":" ["0"-"5"]["0"-"9"] > +| + < #MILLI_SECOND: ","(["0"-"9"]){1, 3} > +| + < #HOUR_MINUTE: ":" > +| + < #HOUR: ["0"-"2"]["0"-"9"] > +| + < #MINUTE: ["0"-"6"]["0"-"9"] > +| + ()*"]" > +| + < #CHAR_REF: "'&" ( + (["a"-"z","A"-"Z"])+ + | + "#" ( (["0"-"9"])+ | "x" (["0"-"9","a"-"f","A"-"F"])+ ) + ) ";'"> +| + < V_CODE_PHRASE: "["()+"::"()+"]"> +} + +/* ----------------------- TOKEN - dADL ---------------------------- */ + +< DADL, ONTOLOGY > TOKEN: /* VALUES - dADL */ +{ + < V_QUALIFIED_TERM_CODE_REF: "["()+"::"()+"]"> +| + ()*> +} + +/* ----------------------- TOKEN - cADL ---------------------------- */ + +< CADL > TOKEN: /* VALUES - cADL */ +{ + < V_REGEXP: (["=","!"]"~ ")? ( + ( "/"(~["\n","\r"])*"/" + | "^"(~["^","\n","\r"])*"^")) > +} + +< CADL, USE_NODE > TOKEN: /* VALUES - cADL */ +{ + < V_ISO8601_DATE_CONSTRAINT_PATTERN: (){4}"-""-" > +| + < V_ISO8601_TIME_CONSTRAINT_PATTERN: (["h","H"]){2}":"":" > +| + < V_ISO8601_DATE_TIME_CONSTRAINT_PATTERN: (){4}"-""-" + [" ","\t","T"]":"":" > +| + < V_TERMINOLOGY_ID_BLOCK: "["()+"::" > : TERM_CODE +| + < #YY: ["y","Y"]> +| + < #MMQX_2: (["m","M","?","X"]){2}> +| + < #MMQ_2: (["m","M","?"]){2}> +| + < #DDQX_2: (["d","D","?","X"]){2}> +| + < #HHQX_2: (["h","H","?","X"]){2}> +| + < #SSQX_2: (["s","S","?","X"]){2}> +| + < V_TYPE_IDENTIFIER: ["A"-"Z"]()*> +| + < V_ATTRIBUTE_IDENTIFIER: ["a"-"z"]()* > +| + < #PATH_SEGMENT: ()? > +| + < V_RELATIVE_PATH: ( "/" )* > +| + < V_ABSOLUTE_PATH: "/"("/")* > : CADL +} + + + TOKEN : /* URL per RFC 1738 Section 5 */ +{ + < URL : | | | | | | | | | | > +| < #genericurl : ":" > +| < #otherurl : > +| < #scheme : ( | | "+" | "-" | "." )+ > +| < #schemepart : ( )* | > +| < #ipschemepart : "//" ( "/" )? > +| < #login : ( ( ":" )? "@" )? > +| < #hostport : ( ":" )? > +| < #host : | > +| < #hostname : ( "." )* > +| < #domainlabel : | ( ( | "-" )* ) > +| < #toplabel : | ( ( | "-" )* ) > +| < #alphadigit : | > +| < #hostnumber : "." "." "." > +| < #port : > +| < #user : ( | ";" | "?" | "&" | "=" )* > +| < #password : ( | ";" | "?" | "&" | "=" )* > +| < #urlpath : ( )* > +| < #ftpurl : "ftp://" ( "/" ( ";type=" )? )? > +| < #fpath : ( "/" )* > +| < #fsegment : ( | "?" | ":" | "@" | "&" | "=" )* > +| < #ftptype : "A" | "I" | "D" | "a" | "i" | "d" > +| < #fileurl : "file://" ( | "localhost" )? "/" > +| < #httpurl : "http://" ( "/" ( "?" )? )? > +| < #hpath : ( "/" )* > +| < #hsegment : ( | ";" | ":" | "@" | "&" | "=" )* > +| < #search : ( | ";" | ":" | "@" | "&" | "=" )* > +| < #gopherurl : "gopher://" ( "/" ( ( ( "%09" ( "%09" )? )? )? )? )? > +| < #gtype : > +| < #selector : ( )* > +| < #gopherstring : ( )* > +| < #mailtourl : "mailto:" > +| < #encoded822addr : ( )+ > +| < #newsurl : "news:" > +| < #grouppart : "*" | |

> +| < #group : ( | | "-" | "." | "+" | "_" )* > +| < #article : ( | ";" | "/" | "?" | ":" | "&" | "=" )* "@" > +| < #nntpurl : "nntp://" "/" ( "/" )? > +| < #telneturl : "telnet://" "/" > +| < #waisurl : | | > +| < #waisdatabase : "wais://" "/" > +| < #waisindex : "wais://" "/" "?" > +| < #waisdoc : "wais://" "/" "/" "/" > +| < #database : ( )* > +| < #wtype : ( )* > +| < #wpath : ( )* > +| < #prosperourl : "prospero://" "/" ( )* > +| < #ppath : ( "/" )* > +| < #psegment : ( | "?" | ":" | "@" | "&" | "=" )* > +| < #fieldspec : ";" "=" > +| < #fieldname : ( | "?" | ":" | "@" | "&" )* > +| < #fieldvalue : ( | "?" | ":" | "@" | "&" )* > +| < #lowalpha : [ "a"-"z" ] > +| < #hialpha : [ "A"-"Z" ] > +| < #alpha : | > +| < #digit : [ "0"-"9" ] > +| < #safe : "$" | "-" | "_" | "." | "+" > +| < #extra : "!" | "*" | "'" | "(" | ")" | "," > +| < #national : "{" | "}" | "|" | "\\" | "^" | "~" | "[" | "]" | "`" > +| < #punctuation : "<" | ">" | "#" | "%" | "\"" > +| < #reserved : ";" | "/" | "?" | ":" | "@" | "&" | "=" > +| < #hex : | "A" | "B" | "C" | "D" | "E" | "F" | "a" | "b" | "c" | "d" | "e" | "f" > +| < #escape : "%" > +| < #unreserved : | | | > +| < #uchar : | > +| < #xchar : | | > +| < #digits : ( )+ > +} + +/***************************************** + * THE ADL LANGUAGE GRAMMAR STARTS HERE * + *****************************************/ + +Archetype archetype() throws Exception : +{ + Token t; + String id; + String adlVersion = null; + HierObjectID uid = null; + boolean isControlled = false; + String parent = null; + String concept; + String lang = null; + String langTerm = null; + String langCode = null; + CodePhrase originalLanguage = null; + Map translations = null; + TranslationDetails translationDetails = null; + RevisionHistory revisionHistory = null; + ResourceDescription description = null; + CComplexObject definition; + ArchetypeOntology ontology; + Set invariants = null; // TODO + TerminologyService terminologyService = + SimpleTerminologyService.getInstance(); +} +{ + + [ + + adlVersion = adl_version() + ( + + (uid = uid() + | + isControlled = controlled() + ) + )* + + ] + + t = + { id = t.image; } + + [ parent = arch_specialisation() ] + concept = arch_concept() + + [ + + "<" originalLanguage = code_phrase() ">" + [ + "<" + + { translations = translations(); } + + ">" + ] + ] + + [ description = arch_description() ] + + definition = arch_definition() + + ontology = arch_ontology() + + + { + if(originalLanguage == null && missingLanguageCompatible) { + langCode = ontology.getPrimaryLanguage(); + originalLanguage = new CodePhrase("ISO_639-1", langCode); + } + + return new Archetype(adlVersion, id, parent, concept, originalLanguage, + translations, description, revisionHistory, isControlled, uid, + definition, ontology, invariants, terminologyService); + } +} + +CodePhrase code_phrase() : +{ + Token t; + String lang = null; + String langTerm = null; + String langCode = null; +} +{ + t = + { + lang = t.image; + int i = lang.indexOf("::"); + langTerm = lang.substring(1, i); + langCode = lang.substring(i + 2, lang.length() - 1); + } + { return new CodePhrase(langTerm, langCode); } +} + +Map translations() throws Exception : +{ + Token t; + String langAsKey; + CodePhrase language = null; + TranslationDetails td; + Map map = new HashMap(); + Map author = null; + String accreditation = null; + Map otherDetails = null; + TerminologyService terminologyService = SimpleTerminologyService.getInstance(); +} +{ + ( + langAsKey = string_value() + { accreditation = null; + author=null; + otherDetails=null; + } + ( + "<" language = code_phrase() ">" + | + + author = string_string_map() + + [ + + accreditation = string_value() + + ] + + [ + + otherDetails = string_string_map() + + ] + )* + + { + // TODO null terminology service + td = new TranslationDetails(language, author, accreditation, + otherDetails, terminologyService); + map.put(langAsKey, td); + } + )+ + { return map; } +} + +Map string_string_map() : +{ + Map map = new HashMap(); + String key; + String value; +} +{ + ( + key = string_value() + value = string_value() + + { map.put(key, value); } + )* + { return map; } +} + +String adl_version() : +{ + Token t; +} +{ + t = + { return t.image; } +} + +HierObjectID uid() : +{ + Token t; +} +{ + t = + { + HierObjectID uidAsObjectID = new HierObjectID(t.image); + return uidAsObjectID; + } +} + +boolean controlled() : +{ + boolean ret = false; +} +{ + + { return true; } + | + + { return false; } +} + +String arch_specialisation() : +{ + Token t; +} +{ + t = + { return t.image; } +} + +String arch_concept() : +{ + String value; +} +{ + value = constraint_ref() + { return value; } +} + +ResourceDescription arch_description() throws Exception : +{ + Map originalAuthor = new HashMap(); + String key = null; + String value = null; + List otherContributors = null; + String lifecycleState = null; + List details = new ArrayList(); + ResourceDescriptionItem item = null; + String resourcePackageURI = null; + Map otherDetails = null; + Archetype parentArchetype = null; + AuthoredResource parent = null; // not used +} +{ + + ( + "<" lifecycleState = string_value() ">" + | + "<" + resourcePackageURI = string_value() + ">" + | + "<" + ( + LOOKAHEAD(2) + item = arch_description_item() + { + details.add(item); + } + )+ + ">" + | + "<" + originalAuthor = string_string_map() + ">" + | + "<" string_value() ">" + | + "<" + ( + otherContributors = string_list_value() + | + otherContributors = index_string_list() + ) + ">" + | + "<" + otherDetails = string_string_map() + ">" + )* + { + ResourceDescription resourceDescription = new ResourceDescription( + originalAuthor, otherContributors, lifecycleState, details, + resourcePackageURI, otherDetails, parent); + + return resourceDescription; + } +} + +ResourceDescriptionItem arch_description_item() throws Exception : +{ + String langAsKey = null; + CodePhrase lang = null; + String purpose = null; + String use = null; + String misuse = null; + String copyright = null; + List keywords = null; + String keyword = null; + Map originalResourceURI = new HashMap(); + Map otherDetails = null; // not used + TerminologyService terminologyService = + SimpleTerminologyService.getInstance(); +} +{ + "[" langAsKey = string_value() "]" "<" + ( + "<" lang = code_phrase() ">" + | + "<" purpose = string_value() ">" + | + + "<" + ( + LOOKAHEAD(2) + keywords = string_list_value() + | + LOOKAHEAD(2) + keyword = string_value() + { + keywords = new ArrayList(); + keywords.add(keyword); + } + ) + + ">" + | + + "<" use = string_value() ">" + | + + "<" misuse = string_value() ">" + | + + "<" copyright = string_value() ">" + + | + "<" + originalResourceURI = string_string_map() + ">" + | + "<" + otherDetails = string_string_map() + ">" + + )* + ">" + { + if(use != null && use.trim().length() == 0) { + use = null; + } + if(misuse != null && misuse.trim().length() == 0) { + misuse = null; + } + if(copyright != null && copyright.trim().length() == 0) { + copyright = null; + } + + if((purpose == null || purpose.length() == 0) && emptyPurposeCompatible) { + purpose = ATTRIBUTE_UNKNOWN; + } + + return new ResourceDescriptionItem(lang, purpose, keywords, + use, misuse, copyright, originalResourceURI, otherDetails, + terminologyService); + } +} + +CComplexObject arch_definition() : +{ + CComplexObject obj; +} +{ + obj = cadl_text() + { return obj; } +} + + +/********************************************* + * THE ONTOLOGY LANGUAGE GRAMMAR STARTS HERE * + *********************************************/ + +ArchetypeOntology arch_ontology() : +{ + String primaryLanguage = null; + List languages = null; + List terminologies = null; + List termDefinitionsList = new ArrayList(); + List constraintDefinitionsList = new ArrayList(); + List termBindingList = new ArrayList(); + List constraintBindingList = new ArrayList(); + + OntologyDefinitions definitions; + OntologyBinding binding; + Token t = null; + String key = null; + Object value = null; +} +{ + + [primaryLanguage = primary_language()] + [languages = languages_available()] + [ terminologies = terminologies_available() ] + + termDefinitionsList = term_definitions_list() + + [ constraintDefinitionsList = constraint_definitions_list() ] + + [ termBindingList = term_binding_list() ] + + [ constraintBindingList = constraint_binding_list() ] + + ( + t = { key = t.image; } + "<" value = dadl_text() ">" + { + // skipped for now + // ontology.extra.put(key, value); + } + )* + + { + return new ArchetypeOntology(primaryLanguage, languages, terminologies, + termDefinitionsList, constraintDefinitionsList, + termBindingList, constraintBindingList); + } +} + +String primary_language() : +{ + String lang; +} +{ + "<" lang = string_value() ">" + { return lang; } +} + +List languages_available() : +{ + List list; +} +{ + "<" list = string_list_value() ">" + { return list; } +} + +List terminologies_available() : +{ + List list; +} +{ + "<" list = string_list_value() ">" + { return list; } +} + +List term_definitions_list() : +{ + List list = new ArrayList(); + OntologyDefinitions definitions = null; +} +{ + "<" + ( + definitions = definitions_body() + { list.add(definitions); } + )+ + ">" + { return list; } +} + +List constraint_definitions_list() : +{ + List list = new ArrayList(); + OntologyDefinitions definitions = null; +} +{ + "<" + ( + definitions = definitions_body() + { list.add(definitions); } + )* + ">" + { return list; } +} + +OntologyDefinitions definitions_body() : +{ + OntologyDefinitions definitions; + String language; + List list = new ArrayList(); + ArchetypeTerm term; +} +{ + "[" language = string_value() "]" + "<" + "<" + [ + ( + term = archetype_term() + { + list.add(term); + } + )+ + ] + ">" + ">" + { return new OntologyDefinitions(language, list); } +} + +DefinitionItem definition_item() : +{ + String code; + String text; + String description; +} +{ + "[" code = local_code_value() "]" "<" + ( + "<" text = string_value() ">" + [ ";" ] + "<" description = string_value() ">" + | + "<" description = string_value() ">" + [ ";" ] + "<" text = string_value() ">" + ) + ">" + { return new DefinitionItem(code, text, description); } +} + +ArchetypeTerm archetype_term() : +{ + Token t; + String code; + String key; + String value = null; + ArchetypeTerm term; +} +{ + "[" + code = local_code_value() + { term = new ArchetypeTerm(code); } + + "]" "<" + ( + "<" + value = string_value() { term.addItem("text", value); } + ">" [ ";" ] + | + "<" + value = string_value() { term.addItem("description", value); } + ">" [ ";" ] + | + "<" + value = string_value() { term.addItem("comment", value); } + ">" [ ";" ] + | + t = "<" + value = string_value() + { + key = t.image; + term.addItem(key, value); + } + ">" [ ";" ] + )* + ">" + { return term; } +} + +List term_binding_list() : +{ + List list = new ArrayList(); + OntologyBinding binding = null; +} +{ + "<" + ( + binding = ontology_binding_body() + { list.add(binding); } + )* + ">" + { return list; } +} + +List constraint_binding_list() : +{ + List list = new ArrayList(); + OntologyBinding binding = null; +} +{ + "<" + ( + binding = ontology_binding_body() + { list.add(binding); } + )* + ">" + { return list; } +} + +OntologyBinding ontology_binding_body() : +{ + OntologyBinding binding; + String terminology; + List bindingList = new ArrayList(); + OntologyBindingItem item; +} +{ + "[" terminology = string_value() "]" "<" + + "<" + + ( + LOOKAHEAD( query_binding_item() ) + item = query_binding_item() + { bindingList.add(item); } + | + LOOKAHEAD( term_binding_item() ) + item = term_binding_item() + { bindingList.add(item); } + )* + ">" + ">" + { return new OntologyBinding(terminology, bindingList); } +} + +TermBindingItem term_binding_item() : +{ + String code; + String term; + List terms = new ArrayList(); +} +{ + "[" + ( + LOOKAHEAD( local_code_value()) + code = local_code_value() + | + code = local_code_path_value() + ) + "]" "<" + term = term_code() { + terms.add(term); + } + ("," term = term_code() { + terms.add(term); + } + )* + ">" + { return new TermBindingItem(code, terms); } +} + +QueryBindingItem query_binding_item() : +{ + String code; + Token t; +} +{ + "[" code = local_code_value() "]" "<" t = ">" + { return new QueryBindingItem(code, new Query(t.image)); } +} + +String local_code_value() : +{ + Token t; +} +{ + t = + { + String value = t.image; + return value.substring(1, value.length() - 1); + } +} + +String local_code_path_value() : +{ + Token t; +} +{ + t = + { + String value = t.image; + return value.substring(1, value.length() - 1); + } +} + + +/***************************************** + * THE dADL LANGUAGE GRAMMAR STARTS HERE * + *****************************************/ + +ContentObject dadl_text() : +{ + ContentObject obj = new ContentObject(); +} +{ + ( + LOOKAHEAD( 2 ) + obj.attributes = attr_vals() + | + LOOKAHEAD( 2 ) + obj = identified_object() + ) + { return obj; } +} + +ContentObject identified_object() : +{ + ContentObject obj = new ContentObject(); + Token t; +} +{ + t = { obj.id = t.image; } + obj.constraint = constraint_ref() + obj.attributes = attr_vals() + + { return obj; } +} + +List attr_vals() : +{ + List list = new ArrayList(); + AttributeValue av; +} +{ + av = attr_val() { list.add(av); } + ( + (";")? av = attr_val() { list.add(av); } + )* + { return list; } +} + +AttributeValue attr_val() : +{ + AttributeValue av = new AttributeValue(); + Token t; + Object value; +} +{ + t = { av.id = t.image; } + [ "(" av.qualifier = simple_value() ")" ] + + [ + LOOKAHEAD ( basic_object_val() ) + av.value = basic_object_val() + | + LOOKAHEAD (attr_vals() ) + av.value = attr_vals() + ] + + { return av; } +} + +Set c_includes() : +{ + Set set ; +} +{ + set = assertions() + { return set; } +} + +Set c_excludes() : +{ + Set set; +} +{ + set = assertions() + { return set; } +} + +Set assertions() : +{ + Set set = new HashSet(); + Assertion a; +} +{ + ( + a = assertion() + { + set.add(a); + } + )+ + { return set; } +} + +Assertion assertion() : +{ + String tag = null; + ExpressionItem expression; + String stringExpression = null; + List variables = null; +} +{ + [ + LOOKAHEAD(2) + tag = any_identifier() ":" + ] + expression = boolean_expression() + + { + stringExpression = expression.toString(); + return new Assertion(tag, expression, stringExpression, variables); + } +} + +Object basic_object_val() : +{ + Object value; +} +{ + ( + LOOKAHEAD( simple_list_value() ) + value = simple_list_value() + | + value = simple_interval_value() + | + LOOKAHEAD( simple_value() ) + value = simple_value() + | + LOOKAHEAD( term_code_list_value() ) + value = term_code_list_value() + | + LOOKAHEAD( term_code() ) + value = term_code() + ) + { return value; } +} + +Object simple_value() : +{ + Object value; + int i = 0; + double d = 0; + boolean b = false; + char c = 0; +} +{ + ( + LOOKAHEAD ( date_time_value() ) + value = date_time_value() + | + LOOKAHEAD( date_value() ) + value = date_value() + | + LOOKAHEAD( time_value() ) + value = time_value() + | + LOOKAHEAD( duration_value() ) + value = duration_value() + | + LOOKAHEAD( real_value() ) + d = real_value() + { value = new Double(d); } + | + LOOKAHEAD( integer_value() ) + i = integer_value() + { value = new Integer(i); } + | + b = boolean_value() + { value = new Boolean(b); } + | + c = character_value() + { value = new Character(c); } + | + LOOKAHEAD( string_value() ) + value = string_value() + ) + { return value; } +} + +List simple_list_value() : +{ + List list; +} +{ + ( + LOOKAHEAD( time_list_value() ) + list = time_list_value() + | + LOOKAHEAD( date_list_value() ) + list = date_list_value() + | + LOOKAHEAD( date_time_list_value() ) + list = date_time_list_value() + | + LOOKAHEAD ( duration_list_value() ) + list = duration_list_value() + | + LOOKAHEAD( integer_list_value() ) + list = integer_list_value() + | + LOOKAHEAD( real_list_value() ) + list = real_list_value() + | + list = boolean_list_value() + | + list = character_list_value() + | + list = string_list_value() + ) + { return list; } +} + +Interval simple_interval_value() : +{ + Interval i; +} +{ + ( + LOOKAHEAD( date_interval_value() ) + i = date_interval_value() + | + LOOKAHEAD( time_interval_value() ) + i = time_interval_value() + | + LOOKAHEAD( date_time_interval_value() ) + i = date_time_interval_value() + | + LOOKAHEAD( duration_interval_value() ) + i = duration_interval_value() + | + LOOKAHEAD( real_interval_value() ) + i = real_interval_value() + | + LOOKAHEAD( integer_interval_value() ) + i = integer_interval_value() + ) + { return i; } +} + +/* ---------------------- dADL - BASIC DATA VALUES ----------------------- */ +String string_value() : +{ + Token t; + String value; +} +{ + t = { + value = t.image; + } + { + // remove escape, \" -> " + value = value.replace("\\\"","\""); + + // remove escape, \\ -> \ + value = value.replace("\\\\","\\"); + + return value.substring(1, value.length() - 1); + } +} + +List index_string_list() :{ + List list = new ArrayList(); + String value = null; + String index = null; // not used +} +{ + ( + index = string_value() + ( value = string_value()) + { list.add(value); } + + )* + { return list.isEmpty() ? null : list; } +} + +List string_list_value() : +{ + List list = new ArrayList(); + String value; +} +{ + value = string_value() { + list.add(value); + } + ( LOOKAHEAD( 2 ) "," ( value = string_value() { + list.add(value); + } + | + ) + )+ + { return list; } +} + +int integer_value() : +{ + int i; + boolean negative = false; +} +{ + [ ( "+" | "-" { negative = true; } ) ] i = positive_int_value() + { + if(negative) { + i = -i; + } + return i; + } +} + +int positive_int_value() : +{ + Token t; +} +{ + t = + { + try { + return Integer.parseInt(t.image); + } catch(NumberFormatException e) { + throw new ParseException("Wrong format of integer: " + t.image); + } + } +} + +List integer_list_value() : +{ + List list = new ArrayList(); + int i; +} +{ + i = integer_value() + { list.add(new Integer(i)); } + ("," ( i = integer_value() | ) + { list.add(new Integer(i)); } + )+ + { return list; } +} + +Interval integer_interval_value() : +{ + Interval i = null; + int lower = 0; + int upper = 0; +} +{ + + ( + LOOKAHEAD( 3 ) + { + boolean lowerInclusive = true; + boolean upperInclusive = true; + boolean upperSpecified = false; + } + [ + { lowerInclusive = false; } + ] + lower = integer_value() + { upper = lower; } + [ + + [ + { upperInclusive = false; } + ] + upper = integer_value() + { 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, + upperInclusive); + } + } + | + upper = integer_value() + { + i = new Interval(null, new Integer(upper), false, false); + } + | + lower = integer_value() + { + i = new Interval(new Integer(lower), null, false, false); + } + | + upper = integer_value() + { + i = new Interval(null, new Integer(upper), false, true); + } + | + lower = integer_value() + { + i = new Interval(new Integer(lower), null, true, false); + } + ) + + + { return i; } +} + +double real_value() : +{ + Token t; + double d; + boolean negative = false; +} +{ + [ ( "+" | "-" { 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; + } +} + +List real_list_value() : +{ + List list = new ArrayList(); + double d; +} +{ + d = real_value() { list.add(new Double(d)); } + ( + "," ( + d = real_value() { list.add(new Double(d)); } + | + + ) + )+ + { return list; } +} + +Interval real_interval_value() : +{ + Interval i = null; + double upper = 0; + double lower = 0; +} +{ + + ( + LOOKAHEAD( 3 ) + { + boolean lowerInclusive = true; + boolean upperInclusive = true; + boolean upperSpecified = false; + } + [ + { lowerInclusive = false; } + ] + lower = real_value() + { upper = lower; } + [ + + [ + { upperInclusive = false; } + ] + 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, + upperInclusive); + } + } + | + upper = real_value() + { + i = new Interval(null, new Double(upper), false, false); + } + | + upper = real_value() + { + i = new Interval(null, new Double(upper), false, true); + } + | + lower = real_value() + { + i = new Interval(new Double(lower), null, false, false); + } + | + lower = real_value() + { + i = new Interval(new Double(lower), null, true, false); + } + ) + + + { return i; } +} + +boolean boolean_value() : +{} +{ + { return true; } + | + { return false; } +} + +List boolean_list_value() : +{ + List list = new ArrayList(); + boolean b; +} +{ + b = boolean_value() + { + list.add(new Boolean(b)); + } + ( + "," ( + b = boolean_value() { list.add(new Boolean(b)); } + | + + ) + )+ + { return list; } +} + +char character_value() : +{ + Token t; +} +{ + t = + { return t.image.charAt(1); } +} + +List character_list_value() : +{ + List list = new ArrayList(); + char c; +} +{ + c = character_value() + { + list.add(new Character(c)); + } + ( + "," ( + c = character_value() { list.add(new Character(c)); } + | + + ) + )+ + { return list; } +} + +DvDate date_value() : +{ + Token t; +} +{ + t = + { + try { + return new DvDate(t.image); + } catch(Exception ignored) { + throw new ParseException("wrong date format: " + t.image); + } + } +} + +List date_list_value() : +{ + List list = new ArrayList(); + DvDate d; +} +{ + d = date_value() { list.add(d); } + ( + "," ( + d = date_value() { list.add(d); } + | + + ) + )+ + { return list; } +} + +Interval date_interval_value() : +{ + Interval i; + DvDate lower = null; + DvDate upper = null; +} +{ + + ( + lower = date_value() + { upper = lower; } + [ upper = date_value() ] + { + i = new Interval(lower, upper, true, true); + } + | + upper = date_value() + { + i = new Interval(null, upper, false, false); + } + | + upper = date_value() + { + i = new Interval(null, upper, false, true); + } + | + lower = date_value() + { + i = new Interval(lower, null, false, false); + } + | + lower = date_value() + { + i = new Interval(lower, null, true, false); + } + ) + + + { return i; } +} + +DvTime time_value() : +{ + Token t; + String pattern; +} +{ + ( + t = + { pattern = "HH:mm"; } + | + t = + { pattern = "HH:mm:ss"; } + | + t = + { pattern = "HH:mm:ss.SSS"; } + | + t = + { pattern = "HH:mm:ssZ"; } + | + t = + { pattern = "HH:mm:ss.SSSZ"; } + ) + { + try { + return new DvTime(t.image); + } catch(Exception e) { + throw new ParseException("wrong date format: " + t.image); + } + } +} + +List time_list_value() : +{ + List list = new ArrayList(); + DvTime time; +} +{ + time = time_value() { list.add(time); } + ( + "," ( + time = time_value() { list.add(time); } + | + ) + )+ + { return list; } +} + +Interval time_interval_value() : +{ + Interval i; + DvTime lower = null; + DvTime upper = null; +} +{ + + ( + lower = time_value() + { upper = lower; } + [ upper = time_value() ] + { + i = new Interval(lower, upper, true, true); + } + | + upper = time_value() + { + i = new Interval(null, upper, false, false); + } + | + upper = time_value() + { + i = new Interval(null, upper, false, true); + } + | + lower = time_value() + { + i = new Interval(lower, null, false, false); + } + | + lower = time_value() + { + i = new Interval(lower, null, true, false); + } + ) + + { return i; } +} + +DvDateTime date_time_value() : +{ + Token t; + String pattern; +} +{ + ( + t = + { pattern = "yyyy-MM-ddTHH:mm:ss"; } + | + t = + { pattern = "yyyy-MM-ddTHH:mm:ss.SSS"; } + | + t = + { pattern = "yyyy-MM-ddTHH:mm:ssZ"; } + | + t = + { pattern = "yyyy-MM-ddTHH:mm:ss.SSSZ"; } + ) + { + try { + return new DvDateTime(t.image); + } catch(Exception e) { + throw new ParseException("wrong datetime format: " + t.image); + } + } +} + +List date_time_list_value() : +{ + List list = new ArrayList(); + DvDateTime datetime; +} +{ + datetime = date_time_value() { list.add(datetime); } + ( + "," ( + datetime = date_time_value() { list.add(datetime); } + | + ) + )+ + { return list; } +} + +Interval date_time_interval_value() : +{ + Interval i; + DvDateTime lower = null; + DvDateTime upper = null; +} +{ + + ( + lower = date_time_value() + { upper = lower; } + [ upper = date_time_value() ] + { + i = new Interval(lower, upper, true, true); + } + | + upper = date_time_value() + { + i = new Interval(null, upper, false, false); + } + | + upper = date_time_value() + { + i = new Interval(null, upper, false, true); + } + | + lower = date_time_value() + { + i = new Interval(lower, null, false, false); + } + | + lower = date_time_value() + { + i = new Interval(lower, null, true, false); + } + ) + + { return i; } +} + +DvDuration duration_value() : +{ + Token t; +} +{ + t = + { + return DvDuration.getInstance(t.image); + } +} + +List duration_list_value() : +{ + List list = new ArrayList(); + DvDuration d; +} +{ + d = duration_value() { list.add(d); } + ( + "," ( + d = duration_value() { list.add(d); } + | + + ) + )+ + { return list; } +} + +Interval duration_interval_value() : +{ + Interval i; + DvDuration lower = null; + DvDuration upper = null; +} +{ + + ( + lower = duration_value() + { upper = lower; } + [ + upper = duration_value() + ] + { + i = new Interval(lower, upper, true, true); + } + | + upper = duration_value() + { + i = new Interval(null, upper, false, false); + } + | + upper = duration_value() + { + i = new Interval(null, upper, false, true); + } + | + lower = duration_value() + { + i = new Interval(lower, null, false, false); + } + | + lower = duration_value() + { + i = new Interval(lower, null, true, false); + } + ) + + { return i; } +} + +String term_code() : +{ + CodePhrase code; +} +{ + code = code_phrase() + { return "[" + code.getTerminologyId() + "::" + code.getCodeString() + "]"; } +} + +List term_code_list_value() : +{ + List list = new ArrayList(); + String term; +} +{ + term = term_code() { list.add(term); } + ( + "," ( + term = term_code()) { list.add(term); } + | + + )+ + { return list; } +} + + +/***************************************** + * THE cADL LANGUAGE GRAMMAR STARTS HERE * + *****************************************/ + +CComplexObject cadl_text() : +{ + CComplexObject c; +} +{ + c = c_complex_object(null, null) + { return c; } +} + +CComplexObject c_complex_object(String path, CAttribute parent) : +{ + String type; + String nodeID = null; + Interval occurrences = new Interval(1, 1); + List attributes; +} +{ + type = type_identifier() + [ nodeID = constraint_ref() ] + [ occurrences = c_occurrences() ] + { + if(path == null) { + path = "/"; + } else { + path += (nodeID == null ? "" : "[" + nodeID + "]"); + } + } + + attributes = c_complex_object_body(path) + + { + return new CComplexObject(path, type, occurrences, nodeID, attributes, parent); + } +} + +List c_complex_object_body(String path) : +{ + List list = null; + CAttribute a = null; +} +{ + ( + c_any() + | + { list = new ArrayList(); } + ( + a = c_attribute(path) + { + list.add(a); + } + )+ + ) + { + return list; + } +} + +CObject c_object(String path, CAttribute parent) : +{ + CObject c = null; +} +{ + ( + c = c_dv_quantity(path, parent) + | + c = c_complex_object(path, parent) + | + c = archetype_internal_ref(path, parent) + | + c = archetype_slot(path, parent) + | + c = c_code_phrase(path, parent) + | + LOOKAHEAD( 3 ) + c = c_dv_ordinal(path, parent) + | + LOOKAHEAD( 3 ) + c = c_primitive_object(path, parent) + | + c = constraint_ref_obj(path, parent) + ) + { + return c; + } +} + +ConstraintRef constraint_ref_obj(String path, CAttribute parent) : +{ + String reference; + String rmTypeName = "CODE_PHRASE"; + Interval occurrences = new Interval(1, 1); + String nodeId = null; +} +{ + reference = constraint_ref() + { + return new ConstraintRef(path, rmTypeName, occurrences, nodeId, parent, + reference); + } +} + +ArchetypeInternalRef archetype_internal_ref(String path, CAttribute +parent) : +{ + String type; + Interval occurrences = new Interval(1, 1); + String target; + String nodeID = null; +} +{ + type = type_identifier() + [ nodeID = constraint_ref() ] + [ occurrences = c_occurrences() ] + target = absolute_path() + { + return new ArchetypeInternalRef(path, type, occurrences, nodeID, parent, + target); + } +} + +ArchetypeSlot archetype_slot(String path, CAttribute parent) : +{ + String type; + String nodeID = null; + Interval occurrences = new Interval(1, 1); + Set includes = null; + Set excludes = null; +} +{ + type = type_identifier() + + [ nodeID = constraint_ref() ] + + [ occurrences = c_occurrences() ] + + + [ includes = c_includes() ] + [ excludes = c_excludes() ] + + { + if(path == null) { + path = "/"; + } else { + path += (nodeID == null ? "" : "[" + nodeID + "]"); + } + return new ArchetypeSlot(path, type, occurrences, nodeID, parent, includes, + excludes); + } +} + +CPrimitiveObject c_primitive_object(String path, CAttribute parent) : +{ + CPrimitive c; + Interval occurrences = new Interval(1, 1); +} +{ + c = c_primitive() + { return new CPrimitiveObject(path, occurrences, null, parent, c); } +} + +CPrimitive c_primitive() : +{ + CPrimitive c; +} +{ + ( + LOOKAHEAD( c_boolean() ) + c = c_boolean() + | + LOOKAHEAD( c_date() ) + c = c_date() + | + LOOKAHEAD( c_time() ) + c = c_time() + | + LOOKAHEAD( 3 ) + c = c_date_time() + | + LOOKAHEAD( c_duration() ) + c = c_duration() + | + LOOKAHEAD( c_string() ) + c = c_string() + | + LOOKAHEAD( c_integer() ) + c = c_integer() + | + LOOKAHEAD( c_real() ) + c = c_real() + ) + { return c; } +} + +void c_any() : +{} +{ + "*" +} + +/* ----------------- BODY - relationships -------------------- */ + +CAttribute c_attribute(String path) : +{ + String name; + CAttribute.Existence existence = CAttribute.Existence.REQUIRED; + Cardinality cardinality = null; // default to non-container type + List children; + CAttribute attribute; +} +{ + { + if( ! path.endsWith("/")) { + path += "/"; + } + } + name = attribute_identifier() + [ existence = c_existence() ] + [ cardinality = c_cardinality() ] + + children = c_attr_values(path + name, null) // TODO fix parent + + { + 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 + if (children!=null){ + for(Iterator it = children.iterator(); it.hasNext();) { + CObject co = (CObject) it.next(); + co.setParent(attribute); + } + } + + return attribute; + } +} + +List c_attr_values(String path, CAttribute parent) : +{ + List list = null; + CObject c = null; +} +{ + ( + LOOKAHEAD(2) + c_any() + | + { list = new ArrayList(); } + ( + LOOKAHEAD(2) + c = c_object(path, parent) + { list.add(c); } + )* + ) + { return list; } +} + +Set c_invariants() : +{ + Set set; +} +{ + set = assertions() + { return set; } +} + +/* ----------------------- expressions ----------------------- */ +ExpressionItem boolean_expression() : +{ + ExpressionItem item = null; +} +{ + LOOKAHEAD( 2 ) + item = boolean_leaf() +| + LOOKAHEAD( 2 ) + item = boolean_node() + + { return item; } +} + +ExpressionItem boolean_node() : +{ + ExpressionItem ret = null; + ExpressionItem item = null; + ExpressionItem item2 = null; + OperatorKind op = null; + String path = null; + boolean precedenceOverridden = false; // TODO + 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); + } +| + LOOKAHEAD( 2 ) + 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 + 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, + OperatorKind.OP_MATCHES, false, item, item2); + } +| + item = boolean_expression() + { + ret = new ExpressionUnaryOperator(ExpressionItem.BOOLEAN, + 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() + { + ret = new ExpressionBinaryOperator(item.getType(), op, false, item, item2); + } +| + 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, + item, item2); + } + } +) + { return ret; } +} + +ExpressionItem boolean_leaf() : +{ + ExpressionItem item = null; +} +{ + + LOOKAHEAD( 3 ) + "(" item = boolean_expression() ")" +| + + { item = ExpressionLeaf.booleanConstant(true); } +| + + { item = ExpressionLeaf.booleanConstant(false); } + + { return item; } +} + +ExpressionItem arithmetic_expression() : +{ + ExpressionItem item = null; +} +{ + LOOKAHEAD( 3 ) + item = arithmetic_leaf() + | + LOOKAHEAD( 3 ) + item = arithmetic_node() + { return item; } +} + +ExpressionItem arithmetic_node() : +{ + ExpressionItem item = null; + ExpressionItem left = null; + ExpressionItem right = null; + OperatorKind op = null; +} +{ + 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() + ) + { + if(right == null) { + item = left; + } else { + item = new ExpressionBinaryOperator(right.getType(), op, false, left, + right); + } + 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() + { + item = ExpressionLeaf.stringConstant(str); + } + { return item; } +} + + + +/* ---------------- existence, occurrences, cardinality ---------------- */ + +/* return true if optional */ +CAttribute.Existence c_existence() : +{ + Interval interval; +} +{ + + interval = occurrence_spec() + + { + if(((Integer) interval.getLower()).intValue() == 1) { + return CAttribute.Existence.REQUIRED; + } + if(((Integer) interval.getUpper()).intValue() == 0) { + return CAttribute.Existence.NOT_ALLOWED; + } else { + return CAttribute.Existence.OPTIONAL; + } + } +} + +Cardinality c_cardinality() : +{ + Cardinality c; +} +{ + + c = cardinality_spec() + + { return c; } +} + +Cardinality cardinality_spec() : +{ + boolean ordered = true; + boolean unique = false; + Interval interval; +} +{ + interval = occurrence_spec() + [ + ";" + ( + [ ";" { unique = true; } ] + | + { ordered = false; } + [ ";" { unique = true; } ] + | + { unique = true; } + [ ";" ( | { ordered = false; } ) ] + ) + ] + { return new Cardinality(ordered, unique, interval); } +} + +Interval c_occurrences() : +{ + Interval i; +} +{ + i = occurrence_spec() + + { return i; } +} + +Interval occurrence_spec() : +{ + Interval i = null; + int num = 0; + Integer lower = null; + Integer upper = null; +} +{ + "*" + { return null; } + | + num = positive_int_value() + { + lower = new Integer(num); + upper = new Integer(num); + } + [ + + ( + num = positive_int_value() + { + upper = new Integer(num); + } + | + "*" + { + upper = null; + } + ) + ] + { return new Interval(lower, upper); } +} + +/* ---------------------- leaf constraint types ----------------------- */ + +CDvOrdinal c_dv_ordinal(String path, CAttribute parent) : +{ + Set list = new LinkedHashSet(); + org.openehr.am.openehrprofile.datatypes.quantity.Ordinal o; + Ordinal defaultValue = null; + int assumed = -1; + Ordinal assumedValue = null; + Interval occurrences = new Interval(1, 1); +} +{ + + o = ordinal() { list.add(o); } + ( + "," o = ordinal() + { list.add(o); } + )* + [ + ";" assumed = integer_value() + { + for(Iterator it = list.iterator(); it.hasNext();) { + Ordinal ord = (Ordinal) it.next(); + if(ord.getValue() == assumed) { + assumedValue = ord; + break; + } + } + } + ] + { + return new CDvOrdinal(path, occurrences, null, parent, list, defaultValue, + assumedValue); + } + | + + { + // any allowed + return new CDvOrdinal(path, occurrences, null, parent, null, null, null); + } +} + +org.openehr.am.openehrprofile.datatypes.quantity.Ordinal ordinal() : +{ + Token t; + int value; + CodePhrase code; +} +{ + value = integer_value() "|" code = code_phrase() + { + return new org.openehr.am.openehrprofile.datatypes.quantity.Ordinal( + value, code); + } +} + +CCodePhrase c_code_phrase(String path, CAttribute parent) : +{ + Token t; + String terminology = null; + TerminologyID terminologyId = null; + List codeList = null; + String assumed = null; + CodePhrase assumedValue = null; + CodePhrase defaultValue = null; // not used + CodePhrase singleValue = null; + Interval occurrences = new Interval(1, 1); +} +{ + ( + t = + { + // remove leading "[" and trailing "::" + terminology = t.image; + terminology = terminology.substring(1, terminology.length() - 2); + terminologyId = new TerminologyID(terminology); + } + [ + t = + { + codeList = new ArrayList(); + codeList.add(t.image); + } + ( + [","] t = { codeList.add(t.image); } + )* + [ + ";" t = + { + assumed = t.image; + assumedValue = new CodePhrase(terminologyId, assumed); + } + ] + ] + "]" + { + // leave lexical state "TERM_CODE" + 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); + } + + +} + +CDvQuantity c_dv_quantity(String path, CAttribute parent) : +{ + CodePhrase property = null; + String terminology = null; + String code = null; + List list = null; + CDvQuantityItem item = null; + Token t = null; + DvQuantity defaultValue = null; + DvQuantity assumedValue = null; + Interval occurrences = new Interval(1, 1); +} +{ + "<" + ( + + "<" property = code_phrase() ">" + + | + + { list = new ArrayList(); } + "<" + ( + item = c_dv_quantity_item() + { list.add(item); } + )+ + ">" + + | + + "<" + assumedValue = dv_quantity() + ">" + + )* + ">" + { + { token_source.SwitchTo(CADL); } + + return new CDvQuantity(path, occurrences, null, parent, list, property, + defaultValue, assumedValue); + } +} + +DvQuantity dv_quantity() : +{ + String units = null; + double magnitude = 0; + int precision = 0; +} +{ + ( + "<" units = string_value() ">" + | + "<" 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_value() "]" "<" + + () "<" + units = string_value() + ">" + + [ + "<" + value = real_interval_value() + ">" + ] + + [ + "<" + precision = integer_interval_value() + ">" + ] + ">" + { + return new CDvQuantityItem(value, precision, units); + } +} + +List string_list() : +{ + List list = new ArrayList(); + String value = null; +} +{ + ( + string_value() + value = string_value() + + { list.add(value); } + )* + + { return list; } +} + +CInteger c_integer() : +{ + int i = 0; + List list = null; + Interval interval = null; + int assumed = 0; + Integer assumedValue = null; +} +{ + ( + LOOKAHEAD( integer_list_value() ) + list = integer_list_value() + | + interval = integer_interval_value() + | + LOOKAHEAD( integer_value() ) + i = integer_value() + | + LOOKAHEAD( occurrence_spec()) + interval = occurrence_spec() + ) + [ ";" assumed = integer_value() + { assumedValue = new Integer(assumed); } + ] + { + if(interval != null) { + return new CInteger(interval, null, assumedValue); + } + List set = new ArrayList(); + if(list != null) { + set.addAll(list); + } else { + set.add(new Integer(i)); + } + return new CInteger(null, set, assumedValue); + } +} + +CReal c_real() : +{ + double d = 0; + List list = null; + double assumed = 0.0; + Double assumedValue = null; + Interval interval = null; +} +{ + ( + LOOKAHEAD( real_list_value() ) + list = real_list_value() + | + interval = real_interval_value() + | + LOOKAHEAD( real_value() ) + d = real_value() + ) + [ + ";" assumed = real_value() + { assumedValue = new Double(assumed); } + ] + { + if(interval != null) { + return new CReal(interval, null, assumedValue); + } + List set = new ArrayList(); + if(list != null) { + set.addAll(list); + } else { + set.add(new Double(d)); + } + return new CReal(null, set, assumedValue); + } +} + +CDate c_date() : +{ + Token t = null; + DvDate date = null; + String pattern = null; + Interval interval = null; + DvDate assumed = null; +} +{ + ( + t = + { pattern = t.image; } + | + date = date_value() + | + interval = date_interval_value() + ) + [ + ";" assumed = date_value() + ] + { + List set = null; + if(date != null) { + set = new ArrayList(); + set.add(date); + } + return new CDate(pattern, interval, set, assumed); + } +} + +CTime c_time() : +{ + Token t = null; + String pattern = null; + DvTime time = null; + Interval interval = null; + DvTime assumed = null; +} +{ + ( + t = + { pattern = t.image; } + | + time = time_value() + | + interval = time_interval_value() + ) + [ + ";" assumed = time_value() + ] + { + List set = null; + if(time != null) { + set = new ArrayList(); + set.add(time); + } + return new CTime(pattern, interval, set, assumed); + } +} + +CDateTime c_date_time() : +{ + Token t = null; + String pattern = null; + DvDateTime datetime = null; + Interval interval = null; + DvDateTime assumed = null; +} +{ + ( + t = + { pattern = t.image; } + | + datetime = date_time_value() + | + interval = date_time_interval_value() + ) + [ + ";" assumed = date_time_value() + ] + { + List set = null; + if(datetime != null) { + set = new ArrayList(); + set.add(datetime); + } + return new CDateTime(pattern, interval, set, assumed); + } +} + +CDuration c_duration() : +{ + DvDuration value = null; + Interval interval = null; + DvDuration assumed = null; + String pattern = null; +} +{ + ( + pattern = duration_pattern() + [ + "/" interval = duration_interval_value() + ] + | + interval = duration_interval_value() + | + value = duration_value() + ) + + [ + ";" assumed = duration_value() + ] + { + return new CDuration(value, interval, assumed, pattern); + } +} + +String duration_pattern() : +{ + Token t = null; +} +{ + t = + { return t.image; } +} + +CString c_string() : +{ + Token t = null; + String value = null; + String pattern = null; + String assumed = null; + List list = null; +} +{ + ( + LOOKAHEAD( string_list_value() ) + list = string_list_value() [ "," ] + | + LOOKAHEAD( string_value() ) + value = string_value() + | + t = + { + String reg = t.image; + pattern = reg.substring(1, reg.length() - 1); + } + ) + [";" assumed = string_value() ] + { + if(pattern != null) { + return new CString(pattern, null, assumed); + } + List set = new ArrayList(); + if(list != null) { + set.addAll(list); + } else if(value != null) { + set.add(value); + } + return new CString(pattern, set, assumed); + } +} + +CBoolean c_boolean() : +{ + boolean trueAllowed = false; + boolean falseAllowed = false; + boolean assumed = false; + boolean hasAssumed = false; +} +{ + ( + { trueAllowed = true; } + [ "," { falseAllowed = true; } ] + | { falseAllowed = true; } + [ "," { trueAllowed = true; } ] + ) + [ + ";" + ( {assumed = true; } | {assumed = false;} ) + { hasAssumed = true; } + ] + { + return new CBoolean(trueAllowed, falseAllowed, assumed, hasAssumed); + } +} + +String constraint_ref() : +{ + Token t; +} +{ + // -- e.g. "[ac0003]" + t = + { + String value = t.image; + return value.substring(1, value.length() - 1); + } +} + +String any_identifier() : +{ + String value; +} +{ + ( value = type_identifier() + | + value = attribute_identifier() + ) + { return value; } +} + +String type_identifier() : +{ + Token t; + String type; +} +{ + t = + { type = t.image; } + [ + "<" t = ">" + { type += "<" + t.image + ">"; } + ] + { return type; } +} + +String attribute_identifier() : +{ + Token t; +} +{ + t = + { return t.image; } +} + + +String absolute_path() : +{ + String path; + StringBuffer buf; + Token t; +} +{ + t = + { return t.image; } +} + +String relative_path() : +{ + StringBuffer buf; + String path; + Token t; +} +{ + ( + t = + | + t = + ) + { return t.image; } +} + +String path_segment() : +{ + Token t; + StringBuffer buf = new StringBuffer(); +} +{ + t = + { buf.append(t.image); } + [ + LOOKAHEAD(2) + t = + { buf.append(t.image); } + ] + { 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 new file mode 100644 index 00000000..f3bff7ca --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeDescriptionTest.java @@ -0,0 +1,124 @@ +package se.acode.openehr.parser; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.openehr.am.archetype.Archetype; +import org.openehr.rm.common.resource.ResourceDescription; +import org.openehr.rm.common.resource.ResourceDescriptionItem; +import org.openehr.rm.datatypes.text.CodePhrase; + +/** + * Testcase for archetype description parsing + * + * @author Rong Chen + * @version 1.0 + */ +public class ArchetypeDescriptionTest extends ParserTestBase { + + /** + * Verifies the content of description instance after parsing + * + * @throws Exception + */ + public void testParseFullArchetypeDescription() throws Exception { + ADLParser parser = new ADLParser( + loadFromClasspath("adl-test-entry.archetype_description.test.adl")); + Archetype archetype = parser.parse(); + ResourceDescription description = archetype.getDescription(); + + assertNotNull("description null", description); + Map originalAuthor = description.getOriginalAuthor(); + assertEquals("name wrong", "Sam Heard", originalAuthor.get("name")); + assertEquals("organisation wrong", "Ocean Informatics", originalAuthor + .get("organisation")); + assertEquals("date wrong", "23/04/2006", originalAuthor.get("date")); + assertEquals("email wrong", "sam.heard@oceaninformatics.biz", + originalAuthor.get("email")); + + List otherContributors = description.getOtherContributors(); + assertNotNull(otherContributors); + assertEquals(1, otherContributors.size()); + assertEquals("Ian McNicoll, MD", otherContributors.get(0)); + + assertEquals("lifecycleState wrong", "AuthorDraft", description + .getLifecycleState()); + + assertEquals("resourcePackageUri", + "www.aihw.org.au/data_sets/diabetic_archetypes.html", + description.getResourcePackageUri()); + + Map map = description.getOtherDetails(); + assertEquals("details 1", map.get("other 1")); + assertEquals("details 2", map.get("other 2")); + + + // TODO: parent_resource + + List details = description.getDetails(); + assertNotNull("details null", details); + assertEquals("details size wrong", 1, details.size()); + + ResourceDescriptionItem item = details.get(0); + assertNotNull("descriptionItem null", item); + CodePhrase language = new CodePhrase("ISO_639-1", "en"); + assertEquals("language wrong", language, item.getLanguage()); + + assertEquals( + "purpose wrong", + "For recording a problem, condition or" + + " issue that has ongoing significance to the person's health.", + item.getPurpose()); + + assertEquals("use wrong", "Used for recording any problem, present or" + + " past - so is used for recording past history as well as " + + "current problems. Used with changed 'Subject of care' for " + + "recording problems of relatives and so for family history.", + item.getUse()); + + assertEquals("misuse wrong", "Use specialisations for medical " + + "diagnoses, 'openEHR-EHR-EVALUATION.problem-diagnosis' and " + + "histological diagnoses 'openEHR-EHR-EVALUATION.problem-" + + "diagnosis-histological'", item.getMisuse()); + + assertEquals("copyright wrong", "copyright (c) 2004 The openEHR " + + "Foundation", item.getCopyright()); + + List keywords = new ArrayList(); + keywords.add("issue"); + keywords.add("condition"); + assertEquals("keywords wrong", keywords, item.getKeywords()); + + map = details.get(0).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(); + assertEquals("item details 1", map.get("item other 1")); + assertEquals("item details 2", map.get("item other 2")); + } + + public void testParseOriginalAuthorAsLast() throws Exception { + ADLParser parser = new ADLParser( + loadFromClasspath("adl-test-entry.archetype_description2.test.adl")); + try { + parser.parse(); + } catch (Exception e) { + e.printStackTrace(); + fail("failed to parse original author as last"); + } + } + + public void testParseEmptyOtherContributors() throws Exception { + ADLParser parser = new ADLParser( + loadFromClasspath("adl-test-entry.empty_other_contributors.test.adl")); + Archetype archetype = parser.parse(); + assertNotNull("failed to parse empty other contributors", archetype); + assertNull("other_contributors not null", archetype.getDescription() + .getOtherContributors()); + } + +} + 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 new file mode 100644 index 00000000..3e6414c9 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeIdentificationTest.java @@ -0,0 +1,52 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.Archetype; + +/** + * MostMinimalADLTest + * + * @author Rong Chen + * @version 1.0 + */ +public class ArchetypeIdentificationTest extends ParserTestBase { + + /** + * Create new test case + * + * @param test + * @throws Exception + */ + public ArchetypeIdentificationTest(String test) throws Exception { + super(test); + } + + public void testParse() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.archetype_identification.test.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + assertEquals("adl_version wrong", "1.4", archetype.getAdlVersion()); + assertEquals("uid wrong", null, archetype.getUid()); + } + + public void testWithUid() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "openEHR-EHR-ELEMENT.uid_test.v1.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + assertEquals("adl_version wrong", "1.4", archetype.getAdlVersion()); + assertEquals("uid wrong", "1.2.456", archetype.getUid().toString()); + } + + public void testWithUidAndControlledFlag() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "openEHR-EHR-ELEMENT.uid_test.v2.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + assertEquals("adl_version wrong", "1.4", archetype.getAdlVersion()); + assertEquals("uid wrong", "1.2.456::22", archetype.getUid().toString()); + assertEquals("controlled flag wrong", false, archetype.isControlled()); + } + +} + 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 new file mode 100644 index 00000000..614c384e --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeInternalRefTest.java @@ -0,0 +1,55 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; +import org.openehr.am.archetype.constraintmodel.ArchetypeInternalRef; +import org.openehr.rm.support.basic.Interval; + +public class ArchetypeInternalRefTest extends ParserTestBase { + public void testParseInternalRefWithOverwrittingOccurrences() + throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.archetype_internal_ref.test.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + + ArchetypeConstraint node = archetype.node("/attribute2"); + assertTrue("ArchetypeInternalRef expected, actual: " + node.getClass(), + node instanceof ArchetypeInternalRef); + + ArchetypeInternalRef ref = (ArchetypeInternalRef) node; + assertEquals("rmType wrong", "SECTION", ref.getRmTypeName()); + assertEquals("path wrong", "/attribute1", ref.getTargetPath()); + + Interval occurrences = new Interval(1, 2); + assertEquals("overwriting occurrences wrong", occurrences, ref + .getOccurrences()); + } + + public void testParseInternalRefWithGenerics() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-SOME_TYPE.generic_type_use_node.draft.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + + ArchetypeConstraint node = archetype.node("/interval_attr2"); + assertTrue("ArchetypeInternalRef expected, actual: " + node.getClass(), + node instanceof ArchetypeInternalRef); + + ArchetypeInternalRef ref = (ArchetypeInternalRef) node; + assertEquals("rmType wrong", "INTERVAL", + ref.getRmTypeName()); + assertEquals("path wrong", "/interval_attr[at0001]", + ref.getTargetPath()); + } + + public void testParseInternalRefWithCommentWithSlashAfterOnlyOneSlashInTarget() + throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.archetype_internal_ref2.test.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + + } + +} 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 new file mode 100644 index 00000000..34b7c2ed --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeLanguageTest.java @@ -0,0 +1,134 @@ +package se.acode.openehr.parser; + +import java.util.Map; + +import org.openehr.am.archetype.Archetype; +import org.openehr.rm.common.resource.TranslationDetails; + +/** + * Testcase for Archetype language section parsing + * + * @author Rong Chen + * @version 1.0 + */ +public class ArchetypeLanguageTest extends ParserTestBase { + + /** + * Create new test case + * + * @param test + * @throws Exception + */ + public ArchetypeLanguageTest(String test) throws Exception { + super(test); + } + + public void testParseLanguageSection() throws Exception { + ADLParser parser = new ADLParser( + loadFromClasspath("adl-test-entry.archetype_language.test.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + + Map translations = archetype + .getTranslations(); + assertNotNull("translations null"); + + TranslationDetails td = translations.get("de"); + assertNotNull("translation de missing", td); + Map map = td.getAuthor(); + assertNotNull("author null", map); + assertEquals("author.name wrong", "Harry Potter", map.get("name")); + assertEquals("author.email wrong", "harry@something.somewhere.co.uk", + map.get("email")); + + assertEquals("acrreditation wrong", + "British Medical Translator id 00400595", td.getAccreditation()); + + map = td.getOtherDetails(); + assertEquals("review 1 wrong", "Ron Weasley", map.get("review 1")); + assertEquals("review 2 wrong", "Rubeus Hagrid", map.get("review 2")); + } + + public void testParseLanguageWithoutAccreditation() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.archetype_language_no_accreditation.test.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + + Map translations = archetype + .getTranslations(); + assertNotNull("translations null"); + + TranslationDetails td = translations.get("de"); + assertNotNull("translation de missing", td); + Map map = td.getAuthor(); + assertNotNull("author null", map); + assertEquals("author.name wrong", "Harry Potter", map.get("name")); + assertEquals("author.email wrong", "harry@something.somewhere.co.uk", + map.get("email")); + + assertEquals("accreditation wrong", null, td.getAccreditation()); + + map = td.getOtherDetails(); + assertEquals("review 1 wrong", "Ron Weasley", map.get("review 1")); + assertEquals("review 2 wrong", "Rubeus Hagrid", map.get("review 2")); + } + + public void testParseLanguageWithAccreditationBeforeLanguage() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.archetype_language_order_of_translation_details.test.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + + Map translations = archetype + .getTranslations(); + assertNotNull("translations null"); + + TranslationDetails td = translations.get("de"); + assertNotNull("translation de missing", td); + Map map = td.getAuthor(); + assertNotNull("author null", map); + assertEquals("author.name wrong", "Harry Potter", map.get("name")); + assertEquals("author.email wrong", "harry@something.somewhere.co.uk", + map.get("email")); + + assertEquals("accreditation wrong", "Seven OWLs at Hogwards", td.getAccreditation()); + assertEquals("language wrong", "de", td.getLanguage().getCodeString()); + map = td.getOtherDetails(); + assertEquals("review 1 wrong", "Ron Weasley", map.get("review 1")); + assertEquals("review 2 wrong", "Rubeus Hagrid", map.get("review 2")); + } + + public void testParseTranslationsLanguageAuthor() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.translations_language_author.test.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + + Map translations = archetype + .getTranslations(); + assertNotNull("translations null"); + + TranslationDetails td = translations.get("de"); + assertNotNull("translation de missing", td); + Map map = td.getAuthor(); + assertNotNull("author null", map); + } + + // test the reverse order of language, author in translations + public void testParseTranslationsAuthorLanguage() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.translations_author_language.test.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + + Map translations = archetype + .getTranslations(); + assertNotNull("translations null"); + + TranslationDetails td = translations.get("de"); + assertNotNull("translation de missing", td); + Map map = td.getAuthor(); + assertNotNull("author null", map); + } +} 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 new file mode 100644 index 00000000..1867ff32 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeOntologyTest.java @@ -0,0 +1,49 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.ontology.*; +import java.util.List; + +public class ArchetypeOntologyTest extends ParserTestBase { + + public void testParseTermDefinition() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.archetype_ontology.test.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + ArchetypeOntology ontology = archetype.getOntology(); + + ArchetypeTerm term = ontology.termDefinition("en", "at0000"); + assertEquals("text wrong", "some text", term.getItem("text")); + assertEquals("comment wrong", "some comment", term.getItem("comment")); + assertEquals("description wrong", "some description", + term.getItem("description")); + } + + /** Tests that term_bindings and constraint_bindings can be written with a tailing s (see http://www.openehr.org/issues/browse/SPEC-284) + */ + public void testBindings() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.archetype_bindings.test.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + ArchetypeOntology ontology = archetype.getOntology(); + List termBindings = ontology.getTermBindingList(); + OntologyBinding termBinding = termBindings.get(0); + assertEquals("term bindings wrong", "SNOMED-CT", termBinding.getTerminology()); + List tbis = termBinding.getBindingList(); + TermBindingItem tbi = (TermBindingItem) tbis.get(0); + assertEquals("term binding item wrong", "[SNOMED-CT::123456]", tbi.getTerms().get(0)); + + List constrBindings = ontology.getConstraintBindingList(); + OntologyBinding constrBinding = constrBindings.get(0); + + assertEquals("binding ontology wrong", "SNOMED-CT", constrBinding.getTerminology()); + List cbis = constrBinding.getBindingList(); + QueryBindingItem qbi = (QueryBindingItem) cbis.get(0); + assertEquals("query binding item wrong", "http://openEHR.org/testconstraintbinding", qbi.getQuery().getUrl()); + + + } + +} 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 new file mode 100644 index 00000000..d93336c3 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeSlotTest.java @@ -0,0 +1,127 @@ +package se.acode.openehr.parser; + +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.ExpressionItem; +import org.openehr.am.archetype.assertion.ExpressionLeaf; +import org.openehr.am.archetype.assertion.ExpressionLeaf.ReferenceType; +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; +import org.openehr.am.archetype.constraintmodel.ArchetypeSlot; +import org.openehr.am.archetype.constraintmodel.primitive.CString; +import org.openehr.rm.support.basic.Interval; + +public class ArchetypeSlotTest extends ParserTestBase { + + /** + * Create new test case + * + * @param test + * @throws Exception + */ + public ArchetypeSlotTest(String test) throws Exception { + super(test); + } + + public void testParseIncludesExcludes() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.archetype_slot.test.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + + ArchetypeConstraint node = archetype.node("/content[at0001]"); + assertTrue("ArchetypeSlot expected", node instanceof ArchetypeSlot); + + ArchetypeSlot slot = (ArchetypeSlot) node; + assertEquals("nodeId wrong", "at0001", slot.getNodeId()); + assertEquals("rmTypeName wrong", "SECTION", slot.getRmTypeName()); + assertEquals("occurrences wrong", new Interval(0, 1), + slot.getOccurrences()); + + assertEquals("path wrong", "/content[at0001]", slot.path()); + + assertEquals("includes total wrong", 1, slot.getIncludes().size()); + assertEquals("Excludes total wrong", 2, slot.getExcludes().size()); + + Assertion assertion = slot.getIncludes().iterator().next(); + + ExpressionItem item = assertion.getExpression(); + + assertTrue("expressionItem type wrong", + item instanceof ExpressionBinaryOperator); + ExpressionBinaryOperator bo = (ExpressionBinaryOperator) item; + ExpressionItem leftOp = bo.getLeftOperand(); + ExpressionItem rightOp = bo.getRightOperand(); + + assertTrue("left operator type wrong", + leftOp instanceof ExpressionLeaf); + ExpressionLeaf left = (ExpressionLeaf) leftOp; + assertEquals("left value wrong", "domain_concept", left.getItem()); + + assertTrue("right operator type wrong", + rightOp instanceof ExpressionLeaf); + ExpressionLeaf right = (ExpressionLeaf) rightOp; + assertTrue("right item type wrong", right.getItem() instanceof CString); + CString cstring = (CString) right.getItem(); + assertEquals("right value wrong", "blood_pressure.v1", + cstring.getPattern()); + } + + public void testParseSingleInclude() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.archetype_slot.test2.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + + ArchetypeConstraint node = archetype.node("/content[at0001]"); + assertTrue("ArchetypeSlot expected", node instanceof ArchetypeSlot); + + ArchetypeSlot slot = (ArchetypeSlot) node; + assertEquals("nodeId wrong", "at0001", slot.getNodeId()); + assertEquals("rmTypeName wrong", "SECTION", slot.getRmTypeName()); + assertEquals("occurrences wrong", new Interval(0, 1), + slot.getOccurrences()); + + assertEquals("path wrong", "/content[at0001]", slot.path()); + + assertEquals("includes total wrong", 1, slot.getIncludes().size()); + + Assertion assertion = slot.getIncludes().iterator().next(); + + ExpressionItem item = assertion.getExpression(); + + assertTrue("expressionItem type wrong", + item instanceof ExpressionBinaryOperator); + ExpressionBinaryOperator bo = (ExpressionBinaryOperator) item; + ExpressionItem leftOp = bo.getLeftOperand(); + ExpressionItem rightOp = bo.getRightOperand(); + + assertTrue("left operator type wrong", + leftOp instanceof ExpressionLeaf); + ExpressionLeaf left = (ExpressionLeaf) leftOp; + assertEquals("left value wrong", "archetype_id/value", left.getItem()); + + assertTrue("right operator type wrong", + rightOp instanceof ExpressionLeaf); + ExpressionLeaf right = (ExpressionLeaf) rightOp; + assertTrue("right item type wrong", right.getItem() instanceof CString); + CString cstring = (CString) right.getItem(); + assertEquals("right value wrong", "openEHR-EHR-CLUSTER\\.device\\.v1", + cstring.getPattern()); + + assertNotNull("stringExpression missing", assertion.getStringExpression()); + String expectedStringExpression = + "archetype_id/value matches {/openEHR-EHR-CLUSTER\\.device\\.v1/}"; + assertEquals("stringExpression wrong, got: " + assertion.getStringExpression(), + expectedStringExpression, assertion.getStringExpression()); + + // "archetype_id/value" refers to a string attribute + assertEquals("Left type inside this archetype slot is wrong", "String", left.getType()); + assertEquals("Left reference type inside this archetype slot is wrong", ReferenceType.ATTRIBUTE, left.getReferenceType() ); + + // Constraint on a C_STRING - I don't think it is really specified if it needs to be C_STRING or CString, but because this is used e.g. for xml-serialisation, it should be consistent across all programming languages, and hence probably not use the Java style here. + assertEquals("Right type inside this archetype slot is wrong", "C_STRING", right.getType()); + assertEquals("Right reference type inside this archetype slot is wrong.", ReferenceType.CONSTRAINT, right.getReferenceType()); + + } +} 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 new file mode 100644 index 00000000..64d3eac1 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeUncommonTermKeysTest.java @@ -0,0 +1,38 @@ +package se.acode.openehr.parser; + +import java.util.*; + +import org.openehr.am.archetype.Archetype; +import org.openehr.rm.common.resource.ResourceDescription; +import org.openehr.rm.common.resource.ResourceDescriptionItem; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.am.archetype.ontology.ArchetypeTerm; + + +/** + * Testcase for uncommon term keys (other than text, description and comment) + * + * @author Sebastian Garde + * @version 1.0 + */ +public class ArchetypeUncommonTermKeysTest extends ParserTestBase { + + /** + * Verifies the content of description instance after parsing + * + * @throws Exception + */ + public void testArchetypeUncommonTerm() throws Exception { + ADLParser parser = new ADLParser( + loadFromClasspath("adl-test-entry.archetype_uncommonkeys.test.adl")); + Archetype archetype = parser.parse(); + ArchetypeTerm aterm = archetype.getOntology().termDefinition("at0000"); + + assertEquals("key value wrong", "another key value", aterm.getItem("anotherkey")); + assertEquals("key value wrong", "test text", aterm.getItem("text")); + assertEquals("key value wrong", "test description", aterm.getItem("description")); + } + + +} + 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 new file mode 100644 index 00000000..c7754be3 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/ArchetypeValidatorTest.java @@ -0,0 +1,47 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.Archetype; + +import java.util.*; + +/** + * Test cases tests archetype validation after parsing. + * + * @author Rong Chen + * @version 1.0 + */ +public class ArchetypeValidatorTest extends ParserTestBase { + + public ArchetypeValidatorTest(String test) { + super(test); + } + + public void setUp() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-car.use_node.test.adl")); + archetype = parser.parse(); + validator = new ArchetypeValidator(archetype); + } + + /** + * Tests validation logic for internal node reference. + * + * @throws Exception + */ + public void testCheckInternalReferences() throws Exception { + Map expected = new HashMap(); + + // wrong target path + expected.put("/wheels[at0005]/parts", + "/engine[at0001]/parts[at0002]"); + + // wrong type + expected.put("/wheels[at0006]/parts", + "/wheels[at0001]/parts[at0002]"); + + assertEquals(expected, validator.checkInternalReferences()); + } + + private Archetype archetype; + private ArchetypeValidator validator; +} 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 new file mode 100644 index 00000000..1faf84ce --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/BasicGenericTypeTest.java @@ -0,0 +1,12 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.Archetype; + +public class BasicGenericTypeTest extends ParserTestBase { + public void testParse() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-SOME_TYPE.generic_type_basic.draft.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + } +} 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 new file mode 100644 index 00000000..5f5545d9 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/BasicTypesTest.java @@ -0,0 +1,578 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.constraintmodel.CAttribute; +import org.openehr.am.archetype.constraintmodel.CComplexObject; +import org.openehr.rm.support.basic.Interval; +import org.openehr.rm.datatypes.quantity.datetime.DvDate; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.quantity.datetime.DvTime; + +import java.util.*; + +/** + * Test case tests parsing basic data types in ADL files. + * + * @author Rong Chen (rong@acode.se) + * @version 1.0 + */ + +public class BasicTypesTest extends ParserTestBase { + + /** + * Create new test case + * + * @param test + * @throws Exception + */ + public BasicTypesTest(String test) throws Exception { + super(test); + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.basic_types.test.adl")); + attributeList = parser.parse().getDefinition().getAttributes(); + } + + /** + * Tests string constraints parsing and verify the resultant constraint + * + * @throws Exception + */ + public void testStringConstraints() throws Exception { + List list = getConstraints(0); + + assertCString(list.get(0), null, new String[] { "something" }, null); + + assertCString(list.get(1), "this|that|something else", null, null); + + assertCString(list.get(2), "cardio.*", null, null); + + assertCString(list.get(3), "mg|mg/ml|mg/g", null, null); + + assertCString(list.get(4), null, new String[] { "apple", "pear" }, null); + + // with assumed values + assertCString(list.get(5), null, new String[] { "something" }, + "nothing"); + + assertCString(list.get(6), "this|that|something else", null, "those"); + + assertCString(list.get(7), "cardio.*", null, "cardio.txt"); + + assertCString(list.get(8), "mg|mg/ml|mg/g", null, "mg"); + + assertCString(list.get(9), null, new String[] { "apple", "pear" }, + "orange"); + + } + + private List getConstraints(int index) { + CAttribute ca = (CAttribute) attributeList.get(index); + return ((CComplexObject) ca.getChildren().get(0)).getAttributes(); + } + + /** + * Tests boolean constraints parsing + * + * @throws Exception + */ + public void testBooleanConstraints() throws Exception { + List list = getConstraints(1); + + assertCBoolean(list.get(0), true, false, false, false); + + assertCBoolean(list.get(1), false, true, false, false); + + assertCBoolean(list.get(2), true, true, false, false); + + // with assumed values + assertCBoolean(list.get(3), true, false, false, true); + + assertCBoolean(list.get(4), false, true, true, true); + + assertCBoolean(list.get(5), true, true, true, true); + } + + /** + * Tests integer constraints parsing + * + * @throws Exception + */ + public void testIntegerConstraints() throws Exception { + List list = getConstraints(2); + + assertCInteger(list.get(0), null, new int[] { 55 }, null); + + assertCInteger(list.get(1), null, new int[] { 10, 20, 30 }, null); + + assertCInteger(list.get(2), new Interval(new Integer(0), + new Integer(100)), null, null); + + assertCInteger(list.get(3), greaterThan(new Integer(10)), null, null); + + assertCInteger(list.get(4), lessThan(new Integer(10)), null, null); + + assertCInteger(list.get(5), greaterEqual(new Integer(10)), null, null); + + assertCInteger(list.get(6), lessEqual(new Integer(10)), null, null); + + assertCInteger(list.get(7), new Interval(new Integer(-10), + new Integer(-5)), null, null); + + // with assumed values + assertCInteger(list.get(8), null, new int[] { 55 }, 50); + + assertCInteger(list.get(9), null, new int[] { 10, 20, 30 }, 20); + + assertCInteger(list.get(10), new Interval(new Integer(0), + new Integer(100)), null, 50); + + assertCInteger(list.get(11), greaterThan(new Integer(10)), null, 20); + + assertCInteger(list.get(12), lessThan(new Integer(10)), null, 5); + + assertCInteger(list.get(13), greaterEqual(new Integer(10)), null, 12); + + assertCInteger(list.get(14), lessEqual(new Integer(10)), null, 8); + + assertCInteger(list.get(15), new Interval(new Integer(-10), + new Integer(-5)), null, -7); + + assertCInteger(list.get(16), new Interval(new Integer(100), + new Integer(100)), null, null); + + // non-inclusive intervals + assertCInteger(list.get(17), new Interval(new Integer(0), + new Integer(100), false, true), null, null); + + assertCInteger(list.get(18), new Interval(new Integer(0), + new Integer(100), true, false), null, null); + + assertCInteger(list.get(19), new Interval(new Integer(0), + new Integer(100), false, false), null, null); + } + + /** + * Tests double constraints parsing + * + * @throws Exception + */ + public void testDoubleConstraints() throws Exception { + List list = getConstraints(3); + + assertCReal(list.get(0), null, new double[] { 100.0 }, null); + + assertCReal(list.get(1), null, new double[] { 10.0, 20.0, 30.0 }, null); + + assertCReal(list.get(2), new Interval(new Double(0.0), + new Double(100.0)), null, null); + + assertCReal(list.get(3), greaterThan(new Double(10.0)), null, null); + + assertCReal(list.get(4), lessThan(new Double(10.0)), null, null); + + assertCReal(list.get(5), greaterEqual(new Double(10.0)), null, null); + + assertCReal(list.get(6), lessEqual(new Double(10.0)), null, null); + + assertCReal(list.get(7), new Interval(new Double(-10.0), + new Double(-5.0)), null, null); + + // with assumed values + assertCReal(list.get(8), null, new double[] { 100.0 }, 80.0); + + assertCReal(list.get(9), null, new double[] { 10.0, 20.0, 30.0 }, 20.0); + + assertCReal(list.get(10), new Interval(new Double(0.0), + new Double(100.0)), null, 60.0); + + assertCReal(list.get(11), greaterThan(new Double(10.0)), null, 30.0); + + assertCReal(list.get(12), lessThan(new Double(10.0)), null, 2.0); + + assertCReal(list.get(13), greaterEqual(new Double(10.0)), null, 10.0); + + assertCReal(list.get(14), lessEqual(new Double(10.0)), null, 9.0); + + assertCReal(list.get(15), new Interval(new Double(-10.0), + new Double(-5.0)), null, -8.0); + + // single value as interval + assertCReal(list.get(16), new Interval(new Double(100.0), + new Double(100.0)), null, null); + + // non-inclusive interval + assertCReal(list.get(17), new Interval(new Double(0.0), + new Double(100.0), false, true), null, null); + + assertCReal(list.get(18), new Interval(new Double(0.0), + new Double(100.0), true, false), null, null); + + assertCReal(list.get(19), new Interval(new Double(0.0), + new Double(100.0), false, false), null, null); + } + + /** + * Tests date and partial date constraints parsing + * + * @throws Exception + */ + public void testDateConstraints() throws Exception { + List list = getConstraints(4); + + assertCDate(list.get(0), "yyyy-mm-dd", null, null, null); + + assertCDate(list.get(1), "yyyy-??-??", null, null, null); + + assertCDate(list.get(2), "yyyy-mm-??", null, null, null); + + assertCDate(list.get(3), "yyyy-??-XX", null, null, null); + + assertCDate(list.get(4), null, null, new String[] { "1983-12-25" }, + null); + + assertCDate(list.get(5), null, null, new String[] { "2000-01-01" }, + null); + + assertCDate(list.get(6), null, new Interval(date("2004-09-20"), + date("2004-10-20")), null, null); + + assertCDate(list.get(7), null, lessThan(date("2004-09-20")), null, + null); + + assertCDate(list.get(8), null, lessEqual(date("2004-09-20")), null, + null); + + assertCDate(list.get(9), null, greaterThan(date("2004-09-20")), null, + null); + + assertCDate(list.get(10), null, greaterEqual(date("2004-09-20")), null, + null); + + // test assumed values + assertCDate(list.get(11), "yyyy-mm-dd", null, null, "2000-01-01"); + + assertCDate(list.get(12), "yyyy-??-??", null, null, "2001-01-01"); + + assertCDate(list.get(13), "yyyy-mm-??", null, null, "2002-01-01"); + + assertCDate(list.get(14), "yyyy-??-XX", null, null, "2003-01-01"); + + assertCDate(list.get(15), null, null, new String[] { "1983-12-25" }, + "2004-01-01"); + + assertCDate(list.get(16), null, null, new String[] { "2000-01-01" }, + "2005-01-01"); + + assertCDate(list.get(17), null, new Interval( + date("2004-09-20"), date("2004-10-20")), null, + "2004-09-30"); + + assertCDate(list.get(18), null, lessThan(date("2004-09-20")), null, + "2004-09-01"); + + assertCDate(list.get(19), null, lessEqual(date("2004-09-20")), null, + "2003-09-20"); + + assertCDate(list.get(20), null, greaterThan(date("2004-09-20")), null, + "2005-01-02"); + + assertCDate(list.get(21), null, greaterEqual(date("2004-09-20")), null, + "2005-10-30"); + } + + /** + * Tests time and partial time constraints parsing + * + * @throws Exception + */ + public void testTimeConstraints() throws Exception { + List list = getConstraints(5); + + assertCTime(list.get(0), "hh:mm:ss", null, null, null); + + assertCTime(list.get(1), "hh:mm:XX", null, null, null); + + assertCTime(list.get(2), "hh:??:XX", null, null, null); + + assertCTime(list.get(3), "hh:??:??", null, null, null); + + assertCTime(list.get(4), null, null, new String[] { "22:00:05" }, + null); + + assertCTime(list.get(5), null, null, new String[] { "00:00:59" }, + null); + + assertCTime(list.get(6), null, null, new String[] { "12:35" }, + null); + + assertCTime(list.get(7), null, null, new String[] { "12:35:45.666" }, + null); + + assertCTime(list.get(8), null, null, new String[] { "12:35:45-0700" }, + null); + + assertCTime(list.get(9), null, null, new String[] { "12:35:45+0800" }, + null); + + assertCTime(list.get(10), null, null, + new String[] { "12:35:45.999-0700" }, null); + + assertCTime(list.get(11), null, null, + new String[] { "12:35:45.000+0800" }, null); + + assertCTime(list.get(12), null, null, + new String[] { "12:35:45.000+0000" }, null); + + assertCTime(list.get(13), null, null, + new String[] { "12:35:45.995-0700" }, null); + + assertCTime(list.get(14), null, null, + new String[] { "12:35:45.001+0800" }, null); + + assertCTime(list.get(15), null, new Interval(time("12:35"), + time("16:35")), null, null); + + assertCTime(list.get(16), null, lessThan(time("12:35")), null, null); + + assertCTime(list.get(17), null, lessEqual(time("12:35")), null, null); + + assertCTime(list.get(18), null, greaterThan(time("12:35")), null, null); + + assertCTime(list.get(19), null, greaterEqual(time("12:35")), null, null); + + } + + /** + * Tests time and partial time constraints parsing + * + * @throws Exception + */ + public void testTimeConstraintsWithAssumedValues() throws Exception { + List list = getConstraints(5); + + assertCTime(list.get(20), "hh:mm:ss", null, null, "10:00:00"); + + assertCTime(list.get(21), "hh:mm:XX", null, null, "10:00:00"); + + assertCTime(list.get(22), "hh:??:XX", null, null, "10:00:00"); + + assertCTime(list.get(23), "hh:??:??", null, null, "10:00:00"); + + assertCTime(list.get(24), null, null, new String[] { "22:00:05" }, + "10:00:00"); + + assertCTime(list.get(25), null, null, new String[] { "00:00:59" }, + "10:00:00"); + + assertCTime(list.get(26), null, null, new String[] { "12:35" }, + "10:00:00"); + + assertCTime(list.get(27), null, null, new String[] { "12:35:45.666" }, + "10:00:00"); + + assertCTime(list.get(28), null, null, new String[] { "12:35:45-0700" }, + "10:00:00"); + + assertCTime(list.get(29), null, null, new String[] { "12:35:45+0800" }, + "10:00:00"); + + assertCTime(list.get(30), null, null, + new String[] { "12:35:45.999-0700" }, "10:00:00"); + + assertCTime(list.get(31), null, null, + new String[] { "12:35:45.000+0800" }, "10:00:00"); + + assertCTime(list.get(32), null, null, + new String[] { "12:35:45.000+0000" }, "10:00:00"); + + assertCTime(list.get(33), null, null, + new String[] { "12:35:45.995-0700" }, "10:00:00"); + + assertCTime(list.get(34), null, null, + new String[] { "12:35:45.001+0800" }, "10:00:00"); + + assertCTime(list.get(35), null, new Interval(time("12:35"), + time("16:35")), null, "10:00:00"); + + assertCTime(list.get(36), null, lessThan(time("12:35")), null, + "10:00:00"); + + assertCTime(list.get(37), null, lessEqual(time("12:35")), null, + "10:00:00"); + + assertCTime(list.get(38), null, greaterThan(time("12:35")), null, + "10:00:00"); + + assertCTime(list.get(39), null, greaterEqual(time("12:35")), null, + "10:00:00"); + } + + /** + * Tests datetime and partial datetime constraints parsing + * + * @throws Exception + */ + public void testDateTimeConstraints() throws Exception { + List list = getConstraints(6); + + assertCDateTime(list.get(0), "yyyy-mm-dd hh:mm:ss", null, null, null); + + assertCDateTime(list.get(1), "yyyy-mm-dd hh:mm:??", null, null, null); + + assertCDateTime(list.get(2), "yyyy-mm-dd hh:mm:XX", null, null, null); + + assertCDateTime(list.get(3), "yyyy-mm-dd hh:??:XX", null, null, null); + + assertCDateTime(list.get(4), "yyyy-??-?? ??:??:??", null, null, null); + + assertCDateTime(list.get(5), null, null, + new String[] { "1983-12-25T22:00:05" }, null); + + assertCDateTime(list.get(6), null, null, + new String[] { "2000-01-01T00:00:59" }, null); + + assertCDateTime(list.get(7), null, null, + new String[] { "2000-01-01T00:00:59" }, null); + + assertCDateTime(list.get(8), null, null, + new String[] { "2000-01-01T00:00:59.105" }, null); + + assertCDateTime(list.get(9), null, null, + new String[] { "2000-01-01T00:00:59+0000" }, null); + + assertCDateTime(list.get(10), null, null, + new String[] { "2000-01-01T00:00:59+1200" }, null); + + assertCDateTime(list.get(11), null, null, + new String[] { "2000-01-01T00:00:59.500+0000" }, null); + + assertCDateTime(list.get(12), null, null, + new String[] { "2000-01-01T00:00:59.500+1200" }, null); + + assertCDateTime(list.get(13), null, null, + new String[] { "2000-01-01T00:00:59.000+0000" }, null); + + assertCDateTime(list.get(14), null, null, + new String[] { "2000-01-01T00:00:59.000+1200" }, null); + + assertCDateTime(list.get(15), null, new Interval( + dateTime("2000-01-01T00:00:00"), + dateTime("2000-01-02T00:00:00")), null, null); + + assertCDateTime(list.get(16), null, + lessThan(dateTime("2000-01-01T00:00:00")), null, null); + + assertCDateTime(list.get(17), null, + lessEqual(dateTime("2000-01-01T00:00:00")), null, null); + + assertCDateTime(list.get(18), null, + greaterThan(dateTime("2000-01-01T00:00:00")), null, null); + + assertCDateTime(list.get(19), null, + greaterEqual(dateTime("2000-01-01T00:00:00")), null, null); + + assertCDateTime(list.get(40), "yyyy-??-??T??:??:??", null, null, null); + } + + /** + * Tests datetime and partial datetime constraints parsing + * + * @throws Exception + */ + public void testDateTimeConstraintsWithAssumedValues() throws Exception { + List list = getConstraints(6); + + assertCDateTime(list.get(20), "yyyy-mm-dd hh:mm:ss", null, null, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(21), "yyyy-mm-dd hh:mm:??", null, null, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(22), "yyyy-mm-dd hh:mm:XX", null, null, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(23), "yyyy-mm-dd hh:??:XX", null, null, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(24), "yyyy-??-?? ??:??:??", null, null, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(25), null, null, + new String[] { "1983-12-25T22:00:05" }, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(26), null, null, + new String[] { "2000-01-01T00:00:59" }, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(27), null, null, + new String[] { "2000-01-01T00:00:59.000" }, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(28), null, null, + new String[] { "2000-01-01T00:00:59.105" }, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(29), null, null, + new String[] { "2000-01-01T00:00:59+0000" }, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(30), null, null, + new String[] { "2000-01-01T00:00:59+1200" }, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(31), null, null, + new String[] { "2000-01-01T00:00:59.500+0000" }, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(32), null, null, + new String[] { "2000-01-01T00:00:59.500+1200" }, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(33), null, null, + new String[] { "2000-01-01T00:00:59.000+0000" }, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(34), null, null, + new String[] { "2000-01-01T00:00:59.000+1200" }, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(35), null, new Interval( + dateTime("2000-01-01T00:00:00"), + dateTime("2000-01-02T00:00:00")), null, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(36), null, + lessThan(dateTime("2000-01-01T00:00:00")), null, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(37), null, + lessEqual(dateTime("2000-01-01T00:00:00")), null, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(38), null, + greaterThan(dateTime("2000-01-01T00:00:00")), null, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(39), null, + greaterEqual(dateTime("2000-01-01T00:00:00")), null, + "2006-03-31T01:12:00"); + } + + private Interval greaterThan(Comparable value) { + return new Interval(value, null, false, false); + } + + private Interval greaterEqual(Comparable value) { + return new Interval(value, null, true, false); + } + + private Interval lessThan(Comparable value) { + return new Interval(null, value, false, false); + } + + private Interval lessEqual(Comparable value) { + return new Interval(null, value, false, true); + } + + private List attributeList; +} 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 new file mode 100644 index 00000000..1502b092 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/CCodePhraseTest.java @@ -0,0 +1,109 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; +import org.openehr.am.archetype.Archetype; +import org.openehr.am.openehrprofile.datatypes.text.CCodePhrase; + +import java.util.*; + +/** + * Test case tests parsing of domain type constraints extension. + * + * @author Rong Chen + * @version 1.0 + */ + +public class CCodePhraseTest extends ParserTestBase { + + public CCodePhraseTest(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_code_phrase.test.adl")); + archetype = parser.parse(); + } + + /** + * The fixture clean up called after every test method. + */ + protected void tearDown() throws Exception { + archetype = null; + node = null; + } + + /** + * Verifies parsing of a simple CCodePhrase + * + * @throws Exception + */ + public void testParseExternalCodes() throws Exception { + node = archetype.node("/types[at0001]/items[at10002]/value"); + String[] codes = { "F43.00", "F43.01", "F32.02" }; + assertCCodePhrase(node, "icd10", codes, null); + } + + public void testParseExternalCodesWithAssumedValue() throws Exception { + node = archetype.node("/types[at0001]/items[at10005]/value"); + String[] codes = { "F43.00", "F43.01", "F32.02" }; + assertCCodePhrase(node, "icd10", codes, "F43.00"); + } + + /** + * Verifies parsing of a simple CCodePhrase with codes defined locally + * + * @throws Exception + */ + public void testParseLocalCodes() throws Exception { + node = archetype.node("/types[at0001]/items[at10003]/value"); + String[] codeList = { "at1311","at1312", "at1313", "at1314","at1315" }; + assertCCodePhrase(node, "local", codeList, null); + } + + public void testParseEmptyCodeList() throws Exception { + node = archetype.node("/types[at0001]/items[at10004]/value"); + String[] codeList = null; + assertCCodePhrase(node, "icd10", codeList, null); + } + + private void assertCCodePhrase(ArchetypeConstraint actual, + String terminologyId, String[] codes, String assumedValue) { + + // check type + assertTrue("CCodePhrase expected, got " + actual.getClass(), + actual instanceof CCodePhrase); + CCodePhrase cCodePhrase = (CCodePhrase) actual; + + // check terminology + assertEquals("terminology", terminologyId, + cCodePhrase.getTerminologyId().getValue()); + + // check code list + if(codes == null) { + assertNull("codeList expected null", cCodePhrase.getCodeList()); + } else { + List codeList = cCodePhrase.getCodeList(); + assertEquals("codes.size wrong", codes.length, codeList.size()); + for (int i = 0; i < codes.length; i++) { + Object c = codeList.get(i); + assertEquals("code wrong, got: " + c, codes[i], c); + } + } + + // check assumed value + if(assumedValue == null) { + assertFalse(cCodePhrase.hasAssumedValue()); + } else { + assertTrue("expected assumedValue", cCodePhrase.hasAssumedValue()); + assertEquals("assumed value wrong", assumedValue, + cCodePhrase.getAssumedValue().getCodeString()); + } + } + + private Archetype archetype; + private ArchetypeConstraint node; +} 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 new file mode 100644 index 00000000..0e1863c2 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/CDurationTest.java @@ -0,0 +1,124 @@ +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 CDurationTest extends ParserTestBase { + + /** + * Create new test case + * + * @param test + * @throws Exception + */ + public CDurationTest() throws Exception { + ADLParser parser = new ADLParser( + loadFromClasspath("adl-test-entry.durations.test.adl")); + archetype = parser.parse(); + } + + /** + * Tests duration constraints parsing + * + * @throws Exception + */ + public void testParseCDuration() throws Exception { + + assertCDuration(archetype.node("/types[at0001]/items[at1001]/value"), + "PT0s", null); + + assertCDuration(archetype.node("/types[at0001]/items[at1002]/value"), + "P1d", null); + + assertCDuration(archetype.node("/types[at0001]/items[at1003]/value"), + "PT2h5m0s", null); + + assertCDuration(archetype.node("/types[at0001]/items[at1004]/value"), + null, + new Interval(DvDuration.getInstance("PT1h55m0s"), + DvDuration.getInstance("PT2h5m0s"))); + + assertCDuration(archetype.node("/types[at0001]/items[at1005]/value"), + null, + new Interval(null, DvDuration.getInstance("PT1h"), + false, true)); + + assertCDuration(archetype.node("/types[at0001]/items[at1006]/value"), + "P1DT1H2M3S", null); + + // bug fix for ISO durationg with weeks + assertCDuration(archetype.node("/types[at0001]/items[at1007]/value"), + "P1W2DT1H2M3S", null); + + // bug fix for ISO duration with months + assertCDuration(archetype.node("/types[at0001]/items[at1008]/value"), + "P3M1W2DT1H2M3S", null); + + // to supported newly added duration pattern + assertCDuration(archetype.node("/types[at0001]/items[at1009]/value"), + null, null, null, "PDTH"); + } + + /** + * Verifies the support for "|PT10M|", single duration interval + */ + public void testParseSingleDurationInverval() throws Exception { + Interval interval = new Interval ( + DvDuration.getInstance("PT10M"), + DvDuration.getInstance("PT10M")); + assertCDuration(archetype.node("/types[at0001]/items[at1010]/value"), + null, interval, null, null); + + // test with assumed value + assertCDuration(archetype.node("/types[at0002]/items[at1010]/value"), + null, interval, "PT12M", null); + } + + /** + * Tests parsing CDurations with assumed values + * + * @throws Exception + */ + public void testParseCDurationWithAssumedValue() throws Exception { + assertCDuration(archetype.node("/types[at0002]/items[at1001]/value"), + "PT0s", null, "P1d"); + + assertCDuration(archetype.node("/types[at0002]/items[at1002]/value"), + "P1d", null, "P1d"); + + assertCDuration(archetype.node("/types[at0002]/items[at1003]/value"), + "PT2h5m0s", null, "P1d"); + + assertCDuration(archetype.node("/types[at0002]/items[at1004]/value"), + null, + new Interval(DvDuration.getInstance("PT1h55m0s"), + DvDuration.getInstance("PT2h5m0s")), "P1d"); + + assertCDuration(archetype.node("/types[at0002]/items[at1005]/value"), + null, + new Interval(null, DvDuration.getInstance("PT1h"), + false, true), "P1d"); + // to supported newly added duration pattern + assertCDuration(archetype.node("/types[at0002]/items[at1006]/value"), + null, null, "P1d", "PDTH"); + } + + /** + * Tests parsing CDurations with assumed values + * + * @throws Exception + */ + public void testParseCDurationWithMixedPatternAndInterval() throws Exception { + Interval interval = new Interval ( + DvDuration.getInstance("PT0S"), + DvDuration.getInstance("PT120S")); + + + assertCDuration(archetype.node("/types[at0001]/items[at1014]/value"), + null, interval, null, "PTS"); + + } + + private Archetype archetype; +} 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 new file mode 100644 index 00000000..3da83dbd --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/CDvOrdinalTest.java @@ -0,0 +1,96 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; +import org.openehr.am.archetype.Archetype; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvOrdinal; +import org.openehr.am.openehrprofile.datatypes.quantity.Ordinal; +import org.openehr.rm.datatypes.text.CodePhrase; + +import java.util.*; + +/** + * Test case tests parsing of domain type constraints extension. + * + * @author Rong Chen + * @version 1.0 + */ + +public class CDvOrdinalTest extends ParserTestBase { + + public CDvOrdinalTest(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_ordinal.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 testCDvOrdinalWithoutAssumedValue() throws Exception { + node = archetype.node("/types[at0001]/items[at10001]/value"); + String[] codes = { + "at0003.0", "at0003.1", "at0003.2", "at0003.3", "at0003.4" + }; + String terminology = "local"; + + assertFalse("unexpected assumed value", + ((CDvOrdinal) node).hasAssumedValue()); + + assertCDvOrdinal(node, terminology, codes, null); + } + + public void testCDvOrdinalWithAssumedValue() throws Exception { + node = archetype.node("/types[at0001]/items[at10002]/value"); + String[] codes = { + "at0003.0", "at0003.1", "at0003.2", "at0003.3", "at0003.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); + } + + public void testEmptyCDvOrdinal() throws Exception { + node = archetype.node("/types[at0001]/items[at10003]/value"); + assertTrue("CDvOrdinal expected", node instanceof CDvOrdinal); + CDvOrdinal cordinal = (CDvOrdinal) node; + assertTrue(cordinal.isAnyAllowed()); + } + + private void assertCDvOrdinal(ArchetypeConstraint node, String terminoloy, + String[] codes, Ordinal assumedValue) { + + assertTrue("CDvOrdinal expected", node instanceof CDvOrdinal); + CDvOrdinal cordinal = (CDvOrdinal) node; + + List codeList = Arrays.asList(codes); + Set 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())); + } + assertEquals("assumedValue wrong", assumedValue, + cordinal.getAssumedValue()); + } + + private Archetype archetype; + private ArchetypeConstraint node; +} 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 new file mode 100644 index 00000000..08e234a1 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/CDvQuantityTest.java @@ -0,0 +1,130 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; +import org.openehr.am.archetype.Archetype; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantity; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantityItem; +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.measurement.*; + +import java.util.*; + +/** + * Test case tests parsing of domain type constraints extension. + * + * @author Rong Chen + * @version 1.0 + */ + +public class CDvQuantityTest extends ParserTestBase { + + /** + * The fixture clean up called after every test method. + */ + protected void tearDown() throws Exception { + archetype = null; + node = null; + } + + public void testParseFullCDvQuantityStartsWithProperty() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.c_dv_quantity_full.test.adl")); + archetype = parser.parse(); + node = archetype.node("/types[at0001]/items[at10005]/value"); + verifyCDvQuantityValue(node); + } + + public void testParseFullCDvQuantityStartsWithList() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.c_dv_quantity_full2.test.adl")); + archetype = parser.parse(); + node = archetype.node("/types[at0001]/items[at10005]/value"); + verifyCDvQuantityValue(node); + } + + public void testParseFullCDvQuantityStartsWithAssumedValue() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.c_dv_quantity_full3.test.adl")); + archetype = parser.parse(); + node = archetype.node( + "/types[at0001]/items[at10005]/value"); + verifyCDvQuantityValue(node); + } + + private void verifyCDvQuantityValue(ArchetypeConstraint node) { + assertTrue("CDvQuantity expected", node instanceof CDvQuantity); + + CDvQuantity cdvquantity = (CDvQuantity) node; + + // verify property + CodePhrase property = cdvquantity.getProperty(); + assertNotNull("property is null", property); + assertEquals("openehr", property.getTerminologyId().name()); + assertEquals("128", property.getCodeString()); + + // verify item list + List list = cdvquantity.getList(); + assertEquals("unexpected size of list", 2, list.size()); + assertCDvQuantityItem(list.get(0), "yr", + new Interval(0.0, 200.0), new Interval(2, 2)); + assertCDvQuantityItem(list.get(1), "mth", + new Interval(1.0, 36.0), new Interval(2, 2)); + + MeasurementService ms = SimpleMeasurementService.getInstance(); + DvQuantity expected = new DvQuantity("yr", 8.0, 2, ms); + assertEquals("assumed value wrong", expected, + cdvquantity.getAssumedValue()); + } + + private void assertCDvQuantityItem(CDvQuantityItem item, String units, + Interval magnitude, Interval precision) { + assertEquals("unexpected units", units, item.getUnits()); + assertEquals("unexpected magnitude interval", magnitude, + item.getMagnitude()); + assertEquals("unexpected precision interval", precision, + item.getPrecision()); + } + + public void testParseCDvQuantityOnlyWithProperty() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.c_dv_quantity_property.test.adl")); + archetype = parser.parse(); + } + + public void testParseCDvQuantityOnlyWithList() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.c_dv_quantity_list.test.adl")); + archetype = parser.parse(); + } + + public void testParseCDvQuantityReversed() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.c_dv_quantity_reversed.test.adl")); + archetype = parser.parse(); + } + + public void testParseCDvQuantityItemWithOnlyUnits() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.c_dv_quantity_item_units_only.test.adl")); + archetype = parser.parse(); + } + + public void testParseEmptyCDvQuantity() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.c_dv_quantity_empty.test.adl")); + archetype = parser.parse(); + node = archetype.node("/types[at0001]/items[at10005]/value"); + assertTrue("CDvQuantity expected", node instanceof CDvQuantity); + + CDvQuantity cdvquantity = (CDvQuantity) node; + assertNull(cdvquantity.getList()); + assertNull(cdvquantity.getProperty()); + assertNull(cdvquantity.getAssumedValue()); + assertTrue(cdvquantity.isAnyAllowed()); + } + + 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 new file mode 100644 index 00000000..99134111 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/ConstraintBindingTest.java @@ -0,0 +1,63 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.ontology.QueryBindingItem; +import org.openehr.am.archetype.ontology.OntologyBinding; + +import java.util.List; + +/** + * TermBindingTest + * + * @author Rong Chen + * @version 1.0 + */ +public class ConstraintBindingTest extends ParserTestBase { + + /** + * Create new test case + * + * @param test + * @throws Exception + */ + public ConstraintBindingTest(String test) throws Exception { + super(test); + } + + /** + * Verifies constraint binding by multiple terminolgies + * + * @throws Exception + */ + public void testConstraintBindingWithMultiTerminologies() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.constraint_binding.test.adl")); + Archetype archetype = parser.parse(); + List list = archetype.getOntology().getConstraintBindingList(); + + assertEquals("unexpected number of onotology binding", 2, list.size()); + + // verify the first constraint binding + OntologyBinding binding = list.get(0); + assertEquals("unexpected binding terminology", "SNOMED_CT", binding.getTerminology()); + + QueryBindingItem item = (QueryBindingItem) binding.getBindingList().get(0); + + assertEquals("unexpected local code", "ac0001", item.getCode()); + assertEquals("exexpected query", + "http://terminology.org?terminology_id=snomed_ct&&has_relation=102002;with_target=128004", + item.getQuery().getUrl()); + + // verify the second constraint binding + binding = list.get(1); + assertEquals("unexpected binding terminology", "ICD10", binding.getTerminology()); + + item = (QueryBindingItem) binding.getBindingList().get(0); + + assertEquals("unexpected local code", "ac0001", item.getCode()); + assertEquals("exexpected query", + "http://terminology.org?terminology_id=icd10&&has_relation=a2;with_target=b19", + item.getQuery().getUrl()); + } +} + 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 new file mode 100644 index 00000000..df96829a --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/ConstraintRefTest.java @@ -0,0 +1,25 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; +import org.openehr.am.archetype.constraintmodel.ConstraintRef; + +public class ConstraintRefTest extends ParserTestBase { + + public void testParseConstraintRef() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.constraint_ref.test.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + + String path = "/content[at0001]/items[at0002]/value/defining_code"; + ArchetypeConstraint node = archetype.node(path); + assertNotNull("node not found at path" + path, node); + + assertTrue("ConstraintRef expected, instead got: " + node.getClass(), + node instanceof ConstraintRef); + + ConstraintRef ref = (ConstraintRef) node; + assertEquals("reference wrong", "ac0001", ref.getReference()); + } +} 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 new file mode 100644 index 00000000..a2f70e42 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/DateTimeTest.java @@ -0,0 +1,403 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.constraintmodel.CAttribute; +import org.openehr.am.archetype.constraintmodel.CComplexObject; +import org.openehr.rm.support.basic.Interval; +import org.openehr.rm.datatypes.quantity.datetime.DvDate; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.quantity.datetime.DvTime; + +import java.util.*; + +/** + * Test case tests parsing of datetime types in ADL files. + * + * @author rong.chen + */ + +public class DateTimeTest extends ParserTestBase { + + /** + * Create new test case + * + * @param test + * @throws Exception + */ + public DateTimeTest(String test) throws Exception { + super(test); + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.datetime.test.adl")); + attributeList = parser.parse().getDefinition().getAttributes(); + } + + private List getConstraints(int index) { + CAttribute ca = (CAttribute) attributeList.get(index); + return ((CComplexObject) ca.getChildren().get(0)).getAttributes(); + } + + /** + * Tests date and partial date constraints parsing + * + * @throws Exception + */ + public void testDateConstraints() throws Exception { + List list = getConstraints(0); + + assertCDate(list.get(0), "yyyy-mm-dd", null, null, null); + + assertCDate(list.get(1), "yyyy-??-??", null, null, null); + + assertCDate(list.get(2), "yyyy-mm-??", null, null, null); + + assertCDate(list.get(3), "yyyy-??-XX", null, null, null); + + assertCDate(list.get(4), null, null, new String[] { "1983-12-25" }, + null); + + assertCDate(list.get(5), null, null, new String[] { "2000-01-01" }, + null); + + assertCDate(list.get(6), null, new Interval(date("2004-09-20"), + date("2004-10-20")), null, null); + + assertCDate(list.get(7), null, lessThan(date("2004-09-20")), null, + null); + + assertCDate(list.get(8), null, lessEqual(date("2004-09-20")), null, + null); + + assertCDate(list.get(9), null, greaterThan(date("2004-09-20")), null, + null); + + assertCDate(list.get(10), null, greaterEqual(date("2004-09-20")), null, + null); + + // test assumed values + assertCDate(list.get(11), "yyyy-mm-dd", null, null, "2000-01-01"); + + assertCDate(list.get(12), "yyyy-??-??", null, null, "2001-01-01"); + + assertCDate(list.get(13), "yyyy-mm-??", null, null, "2002-01-01"); + + assertCDate(list.get(14), "yyyy-??-XX", null, null, "2003-01-01"); + + assertCDate(list.get(15), null, null, new String[] { "1983-12-25" }, + "2004-01-01"); + + assertCDate(list.get(16), null, null, new String[] { "2000-01-01" }, + "2005-01-01"); + + assertCDate(list.get(17), null, new Interval( + date("2004-09-20"), date("2004-10-20")), null, + "2004-09-30"); + + assertCDate(list.get(18), null, lessThan(date("2004-09-20")), null, + "2004-09-01"); + + assertCDate(list.get(19), null, lessEqual(date("2004-09-20")), null, + "2003-09-20"); + + assertCDate(list.get(20), null, greaterThan(date("2004-09-20")), null, + "2005-01-02"); + + assertCDate(list.get(21), null, greaterEqual(date("2004-09-20")), null, + "2005-10-30"); + } + + /** + * Tests time and partial time constraints parsing + * + * @throws Exception + */ + public void testTimeConstraints() throws Exception { + List list = getConstraints(1); + + assertCTime(list.get(0), "hh:mm:ss", null, null, null); + + assertCTime(list.get(1), "hh:mm:XX", null, null, null); + + assertCTime(list.get(2), "hh:??:XX", null, null, null); + + assertCTime(list.get(3), "hh:??:??", null, null, null); + + assertCTime(list.get(4), null, null, new String[] { "22:00:05" }, + null); + + assertCTime(list.get(5), null, null, new String[] { "00:00:59" }, + null); + + assertCTime(list.get(6), null, null, new String[] { "12:35" }, + null); + + assertCTime(list.get(7), null, null, new String[] { "12:35:45.666" }, + null); + + assertCTime(list.get(8), null, null, new String[] { "12:35:45-0700" }, + null); + + assertCTime(list.get(9), null, null, new String[] { "12:35:45+0800" }, + null); + + assertCTime(list.get(10), null, null, + new String[] { "12:35:45.999-0700" }, null); + + assertCTime(list.get(11), null, null, + new String[] { "12:35:45.000+0800" }, null); + + assertCTime(list.get(12), null, null, + new String[] { "12:35:45.000+0000" }, null); + + assertCTime(list.get(13), null, null, + new String[] { "12:35:45.995-0700" }, null); + + assertCTime(list.get(14), null, null, + new String[] { "12:35:45.001+0800" }, null); + + assertCTime(list.get(15), null, new Interval(time("12:35"), + time("16:35")), null, null); + + assertCTime(list.get(16), null, lessThan(time("12:35")), null, null); + + assertCTime(list.get(17), null, lessEqual(time("12:35")), null, null); + + assertCTime(list.get(18), null, greaterThan(time("12:35")), null, null); + + assertCTime(list.get(19), null, greaterEqual(time("12:35")), null, null); + + } + + /** + * Tests time and partial time constraints parsing + * + * @throws Exception + */ + public void testTimeConstraintsWithAssumedValues() throws Exception { + List list = getConstraints(1); + + assertCTime(list.get(20), "hh:mm:ss", null, null, "10:00:00"); + + assertCTime(list.get(21), "hh:mm:XX", null, null, "10:00:00"); + + assertCTime(list.get(22), "hh:??:XX", null, null, "10:00:00"); + + assertCTime(list.get(23), "hh:??:??", null, null, "10:00:00"); + + assertCTime(list.get(24), null, null, new String[] { "22:00:05" }, + "10:00:00"); + + assertCTime(list.get(25), null, null, new String[] { "00:00:59" }, + "10:00:00"); + + assertCTime(list.get(26), null, null, new String[] { "12:35" }, + "10:00:00"); + + assertCTime(list.get(27), null, null, new String[] { "12:35:45.666" }, + "10:00:00"); + + assertCTime(list.get(28), null, null, new String[] { "12:35:45-0700" }, + "10:00:00"); + + assertCTime(list.get(29), null, null, new String[] { "12:35:45+0800" }, + "10:00:00"); + + assertCTime(list.get(30), null, null, + new String[] { "12:35:45.999-0700" }, "10:00:00"); + + assertCTime(list.get(31), null, null, + new String[] { "12:35:45.000+0800" }, "10:00:00"); + + assertCTime(list.get(32), null, null, + new String[] { "12:35:45.000+0000" }, "10:00:00"); + + assertCTime(list.get(33), null, null, + new String[] { "12:35:45.995-0700" }, "10:00:00"); + + assertCTime(list.get(34), null, null, + new String[] { "12:35:45.001+0800" }, "10:00:00"); + + assertCTime(list.get(35), null, new Interval(time("12:35"), + time("16:35")), null, "10:00:00"); + + assertCTime(list.get(36), null, lessThan(time("12:35")), null, + "10:00:00"); + + assertCTime(list.get(37), null, lessEqual(time("12:35")), null, + "10:00:00"); + + assertCTime(list.get(38), null, greaterThan(time("12:35")), null, + "10:00:00"); + + assertCTime(list.get(39), null, greaterEqual(time("12:35")), null, + "10:00:00"); + } + + /** + * Tests datetime and partial datetime constraints parsing + * + * @throws Exception + */ + public void testDateTimeConstraints() throws Exception { + List list = getConstraints(2); + + assertCDateTime(list.get(0), "yyyy-mm-dd hh:mm:ss", null, null, null); + + assertCDateTime(list.get(1), "yyyy-mm-dd hh:mm:??", null, null, null); + + assertCDateTime(list.get(2), "yyyy-mm-dd hh:mm:XX", null, null, null); + + assertCDateTime(list.get(3), "yyyy-mm-dd hh:??:XX", null, null, null); + + assertCDateTime(list.get(4), "yyyy-??-?? ??:??:??", null, null, null); + + assertCDateTime(list.get(5), null, null, + new String[] { "1983-12-25T22:00:05" }, null); + + assertCDateTime(list.get(6), null, null, + new String[] { "2000-01-01T00:00:59" }, null); + + assertCDateTime(list.get(7), null, null, + new String[] { "2000-01-01T00:00:59" }, null); + + assertCDateTime(list.get(8), null, null, + new String[] { "2000-01-01T00:00:59.105" }, null); + + assertCDateTime(list.get(9), null, null, + new String[] { "2000-01-01T00:00:59+0000" }, null); + + assertCDateTime(list.get(10), null, null, + new String[] { "2000-01-01T00:00:59+1200" }, null); + + assertCDateTime(list.get(11), null, null, + new String[] { "2000-01-01T00:00:59.500+0000" }, null); + + assertCDateTime(list.get(12), null, null, + new String[] { "2000-01-01T00:00:59.500+1200" }, null); + + assertCDateTime(list.get(13), null, null, + new String[] { "2000-01-01T00:00:59.000+0000" }, null); + + assertCDateTime(list.get(14), null, null, + new String[] { "2000-01-01T00:00:59.000+1200" }, null); + + assertCDateTime(list.get(15), null, new Interval( + dateTime("2000-01-01T00:00:00"), + dateTime("2000-01-02T00:00:00")), null, null); + + assertCDateTime(list.get(16), null, + lessThan(dateTime("2000-01-01T00:00:00")), null, null); + + assertCDateTime(list.get(17), null, + lessEqual(dateTime("2000-01-01T00:00:00")), null, null); + + assertCDateTime(list.get(18), null, + greaterThan(dateTime("2000-01-01T00:00:00")), null, null); + + assertCDateTime(list.get(19), null, + greaterEqual(dateTime("2000-01-01T00:00:00")), null, null); + + assertCDateTime(list.get(40), "yyyy-??-??T??:??:??", null, null, null); + } + + /** + * Tests datetime and partial datetime constraints parsing + * + * @throws Exception + */ + public void testDateTimeConstraintsWithAssumedValues() throws Exception { + List list = getConstraints(2); + + assertCDateTime(list.get(20), "yyyy-mm-dd hh:mm:ss", null, null, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(21), "yyyy-mm-dd hh:mm:??", null, null, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(22), "yyyy-mm-dd hh:mm:XX", null, null, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(23), "yyyy-mm-dd hh:??:XX", null, null, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(24), "yyyy-??-?? ??:??:??", null, null, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(25), null, null, + new String[] { "1983-12-25T22:00:05" }, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(26), null, null, + new String[] { "2000-01-01T00:00:59" }, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(27), null, null, + new String[] { "2000-01-01T00:00:59.000" }, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(28), null, null, + new String[] { "2000-01-01T00:00:59.105" }, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(29), null, null, + new String[] { "2000-01-01T00:00:59+0000" }, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(30), null, null, + new String[] { "2000-01-01T00:00:59+1200" }, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(31), null, null, + new String[] { "2000-01-01T00:00:59.500+0000" }, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(32), null, null, + new String[] { "2000-01-01T00:00:59.500+1200" }, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(33), null, null, + new String[] { "2000-01-01T00:00:59.000+0000" }, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(34), null, null, + new String[] { "2000-01-01T00:00:59.000+1200" }, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(35), null, new Interval( + dateTime("2000-01-01T00:00:00"), + dateTime("2000-01-02T00:00:00")), null, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(36), null, + lessThan(dateTime("2000-01-01T00:00:00")), null, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(37), null, + lessEqual(dateTime("2000-01-01T00:00:00")), null, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(38), null, + greaterThan(dateTime("2000-01-01T00:00:00")), null, + "2006-03-31T01:12:00"); + + assertCDateTime(list.get(39), null, + greaterEqual(dateTime("2000-01-01T00:00:00")), null, + "2006-03-31T01:12:00"); + } + + private Interval greaterThan(Comparable value) { + return new Interval(value, null, false, false); + } + + private Interval greaterEqual(Comparable value) { + return new Interval(value, null, true, false); + } + + private Interval lessThan(Comparable value) { + return new Interval(null, value, false, false); + } + + private Interval lessEqual(Comparable value) { + return new Interval(null, value, false, true); + } + + private List attributeList; +} 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 new file mode 100644 index 00000000..c6518b5d --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/DvCodedTextTest.java @@ -0,0 +1,23 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; +import org.openehr.am.openehrprofile.datatypes.text.CCodePhrase; + +public class DvCodedTextTest extends ParserTestBase { + + public void testParse() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-composition.dv_coded_text.test.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + + ArchetypeConstraint node = archetype.node("/category/defining_code"); + assertTrue("CCodePhrase expected, but got " + node.getClass(), + node instanceof CCodePhrase); + CCodePhrase ccp = (CCodePhrase) node; + assertEquals("terminologyId wrong", "openehr", + ccp.getTerminologyId().toString()); + assertEquals("codeString wrong", "431", ccp.getCodeList().get(0)); + } +} 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 new file mode 100644 index 00000000..29b4337f --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/EmptyOtherContributorsTest.java @@ -0,0 +1,32 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.Archetype; + +/** + * Testcase verifies parsing of abnormal archetype structures + * to ensure backwards compatibility on 'old' archetypes + * + * @author Rong Chen + * + */ +public class EmptyOtherContributorsTest extends ParserTestBase { + + public EmptyOtherContributorsTest(String test) throws Exception { + super(test); + } + + public void setUp() throws Exception { + + } + + public void testParseEmptyOtherContributors() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.empty_other_contributors.test.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + assertNull("other_contributors not null", + archetype.getDescription().getOtherContributors()); + } + + private Archetype archetype; +} \ No newline at end of file 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 new file mode 100644 index 00000000..c91004b9 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/MissingLanguageTest.java @@ -0,0 +1,25 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.Archetype; + +/** + * Testcase that verifies parser compatibility with archetypes + * that have missing language part + * + * @author Rong Chen + */ +public class MissingLanguageTest extends ParserTestBase { + + public void testMissingLanguageCompatibility() throws Exception { + boolean missingLanguageCompatible = true; + boolean emptyPurposeCompatible = false; + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.missing_language.test.adl"), + missingLanguageCompatible, emptyPurposeCompatible); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + + assertEquals("originalLanguage wrong", "zh", + archetype.getOriginalLanguage().getCodeString()); + } +} 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 new file mode 100644 index 00000000..0c1b6ca0 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/MissingPurposeTest.java @@ -0,0 +1,18 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.Archetype; + +public class MissingPurposeTest extends ParserTestBase { + public void testMissingLanguageCompatibility() throws Exception { + boolean missingLanguageCompatible = false; + boolean emptyPurposeCompatible = true; + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.archetype_desc_missing_purpose.test.adl"), + missingLanguageCompatible, emptyPurposeCompatible); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + + assertNotNull("purpose null", + archetype.getDescription().getDetails().get(0).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 new file mode 100644 index 00000000..ba870444 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/MixedNodeTypesTest.java @@ -0,0 +1,19 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.Archetype; + +public class MixedNodeTypesTest extends ParserTestBase { + + public void testMixedNodeTypes() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.mixed_node_types.draft.adl")); + + try { + Archetype archetype = parser.parse(); + assertNotNull(archetype); + } catch(Exception e) { + e.printStackTrace(); + fail("failed to parse mixed node types"); + } + } +} 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 new file mode 100644 index 00000000..eeca22aa --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/MostMinimalADLTest.java @@ -0,0 +1,35 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.Archetype; + +/** + * MostMinimalADLTest + * + * @author Rong Chen + * @version 1.0 + */ +public class MostMinimalADLTest extends ParserTestBase { + + /** + * Create new test case + * + * @param test + * @throws Exception + */ + public MostMinimalADLTest(String test) throws Exception { + super(test); + } + + public void testParse() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.most_minimal.test.adl")); + Archetype archetype = parser.parse(); + + assertNotNull(archetype); + + assertEquals("originalLanguage wrong", "en", + archetype.getOriginalLanguage().getCodeString()); + + } +} + 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 new file mode 100644 index 00000000..51611527 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/MultiLanguageTest.java @@ -0,0 +1,91 @@ +package se.acode.openehr.parser; + +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.ontology.OntologyDefinitions; +import org.openehr.rm.common.resource.TranslationDetails; + +public class MultiLanguageTest extends ParserTestBase { + + /** + * Create new test case + * + * @param test + * @throws Exception + */ + public MultiLanguageTest(String test) throws Exception { + super(test); + } + + /** + * Verifies term definitions from multiple language + * + * @throws Exception + */ + public void testMultiLanguageTermDefinitions() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.multi_language.test.adl")); + + Archetype archetype = parser.parse(); + List list = + archetype.getOntology().getTermDefinitionsList(); + + assertEquals("expected number of termDefnitionsList", 2, list.size()); + + OntologyDefinitions defs = list.get(0); + assertEquals("unexpected language", "en", defs.getLanguage()); + + defs = list.get(1); + assertEquals("unexpected language", "sv", defs.getLanguage()); + } + + /** + * Verifies constraint definitions from multiple language + * + * @throws Exception + */ + public void testMultiLanguageConstraintDefinitions() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.multi_language.test.adl")); + + Archetype archetype = parser.parse(); + List list = + archetype.getOntology().getConstraintDefinitionsList(); + assertEquals("expected number of constraintDefinitionsList", 2, list.size()); + + OntologyDefinitions defs = list.get(0); + assertEquals("unexpected language", "en", defs.getLanguage()); + + defs = list.get(1); + assertEquals("unexpected language", "sv", defs.getLanguage()); + } + + /** + * Verifies that translation details are parsed correctly if not all optional elements are present. + * + * @throws Exception + */ + public void testTranslationDetails() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.testtranslations.test.adl")); + + Archetype archetype = parser.parse(); + Map translations = archetype.getTranslations(); + + for (Entry translation : translations.entrySet()) { + TranslationDetails transDet = translation.getValue(); + String lang = transDet.getLanguage().getCodeString(); + if (lang.equals("de")) { + assertEquals("wrong accreditation", "test Accreditation!", transDet.getAccreditation()); + assertEquals("wrong organisation", "test organisation", transDet.getAuthor().get("organisation")); + } else if (lang.equals("es")) { + // They need to be null + assertEquals("wrong accreditation", null, transDet.getAccreditation()); + assertEquals("wrong organisation", null, transDet.getAuthor().get("organisation")); + } + } + } +} 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 new file mode 100644 index 00000000..30d891c7 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/ParserTestBase.java @@ -0,0 +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"); +} 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 new file mode 100644 index 00000000..2e30af7d --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/PathTest.java @@ -0,0 +1,114 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.constraintmodel.CComplexObject; +import org.openehr.am.archetype.constraintmodel.CObject; +import org.openehr.am.archetype.constraintmodel.CAttribute; + +/** + * Test case tests archetype path logic. + * + * @author Rong Chen + * @version 1.0 + */ +public class PathTest extends ParserTestBase { + + public PathTest(String test) { + super(test); + } + + public void setUp() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-car.paths.test.adl")); + archetype = parser.parse(); + definition = archetype.getDefinition(); + } + + public void testPath() throws Exception { + + // root path CAR + assertEquals("root", "/", definition.path()); + + // wheels attribute + CAttribute wheels = definition.getAttributes().get(0); + assertEquals("wheels", "/wheels", wheels.path()); + + // first WHEEL node + CObject firstWheel = wheels.getChildren().get(0); + assertEquals("first wheel", "/wheels[at0001]", + firstWheel.path()); + + // description and parts of first WHEEL + CComplexObject firstWheelObj = (CComplexObject) firstWheel; + CAttribute description = firstWheelObj.getAttributes().get(0); + assertEquals("first wheel description", + "/wheels[at0001]/description", description.path()); + CAttribute parts = firstWheelObj.getAttributes().get(1); + assertEquals("first wheel parts", + "/wheels[at0001]/parts", parts.path()); + + // WHEEL_PART node + CObject wheelParts = parts.getChildren().get(0); + assertEquals("wheelPart", "/wheels[at0001]/parts[at0002]", + wheelParts.path()); + + // something and something_else of WHEEL_PART node + CComplexObject wheelPartsObj = (CComplexObject) wheelParts; + assertEquals("something of WHEEL_PART", + "/wheels[at0001]/parts[at0002]/something", + wheelPartsObj.getAttributes().get(0).path()); + + assertEquals("something_else of WHEEL_PART", + "/wheels[at0001]/parts[at0002]/something_else", + wheelPartsObj.getAttributes().get(1).path()); + } + + public void testNodeAtPath() throws Exception { + String[] paths = { + "/", + "/wheels[at0001]", + "/wheels[at0001]/description", + "/wheels[at0001]/parts[at0002]", + "/wheels[at0001]/parts[at0002]/something", + "/wheels[at0001]/parts[at0002]/something_else", + "/wheels[at0003]", + "/wheels[at0003]/description", + "/wheels[at0004]", + "/wheels[at0004]/description", + "/wheels[at0005]", + "/wheels[at0005]/description" + }; + + CAttribute wheels = definition.getAttributes().get(0); + CComplexObject wheel1 = ((CComplexObject) wheels.getChildren().get(0)); + CComplexObject wheel2 = ((CComplexObject) wheels.getChildren().get(1)); + CComplexObject wheel3 = ((CComplexObject) wheels.getChildren().get(2)); + CComplexObject wheel4 = ((CComplexObject) wheels.getChildren().get(3)); + CComplexObject parts = ((CComplexObject) wheel1.getAttributes().get(1) + .getChildren().get(0)); + + + CObject[] nodes = { + definition, + wheel1, + wheel1.getAttributes().get(0).getChildren().get(0), + parts, + parts.getAttributes().get(0).getChildren().get(0), + parts.getAttributes().get(1).getChildren().get(0), + wheel2, + wheel2.getAttributes().get(0).getChildren().get(0), + wheel3, + wheel3.getAttributes().get(0).getChildren().get(0), + wheel4, + wheel4.getAttributes().get(0).getChildren().get(0), + }; + + for(int i = 0; i < paths.length; i++) { + assertEquals("wrong at path: " + paths[i], nodes[i], + archetype.node(paths[i])); + } + } + + private Archetype archetype; + private CComplexObject definition; +} 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 new file mode 100644 index 00000000..2e3fc481 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/RegularExpressionTest.java @@ -0,0 +1,14 @@ +package se.acode.openehr.parser; + +public class RegularExpressionTest extends ParserTestBase { + + public RegularExpressionTest(String test) throws Exception { + super(test); + } + + public void testParseRegularExpressions() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.regular_expression.test.adl")); + assertNotNull(parser.parse().getDefinition()); + } +} 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 new file mode 100644 index 00000000..4f53dfc8 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/SpecialStringTest.java @@ -0,0 +1,33 @@ +package se.acode.openehr.parser; + +import java.util.List; + +import org.openehr.am.archetype.constraintmodel.*; + +public class SpecialStringTest extends ParserTestBase { + + public SpecialStringTest(String test) throws Exception { + super(test); + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.special_string.test.adl")); + attributeList = parser.parse().getDefinition().getAttributes(); + } + + public void testParseEscapedDoubleQuote() throws Exception { + list = getConstraints(0); + assertCString(list.get(0), null, new String[] { "some\"thing" }, null); + } + + public void testParseEscapedBackslash() throws Exception { + list = getConstraints(0); + assertCString(list.get(1), null, new String[] { "any\\thing" }, null); + } + + private List getConstraints(int index) { + CAttribute ca = (CAttribute) attributeList.get(index); + return ((CComplexObject) ca.getChildren().get(0)).getAttributes(); + } + + private List attributeList; + private List list; +} 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 new file mode 100644 index 00000000..19b75981 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/StructureTest.java @@ -0,0 +1,96 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.constraintmodel.*; +import org.openehr.am.archetype.constraintmodel.primitive.CString; +import org.openehr.rm.support.basic.Interval; + +/** + * Test case tests parsing objet structures with archetypes. + * + * @author Rong Chen + * @version 1.0 + */ +public class StructureTest extends ParserTestBase { + + public void setUp() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.structure_test1.test.adl")); + definition = parser.parse().getDefinition(); + } + + public void tearDown() throws Exception { + definition = null; + + } + + public StructureTest(String test) { + super(test); + } + + public void testStructure() throws Exception { + + // root object + CComplexObject obj = definition; + Interval occurrences = new Interval(1, 1); + assertCComplexObject(obj, "ENTRY", "at0000", occurrences, 2); + + // first attribute of root object + CAttribute attr = (CAttribute) obj.getAttributes().get(0); + assertCAttribute(attr, "subject_relationship", 1); + + // 2nd level object + obj = (CComplexObject) attr.getChildren().get(0); + assertCComplexObject(obj, "RELATED_PARTY", null, occurrences, 1); + + // attribute of 2nd level object + attr = (CAttribute) obj.getAttributes().get(0); + assertCAttribute(attr, "relationship", 1); + + // leaf object + obj = (CComplexObject) attr.getChildren().get(0); + assertCComplexObject(obj, "TEXT", null, occurrences, 1); + + // attribute of leaf object + attr = (CAttribute) obj.getAttributes().get(0); + assertCAttribute(attr, "value", 1); + + // primitive constraint of leaf object + CString str = (CString) ((CPrimitiveObject) attr.getChildren().get(0)).getItem(); + assertEquals("pattern", null, str.getPattern()); + assertEquals("set.size", 1, str.getList().size()); + assertTrue("set has", str.getList().contains("self")); + } + + public void testExistenceCardinalityAndOccurrences() throws Exception { + // second attribute of root object + CAttribute attr = (CAttribute) definition.getAttributes().get(1); + Cardinality card = new Cardinality(true, false, interval(0, 8)); + assertCAttribute(attr, "members", CAttribute.Existence.OPTIONAL, card, 2); + + // 1st PERSON + CComplexObject obj = (CComplexObject) attr.getChildren().get(0); + assertCComplexObject(obj, "PERSON", null, interval(1, 1), 1); + + // 2nd PERSON + obj = (CComplexObject) attr.getChildren().get(1); + assertCComplexObject(obj, "PERSON", null, + new Interval(new Integer(0), null, true, false), 1); + } + + public void testParseCommentWithSlashChar() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.structure_test2.test.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + } + + public void testParseCommentWithSlashCharAfterSlot() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "openEHR-EHR-CLUSTER.auscultation.v1.adl")); + Archetype archetype = parser.parse(); + assertNotNull(archetype); + } + + private CComplexObject definition; +} 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 new file mode 100644 index 00000000..db9f24ec --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/TermBindingTest.java @@ -0,0 +1,106 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.ontology.TermBindingItem; +import org.openehr.am.archetype.ontology.OntologyBinding; + +/** + * TermBindingTest + * + * @author Rong Chen + * @version 1.0 + */ +public class TermBindingTest extends ParserTestBase { + + /** + * Create new test case + * + * @param test + * @throws Exception + */ + public TermBindingTest(String test) throws Exception { + super(test); + } + + /** + * Verifies term binding by multiple terminolgies + * + * @throws Exception + */ + public void testTermBindingWithMultiTerminologies() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.term_binding.test.adl")); + Archetype archetype = parser.parse(); + + // verify the first term binding + OntologyBinding binding = archetype.getOntology().getTermBindingList().get(0); + assertEquals("wrong binding terminology", "SNOMED_CT", binding.getTerminology()); + + TermBindingItem item = (TermBindingItem) binding.getBindingList().get(0); + + assertEquals("wrong local code", "at0000", item.getCode()); + assertEquals("wrong terms size", 1, item.getTerms().size()); + assertEquals("wrong term", "[snomed_ct::1000339]", item.getTerms().get(0)); + + // verify the second term binding + binding = archetype.getOntology().getTermBindingList().get(1); + assertEquals("wrong binding terminology", "ICD10", binding.getTerminology()); + + item = (TermBindingItem) binding.getBindingList().get(0); + + assertEquals("wrong local code", "at0000", item.getCode()); + assertEquals("wrong terms size", 2, item.getTerms().size()); + assertEquals("wrong 1st term", "[icd10::1000]", item.getTerms().get(0)); + assertEquals("wrong 2nd term", "[icd10::1001]", item.getTerms().get(1)); + } + + public void testPathBasedBinding() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.term_binding2.test.adl")); + Archetype archetype = parser.parse(); + + OntologyBinding binding = archetype.getOntology().getTermBindingList().get(0); + assertEquals("wrong binding terminology", "LNC205", binding.getTerminology()); + + TermBindingItem item = (TermBindingItem) binding.getBindingList().get(0); + + assertEquals("wrong local code path", + "/data[at0002]/events[at0003]/data[at0001]/item[at0004]", + item.getCode()); + assertEquals("wrong terms size", 1, item.getTerms().size()); + assertEquals("wrong term", "[LNC205::8310-5]", item.getTerms().get(0)); + + } + + public void testPathBasedBindingWithinInternalReference() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "openEHR-EHR-OBSERVATION.test_internal_ref_binding.v1.adl")); + Archetype archetype = parser.parse(); + + OntologyBinding binding = archetype.getOntology().getTermBindingList().get(0); + assertEquals("wrong binding terminology", "DDB00", binding.getTerminology()); + + + TermBindingItem item1 = (TermBindingItem) binding.getBindingList().get(0); + assertEquals("wrong terms size", 1, item1.getTerms().size()); + + assertEquals("wrong local code path", + "/data[at0001]/events[at0002]/data[at0003]/items[at0004]", + item1.getCode()); + assertEquals("wrong term", "[DDB00::12345]", item1.getTerms().get(0)); + + TermBindingItem item2 = (TermBindingItem) binding.getBindingList().get(1); + assertEquals("wrong terms size", 1, item2.getTerms().size()); + + assertEquals("wrong local code path", + "/data[at0001]/events[at0005]/data[at0003]/items[at0004]", + item2.getCode()); + assertEquals("wrong term", "[DDB00::98765]", item2.getTerms().get(0)); + + assertTrue(archetype.physicalPaths().contains("/data[at0001]/events[at0002]/data[at0003]/items[at0004]")); + assertTrue(archetype.physicalPaths().contains("/data[at0001]/events[at0005]/data[at0003]/items[at0004]")); // path within an archetype internal ref. Must be included in the physical paths! + assertFalse(archetype.physicalPaths().contains("/data[at0001]/events[at9999]/data[at0003]/items[at0004]")); + + } +} + 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 new file mode 100644 index 00000000..6060bf84 --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/UnicodeBOMSupportTest.java @@ -0,0 +1,54 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.ontology.ArchetypeTerm; + +/** + * This test case verifies that the parser supports the optional BOM (Byte Order Mark) of UTF-8. +* This BOM is introduced by many Windows based Texteditors and not treated correctly by Java without extra help. + * + * It parses an ADL file (UTF-8 with BOM encoded) to ascertain that it is parsable. + * + * @author Sebastian Garde + * @author Rong Chen + * @version 1.0 + */ +public class UnicodeBOMSupportTest extends ParserTestBase { + + /** + * Create new test case + * + * @param test + * @throws Exception + */ + public UnicodeBOMSupportTest(String test) throws Exception { + super(test); + } + + /** + * Tests parsing of Chinese text in the ADL file + * + * @throws Exception + */ + public void testParsingWithUTF8Encoding() throws Exception { + try { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.unicode_BOM_support.test.adl"), "UTF-8"); + parser.parse(); + + } catch(Throwable t) { + fail("failed to parse BOM with UTF8 encoding.."); + } + } + + public void testParsingWithoutUTF8Encoding() throws Exception { + try { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.unicode_BOM_support.test.adl"), "ISO-8859-1"); + parser.parse(); + + } catch(Throwable t) { + fail("failed to parse BOM without UTF8 encoding.."); + } + } +} 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 new file mode 100644 index 00000000..d3613d2d --- /dev/null +++ b/adl-parser/src/test/java/se/acode/openehr/parser/UnicodeSupportTest.java @@ -0,0 +1,78 @@ +package se.acode.openehr.parser; + +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.ontology.ArchetypeTerm; + +/** + * This test case verifies the unicode support of the parser. + * + * It parses an ADL file which contains Chinese and Swedish text + * encoded in UTF-8, then compare these text with pre-defined unicode + * escaped text strings in the code to check if they get parsed correctly. + * + * @author Rong Chen + * @version 1.0 + */ +public class UnicodeSupportTest extends ParserTestBase { + + /** + * Create new test case + * + * @param test + * @throws Exception + */ + public UnicodeSupportTest(String test) throws Exception { + super(test); + } + + public void setUp() throws Exception { + ADLParser parser = new ADLParser(loadFromClasspath( + "adl-test-entry.unicode_support.test.adl"), "UTF-8"); + archetype = parser.parse(); + } + + public void tearDown() { + archetype = null; + } + + public void testParse() { + assertNotNull("parsing failed", archetype); + } + + /** + * Tests parsing of Chinese text in the ADL file + * + * @throws Exception + */ + public void testParsingWithChineseText() throws Exception { + ArchetypeTerm term = archetype.getOntology().termDefinition("zh", "at0000"); + assertNotNull("definition in zh not found", term); + + // "\u6982\u5ff5" is "concept" in Chinese in escaped unicode format + assertEquals("concept text wrong", "\u6982\u5ff5", term.getItem("text")); + + // "\u63cf\u8ff0" is "description" in Chinese in escaped unicode format + assertEquals("concept description wrong", "\u63cf\u8ff0", + term.getItem("description")); + } + + /** + * Tests parsing of Swedish text in the ADL file + * + * @throws Exception + */ + public void testParsingWithSwedishText() throws Exception { + ArchetypeTerm term = archetype.getOntology().termDefinition("sv", "at0000"); + assertNotNull("definition in sv not found", term); + + // "spr\u00e5k" is "language" in Swedish in escaped unicode format + assertEquals("concept text wrong", "spr\u00e5k", term.getItem("text")); + + // "Hj\u00e4lp" is "help" in Swedish in escaped unicode format + assertEquals("concept description wrong", "Hj\u00e4lp", + term.getItem("description")); + } + + private Archetype archetype; + +} 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 new file mode 100644 index 00000000..20775e62 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-SOME_TYPE.generic_type_basic.draft.adl @@ -0,0 +1,56 @@ +archetype (adl_version=1.4) + adl-test-SOME_TYPE.generic_type_basic.draft + +concept + [at0000] -- root item +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"Thomas Beale"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"Illustrates the use of generic types"> + keywords = <"ADL", "test"> + copyright = <"copyright (c) 2006 The openEHR Foundation"> + > + > + lifecycle_state = <"draft"> + +definition + SOME_TYPE[at0000] matches { -- root item + interval_attr matches { + INTERVAL matches { + lower matches { + QUANTITY matches { + property matches {"temperature"} + unit matches {"C"} + magnitude matches {|>= 37.0|} + } + } + upper matches { + QUANTITY matches { + property matches {"temperature"} + unit matches {"C"} + magnitude matches {|>= 39.0|} + } + } + lower_included matches {True} + upper_included matches {True} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + description = <"xxxx"> + text = <"root item"> + > + > + > + > 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 new file mode 100644 index 00000000..021d89f1 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-SOME_TYPE.generic_type_use_node.draft.adl @@ -0,0 +1,63 @@ +archetype (adl_version=1.4) + adl-test-SOME_TYPE.generic_type_basic.draft + +concept + [at0000] -- root item +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"Thomas Beale"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"Illustrates the use of generic types"> + keywords = <"ADL", "test"> + copyright = <"copyright (c) 2006 The openEHR Foundation"> + > + > + lifecycle_state = <"draft"> + +definition + SOME_TYPE[at0000] matches { -- root item + interval_attr matches { + INTERVAL[at0001] matches { -- interval of quantities + lower matches { + QUANTITY matches { + property matches {"temperature"} + unit matches {"C"} + magnitude matches {|>= 37.0|} + } + } + upper matches { + QUANTITY matches { + property matches {"temperature"} + unit matches {"C"} + magnitude matches {|>= 39.0|} + } + } + lower_included matches {True} + upper_included matches {True} + } + } + interval_attr2 matches { + use_node INTERVAL /interval_attr[at0001] + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + description = <"xxxx"> + text = <"root item"> + > + ["at0001"] = < + description = <"interval"> + text = <"interval of quantities"> + > + > + > + > 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 new file mode 100644 index 00000000..b09d7c4f --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-car.paths.test.adl @@ -0,0 +1,80 @@ +archetype + adl-test-CAR.user_node.draft +concept + [at0000] -- car + +language + original_language = <[ISO_639-1::en]> + +definition + CAR [at0000] matches { + wheels matches { + WHEEL[at0001] matches { + description matches {"front left hand wheel"} + parts matches { + WHEEL_PART[at0002] matches { + something matches {"etc"} + something_else matches {"etc"} + } + } + } + WHEEL[at0003] matches { + description matches {"front right hand wheel"} + parts matches { + use_node WHEEL_PART /wheels[at0001]/parts[at0002] -- will pass + } + } + WHEEL[at0004] matches { + description matches {"rear left hand wheel"} + parts matches { + use_node WHEEL_PART /wheels[at0001]/parts[at0002] -- will pass + } + } + WHEEL[at0005] matches { + description matches {"rear right hand wheel"} + parts matches { + use_node WHEEL_PART /engine[at0001]/parts[at0002] -- will fail + } + } + } + } + + +ontology + primary_language = <"en"> + + languages_available = <"en", ...> + + terminologies_available = <"en", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"car">; + description = <"car"> + > + ["at0001"] = < + text = <"front left hand wheel">; + description = <"front left hand wheel"> + > + ["at0002"] = < + text = <"wheel part">; + description = <"wheel part"> + > + ["at0003"] = < + text = <"front right hand wheel">; + description = <"front right hand wheel"> + > + ["at0004"] = < + text = <"rear left hand wheel">; + description = <"rear left hand wheel"> + > + ["at0005"] = < + text = <"rear right hand wheel">; + description = <"rear right hand wheel"> + > + > + > + > + \ No newline at end of file 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 new file mode 100644 index 00000000..18d568a7 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-car.use_node.test.adl @@ -0,0 +1,87 @@ +archetype + adl-test-CAR.paths.draft +concept + [at0000] -- car + +language + original_language = <[ISO_639-1::en]> + +definition + CAR [at0000] matches { + wheels matches { + WHEEL[at0001] matches { + description matches {"front left hand wheel"} + parts matches { + WHEEL_PART[at0002] matches { + something matches {"etc"} + something_else matches {"etc"} + } + } + } + WHEEL[at0003] matches { + description matches {"front right hand wheel"} + parts matches { + use_node WHEEL_PART /wheels[at0001]/parts[at0002] -- will pass + } + } + WHEEL[at0004] matches { + description matches {"rear left hand wheel"} + parts matches { + use_node WHEEL_PART /wheels[at0001]/parts[at0002] -- will pass + } + } + WHEEL[at0005] matches { + description matches {"rear right hand wheel"} + parts matches { + use_node WHEEL_PART /engine[at0001]/parts[at0002] -- will fail, wrong target path + } + } + WHEEL[at0006] matches { + description matches {"rear right hand wheel"} + parts matches { + use_node WHEEL /wheels[at0001]/parts[at0002] -- will fail, wrong type + } + } + } + } + + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + terminologies_available = <"en", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"car">; + description = <"car"> + > + ["at0001"] = < + text = <"front left hand wheel">; + description = <"front left hand wheel"> + > + ["at0002"] = < + text = <"wheel part">; + description = <"wheel part"> + > + ["at0003"] = < + text = <"front right hand wheel">; + description = <"front right hand wheel"> + > + ["at0004"] = < + text = <"rear left hand wheel">; + description = <"rear left hand wheel"> + > + ["at0005"] = < + text = <"rear right hand wheel">; + description = <"rear right hand wheel"> + > + ["at0006"] = < + text = <"rear right hand wheel">; + description = <"rear right hand wheel"> + > + > + > + > 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 new file mode 100644 index 00000000..60b683b8 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-composition.dv_coded_text.test.adl @@ -0,0 +1,29 @@ +archetype (adl_version=1.4) + openEHR-EHR-COMPOSITION.dv_coded_text.test + +concept + [at0000] -- Problem list + +language + original_language = <[ISO_639-1::en]> + +definition + COMPOSITION[at0000] matches { -- Problem list + category matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::431]} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + description = <"A list of the ongoing health problems of this person."> + text = <"Problem list"> + > + > + > + > 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 new file mode 100644 index 00000000..b86cd472 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.archetype_bindings.test.adl @@ -0,0 +1,47 @@ +archetype + adl-test-entry.archetype_language_order_of_translation_details.test + +concept + [at0000] -- test + +language + original_language = <[ISO_639-1::en]> +definition + ENTRY[at0000] matches {*} + +ontology + terminologies_available = <"SNOMED-CT", ...> + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test">; + description = <"test"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0001"] = < + text = <"test constraint"> + description = <"*"> + > + > + > + > + term_bindings = < + ["SNOMED-CT"] = < + items = < + ["at0002"] = <[SNOMED-CT::123456]> + > + > + > + constraint_bindings = < + ["SNOMED-CT"] = < + items = < + ["ac0001"] = + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..166a7f4c --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.archetype_desc_missing_purpose.test.adl @@ -0,0 +1,45 @@ +archetype + adl-test-ENTRY.archetype_description_missing_purpose.draft + +concept + [at0000] -- test + +language + original_language = <[ISO_639-1::en]> + +description + original_author = < + ["name"] = <"Sam Heard"> + ["organisation"] = <"Ocean Informatics"> + ["date"] = <"23/04/2006"> + ["email"] = <"sam.heard@oceaninformatics.biz"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + use = <"Used for recording any problem, present or past - so is used for recording past history as well as current problems. Used with changed 'Subject of care' for recording problems of relatives and so for family history."> + keywords = <"issue", "condition"> + misuse = <"Use specialisations for medical diagnoses, 'openEHR-EHR-EVALUATION.problem-diagnosis' and histological diagnoses 'openEHR-EHR-EVALUATION.problem-diagnosis-histological'"> + copyright = <"copyright (c) 2004 The openEHR Foundation"> + > + > + lifecycle_state = <"AuthorDraft"> + resource_package_uri = <"www.aihw.org.au/data_sets/diabetic_archetypes.html"> + +definition + ENTRY[at0000] matches {*} + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test">; + description = <"test"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..55916576 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.archetype_description.test.adl @@ -0,0 +1,61 @@ +archetype + adl-test-ENTRY.archetype_description.draft + +concept + [at0000] -- test + +language + original_language = <[ISO_639-1::en]> + +description + original_author = < + ["name"] = <"Sam Heard"> + ["organisation"] = <"Ocean Informatics"> + ["date"] = <"23/04/2006"> + ["email"] = <"sam.heard@oceaninformatics.biz"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"For recording a problem, condition or issue that has ongoing significance to the person's health."> + use = <"Used for recording any problem, present or past - so is used for recording past history as well as current problems. Used with changed 'Subject of care' for recording problems of relatives and so for family history."> + keywords = <"issue", "condition"> + misuse = <"Use specialisations for medical diagnoses, 'openEHR-EHR-EVALUATION.problem-diagnosis' and histological diagnoses 'openEHR-EHR-EVALUATION.problem-diagnosis-histological'"> + copyright = <"copyright (c) 2004 The openEHR Foundation"> + original_resource_uri = < + ["ligne guide"] = <"http://guidelines.are.us/wherever/fr"> + ["medline"] = <"http://some%20medline%20ref"> + > + other_details = < + ["item other 1"] = <"item details 1"> + ["item other 2"] = <"item details 2"> + > + > + > + lifecycle_state = <"AuthorDraft"> + resource_package_uri = <"www.aihw.org.au/data_sets/diabetic_archetypes.html"> + other_contributors = < + ["1"] = <"Ian McNicoll, MD"> + > + other_details = < + ["other 1"] = <"details 1"> + ["other 2"] = <"details 2"> + > + +definition + ENTRY[at0000] matches {*} + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test"> + description = <"test"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..42c80889 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.archetype_description2.test.adl @@ -0,0 +1,45 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.body_mass_index.v1 + +concept + [at0000] -- Body mass index + +language + original_language = <[ISO_639-1::en]> + +description + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"To record the body mass index. This is index is calculated by dividing the weight in kg by the height in metres squared."> + use = <"To record BMI"> + keywords = <"obesity", "index"> + misuse = <""> + > + > + lifecycle_state = <"Initial"> + other_contributors = <> + original_author = < + ["name"] = <"Sam Heard"> + ["organisation"] = <"Ocean Informatics"> + ["date"] = <"22/03/2006"> + ["email"] = <"sam.heard@oceaninformatics.biz"> + > + +definition + ENTRY[at0000] matches {*} + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test">; + description = <"test"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..cbf1aa57 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.archetype_identification.test.adl @@ -0,0 +1,26 @@ +archetype (adl_version=1.4) + adl-test-ENTRY.archetype_identification.draft + +concept + [at0000] -- test + +language + original_language = <[ISO_639-1::en]> + +definition + ENTRY[at0000] matches {*} + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test">; + description = <"test"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..c7bc6d86 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.archetype_internal_ref.test.adl @@ -0,0 +1,40 @@ +archetype + adl-test-entry.archetype_internal_ref.test + +concept + [at0000] + +language + original_language = <[ISO_639-1::en]> + +definition + Entry[at0000] matches { -- Encounter + attribute1 matches { + SECTION[at0001] occurrences matches {0..1} matches {*} + } + attribute2 matches { + use_node SECTION occurrences matches {1..2} /attribute1 + } + attribute3 matches { + 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 + primary_language = <"en"> + languages_available = <"en", ...> + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test composition">; + description = <"test composition"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..f4b097ab --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.archetype_internal_ref2.test.adl @@ -0,0 +1,36 @@ +archetype + adl-test-entry.archetype_internal_ref.test + +concept + [at0000] + +language + original_language = <[ISO_639-1::en]> + +definition + Entry[at0000] matches { -- Encounter + attribute1 matches { + SECTION[at0001] occurrences matches {0..1} matches {*} + } + attribute2 matches { + use_node SECTION occurrences matches {1..2} /attribute1 -- /test withslash in comment after use node + } + attribute3 matches { + use_node COMPLEX_OBJECT /items[at0001] + use_node COMPLEX_OBJECT /items[at0002] + } + } + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test composition">; + description = <"test composition"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..ea5a289e --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.archetype_language.test.adl @@ -0,0 +1,47 @@ +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"> + > + > + > + > \ 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 new file mode 100644 index 00000000..7f4716cb --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.archetype_language_no_accreditation.test.adl @@ -0,0 +1,38 @@ +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"> + > + other_details = < + ["review 1"] = <"Ron Weasley"> + ["review 2"] = <"Rubeus Hagrid"> + > + > + > +definition + ENTRY[at0000] matches {*} + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test">; + description = <"test"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..8862c592 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.archetype_language_order_of_translation_details.test.adl @@ -0,0 +1,40 @@ +archetype + adl-test-entry.archetype_language_order_of_translation_details.test + +concept + [at0000] -- test + +language + original_language = <[ISO_639-1::en]> + translations = < + ["de"] = < + + author = < + ["name"] = <"Harry Potter"> + ["email"] = <"harry@something.somewhere.co.uk"> + > + accreditation = <"Seven OWLs at Hogwards"> + other_details = < + ["review 1"] = <"Ron Weasley"> + ["review 2"] = <"Rubeus Hagrid"> + > + language = <[ISO_639-1::de]> + > + > +definition + ENTRY[at0000] matches {*} + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test">; + description = <"test"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..e29ad0a7 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.archetype_ontology.test.adl @@ -0,0 +1,25 @@ +archetype + adl-test-ENTRY.archetype_ontology.draft +concept + [at0000] -- empty definition test +language + original_language = <[ISO_639-1::en]> + +definition + ENTRY[at0000] matches {*} + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"some text">; + description = <"some description"> + comment = <"some comment"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..903d8cc7 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.archetype_slot.test.adl @@ -0,0 +1,40 @@ +archetype + adl-test-entry.archetype_slot.test + +concept + [at0000] + +language + original_language = <[ISO_639-1::en]> + +definition + Entry[at0000] matches { -- Encounter + content matches { + allow_archetype SECTION [at0001] occurrences matches {0..1} matches { + include + domain_concept matches {/blood_pressure.v1/} + exclude + domain_concept matches {/blood_pressure.v2/} + domain_concept matches {/.*/} + } + } + } + + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test composition">; + description = <"test composition"> + > + ["at0001"] = < + text = <"slot">; + description = <"slot"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..e1b2a20f --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.archetype_slot.test2.adl @@ -0,0 +1,37 @@ +archetype + adl-test-entry.archetype_slot.test + +concept + [at0000] + +language + original_language = <[ISO_639-1::en]> + +definition + Entry[at0000] matches { -- Encounter + content matches { + allow_archetype SECTION [at0001] occurrences matches {0..1} matches { + include + archetype_id/value matches {/openEHR-EHR-CLUSTER\.device\.v1/} + } + } + } + + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test composition">; + description = <"test composition"> + > + ["at0001"] = < + text = <"slot">; + description = <"slot"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..a000680e --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.archetype_uncommonkeys.test.adl @@ -0,0 +1,29 @@ +archetype (adl_version=1.4) + adl-test-ENTRY.archetype_uncommonkeys.v1 + +concept + [at0000] -- test + +language + original_language = <[ISO_639-1::en]> + +definition + ENTRY[at0000] matches {*} + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test text">; + description = <"test description"> + anotherkey = <"another key value"> + status = <"status value"> + revision = <"revision value"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..99500647 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.basic_types.test.adl @@ -0,0 +1,275 @@ +archetype + adl-test-ENTRY.test.draft + +concept + [at0000] -- basic data types test 1 + +language + original_language = <[ISO_639-1::en]> + +definition + ENTRY[at0000] matches { + string_attributes matches { + LIST matches { + string_attr1 matches {"something"} + string_attr2 matches {/this|that|something else/} + string_attr3 matches {/cardio.*/} + string_attr4 matches {^mg|mg/ml|mg/g^} + string_attr5 matches {"apple","pear"} + + + -- with assumed values + string_attr6 matches {"something"; "nothing"} + string_attr7 matches {/this|that|something else/; "those"} + string_attr8 matches {/cardio.*/; "cardio.txt"} + string_attr9 matches {^mg|mg/ml|mg/g^; "mg"} + string_attr10 matches {"apple","pear"; "orange"} + + string_attr5 matches {"apple","pear","grape"} + } + } + boolean_attributes matches { + LIST matches { + boolean_attr1 matches {True} + boolean_attr2 matches {False} + boolean_attr3 matches {True, False} + + -- with assumed values + boolean_attr4 matches {True; False} + boolean_attr5 matches {False; True} + boolean_attr6 matches {True, False; True} + } + } + integer_attributes matches { + LIST matches { + integer_attr1 matches {55} + integer_attr2 matches {10, 20, 30} + integer_attr3 matches {|0..100|} + integer_attr4 matches {|>10|} + integer_attr5 matches {|<10|} + integer_attr6 matches {|>=10|} + integer_attr7 matches {|<=10|} + integer_attr8 matches {|-10..-5|} + -- integer_attr9 matches {|100 +/-2|} -- not yet supported + + -- with assumed values + integer_attr10 matches {55; 50} + integer_attr11 matches {10, 20, 30; 20} + integer_attr12 matches {|0..100|; 50} + integer_attr13 matches {|>10|; 20} + integer_attr14 matches {|<10|; 5} + integer_attr15 matches {|>=10|; 12} + integer_attr16 matches {|<=10|; 8} + integer_attr17 matches {|-10..-5|; -7} + + -- single value as interval + integer_attr18 matches {|100|} + + -- non-inclusive interval + integer_attr19 matches {|>0..100|} + integer_attr20 matches {|0..<100|} + integer_attr21 matches {|>0..<100|} + + } + } + real_attributes matches { + LIST matches { + real_attr1 matches {100.0} + real_attr2 matches {10.0, 20.0, 30.0} + real_attr3 matches {|0.0..100.0|} + real_attr4 matches {|>10.0|} + real_attr5 matches {|<10.0|} + real_attr6 matches {|>=10.0|} + real_attr7 matches {|<=10.0|} + real_attr8 matches {|-10.0..-5.0|} + -- real_attr9 matches {|80.0 +/-12.0|} -- not yet supported + + -- with assumed value + real_attr10 matches {100.0; 80.0} + real_attr11 matches {10.0, 20.0, 30.0; 20.0} + real_attr12 matches {|0.0..100.0|; 60.0} + real_attr13 matches {|>10.0|; 30.0} + real_attr14 matches {|<10.0|; 2.0} + real_attr15 matches {|>=10.0|; 10.0} + real_attr16 matches {|<=10.0|; 9.0} + real_attr17 matches {|-10.0..-5.0|; -8.0} + + -- single value as interval + real_attr18 matches {|100.0|} + + -- non-inclusive interval + real_attr19 matches {|>0.0..100.0|} + real_attr20 matches {|0.0..<100.0|} + real_attr21 matches {|>0.0..<100.0|} + } + } + date_attributes matches { + LIST matches { + date_attr1 matches {yyyy-mm-dd} + date_attr2 matches {yyyy-??-??} + date_attr3 matches {yyyy-mm-??} + date_attr4 matches {yyyy-??-XX} + date_attr5 matches {1983-12-25} + date_attr6 matches {2000-01-01} + + date_attr7 matches {|2004-09-20..2004-10-20|} + date_attr8 matches {|< 2004-09-20|} + date_attr9 matches {|<= 2004-09-20|} + date_attr10 matches {|> 2004-09-20|} + date_attr11 matches {|>= 2004-09-20|} + + -- date_attr12 matches {2001-12-25, ...} -- Not currently in ADL syntax + + -- with assumed values + date_attr13 matches {yyyy-mm-dd; 2000-01-01} + date_attr14 matches {yyyy-??-??; 2001-01-01} + date_attr15 matches {yyyy-mm-??; 2002-01-01} + date_attr16 matches {yyyy-??-XX; 2003-01-01} + date_attr17 matches {1983-12-25; 2004-01-01} + date_attr18 matches {2000-01-01; 2005-01-01} + + date_attr19 matches {|2004-09-20..2004-10-20|; 2004-09-30} + date_attr20 matches {|< 2004-09-20|; 2004-09-01} + date_attr21 matches {|<= 2004-09-20|; 2003-09-20} + date_attr22 matches {|> 2004-09-20|; 2005-01-02} + date_attr23 matches {|>= 2004-09-20|; 2005-10-30} + + -- single value as interval + date_attr24 matches {|2004-09-20|} + + date_attr25 matches {1995-03} + } + } + time_attributes matches { + LIST matches { + time_attr1 matches {hh:mm:ss} + time_attr2 matches {hh:mm:XX} + time_attr3 matches {hh:??:XX} + time_attr4 matches {hh:??:??} + time_attr5 matches {22:00:05} + time_attr6 matches {00:00:59} + + time_attr7 matches {12:35} + time_attr8 matches {12:35:45,666} + time_attr9 matches {12:35:45-0700} + time_attr10 matches {12:35:45+0800} + time_attr11 matches {12:35:45,999-0700} + time_attr12 matches {12:35:45,000+0800} + time_attr13 matches {12:35:45,000Z} + time_attr14 matches {12:35:45,995-0700} + time_attr15 matches {12:35:45,001+0800} + + time_attr16 matches {|12:35..16:35|} + time_attr17 matches {|< 12:35|} + time_attr18 matches {|<= 12:35|} + time_attr19 matches {|> 12:35|} + time_attr20 matches {|>= 12:35|} + + -- with assumed values + time_attr21 matches {hh:mm:ss; 10:00:00} + time_attr22 matches {hh:mm:XX; 10:00:00} + time_attr23 matches {hh:??:XX; 10:00:00} + time_attr24 matches {hh:??:??; 10:00:00} + time_attr25 matches {22:00:05; 10:00:00} + time_attr26 matches {00:00:59; 10:00:00} + + time_attr27 matches {12:35; 10:00:00} + time_attr28 matches {12:35:45,666; 10:00:00} + time_attr29 matches {12:35:45-0700; 10:00:00} + time_attr30 matches {12:35:45+0800; 10:00:00} + time_attr31 matches {12:35:45,999-0700; 10:00:00} + time_attr32 matches {12:35:45,000+0800; 10:00:00} + time_attr33 matches {12:35:45,000Z; 10:00:00} + time_attr34 matches {12:35:45,995-0700; 10:00:00} + time_attr35 matches {12:35:45,001+0800; 10:00:00} + + time_attr36 matches {|12:35..16:35|; 10:00:00} + time_attr37 matches {|< 12:35|; 10:00:00} + time_attr38 matches {|<= 12:35|; 10:00:00} + time_attr39 matches {|> 12:35|; 10:00:00} + time_attr40 matches {|>= 12:35|; 10:00:00} + + -- single value as interval + time_attr41 matches {|12:35|} + + -- time_attr7 matches {64:02:25, ...} -- Not currently in ADL syntax + + time_attr6 matches {00:00:59,0} + } + } + date_time_attributes matches { + LIST matches { + date_time_attr1 matches {yyyy-mm-dd hh:mm:ss} + date_time_attr2 matches {yyyy-mm-dd hh:mm:??} + date_time_attr3 matches {yyyy-mm-dd hh:mm:XX} + date_time_attr4 matches {yyyy-mm-dd hh:??:XX} + date_time_attr5 matches {yyyy-??-?? ??:??:??} + date_time_attr6 matches {1983-12-25T22:00:05} + date_time_attr7 matches {2000-01-01T00:00:59} + + date_time_attr8 matches {2000-01-01T00:00:59} + date_time_attr9 matches {2000-01-01T00:00:59,105} + date_time_attr10 matches {2000-01-01T00:00:59Z} + date_time_attr11 matches {2000-01-01T00:00:59+1200} + date_time_attr12 matches {2000-01-01T00:00:59,500Z} + date_time_attr13 matches {2000-01-01T00:00:59,500+1200} + date_time_attr14 matches {2000-01-01T00:00:59,000Z} + date_time_attr15 matches {2000-01-01T00:00:59,000+1200} + + date_time_attr16 matches {|2000-01-01T00:00:00..2000-01-02T00:00:00|} + date_time_attr17 matches {|< 2000-01-01T00:00:00|} + date_time_attr18 matches {|<= 2000-01-01T00:00:00|} + date_time_attr19 matches {|> 2000-01-01T00:00:00|} + date_time_attr20 matches {|>= 2000-01-01T00:00:00|} + + -- date_time_attr8 matches {2000-12-25T00:00:59, ...} -- Not currently in ADL syntax + + -- with assumed values + date_time_attr1 matches {yyyy-mm-dd hh:mm:ss; 2006-03-31T01:12:00} + date_time_attr2 matches {yyyy-mm-dd hh:mm:??; 2006-03-31T01:12:00} + date_time_attr3 matches {yyyy-mm-dd hh:mm:XX; 2006-03-31T01:12:00} + date_time_attr4 matches {yyyy-mm-dd hh:??:XX; 2006-03-31T01:12:00} + date_time_attr5 matches {yyyy-??-?? ??:??:??; 2006-03-31T01:12:00} + date_time_attr6 matches {1983-12-25T22:00:05; 2006-03-31T01:12:00} + date_time_attr7 matches {2000-01-01T00:00:59; 2006-03-31T01:12:00} + + date_time_attr8 matches {2000-01-01T00:00:59,000; 2006-03-31T01:12:00} + date_time_attr9 matches {2000-01-01T00:00:59,105; 2006-03-31T01:12:00} + date_time_attr10 matches {2000-01-01T00:00:59Z; 2006-03-31T01:12:00} + date_time_attr11 matches {2000-01-01T00:00:59+1200; 2006-03-31T01:12:00} + date_time_attr12 matches {2000-01-01T00:00:59,500Z; 2006-03-31T01:12:00} + date_time_attr13 matches {2000-01-01T00:00:59,500+1200; 2006-03-31T01:12:00} + date_time_attr14 matches {2000-01-01T00:00:59,000Z; 2006-03-31T01:12:00} + date_time_attr15 matches {2000-01-01T00:00:59,000+1200; 2006-03-31T01:12:00} + + date_time_attr16 matches {|2000-01-01T00:00:00..2000-01-02T00:00:00|; 2006-03-31T01:12:00} + date_time_attr17 matches {|< 2000-01-01T00:00:00|; 2006-03-31T01:12:00} + date_time_attr18 matches {|<= 2000-01-01T00:00:00|; 2006-03-31T01:12:00} + date_time_attr19 matches {|> 2000-01-01T00:00:00|; 2006-03-31T01:12:00} + date_time_attr20 matches {|>= 2000-01-01T00:00:00|; 2006-03-31T01:12:00} + + -- newly supported pattern with "T" in the middle + date_time_attr21 matches {yyyy-??-??T??:??:??} + + -- single value as interval + date_time_attr22 matches {|2000-01-01T00:00:00|} + + --time_attr6 matches {|00:00:59,0|} + } + } + } +ontology + primary_language = <"en"> + languages_available = <"en", ...> + terminologies_available = <"adl_test", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test entry">; + description = <"test entry"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..5ca30c08 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.c_code_phrase.test.adl @@ -0,0 +1,77 @@ +archetype + adl-test-ENTRY.c_code_phrase.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[at10002] matches { -- code_phrase + value matches { + [icd10:: + F43.00, -- acute stress reaction, mild + F43.01, -- acute stress reaction, moderate + F32.02] -- acute stress reaction, severe + } + } + ELEMENT[at10003] matches { -- code_phrase + value matches { + [local:: + at1311, -- Colo-colonic anastomosis + at1312, -- Ileo-colonic anastomosis + at1313, -- Colo-anal anastomosis + at1314, -- Ileo-anal anastomosis + at1315] -- Colostomy + } + } + ELEMENT[at10004] matches { -- code_phrase + value matches { + [icd10::] -- empty code list + } + } + ELEMENT[at10005] matches { -- with assumed value + value matches { + [icd10:: + F43.00, -- acute stress reaction, mild + F43.01, -- acute stress reaction, moderate + F32.02; -- acute stress reaction, severe + F43.00] -- assumed value + } + } + ELEMENT[at10006] matches { -- code_phrase + value matches { + [openehr::431] -- single code + } + } + } + } + } + } + +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"> + > + ["at0002"] = < + text = <"*"> + description = <"*"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..1c2761fd --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.c_dv_ordinal.test.adl @@ -0,0 +1,66 @@ +archetype + adl-test-ENTRY.c_dv_ordinal.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 { -- ordinal + value matches { + 0|[local::at0003.0], -- capsule + 1|[local::at0003.1], -- powder + 2|[local::at0003.2], -- tablet + 3|[local::at0003.3], -- solution + 4|[local::at0003.4] -- suspension + } + } + ELEMENT[at10002] matches { -- ordinal 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|[local::at0003.4]; -- suspension + 0 -- assumed value + } + } + ELEMENT[at10003] matches { -- ordinal with assumed value + value matches { -- any allowed + C_DV_ORDINAL < + > + } + } + + } + } + } + } + +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_ordinal"> + description = <"c_dv_ordinal node"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..d0e4c844 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_empty.test.adl @@ -0,0 +1,46 @@ +archetype + adl-test-ENTRY.c_dv_quantity_empty.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[at10005] matches { -- c_quantity + value matches { + C_DV_QUANTITY < + > + } + } + } + } + } + } + +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"> + > + ["at10005"] = < + text = <"c_quantity"> + description = <"c_quantity node"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..9ab6bc10 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_full.test.adl @@ -0,0 +1,64 @@ +archetype + adl-test-ENTRY.c_dv_quantity.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[at10005] matches { -- c_quantity + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"yr"> + magnitude = <|0.0..200.0|> + precision = <|2|> + > + ["2"] = < + units = <"mth"> + magnitude = <|1.0..36.0|> + precision = <|2|> + > + > + assumed_value = < + units = <"yr"> + magnitude = <8.0> + precision = <2> + > + > + } + } + } + } + } + } + +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"> + > + ["at10005"] = < + text = <"c_quantity"> + description = <"c_quantity node"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..fe1e8a1d --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_full2.test.adl @@ -0,0 +1,64 @@ +archetype + adl-test-ENTRY.c_dv_quantity.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[at10005] matches { -- c_quantity + value matches { + C_DV_QUANTITY < + list = < + ["1"] = < + units = <"yr"> + magnitude = <|0.0..200.0|> + precision = <|2|> + > + ["2"] = < + units = <"mth"> + magnitude = <|1.0..36.0|> + precision = <|2|> + > + > + property = <[openehr::128]> + assumed_value = < + units = <"yr"> + magnitude = <8.0> + precision = <2> + > + > + } + } + } + } + } + } + +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"> + > + ["at10005"] = < + text = <"c_quantity"> + description = <"c_quantity node"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..e9b2eeea --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_full3.test.adl @@ -0,0 +1,64 @@ +archetype + adl-test-ENTRY.c_dv_quantity.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[at10005] matches { -- c_quantity + value matches { + C_DV_QUANTITY < + assumed_value = < + units = <"yr"> + magnitude = <8.0> + precision = <2> + > + property = <[openehr::128]> + list = < + ["1"] = < + units = <"yr"> + magnitude = <|0.0..200.0|> + precision = <|2|> + > + ["2"] = < + units = <"mth"> + magnitude = <|1.0..36.0|> + precision = <|2|> + > + > + > + } + } + } + } + } + } + +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"> + > + ["at10005"] = < + text = <"c_quantity"> + description = <"c_quantity node"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..871163a2 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_item_units_only.test.adl @@ -0,0 +1,55 @@ +archetype + adl-test-ENTRY.c_dv_quantity.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[at10005] matches { -- c_quantity + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"yr"> + > + ["2"] = < + units = <"mth"> + > + > + > + } + } + } + } + } + } + +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"> + > + ["at10005"] = < + text = <"c_quantity"> + description = <"c_quantity node"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..8a8c5707 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_list.test.adl @@ -0,0 +1,58 @@ +archetype + adl-test-ENTRY.c_dv_quantity.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[at10005] matches { -- c_quantity + value matches { + C_DV_QUANTITY < + list = < + ["1"] = < + units = <"yr"> + magnitude = <|0.0..200.0|> + precision = <|2|> + > + ["2"] = < + units = <"mth"> + magnitude = <|1.0..36.0|> + precision = <|2|> + > + > + > + } + } + } + } + } + } + +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"> + > + ["at10005"] = < + text = <"c_quantity"> + description = <"c_quantity node"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..cb469167 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_property.test.adl @@ -0,0 +1,47 @@ +archetype + adl-test-ENTRY.c_dv_quantity.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[at10005] matches { -- c_quantity + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + > + } + } + } + } + } + } + +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"> + > + ["at10005"] = < + text = <"c_quantity"> + description = <"c_quantity node"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..2997cf29 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.c_dv_quantity_reversed.test.adl @@ -0,0 +1,59 @@ +archetype + adl-test-ENTRY.c_dv_quantity.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[at10005] matches { -- c_quantity + value matches { + C_DV_QUANTITY < + list = < + ["1"] = < + units = <"yr"> + magnitude = <|0.0..200.0|> + precision = <|2|> + > + ["2"] = < + units = <"mth"> + magnitude = <|1.0..36.0|> + precision = <|2|> + > + > + property = <[openehr::128]> + > + } + } + } + } + } + } + +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"> + > + ["at10005"] = < + text = <"c_quantity"> + description = <"c_quantity 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 new file mode 100644 index 00000000..22986e5f --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.constraint_binding.test.adl @@ -0,0 +1,37 @@ +archetype + adl-test-ENTRY.constraint_binding.draft +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ENTRY[at0000] matches {*} + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + constraint_binding = < + ["SNOMED_CT"] = < + items = < + ["ac0001"] = + > + > + ["ICD10"] = < + items = < + ["ac0001"] = + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..4da160c7 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.constraint_ref.test.adl @@ -0,0 +1,43 @@ +archetype + adl-test-ENTRY.c_code_phrase.test + +concept + [at0000] + +language + original_language = <[ISO_639-1::en]> + +definition + ENTRY[at0000] matches { + content matches { + LIST[at0001] matches { + items cardinality matches {0..*} matches { + ELEMENT[at0002] matches { + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0001]} + } + } + } + } + } + } + } + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test"> + description = <"desc"> + > + ["at0001"] = < + text = <"text"> + description = <"desc"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..a52de729 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.datetime.test.adl @@ -0,0 +1,183 @@ +archetype + adl-test-ENTRY.test.draft + +concept + [at0000] -- basic data types test 1 + +language + original_language = <[ISO_639-1::en]> + +definition + ENTRY[at0000] matches { + date_attributes matches { + LIST matches { + date_attr1 matches {yyyy-mm-dd} + date_attr2 matches {yyyy-??-??} + date_attr3 matches {yyyy-mm-??} + date_attr4 matches {yyyy-??-XX} + date_attr5 matches {1983-12-25} + date_attr6 matches {2000-01-01} + + date_attr7 matches {|2004-09-20..2004-10-20|} + date_attr8 matches {|< 2004-09-20|} + date_attr9 matches {|<= 2004-09-20|} + date_attr10 matches {|> 2004-09-20|} + date_attr11 matches {|>= 2004-09-20|} + + -- date_attr12 matches {2001-12-25, ...} -- Not currently in ADL syntax + + -- with assumed values + date_attr13 matches {yyyy-mm-dd; 2000-01-01} + date_attr14 matches {yyyy-??-??; 2001-01-01} + date_attr15 matches {yyyy-mm-??; 2002-01-01} + date_attr16 matches {yyyy-??-XX; 2003-01-01} + date_attr17 matches {1983-12-25; 2004-01-01} + date_attr18 matches {2000-01-01; 2005-01-01} + + date_attr19 matches {|2004-09-20..2004-10-20|; 2004-09-30} + date_attr20 matches {|< 2004-09-20|; 2004-09-01} + date_attr21 matches {|<= 2004-09-20|; 2003-09-20} + date_attr22 matches {|> 2004-09-20|; 2005-01-02} + date_attr23 matches {|>= 2004-09-20|; 2005-10-30} + + -- single value as interval + date_attr24 matches {|2004-09-20|} + } + } + time_attributes matches { + LIST matches { + time_attr1 matches {hh:mm:ss} + time_attr2 matches {hh:mm:XX} + time_attr3 matches {hh:??:XX} + time_attr4 matches {hh:??:??} + time_attr5 matches {22:00:05} + time_attr6 matches {00:00:59} + + time_attr7 matches {12:35} + time_attr8 matches {12:35:45,666} + time_attr9 matches {12:35:45-0700} + time_attr10 matches {12:35:45+0800} + time_attr11 matches {12:35:45,999-0700} + time_attr12 matches {12:35:45,000+0800} + time_attr13 matches {12:35:45,000Z} + time_attr14 matches {12:35:45,995-0700} + time_attr15 matches {12:35:45,001+0800} + + time_attr16 matches {|12:35..16:35|} + time_attr17 matches {|< 12:35|} + time_attr18 matches {|<= 12:35|} + time_attr19 matches {|> 12:35|} + time_attr20 matches {|>= 12:35|} + + -- with assumed values + time_attr21 matches {hh:mm:ss; 10:00:00} + time_attr22 matches {hh:mm:XX; 10:00:00} + time_attr23 matches {hh:??:XX; 10:00:00} + time_attr24 matches {hh:??:??; 10:00:00} + time_attr25 matches {22:00:05; 10:00:00} + time_attr26 matches {00:00:59; 10:00:00} + + time_attr27 matches {12:35; 10:00:00} + time_attr28 matches {12:35:45,666; 10:00:00} + time_attr29 matches {12:35:45-0700; 10:00:00} + time_attr30 matches {12:35:45+0800; 10:00:00} + time_attr31 matches {12:35:45,999-0700; 10:00:00} + time_attr32 matches {12:35:45,000+0800; 10:00:00} + time_attr33 matches {12:35:45,000Z; 10:00:00} + time_attr34 matches {12:35:45,995-0700; 10:00:00} + time_attr35 matches {12:35:45,001+0800; 10:00:00} + + time_attr36 matches {|12:35..16:35|; 10:00:00} + time_attr37 matches {|< 12:35|; 10:00:00} + time_attr38 matches {|<= 12:35|; 10:00:00} + time_attr39 matches {|> 12:35|; 10:00:00} + time_attr40 matches {|>= 12:35|; 10:00:00} + + -- single value as interval + time_attr41 matches {|12:35|} + + -- time_attr7 matches {64:02:25, ...} -- Not currently in ADL syntax + + time_attr6 matches {00:00:59,0} + } + } + date_time_attributes matches { + LIST matches { + date_time_attr1 matches {yyyy-mm-dd hh:mm:ss} + date_time_attr2 matches {yyyy-mm-dd hh:mm:??} + date_time_attr3 matches {yyyy-mm-dd hh:mm:XX} + date_time_attr4 matches {yyyy-mm-dd hh:??:XX} + date_time_attr5 matches {yyyy-??-?? ??:??:??} + date_time_attr6 matches {1983-12-25T22:00:05} + date_time_attr7 matches {2000-01-01T00:00:59} + + date_time_attr8 matches {2000-01-01T00:00:59} + date_time_attr9 matches {2000-01-01T00:00:59,105} + date_time_attr10 matches {2000-01-01T00:00:59Z} + date_time_attr11 matches {2000-01-01T00:00:59+1200} + date_time_attr12 matches {2000-01-01T00:00:59,500Z} + date_time_attr13 matches {2000-01-01T00:00:59,500+1200} + date_time_attr14 matches {2000-01-01T00:00:59,000Z} + date_time_attr15 matches {2000-01-01T00:00:59,000+1200} + + date_time_attr16 matches {|2000-01-01T00:00:00..2000-01-02T00:00:00|} + date_time_attr17 matches {|< 2000-01-01T00:00:00|} + date_time_attr18 matches {|<= 2000-01-01T00:00:00|} + date_time_attr19 matches {|> 2000-01-01T00:00:00|} + date_time_attr20 matches {|>= 2000-01-01T00:00:00|} + + -- date_time_attr8 matches {2000-12-25T00:00:59, ...} -- Not currently in ADL syntax + + -- with assumed values + date_time_attr1 matches {yyyy-mm-dd hh:mm:ss; 2006-03-31T01:12:00} + date_time_attr2 matches {yyyy-mm-dd hh:mm:??; 2006-03-31T01:12:00} + date_time_attr3 matches {yyyy-mm-dd hh:mm:XX; 2006-03-31T01:12:00} + date_time_attr4 matches {yyyy-mm-dd hh:??:XX; 2006-03-31T01:12:00} + date_time_attr5 matches {yyyy-??-?? ??:??:??; 2006-03-31T01:12:00} + date_time_attr6 matches {1983-12-25T22:00:05; 2006-03-31T01:12:00} + date_time_attr7 matches {2000-01-01T00:00:59; 2006-03-31T01:12:00} + + date_time_attr8 matches {2000-01-01T00:00:59,000; 2006-03-31T01:12:00} + date_time_attr9 matches {2000-01-01T00:00:59,105; 2006-03-31T01:12:00} + date_time_attr10 matches {2000-01-01T00:00:59Z; 2006-03-31T01:12:00} + date_time_attr11 matches {2000-01-01T00:00:59+1200; 2006-03-31T01:12:00} + date_time_attr12 matches {2000-01-01T00:00:59,500Z; 2006-03-31T01:12:00} + date_time_attr13 matches {2000-01-01T00:00:59,500+1200; 2006-03-31T01:12:00} + date_time_attr14 matches {2000-01-01T00:00:59,000Z; 2006-03-31T01:12:00} + date_time_attr15 matches {2000-01-01T00:00:59,000+1200; 2006-03-31T01:12:00} + + date_time_attr16 matches {|2000-01-01T00:00:00..2000-01-02T00:00:00|; 2006-03-31T01:12:00} + date_time_attr17 matches {|< 2000-01-01T00:00:00|; 2006-03-31T01:12:00} + date_time_attr18 matches {|<= 2000-01-01T00:00:00|; 2006-03-31T01:12:00} + date_time_attr19 matches {|> 2000-01-01T00:00:00|; 2006-03-31T01:12:00} + date_time_attr20 matches {|>= 2000-01-01T00:00:00|; 2006-03-31T01:12:00} + + -- newly supported pattern with "T" in the middle + date_time_attr21 matches {yyyy-??-??T??:??:??} + + -- single value as interval + date_time_attr22 matches {|2000-01-01T00:00:00|} + + -- datetime without specified seconds + date_time_attr23 matches {1995-03-17T12:01} + + -- datetime without specified minute or seconds + date_time_attr23 matches {1995-03-17T12} + } + } + } +ontology + primary_language = <"en"> + languages_available = <"en", ...> + terminologies_available = <"adl_test", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test entry">; + description = <"test entry"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..ecedc4f1 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.domain_types.test.adl @@ -0,0 +1,97 @@ +archetype + adl-test-ENTRY.domain_types.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 { -- ordinal + value matches { + 0|[local::at0003.0], -- capsule + 1|[local::at0003.1], -- powder + 2|[local::at0003.2], -- tablet + 3|[local::at0003.3], -- solution + 4|[local::at0003.4] -- suspension + } + } + ELEMENT[at10002] matches { -- coded_text + value matches { + [local:: + at2001.0, -- initial + at2001.1, -- wait + at2001.2] -- completed + } + } + + -- not a domain type + -- here for testing C_QUANTITY parsing + + ELEMENT[at10006] matches { -- count + value matches { + COUNT matches { + magnitude matches {|0..100|} + } + } + } + + -- not a domain type + -- here for verifying a bug fix + + ELEMENT[at10006] matches { -- count + value matches { + COUNT matches {*} + } + } + } + } + } + } + +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"> + > + ["at0002"] = < + text = <"*"> + description = <"*"> + > + ["at0003.0"] = < + text = <"capsule"> + description = <""> + > + ["at0003.1"] = < + text = <"powder"> + description = <""> + > + ["at0003.2"] = < + text = <"tablet"> + description = <""> + > + ["at0003.3"] = < + text = <"solution"> + description = <""> + > + ["at0003.4"] = < + text = <"suspension"> + description = <""> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..4ebc7571 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.durations.test.adl @@ -0,0 +1,111 @@ +archetype + adl-test-ENTRY.test.draft + +concept + [at0000] -- basic data types test 1 + +language + original_language = <[ISO_639-1::en]> + +definition + ENTRY[at0000] matches { + types matches { + LIST[at0001] matches { + items cardinality matches {0..*} matches { + ELEMENT[at1001] matches { -- duration + value matches {PT0s} + } + ELEMENT[at1002] matches { -- duration + value matches {P1d} + } + ELEMENT[at1003] matches { -- duration + value matches {PT2h5m0s} + } + ELEMENT[at1004] matches { -- duration + value matches {|PT1h55m0s..PT2h5m0s|} + } + ELEMENT[at1005] matches { -- duration + value matches {|<=PT1h|} + } + ELEMENT[at1006] matches { -- duration + value matches {P1DT1H2M3S} + } + ELEMENT[at1007] matches { -- duration + value matches {P1W2DT1H2M3S} + } + ELEMENT[at1008] matches { -- duration + value matches {P3M1W2DT1H2M3S} + } + ELEMENT[at1009] matches { -- duration pattern + value matches {PDTH} + } + ELEMENT[at1010] matches { -- duration interval + value matches {|PT10M|} + } + ELEMENT[at1011] matches { -- duration ISO8601 pattern + value matches {PYMWDTHMS} + } + ELEMENT[at1011] matches { -- duration with fractional seconds + value matches {|PT0.004s|} + } + ELEMENT[at1012] matches { -- duration with fractional seconds + value matches {|PT10.01s|} + } + ELEMENT[at1013] matches { -- duration with fractional seconds + value matches {|PT1.1s|} + } + ELEMENT[at1014] matches { -- duration with mixed Pattern and Interval + value matches {PTS/|PT0S..PT120S|} + } + -- matches {PT30s, PT45s, PT1m0s, PT2m0s} -- Not currently in ADL syntax + -- matches {|P1d +/PT4h|} + } + } + + LIST[at0002] matches { + items cardinality matches {0..*} matches { + ELEMENT[at1001] matches { -- duration with assumed values + value matches {PT0s; P1d} + } + ELEMENT[at1002] matches { -- duration with assumed values + value matches {P1d; P1d} + } + ELEMENT[at1003] matches { -- duration with assumed values + value matches {PT2h5m0s; P1d} + } + ELEMENT[at1004] matches { -- duration with assumed values + value matches {|PT1h55m0s..PT2h5m0s|; P1d} + } + ELEMENT[at1005] matches { -- duration with assumed values + value matches {|<=PT1h|; P1d} + } + ELEMENT[at1006] matches { -- duration + value matches {PDTH; P1d} + } + + ELEMENT[at1010] matches { -- duration interval + value matches {|PT10M|; PT12M} + } + } + } + } + } +ontology + primary_language = <"en"> + languages_available = <"en", ...> + terminologies_available = <"adl_test", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test entry">; + description = <"test entry"> + > + ["at0001"] = < + text = <"test list">; + description = <"test list"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..b7b6076a --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.empty_other_contributors.test.adl @@ -0,0 +1,42 @@ +archetype + adl-test-ENTRY.empty_other_contributors.draft + +concept + [at0000] -- test + +language + original_language = <[ISO_639-1::en]> + +description + original_author = < + ["name"] = <"name"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"purpose"> + use = <"use"> + misuse = <"misuse"> + copyright = <"copyright"> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <> + +definition + ENTRY[at0000] matches {*} + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"text">; + description = <"description"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..df060bf7 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.missing_language.test.adl @@ -0,0 +1,23 @@ +archetype + adl-test-ENTRY.missing_language.draft + +concept + [at0000] -- testing missing language compatibility + +definition + ENTRY[at0000] matches {*} + +ontology + primary_language = <"zh"> + languages_available = <"zh", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..9668c1d3 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.mixed_node_types.draft.adl @@ -0,0 +1,61 @@ +archetype (adl_version=1.4) + adl-test-OUTER.mixed_types.draft + +concept + [at0000] -- outer object +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"Thomas Beale"> + ["submission"] = <"01/05/2004"> + ["organisation"] = <"OceanInformatics.biz"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"Test archetype for mixed node types"> + keywords = <"ADL", "test"> + copyright = <"copyright (c) 2004 The openEHR Foundation"> + > + > + lifecycle_state = <"draft"> + +definition + OUTER[at0000] matches { -- outer object + items cardinality matches {0..*; ordered} matches { + COMPLEX_OBJECT[at0001] matches {*} + use_node COMPLEX_OBJECT /items[at0001] + use_node COMPLEX_OBJECT /items[at0002] + COMPLEX_OBJECT[at0002] matches {*} + allow_archetype COMPLEX_OBJECT matches { + include + archetype_id/value matches {/.*/} + } + COMPLEX_OBJECT[at0003] matches {*} + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + description = <"outer object"> + text = <"outer object"> + > + ["at0001"] = < + description = <"complex object 1"> + text = <"complex object 1"> + > + ["at0002"] = < + description = <"complex object 2"> + text = <"complex object 2"> + > + ["at0003"] = < + description = <"complex object 3"> + text = <"complex object 3"> + > + > + > + > 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 new file mode 100644 index 00000000..28fe5e50 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.most_minimal.test.adl @@ -0,0 +1,23 @@ +archetype + adl-test-ENTRY.most_minimal.draft + +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/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 new file mode 100644 index 00000000..4b057aac --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.multi_language.test.adl @@ -0,0 +1,52 @@ +archetype + adl-test-ENTRY.multi-language.draft +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ENTRY[at0000] matches {*} + +ontology + primary_language = <"en"> + languages_available = <"en", "sv"> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + ["sv"] = < + items = < + ["at0000"] = < + text = <"mesta minimal">; + description = <"mesta minimal"> + > + > + > + > + + constraint_definitions = < + ["en"] = < + items = < + ["ac0001"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + ["sv"] = < + items = < + ["ac0001"] = < + text = <"mesta minimal">; + description = <"mesta minimal"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..e4fc67ab --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.regular_expression.test.adl @@ -0,0 +1,45 @@ +archetype + adl-test-ENTRY.regular_expression.test + +concept + [at0000] -- test 1 + +language + original_language = <[ISO_639-1::en]> + +definition + ENTRY[at0000] matches { + string_attributes matches { + LIST matches { + -- + string_attr1 matches {/.*/} + + -- + string_attr2 matches {/[0-9]|([0-9]|[0-9]\.[0-9]+)([+\-][0-9])?/} + + -- problematic one (part) + string_attr3 matches {/[0-9]{1,8}/} + + -- problematic one + string_attr4 matches {/[0-9]{1,8}|([0-9]{9,14}|[0-9]{14,14}\.[0-9]+)([+\-][0-9]{1,4})?/} + + -- yet another one + string_attr5 matches {/[^\s]*/} + } + } + } +ontology + primary_language = <"en"> + languages_available = <"en", ...> + terminologies_available = <"adl_test", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test entry">; + description = <"test entry"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..ddc92f07 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.special_string.test.adl @@ -0,0 +1,88 @@ +archetype + adl-test-ENTRY.test.draft + +concept + [at0000] -- basic data types test 1 + +language + original_language = <[ISO_639-1::en]> + +definition + ENTRY[at0000] matches { + string_attributes matches { + LIST matches { + + -- escaped double quote + string_attr10 matches {"some\"thing"} + + -- escaped backslash + string_attr11 matches {"any\\thing"} + + -- three-lines string + string_attr21 matches {"this is what it is used for, this could be a really long line or even +multiple lines, just like +what you are reading now"} + + -- nine-lines string with leading and trailing spaces + string_attr21 matches {"this is what it is used for, this could + be a really long line or even multiple lines, just like what you + string_attr21 matches this is what it is used for, this could + be a really long line or even multiple lines, just like what you + string_attr21 matches this is what it is used for, this could + be a really long line or even multiple lines, just like what you + string_attr21 matches this is what it is used for, this could + be a really long line or even multiple lines, just like what you + are reading now "} + + -- multi-line string with empty lines in the middle + string_attr22 matches {"this is what it is used for, this could be a really long line or even + + +multiple lines, just like"} + + + -- another multi-line string starting with empty line + string_attr23 matches {" + + this is what it is used + + for, this could + + be a really long line or even + + multiple lines, just like + + multiple lines, just like + + multiple lines, just like + + multiple lines, just like + + multiple lines, just like + + "} + + -- units = <"/min">, possibile confict with path syntax + units_1 matches {"/min"} + + -- units = + units_2 matches {"km/h"} + + } + } + } +ontology + primary_language = <"en"> + languages_available = <"en", ...> + terminologies_available = <"adl_test", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test entry">; + description = <"test entry"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..cbe47db1 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.structure_test1.test.adl @@ -0,0 +1,45 @@ +archetype + adl-test-ENTRY.structure_test1.draft +concept + [at0000] -- structure test 1 +language + original_language = <[ISO_639-1::en]> + + +definition + ENTRY[at0000] matches { + subject_relationship matches { + RELATED_PARTY matches { + relationship matches { + TEXT matches { + value matches {"self"} + } + } + } + } + members existence matches {0..1} cardinality matches {0..8} matches { + PERSON occurrences matches {1} matches { + title matches {"head"} + } + PERSON occurrences matches {0..*} matches { + title matches {"member"} + } + } + } + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + terminologies_available = <"adl_test", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test entry">; + description = <"test entry"> + > + > + > + > + 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 new file mode 100644 index 00000000..1e1f7d16 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.structure_test2.test.adl @@ -0,0 +1,45 @@ +archetype + adl-test-ENTRY.structure_test1.draft +concept + [at0000] -- structure test 1 +language + original_language = <[ISO_639-1::en]> + + +definition + ENTRY[at0000] matches { -- /items[Clinical Description] + subject_relationship matches { + RELATED_PARTY matches { + relationship matches { + TEXT matches { + value matches {"self"} + } + } + } + } + members existence matches {0..1} cardinality matches {0..8} matches { + PERSON occurrences matches {1} matches { + title matches {"head"} + } + PERSON occurrences matches {0..*} matches { + title matches {"member"} + } + } + } + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + terminologies_available = <"adl_test", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test entry">; + description = <"test entry"> + > + > + > + > + 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 new file mode 100644 index 00000000..b9a1ea6b --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.term_binding.test.adl @@ -0,0 +1,37 @@ +archetype + adl-test-ENTRY.term_binding.draft +concept + [at0000] -- empty definition test +language + original_language = <[ISO_639-1::en]> + + +definition + ENTRY[at0000] matches {*} + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + term_binding = < + ["SNOMED_CT"] = < + items = < + ["at0000"] = <[snomed_ct::1000339]> + > + > + ["ICD10"] = < + items = < + ["at0000"] = <[icd10::1000],[icd10::1001]> + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..202e7f64 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.term_binding2.test.adl @@ -0,0 +1,32 @@ +archetype + adl-test-ENTRY.term_binding.draft +concept + [at0000] -- path-based binding test +language + original_language = <[ISO_639-1::en]> + + +definition + ENTRY[at0000] matches {*} + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > + term_binding = < + ["LNC205"] = < + items = < + ["/data[at0002]/events[at0003]/data[at0001]/item[at0004]"] = <[LNC205::8310-5]> + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..f4258299 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.testtranslations.test.adl @@ -0,0 +1,83 @@ +archetype + adl-test-ENTRY.testtranslations.draft +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + translations = < + ["de"] = < + language = <[ISO_639-1::de]> + author = < + ["organisation"] = <"test organisation"> + ["name"] = <"test author"> + > + accreditation = <"test Accreditation!"> + > + ["es"] = < + language = <[ISO_639-1::es]> + author = < + ["name"] = <"Another test author"> + > -- no organisation or accreditation here to test that the parser won't take the old accreditation/organisation! + > + > +definition + ENTRY[at0000] matches {*} + +ontology + primary_language = <"en"> + languages_available = <"en", "de", "es"> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + ["de"] = < + items = < + ["at0000"] = < + text = <"sehr minimal">; + description = <"sehr minimal"> + > + > + > + ["es"] = < + items = < + ["at0000"] = < + text = <"mesta minimal">; + description = <"mesta minimal"> + > + > + > + > + + constraint_definitions = < + ["en"] = < + items = < + ["ac0001"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + ["de"] = < + items = < + ["ac0001"] = < + text = <"sehr minimal">; + description = <"sehr minimal"> + > + > + > + ["es"] = < + items = < + ["ac0001"] = < + text = <"mesta minimal">; + description = <"mesta minimal"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..edc72448 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.translations_author_language.test.adl @@ -0,0 +1,34 @@ +archetype + adl-test-ENTRY.translation_author_language.draft + +concept + [at0000] -- test + +language + original_language = <[ISO_639-1::en]> + translations = < + ["de"] = < + author = < + ["name"] = <"Harry Potter"> + ["email"] = <"harry@something.somewhere.co.uk"> + > + language = <[ISO_639-1::de]> + > + > +definition + ENTRY[at0000] matches {*} + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test">; + description = <"test"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..bb394ffd --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.translations_language_author.test.adl @@ -0,0 +1,34 @@ +archetype + adl-test-ENTRY.translation_language_author.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"> + > + > + > +definition + ENTRY[at0000] matches {*} + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test">; + description = <"test"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..0d8d97a4 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.unicode_BOM_support.test.adl @@ -0,0 +1,41 @@ +archetype + adl-test-ENTRY.unicode_BOM_support.draft +concept + [at0000] -- empty definition test +language + original_language = <[ISO_639-1::en]> + + +definition + ENTRY[at0000] matches {*} + +ontology + primary_language = <"en"> + languages_available = <"en", "zh", "sv"> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"concept">; + description = <"description"> + > + > + > + ["zh"] = < + items = < + ["at0000"] = < + text = <"概念">; -- "concept" in Chinese + description = <"描述"> -- "description" in Chinese + > + > + > + ["sv"] = < + items = < + ["at0000"] = < + text = <"språk">; -- "language" in Swedish + description = <"Hjälp"> -- "help" in Swedish + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..8a968c88 --- /dev/null +++ b/adl-parser/src/test/resources/adl-test-entry.unicode_support.test.adl @@ -0,0 +1,41 @@ +archetype + adl-test-ENTRY.unicode_support.draft +concept + [at0000] -- empty definition test +language + original_language = <[ISO_639-1::en]> + + +definition + ENTRY[at0000] matches {*} + +ontology + primary_language = <"en"> + languages_available = <"en", "zh", "sv"> + + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"concept">; + description = <"description"> + > + > + > + ["zh"] = < + items = < + ["at0000"] = < + text = <"概念">; -- "concept" in Chinese + description = <"描述"> -- "description" in Chinese + > + > + > + ["sv"] = < + items = < + ["at0000"] = < + text = <"språk">; -- "language" in Swedish + description = <"Hjälp"> -- "help" in Swedish + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..77ed0ccc --- /dev/null +++ b/adl-parser/src/test/resources/openEHR-EHR-CLUSTER.auscultation.v1.adl @@ -0,0 +1,48 @@ +archetype (adl_version=1.4) + openEHR-EHR-CLUSTER.auscultation.v1 + +concept + [at0000] -- Auscultation +language + original_language = <[ISO_639-1::en]> + +definition + CLUSTER[at0000] matches { -- Auscultation + items cardinality matches {0..*; unordered} matches { + CLUSTER[at0002] occurrences matches {0..1} matches { -- Findings + items cardinality matches {0..*; unordered} matches { + CLUSTER[at0009] occurrences matches {0..1} matches { -- Bowel sounds + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0074] occurrences matches {0..*} matches { -- Specific Findings + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0078, -- Absent bowel sounds + at0079, -- Decreased bowel sounds + at0080, -- Increased bowel sounds + at0081] -- Tinkling bowel sounds + } + } + } + } + use_node ELEMENT /items[at0004] -- /items[Clinical Description] + } + } + + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Auscultation"> + description = <"Findings on Auscultation"> + > + > + > + > 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 new file mode 100644 index 00000000..dd16105e --- /dev/null +++ b/adl-parser/src/test/resources/openEHR-EHR-ELEMENT.uid_test.v1.adl @@ -0,0 +1,44 @@ +archetype (adl_version=1.4; uid=1.2.456) + openEHR-EHR-ELEMENT.uid_test.v1 + +concept + [at0000] -- Uid test +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"] = <"826347FFD4FDDD289CB364144AB51BFB"> + > + +definition + ELEMENT[at0000] matches { -- Uid test + value matches { + DV_TEXT matches {*} + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Uid test"> + description = <"unknown"> + > + > + > + > 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 new file mode 100644 index 00000000..89ea3911 --- /dev/null +++ b/adl-parser/src/test/resources/openEHR-EHR-ELEMENT.uid_test.v2.adl @@ -0,0 +1,44 @@ +archetype (adl_version=1.4; uncontrolled; uid=1.2.456::22) + openEHR-EHR-ELEMENT.uid_test.v2 + +concept + [at0000] -- Uid test +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"] = <"826347FFD4FDDD289CB364144AB51BFB"> + > + +definition + ELEMENT[at0000] matches { -- Uid test + value matches { + DV_TEXT matches {*} + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Uid test"> + description = <"unknown"> + > + > + > + > 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 new file mode 100644 index 00000000..3428ecd6 --- /dev/null +++ b/adl-parser/src/test/resources/openEHR-EHR-EVALUATION.columna_vertebral.v1.adl @@ -0,0 +1,85 @@ +archetype (adl_version=1.4) + openEHR-EHR-EVALUATION.columna_vertebral.v1 + +concept + [at0000] -- Columna vertebral +language + original_language = <[ISO_639-1::es]> +description + original_author = < + ["name"] = <""> + > + details = < + ["es"] = < + language = <[ISO_639-1::es]> + purpose = <"Evaluacion de columna vertebral"> + use = <"Evaluacion de columna vertebral"> + misuse = <""> + > + > + lifecycle_state = <"0"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"0CD148BEA5220C93A938A3038D526998"> + > + +definition + EVALUATION[at0000] matches { -- Columna vertebral + data matches { + ITEM_LIST[at0001] matches { -- Lista + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0002] occurrences matches {0..1} matches { -- Exploracion clinica cervical anormal + value matches { + DV_BOOLEAN matches { + value matches {True, False; True} + } + } + } + ELEMENT[at0003] occurrences matches {0..1} matches { -- Indicacion de collar cervical + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0004, -- Si + at0005] -- No + } + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["es"] = < + items = < + ["at0000"] = < + text = <"Columna vertebral"> + description = <"Columna vertebral"> + > + ["at0001"] = < + text = <"Lista"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Exploracion clinica cervical anormal"> + description = <"Exploracion clinica cervical anormal"> + > + ["at0003"] = < + text = <"Indicacion de collar cervical"> + description = <"Indicacion de collar cervical"> + > + ["at0004"] = < + text = <"Si"> + description = <"hay indicacion de collar cervical"> + > + ["at0005"] = < + text = <"No"> + description = <"no hay indicacion de collar cervical"> + > + > + > + > 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 new file mode 100644 index 00000000..21a11734 --- /dev/null +++ b/adl-parser/src/test/resources/openEHR-EHR-OBSERVATION.test_internal_ref_binding.v1.adl @@ -0,0 +1,94 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.test_internal_ref_binding.v1 + +concept + [at0000] -- Test internal ref binding +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"] = <"90A264EB6540FEEE77D65E14C98CAC80"> + > + +definition + OBSERVATION[at0000] matches { -- Test internal ref binding + 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 { + ELEMENT[at0004] occurrences matches {0..1} matches { -- test element + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + EVENT[at0005] occurrences matches {0..1} matches { -- another event using use node + data matches { + use_node ITEM_TREE /data[at0001]/events[at0002]/data[at0003] -- /data[Event Series]/events[Any event]/data[Tree] + } + } + } + } + } + } + +ontology + terminologies_available = <"DDB00", ...> + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Test internal ref binding"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Event Series"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Any event"> + description = <"*"> + > + ["at0003"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0004"] = < + text = <"test element"> + description = <"*"> + > + ["at0005"] = < + text = <"another event using use node"> + description = <"*"> + > + > + > + > + term_bindings = < + ["DDB00"] = < + items = < + ["/data[at0001]/events[at0002]/data[at0003]/items[at0004]"] = <[DDB00::12345]> + ["/data[at0001]/events[at0005]/data[at0003]/items[at0004]"] = <[DDB00::98765]> + > + > + > 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 new file mode 100644 index 00000000..16fe88bf --- /dev/null +++ b/adl-parser/src/test/resources/openEHR-EHR-OBSERVATION.testassumedvalue.v1.adl @@ -0,0 +1,99 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.testassumedvalue.v1 + +concept + [at0000] -- Test assumed value +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <""> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <""> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"0"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"0B09C5A77713C376B458BDB09F83F018"> + > + +definition + OBSERVATION[at0000] matches { -- Test assumed value + 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 { + ELEMENT[at0004] occurrences matches {0..1} matches { -- New element + value matches { + DV_BOOLEAN matches { + value matches {True, False; True} + } + } + } + } + } + } + state matches { + ITEM_TREE[at0005] matches { -- Tree + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0006] occurrences matches {0..1} matches { -- New element + value matches { + DV_BOOLEAN matches { + value matches {True, False; True} + } + } + } + } + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Test assumed value"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Event Series"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Any event"> + description = <"*"> + > + ["at0003"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0004"] = < + text = <"New element"> + description = <"*"> + > + ["at0005"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0006"] = < + text = <"New element"> + description = <"*"> + > + > + > + > diff --git a/adl-serializer/docs/changes.txt b/adl-serializer/docs/changes.txt new file mode 100644 index 00000000..6165a0c0 --- /dev/null +++ b/adl-serializer/docs/changes.txt @@ -0,0 +1,28 @@ +2007/02/14 +.better interval output for same lower and upper limit +.added precision in CDvQuantity output +.added ConstraintRef output + +2007/02/13 +.added support for translations +.fixed archetypeInternalRef output bug +.fixed unclosed brace when code list is empty + +2007/02/11 +.archetype language support + +2007/01/24 +.added assumedValue in all CPrimitive types +.added assumedValue in CDvOrdinal output +.added pattern in CDuration output + +2007/01/20 +.bug fix related to null includes or excludes in printArchetypeSlot +.added support for assumedValue in CCodePhrase + +2007/01/14 +.added support for CCodePhrase +.added support for archetype language + +2006/12/16 +.updated support for ArchetypeSlot \ No newline at end of file diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml new file mode 100644 index 00000000..0d39ed21 --- /dev/null +++ b/adl-serializer/pom.xml @@ -0,0 +1,78 @@ + + 4.0.0 + + openehr + ref_impl_java + 1.0.5-SNAPSHOT + + adl-serializer + jar + ADL Serializer + http://www.openehr.org/projects/java.html + + openEHR + http://www.openehr.org/ + + 2004 + + java ADL Serializer for Archetype Object Model + + + + + src/test/adl + + + + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + openehr-aom + ${project.version} + + + openehr + openehr-ap + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + openehr + adl-parser + ${project.version} + test + + + commons-lang + commons-lang + 2.6 + + + commons-io + commons-io + 1.2 + test + + + junit + junit + 3.8.1 + test + + + diff --git a/adl-serializer/readme.txt b/adl-serializer/readme.txt new file mode 100644 index 00000000..ccd95a7e --- /dev/null +++ b/adl-serializer/readme.txt @@ -0,0 +1 @@ +ADL serializer for Archetype Object Model 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 new file mode 100644 index 00000000..af138e25 --- /dev/null +++ b/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java @@ -0,0 +1,1290 @@ +/* + * 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 ***** + */ 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 new file mode 100644 index 00000000..b32c03e4 --- /dev/null +++ b/adl-serializer/src/test/adl/adl-test-entry.most_minimal.test.adl @@ -0,0 +1,19 @@ +archetype (adl_version=1.4) + adl-test-ENTRY.most_minimal.draft +concept + [at0000] +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/adl-serializer/src/test/adl/archetype-internal-ref-test.adl b/adl-serializer/src/test/adl/archetype-internal-ref-test.adl new file mode 100644 index 00000000..35eb8d33 --- /dev/null +++ b/adl-serializer/src/test/adl/archetype-internal-ref-test.adl @@ -0,0 +1 @@ +use_node SECTION occurrences matches {1..2} /attribute1 \ No newline at end of file diff --git a/adl-serializer/src/test/adl/archetype-language.adl b/adl-serializer/src/test/adl/archetype-language.adl new file mode 100644 index 00000000..2b6954ab --- /dev/null +++ b/adl-serializer/src/test/adl/archetype-language.adl @@ -0,0 +1,16 @@ +language + original_language = <[ISO_639-1::en]> + translations = < + ["de"] = < + language = <[ISO_639-1::de]> + author = < + ["email"] = <"harry@something.somewhere.co.uk"> + ["name"] = <"Harry Potter"> + > + accreditation = <"British Medical Translator id 00400595"> + other_details = < + ["reviewer 1"] = <"Ron Weasley"> + ["reviewer 2"] = <"Rubeus Hagrid"> + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..e986e641 --- /dev/null +++ b/adl-serializer/src/test/adl/archetype-slot-any-allowed-test.adl @@ -0,0 +1 @@ +allow_archetype OBSERVATION[at0001] matches {*} \ No newline at end of file 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 new file mode 100644 index 00000000..01d2b9fa --- /dev/null +++ b/adl-serializer/src/test/adl/archetype-slot-empty-excludes-test.adl @@ -0,0 +1,5 @@ +allow_archetype OBSERVATION[at0001] occurrences matches {1..*} matches { + include + domain_concept matches {/blood_pressure.v1/} + domain_concept matches {/blood_pressure.v2/} +} \ No newline at end of file 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 new file mode 100644 index 00000000..ef1f5239 --- /dev/null +++ b/adl-serializer/src/test/adl/archetype-slot-empty-includes-test.adl @@ -0,0 +1,4 @@ +allow_archetype OBSERVATION[at0001] occurrences matches {1..*} matches { + exclude + domain_concept matches {/.*/} +} \ No newline at end of file diff --git a/adl-serializer/src/test/adl/archetype-slot-test.adl b/adl-serializer/src/test/adl/archetype-slot-test.adl new file mode 100644 index 00000000..62b21274 --- /dev/null +++ b/adl-serializer/src/test/adl/archetype-slot-test.adl @@ -0,0 +1,7 @@ +allow_archetype OBSERVATION[at0001] occurrences matches {1..*} matches { + include + domain_concept matches {/blood_pressure.v1/} + domain_concept matches {/blood_pressure.v2/} + exclude + domain_concept matches {/.*/} +} \ No newline at end of file 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 new file mode 100644 index 00000000..950100a5 --- /dev/null +++ b/adl-serializer/src/test/adl/c-code-phrase-test-empty.adl @@ -0,0 +1,2 @@ +C_CODE_PHRASE < +> \ No newline at end of file diff --git a/adl-serializer/src/test/adl/c-code-phrase-test.adl b/adl-serializer/src/test/adl/c-code-phrase-test.adl new file mode 100644 index 00000000..bced79b3 --- /dev/null +++ b/adl-serializer/src/test/adl/c-code-phrase-test.adl @@ -0,0 +1,5 @@ +[icd10:: + F43.00, + F43.01, + F32.02; + F43.01] \ No newline at end of file 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 new file mode 100644 index 00000000..be3b83d2 --- /dev/null +++ b/adl-serializer/src/test/adl/c-dv-ordinal-test-empty.adl @@ -0,0 +1,2 @@ +C_DV_ORDINAL < +> \ No newline at end of file diff --git a/adl-serializer/src/test/adl/c-dv-ordinal-test.adl b/adl-serializer/src/test/adl/c-dv-ordinal-test.adl new file mode 100644 index 00000000..f65037ba --- /dev/null +++ b/adl-serializer/src/test/adl/c-dv-ordinal-test.adl @@ -0,0 +1,5 @@ +1|[local::at2001], +2|[local::at2002], +3|[local::at2003], +4|[local::at2004]; +1|[local::at2001] \ No newline at end of file diff --git a/adl-serializer/src/test/adl/c-dv-ordinal-test2.adl b/adl-serializer/src/test/adl/c-dv-ordinal-test2.adl new file mode 100644 index 00000000..ed804156 --- /dev/null +++ b/adl-serializer/src/test/adl/c-dv-ordinal-test2.adl @@ -0,0 +1,4 @@ +1|[local::at2001], +2|[local::at2002], +3|[local::at2003], +4|[local::at2004] \ No newline at end of file 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 new file mode 100644 index 00000000..c3a3bff5 --- /dev/null +++ b/adl-serializer/src/test/adl/c-dv-quantity-test-empty.adl @@ -0,0 +1,2 @@ +C_DV_QUANTITY < +> \ No newline at end of file diff --git a/adl-serializer/src/test/adl/c-dv-quantity-test.adl b/adl-serializer/src/test/adl/c-dv-quantity-test.adl new file mode 100644 index 00000000..a8b3416f --- /dev/null +++ b/adl-serializer/src/test/adl/c-dv-quantity-test.adl @@ -0,0 +1,14 @@ +C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"year"> + magnitude = <|0.0..200.0|> + precision = <|2|> + > + ["2"] = < + units = <"month"> + magnitude = <|1.0..36.0|> + > + > +> \ No newline at end of file diff --git a/adl-serializer/src/test/adl/c-string-test.adl b/adl-serializer/src/test/adl/c-string-test.adl new file mode 100644 index 00000000..72f7a1ea --- /dev/null +++ b/adl-serializer/src/test/adl/c-string-test.adl @@ -0,0 +1 @@ +"value"; "assumed value" \ No newline at end of file diff --git a/adl-serializer/src/test/adl/empty-attribute-list-test.adl b/adl-serializer/src/test/adl/empty-attribute-list-test.adl new file mode 100644 index 00000000..20f05e87 --- /dev/null +++ b/adl-serializer/src/test/adl/empty-attribute-list-test.adl @@ -0,0 +1 @@ +DV_TEXT[at0001] matches {*} \ No newline at end of file diff --git a/adl-serializer/src/test/adl/empty-children-list-test.adl b/adl-serializer/src/test/adl/empty-children-list-test.adl new file mode 100644 index 00000000..c2a24214 --- /dev/null +++ b/adl-serializer/src/test/adl/empty-children-list-test.adl @@ -0,0 +1 @@ +value matches {*} \ No newline at end of file diff --git a/adl-serializer/src/test/adl/multi-language.adl b/adl-serializer/src/test/adl/multi-language.adl new file mode 100644 index 00000000..eaa9f324 --- /dev/null +++ b/adl-serializer/src/test/adl/multi-language.adl @@ -0,0 +1,53 @@ +ontology + term_definitions = < + ["en"] = < + items = < + ["at0001"] = < + text = <"text at0001"> + description = <"desc at0001"> + > + ["at0002"] = < + text = <"text at0002"> + description = <"desc at0002"> + > + > + > + ["zh"] = < + items = < + ["at0001"] = < + text = <"text at0001"> + description = <"desc at0001"> + > + ["at0002"] = < + text = <"text at0002"> + description = <"desc at0002"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0001"] = < + text = <"text ac0001"> + description = <"desc ac0001"> + > + ["ac0002"] = < + text = <"text ac0002"> + description = <"desc ac0002"> + > + > + > + ["zh"] = < + items = < + ["ac0001"] = < + text = <"text ac0001"> + description = <"desc ac0001"> + > + ["ac0002"] = < + text = <"text ac0002"> + description = <"desc ac0002"> + > + > + > + > \ No newline at end of file diff --git a/adl-serializer/src/test/adl/multi-terminology.adl b/adl-serializer/src/test/adl/multi-terminology.adl new file mode 100644 index 00000000..f82c1a71 --- /dev/null +++ b/adl-serializer/src/test/adl/multi-terminology.adl @@ -0,0 +1,36 @@ +ontology + terminologies_available = <"SNOMED_CT", "ICD10", ...> + term_definitions = < + ["en"] = < + items = < + ["at0001"] = < + text = <"text at0001"> + description = <"desc at0001"> + > + > + > + > + term_binding = < + ["SNOMED_CT"] = < + items = < + ["at0001"] = <[snomed_ct::1000339]> + > + > + ["ICD10"] = < + items = < + ["at0001"] = <[icd10::1000],[icd10::1001]> + > + > + > + constraint_binding = < + ["SNOMED_CT"] = < + items = < + ["ac0001"] = + > + > + ["ICD10"] = < + items = < + ["ac0001"] = + > + > + > \ No newline at end of file diff --git a/adl-serializer/src/test/adl/ontology.adl b/adl-serializer/src/test/adl/ontology.adl new file mode 100644 index 00000000..b0d31f93 --- /dev/null +++ b/adl-serializer/src/test/adl/ontology.adl @@ -0,0 +1,45 @@ +ontology + terminologies_available = <"local", ...> + term_definitions = < + ["en"] = < + items = < + ["at0001"] = < + text = <"text at0001"> + description = <"desc at0001"> + > + ["at0002"] = < + text = <"text at0002"> + description = <"desc at0002"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0001"] = < + text = <"text ac0001"> + description = <"desc ac0001"> + > + ["ac0002"] = < + text = <"text ac0002"> + description = <"desc ac0002"> + > + > + > + > + term_binding = < + ["local"] = < + items = < + ["at0001"] = <[local::100000]> + ["at0002"] = <[local::200000]> + > + > + > + constraint_binding = < + ["local"] = < + items = < + ["ac0001"] = + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..ac64a59b --- /dev/null +++ b/adl-serializer/src/test/adl/openEHR-EHR-EVALUATION.test_concept.v1.adl @@ -0,0 +1,47 @@ +archetype (adl_version=1.4) + openEHR-EHR-EVALUATION.test_concept.v1 + +concept + [at0000] -- unknown +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"????"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"testing archetype conversion"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"0"> + other_contributors = <> + other_details = < + ["references"] = <""> + > + +definition + EVALUATION[at0000] matches { -- unknown + data matches { + ITEM_TREE[at0001] matches {*} + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"unknown"> + description = <"unknown"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + > + > + > 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 new file mode 100644 index 00000000..6de50aa6 --- /dev/null +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/ArchetypeInternalRefTest.java @@ -0,0 +1,22 @@ +package org.openehr.am.serialize; + +import org.openehr.am.archetype.constraintmodel.ArchetypeInternalRef; +import org.openehr.am.archetype.constraintmodel.CAttribute; +import org.openehr.rm.support.basic.Interval; + +public class ArchetypeInternalRefTest extends SerializerTestBase { + + public void testPrintArchetypeInternalRef() throws Exception { + String path = "/attribute2"; + String type = "SECTION"; + Interval occurrences = new Interval(1, 2); + CAttribute parent = null; + String target = "/attribute1"; + + ArchetypeInternalRef ref = new ArchetypeInternalRef(path, type, + occurrences, null, parent, target); + clean(); + outputter.printArchetypeInternalRef(ref, 0, out); + verifyByFile("archetype-internal-ref-test.adl"); + } +} 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 new file mode 100644 index 00000000..f6a8e94d --- /dev/null +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/ArchetypeLanguageTest.java @@ -0,0 +1,51 @@ +package org.openehr.am.serialize; + +import java.util.*; + +import org.openehr.rm.common.generic.RevisionHistory; +import org.openehr.rm.common.resource.AuthoredResource; +import org.openehr.rm.common.resource.ResourceDescription; +import org.openehr.rm.common.resource.TranslationDetails; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.terminology.SimpleTerminologyService; + +public class ArchetypeLanguageTest extends SerializerTestBase { + + public ArchetypeLanguageTest(String test) { + super(test); + } + + public void testPrintArchetypeLanguage() throws Exception { + CodePhrase originalLanguage = new CodePhrase("ISO_639-1", "en"); + Map translations = + new HashMap(); + SortedMap author = new TreeMap(); + author.put("name", "Harry Potter"); + author.put("email", "harry@something.somewhere.co.uk"); + SortedMap otherDetails = new TreeMap(); + otherDetails.put("reviewer 1", "Ron Weasley"); + otherDetails.put("reviewer 2", "Rubeus Hagrid"); + TerminologyService ts = SimpleTerminologyService.getInstance(); + + TranslationDetails td = new TranslationDetails( + new CodePhrase("ISO_639-1", "de"), author, + "British Medical Translator id 00400595", otherDetails, ts); + + translations.put("de", td); + + ResourceDescription description = null; + RevisionHistory revisionHistory = null; + boolean isControlled = false; + + AuthoredResource authored = new AuthoredResource(originalLanguage, + translations, description, revisionHistory, isControlled, + ts) {}; + + clean(); + outputter.printLanguage(authored, out); + verifyByFile("archetype-language.adl"); + } + + +} 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 new file mode 100644 index 00000000..3bc8af4f --- /dev/null +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/ArchetypeSlotTest.java @@ -0,0 +1,173 @@ +package org.openehr.am.serialize; + +import java.util.LinkedHashSet; + +import org.openehr.am.archetype.assertion.Assertion; +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.OperatorKind; +import org.openehr.am.archetype.constraintmodel.ArchetypeSlot; +import org.openehr.am.archetype.constraintmodel.primitive.CString; +import org.openehr.rm.support.basic.Interval; + +/** + * Testcase for ArchetypeSlot print in ADL serialization + */ + +public class ArchetypeSlotTest extends SerializerTestBase { + + public ArchetypeSlotTest(String test) { + super(test); + } + + public void testPrintArchetypeSlot() throws Exception { + final ExpressionItem concept = new ExpressionLeaf( + ExpressionItem.ARCHETYPE, "domain_concept", + ExpressionLeaf.ReferenceType.ATTRIBUTE); + + // Use linked hashsets to get the ordering right when we run [clean, install]. + final LinkedHashSet includes = new LinkedHashSet(); + final LinkedHashSet excludes = new LinkedHashSet(); + ExpressionLeaf aid = new ExpressionLeaf(ExpressionItem.ARCHETYPE, + new CString("/blood_pressure.v1/", null), + ExpressionLeaf.ReferenceType.CONSTANT); + ExpressionItem expression = new ExpressionBinaryOperator( + ExpressionItem.BOOLEAN, OperatorKind.OP_MATCHES, false, + concept, aid); + String stringExpression = "domain_concept matches {/blood_pressure.v1/}"; + Assertion assertion = new Assertion(expression, stringExpression); + includes.add(assertion); + aid = new ExpressionLeaf(ExpressionItem.ARCHETYPE, + new CString("/blood_pressure.v2/", null), + ExpressionLeaf.ReferenceType.CONSTANT); + expression = new ExpressionBinaryOperator(ExpressionItem.BOOLEAN, + OperatorKind.OP_MATCHES, false, concept, aid); + stringExpression = "domain_concept matches {/blood_pressure.v2/}"; + assertion = new Assertion(expression, stringExpression); + includes.add(assertion); + + aid = new ExpressionLeaf(ExpressionItem.ARCHETYPE, "/.*/", + ExpressionLeaf.ReferenceType.CONSTANT); + expression = new ExpressionBinaryOperator(ExpressionItem.BOOLEAN, + OperatorKind.OP_MATCHES, false, concept, aid); + stringExpression = "domain_concept matches {/.*/}"; + assertion = new Assertion(expression, stringExpression); + excludes.add(assertion); + + Interval occurrences = new Interval(1, null, true, + false); + ArchetypeSlot slot = new ArchetypeSlot("/path", "OBSERVATION", + occurrences, "at0001", null, includes, excludes); + + clean(); + outputter.printArchetypeSlot(slot, 0, out); + verifyByFile("archetype-slot-test.adl"); + } + + public void testPrintArchetypeSlotWithEmptyExcludes() throws Exception { + final ExpressionItem concept = new ExpressionLeaf( + ExpressionItem.ARCHETYPE, "domain_concept", + ExpressionLeaf.ReferenceType.ATTRIBUTE); + + // Use linked hashsets to get the ordering right when we run [clean, install]. + final LinkedHashSet includes = new LinkedHashSet(); + final LinkedHashSet excludes = null; + ExpressionLeaf aid = new ExpressionLeaf(ExpressionItem.ARCHETYPE, + "/blood_pressure.v1/", ExpressionLeaf.ReferenceType.CONSTANT); + ExpressionItem expression = new ExpressionBinaryOperator( + ExpressionItem.BOOLEAN, OperatorKind.OP_MATCHES, false, + concept, aid); + String stringExpression = "domain_concept matches {/blood_pressure.v1/}"; + Assertion assertion = new Assertion(expression, stringExpression); + includes.add(assertion); + aid = new ExpressionLeaf(ExpressionItem.ARCHETYPE, + "/blood_pressure.v2/", ExpressionLeaf.ReferenceType.CONSTANT); + expression = new ExpressionBinaryOperator(ExpressionItem.BOOLEAN, + OperatorKind.OP_MATCHES, false, concept, aid); + stringExpression = "domain_concept matches {/blood_pressure.v2/}"; + assertion = new Assertion(expression, stringExpression); + includes.add(assertion); + + Interval occurrences = new Interval(1, null, true, + false); + ArchetypeSlot slot = new ArchetypeSlot("/path", "OBSERVATION", + occurrences, "at0001", null, includes, excludes); + + clean(); + outputter.printArchetypeSlot(slot, 0, out); + verifyByFile("archetype-slot-empty-excludes-test.adl"); + } + + public void testPrintArchetypeSlotWithEmptyIncludes() throws Exception { + final ExpressionItem concept = new ExpressionLeaf( + ExpressionItem.ARCHETYPE, "domain_concept", + ExpressionLeaf.ReferenceType.ATTRIBUTE); + + // Use linked hashsets to get the ordering right when we run [clean, install]. + final LinkedHashSet includes = null; + final LinkedHashSet excludes = new LinkedHashSet(); + ExpressionLeaf aid = null; + ExpressionItem expression = null; + String stringExpression = null; + Assertion assertion = null; + + aid = new ExpressionLeaf(ExpressionItem.ARCHETYPE, "/.*/", + ExpressionLeaf.ReferenceType.CONSTANT); + expression = new ExpressionBinaryOperator(ExpressionItem.BOOLEAN, + OperatorKind.OP_MATCHES, false, concept, aid); + stringExpression = "domain_concept matches {/.*/}"; + assertion = new Assertion(expression, stringExpression); + excludes.add(assertion); + + Interval occurrences = new Interval(1, null, true, + false); + ArchetypeSlot slot = new ArchetypeSlot("/path", "OBSERVATION", + occurrences, "at0001", null, includes, excludes); + + clean(); + outputter.printArchetypeSlot(slot, 0, out); + verifyByFile("archetype-slot-empty-includes-test.adl"); + } + + public void testPrintAnyAllowedSlot() throws Exception { + LinkedHashSet includes = null; + LinkedHashSet excludes = null; + Interval occurrences = new Interval(1, 1); + ArchetypeSlot slot = new ArchetypeSlot("/path", "OBSERVATION", + occurrences, "at0001", null, includes, excludes); + + clean(); + outputter.printArchetypeSlot(slot, 0, out); + verifyByFile("archetype-slot-any-allowed-test.adl"); + } +} +/* + * ***** 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 ArchetypeSlotTest.java + * + * The Initial Developer of the Original Code is Mattias Forss. + * Portions created by the Initial Developer are Copyright (C) 2006 + * 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 ***** + */ 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 new file mode 100644 index 00000000..a08ea4e9 --- /dev/null +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/CCodePhraseTest.java @@ -0,0 +1,92 @@ +package org.openehr.am.serialize; + +import java.util.Arrays; +import java.util.List; + +import org.openehr.am.openehrprofile.datatypes.text.CCodePhrase; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.basic.Interval; +import org.openehr.rm.support.identification.TerminologyID; + +public class CCodePhraseTest extends SerializerTestBase { + + public CCodePhraseTest(String test) { + super(test); + } + + public void testPrintCCodePhrase() throws Exception { + String[] codes = { "at2001", "at2002", "at2003" }; + String terminology = "local"; + Interval occurrences = new Interval(1, 1); + CCodePhrase ccoded = new CCodePhrase("/path", occurrences, null, null, + new TerminologyID(terminology), Arrays.asList(codes), null, + null); + + clean(); + outputter.printCCodePhrase(ccoded, 1, out); + verify(" [" + terminology + "::\r\n" + " " + codes[0] + ",\r\n" + + " " + codes[1] + ",\r\n" + " " + codes[2] + "]\r\n"); + } + + public void testPrintCCodePhraseWithSingleCode() throws Exception { + String[] codes = { "at3102.0" }; + String terminology = "local"; + Interval occurrences = new Interval(1, 1); + CCodePhrase ccoded = new CCodePhrase("/path", occurrences, null, null, + new TerminologyID(terminology), Arrays.asList(codes), null, + null); + clean(); + outputter.printCCodePhrase(ccoded, 0, out); + verify("[local::at3102.0]\r\n"); + } + + public void testPrintCCodePhraseWithSingleCodeAssumedValue() + throws Exception { + String[] codes = { "at3102.0" }; + String terminology = "local"; + CodePhrase assumed = new CodePhrase(terminology, codes[0]); + Interval occurrences = new Interval(1, 1); + CCodePhrase ccoded = new CCodePhrase("/path", occurrences, null, null, + new TerminologyID(terminology), Arrays.asList(codes), null, + assumed); + clean(); + outputter.printCCodePhrase(ccoded, 0, out); + verify("[local::at3102.0;at3102.0]\r\n"); + } + + public void testPrintCCodePhraseWithAssumedValue() throws Exception { + String[] codes = { "F43.00", "F43.01", "F32.02" }; + String terminology = "icd10"; + CodePhrase assumed = new CodePhrase(terminology, codes[1]); + Interval occurrences = new Interval(1, 1); + CCodePhrase ccoded = new CCodePhrase("/path", occurrences, null, null, + new TerminologyID(terminology), Arrays.asList(codes), null, + assumed); + clean(); + outputter.printCCodePhrase(ccoded, 0, out); + verifyByFile("c-code-phrase-test.adl"); + } + + public void testPrintCCodePhraseWithNoCode() throws Exception { + String terminology = "local"; + Interval occurrences = new Interval(1, 1); + CCodePhrase ccoded = new CCodePhrase("/path", occurrences, null, null, + new TerminologyID(terminology), null, null, null); + clean(); + outputter.printCCodePhrase(ccoded, 0, out); + verify("[local::]\r\n"); + } + + public void testPrintEmptyCCodePhrase() throws Exception { + List codeList = null; + TerminologyID terminology = null; + CodePhrase defaultValue = null; + CodePhrase assumedValue = null; + Interval occurrences = new Interval(1, 1); + CCodePhrase ccoded = new CCodePhrase("/path", occurrences, null, null, + terminology, codeList, defaultValue, assumedValue); + clean(); + outputter.printCCodePhrase(ccoded, 0, out); + verifyByFile("c-code-phrase-test-empty.adl"); + } +} 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 new file mode 100644 index 00000000..7ebedad2 --- /dev/null +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/CDurationTest.java @@ -0,0 +1,64 @@ +package org.openehr.am.serialize; + +import org.openehr.am.archetype.constraintmodel.primitive.CDuration; +import org.openehr.rm.datatypes.quantity.datetime.DvDuration; +import org.openehr.rm.support.basic.Interval; + +public class CDurationTest extends SerializerTestBase { + + public CDurationTest(String test) { + super(test); + } + + public void testCDurationWithDayValue() throws Exception { + // 5 day + DvDuration duration = new DvDuration(0, 0, 0, 5, 0, 0, 0, 0.0); + cd = new CDuration(duration, null, null, null); + outputter.printCDuration(cd, out); + verify("P5D"); + } + + public void testCDurationWithHourValue() throws Exception { + // 1 hour + DvDuration duration = new DvDuration(0, 0, 0, 0, 1, 0, 0, 0.0); + cd = new CDuration(duration, null, null, null); + outputter.printCDuration(cd, out); + verify("PT1H"); + } + + public void testCDurationWithInterval() throws Exception { + DvDuration d1 = new DvDuration(0, 0, 0, 0, 0, 0, 0, 0.0); + DvDuration d2 = new DvDuration(0, 0, 0, 0, 0, 1, 30, 0.0); + Interval i = new Interval(d1, d2); + cd = new CDuration(null, i, null, null); + outputter.printCDuration(cd, out); + verify("|PT0S..PT1M30S|"); + } + + public void testCDurationWithPattern() throws Exception { + String pattern = "PD"; + cd = new CDuration(null, null, null, pattern); + outputter.printCDuration(cd, out); + verify("PD"); + } + + public void testCDurationWithPatternAssumedValue() throws Exception { + String pattern = "PD"; + DvDuration assumed = new DvDuration(0, 0, 0, 1, 0, 0, 0, 0.0); + cd = new CDuration(null, null, assumed, pattern); + outputter.printCDuration(cd, out); + verify("PD; P1D"); + } + + public void testCDurationWithIntervalAssumedValue() throws Exception { + DvDuration d1 = new DvDuration(0, 0, 0, 0, 0, 0, 0, 0.0); + DvDuration d2 = new DvDuration(0, 0, 0, 0, 0, 1, 30, 0.0); + Interval i = new Interval(d1, d2); + DvDuration assumed = new DvDuration(0, 0, 0, 1, 0, 0, 0, 0.0); + cd = new CDuration(null, i, assumed, null); + outputter.printCDuration(cd, out); + verify("|PT0S..PT1M30S|; P1D"); + } + + private CDuration cd; +} 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 new file mode 100644 index 00000000..74d79657 --- /dev/null +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/CDvOrdinalTest.java @@ -0,0 +1,53 @@ +package org.openehr.am.serialize; + +import java.util.LinkedHashSet; +import java.util.Set; + +import org.openehr.am.openehrprofile.datatypes.quantity.CDvOrdinal; +import org.openehr.am.openehrprofile.datatypes.quantity.Ordinal; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.basic.Interval; + +public class CDvOrdinalTest extends SerializerTestBase { + + public void testPrintCDvOrdinalWithAssumedValue() throws Exception { + Set list = new LinkedHashSet(); + for (int i = 1; i <= 4; i++) { + list.add(new Ordinal(i, new CodePhrase("local", "at200" + i))); + } + Ordinal assumed = new Ordinal(1, new CodePhrase("local", "at2001")); + Interval occurrences = new Interval(1, 1); + cordinal = new CDvOrdinal("/path", occurrences, null, null, list, + null, assumed); + clean(); + outputter.printCDvOrdinal(cordinal, 0, out); + verifyByFile("c-dv-ordinal-test.adl"); + } + + public void testPrintCDvOrdinal() throws Exception { + Set list = new LinkedHashSet(); + for (int i = 1; i <= 4; i++) { + list.add(new Ordinal(i, new CodePhrase("local", "at200" + i))); + } + Interval occurrences = new Interval(1, 1); + cordinal = new CDvOrdinal("/path", occurrences, null, null, list, + null, null); + clean(); + outputter.printCDvOrdinal(cordinal, 0, out); + verifyByFile("c-dv-ordinal-test2.adl"); + } + + public void testPrintEmptyCDvOrdinal() throws Exception { + Set list = null; + + Interval occurrences = new Interval(1, 1); + cordinal = new CDvOrdinal("/path", occurrences, null, null, list, + null, null); + clean(); + outputter.printCDvOrdinal(cordinal, 0, out); + verifyByFile("c-dv-ordinal-test-empty.adl"); + } + + private CDvOrdinal cordinal; +} + 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 new file mode 100644 index 00000000..98ce3184 --- /dev/null +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/CDvQuantityTest.java @@ -0,0 +1,84 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DomainTypeTest" + * 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.*; + +import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantity; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantityItem; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.basic.Interval; + +public class CDvQuantityTest extends SerializerTestBase { + + public void testPrintCDvQuantity() throws Exception { + CDvQuantityItem item1 = new CDvQuantityItem(new Interval(0.0, + 200.0), new Interval(2, 2), "year"); + CDvQuantityItem item2 = new CDvQuantityItem(new Interval(1.0, + 36.0), "month"); + List list = new ArrayList(); + list.add(item1); + list.add(item2); + CodePhrase property = new CodePhrase("openehr", "128"); + Interval occurrences = new Interval(1, 1); + CDvQuantity cquantity = new CDvQuantity("/path", occurrences, null, null, + list, property, null, null); + + clean(); + outputter.printCDvQuantity(cquantity, 0, out); + verifyByFile("c-dv-quantity-test.adl"); + } + + public void testPrintEmptyCDvQuantity() throws Exception { + Interval occurrences = new Interval(1, 1); + List list = null; + CodePhrase property = null; + CDvQuantity cquantity = new CDvQuantity("/path", occurrences, null, null, + list, property, null, null); + clean(); + outputter.printCDvQuantity(cquantity, 0, out); + verifyByFile("c-dv-quantity-test-empty.adl"); + } + +} +/* + * ***** 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 DomainTypeTest.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/CommonTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/CommonTest.java new file mode 100644 index 00000000..72f559ed --- /dev/null +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/CommonTest.java @@ -0,0 +1,139 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CommonTest" + * 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: $" + */ +/** + * ADLOutputterTest + * + * @author Rong Chen + * @author Mattias Forss, Johan Hjalmarsson + * + * @version 1.0 + */ +package org.openehr.am.serialize; + +import org.openehr.am.archetype.constraintmodel.CAttribute; +import org.openehr.am.archetype.constraintmodel.Cardinality; +import org.openehr.rm.support.basic.Interval; +import org.openehr.rm.support.identification.ArchetypeID; + +public class CommonTest extends SerializerTestBase { + + public CommonTest(String test) { + super(test); + } + + public void testPrintHeader() throws Exception { + String id = "openEHR-EHR-EVALUATION.adverse_reaction-medication.v1"; + String parentId = "openEHR-EHR-EVALUATION.adverse_reaction.v1"; + String conceptCode = "at0000"; + + clean(); + outputter.printHeader(null, new ArchetypeID(id), + new ArchetypeID(parentId), null, conceptCode, out); + + verify("archetype\r\n" + " " + id + "\r\n" + "specialize\r\n" + + " " + parentId + "\r\n\r\n" + "concept\r\n" + " [" + + conceptCode + "]\r\n"); + } + + public void testPrintExistence() throws Exception { + clean(); + outputter.printExistence(CAttribute.Existence.REQUIRED, out); + verify(""); + + clean(); + outputter.printExistence(CAttribute.Existence.OPTIONAL, out); + verify("existence matches {0..1}"); + + clean(); + outputter.printExistence(CAttribute.Existence.NOT_ALLOWED, out); + verify("existence matches {0}"); + } + + public void testPrintCardinality() throws Exception { + clean(); + outputter.printCardinality(Cardinality.LIST, out); + verify("cardinality matches {0..*; ordered}"); + + clean(); + outputter.printCardinality(Cardinality.SET, out); + verify("cardinality matches {0..*; unordered; unique}"); + + clean(); + Cardinality cardinality = new Cardinality(true, true, + new Interval(2, 8)); + outputter.printCardinality(cardinality, out); + verify("cardinality matches {2..8; ordered; unique}"); + } + + public void testPrintInterval() throws Exception { + clean(); + outputter.printInterval(new Interval(0, 10), out); + verify("|0..10|"); + + clean(); + outputter.printInterval(new Interval(null, 10, false, false), + out); + verify("|<10|"); + + clean(); + outputter.printInterval(new Interval(null, 10, false, true), + out); + verify("|<=10|"); + + clean(); + outputter.printInterval(new Interval(0, null, false, false), + out); + verify("|>0|"); + + clean(); + outputter.printInterval(new Interval(0, null, true, false), + out); + verify("|>=0|"); + + clean(); + outputter.printInterval(new Interval(2, 2, true, true), + out); + verify("|2|"); + } +} +/* + * ***** 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 CommonTest.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 ***** + */ \ No newline at end of file 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 new file mode 100644 index 00000000..3fc3916f --- /dev/null +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/DescriptionTest.java @@ -0,0 +1,126 @@ +/* + * 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 ***** + */ 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 new file mode 100644 index 00000000..2c7bded0 --- /dev/null +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/EmptyAttributeListTest.java @@ -0,0 +1,29 @@ +package org.openehr.am.serialize; + +import java.util.List; + +import org.openehr.am.archetype.constraintmodel.*; +import org.openehr.am.archetype.constraintmodel.CAttribute.Existence; +import org.openehr.rm.support.basic.Interval; + +public class EmptyAttributeListTest extends SerializerTestBase { + + public void testOutputCComplexObjectWithEmptyAttributeList() throws Exception { + Interval occurrences = new Interval(1, 1); + List attributes = null; + CComplexObject ccobj = new CComplexObject("/path", "DV_TEXT", + occurrences, "at0001", attributes, null); + outputter.printCComplexObject(ccobj, 0, out); + verifyByFile("empty-attribute-list-test.adl"); + } + + public void testOutputCAttributeWithEmptyChildrenList() throws Exception { + + List children = null; + CSingleAttribute cattr = new CSingleAttribute("/path", "value", + Existence.REQUIRED, children); + + outputter.printCAttribute(cattr, 0, out); + verifyByFile("empty-children-list-test.adl"); + } +} 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 new file mode 100644 index 00000000..1519ff90 --- /dev/null +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/MultipleLanguageTest.java @@ -0,0 +1,143 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class MultipleLanguageTest" + * 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.List; + +import org.openehr.am.archetype.ontology.ArchetypeOntology; +import org.openehr.am.archetype.ontology.ArchetypeTerm; +import org.openehr.am.archetype.ontology.OntologyDefinitions; + +/** + * Multi-language ontology serialization test + * + * @author Rong Chen + */ +public class MultipleLanguageTest extends SerializerTestBase { + + public MultipleLanguageTest(String test) { + super(test); + } + + public void testPrintOntology() throws Exception { + + // *** TERM DEFINITIONS (in two languages) *** + + // A main list containing the sublists for different languages + List termDefinitionsList = + new ArrayList(); + + // A term list (used for English terms) + List items = new ArrayList(); + + // First example (for pedagocical purposes) shows how to use + // the short general constructor, followed by adding items + // step by step. Other keys could be used as well if there is + // more information available. + ArchetypeTerm item = new ArchetypeTerm("at0001"); + item.addItem(ArchetypeTerm.TEXT, "text at0001"); + item.addItem(ArchetypeTerm.DESCRIPTION, "desc at0001"); + items.add(item); + + // In the rest of the examples a convenience constructor is used + // that preforms several steps at once. + item = new ArchetypeTerm("at0002", "text at0002", "desc at0002"); + items.add(item); + + // Wrap the first list and tag it as English + OntologyDefinitions definitions = new OntologyDefinitions("en", items); + + // Add it to the main list + termDefinitionsList.add(definitions); + + + // make a new list object and use it for Chinese terms + items = new ArrayList(); + item = new ArchetypeTerm("at0001", "text at0001", "desc at0001"); + items.add(item); + item = new ArchetypeTerm("at0002", "text at0002", "desc at0002"); + items.add(item); + definitions = new OntologyDefinitions("zh", items); + // Add it to the main list + termDefinitionsList.add(definitions); + + + // *** CONSTRAINT DEFINITIONS (in two languages) *** + + List constraintDefinitionsList = + new ArrayList(); + + // English + items = new ArrayList(); + item = new ArchetypeTerm("ac0001", "text ac0001", "desc ac0001"); + items.add(item); + item = new ArchetypeTerm("ac0002", "text ac0002", "desc ac0002"); + items.add(item); + definitions = new OntologyDefinitions("en", items); + constraintDefinitionsList.add(definitions); + + // Chinese + item = new ArchetypeTerm("ac0001", "text ac0001", "desc ac0001"); + items = new ArrayList(); + items.add(item); + item = new ArchetypeTerm("ac0002", "text ac0002", "desc ac0002"); + 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, + null, termDefinitionsList, constraintDefinitionsList, + null, null); + + clean(); + outputter.printOntology(ontology, out); + verifyByFile("multi-language.adl"); + } +} +/* + * ***** 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 MultipleLanguageTest.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): Mattias Forss, Erik Sundvall + * + * 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/MultipleTerminologyTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/MultipleTerminologyTest.java new file mode 100644 index 00000000..936c4999 --- /dev/null +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/MultipleTerminologyTest.java @@ -0,0 +1,125 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class MultipleTerminologyTest" + * 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.List; + +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.Query; +import org.openehr.am.archetype.ontology.QueryBindingItem; +import org.openehr.am.archetype.ontology.TermBindingItem; + +/** + * Multi-terminology ontology serialization test + * + * @author Rong Chen + */ +public class MultipleTerminologyTest extends SerializerTestBase { + + public MultipleTerminologyTest(String test) { + super(test); + } + + public void testPrintOntology() throws Exception { + ArchetypeTerm item = new ArchetypeTerm("at0001", + "text at0001", "desc at0001"); + List items = new ArrayList(); + items.add(item); + OntologyDefinitions definitions = new OntologyDefinitions("en", items); + List termDefinitionsList = + new ArrayList(); + termDefinitionsList.add(definitions); + + List languages = new ArrayList(); + languages.add("en"); + List terminologies = new ArrayList(); + terminologies.add("SNOMED_CT"); + terminologies.add("ICD10"); + + List terms = new ArrayList(); + terms.add("[snomed_ct::1000339]"); + TermBindingItem termBindItem = new TermBindingItem("at0001",terms); + List termBindList = new ArrayList(); + termBindList.add(termBindItem); + OntologyBinding ontologyBind = new OntologyBinding("SNOMED_CT",termBindList); + List termBindingList = new ArrayList(); + termBindingList.add(ontologyBind); + + terms = new ArrayList(); + terms.add("[icd10::1000]"); + terms.add("[icd10::1001]"); + termBindItem = new TermBindingItem("at0001",terms); + termBindList = new ArrayList(); + termBindList.add(termBindItem); + ontologyBind = new OntologyBinding("ICD10",termBindList); + termBindingList.add(ontologyBind); + + Query query = new Query("http://terminology.org?terminology_id=snomed_ct&&has_relation=[102002];with_target=[128004]"); + QueryBindingItem queryBindItem = new QueryBindingItem("ac0001",query); + List constraintBindList = new ArrayList(); + constraintBindList.add(queryBindItem); + ontologyBind = new OntologyBinding("SNOMED_CT",constraintBindList); + List constraintBindingList = new ArrayList(); + constraintBindingList.add(ontologyBind); + + query = new Query("http://terminology.org?terminology_id=icd10&&has_relation=[102002];with_target=[128004]"); + queryBindItem = new QueryBindingItem("ac0001",query); + constraintBindList = new ArrayList(); + constraintBindList.add(queryBindItem); + ontologyBind = new OntologyBinding("ICD10",constraintBindList); + constraintBindingList.add(ontologyBind); + + ArchetypeOntology ontology = new ArchetypeOntology("en", languages, + terminologies, termDefinitionsList, null, termBindingList, constraintBindingList); + clean(); + outputter.printOntology(ontology, out); + verifyByFile("multi-terminology.adl"); + } +} +/* + * ***** 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 MultipleTerminologyTest.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): Mattias Forss, Erik Sundvall + * + * 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/OntologyTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/OntologyTest.java new file mode 100644 index 00000000..62fc07d6 --- /dev/null +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/OntologyTest.java @@ -0,0 +1,129 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class OntologyTest" + * 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.List; + +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.Query; +import org.openehr.am.archetype.ontology.QueryBindingItem; +import org.openehr.am.archetype.ontology.TermBindingItem; + +/** + * Simple ontology serialization test + * + * @author Rong Chen + */ +public class OntologyTest extends SerializerTestBase { + + public OntologyTest(String test) { + super(test); + } + + public void testPrintOntology() throws Exception { + ArchetypeTerm item = new ArchetypeTerm("at0001", "text at0001", + "desc at0001"); + List items = new ArrayList(); + items.add(item); + item = new ArchetypeTerm("at0002", "text at0002", "desc at0002"); + items.add(item); + OntologyDefinitions definitions = new OntologyDefinitions("en", items); + List termDefinitionsList = + new ArrayList(); + termDefinitionsList.add(definitions); + + item = new ArchetypeTerm("ac0001", "text ac0001", "desc ac0001"); + items = new ArrayList(); + items.add(item); + item = new ArchetypeTerm("ac0002", "text ac0002", "desc ac0002"); + items.add(item); + definitions = new OntologyDefinitions("en", items); + List constraintDefinitionsList = + new ArrayList(); + constraintDefinitionsList.add(definitions); + + List languages = new ArrayList(); + languages.add("en"); + List terminologies = new ArrayList(); + terminologies.add("local"); + + List terms = new ArrayList(); + terms.add("[local::100000]"); + TermBindingItem termBindItem = new TermBindingItem("at0001", terms); + List termBindList = + new ArrayList(); + termBindList.add(termBindItem); + terms = new ArrayList(); + terms.add("[local::200000]"); + termBindItem = new TermBindingItem("at0002", terms); + termBindList.add(termBindItem); + OntologyBinding ontologyBind = new OntologyBinding("local", + termBindList); + List termBindingList = new ArrayList(); + termBindingList.add(ontologyBind); + + Query query = new Query("http://terminology.org?terminology_id=" + + "snomed_ct&&has_relation=[102002];with_target=[128004]"); + QueryBindingItem queryBindItem = new QueryBindingItem("ac0001", query); + List constraintBindList = + new ArrayList(); + constraintBindList.add(queryBindItem); + ontologyBind = new OntologyBinding("local", constraintBindList); + List constraintBindingList = + new ArrayList(); + constraintBindingList.add(ontologyBind); + + ArchetypeOntology ontology = new ArchetypeOntology("en", languages, + terminologies, termDefinitionsList, constraintDefinitionsList, + termBindingList, constraintBindingList); + clean(); + outputter.printOntology(ontology, out); + verifyByFile("ontology.adl"); + } +} +/* + * ***** 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 OnotologyTest.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): Erik Sundvall + * + * 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/PrimitiveTypesTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/PrimitiveTypesTest.java new file mode 100644 index 00000000..e9132e43 --- /dev/null +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/PrimitiveTypesTest.java @@ -0,0 +1,76 @@ +package org.openehr.am.serialize; + +import java.util.ArrayList; +import java.util.List; + +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.CInteger; +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.rm.datatypes.quantity.datetime.DvDate; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.quantity.datetime.DvTime; +import org.openehr.rm.support.basic.Interval; + +public class PrimitiveTypesTest extends SerializerTestBase { + + public PrimitiveTypesTest(String test) { + super(test); + } + + public void testPrintCString() throws Exception { + List values = new ArrayList(); + String value = "value"; + String assumed = "assumed value"; + values.add(value); + CString cstring = new CString(null, values, assumed); + outputter.printCString(cstring, out); + verifyByFile("c-string-test.adl"); + } + + public void testPrintCBoolean () throws Exception { + CBoolean cboolean = new CBoolean(true, true, true, true); + outputter.printCBoolean(cboolean, out); + verify("true, false; true"); + } + + public void testPrintDate() throws Exception { + DvDate assumed = new DvDate(2001, 10, 20); + CDate cdate = new CDate("yyyy-mm-dd", null, null, assumed); + outputter.printCDate(cdate, out); + verify("yyyy-mm-dd; 2001-10-20"); + } + + public void testPrintTime() throws Exception { + DvTime assumed = new DvTime("00:00:00"); + CTime ctime = new CTime("hh:mm:ss", null, null, assumed); + outputter.printCTime(ctime, out); + verify("hh:mm:ss; 00:00:00"); + } + public void testPrintDateTime() throws Exception { + DvDateTime assumed = new DvDateTime("2004-10-31T20:10:55"); + String pattern = "yyyy-mm-ddThh:mm:ss"; + CDateTime cdatetime = new CDateTime(pattern, null, null, assumed); + outputter.printCDateTime(cdatetime, out); + verify("yyyy-mm-ddThh:mm:ss; 2004-10-31T20:10:55"); + } + public void testPrintInteger() throws Exception { + Integer assumed = new Integer(8); + Interval i = new Interval(new Integer(1), + new Integer(10)); + CInteger ci = new CInteger(i, null, assumed); + outputter.printCInteger(ci, out); + verify("|1..10|; 8"); + } + public void testPrintReal() throws Exception { + Double assumed = new Double(8.0); + Interval i = new Interval(new Double(1.0), + new Double(8.0)); + CReal cr = new CReal(i, null, assumed); + outputter.printCReal(cr, out); + verify("|1.0..8.0|; 8.0"); + } +} 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 new file mode 100644 index 00000000..978f47d9 --- /dev/null +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/RoundTripTest.java @@ -0,0 +1,46 @@ +package org.openehr.am.serialize; + +import java.io.InputStream; +import java.io.StringReader; + +import org.openehr.am.archetype.Archetype; + +import se.acode.openehr.parser.ADLParser; + +public class RoundTripTest extends SerializerTestBase { + + public void testRoundTripOnSimpleEvaluation() throws Exception { + adlFile = "openEHR-EHR-EVALUATION.test_concept.v1.adl"; + ADLParser parser = new ADLParser(loadFromClasspath(adlFile)); + Archetype archetype = parser.parse(); + + outputter.output(archetype, out); + + parser.ReInit(new StringReader(out.toString())); + + Archetype roundTripedArchetype = parser.parse(); + + assertEquals("adlVersion diff", archetype.getAdlVersion(), + roundTripedArchetype.getAdlVersion()); + assertEquals("archetypeId diff", archetype.getArchetypeId(), + roundTripedArchetype.getArchetypeId()); + assertEquals("concept diff", archetype.getConcept(), + roundTripedArchetype.getConcept()); + assertEquals("definition diff", archetype.getDefinition(), + roundTripedArchetype.getDefinition()); + + // TODO skipped problematic description comparison + // assertEquals("description diff", archetype.getDescription(), + // roundTripedArchetype.getDescription()); + + assertEquals("ontology diff", archetype.getOntology(), + roundTripedArchetype.getOntology()); + assertEquals("original language diff", archetype.getOriginalLanguage(), + roundTripedArchetype.getOriginalLanguage()); + + } + + private InputStream loadFromClasspath(String adl) throws Exception { + return this.getClass().getClassLoader().getResourceAsStream(adl); + } +} 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 new file mode 100644 index 00000000..0271d35b --- /dev/null +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/SerializerTestBase.java @@ -0,0 +1,226 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class SerializerTestBase" + * 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.io.*; +import java.util.*; + +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.terminology.CodeSetAccess; +import org.openehr.rm.support.terminology.OpenEHRCodeSetIdentifiers; +import org.openehr.rm.support.terminology.TerminologyAccess; +import org.openehr.rm.support.terminology.TerminologyService; + +import junit.framework.TestCase; + +public class SerializerTestBase extends TestCase + implements TerminologyService, CodeSetAccess { + + /** + * Constructor + * + * @param test + */ + public SerializerTestBase(String test) { + super(test); + } + + public SerializerTestBase() { + } + + /** + * The fixture set up called before every test method. + */ + protected void setUp() throws Exception { + outputter = new ADLSerializer(); + clean(); + } + + /** + * The fixture clean up called after every test method. + */ + protected void tearDown() throws Exception { + outputter = null; + adlFile = null; + } + + /* clean the string writer for next test */ + protected void clean() { + out = new StringWriter(); + } + + /* take the result from writer and compare with the expected */ + protected void verify(String expected) { + String actual = out.toString(); + verify(expected, actual); + } + + protected void verifyByFile(String expectedFile) throws Exception { + List expected = readFile(expectedFile); + List actual = toLines(out.toString()); + verifyByLines(expected, actual); + } + + private List readFile(String filename) throws Exception { + InputStream input = null; + List list = new ArrayList(); + try { + input = this.getClass().getClassLoader().getResourceAsStream(filename); + BufferedReader reader = new BufferedReader(new InputStreamReader(input)); + String line = reader.readLine(); + while(line != null) { + list.add(line); + line = reader.readLine(); + } + + return list; + + } finally { + if(input != null) { + input.close(); + } + } + } + + private List toLines(String source) { + List list = new ArrayList(); + StringTokenizer tokens = new StringTokenizer(source, "\r\n"); + while(tokens.hasMoreTokens()) { + list.add(tokens.nextToken()); + } + return list; + } + + private void verify(String expected, String actual) { + assertEquals(">>> expected: \r\n" + expected + "\r\n >>> actual:\r\n" + actual, + expected, actual); + } + + /* verify line by line, preceeding and trailing white spaces, line returns are ignored */ + private void verifyByLines(List expected, List actual) { + int expectedSize = expected.size(); + int actualSize = actual.size(); + + // check if preceeding lines match + for(int i = 0; i < expectedSize && i < actualSize; i++) { + String lineExpected = expected.get(i).trim(); + String lineActual = actual.get(i).trim(); + if( ! lineExpected.equals(lineActual)) { + assertEquals(">>> line no." + i + " different.. got[" + + lineActual +"] - expected: " + lineExpected + "]", + lineExpected, lineActual); + } + } + + if(expectedSize != actualSize) { + assertEquals("total number of lines wrong", expectedSize, actualSize); + } + } + + /* field */ + protected ADLSerializer outputter; + protected StringWriter out; + protected String adlFile; + + /* static fields */ + protected static final CodePhrase ENGLISH = new CodePhrase("ISO_639-1", "en"); + + // mocked terminologyService + public CodeSetAccess codeSet(String arg0) { + // return this mock implementation + return this; + } + + public boolean hasCodeSet(String arg0) { + return true; + } + + public boolean hasTerminology(String arg0) { + return true; + } + + public TerminologyAccess terminology(String arg0) { + // TODO Auto-generated method stub + return null; + } + + // mocked codeSetAccess + public Set allCodes() { + // TODO Auto-generated method stub + return null; + } + + public boolean hasCode(CodePhrase arg0) { + return true; + } + + public boolean hasLang(CodePhrase arg0) { + return true; + } + + public String id() { + // TODO Auto-generated method stub + return null; + } + + public List terminologyIdentifiers() { + // TODO Auto-generated method stub + return null; + } + + public List codeSetIdentifiers() { + // TODO Auto-generated method stub + return null; + } + + public Map openehrCodeSets() { + // TODO Auto-generated method stub + return null; + } + + public CodeSetAccess codeSetForId(OpenEHRCodeSetIdentifiers arg0) { + // 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 SerializerTestBase.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/SimpleArchetypeTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/SimpleArchetypeTest.java new file mode 100644 index 00000000..33be739e --- /dev/null +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/SimpleArchetypeTest.java @@ -0,0 +1,83 @@ +package org.openehr.am.serialize; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.assertion.Assertion; +import org.openehr.am.archetype.constraintmodel.CComplexObject; +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.rm.common.generic.RevisionHistory; +import org.openehr.rm.common.resource.ResourceDescription; +import org.openehr.rm.common.resource.TranslationDetails; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.basic.Interval; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.terminology.SimpleTerminologyService; + +/** + * Testcase that verifies print out of a simple archetype + * + * @author Rong.Chen + * + */ +public class SimpleArchetypeTest extends SerializerTestBase { + + public SimpleArchetypeTest(String test) { + super(test); + } + + public void testPrintArchetypeLanguagePart() throws Exception { + String adlVersion = "1.4"; + String id = "adl-test-ENTRY.most_minimal.draft"; + String parentId = null; + String concept = "at0000"; + CodePhrase originalLanguage = new CodePhrase("ISO_639-1", "en"); + + Map translations = null; + ResourceDescription description = null; + RevisionHistory revisionHistory = null; + boolean isControlled = false; + Interval occurrences = new Interval(1, 1); + CComplexObject definition = new CComplexObject("/", "ENTRY", + occurrences, "at0000", null, null); + + ArchetypeTerm item = new ArchetypeTerm("at0000", "most minimal", + "most minimal"); + List items = new ArrayList(); + items.add(item); + OntologyDefinitions definitions = new OntologyDefinitions("en", items); + List termDefinitionsList = + new ArrayList(); + 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, + terminologies, termDefinitionsList, constraintDefinitionsList, + termBindingList, constraintBindingList); + + Set invariants = null; + TerminologyService terminologyService = + SimpleTerminologyService.getInstance(); + + Archetype archetype = new Archetype(adlVersion, id, parentId, concept, + originalLanguage, translations, description, revisionHistory, + isControlled, null, definition, ontology, invariants, + terminologyService); + + clean(); + outputter.output(archetype, out); + verifyByFile("adl-test-entry.most_minimal.test.adl"); + } +} diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml new file mode 100644 index 00000000..2992000a --- /dev/null +++ b/archetype-validator/pom.xml @@ -0,0 +1,89 @@ + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5-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.5 + 1.5 + + + + + + + + commons-lang + commons-lang + 2.4 + + + log4j + log4j + 1.2.13 + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + openehr-aom + ${project.version} + + + openehr + openehr-ap + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + openehr + measure-serv + ${project.version} + + + openehr + 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 100644 index 00000000..79e749c5 --- /dev/null +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java @@ -0,0 +1,1545 @@ +/* + * 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 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.Ordinal; +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 reportConstraintsOnFunctionalPropertiesAsInfo 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; + } + + // check purpose in each available language + for (ResourceDescriptionItem detail : archetype.getDescription().getDetails()) { + 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 (TBD) + 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 cobj + * @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); + } + } + } + + /** 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(); + if (!pattern.equals(".*")) { + // make readability modifications for the pattern + while (pattern.indexOf("(-[a-zA-Z0-9_]+)*\\") >0) { + int i = pattern.indexOf("(-[a-zA-Z0-9_]+)*\\"); + 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("\\.", "."); + } + while (pattern.indexOf("|") >0) { + String oneId = pattern.substring(0,pattern.indexOf("|") ); + pattern = pattern.substring(pattern.indexOf("|")+1); + 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 + boolean containsCorrectNumberOfDots = (StringUtils.countMatches(oneId, ".") == 2); + + // check that the id ends with .v[0..9]* + boolean endsWithDotVNumber =true; // assume it is ok, until proven false + if (oneId.lastIndexOf(".v")== -1) { + endsWithDotVNumber = false; + } else { + String tail = oneId.substring(oneId.lastIndexOf(".v")+2); + log.debug("tail: "+ tail); + if (tail.length() == 0 || !StringUtils.isNumeric(tail)) { + endsWithDotVNumber = false; + } + } + + // check that the first part of the id (the qualified RM Entity) contains the right number of hyphens + boolean containsCorrectNumberOfHyphensInQualifiedRMEntity = true; // assume it is ok, until proven wrong + String qualifiedRMEntity = oneId.substring(0, oneId.indexOf(".")); + if (StringUtils.countMatches(qualifiedRMEntity, "-") != 2) { + containsCorrectNumberOfHyphensInQualifiedRMEntity = false; + } + + // add all the errors + if (!containsCorrectNumberOfDots) { + ValidationError error = new ValidationError(ErrorType.VDFAI, "NUMBEROFDOTS", oneId, slot.path()); + errors.add(error); + + } + if (!endsWithDotVNumber) { + ValidationError error = new ValidationError(ErrorType.VDFAI, "DOTVNUMBER", oneId, slot.path()); + errors.add(error); + + } + if (!containsCorrectNumberOfHyphensInQualifiedRMEntity) { + 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 cobj + * @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; + } + String codes = ""; + for(String code : ccodephrase.getCodeList()) { + if( ! openEHRTerminology.allCodes().contains( + new CodePhrase(TerminologyService.OPENEHR, code))) { + codes += code + ", "; + } + } + if(codes.length() != 0) { + ValidationError error = new ValidationError(ErrorType.VOTC, null, + codes, ccodephrase.path()); + errors.add(error); + } + } + + /** + * @param cobj + * @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 + * + * 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(); + List constraintDefList = + archetype.getOntology().getConstraintDefinitionsList(); + Set termDefLangs = retrieveLanguageSet(termDefList); + Set constraintDefLangs = retrieveLanguageSet(constraintDefList); + ValidationError error = null; + for(String lang : languages) { + 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 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; + Set 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 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 = new Integer(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..161d9d18 --- /dev/null +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ErrorType.java @@ -0,0 +1,80 @@ +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 + 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 100644 index 00000000..377f71f5 --- /dev/null +++ b/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java @@ -0,0 +1,583 @@ +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.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.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, + + // 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, + 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 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 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") || + parentObj.getRmTypeName().equalsIgnoreCase("SECTION")) { + 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")) { + 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..e7aa9dfb --- /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, + 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..10b178a8 --- /dev/null +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ValidationError.java @@ -0,0 +1,139 @@ +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) { + // this(type, null); + // } + + 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 errorText = ResourceBundle.getBundle("validations", locale, UTF8Control.getInstance()).getString(getTextKey()); + if (params != null) { + errorText= MessageFormat.format(errorText, params); + } + return errorText; + } + + protected String getTextKey() { + if (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..81381f48 --- /dev/null +++ b/archetype-validator/src/main/resources/validations.properties @@ -0,0 +1,113 @@ +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 + +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}. +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[0..9]*. +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. +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. \ No newline at end of file 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..75d1c2f6 --- /dev/null +++ b/archetype-validator/src/main/resources/validations_de.properties @@ -0,0 +1,113 @@ +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. + +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}. +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[0..9]*. +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. +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. \ No newline at end of file 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..e4b648d1 --- /dev/null +++ b/archetype-validator/src/main/resources/validations_ru.properties @@ -0,0 +1,113 @@ +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 + +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}. +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[0..9]*. +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. +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. \ No newline at end of file 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..188d58d0 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeSlotCheckTest.java @@ -0,0 +1,24 @@ +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); + } + + + 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..b6a03919 --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeTermValidityTest.java @@ -0,0 +1,68 @@ +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()); + } + } + + 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..068740ae --- /dev/null +++ b/archetype-validator/src/test/java/org/openehr/am/validation/OntologyTranslationCheckTest.java @@ -0,0 +1,53 @@ +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); + } + + 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/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.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-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..8c2be792 --- /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.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/dadl-binding/pom.xml b/dadl-binding/pom.xml new file mode 100644 index 00000000..c81942cc --- /dev/null +++ b/dadl-binding/pom.xml @@ -0,0 +1,84 @@ + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5-SNAPSHOT + + dadl-binding + jar + java dADL Binding + http://www.openehr.org/svn/ref_impl_java/TRUNK/project_page.htm + + openEHR + http://www.openehr.org/ + + 2008 + java openEHR RM and dADL Binding Component + + + + openehr + openehr-rm-core + ${project.version} + + + + + openehr + openehr-aom + ${project.version} + + + + + openehr + adl-parser + ${project.version} + + + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + openehr + measure-serv + ${project.version} + + + openehr + rm-builder + ${project.version} + + + openehr + dadl-parser + ${project.version} + + + junit + junit + 3.8.1 + test + + + commons-jxpath + commons-jxpath + 1.3 + + + commons-io + commons-io + 2.3 + + + 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 new file mode 100644 index 00000000..025803ef --- /dev/null +++ b/dadl-binding/src/main/java/org/openehr/rm/binding/DADLBinding.java @@ -0,0 +1,407 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Class DADLBinding" + * keywords: "binding" + * + * author: "Rong Chen " + * 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.rm.binding; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.openehr.am.parser.AttributeValue; +import org.openehr.am.parser.ComplexObjectBlock; +import org.openehr.am.parser.ContentObject; +import org.openehr.am.parser.KeyedObject; +import org.openehr.am.parser.MultipleAttributeObjectBlock; +import org.openehr.am.parser.ObjectBlock; +import org.openehr.am.parser.PrimitiveObjectBlock; +import org.openehr.am.parser.SimpleValue; +import org.openehr.am.parser.SingleAttributeObjectBlock; +import org.openehr.build.RMObjectBuilder; +import org.openehr.build.RMObjectBuildingException; +import org.openehr.build.SystemValue; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.RMObject; +import org.openehr.rm.datatypes.quantity.ProportionKind; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.basic.Interval; +import org.openehr.rm.support.measurement.MeasurementService; +import org.openehr.rm.support.measurement.SimpleMeasurementService; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.terminology.SimpleTerminologyService; + +/** + * Utility class that binds data in DADL format to openEHR RM + * + * @author rong.chen + */ +public class DADLBinding { + + public DADLBinding() { + try { + TerminologyService termServ; + MeasurementService measureServ; + termServ = SimpleTerminologyService.getInstance(); + measureServ = SimpleMeasurementService.getInstance(); + + CodePhrase lang = new CodePhrase("ISO_639-1", "en"); + CodePhrase charset = new CodePhrase("IANA_character-sets", "UTF-8"); + + Map values = new HashMap(); + values.put(SystemValue.LANGUAGE, lang); + values.put(SystemValue.CHARSET, charset); + values.put(SystemValue.ENCODING, charset); + values.put(SystemValue.TERMINOLOGY_SERVICE, termServ); + values.put(SystemValue.MEASUREMENT_SERVICE, measureServ); + builder = new RMObjectBuilder(values); + + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("failed to start DADLBinding.."); + } + } + + public Object bind(ContentObject co) throws DADLBindingException, + RMObjectBuildingException { + if (co.getAttributeValues() != null) { + + return bindAttributes(null, co.getAttributeValues()); + + } else { + ComplexObjectBlock complexObj = co.getComplexObjectBlock(); + return bindComplexBlock(complexObj); + } + } + + RMObject bindAttributes(String type, List attributes) + throws DADLBindingException, RMObjectBuildingException { + + Map values = new HashMap(); + for (AttributeValue attr : attributes) { + String id = attr.getId(); + Object value = bindObjectBlock(attr.getValue()); + values.put(id, value); + } + return invokeRMObjectBuilder(type, values); + } + + RMObject invokeRMObjectBuilder(String type, Map valueMap) + throws DADLBindingException, RMObjectBuildingException { + + if(type == null) { + type = builder.findMatchingRMClass(valueMap); + if(type == null) { + throw new DADLBindingException("failed untyped binding with - " + + valueMap); + } + } + RMObject rmObj = builder.construct(type, valueMap); + return rmObj; + } + + Object bindObjectBlock(ObjectBlock block) throws DADLBindingException, + RMObjectBuildingException { + if (block instanceof PrimitiveObjectBlock) { + return bindPrimitiveBlock((PrimitiveObjectBlock) block); + } else { + return bindComplexBlock((ComplexObjectBlock) block); + } + } + + Object bindPrimitiveBlock(PrimitiveObjectBlock block) + throws DADLBindingException { + if (block.getSimpleValue() != null) { + return block.getSimpleValue().getValue(); + } else if (block.getSimpleListValue() != null) { + List values = block.getSimpleListValue(); + List list = new ArrayList(values.size()); + for (SimpleValue sv : values) { + list.add(sv.getValue()); + } + return list; + } else if (block.getSimpleIntervalValue() != null) { + Interval values = block.getSimpleIntervalValue(); + // TODO + return null; + } else if (block.getTermCode() != null) { + return block.getTermCode(); + } else if (block.getTermCodeListValue() != null) { + return block.getTermCodeListValue(); + } else { + throw new DADLBindingException("empty block"); + } + + } + + Object bindComplexBlock(ComplexObjectBlock block) + throws DADLBindingException, RMObjectBuildingException { + + if (block instanceof SingleAttributeObjectBlock) { + SingleAttributeObjectBlock singleBlock = + (SingleAttributeObjectBlock) block; + + // a special case to deal with empty attribute list + if("LIST".equalsIgnoreCase(singleBlock.getTypeIdentifier()) + && singleBlock.getAttributeValues().isEmpty()) { + + return new ArrayList(); + } + + return bindAttributes(singleBlock.getTypeIdentifier(), singleBlock + .getAttributeValues()); + + } else { + MultipleAttributeObjectBlock multiBlock = + (MultipleAttributeObjectBlock) block; + String type = multiBlock.getTypeIdentifier(); + List list = multiBlock.getKeyObjects(); + // TODO assume list? + List valueList = new ArrayList(); + for(KeyedObject ko : list) { + Object key = ko.getKey().getValue(); + Object value = bindObjectBlock(ko.getObject()); + valueList.add(value); + } + return valueList; + } + } + + public List toDADL(Object obj) throws Exception { + List lines = new ArrayList(); + return toDADL(obj, 1, lines); + } + + public List toDADL(Object obj, int indent, List lines) throws Exception { + + + log.debug("toDADL on obj.getClass: " + obj.getClass().getCanonicalName() + + ", indent: " + indent + ", line.size: " + lines.size()); + + Class klass = obj.getClass(); + + String className = klass.getSimpleName(); + String rmName = toUnderscoreSeparated(className).toUpperCase(); + + String typeHeader = "(" + rmName + ") <"; + int size = lines.size(); + if(size == 0) { + lines.add(typeHeader); + } else { + String l = lines.get(size - 1); + l += typeHeader; + lines.set(size -1, l); + } + + SortedMap attributes = attributeMap(obj.getClass()); + 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); + if(attribute.system()) { + continue; + } + + if("parent".equals(attribute.name())) { + continue; // causing dead-loops + } + + Method getter = getter(name, obj.getClass()); + if(getter != null) { + value = getter.invoke(obj, null); + buf = new StringBuffer(); + if(value != null ) { + for(int i = 0; i < indent; i++) { + buf.append("\t"); + } + buf.append(toUnderscoreSeparated(name)); + buf.append(" = "); + + if(isOpenEHRRMClass(value) && !(value instanceof ProportionKind)) { + + lines.add(buf.toString()); + + log.debug("fetching attribute: " + name); + + toDADL(value, indent + 1, lines); + + } else if(value instanceof List) { + + buf.append("<"); + lines.add(buf.toString()); + + List list = (List) value; + for(int i = 0, j = list.size(); i < j; i++) { + buf = new StringBuffer(); + for(int k = 0; k < indent + 1; k++) { + buf.append("\t"); + } + lines.add(buf.toString() + "[" + (i+1) + "] = "); + toDADL(list.get(i), indent + 2, lines); + } + + buf = new StringBuffer(); + for(int i = 0; i < indent; i++) { + buf.append("\t"); + } + buf.append(">"); + lines.add(buf.toString()); + + } else { + + buf.append("<"); + if(value instanceof String || value instanceof Boolean) { + buf.append("\""); + buf.append(value); + buf.append("\""); + } else { + buf.append(value.toString()); + } + buf.append(">"); + lines.add(buf.toString()); + } + + } + } + } + buf = new StringBuffer(); + for(int i = 0; i < indent - 1; i++) { + buf.append("\t"); + } + buf.append(">"); + lines.add(buf.toString()); + return lines; + } + + private Method getter(String attributeName, Class klass) { + Method[] methods = klass.getMethods(); + String name = "get" + attributeName.substring(0, 1).toUpperCase() + + attributeName.substring(1); + + log.debug("search getter method of name '" + name + "'"); + + for(Method method : methods) { + if(method.getName().equals(name)) { + Type[] paras = method.getParameterTypes(); + if(paras.length == 0) { + return method; + } + } + } + return null; + } + + /** + * 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 SortedMap attributeMap(Class rmClass) { + SortedMap map = new TreeMap(); + Constructor constructor = fullConstructor(rmClass); + + if(constructor == null) { + throw new IllegalArgumentException("Unknown RM Class: " + + rmClass.getClass().getCanonicalName()); + } + + 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; + } + + 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(); + } + + private boolean isOpenEHRRMClass(Object obj) { + return obj.getClass().getName().contains(OPENEHR_RM_PACKAGE); + } + + + private RMObjectBuilder builder; + private static Logger log = Logger.getLogger(DADLBinding.class); + private static final String OPENEHR_RM_PACKAGE = "org.openehr.rm."; + private static final String LINE_RETURN = "\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 DADLBinding.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/dadl-binding/src/main/java/org/openehr/rm/binding/DADLBindingException.java b/dadl-binding/src/main/java/org/openehr/rm/binding/DADLBindingException.java new file mode 100644 index 00000000..75635669 --- /dev/null +++ b/dadl-binding/src/main/java/org/openehr/rm/binding/DADLBindingException.java @@ -0,0 +1,54 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Class DADLBindingException" + * keywords: "binding" + * + * author: "Rong Chen " + * 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.rm.binding; + +/** + * Exception thrown by dadl binding utility + * + * @author rong.chen + */ +public class DADLBindingException extends Exception { + + public DADLBindingException(String msg) { + super(msg); + } + + public DADLBindingException() { + } +} +/* + * ***** 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 DADLBindingException.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): + * + * 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/dadl-binding/src/main/java/org/openehr/rm/binding/RMInspector.java b/dadl-binding/src/main/java/org/openehr/rm/binding/RMInspector.java new file mode 100644 index 00000000..84e72fa0 --- /dev/null +++ b/dadl-binding/src/main/java/org/openehr/rm/binding/RMInspector.java @@ -0,0 +1,528 @@ +package org.openehr.rm.binding; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.util.*; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +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.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.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.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.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 { + + public static RMInspector getInstance() { + return soleInstance; + } + + /** + * Create a RMInspector + */ + private 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, + + // 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, + UUID.class, + VersionTreeID.class, + + // datatypes classes + DvBoolean.class, + DvURI.class, + DvState.class, + DvIdentifier.class, + DvText.class, + DvCodedText.class, + DvParagraph.class, + CodePhrase.class, + DvCount.class, + DvOrdinal.class, + DvQuantity.class, + DvInterval.class, + DvProportion.class, + ProportionKind.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, 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 class 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 attribute as the value for + * all parameters of the full constructor in the RMObject + * + * @param rmClass + * @return + */ + public 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) { + Class rmClass = typeMap.get(rmClassName); + if (rmClass == null) { + rmClass = upperCaseMap.get(rmClassName.replace("_", "")); + } + 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); + + 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; + } + + /* + * 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; + private static final RMInspector soleInstance = new RMInspector(); + + 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/dadl-binding/src/main/java/org/openehr/rm/binding/XPathUtil.java b/dadl-binding/src/main/java/org/openehr/rm/binding/XPathUtil.java new file mode 100644 index 00000000..50e512c9 --- /dev/null +++ b/dadl-binding/src/main/java/org/openehr/rm/binding/XPathUtil.java @@ -0,0 +1,206 @@ +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.datastructure.itemstructure.representation.Element; + +public class XPathUtil { + + public Set extractXPaths(Locatable root) throws Exception { + 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); + } + } + } + } + + public Map> extractPaths(Locatable root) throws Exception { + 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); + + } else if(obj instanceof Locatable) { + + Locatable locatable = (Locatable) obj; + + inspector.retrieveRMAttributes(obj.getClass().getSimpleName()); + Class klass = obj.getClass(); + String className = klass.getSimpleName(); + + //System.out.println(">>> className: " + className); + + Map attributeMap = inspector.attributeMap(klass); + for(String attributeName : attributeMap.keySet()) { + + //System.out.println("Attribute name: " + attributeName); + + Attribute attribute = attributeMap.get(attributeName); + + if(attribute.system()) { + continue; + } + + String methodName = "get" + + attributeName.substring(0, 1).toUpperCase() + + attributeName.substring(1); + + //System.out.println("method name: " + methodName); + + Method method = klass.getMethod(methodName, null); + + assert(method != null); + + Object value = method.invoke(obj, null); + + if(value != null && !methodName.equals("getParent")) { + + //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()); + } + } + + public Set extractRootXPaths(Locatable root) throws Exception { + 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); + } + } + } + } + + 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 new file mode 100644 index 00000000..1c926a51 --- /dev/null +++ b/dadl-binding/src/test/java/org/openehr/rm/binding/BindRMToDADLTest.java @@ -0,0 +1,165 @@ +package org.openehr.rm.binding; + +import java.io.*; +import java.util.*; + +import org.openehr.rm.composition.content.entry.Observation; +import org.openehr.rm.datastructure.history.History; +import org.openehr.rm.datastructure.history.PointEvent; +import org.openehr.rm.datatypes.basic.DvBoolean; +import org.openehr.rm.datatypes.quantity.DvOrdinal; +import org.openehr.rm.datatypes.quantity.DvQuantity; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.datatypes.text.DvText; + +public class BindRMToDADLTest extends DADLBindingTestBase { + + public void tearDown() { + expected = null; + actual = null; + } + + public void testBindDvText() throws Exception { + DvText dvText = new DvText("sitting"); + expected = readLines("typed_dv_text.dadl"); + actual = binding.toDADL(dvText); + assertEquals(expected, actual); + } + + public void testBindDvBoolean() throws Exception { + DvBoolean dv = new DvBoolean("true"); + expected = readLines("typed_dv_boolean.dadl"); + actual = binding.toDADL(dv); + assertEquals(expected, actual); + } + + public void testBindDvQuantity() throws Exception { + DvQuantity q = new DvQuantity("mmHg", 120.0, 1); + expected = readLines("typed_dv_quantity2.dadl"); + actual = binding.toDADL(q); + assertEquals(expected, actual); + } + + public void testBindDvOrdinal() throws Exception { + DvOrdinal ordinal = new DvOrdinal(1, + new DvCodedText("Sitting", + new CodePhrase("SNOMED-CT", "12345678"))); + + expected = readLines("typed_dv_ordinal.dadl"); + actual = binding.toDADL(ordinal); + + assertLinesEqual(expected, actual); + } + + public void testBindDvDateTime() throws Exception { + DvDateTime dv = (new DvDateTime(2013, 03, 04, 16, 46, 16, TimeZone.getDefault())); + List dvStrLines = binding.toDADL(dv); + Object rmObj2 = bindString(toString(dvStrLines)); + assertEquals(dv, rmObj2); + } + + public void testBindPointEvent() throws Exception { + rmObj = bind("point_event2.dadl"); + + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not PointEvent: " + rmObj.getClass().getName(), + rmObj instanceof PointEvent); + + PointEvent event = (PointEvent) rmObj; + + expected = readLines("point_event2.dadl"); + actual = binding.toDADL(event); + + assertLinesEqual(expected, actual); + } + + public void testBindHistory() throws Exception { + rmObj = bind("history.dadl"); + + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not History: " + rmObj.getClass().getName(), + rmObj instanceof History); + + History history = (History) rmObj; + + expected = readLines("history2.dadl"); + actual = binding.toDADL(history); + + //print(actual); + + assertLinesEqual(expected, actual); + } + + public void testBindObservation() throws Exception { + rmObj = bind("observation.dadl"); + + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not Observation: " + rmObj.getClass().getName(), + rmObj instanceof Observation); + + Observation obs = (Observation) rmObj; + + expected = readLines("observation3.dadl"); + actual = binding.toDADL(obs); + + //print(actual); + + String dadl = toString(actual); + + // round-trip!! + rmObj = bindString(dadl); + + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not Observation: " + rmObj.getClass().getName(), + rmObj instanceof Observation); + + obs = (Observation) rmObj; + List afterRoundTrip = binding.toDADL(obs); + + assertLinesEqual(actual, afterRoundTrip); + } + + private List readLines(String name) throws Exception { + List lines = new ArrayList(); + BufferedReader reader = + new BufferedReader(new InputStreamReader( + this.getClass().getClassLoader().getResourceAsStream(name))); + + String line = reader.readLine(); + while(line != null) { + lines.add(line); + line = reader.readLine(); + } + return lines; + } + + private String toString(List lines) { + StringBuffer buf = new StringBuffer(); + for(int i = 0, j = lines.size(); i < j; i++) { + buf.append(lines.get(i)); + } + return buf.toString(); + } + + private void assertLinesEqual(List expected, List actual) { + assertEquals("line number differ, expected: " + + expected.size() + ", but got: " + actual.size(), + expected.size(), actual.size()); + for(int i = 0; i < expected.size(); i++) { + assertEquals("line " + i + " differ", expected.get(i).trim(), + actual.get(i).trim()); + } + } + + private void print(List lines) { + System.out.println("total lines: " + lines.size()); + for(Iterator it = lines.iterator(); it.hasNext();) { + System.out.println(it.next()); + } + } + + private List expected; + private List actual; +} 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 new file mode 100644 index 00000000..ef19c32a --- /dev/null +++ b/dadl-binding/src/test/java/org/openehr/rm/binding/DADLBindingTest.java @@ -0,0 +1,371 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Class DADLBindingTest" + * keywords: "binding" + * + * author: "Rong Chen " + * 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.rm.binding; + +import java.io.InputStream; +import java.util.TimeZone; + +import org.joda.time.DateTime; +import org.openehr.am.parser.*; +import org.openehr.rm.common.archetyped.Archetyped; +import org.openehr.rm.common.generic.PartySelf; +import org.openehr.rm.composition.content.entry.Observation; +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.ItemList; +import org.openehr.rm.datastructure.itemstructure.ItemTree; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datatypes.quantity.DvOrdinal; +import org.openehr.rm.datatypes.quantity.DvQuantity; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +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.*; + +import junit.framework.TestCase; + +public class DADLBindingTest extends DADLBindingTestBase { + + public void setUp() throws Exception { + binding = new DADLBinding(); + } + + public void tearDown() throws Exception { + rmObj = null; + } + + public void testBindTypedDvQuantity() throws Exception { + rmObj = bind("typed_dv_quantity.dadl"); + assertTrue("rmObject not DvQuantity", rmObj instanceof DvQuantity); + + DvQuantity dq = (DvQuantity) rmObj; + assertEquals("DvQuantity magnitude wrong", 120.0, dq.getMagnitude(), 0); + assertEquals("DvQuantity units wrong", "mmHg", dq.getUnits()); + } + + public void testBindTypedDvOrdinal() throws Exception { + rmObj = bind("typed_dv_ordinal.dadl"); + assertTrue("rmObject not DvOrdinal", rmObj instanceof DvOrdinal); + + DvOrdinal expected = new DvOrdinal(1, new DvCodedText("Sitting", + new CodePhrase("SNOMED-CT", "12345678"))); + } + + public void testBindUntypedDvQuantity() throws Exception { + rmObj = bind("dv_quantity.dadl"); + assertTrue("rmObject not DvQuantity", rmObj instanceof DvQuantity); + + DvQuantity dq = (DvQuantity) rmObj; + assertEquals("DvQuantity magnitude wrong", 120.0, dq.getMagnitude(), 0); + assertEquals("DvQuantity units wrong", "mmHg", dq.getUnits()); + } + + public void testBindTypedDvText() throws Exception { + rmObj = bind("typed_dv_text.dadl"); + assertTrue("rmObject not DvText", rmObj instanceof DvText); + + DvText dt = (DvText) rmObj; + assertEquals("DvText value wrong", "sitting", dt.getValue()); + } + + public void testBindUntypedElement() throws Exception { + rmObj = bind("element.dadl"); + + assertTrue("rmObject not Element", rmObj instanceof Element); + Element element = (Element) rmObj; + assertEquals("element name wrong", "systolic", + element.getName().getValue()); + assertEquals("element archetypeNodeId wrong", "at0004", + element.getArchetypeNodeId()); + assertTrue("dataValue not DvQuantity", + element.getValue() instanceof DvQuantity); + DvQuantity dq = (DvQuantity) element.getValue(); + assertEquals("dvQuantity magnitude wrong", 120.0, dq.getMagnitude(), 0); + assertEquals("dvQuantity units wrong", "mmHg", dq.getUnits()); + } + + public void testBindTypedEmptyElement() throws Exception { + rmObj = bind("empty_element_with_null_flavour.dadl"); + + assertTrue("rmObject not Element", rmObj instanceof Element); + Element element = (Element) rmObj; + assertEquals("element name wrong", "systolic", + element.getName().getValue()); + assertEquals("element archetypeNodeId wrong", "at0004", + element.getArchetypeNodeId()); + assertNull(element.getValue()); + } + + public void testBindTypedTextElement() throws Exception { + rmObj = bind("element_with_text.dadl"); + + assertTrue("rmObject not Element", rmObj instanceof Element); + Element element = (Element) rmObj; + assertEquals("element name wrong", "text", + element.getName().getValue()); + assertEquals("element archetypeNodeId wrong", "at0001", + element.getArchetypeNodeId()); + DvText text = (DvText) element.getValue(); + assertEquals("text value", text.getValue()); + } + + public void testBindUntypedItemList() throws Exception { + rmObj = bind("item_list.dadl"); + + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not ItemList: " + + rmObj.getClass().getSimpleName(), rmObj instanceof ItemList); + + ItemList itemList = (ItemList) rmObj; + assertEquals("ItemList name wrong", "item list", + itemList.getName().getValue()); + assertEquals("ItemList.items size wrong", 2, itemList.getItems().size()); + assertEquals("itemList.items[0].value.magnitude wrong", 120.0, + ((DvQuantity) itemList.ithItem(0).getValue()).getMagnitude(), 0); + assertEquals("itemList.items[1].value.magnitude wrong", 80.0, + ((DvQuantity) itemList.ithItem(1).getValue()).getMagnitude(), 0); + } + + public void testBindEmptyItemList() throws Exception { + rmObj = bind("empty_item_list.dadl"); + + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not ItemList: " + + rmObj.getClass().getSimpleName(), rmObj instanceof ItemList); + + ItemList itemList = (ItemList) rmObj; + assertEquals("ItemList name wrong", "item list", + itemList.getName().getValue()); + assertEquals("ItemList.items size wrong", 0, itemList.getItems().size()); + } + + public void testBindPointEvent() throws Exception { + rmObj = bind("point_event.dadl"); + + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not PointEvent: " + rmObj.getClass().getName(), + rmObj instanceof PointEvent); + + PointEvent event = (PointEvent) rmObj; + assertEquals("pointEvent.time wrong", + new DvDateTime("2005-12-03T09:22:00"), event.getTime()); + assertEquals("pointEvent.name.value wrong", "sitting", + event.getName().getValue()); + } + + public void testBindHistory() throws Exception { + rmObj = bind("history.dadl"); + + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not History: " + rmObj.getClass().getSimpleName(), + rmObj instanceof History); + + History history = (History) rmObj; + assertEquals("history.name.value wrong", "history", + history.getName().getValue()); + assertEquals("history.origin wrong", + new DvDateTime("2007-10-30T09:22:00"), history.getOrigin()); + assertEquals("history.event.size wrong", 1, history.getEvents().size()); + assertEquals("history.events[0].time wrong", + new DvDateTime("2005-12-03T09:22:00"), + ((Event) history.getEvents().get(0)).getTime()); + } + + public void testBindTypedArchetypID() throws Exception { + rmObj = bind("typed_archetype_id.dadl"); + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not ArchetypeID: " + rmObj.getClass().getName(), + rmObj instanceof ArchetypeID); + ArchetypeID archetypeId = (ArchetypeID) rmObj; + assertEquals("archetypeId.value wrong", + "openEHR-EHR-OBSERVATION.blood_pressure.v1", + archetypeId.getValue()); + } + + public void testBindTypedTerminologyID() throws Exception { + rmObj = bind("typed_terminology_id.dadl"); + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not ArchetypeID: " + rmObj.getClass().getName(), + rmObj instanceof TerminologyID); + TerminologyID id = (TerminologyID) rmObj; + assertEquals("archetypeId.value wrong", "openehr", id.getValue()); + } + + public void testBindArchetyped() throws Exception { + rmObj = bind("archetyped.dadl"); + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not Archetyped: " + rmObj.getClass().getName(), + rmObj instanceof Archetyped); + Archetyped archetyped = (Archetyped) rmObj; + assertEquals("archtyped.archetypeId wrong", + "openEHR-EHR-OBSERVATION.blood_pressure.v1", + archetyped.getArchetypeId().getValue()); + assertEquals("archtyped.rmVersion wrong", "1.0.1", + archetyped.getRmVersion()); + } + + public void testBindCodePhrase() throws Exception { + rmObj = bind("code_phrase.dadl"); + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not CodePhrase: " + rmObj.getClass().getName(), + rmObj instanceof CodePhrase); + CodePhrase cp = (CodePhrase) rmObj; + assertEquals("codePhrase.terminologyId wrong", "ISO_639-1", + cp.getTerminologyId().getValue()); + assertEquals("codePhrase.codeString", "en", cp.getCodeString()); + } + + public void testUntypedDvCodedText() throws Exception { + rmObj = bind("dv_coded_text.dadl"); + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not DvCodedText: " + rmObj.getClass().getName(), + rmObj instanceof DvCodedText); + + DvCodedText dt = (DvCodedText) rmObj; + CodePhrase cp = (CodePhrase) dt.getDefiningCode(); + assertEquals("dvCodedText.definingCode.terminologyId wrong", "ISO_639-1", + cp.getTerminologyId().getValue()); + assertEquals("dvCodedText.value wrong", "sitting", + dt.getValue()); + } + + public void testBindTypedPartySelf() throws Exception { + rmObj = bind("typed_party_self.dadl"); + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not PartySelf: " + rmObj.getClass().getName(), + rmObj instanceof PartySelf); + } + + public void testBindSimpleObservation() throws Exception { + rmObj = bind("observation.dadl"); + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not Observation: " + rmObj.getClass().getName(), + rmObj instanceof Observation); + + Observation observation = (Observation) rmObj; + Event event = observation.getData().getEvents().get(0); + ItemList list = (ItemList) event.getData(); + assertEquals("observatoin.events[0].data.items.size wrong", 2, + list.getItems().size()); + DvQuantity dq = (DvQuantity) list.getItems().get(0).getValue(); + assertEquals("items[0].value.magnitude wrong", 120.0, + dq.getMagnitude(), 0); + dq = (DvQuantity) list.getItems().get(1).getValue(); + assertEquals("items[0].value.magnitude wrong", 80.0, + dq.getMagnitude(), 0); + + assertNull("data.events[0].state not null", event.getState()); + } + + public void testBindObservationWithEventState() throws Exception { + rmObj = bind("observation2.dadl"); + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not Observation: " + rmObj.getClass().getName(), + rmObj instanceof Observation); + + Observation observation = (Observation) rmObj; + Event event = observation.getData().getEvents().get(0); + ItemList list = (ItemList) event.getData(); + assertEquals("observatoin.data.events[0].data.items.size wrong", 2, + list.getItems().size()); + DvQuantity dq = (DvQuantity) list.getItems().get(0).getValue(); + assertEquals("items[0].value.magnitude wrong", 120.0, + dq.getMagnitude(), 0); + dq = (DvQuantity) list.getItems().get(1).getValue(); + assertEquals("items[0].value.magnitude wrong", 80.0, + dq.getMagnitude(), 0); + + assertNotNull("data.events[0].state null", event.getState()); + list = (ItemList) event.getState(); + assertEquals("event.state.size wrong", 1, list.getItems().size()); + DvCodedText codedText = (DvCodedText) list.getItems().get(0).getValue(); + assertEquals("event.state.items[0].value.value wrong", "Sitting", + codedText.getValue()); + assertEquals("event.state.items[0].value.definingCode.terminologyId wrong", + "local", codedText.getDefiningCode().getTerminologyId().getValue()); + assertEquals("event.state.items[0].value.definingCode.codeString wrong", + "at1001", codedText.getDefiningCode().getCodeString()); + + // test with paths + String path = "/data/events[0]/data/items[0]/value/magnitude"; + } + + public void testBindSimpleTypedItemTree() throws Exception { + rmObj = bind("item_tree_bp2.dadl"); + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not ItemTree: " + rmObj.getClass().getName(), + rmObj instanceof ItemTree); + + ItemTree itemTree = (ItemTree) rmObj; + assertEquals("ItemList name wrong", "item tree", + itemTree.getName().getValue()); + assertEquals("itemTree.items size wrong", 2, itemTree.getItems().size()); + assertEquals("itemTree.items[0].value.magnitude wrong", 120.0, + ((DvQuantity) ((Element) itemTree.getItems().get(0)).getValue()).getMagnitude(), 0); + assertEquals("itemTree.items[1].value.magnitude wrong", 80.0, + ((DvQuantity) ((Element) itemTree.getItems().get(1)).getValue()).getMagnitude(), 0); + + } + + public void testBindComplexItemTree() throws Exception { + rmObj = bind("item_tree_bp.dadl"); + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not ItemTree: " + rmObj.getClass().getName(), + rmObj instanceof ItemTree); + + ItemTree itemTree = (ItemTree) rmObj; + assertEquals("ItemList name wrong", "item tree", + itemTree.getName().getValue()); + assertEquals("itemTree.items size wrong", 3, itemTree.getItems().size()); + assertEquals("itemTree.items[0].value.magnitude wrong", 120.0, + ((DvQuantity) ((Element) itemTree.getItems().get(0)).getValue()).getMagnitude(), 0); + assertEquals("itemTree.items[1].value.magnitude wrong", 80.0, + ((DvQuantity) ((Element) itemTree.getItems().get(1)).getValue()).getMagnitude(), 0); + + Object value = itemTree.itemAtPath("/items[at0006]/items[at0007]/value"); + assertTrue(value instanceof DvQuantity); + assertEquals(150.0, ((DvQuantity) value).getMagnitude(), 0); + + + } + + +} +/* + * ***** 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 DADLBindingTest.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): + * + * 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/dadl-binding/src/test/java/org/openehr/rm/binding/DADLBindingTestBase.java b/dadl-binding/src/test/java/org/openehr/rm/binding/DADLBindingTestBase.java new file mode 100644 index 00000000..e882e435 --- /dev/null +++ b/dadl-binding/src/test/java/org/openehr/rm/binding/DADLBindingTestBase.java @@ -0,0 +1,47 @@ +package org.openehr.rm.binding; + +import java.io.InputStream; + +import org.openehr.am.parser.*; + +import junit.framework.TestCase; + +public class DADLBindingTestBase extends TestCase { + + public void setUp() throws Exception { + binding = new DADLBinding(); + } + + public void tearDown() throws Exception { + rmObj = null; + } + + /* + * Loads dadl from file and binds data to RM object + */ + Object bind(String filename) throws Exception { + DADLParser parser = new DADLParser(fromClasspath(filename)); + ContentObject contentObj = parser.parse(); + return binding.bind(contentObj); + } + + Object bindString(String dadl) throws Exception { + DADLParser parser = new DADLParser(dadl); + ContentObject contentObj = parser.parse(); + return binding.bind(contentObj); + } + + /* + * Loads given resource from classpath + * + * @param adl + * @return + * @throws Exception + */ + InputStream fromClasspath(String res) throws Exception { + return this.getClass().getClassLoader().getResourceAsStream(res); + } + + protected Object rmObj; + protected DADLBinding binding; +} 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 new file mode 100644 index 00000000..c2f4c7bf --- /dev/null +++ b/dadl-binding/src/test/java/org/openehr/rm/binding/DuplicatedCodesTest.java @@ -0,0 +1,15 @@ +package org.openehr.rm.binding; + +import org.openehr.am.parser.ContentObject; +import org.openehr.am.parser.DADLParser; + +public class DuplicatedCodesTest extends DADLBindingTestBase { + + public void testDuplicatedCodesInMap() throws Exception { + DADLParser parser = new DADLParser(fromClasspath("duplicated_codes.dadl")); + ContentObject contentObj = parser.parse(); + + System.out.println(""); + } + +} 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 new file mode 100644 index 00000000..9472b324 --- /dev/null +++ b/dadl-binding/src/test/java/org/openehr/rm/binding/LoadTest.java @@ -0,0 +1,27 @@ +package org.openehr.rm.binding; + +import org.openehr.rm.composition.content.entry.Observation; + +public class LoadTest extends DADLBindingTestBase { + + public void testLoadHeight() throws Exception { + rmObj = bind("observation2.dadl"); + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not Observation: " + rmObj.getClass().getName(), + rmObj instanceof Observation); + } + + public void testLoadBodyWegith() throws Exception { + rmObj = bind("body_weight.dadl"); + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not Observation: " + rmObj.getClass().getName(), + rmObj instanceof Observation); + } + + public void testLoadDemographics() throws Exception { + rmObj = bind("demographics.dadl"); + assertNotNull("rmObject null", rmObj); + assertTrue("rmObject not Observation: " + rmObj.getClass().getName(), + rmObj instanceof Observation); + } +} 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 new file mode 100644 index 00000000..700570c8 --- /dev/null +++ b/dadl-binding/src/test/java/org/openehr/rm/binding/XPathTest.java @@ -0,0 +1,576 @@ +package org.openehr.rm.binding; + +import java.io.File; +import java.io.InputStream; +import java.util.*; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.jxpath.JXPathContext; +import org.openehr.am.archetype.Archetype; +import org.openehr.rm.Attribute; +import org.openehr.rm.common.archetyped.Archetyped; +import org.openehr.rm.composition.Composition; +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.datastructure.itemstructure.representation.Item; +import org.openehr.rm.datatypes.quantity.DvQuantity; +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.measurement.MeasurementService; + +public class XPathTest extends DADLBindingTestBase { + + public void testCreatePathMapWithOrderSet() throws Exception { + Composition composition = (Composition) bind("order_set1.dadl"); + assertEquals(3, composition.getContent().size()); + } + + public void testGetValue() throws Exception { + ItemTree tree = createTree(); + JXPathContext context = JXPathContext.newContext(tree); + assertTrue(context.getValue("/items[2]") instanceof Cluster); + 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); + assertTrue(attributeMap.containsKey("items")); + } + + public void testCreatePathMapWithDefaultTree() throws Exception { + ItemTree tree = createTree(); + XPathUtil util = new XPathUtil(); + Map> actual = util.extractPaths(tree); + + assertEquals(5, actual.size()); + + // first element + Set set = actual.get("/items[at0001]"); + assertEquals(1, set.size()); + assertEquals("/items[1]", set.toArray()[0]); + + // second element + set = actual.get("/items[at0005]/items[at0002]"); + assertEquals(1, set.size()); + assertEquals("/items[2]/items[1]", set.toArray()[0]); + + // third element + set = actual.get("/items[at0005]/items[at0003]"); + assertEquals(1, set.size()); + assertEquals("/items[2]/items[2]", set.toArray()[0]); + + // forth element + set = actual.get("/items[at0005]/items[at0004]"); + assertEquals(1, set.size()); + assertEquals("/items[2]/items[3]", set.toArray()[0]); + + // fifth element + set = actual.get("/items[at0006]"); + assertEquals(1, set.size()); + assertEquals("/items[3]", set.toArray()[0]); + } + + public void testCreatePathMapWithRepeatedCluster() throws Exception { + ItemTree tree = createTreeWithRepeatedCluster(); + XPathUtil util = new XPathUtil(); + Map> actual = util.extractPaths(tree); + assertEquals(5, 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(2, set.size()); + assertTrue(set.contains("/items[2]/items[1]")); + assertTrue(set.contains("/items[3]/items[1]")); + + // third element + set = actual.get("/items[at0005]/items[at0003]"); + assertEquals(2, set.size()); + assertTrue(set.contains("/items[2]/items[2]")); + assertTrue(set.contains("/items[3]/items[2]")); + + // forth element + set = actual.get("/items[at0005]/items[at0004]"); + assertEquals(2, set.size()); + assertTrue(set.contains("/items[2]/items[3]")); + assertTrue(set.contains("/items[3]/items[3]")); + + // fifth element + set = actual.get("/items[at0006]"); + assertEquals(1, set.size()); + assertTrue(set.contains("/items[4]")); + } + + public void testCreatePathMapWithRepeatedSampleElement() throws Exception { + ItemTree tree = createTreeWithRepeatedElement(); + XPathUtil util = new XPathUtil(); + Map> actual = util.extractPaths(tree); + + assertEquals(5, actual.size()); + + // first element, and its copy + Set set = actual.get("/items[at0001]"); + assertEquals(2, set.size()); + assertTrue(set.contains("/items[1]")); + assertTrue(set.contains("/items[2]")); + + // second element + set = actual.get("/items[at0005]/items[at0002]"); + assertEquals(1, set.size()); + assertEquals("/items[3]/items[1]", set.toArray()[0]); + + // third element + set = actual.get("/items[at0005]/items[at0003]"); + assertEquals(1, set.size()); + assertEquals("/items[3]/items[2]", set.toArray()[0]); + + // forth element + set = actual.get("/items[at0005]/items[at0004]"); + assertEquals(1, set.size()); + assertEquals("/items[3]/items[3]", set.toArray()[0]); + + // fifth element + set = actual.get("/items[at0006]"); + assertEquals(1, set.size()); + assertTrue(set.contains("/items[4]")); + } + + public void testExtratRootPathWithOneSlot() throws Exception { + ItemTree tree = (ItemTree) bind("tree_slot.dadl"); + Set paths = new XPathUtil().extractRootXPaths(tree); + assertEquals(1, paths.size()); + assertTrue(paths.contains("/items[4]")); + } + + public void testExtratRootPathWithTwoSlots() throws Exception { + 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"); + + XPathUtil util = new XPathUtil(); + 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]")); + + // third element + set = actual.get("/items[at0005]/items[at0003]"); + assertEquals(1, set.size()); + assertTrue(set.contains("/items[2]/items[2]")); + + // forth element + set = actual.get("/items[at0005]/items[at0004]"); + assertEquals(1, set.size()); + assertTrue(set.contains("/items[2]/items[3]")); + + // fifth element + set = actual.get("/items[at0006]"); + assertEquals(1, set.size()); + 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"); + + 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]")); + + // third element + set = actual.get("/items[adl-test-CLUSTER.test_cluster.v1]/items[at0002]"); + assertEquals(1, set.size()); + assertTrue(set.contains("/items[3]/items[1]")); + + // forth element + set = actual.get("/items[adl-test-CLUSTER.test_cluster.v1]/items[adl-test-CLUSTER.test_cluster.v1]/items[at0002]"); + 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"); + 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]")); + + // third element + set = actual.get("/items[adl-test-CLUSTER.test_cluster.v1]/items[at0002]"); + assertEquals(2, set.size()); + assertTrue(set.contains("/items[3]/items[1]")); + assertTrue(set.contains("/items[4]/items[1]")); + + // forth element + set = actual.get("/items[adl-test-CLUSTER.test_cluster.v1]/items[adl-test-CLUSTER.test_cluster.v1]/items[at0002]"); + assertEquals(2, set.size()); + 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(); + XPathUtil util = new XPathUtil(); + 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]")); + + // third element + set = actual.get("/items[at0005]/items[at0003]"); + assertEquals(1, set.size()); + assertTrue(set.contains("/items[2]/items[2]")); + + // forth element + set = actual.get("/items[at0005]/items[at0004]"); + assertEquals(1, set.size()); + assertTrue(set.contains("/items[2]/items[3]")); + + // fifth element + set = actual.get("/items[at0006]"); + assertEquals(1, set.size()); + 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()); + assertTrue(set.contains("/items[4]/items[3]")); + assertTrue(set.contains("/items[5]/items[3]")); + } + + private InputStream loadFromClasspath(String adl) throws Exception { + return this.getClass().getClassLoader().getResourceAsStream(adl); + } + + public void testExtractXPaths() throws Exception { + ItemTree tree = createTree(); + XPathUtil util = new XPathUtil(); + Set actual = util.extractXPaths(tree); + assertEquals(5, actual.size()); + assertTrue(actual.contains("/items[1]")); + assertTrue(actual.contains("/items[2]/items[1]")); + assertTrue(actual.contains("/items[2]/items[2]")); + 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"); + XPathUtil util = new XPathUtil(); + Set actual = util.extractXPaths(tree); + assertEquals(5, actual.size()); + assertTrue(actual.contains("/items[1]")); + assertTrue(actual.contains("/items[2]/items[1]")); + assertTrue(actual.contains("/items[2]/items[2]")); + assertTrue(actual.contains("/items[2]/items[3]")); + assertTrue(actual.contains("/items[3]")); + } + + /** + * /sample + * /lipid studies/total cholesterol + * /lipid studies/ldl cholesterol + * /lipid studies/hdl cholesterol + * /comment + */ + private ItemTree createTree() { + List items = new ArrayList(); + items.add(sampleElement()); + items.add(cluster()); + items.add(commentElement()); + 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[at0005, 'lipid studies']/items[at0004, 'hdl cholesterol'] + * /items[at0006, 'comment'] + * /items[adl-test-CLUSTER.test_cluster.v1, 'test cluster']/items[at0002, 'element 1'] + * /items[adl-test-CLUSTER.test_cluster.v1, 'test cluster']/items[at0003, 'element 2'] + * /items[adl-test-CLUSTER.test_cluster.v1, 'test cluster']/items[at0004, 'element 3'] + */ + private ItemTree createRootTreeWithTwoSlottedClusters() throws Exception { + List items = new ArrayList(); + items.add(sampleElement()); + items.add(cluster()); + items.add(commentElement()); + items.add(slottedCluster()); + 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, + new DvText("biochemstry result"), details, null, null, null, items); + + 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); + FileUtils.writeLines(new File(name), lines); + } + + /** + * /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()); + + // repeated sample element + items.add(sampleElement()); + items.add(cluster()); + items.add(comment); + 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 + * /lipid studies/hdl 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 comment; + sample = new Element("at0001", new DvText("sample"), new DvCodedText( + "serum", new CodePhrase("terminology", "111"))); + // comment + comment = new Element("at0006", new DvText("comment"), new DvText( + "high cardiac risk")); + + List items = new ArrayList(); + items.add(sample); + items.add(cluster()); + + // repeated 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; + Element hdlCholesterol; + MeasurementService measureServ = TestMeasurementService.getInstance(); + totalCholesterol = new Element("at0002", + new DvText("total cholesterol"), new DvQuantity("mmol/L", 6.1, + measureServ)); + ldlCholesterol = new Element("at0003", new DvText("LDL cholesterol"), + new DvQuantity("mmol/L", 0.9, measureServ)); + hdlCholesterol = new Element("at0004", new DvText("HDL cholesterol"), + new DvQuantity("mmol/L", 5.2, measureServ)); + List items = new ArrayList(); + items.add(totalCholesterol); + items.add(ldlCholesterol); + 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", + new DvText("element 2"), new DvText("element 2")); + 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); + Archetyped details = new Archetyped("adl-test-CLUSTER.test_cluster.v1", + "1.0.1"); + Cluster cluster = new Cluster(null, archetypeId, + new DvText("test cluster"), details, null, null, null, items); + 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 + * if units null + */ + public boolean isValidUnitsString(String units) { + return true; + } + + /** + * Return True if two units strings correspond to the same measured + * property. + * + * @param units1 + * @param units2 + * @return true if two units equal + * @throws IllegalArgumentException + * if units1 or units2 null + */ + public boolean unitsEquivalent(String units1, String units2) { + return true; + } + + /** + * Return a new instance of test measurement service + * + * @return + */ + public static MeasurementService getInstance() { + return new TestMeasurementService(); + } + + @Override + public boolean unitsComparable(String units1, String units2) { + return true; + } + + @Override + public int compare(String units1, Double value1, String units2, + Double value2) { + return 0; + } + } +} 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 new file mode 100644 index 00000000..1aee460b --- /dev/null +++ b/dadl-binding/src/test/resources/adl-test-CLUSTER.test_cluster.v1.adl @@ -0,0 +1,88 @@ +archetype + adl-test-CLUSTER.test_cluster.v1 + +concept + [at0000] -- test cluster + +language + original_language = <[ISO_639-1::en]> + +definition + CLUSTER[at0001] occurrences matches {0..1} matches { + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0002] matches { -- element 1 + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"yr"> + magnitude = <|0.0..200.0|> + precision = <|2|> + > + > + > + } + } + ELEMENT[at0003] matches { -- element 2 + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"yr"> + magnitude = <|0.0..200.0|> + precision = <|2|> + > + > + > + } + } + ELEMENT[at0004] matches { -- element 3 + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"yr"> + magnitude = <|0.0..200.0|> + precision = <|2|> + > + > + > + } + } + allow_archetype CLUSTER[at2012] occurrences matches {0..1} matches { -- test cluster slot + include + archetype_id/value matches {/adl-test-CLUSTER.test_cluster.v1/} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test cluster">; + description = <"most minimal"> + > + ["at0001"] = < + text = <"cluster">; + description = <"most minimal"> + > + ["at0002"] = < + text = <"element 1">; + description = <"most minimal"> + > + ["at0003"] = < + text = <"element 2">; + description = <"most minimal"> + > + ["at0004"] = < + text = <"element 3">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..e5e43460 --- /dev/null +++ b/dadl-binding/src/test/resources/adl-test-ITEM_TREE.test_tree.v1.adl @@ -0,0 +1,110 @@ +archetype + adl-test-ITEM_TREE.test_tree.v1 + +concept + [at0000] -- empty definition test + +language + original_language = <[ISO_639-1::en]> + +definition + ItemTree[at0000] matches { + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0001] occurrences matches {0..1} matches { -- sample + value matches { + DV_TEXT matches {*} + } + } + CLUSTER[at0005] occurrences matches {0..1} matches { + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0002] matches { -- total cholesterol + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"yr"> + magnitude = <|0.0..200.0|> + precision = <|2|> + > + > + > + } + } + ELEMENT[at0003] matches { -- LDL cholesterol + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"yr"> + magnitude = <|0.0..200.0|> + precision = <|2|> + > + > + > + } + } + ELEMENT[at0004] matches { -- HDL cholesterol + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"yr"> + magnitude = <|0.0..200.0|> + precision = <|2|> + > + > + > + } + } + } + } + ELEMENT[at0006] occurrences matches {0..1} matches { -- commnet + value matches { + DV_TEXT matches {*} + } + } + allow_archetype CLUSTER[at1025] occurrences matches {0..1} matches { -- test cluster slot + include + archetype_id/value matches {/adl-test-CLUSTER.test_cluster.v1/} + } + } + } + +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"> + > + ["at0004"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0005"] = < + text = <"most minimal">; + description = <"most minimal"> + > + ["at0006"] = < + text = <"most minimal">; + description = <"most minimal"> + > + > + > + > \ No newline at end of file diff --git a/dadl-binding/src/test/resources/archetyped.dadl b/dadl-binding/src/test/resources/archetyped.dadl new file mode 100644 index 00000000..607a5632 --- /dev/null +++ b/dadl-binding/src/test/resources/archetyped.dadl @@ -0,0 +1,6 @@ +< + archetype_id = (ARCHETYPE_ID) < + value = <"openEHR-EHR-OBSERVATION.blood_pressure.v1"> + > + rm_version = <"1.0.1"> +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/body_weight.dadl b/dadl-binding/src/test/resources/body_weight.dadl new file mode 100644 index 00000000..153cb481 --- /dev/null +++ b/dadl-binding/src/test/resources/body_weight.dadl @@ -0,0 +1,59 @@ +< + archetype_node_id = <"openEHR-EHR-OBSERVATION.lab_test.v1"> + name = < + value = <"Lab Test"> + > + archetype_details = < + archetype_id = (ARCHETYPE_ID) < + value = <"openEHR-EHR-OBSERVATION.lab_test.v1"> + > + rm_version = <"1.0.1"> + > + language = < + terminology_id = (TERMINOLOGY_ID) < + value = <"ISO_639-1"> + > + code_string = <"en"> + > + encoding = < + terminology_id = (TERMINOLOGY_ID) < + value = <"IANA_character-sets"> + > + code_string = <"UTF-8"> + > + subject = (PARTY_SELF) <> + data = < + archetype_node_id = <"at0001"> + name = < + value = <"history"> + > + origin = <2007-10-30T09:22:00> + events = < + [1] = < + archetype_node_id = <"at0006"> + name = < + value = <"event"> + > + time = <2005-12-03T09:22:00> + data = < + archetype_node_id = <"at0003"> + name = < + value = <"S-Creatine"> + > + items = < + [1] = < + name = < + value = <"Result"> + > + archetype_node_id = <"at0004"> + value = < + magnitude = <70.0> + units = <"mol/L"> + > + > + > + > + > + > + > +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/code_phrase.dadl b/dadl-binding/src/test/resources/code_phrase.dadl new file mode 100644 index 00000000..9e50f115 --- /dev/null +++ b/dadl-binding/src/test/resources/code_phrase.dadl @@ -0,0 +1,6 @@ +< + terminology_id = (TERMINOLOGY_ID) < + value = <"ISO_639-1"> + > + code_string = <"en"> +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/demographics.dadl b/dadl-binding/src/test/resources/demographics.dadl new file mode 100644 index 00000000..20ed444a --- /dev/null +++ b/dadl-binding/src/test/resources/demographics.dadl @@ -0,0 +1,68 @@ +< + archetype_node_id = <"openEHR-EHR-OBSERVATION.demographics.v1"> + name = < + value = <"Demographics"> + > + archetype_details = < + archetype_id = (ARCHETYPE_ID) < + value = <"openEHR-EHR-OBSERVATION.demographics.v1"> + > + rm_version = <"1.0.1"> + > + language = < + terminology_id = (TERMINOLOGY_ID) < + value = <"ISO_639-1"> + > + code_string = <"en"> + > + encoding = < + terminology_id = (TERMINOLOGY_ID) < + value = <"IANA_character-sets"> + > + code_string = <"UTF-8"> + > + subject = (PARTY_SELF) <> + data = < + archetype_node_id = <"at0001"> + name = < + value = <"history"> + > + origin = <2012-04-30T09:22:00> + events = < + [1] = < + archetype_node_id = <"at0006"> + name = < + value = <"event"> + > + time = <2010-04-30T09:22:00> + data = < + archetype_node_id = <"at0003"> + name = < + value = <"item tree"> + > + items = < + [1] = < + name = < + value = <"Gender"> + > + archetype_node_id = <"at0004"> + value = < + value = <"Male"> + > + > + [2] = < + name = < + value = <"Age"> + > + archetype_node_id = <"at0005"> + value = < + magnitude = <80.0> + units = <"yr"> + > + > + > + > + > + > + > +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/duplicated_codes.dadl b/dadl-binding/src/test/resources/duplicated_codes.dadl new file mode 100644 index 00000000..e72519aa --- /dev/null +++ b/dadl-binding/src/test/resources/duplicated_codes.dadl @@ -0,0 +1,5 @@ +ontology = (GUIDE_ONTOLOGY) < + term_bindings = < + codes = <"ddd",...> + > +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/dv_coded_text.dadl b/dadl-binding/src/test/resources/dv_coded_text.dadl new file mode 100644 index 00000000..a4cc9c6b --- /dev/null +++ b/dadl-binding/src/test/resources/dv_coded_text.dadl @@ -0,0 +1,9 @@ +< + defining_code = < + terminology_id = (TERMINOLOGY_ID) < + value = <"ISO_639-1"> + > + code_string = <"en"> + > + value = <"sitting"> +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/dv_quantity.dadl b/dadl-binding/src/test/resources/dv_quantity.dadl new file mode 100644 index 00000000..5d542fb1 --- /dev/null +++ b/dadl-binding/src/test/resources/dv_quantity.dadl @@ -0,0 +1,4 @@ +< + magnitude = <120.0> + units = <"mmHg"> +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/dv_text.dadl b/dadl-binding/src/test/resources/dv_text.dadl new file mode 100644 index 00000000..79dacfe2 --- /dev/null +++ b/dadl-binding/src/test/resources/dv_text.dadl @@ -0,0 +1,3 @@ +< + value = <"sitting"> +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/element.dadl b/dadl-binding/src/test/resources/element.dadl new file mode 100644 index 00000000..94e6aee9 --- /dev/null +++ b/dadl-binding/src/test/resources/element.dadl @@ -0,0 +1,10 @@ +< + name = < + value = <"systolic"> + > + archetype_node_id = <"at0004"> + value = < + magnitude = <120.0> + units = <"mmHg"> + > +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/element_with_text.dadl b/dadl-binding/src/test/resources/element_with_text.dadl new file mode 100644 index 00000000..b3cae162 --- /dev/null +++ b/dadl-binding/src/test/resources/element_with_text.dadl @@ -0,0 +1,9 @@ +(ELEMENT) < + name = < + value = <"text"> + > + archetype_node_id = <"at0001"> + value = < + value = <"text value"> + > +> \ No newline at end of file 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 new file mode 100644 index 00000000..155d6377 --- /dev/null +++ b/dadl-binding/src/test/resources/empty_element_with_null_flavour.dadl @@ -0,0 +1,15 @@ +(ELEMENT) < + name = < + value = <"systolic"> + > + archetype_node_id = <"at0004"> + null_flavour = < + defining_code = < + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + code_string = <"271"> + > + value = <"no information"> + > +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/empty_item_list.dadl b/dadl-binding/src/test/resources/empty_item_list.dadl new file mode 100644 index 00000000..d9ec4843 --- /dev/null +++ b/dadl-binding/src/test/resources/empty_item_list.dadl @@ -0,0 +1,7 @@ +< + archetype_node_id = <"at0003"> + name = < + value = <"item list"> + > + items = (LIST) <> +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/history.dadl b/dadl-binding/src/test/resources/history.dadl new file mode 100644 index 00000000..85024142 --- /dev/null +++ b/dadl-binding/src/test/resources/history.dadl @@ -0,0 +1,44 @@ +(HISTORY) < + archetype_node_id = <"at0001"> + name = < + value = <"history"> + > + origin = <2007-10-30T09:22:00> + events = (POINT_EVENT) < + [1] = < + archetype_node_id = <"at0006"> + name = < + value = <"sitting"> + > + time = <2005-12-03T09:22:00> + data = < + archetype_node_id = <"at0003"> + name = < + value = <"item list"> + > + items = < + [1] = < + name = < + value = <"systolic"> + > + archetype_node_id = <"at0004"> + value = < + magnitude = <120.0> + units = <"mmHg"> + > + > + [2] = < + name = < + value = <"diastolic"> + > + archetype_node_id = <"at0005"> + value = < + magnitude = <80.0> + units = <"mmHg"> + > + > + > + > + > + > +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/history2.dadl b/dadl-binding/src/test/resources/history2.dadl new file mode 100644 index 00000000..66bd7420 --- /dev/null +++ b/dadl-binding/src/test/resources/history2.dadl @@ -0,0 +1,52 @@ +(HISTORY) < + archetype_node_id = <"at0001"> + events = < + [1] = (POINT_EVENT) < + archetype_node_id = <"at0006"> + data = (ITEM_LIST) < + archetype_node_id = <"at0003"> + items = < + [1] = (ELEMENT) < + archetype_node_id = <"at0004"> + name = (DV_TEXT) < + value = <"systolic"> + > + value = (DV_QUANTITY) < + accuracy = <0.0> + magnitude = <120.0> + precision = <0> + units = <"mmHg"> + > + > + [2] = (ELEMENT) < + archetype_node_id = <"at0005"> + name = (DV_TEXT) < + value = <"diastolic"> + > + value = (DV_QUANTITY) < + accuracy = <0.0> + magnitude = <80.0> + precision = <0> + units = <"mmHg"> + > + > + > + name = (DV_TEXT) < + value = <"item list"> + > + > + name = (DV_TEXT) < + value = <"sitting"> + > + time = (DV_DATE_TIME) < + value = <"2005-12-03T09:22:00"> + > + > + > + name = (DV_TEXT) < + value = <"history"> + > + origin = (DV_DATE_TIME) < + value = <"2007-10-30T09:22:00"> + > +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/item_list.dadl b/dadl-binding/src/test/resources/item_list.dadl new file mode 100644 index 00000000..0866e12e --- /dev/null +++ b/dadl-binding/src/test/resources/item_list.dadl @@ -0,0 +1,28 @@ +< + archetype_node_id = <"at0003"> + name = < + value = <"item list"> + > + items = < + [1] = < + name = < + value = <"systolic"> + > + archetype_node_id = <"at0004"> + value = < + magnitude = <120.0> + units = <"mmHg"> + > + > + [2] = < + name = < + value = <"diastolic"> + > + archetype_node_id = <"at0005"> + value = < + magnitude = <80.0> + units = <"mmHg"> + > + > + > +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/item_tree_bp.dadl b/dadl-binding/src/test/resources/item_tree_bp.dadl new file mode 100644 index 00000000..ea0184ca --- /dev/null +++ b/dadl-binding/src/test/resources/item_tree_bp.dadl @@ -0,0 +1,46 @@ +(ITEM_TREE) < + archetype_node_id = <"at0003"> + name = < + value = <"item tree"> + > + items = < + [1] = < + name = < + value = <"systolic"> + > + archetype_node_id = <"at0004"> + value = < + magnitude = <120.0> + units = <"mmHg"> + > + > + [2] = < + name = < + value = <"diastolic"> + > + archetype_node_id = <"at0005"> + value = < + magnitude = <80.0> + units = <"mmHg"> + > + > + [3] = < + name = < + value = <"cluster"> + > + archetype_node_id = <"at0006"> + items = < + [1] = < + name = < + value = <"extra"> + > + archetype_node_id = <"at0007"> + value = < + magnitude = <150.0> + units = <"mmHg"> + > + > + > + > + > +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/item_tree_bp2.dadl b/dadl-binding/src/test/resources/item_tree_bp2.dadl new file mode 100644 index 00000000..95e81a40 --- /dev/null +++ b/dadl-binding/src/test/resources/item_tree_bp2.dadl @@ -0,0 +1,28 @@ +(ITEM_TREE) < + archetype_node_id = <"at0003"> + name = < + value = <"item tree"> + > + items = < + [1] = < + name = < + value = <"systolic"> + > + archetype_node_id = <"at0004"> + value = < + magnitude = <120.0> + units = <"mmHg"> + > + > + [2] = < + name = < + value = <"diastolic"> + > + archetype_node_id = <"at0005"> + value = < + magnitude = <80.0> + units = <"mmHg"> + > + > + > +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/lab_test.dadl b/dadl-binding/src/test/resources/lab_test.dadl new file mode 100644 index 00000000..153cb481 --- /dev/null +++ b/dadl-binding/src/test/resources/lab_test.dadl @@ -0,0 +1,59 @@ +< + archetype_node_id = <"openEHR-EHR-OBSERVATION.lab_test.v1"> + name = < + value = <"Lab Test"> + > + archetype_details = < + archetype_id = (ARCHETYPE_ID) < + value = <"openEHR-EHR-OBSERVATION.lab_test.v1"> + > + rm_version = <"1.0.1"> + > + language = < + terminology_id = (TERMINOLOGY_ID) < + value = <"ISO_639-1"> + > + code_string = <"en"> + > + encoding = < + terminology_id = (TERMINOLOGY_ID) < + value = <"IANA_character-sets"> + > + code_string = <"UTF-8"> + > + subject = (PARTY_SELF) <> + data = < + archetype_node_id = <"at0001"> + name = < + value = <"history"> + > + origin = <2007-10-30T09:22:00> + events = < + [1] = < + archetype_node_id = <"at0006"> + name = < + value = <"event"> + > + time = <2005-12-03T09:22:00> + data = < + archetype_node_id = <"at0003"> + name = < + value = <"S-Creatine"> + > + items = < + [1] = < + name = < + value = <"Result"> + > + archetype_node_id = <"at0004"> + value = < + magnitude = <70.0> + units = <"mol/L"> + > + > + > + > + > + > + > +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/log4j.properties b/dadl-binding/src/test/resources/log4j.properties new file mode 100644 index 00000000..b67fb578 --- /dev/null +++ b/dadl-binding/src/test/resources/log4j.properties @@ -0,0 +1,10 @@ +# Set root logger level to DEBUG 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 +log4j.logger.org.openehr.build=ERROR +log4j.logger.org.openehr.binding=DEBUG \ No newline at end of file diff --git a/dadl-binding/src/test/resources/observation.dadl b/dadl-binding/src/test/resources/observation.dadl new file mode 100644 index 00000000..2b13c52a --- /dev/null +++ b/dadl-binding/src/test/resources/observation.dadl @@ -0,0 +1,69 @@ +< + archetype_node_id = <"openEHR-EHR-OBSERVATION.blood_pressure.v1"> + name = < + value = <"BP measurement"> + > + archetype_details = < + archetype_id = (ARCHETYPE_ID) < + value = <"openEHR-EHR-OBSERVATION.blood_pressure.v1"> + > + rm_version = <"1.0.1"> + > + language = < + terminology_id = (TERMINOLOGY_ID) < + value = <"ISO_639-1"> + > + code_string = <"en"> + > + encoding = < + terminology_id = (TERMINOLOGY_ID) < + value = <"IANA_character-sets"> + > + code_string = <"UTF-8"> + > + subject = (PARTY_SELF) <> + data = < + archetype_node_id = <"at0001"> + name = < + value = <"history"> + > + origin = <2007-10-30T09:22:00> + events = < + [1] = < + archetype_node_id = <"at0006"> + name = < + value = <"sitting"> + > + time = <2005-12-03T09:22:00> + data = < + archetype_node_id = <"at0003"> + name = < + value = <"item list"> + > + items = < + [1] = < + name = < + value = <"systolic"> + > + archetype_node_id = <"at0004"> + value = < + magnitude = <120.0> + units = <"mmHg"> + > + > + [2] = < + name = < + value = <"diastolic"> + > + archetype_node_id = <"at0005"> + value = < + magnitude = <80.0> + units = <"mmHg"> + > + > + > + > + > + > + > +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/observation2.dadl b/dadl-binding/src/test/resources/observation2.dadl new file mode 100644 index 00000000..5b1db485 --- /dev/null +++ b/dadl-binding/src/test/resources/observation2.dadl @@ -0,0 +1,92 @@ +< + archetype_node_id = <"openEHR-EHR-OBSERVATION.blood_pressure.v1"> + name = < + value = <"BP measurement"> + > + archetype_details = < + archetype_id = (ARCHETYPE_ID) < + value = <"openEHR-EHR-OBSERVATION.blood_pressure.v1"> + > + rm_version = <"1.0.1"> + > + language = < + terminology_id = (TERMINOLOGY_ID) < + value = <"ISO_639-1"> + > + code_string = <"en"> + > + encoding = < + terminology_id = (TERMINOLOGY_ID) < + value = <"IANA_character-sets"> + > + code_string = <"UTF-8"> + > + subject = (PARTY_SELF) <> + data = < + archetype_node_id = <"at0001"> + name = < + value = <"history"> + > + origin = <2007-10-30T09:22:00> + events = < + [1] = < + archetype_node_id = <"at0006"> + name = < + value = <"sitting"> + > + time = <2005-12-03T09:22:00> + data = < + archetype_node_id = <"at0003"> + name = < + value = <"item list"> + > + items = < + [1] = < + name = < + value = <"systolic"> + > + archetype_node_id = <"at0004"> + value = < + magnitude = <120.0> + units = <"mmHg"> + > + > + [2] = < + name = < + value = <"diastolic"> + > + archetype_node_id = <"at0005"> + value = < + magnitude = <80.0> + units = <"mmHg"> + > + > + > + > + state = < + name = < + value = <"state structure"> + > + archetype_node_id = <"at0007"> + items = < + [1] = < + name = < + value = <"position"> + > + archetype_node_id = <"at0008"> + value = < + value = <"Sitting"> + defining_code = < + terminology_id = (TERMINOLOGY_ID) < + value = <"local"> + > + code_string = <"at1001"> + > + > + > + > + > + > + > + > +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/observation3.dadl b/dadl-binding/src/test/resources/observation3.dadl new file mode 100644 index 00000000..9d49fb48 --- /dev/null +++ b/dadl-binding/src/test/resources/observation3.dadl @@ -0,0 +1,69 @@ +< + archetype_node_id = <"openEHR-EHR-OBSERVATION.blood_pressure.v1"> + name = < + value = <"BP measurement"> + > + archetype_details = < + archetype_id = (ARCHETYPE_ID) < + value = <"openEHR-EHR-OBSERVATION.blood_pressure.v1"> + > + rm_version = <"1.0.1"> + > + language = < + terminology_id = (TERMINOLOGY_ID) < + value = <"ISO_639-1"> + > + code_string = <"en"> + > + encoding = < + terminology_id = (TERMINOLOGY_ID) < + value = <"IANA_character-sets"> + > + code_string = <"UTF-8"> + > + subject = (PARTY_SELF) <> + data = < + archetype_node_id = <"at0001"> + name = < + value = <"history"> + > + origin = <2007-10-30T09:22:00> + events = < + [1] = < + archetype_node_id = <"at0006"> + name = < + value = <"sitting"> + > + time = <2005-12-03T09:22:00> + data = < + archetype_node_id = <"at0003"> + name = < + value = <"item list"> + > + items = < + [1] = < + name = < + value = <"systolic"> + > + archetype_node_id = <"at0004"> + value = < + magnitude = <120.0> + units = <"mmHg"> + > + > + [2] = < + name = < + value = <"diastolic"> + > + archetype_node_id = <"at0005"> + value = < + magnitude = <80.0> + units = <"mmHg"> + > + > + > + > + > + > + > +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/order_set1.dadl b/dadl-binding/src/test/resources/order_set1.dadl new file mode 100644 index 00000000..dc0476d4 --- /dev/null +++ b/dadl-binding/src/test/resources/order_set1.dadl @@ -0,0 +1,826 @@ +(COMPOSITION) < + archetype_details = (ARCHETYPED) < + archetype_id = (ARCHETYPE_ID) < + value = <"openEHR-EHR-COMPOSITION.referral.v1"> + > + rm_version = <"1.0.1"> + template_id = (TEMPLATE_ID) < + value = <"referral_sample"> + > + > + archetype_node_id = <"openEHR-EHR-COMPOSITION.referral.v1"> + category = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"433"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"event"> + > + composer = (PARTY_IDENTIFIED) < + name = <"Doctor"> + > + content = < + [1] = (INSTRUCTION) < + activities = < + [1] = (ACTIVITY) < + action_archetype_id = <"string value"> + archetype_node_id = <"at0001"> + description = (ITEM_TREE) < + archetype_node_id = <"at0009"> + items = < + [1] = (ELEMENT) < + archetype_node_id = <"at0121"> + name = (DV_TEXT) < + value = <"Test requested"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [2] = (ELEMENT) < + archetype_node_id = <"at0135"> + name = (DV_TEXT) < + value = <"Description of test"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [3] = (ELEMENT) < + archetype_node_id = <"at0062"> + name = (DV_TEXT) < + value = <"Reason for request"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [4] = (ELEMENT) < + archetype_node_id = <"at0064"> + name = (DV_TEXT) < + value = <"Reason description"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [5] = (ELEMENT) < + archetype_node_id = <"at0065"> + name = (DV_TEXT) < + value = <"Intent"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [6] = (ELEMENT) < + archetype_node_id = <"at0068"> + name = (DV_TEXT) < + value = <"Urgency"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [7] = (ELEMENT) < + archetype_node_id = <"at0040.1"> + name = (DV_TEXT) < + value = <"DateTime test preferred"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [8] = (ELEMENT) < + archetype_node_id = <"at0144.1"> + name = (DV_TEXT) < + value = <"Latest DateTime test required"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [9] = (ELEMENT) < + archetype_node_id = <"at0076"> + name = (DV_TEXT) < + value = <"Supplementary information to follow"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [10] = (ELEMENT) < + archetype_node_id = <"at0078"> + name = (DV_TEXT) < + value = <"Supplementary information expected"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + > + name = (DV_TEXT) < + value = <"Tree"> + > + > + name = (DV_TEXT) < + value = <"Request"> + > + timing = (DV_PARSABLE) < + formalism = <"txt"> + value = <"activity timing"> + > + > + > + archetype_details = (ARCHETYPED) < + archetype_id = (ARCHETYPE_ID) < + value = <"openEHR-EHR-INSTRUCTION.request-lab_test.v1"> + > + rm_version = <"1.0.1"> + > + archetype_node_id = <"openEHR-EHR-INSTRUCTION.request-lab_test.v1"> + 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 = <"Laboratory Test request"> + > + narrative = (DV_TEXT) < + value = <"instruction narrative"> + > + protocol = (ITEM_TREE) < + archetype_node_id = <"at0008"> + items = < + [1] = (ELEMENT) < + archetype_node_id = <"at0010"> + name = (DV_TEXT) < + value = <"Requestor Identifier"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [2] = (ELEMENT) < + archetype_node_id = <"at0011"> + name = (DV_TEXT) < + value = <"Receiver identifier"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [3] = (ELEMENT) < + archetype_node_id = <"at0127"> + name = (DV_TEXT) < + value = <"Request status"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + > + name = (DV_TEXT) < + value = <"Tree"> + > + > + subject = (PARTY_SELF) < + external_ref = (PARTY_REF) < + id = (HIER_OBJECT_ID) < + value = <"1.2.4.5.6.12.1"> + > + type = <"PARTY"> + > + > + > + [2] = (INSTRUCTION) < + activities = < + [1] = (ACTIVITY) < + action_archetype_id = <"string value"> + archetype_node_id = <"at0001"> + description = (ITEM_TREE) < + archetype_node_id = <"at0009"> + items = < + [1] = (ELEMENT) < + archetype_node_id = <"at0121"> + name = (DV_TEXT) < + value = <"Procedure requested"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [2] = (ELEMENT) < + archetype_node_id = <"at0.146"> + name = (DV_TEXT) < + value = <"Type of procedure"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [3] = (ELEMENT) < + archetype_node_id = <"at0135"> + name = (DV_TEXT) < + value = <"Description of Procedure"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [4] = (ELEMENT) < + archetype_node_id = <"at0062"> + name = (DV_TEXT) < + value = <"Reason for request"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [5] = (ELEMENT) < + archetype_node_id = <"at0064"> + name = (DV_TEXT) < + value = <"Reason description"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [6] = (ELEMENT) < + archetype_node_id = <"at0.145"> + name = (DV_TEXT) < + value = <"Objective"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [7] = (ELEMENT) < + archetype_node_id = <"at0065"> + name = (DV_TEXT) < + value = <"Intent"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [8] = (ELEMENT) < + archetype_node_id = <"at0068"> + name = (DV_TEXT) < + value = <"Urgency"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [9] = (ELEMENT) < + archetype_node_id = <"at0040"> + name = (DV_TEXT) < + value = <"Date &/or time service required"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [10] = (ELEMENT) < + archetype_node_id = <"at0144"> + name = (DV_TEXT) < + value = <"Latest date service required"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [11] = (ELEMENT) < + archetype_node_id = <"at0076"> + name = (DV_TEXT) < + value = <"Supplementary information to follow"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [12] = (ELEMENT) < + archetype_node_id = <"at0078"> + name = (DV_TEXT) < + value = <"Supplementary information expected"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + > + name = (DV_TEXT) < + value = <"Tree"> + > + > + name = (DV_TEXT) < + value = <"Request"> + > + timing = (DV_PARSABLE) < + formalism = <"txt"> + value = <"activity timing"> + > + > + > + archetype_details = (ARCHETYPED) < + archetype_id = (ARCHETYPE_ID) < + value = <"openEHR-EHR-INSTRUCTION.request-procedure.v1"> + > + rm_version = <"1.0.1"> + > + archetype_node_id = <"openEHR-EHR-INSTRUCTION.request-procedure.v1"> + 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 = <"Procedure request"> + > + narrative = (DV_TEXT) < + value = <"instruction narrative"> + > + protocol = (ITEM_TREE) < + archetype_node_id = <"at0008"> + items = < + [1] = (ELEMENT) < + archetype_node_id = <"at0010"> + name = (DV_TEXT) < + value = <"Requestor Identifier"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [2] = (ELEMENT) < + archetype_node_id = <"at0011"> + name = (DV_TEXT) < + value = <"Receiver identifier"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [3] = (ELEMENT) < + archetype_node_id = <"at0127"> + name = (DV_TEXT) < + value = <"Request status"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + > + name = (DV_TEXT) < + value = <"Tree"> + > + > + subject = (PARTY_SELF) < + external_ref = (PARTY_REF) < + id = (HIER_OBJECT_ID) < + value = <"1.2.4.5.6.12.1"> + > + type = <"PARTY"> + > + > + > + [3] = (INSTRUCTION) < + activities = < + [1] = (ACTIVITY) < + action_archetype_id = <"string value"> + archetype_node_id = <"at0001"> + description = (ITEM_TREE) < + archetype_node_id = <"openEHR-EHR-ITEM_TREE.imaging.v1"> + items = < + [1] = (CLUSTER) < + archetype_node_id = <"at0002"> + items = < + [1] = (ELEMENT) < + archetype_node_id = <"at0003"> + name = (DV_TEXT) < + value = <"Findings"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + > + name = (DV_TEXT) < + value = <"Clinical information"> + > + > + [2] = (CLUSTER) < + archetype_node_id = <"at0004"> + items = < + [1] = (ELEMENT) < + archetype_node_id = <"at0005"> + name = (DV_TEXT) < + value = <"Imaging procedure"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [2] = (ELEMENT) < + archetype_node_id = <"at0007"> + name = (DV_TEXT) < + value = <"Anatomical site"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [3] = (ELEMENT) < + archetype_node_id = <"at0006"> + name = (DV_TEXT) < + value = <"Views"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + > + name = (DV_TEXT) < + value = <"Imaging"> + > + > + [3] = (CLUSTER) < + archetype_node_id = <"at0008"> + items = < + [1] = (ELEMENT) < + archetype_node_id = <"at0009"> + name = (DV_TEXT) < + value = <"Date of imaging"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [2] = (ELEMENT) < + archetype_node_id = <"at0010"> + name = (DV_TEXT) < + value = <"Location"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + > + name = (DV_TEXT) < + value = <"Process"> + > + > + > + name = (DV_TEXT) < + value = <"Imaging data"> + > + > + name = (DV_TEXT) < + value = <"Imaging activity"> + > + timing = (DV_PARSABLE) < + formalism = <"txt"> + value = <"activity timing"> + > + > + > + archetype_details = (ARCHETYPED) < + archetype_id = (ARCHETYPE_ID) < + value = <"openEHR-EHR-INSTRUCTION.imaging.v1"> + > + rm_version = <"1.0.1"> + > + archetype_node_id = <"openEHR-EHR-INSTRUCTION.imaging.v1"> + 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 = <"Imaging request"> + > + narrative = (DV_TEXT) < + value = <"instruction narrative"> + > + subject = (PARTY_SELF) < + external_ref = (PARTY_REF) < + id = (HIER_OBJECT_ID) < + value = <"1.2.4.5.6.12.1"> + > + type = <"PARTY"> + > + > + > + > + context = (EVENT_CONTEXT) < + other_context = (ITEM_TREE) < + archetype_node_id = <"at0001"> + items = < + [1] = (ELEMENT) < + archetype_node_id = <"at0028"> + name = (DV_TEXT) < + value = <"Requestor Identifier"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [2] = (ELEMENT) < + archetype_node_id = <"at0039"> + name = (DV_TEXT) < + value = <"DateTime attested"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + [3] = (ELEMENT) < + archetype_node_id = <"at0040"> + name = (DV_TEXT) < + value = <"Document Status"> + > + null_flavour = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"271"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"no information"> + > + > + > + name = (DV_TEXT) < + value = <"Tree"> + > + > + setting = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"227"> + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + > + value = <"emergency care"> + > + start_time = (DV_DATE_TIME) < + value = <"2012-07-10T12:07:51,653"> + > + > + language = (CODE_PHRASE) < + code_string = <"en"> + terminology_id = (TERMINOLOGY_ID) < + value = <"ISO_639-1"> + > + > + name = (DV_TEXT) < + value = <"Referral document"> + > + territory = (CODE_PHRASE) < + code_string = <"SE"> + terminology_id = (TERMINOLOGY_ID) < + value = <"ISO_3166-1"> + > + > +> diff --git a/dadl-binding/src/test/resources/point_event.dadl b/dadl-binding/src/test/resources/point_event.dadl new file mode 100644 index 00000000..fdbaed20 --- /dev/null +++ b/dadl-binding/src/test/resources/point_event.dadl @@ -0,0 +1,35 @@ +(POINT_EVENT) < + archetype_node_id = <"at0006"> + data = (ITEM_LIST) < + archetype_node_id = <"at0003"> + items = < + [1] = (ELEMENT) < + archetype_node_id = <"at0004"> + name = (DV_TEXT) < + value = <"systolic"> + > + value = < + magnitude = <120.0> + units = <"mmHg"> + > + > + [2] = (ELEMENT) < + name = < + value = <"diastolic"> + > + archetype_node_id = <"at0005"> + value = < + magnitude = <80.0> + units = <"mmHg"> + > + > + > + name = < + value = <"item list"> + > + > + name = < + value = <"sitting"> + > + time = <2005-12-03T09:22:00> +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/point_event2.dadl b/dadl-binding/src/test/resources/point_event2.dadl new file mode 100644 index 00000000..005f8e01 --- /dev/null +++ b/dadl-binding/src/test/resources/point_event2.dadl @@ -0,0 +1,41 @@ +(POINT_EVENT) < + archetype_node_id = <"at0006"> + data = (ITEM_LIST) < + archetype_node_id = <"at0003"> + items = < + [1] = (ELEMENT) < + archetype_node_id = <"at0004"> + name = (DV_TEXT) < + value = <"systolic"> + > + value = (DV_QUANTITY) < + accuracy = <0.0> + magnitude = <120.0> + precision = <0> + units = <"mmHg"> + > + > + [2] = (ELEMENT) < + archetype_node_id = <"at0005"> + name = (DV_TEXT) < + value = <"diastolic"> + > + value = (DV_QUANTITY) < + accuracy = <0.0> + magnitude = <80.0> + precision = <0> + units = <"mmHg"> + > + > + > + name = (DV_TEXT) < + value = <"item list"> + > + > + name = (DV_TEXT) < + value = <"sitting"> + > + time = (DV_DATE_TIME) < + value = <"2005-12-03T09:22:00"> + > +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/tree_2_slots.dadl b/dadl-binding/src/test/resources/tree_2_slots.dadl new file mode 100644 index 00000000..1231ced5 --- /dev/null +++ b/dadl-binding/src/test/resources/tree_2_slots.dadl @@ -0,0 +1,164 @@ +(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-binding/src/test/resources/tree_nested_slot.dadl b/dadl-binding/src/test/resources/tree_nested_slot.dadl new file mode 100644 index 00000000..aea3b677 --- /dev/null +++ b/dadl-binding/src/test/resources/tree_nested_slot.dadl @@ -0,0 +1,146 @@ +(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] = (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 = <"test cluster"> + > + > + > + name = (DV_TEXT) < + value = <"biochemstry result"> + > +> diff --git a/dadl-binding/src/test/resources/tree_nested_slot2.dadl b/dadl-binding/src/test/resources/tree_nested_slot2.dadl new file mode 100644 index 00000000..d969b3c2 --- /dev/null +++ b/dadl-binding/src/test/resources/tree_nested_slot2.dadl @@ -0,0 +1,172 @@ +(ITEM_TREE) < + 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] = (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 1"> + > + value = (DV_TEXT) < + value = <"element 1"> + > + > + [3] = (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 1"> + > + value = (DV_TEXT) < + value = <"element 1"> + > + > + [3] = (ELEMENT) < + archetype_node_id = <"at0004"> + name = (DV_TEXT) < + value = <"element 1"> + > + value = (DV_TEXT) < + value = <"element 1"> + > + > + > + name = (DV_TEXT) < + value = <"test cluster"> + > + > + > + name = (DV_TEXT) < + value = <"test cluster"> + > + > + > + name = (DV_TEXT) < + value = <"test cluster"> + > + > + > + name = (DV_TEXT) < + value = <"biochemstry result"> + > +> diff --git a/dadl-binding/src/test/resources/tree_nested_slot3.dadl b/dadl-binding/src/test/resources/tree_nested_slot3.dadl new file mode 100644 index 00000000..b4a12738 --- /dev/null +++ b/dadl-binding/src/test/resources/tree_nested_slot3.dadl @@ -0,0 +1,95 @@ +(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"> + > + > + > + name = (DV_TEXT) < + value = <"lipid studies"> + > + > + [3] = (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] = (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"> + > + > + > + name = (DV_TEXT) < + value = <"test cluster"> + > + > + > + name = (DV_TEXT) < + value = <"test cluster"> + > + > + > + name = (DV_TEXT) < + value = <"biochemstry result"> + > +> diff --git a/dadl-binding/src/test/resources/tree_nested_slot4.dadl b/dadl-binding/src/test/resources/tree_nested_slot4.dadl new file mode 100644 index 00000000..3bf886d1 --- /dev/null +++ b/dadl-binding/src/test/resources/tree_nested_slot4.dadl @@ -0,0 +1,141 @@ +(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"> + > + > + > + name = (DV_TEXT) < + value = <"lipid studies"> + > + > + [3] = (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] = (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"> + > + > + > + name = (DV_TEXT) < + value = <"test cluster"> + > + > + > + name = (DV_TEXT) < + value = <"slot 1"> + > + > + [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] = (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"> + > + > + > + name = (DV_TEXT) < + value = <"test cluster"> + > + > + > + name = (DV_TEXT) < + value = <"slot 2"> + > + > + > + name = (DV_TEXT) < + value = <"biochemstry result"> + > +> diff --git a/dadl-binding/src/test/resources/tree_slot.dadl b/dadl-binding/src/test/resources/tree_slot.dadl new file mode 100644 index 00000000..de8d8a1b --- /dev/null +++ b/dadl-binding/src/test/resources/tree_slot.dadl @@ -0,0 +1,123 @@ +(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"> + > + > + > + name = (DV_TEXT) < + value = <"biochemstry result"> + > +> diff --git a/dadl-binding/src/test/resources/typed_archetype_id.dadl b/dadl-binding/src/test/resources/typed_archetype_id.dadl new file mode 100644 index 00000000..22b74ba7 --- /dev/null +++ b/dadl-binding/src/test/resources/typed_archetype_id.dadl @@ -0,0 +1,3 @@ +(ARCHETYPE_ID) < + value = <"openEHR-EHR-OBSERVATION.blood_pressure.v1"> +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/typed_dv_boolean.dadl b/dadl-binding/src/test/resources/typed_dv_boolean.dadl new file mode 100644 index 00000000..62ec1d4e --- /dev/null +++ b/dadl-binding/src/test/resources/typed_dv_boolean.dadl @@ -0,0 +1,3 @@ +(DV_BOOLEAN) < + value = <"true"> +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/typed_dv_ordinal.dadl b/dadl-binding/src/test/resources/typed_dv_ordinal.dadl new file mode 100644 index 00000000..f0b931cd --- /dev/null +++ b/dadl-binding/src/test/resources/typed_dv_ordinal.dadl @@ -0,0 +1,12 @@ +(DV_ORDINAL) < + symbol = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"12345678"> + terminology_id = (TERMINOLOGY_ID) < + value = <"SNOMED-CT"> + > + > + value = <"Sitting"> + > + value = <1> +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/typed_dv_quantity.dadl b/dadl-binding/src/test/resources/typed_dv_quantity.dadl new file mode 100644 index 00000000..e1a41a2c --- /dev/null +++ b/dadl-binding/src/test/resources/typed_dv_quantity.dadl @@ -0,0 +1,4 @@ +(DV_QUANTITY) < + magnitude = <120.0> + units = <"mmHg"> +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/typed_dv_quantity2.dadl b/dadl-binding/src/test/resources/typed_dv_quantity2.dadl new file mode 100644 index 00000000..eeb278ba --- /dev/null +++ b/dadl-binding/src/test/resources/typed_dv_quantity2.dadl @@ -0,0 +1,6 @@ +(DV_QUANTITY) < + accuracy = <0.0> + magnitude = <120.0> + precision = <1> + units = <"mmHg"> +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/typed_dv_text.dadl b/dadl-binding/src/test/resources/typed_dv_text.dadl new file mode 100644 index 00000000..ab4b7c56 --- /dev/null +++ b/dadl-binding/src/test/resources/typed_dv_text.dadl @@ -0,0 +1,3 @@ +(DV_TEXT) < + value = <"sitting"> +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/typed_party_self.dadl b/dadl-binding/src/test/resources/typed_party_self.dadl new file mode 100644 index 00000000..926d8a46 --- /dev/null +++ b/dadl-binding/src/test/resources/typed_party_self.dadl @@ -0,0 +1 @@ +(PARTY_SELF) <> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/typed_terminology_id.dadl b/dadl-binding/src/test/resources/typed_terminology_id.dadl new file mode 100644 index 00000000..992ff85d --- /dev/null +++ b/dadl-binding/src/test/resources/typed_terminology_id.dadl @@ -0,0 +1,3 @@ +(TERMINOLOGY_ID) < + value = <"openehr"> +> \ No newline at end of file diff --git a/dadl-binding/src/test/resources/weight.dadl b/dadl-binding/src/test/resources/weight.dadl new file mode 100644 index 00000000..e69de29b diff --git a/dadl-binding/tree_2_slots.dadl b/dadl-binding/tree_2_slots.dadl new file mode 100644 index 00000000..1231ced5 --- /dev/null +++ b/dadl-binding/tree_2_slots.dadl @@ -0,0 +1,164 @@ +(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 new file mode 100644 index 00000000..496f33f1 --- /dev/null +++ b/dadl-parser/pom.xml @@ -0,0 +1,80 @@ + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5-SNAPSHOT + + dadl-parser + jar + java dADL Parser + http://svn.openehr.org/ref_impl_java/TRUNK/project_page.htm + + openEHR + http://www.openehr.org/ + + 2007 + + java dADL Parser + + + + + org.codehaus.mojo + javacc-maven-plugin + 2.6 + + + + javacc + + + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.codehaus.mojo + javacc-maven-plugin + [2.1,) + + javacc + + + + + + + + + + + + + + + + + openehr + openehr-rm-core + ${project.version} + + + junit + junit + 3.8.1 + test + + + 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 new file mode 100644 index 00000000..f8540b3c --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/AttributeValue.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2007,2008 Cambio Healthcare Systems AB, Sweden + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ + +package org.openehr.am.parser; + +/** + * AttributeValue + * + * @author Rong Chen + * @version 1.0 + */ +public class AttributeValue extends Parsed { + + public AttributeValue(String id, ObjectBlock value) { + this.id = id; + this.value = value; + } + + public String getId() { + return id; + } + + public ObjectBlock getValue() { + return value; + } + + /* fields */ + private String id; + private ObjectBlock value; +} 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 new file mode 100644 index 00000000..35dc2f0e --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/BooleanValue.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2007,2008 Cambio Healthcare Systems AB, Sweden + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ + +package org.openehr.am.parser; + +public class BooleanValue extends SimpleValue { + public BooleanValue(Boolean value) { + super(value); + } +} 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 new file mode 100644 index 00000000..c976c657 --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/CharacterValue.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2007,2008 Cambio Healthcare Systems AB, Sweden + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ + +package org.openehr.am.parser; + +public class CharacterValue extends SimpleValue { + public CharacterValue(Character value) { + super(value); + } +} 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 new file mode 100644 index 00000000..ddb5d4b4 --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/CodeValue.java @@ -0,0 +1,9 @@ +package org.openehr.am.parser; + +import org.openehr.rm.datatypes.text.CodePhrase; + +public class CodeValue extends SimpleValue { + public CodeValue(CodePhrase code) { + super(code); + } +} 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 new file mode 100644 index 00000000..c5385eee --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/ComplexObjectBlock.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2007,2008 Cambio Healthcare Systems AB, Sweden + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ + +package org.openehr.am.parser; + +public class ComplexObjectBlock extends ObjectBlock { + public ComplexObjectBlock(String type) { + super(type); + } +} 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 new file mode 100644 index 00000000..7d879b53 --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/ContentObject.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2008 Cambio Healthcare Systems, Sweden. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ + +package org.openehr.am.parser; + +import java.util.List; + +/** + * The result of parsing DADL input, the value is either + * a list of attribute values or a complex object block + * + * @author Rong Chen + * @version 1.0 + */ +public class ContentObject extends Parsed { + + public ContentObject(List attributeValues, + ComplexObjectBlock complexObjectBlock) { + this.attributeValues = attributeValues; + this.complexObjectBlock = complexObjectBlock; + } + + public ComplexObjectBlock getComplexObjectBlock() { + return this.complexObjectBlock; + } + + public List getAttributeValues() { + return this.attributeValues; + } + + /* fields */ + private List attributeValues; + private ComplexObjectBlock complexObjectBlock; +} 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 new file mode 100644 index 00000000..e969621c --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/DateTimeValue.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2007,2008 Cambio Healthcare Systems AB, Sweden + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ + +package org.openehr.am.parser; + +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; + +public class DateTimeValue extends SimpleValue { + public DateTimeValue(DvDateTime value) { + super(value); + } +} 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 new file mode 100644 index 00000000..8bf7e064 --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/DateValue.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2007,2008 Cambio Healthcare Systems AB, Sweden + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ + +package org.openehr.am.parser; + +import org.openehr.rm.datatypes.quantity.datetime.DvDate; + +public class DateValue extends SimpleValue { + public DateValue(DvDate value) { + super(value); + } +} 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 new file mode 100644 index 00000000..1323c768 --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/DurationValue.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2007,2008 Cambio Healthcare Systems AB, Sweden + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ + +package org.openehr.am.parser; + +import org.openehr.rm.datatypes.quantity.datetime.DvDuration; + +public class DurationValue extends SimpleValue { + public DurationValue(DvDuration value) { + super(value); + } +} 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 new file mode 100644 index 00000000..09d7cb7c --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/IntegerValue.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2007,2008 Cambio Healthcare Systems AB, Sweden + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ + +package org.openehr.am.parser; + +public class IntegerValue extends SimpleValue { + public IntegerValue(Integer value) { + super(value); + } +} 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 new file mode 100644 index 00000000..a43b7e22 --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/KeyedObject.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2007,2008 Cambio Healthcare Systems AB, Sweden + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ + +package org.openehr.am.parser; + +public class KeyedObject extends Parsed { + + public KeyedObject(SimpleValue key, ObjectBlock object) { + this.key = key; + this.object = object; + } + + public SimpleValue getKey() { + return key; + } + + public ObjectBlock getObject() { + return object; + } + + private SimpleValue key; + private ObjectBlock object; +} 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 new file mode 100644 index 00000000..6f30ab51 --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/MultipleAttributeObjectBlock.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2007,2008 Cambio Healthcare Systems AB, Sweden + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ + +package org.openehr.am.parser; + +import java.util.List; + +public class MultipleAttributeObjectBlock extends ComplexObjectBlock { + + public MultipleAttributeObjectBlock(String type, + List keyedObjects) { + super(type); + this.keyedObjects = keyedObjects; + } + + public List getKeyObjects() { + return keyedObjects; + } + + private List keyedObjects; +} 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 new file mode 100644 index 00000000..de70da29 --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/ObjectBlock.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2007,2008 Cambio Healthcare Systems AB, Sweden + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ + +package org.openehr.am.parser; + +public abstract class ObjectBlock extends Parsed { + + public ObjectBlock(String typeIdentifier) { + this.typeIdentifier = typeIdentifier; + } + + /** + * Type identifier + * + * @return null if not specified + */ + public String getTypeIdentifier() { + return typeIdentifier; + } + + private String typeIdentifier; +} 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 new file mode 100644 index 00000000..d1fdaa35 --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/Parsed.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2008 Cambio Healthcare Systems AB, Sweden. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ + +package org.openehr.am.parser; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; + +/** + * Super class of all parsed archetype items. It provides basic functions for + * all parsed items. + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class Parsed { + + public String toString() { + + return ToStringBuilder.reflectionToString(this, style); + } + + private static final ToStringStyle style = ToStringStyle.MULTI_LINE_STYLE; +} 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 new file mode 100644 index 00000000..a9a29490 --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/PrimitiveObjectBlock.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2007,2008 Cambio Healthcare Systems AB, Sweden + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ + +package org.openehr.am.parser; + +import java.util.List; + +import org.openehr.rm.support.basic.Interval; + +public class PrimitiveObjectBlock extends ObjectBlock { + + public PrimitiveObjectBlock(String type, SimpleValue simpleValue, + List simpleListValue, + Interval simpleIntervalValue, String termCode, + List termCodeListValue) { + super(type); + this.simpleValue = simpleValue; + this.simpleIntervalValue = simpleIntervalValue; + this.simpleListValue = simpleListValue; + this.termCode = termCode; + this.termCodeListValue = termCodeListValue; + } + + public SimpleValue getSimpleValue() { + return this.simpleValue; + } + + public List getSimpleListValue() { + return simpleListValue; + } + + public Interval getSimpleIntervalValue() { + return simpleIntervalValue; + } + + public String getTermCode() { + return termCode; + } + + public List getTermCodeListValue() { + return termCodeListValue; + } + + private SimpleValue simpleValue; + private List simpleListValue; + private Interval simpleIntervalValue; + private String termCode; + private List termCodeListValue; +} 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 new file mode 100644 index 00000000..393df319 --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/RealValue.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2007,2008 Cambio Healthcare Systems AB, Sweden + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ + +package org.openehr.am.parser; + +public class RealValue extends SimpleValue { + public RealValue(Double value) { + super(value); + } +} 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 new file mode 100644 index 00000000..78fabee3 --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/SimpleValue.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2007,2008 Cambio Healthcare Systems AB, Sweden + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ + +package org.openehr.am.parser; + +/* a simple value supported by dadl syntax */ + +public abstract class SimpleValue extends Parsed { + public SimpleValue(T value) { + this.value = value; + } + + public T getValue() { + return value; + } + + private T value; +} 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 new file mode 100644 index 00000000..d2924ae9 --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/SingleAttributeObjectBlock.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2007,2008 Cambio Healthcare Systems AB, Sweden + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ + +package org.openehr.am.parser; + +import java.util.List; + +public class SingleAttributeObjectBlock extends ComplexObjectBlock { + + public SingleAttributeObjectBlock(String type, + List attributeValues) { + super(type); + this.attributeValues = attributeValues; + } + + public List getAttributeValues() { + return attributeValues; + } + + private List attributeValues; +} 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 new file mode 100644 index 00000000..7b99e6f8 --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/StringValue.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2007,2008 Cambio Healthcare Systems AB, Sweden + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ + +package org.openehr.am.parser; + +public class StringValue extends SimpleValue { + public StringValue(String value) { + super(value); + } +} \ No newline at end of file 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 new file mode 100644 index 00000000..b97ab51c --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/TimeValue.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2007,2008 Cambio Healthcare Systems AB, Sweden + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ + +package org.openehr.am.parser; + +import org.openehr.rm.datatypes.quantity.datetime.DvTime; + +public class TimeValue extends SimpleValue { + public TimeValue(DvTime value) { + super(value); + } +} 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 new file mode 100644 index 00000000..ec19146d --- /dev/null +++ b/dadl-parser/src/main/java/org/openehr/am/parser/UriValue.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2007,2008 Cambio Healthcare Systems AB, Sweden + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ + +package org.openehr.am.parser; + +import org.openehr.rm.datatypes.uri.DvURI; + +public class UriValue extends SimpleValue{ + public UriValue(DvURI value) { + super(value); + } +} diff --git a/dadl-parser/src/main/javacc/dadl.jj b/dadl-parser/src/main/javacc/dadl.jj new file mode 100644 index 00000000..1d1f11ba --- /dev/null +++ b/dadl-parser/src/main/javacc/dadl.jj @@ -0,0 +1,32 @@ + /* + * Copyright (C) 2007,2008 Cambio Healthcare Systems AB, Sweden + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ options { STATIC = false; DEBUG_PARSER = false; DEBUG_TOKEN_MANAGER = false; DEBUG_LOOKAHEAD = false; LOOKAHEAD= 1; UNICODE_INPUT = true; } PARSER_BEGIN(DADLParser) package org.openehr.am.parser; import java.io.*; import java.util.*; import java.text.*; import org.openehr.rm.support.basic.Interval; import org.openehr.rm.datatypes.quantity.datetime.*; import org.openehr.rm.datatypes.text.*; import org.openehr.rm.datatypes.quantity.*; import org.openehr.rm.common.resource.*; import org.openehr.rm.common.generic.RevisionHistory; import org.openehr.rm.support.identification.*; import org.openehr.rm.support.terminology.*; /** + * JavaCC grammer file for Archteype Definition Language (ADL) + * + * Targeted DADL revision 1.4 + * + * Included uriGrammarFragment.txt from Gregory Kick + * + * @author Rong Chen (rong.acode@gmail.com) + * @version 1.4 + */ public class DADLParser { /* static fields */ private static final String CHARSET = "UTF-8"; private static final String ATTRIBUTE_UNKNOWN = "__unknown__"; /* ======================= public constructors ======================== */ /* Constructor that takes file as input */ public DADLParser(File file) throws IOException { this (new FileInputStream(file), CHARSET); } /* Constructor that takes string as input */ public DADLParser(String value) { this (new BufferedReader(new StringReader(value))); } /* ========================= public interface ======================== */ /* execute the parsing */ public ContentObject parse() throws ParseException { return input(); } /* re-initial the parser */ public void reInit(File file) throws IOException { ReInit(new FileInputStream(file), CHARSET); } /* re-initial the parser */ public void reInit(InputStream input) throws IOException { ReInit(new BufferedInputStream(input)); } } PARSER_END(DADLParser) <* > SKIP : /* WHITE SPACE */ { " " | "\t" | "\n" | "\r" | "\f" | "\ufeff" /* UTF-8 Byte Order Mark */ } <* > SPECIAL_TOKEN : /* COMMENTS */ { < SINGLE_LINE_COMMENT : "--" (~[ "\n", "\r" ])* > } <* > TOKEN [ IGNORE_CASE ] : /* KEYWORDS - dADL */ { < SYM_TRUE : "true" > | < SYM_FALSE : "false" > } <* > TOKEN : /* SYMBOLS - common */ { < SYM_MINUS : "-" > | < SYM_PLUS : "+" > | < SYM_STAR : "*" > | < SYM_SLASH : "/" > | < SYM_CARET : "^" > | < SYM_DOT : "." > | < SYM_SEMICOLON : ";" > | < SYM_COMMA : "," > | < SYM_TWO_COLONS : "::" > | < SYM_COLON : ":" > | < SYM_EXCLAMATION : "!" > | < SYM_L_PARENTHESIS : "(" > | < SYM_R_PARENTHESIS : ")" > | < SYM_DOLLAR : "$" > | < SYM_QUESTION : "?" > | < SYM_L_BRACKET : "[" > | < SYM_R_BRACKET : "]" > | < SYM_INTERVAL_DELIM : "|" > | < SYM_EQ : "=" > | < SYM_GE : ">=" > | < SYM_LE : "<=" > | < SYM_LT : "<" > | < SYM_GT : ">" > | < SYM_NE : "!=" > | < SYM_MODULO : "\\" > | < SYM_DIV : "//" > | < SYM_ELLIPSIS : ".." > | < SYM_LIST_CONTINUE : "..." > | < SYM_C_DV_ORDINAL : "C_DV_ORDINAL" > } <* > TOKEN : /* LOCAL TOKENS */ { < #DIG : [ "0"-"9" ] > | < #LET_DIG : [ "a"-"z", "A"-"Z", "0"-"9" ] > | < #LET_DIG_DD : < LET_DIG > | "." | "-" > | < #LET_DIG_U : < LET_DIG > | "_" > | < #LET_DIG_DU : < LET_DIG_U > | "-" > | < #LET_DIG_DUDS : < LET_DIG_DU > | "." | "\\" > | < #LET_DIG_DUDSLR : < LET_DIG_DUDS > | "(" | ")" > } /* -------------------- TOKEN - dADL & cADL ------------------------- */ <* > TOKEN : /* VALUES - dADL & cADL */ { < V_ISO8601_DURATION : ("-")? "P" ( (< DIG >)+ [ "m", "M" ] )? ( (< DIG >)+ [ "w", "W" ] )? ( (< DIG >)+ [ "d", "D" ] )? ( "T" ( (< DIG >)+ [ "h", "H" ] )? ( (< DIG >)+ [ "m", "M" ] )? ( (< DIG >)+ [ "s", "S" ] )? )? > | < V_TYPE_IDENTIFIER : [ "A"-"Z" ] (< LET_DIG_U >)* > | < V_GENERIC_TYPE_IDENTIFIER : [ "A"-"Z" ] (< LET_DIG_U >)* "<" ( < LET_DIG_U > | "," | "<" | ">" )+ ">" > | < V_ATTRIBUTE_IDENTIFIER : [ "a"-"z" ] (< LET_DIG_U >)* > | < #V_LOCAL_CODE_CORE : "a" [ "c", "t" ] ([ "0"-"9", "." ])+ > | < V_INTEGER : (< DIG >)+ | (< DIG >) { 1, 3 } ( "," (< DIG >) { 3 } )+ > | < V_REAL : (< DIG >)+ "./" ~[ ".", "0"-"9" ] | (< DIG >)+ "." (< DIG >)* [ "e", "E" ] ([ "+", "-" ])? (< DIG >)+ | (< DIG >)* "." (< DIG >)+ ( [ "e", "E" ] ([ "+", "-" ])? (< DIG >)+ )? | (< DIG >) { 1, 3 } ( "_" (< DIG >) { 3 } )+ "./" ~[ ".", "0"-"9" ] | (< DIG >) { 1, 3 } ( "_" (< DIG >) { 3 } )* "." ( (< DIG >) { 1, 3 } ( "_" (< DIG >) { 3 } )* )? [ "e", "E" ] ([ "+", "-" ])? (< DIG >) { 1, 3 } ( "_" (< DIG >) { 3 } )* | ( (< DIG >) { 1, 3 } ( "_" (< DIG >) { 3 } )* )? "." (< DIG >) { 1, 3 } ( "_" (< DIG >) { 3 } )* ( [ "e", "E" ] ([ "+", "-" ])? (< DIG >) { 1, 3 } ( "_" (< DIG >) { 3 } )* )? > | < V_STRING : "\"" ( ( "\\\"" (~[ "\"", "\n", "\\" ])* ) | ( "\n" ([ "\r", " ", "\t" ])* ) | (~[ "\\", "\n", "\"" ])* )* "\"" > | < V_LOCAL_CODE_PATH : "\"[" < V_LOCAL_CODE_CORE > "]/" ( < V_ATTRIBUTE_IDENTIFIER > ("/" < V_ATTRIBUTE_IDENTIFIER >)* "[" < V_LOCAL_CODE_CORE > "]/" )* "\"" > | < V_CHARACTER : "'" ~[ "\\", "\n", "'" ] "'" | < CHAR_REF > > | < V_DATE : ([ "0"-"9" ]) { 4 } "-" ( "0" [ "1"-"9" ] | "1" [ "0"-"2" ] ) "-" ( "0" [ "1"-"9" ] | [ "1"-"2" ] [ "0"-"9" ] | "3" [ "0"-"1" ] ) > | < V_HHMM_TIME : < HOUR_MINUTE > > | < V_HHMMSS_TIME : < HOUR_MINUTE > < SECOND > > | < V_HHMMSSss_TIME : < HOUR_MINUTE > < SECOND > < MILLI_SECOND > > | < V_HHMMSSZ_TIME : < HOUR_MINUTE > < SECOND > < TIME_ZONE > > | < V_HHMMSSssZ_TIME : < HOUR_MINUTE > < SECOND > < MILLI_SECOND > < TIME_ZONE > > | < V_DATE_TIME : < V_DATE > "T" < HOUR_MINUTE > < SECOND > > | < V_DATE_TIME_MS : < V_DATE_TIME > < MILLI_SECOND > > | < V_DATE_TIME_Z : < V_DATE_TIME > < TIME_ZONE > > | < V_DATE_TIME_MSZ : < V_DATE_TIME > < MILLI_SECOND > < TIME_ZONE > > | < #TIME_ZONE : [ "-", "+" ] ([ "0"-"9" ]) { 4 } | "Z" > | < #SECOND : ":" [ "0"-"5" ] [ "0"-"9" ] > | < #MILLI_SECOND : "." ([ "0"-"9" ]) { 2, 3 } > | < #HOUR_MINUTE : [ "0"-"9" ] [ "0"-"9" ] ":" [ "0"-"5" ] [ "0"-"9" ] > | < #CHAR_REF : "'&" ( ([ "a"-"z", "A"-"Z" ])+ | "#" ( ([ "0"-"9" ])+ | "x" ([ "0"-"9", "a"-"f", "A"-"F" ])+ ) ) ";'" > | < V_CODE_PHRASE : "[" (< LET_DIG_DUDSLR >)+ "::" (< LET_DIG_DUDS >)+ "]" > } <* > TOKEN : /* VALUES - dADL */ { < V_QUALIFIED_TERM_CODE_REF : "[" (< LET_DIG_DUDSLR >)+ "::" (< LET_DIG_DUDS >)+ "]" > } /***************************************** + * THE dADL LANGUAGE GRAMMAR STARTS HERE * + *****************************************/ ContentObject input() : { ContentObject obj; List < AttributeValue > attributeValues = null; ComplexObjectBlock complexObjectBlock = null; } { ( LOOKAHEAD(2) attributeValues = attr_vals() | LOOKAHEAD(2) complexObjectBlock = complex_object_block() ) { obj = new ContentObject(attributeValues, complexObjectBlock); return obj; } } ComplexObjectBlock complex_object_block() : { ComplexObjectBlock obj; } { ( LOOKAHEAD(single_attr_object_block()) obj = single_attr_object_block() | LOOKAHEAD(multiple_attr_object_block()) obj = multiple_attr_object_block() ) { return obj; } } SingleAttributeObjectBlock single_attr_object_block() : { String type = null; List < AttributeValue > values = Collections.EMPTY_LIST; } { [ type = type_identifier() ] < SYM_LT > [ values = attr_vals() ] < SYM_GT > { return new SingleAttributeObjectBlock(type, values); } } MultipleAttributeObjectBlock multiple_attr_object_block() : { String type = null; KeyedObject obj; List < KeyedObject > keyedObjects = new ArrayList < KeyedObject > (); } { [ type = type_identifier() ] < SYM_LT > ( obj = keyed_object() { keyedObjects.add(obj); } )+ < SYM_GT > { return new MultipleAttributeObjectBlock(type, keyedObjects); } } KeyedObject keyed_object() : { SimpleValue key; ObjectBlock object; } { key = object_key() < SYM_EQ > object = object_block() { return new KeyedObject(key, object); } } SimpleValue object_key() : { SimpleValue key; } { < SYM_L_BRACKET > key = simple_value() < SYM_R_BRACKET > { return key; } } ObjectBlock object_block() : { ObjectBlock object; } { ( LOOKAHEAD(complex_object_block()) object = complex_object_block() | LOOKAHEAD(primitive_object_block()) object = primitive_object_block() ) { return object; } } PrimitiveObjectBlock primitive_object_block() : { String type = null; SimpleValue simpleValue = null; List < SimpleValue > simpleListValue = null; Interval < Comparable > simpleIntervalValue = null; String termCode = null; List < String > termCodeList = null; } { [ type = type_identifier() ] < SYM_LT > ( LOOKAHEAD(2) simpleListValue = simple_list_value() | LOOKAHEAD(2) simpleValue = simple_value() | simpleIntervalValue = simple_interval_value() | LOOKAHEAD(2) termCode = term_code() | LOOKAHEAD(2) termCodeList = term_code_list_value() ) < SYM_GT > { return new PrimitiveObjectBlock(type, simpleValue, simpleListValue, simpleIntervalValue, termCode, termCodeList); } } List < AttributeValue > attr_vals() : { List < AttributeValue > list = new ArrayList < AttributeValue > (); AttributeValue av; } { av = attr_val() { list.add(av); } ( (";")? av = attr_val() { list.add(av); } )* { return list; } } AttributeValue attr_val() : { String id; ObjectBlock value; } { id = attribute_identifier() < SYM_EQ > value = object_block() { return new AttributeValue(id, value); } } SimpleValue simple_value() : { SimpleValue value; DvDateTime datetime = null; DvDate date = null; DvTime time = null; DvDuration duration = null; int i = 0; double d = 0; boolean b = false; char c = 0; String str = null; CodePhrase cp = null; } { ( LOOKAHEAD(date_time_value()) datetime = date_time_value() { value = new DateTimeValue(datetime); } | LOOKAHEAD(date_value()) date = date_value() { value = new DateValue(date); } | LOOKAHEAD(time_value()) time = time_value() { value = new TimeValue(time); } | LOOKAHEAD(duration_value()) duration = duration_value() { value = new DurationValue(duration); } | LOOKAHEAD(real_value()) d = real_value() { value = new RealValue(new Double(d)); } | LOOKAHEAD(integer_value()) i = integer_value() { value = new IntegerValue(new Integer(i)); } | b = boolean_value() { value = new BooleanValue(new Boolean(b)); } | c = character_value() { value = new CharacterValue(new Character(c)); } | cp = code_phrase() { value = new CodeValue(cp); } | LOOKAHEAD(string_value()) str = string_value() { value = new StringValue(str); } ) { return value; } } List simple_list_value() : { List list; } { ( LOOKAHEAD(time_list_value()) list = time_list_value() | LOOKAHEAD(date_list_value()) list = date_list_value() | LOOKAHEAD(date_time_list_value()) list = date_time_list_value() | LOOKAHEAD(duration_list_value()) list = duration_list_value() | LOOKAHEAD(integer_list_value()) list = integer_list_value() | LOOKAHEAD(real_list_value()) list = real_list_value() | list = boolean_list_value() | list = character_list_value() | list = string_list_value() | list = code_phrase_list_value() ) { return list; } } Interval < Comparable > simple_interval_value() : { Interval < Comparable > i; } { ( LOOKAHEAD(date_interval_value()) i = date_interval_value() | LOOKAHEAD(time_interval_value()) i = time_interval_value() | LOOKAHEAD(date_time_interval_value()) i = date_time_interval_value() | LOOKAHEAD(duration_interval_value()) i = duration_interval_value() | LOOKAHEAD(real_interval_value()) i = real_interval_value() | LOOKAHEAD(integer_interval_value()) i = integer_interval_value() ) { return i; } } String string_value() : { Token t; String value; } { t = < V_STRING > { value = t.image; } { return value.substring(1, value.length() - 1); } } List index_string_list() : { List list = new ArrayList(); String value = null; String index = null; // not used +} { ( < SYM_L_BRACKET > index = string_value() < SYM_R_BRACKET > < SYM_EQ > < SYM_LT > ( value = string_value() ) { list.add(value); } < SYM_GT > )* { return list.isEmpty() ? null : list; } } List string_list_value() : { List list = new ArrayList(); String value; } { value = string_value() { list.add(new StringValue(value)); } ( LOOKAHEAD(2) "," ( value = string_value() { list.add(new StringValue(value)); } | < SYM_LIST_CONTINUE > ) )+ { return list; } } int integer_value() : { int i; boolean negative = false; } { [ ( "+" | "-" { negative = true; } ) ] i = positive_int_value() { if (negative) { i = - i; } return i; } } int positive_int_value() : { Token t; } { t = < V_INTEGER > { try { return Integer.parseInt(t.image); } catch (NumberFormatException e) { throw new ParseException("Wrong format of integer: " + t.image); } } } List integer_list_value() : { List list = new ArrayList(); int i; } { i = integer_value() { list.add(new Integer(i)); } ( "," ( i = integer_value() { list.add(new Integer(i)); } | < SYM_LIST_CONTINUE > ) )+ { return list; } } List code_phrase_list_value() : { List list = new ArrayList(); CodePhrase cp = null; } { cp = code_phrase() { list.add(new CodeValue(cp)); } ( "," ( cp = code_phrase() { list.add(new CodeValue(cp)); } | < SYM_LIST_CONTINUE > ) )+ { return list; } } Interval integer_interval_value() : { Interval i = null; int lower = 0; int upper = 0; } { < SYM_INTERVAL_DELIM > ( LOOKAHEAD(3) { boolean lowerInclusive = true; boolean upperInclusive = true; boolean upperSpecified = false; } [ < SYM_GT > { lowerInclusive = false; } ] lower = integer_value() { upper = lower; } [ < SYM_ELLIPSIS > [ < SYM_LT > { upperInclusive = false; } ] upper = integer_value() { 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, upperInclusive); } } | < SYM_LT > upper = integer_value() { i = new Interval(null, new Integer(upper), false, false); } | < SYM_GT > lower = integer_value() { i = new Interval(new Integer(lower), null, false, false); } | < SYM_LE > upper = integer_value() { i = new Interval(null, new Integer(upper), false, true); } | < SYM_GE > lower = integer_value() { i = new Interval(new Integer(lower), null, true, false); } ) < SYM_INTERVAL_DELIM > { return i; } } CodePhrase code_phrase() : { Token t; String lang = null; String langTerm = null; String langCode = null; } { t = < V_CODE_PHRASE > { lang = t.image; int i = lang.indexOf("::"); langTerm = lang.substring(1, i); langCode = lang.substring(i + 2, lang.length() - 1); } { return new CodePhrase(langTerm, langCode); } } double real_value() : { Token t; double d; boolean negative = false; } { [ ( "+" | "-" { negative = true; } ) ] t = < V_REAL > { try { d = Double.parseDouble(t.image); } catch (NumberFormatException e) { throw new ParseException("Wrong format of double: " + t.image); } if (negative) { d = - d; } return d; } } List real_list_value() : { List list = new ArrayList(); double d; } { d = real_value() { list.add(new Double(d)); } ( "," ( d = real_value() { list.add(new Double(d)); } | < SYM_LIST_CONTINUE > ) )+ { return list; } } Interval real_interval_value() : { Interval i = null; double upper = 0; double lower = 0; } { < SYM_INTERVAL_DELIM > ( LOOKAHEAD(3) { boolean lowerInclusive = true; boolean upperInclusive = true; boolean upperSpecified = false; } [ < SYM_GT > { lowerInclusive = false; } ] lower = real_value() { upper = lower; } [ < SYM_ELLIPSIS > [ < SYM_LT > { upperInclusive = false; } ] 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, upperInclusive); } } | < SYM_LT > upper = real_value() { i = new Interval(null, new Double(upper), false, false); } | < SYM_LE > upper = real_value() { i = new Interval(null, new Double(upper), false, true); } | < SYM_GT > lower = real_value() { i = new Interval(new Double(lower), null, false, false); } | < SYM_GE > lower = real_value() { i = new Interval(new Double(lower), null, true, false); } ) < SYM_INTERVAL_DELIM > { return i; } } boolean boolean_value() : {} { < SYM_TRUE > { return true; } | < SYM_FALSE > { return false; } } List boolean_list_value() : { List list = new ArrayList(); boolean b; } { b = boolean_value() { list.add(new Boolean(b)); } ( "," ( b = boolean_value() { list.add(new Boolean(b)); } | < SYM_LIST_CONTINUE > ) )+ { return list; } } char character_value() : { Token t; } { t = < V_CHARACTER > { return t.image.charAt(1); } } List character_list_value() : { List list = new ArrayList(); char c; } { c = character_value() { list.add(new Character(c)); } ( "," ( c = character_value() { list.add(new Character(c)); } | < SYM_LIST_CONTINUE > ) )+ { return list; } } DvDate date_value() : { Token t; } { t = < V_DATE > { try { return new DvDate(t.image); } catch (Exception ignored) { throw new ParseException("wrong date format: " + t.image); } } } List date_list_value() : { List list = new ArrayList(); DvDate d; } { d = date_value() { list.add(d); } ( "," ( d = date_value() { list.add(d); } | < SYM_LIST_CONTINUE > ) )+ { return list; } } Interval date_interval_value() : { Interval i; DvDate lower = null; DvDate upper = null; } { < SYM_INTERVAL_DELIM > ( lower = date_value() { upper = lower; } [ < SYM_ELLIPSIS > upper = date_value() ] { i = new Interval(lower, upper, true, true); } | < SYM_LT > upper = date_value() { i = new Interval(null, upper, false, false); } | < SYM_LE > upper = date_value() { i = new Interval(null, upper, false, true); } | < SYM_GT > lower = date_value() { i = new Interval(lower, null, false, false); } | < SYM_GE > lower = date_value() { i = new Interval(lower, null, true, false); } ) < SYM_INTERVAL_DELIM > { return i; } } DvTime time_value() : { Token t; String pattern; } { ( t = < V_HHMM_TIME > { pattern = "HH:mm"; } | t = < V_HHMMSS_TIME > { pattern = "HH:mm:ss"; } | t = < V_HHMMSSss_TIME > { pattern = "HH:mm:ss.SSS"; } | t = < V_HHMMSSZ_TIME > { pattern = "HH:mm:ssZ"; } | t = < V_HHMMSSssZ_TIME > { pattern = "HH:mm:ss.SSSZ"; } ) { try { return new DvTime(t.image); } catch (Exception e) { throw new ParseException("wrong date format: " + t.image); } } } List time_list_value() : { List list = new ArrayList(); DvTime time; } { time = time_value() { list.add(time); } ( "," ( time = time_value() { list.add(time); } | < SYM_LIST_CONTINUE > ) )+ { return list; } } Interval time_interval_value() : { Interval i; DvTime lower = null; DvTime upper = null; } { < SYM_INTERVAL_DELIM > ( lower = time_value() { upper = lower; } [ < SYM_ELLIPSIS > upper = time_value() ] { i = new Interval(lower, upper, true, true); } | < SYM_LT > upper = time_value() { i = new Interval(null, upper, false, false); } | < SYM_LE > upper = time_value() { i = new Interval(null, upper, false, true); } | < SYM_GT > lower = time_value() { i = new Interval(lower, null, false, false); } | < SYM_GE > lower = time_value() { i = new Interval(lower, null, true, false); } ) < SYM_INTERVAL_DELIM > { return i; } } DvDateTime date_time_value() : { Token t; String pattern; } { ( t = < V_DATE_TIME > { pattern = "yyyy-MM-ddTHH:mm:ss"; } | t = < V_DATE_TIME_MS > { pattern = "yyyy-MM-ddTHH:mm:ss.SSS"; } | t = < V_DATE_TIME_Z > { pattern = "yyyy-MM-ddTHH:mm:ssZ"; } | t = < V_DATE_TIME_MSZ > { pattern = "yyyy-MM-ddTHH:mm:ss.SSSZ"; } ) { try { return new DvDateTime(t.image); } catch (Exception e) { throw new ParseException("wrong datetime format: " + t.image); } } } List date_time_list_value() : { List list = new ArrayList(); DvDateTime datetime; } { datetime = date_time_value() { list.add(datetime); } ( "," ( datetime = date_time_value() { list.add(datetime); } | < SYM_LIST_CONTINUE > ) )+ { return list; } } Interval date_time_interval_value() : { Interval i; DvDateTime lower = null; DvDateTime upper = null; } { < SYM_INTERVAL_DELIM > ( lower = date_time_value() { upper = lower; } [ < SYM_ELLIPSIS > upper = date_time_value() ] { i = new Interval(lower, upper, true, true); } | < SYM_LT > upper = date_time_value() { i = new Interval(null, upper, false, false); } | < SYM_LE > upper = date_time_value() { i = new Interval(null, upper, false, true); } | < SYM_GT > lower = date_time_value() { i = new Interval(lower, null, false, false); } | < SYM_GE > lower = date_time_value() { i = new Interval(lower, null, true, false); } ) < SYM_INTERVAL_DELIM > { return i; } } DvDuration duration_value() : { Token t; } { t = < V_ISO8601_DURATION > { return DvDuration.getInstance(t.image); } } List duration_list_value() : { List list = new ArrayList(); DvDuration d; } { d = duration_value() { list.add(d); } ( "," ( d = duration_value() { list.add(d); } | < SYM_LIST_CONTINUE > ) )+ { return list; } } Interval duration_interval_value() : { Interval i; DvDuration lower = null; DvDuration upper = null; } { < SYM_INTERVAL_DELIM > ( lower = duration_value() { upper = lower; } [ < SYM_ELLIPSIS > upper = duration_value() ] { i = new Interval(lower, upper, true, true); } | < SYM_LT > upper = duration_value() { i = new Interval(null, upper, false, false); } | < SYM_LE > upper = duration_value() { i = new Interval(null, upper, false, true); } | < SYM_GT > lower = duration_value() { i = new Interval(lower, null, false, false); } | < SYM_GE > lower = duration_value() { i = new Interval(lower, null, true, false); } ) < SYM_INTERVAL_DELIM > { return i; } } String term_code() : { Token t; } { t = < V_QUALIFIED_TERM_CODE_REF > { return t.image; } } List < String > term_code_list_value() : { List list = new ArrayList(); String term; } { term = term_code() { list.add(term); } ( "," ( term = term_code() ) { list.add(term); } | < SYM_LIST_CONTINUE > )+ { return list; } } List < String > string_list() : { List < String > list = new ArrayList(); String value = null; } { ( < SYM_L_BRACKET > string_value() < SYM_R_BRACKET > < SYM_EQ > < SYM_LT > value = string_value() < SYM_GT > { list.add(value); } )* { return list; } } String type_identifier() : { Token t; String type; } { < SYM_L_PARENTHESIS > ( t = < V_TYPE_IDENTIFIER > { type = t.image; } | t = < V_GENERIC_TYPE_IDENTIFIER > { type = t.image; } ) < SYM_R_PARENTHESIS > { return type; } } String attribute_identifier() : { Token t; } { t = < V_ATTRIBUTE_IDENTIFIER > { return t.image; } } \ No newline at end of file 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 new file mode 100644 index 00000000..ba02ed53 --- /dev/null +++ b/dadl-parser/src/test/java/org/openehr/am/parser/EmptyAttributeListBlockTest.java @@ -0,0 +1,28 @@ +package org.openehr.am.parser; + +public class EmptyAttributeListBlockTest extends ParserTestBase { + + public void testParseBlockWithEmptyAttrList() throws Exception { + DADLParser parser = new DADLParser(loadFromClasspath( + "empty_attr_list.dadl")); + ContentObject obj = parser.parse(); + + assertNotNull("contentObj null", obj); + assertEquals("type identifier missing", "DESTINATION_PROFILE", + obj.getComplexObjectBlock().getTypeIdentifier()); + + assertTrue(obj.getComplexObjectBlock() instanceof SingleAttributeObjectBlock); + } + + public void testParseEmptyAttrListWithoutTypeIdentifier() throws Exception { + DADLParser parser = new DADLParser(loadFromClasspath( + "empty_attr_list_without_type.dadl")); + ContentObject obj = parser.parse(); + + assertNotNull("contentObj null", obj); + + assertNull(obj.getComplexObjectBlock().getTypeIdentifier()); + + assertTrue(obj.getComplexObjectBlock() instanceof SingleAttributeObjectBlock); + } +} 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 new file mode 100644 index 00000000..654fee37 --- /dev/null +++ b/dadl-parser/src/test/java/org/openehr/am/parser/ItemListTest.java @@ -0,0 +1,27 @@ +package org.openehr.am.parser; + +public class ItemListTest extends ParserTestBase { + + public void testParseBlockWithEmptyAttrList() throws Exception { + DADLParser parser = new DADLParser(loadFromClasspath( + "state_item_list.dadl")); + ContentObject obj = parser.parse(); + + AttributeValue av = obj.getAttributeValues().get(0); + assertEquals("state", av.getId()); + + assertTrue(av.getValue() instanceof SingleAttributeObjectBlock); + + SingleAttributeObjectBlock saob = (SingleAttributeObjectBlock) av.getValue(); + assertEquals(3, saob.getAttributeValues().size()); + + av = saob.getAttributeValues().get(2); + assertEquals("items", av.getId()); + + ObjectBlock ob = av.getValue(); + assertTrue(ob instanceof SingleAttributeObjectBlock); + + saob = (SingleAttributeObjectBlock) ob; + assertTrue(saob.getAttributeValues().isEmpty()); + } +} \ No newline at end of file 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 new file mode 100644 index 00000000..88dda1dc --- /dev/null +++ b/dadl-parser/src/test/java/org/openehr/am/parser/KeyedObjectTest.java @@ -0,0 +1,72 @@ +package org.openehr.am.parser; + +import java.util.List; + +public class KeyedObjectTest extends ParserTestBase { + + public void testParseAndVerifySimpleValues() throws Exception { + DADLParser parser = new DADLParser(loadFromClasspath( + "keyed_objects.dadl")); + ContentObject content = parser.parse(); + + assertNotNull("contentObject is null", content); + + assertNull("contentObject.complexObjectBlock is not null", + content.getComplexObjectBlock()); + + assertNotNull("contentObject.attributeValues is null", + content.getAttributeValues()); + + assertEquals("contentObject.attributeValues.size wrong", 1, + content.getAttributeValues().size()); + + AttributeValue av = content.getAttributeValues().get(0); + + ObjectBlock ob = av.getValue(); + + assertTrue("not multiple attribute object block", + ob instanceof MultipleAttributeObjectBlock); + + MultipleAttributeObjectBlock maob = (MultipleAttributeObjectBlock) ob; + + List keyedObjects = maob.getKeyObjects(); + + assertEquals("total keyed objects wrong", keyedObjects.size(), 2); + + assertKeyedObject(keyedObjects.get(0), 1, "name", "systolic"); + assertKeyedObject(keyedObjects.get(1), 2, "name", "diastolic"); + } + + public void testParseCodePhraseAsKey() throws Exception { + DADLParser parser = new DADLParser(loadFromClasspath( + "keyed_objects2.dadl")); + ContentObject content = parser.parse(); + + assertNotNull("contentObject is null", content); + } + + private void assertKeyedObject(KeyedObject ko, int key, + String attribute, String value) { + SimpleValue keyValue = ko.getKey(); + assertTrue("key is not int", keyValue instanceof IntegerValue); + IntegerValue iv = (IntegerValue) keyValue; + assertEquals("key value wrong", iv.getValue(), new Integer(key)); + + ObjectBlock ob = ko.getObject(); + assertTrue("value is not single attribute object block, " + ob.getClass(), + ob instanceof SingleAttributeObjectBlock); + SingleAttributeObjectBlock saob = (SingleAttributeObjectBlock) ob; + List attributes = saob.getAttributeValues(); + assertEquals("total attribute wrong", attributes.size(), 1); + AttributeValue av = attributes.get(0); + assertEquals("attribute id wrong", av.getId(), attribute); + + ob = av.getValue(); + assertTrue("value is not primitive object block", + ob instanceof PrimitiveObjectBlock); + SimpleValue sv = ((PrimitiveObjectBlock) ob).getSimpleValue(); + assertTrue("value is not string", sv instanceof StringValue); + StringValue str = (StringValue) sv; + assertEquals("string value wrong", str.getValue(), value); + } +} 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 new file mode 100644 index 00000000..9330182e --- /dev/null +++ b/dadl-parser/src/test/java/org/openehr/am/parser/ParserTestBase.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2008 Cambio Healthcare Systems AB, Sweden + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You may obtain a copy of the License at + * http://www.gnu.org/licenses/gpl.txt + * + */ +package org.openehr.am.parser; + +import junit.framework.TestCase; + +import java.io.File; +import java.io.InputStream; + +/** + * Base class for all parser test cases + * + * @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); + } + + + /* fields */ + static protected File dir = new File("res" + File.separator + "test"); +} + 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 new file mode 100644 index 00000000..9a401779 --- /dev/null +++ b/dadl-parser/src/test/java/org/openehr/am/parser/SimpleValuesTest.java @@ -0,0 +1,158 @@ +package org.openehr.am.parser; + +import java.util.List; + +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; + +public class SimpleValuesTest extends ParserTestBase { + + public void testParseAndVerifySimpleValues() throws Exception { + DADLParser parser = new DADLParser(loadFromClasspath( + "simple_values.dadl")); + ContentObject content = parser.parse(); + + assertNotNull("contentObject is null", content); + + assertNull("contentObject.complexObjectBlock is not null", + content.getComplexObjectBlock()); + + assertNotNull("contentObject.attributeValues is null", + content.getAttributeValues()); + + assertEquals("contentObject.attributeValues.size wrong", 1, + content.getAttributeValues().size()); + + AttributeValue av = content.getAttributeValues().get(0); + + assertEquals("attribute id wrong", "simple_values", av.getId()); + + ObjectBlock ob = av.getValue(); + + assertTrue("attribute value type wrong", + ob instanceof SingleAttributeObjectBlock); + + SingleAttributeObjectBlock single = (SingleAttributeObjectBlock) ob; + + List values = single.getAttributeValues(); + + assertEquals("total number of simple values wrong", 10, values.size()); + + assertDateTimeValue(values.get(0), "2007-10-30T09:22:00"); + + assertDateValue(values.get(1), "2008-04-02"); + + assertTimeValue(values.get(2), "11:09:40"); + + assertDurationValue(values.get(3), "PT10M"); + + assertStringValue(values.get(4), "a string value"); + + assertCharacterValue(values.get(5), 'a'); + + assertIntegerValue(values.get(6), 100); + + assertRealValue(values.get(7), 9.5); + + assertBooleanValue(values.get(8), true); + } + + public void testParseValueList() throws Exception { + DADLParser parser = new DADLParser(loadFromClasspath( + "simple_values_list.dadl")); + ContentObject content = parser.parse(); + + assertNotNull("contentObject is null", content); + } + + private void assertDateTimeValue(AttributeValue attr, String value) { + assertTrue(attr.getValue() instanceof PrimitiveObjectBlock); + PrimitiveObjectBlock pob = (PrimitiveObjectBlock) attr.getValue(); + assertTrue("not datetime value", + pob.getSimpleValue() instanceof DateTimeValue); + DateTimeValue actual = (DateTimeValue) pob.getSimpleValue(); + DvDateTime expected = new DvDateTime(value); + assertEquals("datetime value wrong", actual.getValue(), expected); + } + + private void assertDateValue(AttributeValue attr, String value) { + assertTrue(attr.getValue() instanceof PrimitiveObjectBlock); + PrimitiveObjectBlock pob = (PrimitiveObjectBlock) attr.getValue(); + assertTrue("not date value", + pob.getSimpleValue() instanceof DateValue); + DateValue actual = (DateValue) pob.getSimpleValue(); + DvDate expected = new DvDate(value); + assertEquals("date value wrong", actual.getValue(), expected); + } + + private void assertTimeValue(AttributeValue attr, String value) { + assertTrue(attr.getValue() instanceof PrimitiveObjectBlock); + PrimitiveObjectBlock pob = (PrimitiveObjectBlock) attr.getValue(); + assertTrue("not time value", + pob.getSimpleValue() instanceof TimeValue); + TimeValue actual = (TimeValue) pob.getSimpleValue(); + DvTime expected = new DvTime(value); + assertEquals("time value wrong", actual.getValue(), expected); + } + + private void assertDurationValue(AttributeValue attr, String value) { + assertTrue(attr.getValue() instanceof PrimitiveObjectBlock); + PrimitiveObjectBlock pob = (PrimitiveObjectBlock) attr.getValue(); + assertTrue("not duration value", + pob.getSimpleValue() instanceof DurationValue); + DurationValue actual = (DurationValue) pob.getSimpleValue(); + DvDuration expected = new DvDuration(value); + assertEquals("duration value wrong", actual.getValue(), expected); + } + + private void assertStringValue(AttributeValue attr, String value) { + assertTrue(attr.getValue() instanceof PrimitiveObjectBlock); + PrimitiveObjectBlock pob = (PrimitiveObjectBlock) attr.getValue(); + assertTrue("not string value", + pob.getSimpleValue() instanceof StringValue); + StringValue str = (StringValue) pob.getSimpleValue(); + assertEquals("string value wrong", str.getValue(), value); + } + + private void assertCharacterValue(AttributeValue attr, char value) { + assertTrue(attr.getValue() instanceof PrimitiveObjectBlock); + PrimitiveObjectBlock pob = (PrimitiveObjectBlock) attr.getValue(); + assertTrue("not Character value", + pob.getSimpleValue() instanceof CharacterValue); + CharacterValue actual = (CharacterValue) pob.getSimpleValue(); + Character expected = new Character(value); + assertEquals("character value wrong", actual.getValue(), expected); + } + + private void assertIntegerValue(AttributeValue attr, int value) { + assertTrue(attr.getValue() instanceof PrimitiveObjectBlock); + PrimitiveObjectBlock pob = (PrimitiveObjectBlock) attr.getValue(); + assertTrue("not integer value", + pob.getSimpleValue() instanceof IntegerValue); + IntegerValue actual = (IntegerValue) pob.getSimpleValue(); + Integer expected = new Integer(value); + assertEquals("integer value wrong", actual.getValue(), expected); + } + + private void assertRealValue(AttributeValue attr, double value) { + assertTrue(attr.getValue() instanceof PrimitiveObjectBlock); + PrimitiveObjectBlock pob = (PrimitiveObjectBlock) attr.getValue(); + assertTrue("not real value", + pob.getSimpleValue() instanceof RealValue); + RealValue actual = (RealValue) pob.getSimpleValue(); + Double expected = new Double(value); + assertEquals("real value wrong", actual.getValue(), expected); + } + + private void assertBooleanValue(AttributeValue attr, boolean value) { + assertTrue(attr.getValue() instanceof PrimitiveObjectBlock); + PrimitiveObjectBlock pob = (PrimitiveObjectBlock) attr.getValue(); + assertTrue("not boolean value", + pob.getSimpleValue() instanceof BooleanValue); + BooleanValue actual = (BooleanValue) pob.getSimpleValue(); + Boolean expected = new Boolean(value); + assertEquals("boolean value wrong", actual.getValue(), expected); + } +} 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 new file mode 100644 index 00000000..a7d81bc1 --- /dev/null +++ b/dadl-parser/src/test/java/org/openehr/am/parser/SingleValueListTest.java @@ -0,0 +1,30 @@ +package org.openehr.am.parser; + +public class SingleValueListTest extends ParserTestBase { + + // verify the fix of a bug introducing duplicated items in single value list + public void testParseSingleValueLists() throws Exception { + DADLParser parser = new DADLParser(loadFromClasspath( + "single_values_list.dadl")); + content = parser.parse(); + assertEquals(1, listSize(0)); + assertEquals(1, listSize(1)); + assertEquals(1, listSize(2)); + assertEquals(1, listSize(3)); + assertEquals(1, listSize(4)); + assertEquals(1, listSize(5)); + assertEquals(1, listSize(6)); + assertEquals(1, listSize(7)); + assertEquals(1, listSize(8)); + assertEquals(1, listSize(9)); + } + + int listSize(int index) { + return ((PrimitiveObjectBlock) ((AttributeValue) + ((SingleAttributeObjectBlock) content.getAttributeValues() + .get(0).getValue()).getAttributeValues().get(index)) + .getValue()).getSimpleListValue().size(); + } + + private ContentObject content; +} 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 new file mode 100644 index 00000000..76054d11 --- /dev/null +++ b/dadl-parser/src/test/java/org/openehr/am/parser/StructureTest.java @@ -0,0 +1,20 @@ +package org.openehr.am.parser; + +public class StructureTest extends ParserTestBase { + + public StructureTest(String test) { + super(test); + } + + public void testParseSimpleDADL() throws Exception { + DADLParser parser = new DADLParser(loadFromClasspath( + "blood_pressure_001.dadl")); + parser.parse(); + } + + public void testTypedObjectWithKeyedAttributes() throws Exception { + DADLParser parser = new DADLParser(loadFromClasspath( + "person_001.dadl")); + parser.parse(); + } +} 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 new file mode 100644 index 00000000..bf174f6d --- /dev/null +++ b/dadl-parser/src/test/java/org/openehr/am/parser/TypedObjectBlockTest.java @@ -0,0 +1,15 @@ +package org.openehr.am.parser; + +public class TypedObjectBlockTest extends ParserTestBase { + + public void testParseTypedDvQuantity() throws Exception { + DADLParser parser = new DADLParser(loadFromClasspath("typed_dv_quantity.dadl")); + ContentObject obj = parser.parse(); + + assertNotNull("contentObj null", obj); + + // message, expected, actual + assertEquals("type identifier missing", "DV_QUANTITY", + obj.getComplexObjectBlock().getTypeIdentifier()); + } +} diff --git a/dadl-parser/src/test/resources/blood_pressure_001.dadl b/dadl-parser/src/test/resources/blood_pressure_001.dadl new file mode 100644 index 00000000..c62e59c5 --- /dev/null +++ b/dadl-parser/src/test/resources/blood_pressure_001.dadl @@ -0,0 +1,44 @@ +blood_pressure_001 = < + archetype_node_id = <"openEHR-EHR-OBSERVATION.blood_pressure.v1"> + name = < + value = <"BP measurement"> + > + data = < + archetype_node_id = <"at0001"> + origin = <2007-10-30T09:22:00> + events = < + [1] = < + archetype_node_id = <"at0006"> + name = < + value = <"sitting"> + > + time = <2005-12-03T09:22:00> + data = < + archetype_node_id = <"at0003"> + items = < + [1] = < + name = < + value = <"systolic"> + > + archetype_node_id = <"at0004"> + value = < + magnitude = <120.0> + units = <"mmHg"> + > + > + [2] = < + name = < + value = <"diastolic"> + > + archetype_node_id = <"at0005"> + value = < + magnitude = <80.0> + units = <"mmHg"> + > + > + > + > + > + > + > +> \ No newline at end of file diff --git a/dadl-parser/src/test/resources/empty_attr_list.dadl b/dadl-parser/src/test/resources/empty_attr_list.dadl new file mode 100644 index 00000000..c55a0c69 --- /dev/null +++ b/dadl-parser/src/test/resources/empty_attr_list.dadl @@ -0,0 +1 @@ +(DESTINATION_PROFILE) <> \ No newline at end of file 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 new file mode 100644 index 00000000..6787e487 --- /dev/null +++ b/dadl-parser/src/test/resources/empty_attr_list_without_type.dadl @@ -0,0 +1 @@ +<> \ No newline at end of file diff --git a/dadl-parser/src/test/resources/keyed_objects.dadl b/dadl-parser/src/test/resources/keyed_objects.dadl new file mode 100644 index 00000000..17c5d5f7 --- /dev/null +++ b/dadl-parser/src/test/resources/keyed_objects.dadl @@ -0,0 +1,8 @@ +items = < + [1] = < + name = <"systolic"> + > + [2] = < + name = <"diastolic"> + > +> \ No newline at end of file diff --git a/dadl-parser/src/test/resources/keyed_objects2.dadl b/dadl-parser/src/test/resources/keyed_objects2.dadl new file mode 100644 index 00000000..05dc11ba --- /dev/null +++ b/dadl-parser/src/test/resources/keyed_objects2.dadl @@ -0,0 +1,8 @@ +items = < + [[ISO_639-1::en]] = < + name = <"systolic"> + > + [[ISO_639-1::es]] = < + name = <"diastolic"> + > +> \ No newline at end of file diff --git a/dadl-parser/src/test/resources/person_001.dadl b/dadl-parser/src/test/resources/person_001.dadl new file mode 100644 index 00000000..8f8b64dc --- /dev/null +++ b/dadl-parser/src/test/resources/person_001.dadl @@ -0,0 +1,14 @@ +(PERSON)< + details = (ITEM_TREE)< + archetype_node_id = <"at0001"> + items = (List)< + [1] = (ELEMENT)< + archetype_node_id = <"at0002"> + > + [2] = (ELEMENT)< + > + [3] = (CLUSTER)< + > + > + > +> \ No newline at end of file diff --git a/dadl-parser/src/test/resources/simple_values.dadl b/dadl-parser/src/test/resources/simple_values.dadl new file mode 100644 index 00000000..762ecbd7 --- /dev/null +++ b/dadl-parser/src/test/resources/simple_values.dadl @@ -0,0 +1,12 @@ +simple_values = < + datetime_value = <2007-10-30T09:22:00> + date_value = <2008-04-02> + time_value = <11:09:40> + duration_value = + string_value = <"a string value"> + character_value = <'a'> + integer_value = <100> + real_value = <9.5> + boolean_value = + code_value = <[ISO_639-1::en]> +> \ No newline at end of file diff --git a/dadl-parser/src/test/resources/simple_values_list.dadl b/dadl-parser/src/test/resources/simple_values_list.dadl new file mode 100644 index 00000000..806b34de --- /dev/null +++ b/dadl-parser/src/test/resources/simple_values_list.dadl @@ -0,0 +1,13 @@ +simple_values = < + datetime_value = <2007-10-30T09:22:00> + date_value = <2008-04-02> + time_value = <11:09:40> + duration_value = + string_value = <"a string value", "2nd string value", "3rd value"> + character_value = <'a'> + integer_value = <100> + real_value = <9.5> + boolean_value = + code_value = <[ISO_639-1::en]> + codes =<[SNOMEDCT::1111111], [SNOMEDCT::22222222], [SNOMEDCT::33333333]> +> \ No newline at end of file diff --git a/dadl-parser/src/test/resources/single_values_list.dadl b/dadl-parser/src/test/resources/single_values_list.dadl new file mode 100644 index 00000000..2678560a --- /dev/null +++ b/dadl-parser/src/test/resources/single_values_list.dadl @@ -0,0 +1,12 @@ +single_values = < + datetime = <2007-10-30T09:22:00,...> + date = <2008-04-02,...> + time = <11:09:40,...> + duration = + string = <"a string value",...> + char = <'a',...> + integer = <100,...> + real = <9.5,...> + boolean = + code_phrase = <[ISO_639-1::en],...> +> \ No newline at end of file diff --git a/dadl-parser/src/test/resources/state_item_list.dadl b/dadl-parser/src/test/resources/state_item_list.dadl new file mode 100644 index 00000000..4c1c00fe --- /dev/null +++ b/dadl-parser/src/test/resources/state_item_list.dadl @@ -0,0 +1,7 @@ +state = (ITEM_LIST) < + archetype_node_id = <"at0007"> + name = < + value = <"item list"> + > + items = <> +> \ No newline at end of file diff --git a/dadl-parser/src/test/resources/typed_dv_quantity.dadl b/dadl-parser/src/test/resources/typed_dv_quantity.dadl new file mode 100644 index 00000000..e1a41a2c --- /dev/null +++ b/dadl-parser/src/test/resources/typed_dv_quantity.dadl @@ -0,0 +1,4 @@ +(DV_QUANTITY) < + magnitude = <120.0> + units = <"mmHg"> +> \ No newline at end of file diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml new file mode 100644 index 00000000..2efaca6d --- /dev/null +++ b/measure-serv/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5-SNAPSHOT + + measure-serv + jar + openEHR Measurement Service Implementation + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2007 + + Java implementation of the openEHR Measurement Service + + + + commons-lang + commons-lang + 2.6 + + + junit + junit + 3.8.1 + test + + + javax.measure + jsr-275 + 0.9.4 + + + diff --git a/measure-serv/readme.txt b/measure-serv/readme.txt new file mode 100644 index 00000000..989981f0 --- /dev/null +++ b/measure-serv/readme.txt @@ -0,0 +1 @@ +A simple implementation of the openEHR meausrement service \ No newline at end of file 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 new file mode 100644 index 00000000..4c8aea2a --- /dev/null +++ b/measure-serv/src/main/java/org/openehr/rm/support/measurement/MeasurementService.java @@ -0,0 +1,99 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class MeasurementService" + * keywords: "support" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/support/measurement/MeasurementService.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.support.measurement; + +import java.io.Serializable; + +/** + * Defines an interfaceto a measurement information service + * + * @author Rong Chen + * @version 1.0 + * + */ +public interface MeasurementService extends Serializable{ + + /** + * Returns True if the units string according to + * the HL7 UCUM specification. + * + * @param units + * @return true if units valid + * @throws IllegalArgumentException if units null + */ + 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 + * @throws IllegalArgumentException if units1 or units2 null + */ + public boolean unitsEquivalent(String units1, String units2); + + /** + * Return True if two units strings are comparable. + * + * @param units1 + * @param units2 + * @return true if two units comparable + * @throws IllegalArgumentException if units1 or units2 null + */ + public boolean unitsComparable(String units1, String units2); + + /** + * Comparison between two measures. + * + * @param units1 + * @param units2 + * @return a negative integer, zero, or a positive integer as this measure + * is less than, equal to, or greater than the specified measurable + * quantity. + * @throws IllegalArgumentException if units1, units2 null or not comparable + */ + public int compare(String units1, Double value1, String units2, Double value2); +} +/* + * ***** 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 MeasurementService.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/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 new file mode 100644 index 00000000..4e294532 --- /dev/null +++ b/measure-serv/src/main/java/org/openehr/rm/support/measurement/SimpleMeasurementService.java @@ -0,0 +1,263 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class SimpleMeasurementService" + * keywords: "support" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2007 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +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; + +/** + * Simple implementation of measurement information service + * + * @author Rong Chen + * @version 1.0 + * + */ +public class SimpleMeasurementService implements MeasurementService { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public static MeasurementService getInstance() { + return soleInstance; + } + + private static final SimpleMeasurementService soleInstance = + new SimpleMeasurementService(); + + 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" + + )); + /** + * Returns True if the units string according to + * the HL7 UCUM specification. + * Note that this implementation currrently 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"); + } + + // 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; + } + + /** + * Return True if two units strings correspond to the same + * measured property. + * + * @param units1 + * @param units2 + * @return true if two units equal + * @throws IllegalArgumentException if units1 or units2 null + */ + public boolean unitsEquivalent(String units1, String units2) { + if(units1 == null) { + throw new IllegalArgumentException("units1 null"); + } + if(units2 == null) { + throw new IllegalArgumentException("units2 null"); + } + 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); + } + + /** + * Return True if two units strings are comparable. + * + * @param units1 + * @param units2 + * @return true if two units comparable + * @throws IllegalArgumentException if units1 or units2 null + */ + public boolean unitsComparable(String units1, String units2) { + if (unitsEquivalent(units1, units2)){ + return true; + }else{ + Unit u1 = Unit.valueOf(units1); + Unit u2 = Unit.valueOf(units2); + return u1.isCompatible(u2); + } + } + + /** + * Comparison between two measures. + * + * @param units1 + * @param units2 + * @return a negative integer, zero, or a positive integer as this measure + * is less than, equal to, or greater than the specified measurable + * quantity. + * @throws IllegalArgumentException if units1, units2 null or not comparable + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public int compare(String units1, Double value1, String units2, Double value2) { + if(value1 == null) { + throw new IllegalArgumentException("value1 null"); + } + if(value2 == null) { + throw new IllegalArgumentException("value2 null"); + } + if (unitsEquivalent(units1, units2)){ + return value1.compareTo(value2); + }else{ + Unit unit1 = Unit.valueOf(units1); + Unit unit2 = Unit.valueOf(units2); + + if (!unit1.isCompatible(unit2)){ + throw new IllegalArgumentException("units '"+units1+"' is not comparable to '"+units2+"'"); + } + Measure measure1 = Measure.valueOf(value1, unit1); + Measure measure2 = Measure.valueOf(value2, unit2); + return measure1.compareTo(measure2); + } + } +} +/* + * ***** 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 SimpleMeasurementService.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2007 + * 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/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 new file mode 100644 index 00000000..e5d26eed --- /dev/null +++ b/measure-serv/src/test/java/org/openehr/rm/support/measurement/SimpleMeasurementServiceTest.java @@ -0,0 +1,57 @@ +package org.openehr.rm.support.measurement; + +import junit.framework.TestCase; + +public class SimpleMeasurementServiceTest extends TestCase { + + @Override + public void setUp() { + service = SimpleMeasurementService.getInstance(); + } + + public void testunitsEquivalent() throws Exception { + //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]")); + } + + 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); + } + + 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("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")); + + } + + private MeasurementService service; +} diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml new file mode 100644 index 00000000..bfd23682 --- /dev/null +++ b/mini-termserv/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5-SNAPSHOT + + mini-termserv + jar + openEHR Minimum Terminology Service + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2007 + + The minimum terminology service required by the Java kernel + + + + openehr + openehr-rm-core + ${project.version} + + + jdom + jdom + 1.0 + + + log4j + log4j + 1.2.8 + + + junit + junit + 3.8.1 + test + + + diff --git a/mini-termserv/src/main/java/org/openehr/terminology/CodeSet.java b/mini-termserv/src/main/java/org/openehr/terminology/CodeSet.java new file mode 100644 index 00000000..51db0222 --- /dev/null +++ b/mini-termserv/src/main/java/org/openehr/terminology/CodeSet.java @@ -0,0 +1,63 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CodeSet" + * keywords: "terminology" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Rong Chen" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.terminology; + +import java.util.ArrayList; +import java.util.List; + +class CodeSet { + CodeSet() { + codes = new ArrayList(); + } + + void addCode(String code) { + if( ! codes.contains(code)) { + codes.add(code); + } + } + + String issuer; + String openehrId; + String externalId; + List codes; +} +/* + * ***** 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 CodeSet.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2007 + * 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/mini-termserv/src/main/java/org/openehr/terminology/Concept.java b/mini-termserv/src/main/java/org/openehr/terminology/Concept.java new file mode 100644 index 00000000..f8e0cd69 --- /dev/null +++ b/mini-termserv/src/main/java/org/openehr/terminology/Concept.java @@ -0,0 +1,49 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Concept" + * keywords: "terminology" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Rong Chen" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.terminology; + +class Concept { + String id; + String rubric; + String 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 Concept.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2007 + * 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/mini-termserv/src/main/java/org/openehr/terminology/Group.java b/mini-termserv/src/main/java/org/openehr/terminology/Group.java new file mode 100644 index 00000000..4d953e2f --- /dev/null +++ b/mini-termserv/src/main/java/org/openehr/terminology/Group.java @@ -0,0 +1,60 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Group" + * keywords: "terminology" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Rong Chen" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.terminology; + +import java.util.*; + +public class Group { + Group() { + concepts = new ArrayList(); + } + + void addConcept(Concept concept) { + if( ! concepts.contains(concept)) { + concepts.add(concept); + } + } + + String name; // name in English, used also as grup id + List concepts; +} +/* + * ***** 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 Group.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2007 + * 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/mini-termserv/src/main/java/org/openehr/terminology/SimpleCodeSetAccess.java b/mini-termserv/src/main/java/org/openehr/terminology/SimpleCodeSetAccess.java new file mode 100644 index 00000000..4d866fcb --- /dev/null +++ b/mini-termserv/src/main/java/org/openehr/terminology/SimpleCodeSetAccess.java @@ -0,0 +1,117 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class SimpleCodeSetAccess" + * keywords: "terminology" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Rong Chen" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.terminology; + +import java.util.*; + +import org.apache.commons.lang.StringUtils; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.terminology.CodeSetAccess; + +/** + * A simple in-memory implementation of CodeSetAccess + * + * @author Rong Chen + */ +public class SimpleCodeSetAccess implements CodeSetAccess { + + /** + * External identifier of this code set + */ + public String id() { + return id; + } + + /** + * Gets all codes known to this code set + * + * @return unmodifiable view of all codes + */ + public Set allCodes() { + return allCodes; + } + + /** + * Returns true if has this code + * + * @throws IllegalArgumentException if code null + */ + public boolean hasCode(CodePhrase code) { + if(code == null) { + throw new IllegalArgumentException("code null"); + } + return allCodes.contains(code); + } + + // TODO: seems to be impossible to implement + // code sets are language _independent_ by definition + public boolean hasLang(CodePhrase lang) { + return false; + } + + /** + * Creates a simple code set + * + * @param id not null or empty + * @param codes not null or empty + * @throws IllegalArgumentException if id or codes empty + */ + SimpleCodeSetAccess(String id, Set codes) { + if(StringUtils.isEmpty(id)) { + throw new IllegalArgumentException("null or empty id"); + } + if(codes == null || codes.isEmpty()) { + throw new IllegalArgumentException("null or empty codes"); + } + this.id = id; + this.allCodes = new HashSet(); + for(String code : codes) { + CodePhrase cp = new CodePhrase(id, code); + this.allCodes.add(cp); + } + } + + /* fields */ + private final String id; + private final Set allCodes; +} +/* + * ***** 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 SimpleCodeSetAccess.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2007 + * 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/mini-termserv/src/main/java/org/openehr/terminology/SimpleTerminologyAccess.java b/mini-termserv/src/main/java/org/openehr/terminology/SimpleTerminologyAccess.java new file mode 100644 index 00000000..ffd6b06a --- /dev/null +++ b/mini-termserv/src/main/java/org/openehr/terminology/SimpleTerminologyAccess.java @@ -0,0 +1,182 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class SimpleTerminologyAccess" + * keywords: "terminology" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Rong Chen" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.terminology; + +import java.util.*; + +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.terminology.TerminologyAccess; + +/** + * Simple in-memory implementation of a terminology access + * + * @author Rong Chen + */ +public class SimpleTerminologyAccess implements TerminologyAccess { + + /** + * Creates an simple terminology access + * + * @param id + */ + SimpleTerminologyAccess(String id) { + this.id = id; + this.groups = new HashMap>(); + this.groupLangNameToId = new HashMap>(); + this.codeRubrics = new HashMap>(); + } + + static SimpleTerminologyAccess getInstance(String id) { + return new SimpleTerminologyAccess(id); + } + + /** + * Adds a group of codes with language dependent names + * + * @param groupId not null + * @param codes not null + * @param names not null + */ + void addGroup(String groupId, Collection codes, + Map names) { + + Set group = new HashSet(); + for(String c : codes) { + CodePhrase code = new CodePhrase(id, c); + group.add(code); + } + groups.put(groupId, group); + for(String lang : names.keySet()) { + Map nameToId = groupLangNameToId.get(lang); + if(nameToId == null) { + nameToId = new HashMap(); + } + String name = names.get(lang); + + nameToId.put(name, groupId); + groupLangNameToId.put(lang, nameToId); + } + } + + /** + * Adds a rubric for given language and code + * + * @param lang + * @param code + * @param rubric + */ + void addRubric(String lang, String code, String rubric) { + Map map = codeRubrics.get(lang); + if(map == null) { + map = new HashMap(); + codeRubrics.put(lang, map); + } + map.put(code, rubric); + } + + /** + * @returns "openehr" + */ + public String id() { + return id; + } + + public Set allCodes() { + Set allCodes = new HashSet(); + for(Set codes : groups.values()) { + allCodes.addAll(codes); + } + return allCodes; + } + + public Set codesForGroupId(String groupID) { + return groups.get(groupID); + } + + public Set codesForGroupName(String name, String language) { + Map map = groupLangNameToId.get(language); + if(map == null) { + return null; + } + String groupId = map.get(name); + return groups.get(groupId); + } + + public String rubricForCode(String code, String language) { + Map map = codeRubrics.get(language); + if(map == null) { + return null; + } + return map.get(code); + } + + public boolean hasCodeForGroupId(String groupId, CodePhrase code) { + Set group = groups.get(groupId); + if(group == null) { + return false; + } + return group.contains(code); + } + + /* + * Id of this terminology + */ + private final String id; + + /* + * Groups indexed by group id + * + */ + private final Map> groups; + + /** + * GroupIds indexed by language and group name + * > + */ + private final Map> groupLangNameToId; + + /** + * Code rubrics indexed by lang, code + */ + private final Map> codeRubrics; + } +/* + * ***** 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 SimpleTerminologyAccess.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2007 + * 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/mini-termserv/src/main/java/org/openehr/terminology/SimpleTerminologyService.java b/mini-termserv/src/main/java/org/openehr/terminology/SimpleTerminologyService.java new file mode 100644 index 00000000..0081c3c7 --- /dev/null +++ b/mini-termserv/src/main/java/org/openehr/terminology/SimpleTerminologyService.java @@ -0,0 +1,183 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class SimpleTerminologyService" + * keywords: "terminology" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Rong Chen" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.terminology; + +import java.util.*; +import org.apache.log4j.Logger; +import org.openehr.rm.support.terminology.*; + +/** + * A simple implementation of terminology service that provides + * complete openEHR terminology and necessary code sets for the + * kernel to work properly + * + * TODO: load complete external codesets + * + * @author rong.chen + */ +public class SimpleTerminologyService implements TerminologyService { + + /** + * Gets an instance of terminology service + * + * @return terminology service + * @throws Exception + */ + public static TerminologyService getInstance() throws Exception { + return soleInstance; + } + + public TerminologyAccess terminology(String name) { + return terminologies.get(name); + } + + public CodeSetAccess codeSet(String name) { + return codeSets.get(name); + } + + public CodeSetAccess codeSetForId(OpenEHRCodeSetIdentifiers id) { + String name = codeSetInternalIdToExternalName.get(id.toString()); + if(name == null) { + return null; + } + return codeSets.get(name); + } + + public boolean hasTerminology(String name) { + return terminologies.containsKey(name); + } + + public boolean hasCodeSet(String name) { + return codeSetInternalIdToExternalName.containsKey(name); + } + + public List terminologyIdentifiers() { + return new ArrayList(terminologies.keySet()); + } + + public List codeSetIdentifiers() { + return new ArrayList(codeSets.keySet()); + } + + public Map openehrCodeSets() { + return Collections.unmodifiableMap(codeSetInternalIdToExternalName); + } + + /* + * Creates a simpleTerminologyService + */ + private SimpleTerminologyService() { + + terminologies = new HashMap(); + codeSets = new HashMap(); + codeSetInternalIdToExternalName = new HashMap(); + + try { + TerminologySource terminologySource = + TerminologySourceFactory.getOpenEHRTerminology(); + + loadTerminologies(terminologySource); + loadCodeSets(terminologySource); + + terminologySource = + TerminologySourceFactory.getExternalTerminologies(); + + loadTerminologies(terminologySource); + loadCodeSets(terminologySource); + + } catch(Exception e) { + log.error("failed to initialize terminology service..", e); + throw new RuntimeException(e); + } + } + + private void loadTerminologies(TerminologySource source) { + + SimpleTerminologyAccess terminology = (SimpleTerminologyAccess) + terminologies.get(TerminologyService.OPENEHR); + if(terminology == null) { + terminology = new SimpleTerminologyAccess(TerminologyService.OPENEHR); + } + + List groups = source.getConceptGroups(); + for(Group group : groups) { + Set codes = new HashSet(); + Map names = new HashMap(); + names.put("en", group.name); + for(Concept concept : group.concepts) { + codes.add(concept.id); + terminology.addRubric("en", concept.id, concept.rubric); + } + // English name as group id + terminology.addGroup(group.name, codes, names); + } + terminologies.put(TerminologyService.OPENEHR, terminology); + } + + private void loadCodeSets(TerminologySource source) { + + for(CodeSet codeset : source.getCodeSets()) { + SimpleCodeSetAccess codeSetAccess = new SimpleCodeSetAccess( + codeset.externalId, new HashSet(codeset.codes)); + codeSets.put(codeset.externalId, codeSetAccess); + codeSetInternalIdToExternalName.put(codeset.openehrId, + codeset.externalId); + } + } + + /* static final field */ + private static final Logger log = + Logger.getLogger(SimpleTerminologyService.class); + + /* code sets indexed by external codeset name */ + private Map codeSets; + + /* terminology indexed by name */ + private Map terminologies; + + /* mapping between external name and openEHR codeset id */ + private Map codeSetInternalIdToExternalName; + + /* static instance */ + private static TerminologyService soleInstance = new SimpleTerminologyService(); +} +/* + * ***** 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 SimpleTerminologyService.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2007 + * 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/mini-termserv/src/main/java/org/openehr/terminology/TerminologySource.java b/mini-termserv/src/main/java/org/openehr/terminology/TerminologySource.java new file mode 100644 index 00000000..a4c7f1b5 --- /dev/null +++ b/mini-termserv/src/main/java/org/openehr/terminology/TerminologySource.java @@ -0,0 +1,58 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TerminologySource" + * keywords: "terminology" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Rong Chen" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.terminology; + +import java.util.List; + +/** + * Interface for access a terminology content + * + * @author rong.chen + * + */ +public interface TerminologySource { + + public List getConceptGroups(); + + public List getCodeSets(); +} +/* + * ***** 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 TerminologySource.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2007 + * 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/mini-termserv/src/main/java/org/openehr/terminology/TerminologySourceFactory.java b/mini-termserv/src/main/java/org/openehr/terminology/TerminologySourceFactory.java new file mode 100644 index 00000000..53d4deae --- /dev/null +++ b/mini-termserv/src/main/java/org/openehr/terminology/TerminologySourceFactory.java @@ -0,0 +1,72 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TerminologySourceFactory" + * keywords: "terminology" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Rong Chen" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.terminology; + +/** + * Factory for concrete terminology source implementation + * + * @author rong.chen + */ +public class TerminologySourceFactory { + + private static final String OPENEHR_TERMINOLOGY = "/openehr_terminology_en.xml"; + private static final String EXTERNAL_TERMINOLOGIES = "/external_terminologies_en.xml"; + + /** + * Gets an instance of openEHR terminology source + * + * @return terminology source instance + */ + public static TerminologySource getOpenEHRTerminology() throws Exception { + return XMLTerminologySource.getInstance(OPENEHR_TERMINOLOGY); + } + + /** + * Gets an instance of external terminologies source + * + * @return terminology source instance + */ + public static TerminologySource getExternalTerminologies() throws Exception { + return XMLTerminologySource.getInstance(EXTERNAL_TERMINOLOGIES); + } +} +/* + * ***** 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 TerminologySourceFactory.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2007 + * 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/mini-termserv/src/main/java/org/openehr/terminology/XMLTerminologySource.java b/mini-termserv/src/main/java/org/openehr/terminology/XMLTerminologySource.java new file mode 100644 index 00000000..4903dafa --- /dev/null +++ b/mini-termserv/src/main/java/org/openehr/terminology/XMLTerminologySource.java @@ -0,0 +1,147 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class XMLTerminologySource" + * keywords: "terminology" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Rong Chen" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.terminology; + +import java.io.*; +import java.util.*; + +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.input.SAXBuilder; + +/** + * This class provides access to terminology content in XML format + * + * @author rong.chen + */ +public class XMLTerminologySource implements TerminologySource { + + /** + * Gets an terminology source loaded with specified xml content + */ + public static XMLTerminologySource getInstance(String xmlfilename) + throws Exception { + return new XMLTerminologySource(xmlfilename); + } + + public List getCodeSets() { + return codeSetList; + } + + public List getConceptGroups() { + return groupList; + } + + /* + * Constructs an instance loaded with terminology content + */ + private XMLTerminologySource(String filename) throws Exception { + codeSetList = new ArrayList(); + groupList = new ArrayList(); + loadTerminologyFromXML(filename); + } + + private void loadTerminologyFromXML(String filename) throws Exception { + SAXBuilder builder = new SAXBuilder(); + InputStream input = this.getClass().getResourceAsStream(filename); + try { + Document doc = builder.build(input); + Element root = doc.getRootElement(); + List codesets = root.getChildren("codeset"); + codeSetList.clear(); + groupList.clear(); + + for(Iterator it = codesets.iterator(); it.hasNext();) { + Element element = (Element) it.next(); + codeSetList.add(loadCodeSet(element)); + } + + List groups = root.getChildren("group"); + for(Iterator it = groups.iterator(); it.hasNext();) { + Element element = (Element) it.next(); + groupList.add(loadGroup(element)); + } + } finally { + if(input != null) { + input.close(); + } + } + } + + /* + * Loads a code set from XML element + */ + private CodeSet loadCodeSet(Element element) { + CodeSet codeset = new CodeSet(); + codeset.openehrId = element.getAttributeValue("openehr_id"); + codeset.issuer = element.getAttributeValue("issuer"); + codeset.externalId = element.getAttributeValue("external_id"); + List children = element.getChildren("code"); + for(Iterator it = children.iterator(); it.hasNext();) { + Element code = (Element) it.next(); + codeset.addCode(code.getAttributeValue("value")); + } + return codeset; + } + + /* + * Loads a concept group from XML element + */ + private Group loadGroup(Element element) { + Group group = new Group(); + group.name = element.getAttributeValue("name"); + + List children = element.getChildren("concept"); + for(Iterator it = children.iterator(); it.hasNext();) { + Concept concept = new Concept(); + Element e = (Element) it.next(); + concept.id = (e.getAttributeValue("id")); + concept.rubric = (e.getAttributeValue("rubric")); + group.addConcept(concept); + } + return group; + } + + private List groupList; + private List codeSetList; +} +/* + * ***** 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 XMLTerminologySource.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2007 + * 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/mini-termserv/src/main/resources/external_terminologies_en.xml b/mini-termserv/src/main/resources/external_terminologies_en.xml new file mode 100644 index 00000000..12bf14f4 --- /dev/null +++ b/mini-termserv/src/main/resources/external_terminologies_en.xml @@ -0,0 +1,409 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mini-termserv/src/main/resources/log4j.properties b/mini-termserv/src/main/resources/log4j.properties new file mode 100644 index 00000000..c2a7d4b6 --- /dev/null +++ b/mini-termserv/src/main/resources/log4j.properties @@ -0,0 +1,9 @@ +# Set root logger level to DEBUG and its only appender to stdout. +log4j.rootLogger=INFO, 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 + +# logging level +log4j.logger.org.openehr.terminology=DEBUG \ No newline at end of file diff --git a/mini-termserv/src/main/resources/openehr_terminology_en.xml b/mini-termserv/src/main/resources/openehr_terminology_en.xml new file mode 100644 index 00000000..e2ac826b --- /dev/null +++ b/mini-termserv/src/main/resources/openehr_terminology_en.xml @@ -0,0 +1,320 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mini-termserv/src/test/java/org/openehr/terminology/OpenEHRTerminologyTest.java b/mini-termserv/src/test/java/org/openehr/terminology/OpenEHRTerminologyTest.java new file mode 100644 index 00000000..95515de6 --- /dev/null +++ b/mini-termserv/src/test/java/org/openehr/terminology/OpenEHRTerminologyTest.java @@ -0,0 +1,85 @@ +package org.openehr.terminology; + +import java.util.Set; + +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.terminology.*; + +import junit.framework.TestCase; + +public class OpenEHRTerminologyTest extends TestCase { + + public OpenEHRTerminologyTest() throws Exception { + service = SimpleTerminologyService.getInstance(); + } + + public void setUp() throws Exception { + + } + + public void testHasOpenEHRSettingCode() { + + TerminologyAccess terminology = service.terminology( + TerminologyService.OPENEHR); + + assertNotNull("openEHR terminology missing", terminology); + + Set codes = terminology.codesForGroupName("setting", "en"); + + assertNotNull("setting(en) missing", codes); + + CodePhrase home = new CodePhrase("openehr", "225"); + + assertTrue("code 225 (home) doesn't exist..", codes.contains(home)); + } + + public void testRubricForCode() throws Exception { + TerminologyAccess terminology = service.terminology( + TerminologyService.OPENEHR); + + assertEquals("event", terminology.rubricForCode("433", "en")); + assertEquals("initial", terminology.rubricForCode("524", "en")); + } + + public void testHasCountryCodes() throws Exception { + CodeSetAccess codeSet = service.codeSetForId( + OpenEHRCodeSetIdentifiers.COUNTRIES); + + assertNotNull("countries codeSet missing", codeSet); + + assertTrue("China missing", + codeSet.hasCode(new CodePhrase("ISO_3166-1", "CN"))); + assertTrue("Sweden missing", + codeSet.hasCode(new CodePhrase("ISO_3166-1", "SE"))); + assertTrue("United Kingdom missing", + codeSet.hasCode(new CodePhrase("ISO_3166-1", "GB"))); + assertTrue("Denmark missing", + codeSet.hasCode(new CodePhrase("ISO_3166-1", "DK"))); + assertTrue("France missing", + codeSet.hasCode(new CodePhrase("ISO_3166-1", "FR"))); + } + + public void testHasOpenEHRCode() throws Exception { + TerminologyAccess terminology = service.terminology( + TerminologyService.OPENEHR); + assertTrue("code for signed missing", terminology.allCodes().contains( + new CodePhrase(TerminologyService.OPENEHR, "240"))); + } + + // TODO some test isolation issue here.. + public void _testHasPlainTextMediaType() throws Exception { + CodeSetAccess codeSet = service.codeSetForId( + OpenEHRCodeSetIdentifiers.MEDIA_TYPES); + CodePhrase mediaType = new CodePhrase("IANA_media-types", "text/plain"); + assertTrue("media type: text/plain is missing", codeSet.hasCode(mediaType)); + } + + public void __testHasCompressionAlgorithmsOther() throws Exception { + CodeSetAccess codeSet = service.codeSetForId( + OpenEHRCodeSetIdentifiers.COMPRESSION_ALGORITHMS); + CodePhrase mediaType = new CodePhrase("openehr_compression_algorithms", "others"); + assertTrue("openehr_compression_algorithms is missing", codeSet.hasCode(mediaType)); + } + + TerminologyService service; +} diff --git a/mini-termserv/src/test/java/org/openehr/terminology/SimpleCodeSetAccessTest.java b/mini-termserv/src/test/java/org/openehr/terminology/SimpleCodeSetAccessTest.java new file mode 100644 index 00000000..f049f27a --- /dev/null +++ b/mini-termserv/src/test/java/org/openehr/terminology/SimpleCodeSetAccessTest.java @@ -0,0 +1,57 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class SimpleCodeSetAccessTest" + * keywords: "terminology" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Rong Chen" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.terminology; + +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.terminology.CodeSetAccess; + +import java.util.*; +import junit.framework.TestCase; + +public class SimpleCodeSetAccessTest extends TestCase { + + public void setUp() { + String id = CODESET_ID; + Set codes = new HashSet(Arrays.asList(CODES)); + instance = new SimpleCodeSetAccess(id, codes); + } + + public void testGetId() { + assertEquals("id wrong", CODESET_ID, instance.id()); + } + + public void testGetAllCodes() { + Set allCodes = new HashSet(); + for(String c : CODES) { + allCodes.add(new CodePhrase(CODESET_ID, c)); + } + assertEquals("allCodes wrong", allCodes, instance.allCodes()); + } + + public void testHasCode() { + for(String c : CODES) { + CodePhrase code = new CodePhrase(CODESET_ID, c); + assertTrue("code " + c + " should exist", instance.hasCode(code)); + } + } + + /* fixtures */ + private final static String CODESET_ID = "test_id"; + private final static String[] CODES = { + "code1", "code2", "code3", "code4" + }; + + /* test instance */ + private CodeSetAccess instance; +} diff --git a/mini-termserv/src/test/java/org/openehr/terminology/SimpleTerminologyAccessTest.java b/mini-termserv/src/test/java/org/openehr/terminology/SimpleTerminologyAccessTest.java new file mode 100644 index 00000000..bf7c9e43 --- /dev/null +++ b/mini-termserv/src/test/java/org/openehr/terminology/SimpleTerminologyAccessTest.java @@ -0,0 +1,154 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class SimpleTerminologyAccessTest" + * keywords: "terminology" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Rong Chen" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.terminology; + +import java.util.*; + +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.terminology.TerminologyAccess; + +import junit.framework.TestCase; + +public class SimpleTerminologyAccessTest extends TestCase { + + public void setUp() { + instance = new SimpleTerminologyAccess(TEST_ID); + + Map names = new HashMap(); + names.put(LANG1, LANG1_GROUP1_NAME); + names.put(LANG2, LANG2_GROUP1_NAME); + ((SimpleTerminologyAccess) instance).addGroup(GROUP1_ID, + Arrays.asList(GROUP1_CODES), names); + + names.clear(); + names.put(LANG1, LANG1_GROUP2_NAME); + names.put(LANG2, LANG2_GROUP2_NAME); + ((SimpleTerminologyAccess) instance).addGroup(GROUP2_ID, + Arrays.asList(GROUP2_CODES), names); + + for(int i = 0; i < GROUP1_RUBRICS_EN.length; i++) { + ((SimpleTerminologyAccess) instance).addRubric( + LANG1, GROUP1_CODES[i], GROUP1_RUBRICS_EN[i]); + } + } + + public void tearDown() { + instance = null; + } + + public void testGetId() { + assertEquals("id wrong", TEST_ID, instance.id()); + } + + public void testGetAllCodes() { + Set codes = new HashSet(); + for(String c : GROUP1_CODES) { + codes.add(new CodePhrase(TEST_ID, c)); + } + for(String c : GROUP2_CODES) { + codes.add(new CodePhrase(TEST_ID, c)); + } + assertEquals("allCodes wrong", codes, instance.allCodes()); + } + + public void testGetCodesForGroupIdWithAllValidIds() { + Set codes = new HashSet(); + for(String c : GROUP1_CODES) { + codes.add(new CodePhrase(TEST_ID, c)); + } + assertEquals("group1 codes wrong", codes, + instance.codesForGroupId(GROUP1_ID)); + + codes.clear(); + for(String c : GROUP2_CODES) { + codes.add(new CodePhrase(TEST_ID, c)); + } + assertEquals("group2 codes wrong", codes, + instance.codesForGroupId(GROUP2_ID)); + } + + public void testGetCodesForGroup1NameWithTwoLanguages() { + Set codes = new HashSet(); + for(String c : GROUP1_CODES) { + codes.add(new CodePhrase(TEST_ID, c)); + } + assertEquals("group1 codes wrong", codes, + instance.codesForGroupName(LANG1_GROUP1_NAME, LANG1)); + assertEquals("group1 codes wrong", codes, + instance.codesForGroupName(LANG2_GROUP1_NAME, LANG2)); + } + + public void testGetCodesForGroup2NameWithTwoLanguages() { + Set codes = new HashSet(); + for(String c : GROUP2_CODES) { + codes.add(new CodePhrase(TEST_ID, c)); + } + assertEquals("group2 codes wrong", codes, + instance.codesForGroupName(LANG1_GROUP2_NAME, LANG1)); + assertEquals("group2 codes wrong", codes, + instance.codesForGroupName(LANG2_GROUP2_NAME, LANG2)); + } + + public void testGetRubricForCodeWithExistingLangCode() { + String code = "code1"; + String rubric = instance.rubricForCode(code, "en"); + String expected = "rubric1_en"; + assertEquals("rubric wrong for code " + code, expected, rubric); + } + + public void testGetRubricForCodeWithNoneExistingLang() { + String code = "code1"; + String rubric = instance.rubricForCode(code, "zh"); + String expected = null; + assertEquals("rubric wrong for code " + code, expected, rubric); + } + + public void testGetRubricForCodeWithNoneExistingCode() { + String code = "code6"; + String rubric = instance.rubricForCode(code, "en"); + String expected = null; + assertEquals("rubric wrong for code " + code, expected, rubric); + } + + public void testhasCodeForGroupId() { + for(String code : GROUP1_CODES) { + CodePhrase codePhrase = new CodePhrase(TEST_ID, code); + assertTrue("code: " + code + " missing from " + GROUP1_ID, + instance.hasCodeForGroupId(GROUP1_ID, codePhrase)); + } + } + + /* test fixture */ + private static final String TEST_ID = "test_id"; + private static final String LANG1 = "en"; + private static final String LANG2 = "fr"; + private static final String[] GROUP1_CODES = { + "code1", "code2", "code3" + }; + private static final String[] GROUP1_RUBRICS_EN = { + "rubric1_en", "rubric2_en", "rubric3_en" + }; + private static final String[] GROUP2_CODES = { + "code4", "code5" + }; + private static final String LANG1_GROUP1_NAME = "group1_en"; + private static final String LANG2_GROUP1_NAME = "group1_fr"; + private static final String LANG1_GROUP2_NAME = "group2_en"; + private static final String LANG2_GROUP2_NAME = "group2_fr"; + private static final String GROUP1_ID = "group 1"; + private static final String GROUP2_ID = "group 2"; + + + private TerminologyAccess instance; +} diff --git a/mini-termserv/src/test/java/org/openehr/terminology/SimpleTerminologyServiceTest.java b/mini-termserv/src/test/java/org/openehr/terminology/SimpleTerminologyServiceTest.java new file mode 100644 index 00000000..ec5fc1a4 --- /dev/null +++ b/mini-termserv/src/test/java/org/openehr/terminology/SimpleTerminologyServiceTest.java @@ -0,0 +1,102 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class SimpleTerminologyServiceTest" + * keywords: "terminology" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Rong Chen" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.terminology; + +import java.util.List; +import java.util.Map; + +import org.openehr.rm.support.terminology.CodeSetAccess; +import org.openehr.rm.support.terminology.OpenEHRCodeSetIdentifiers; +import org.openehr.rm.support.terminology.TerminologyAccess; +import org.openehr.rm.support.terminology.TerminologyService; + +import junit.framework.TestCase; + +/** + * Test case for SimpleTerminologyService + * + * @author rong.chen + */ +public class SimpleTerminologyServiceTest extends TestCase { + + public void setUp() throws Exception { + instance = SimpleTerminologyService.getInstance(); + } + + public void tearDown() throws Exception { + instance = null; + } + + public void testGetTerminology() { + TerminologyAccess terminology = + instance.terminology(TerminologyService.OPENEHR); + assertNotNull("failed to get openehr terminology", terminology); + } + + public void testGetCodeSetWithAllValidIds() { + for(OpenEHRCodeSetIdentifiers id : OpenEHRCodeSetIdentifiers.values()) { + CodeSetAccess codeSet = instance.codeSetForId(id); + assertNotNull("code set " + id + " should exist", codeSet); + } + } + + public void testHasTerminologyWithOpenEHR() { + String name = TerminologyService.OPENEHR; + assertTrue("terminology " + name + " should exist", + instance.hasTerminology(name)); + } + + public void testHasCodeSet(String name) { + for(OpenEHRCodeSetIdentifiers id : OpenEHRCodeSetIdentifiers.values()) { + assertNotNull("code set " + id + " should exist", + instance.hasCodeSet(id.toString())); + } + } + + public void testGetTerminologyIdentifiers() { + List ids = instance.terminologyIdentifiers(); + assertNotNull("terminology ids should not be null", ids); + assertTrue("terminology ids should not be empty", ids.size() > 0); + } + + public void testGetCodeSetIdentifiers() { + List ids = instance.codeSetIdentifiers(); + assertNotNull("code set ids should not be null", ids); + assertTrue("code set ids should not be empty", ids.size() > 0); + } + + public void testGetOpenehrCodeSets() { + Map codeSets = instance.openehrCodeSets(); + assertNotNull("code set ids should not be null", codeSets); + assertTrue("code set ids should not be empty", codeSets.size() > 0); + } + + public void testGetCountryCodeSetByExternalName() { + String[] externalNames = { + "ISO_3166-1", "IANA_character-sets", + "openehr_compression_algorithms", + "openehr_integrity_check_algorithms", + "ISO_639-1", "IANA_media-types", + "openehr_normal_statuses" + }; + for(String name : externalNames) { + CodeSetAccess codeSet = instance.codeSet(name); + assertNotNull("Code set of external name: " + name + " missing", + codeSet); + } + } + + /* test instance */ + private TerminologyService instance; +} diff --git a/mini-termserv/src/test/java/org/openehr/terminology/TranslationDetailsTest.java b/mini-termserv/src/test/java/org/openehr/terminology/TranslationDetailsTest.java new file mode 100644 index 00000000..c1fa6f4f --- /dev/null +++ b/mini-termserv/src/test/java/org/openehr/terminology/TranslationDetailsTest.java @@ -0,0 +1,25 @@ +package org.openehr.terminology; + +import java.util.*; + +import org.openehr.rm.common.resource.TranslationDetails; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.terminology.TerminologyService; + +import junit.framework.TestCase; + +public class TranslationDetailsTest extends TestCase { + + public void testCreateTranslationDetails() throws Exception { + CodePhrase language = new CodePhrase("ISO_639-1", "en"); + Map author = new HashMap(); + author.put("rong", "openehr"); + String accreditation = null; + Map otherDetails = null; + TerminologyService terminologyService = + SimpleTerminologyService.getInstance(); + TranslationDetails td = new TranslationDetails(language, + author, accreditation, otherDetails, terminologyService); + } + +} diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml new file mode 100644 index 00000000..55f0f184 --- /dev/null +++ b/oet-parser/pom.xml @@ -0,0 +1,119 @@ + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5-SNAPSHOT + + oet-parser + jar + openEHR OET Template Parser and Flattener + + + rong.chen + Rong Chen + rong.acode@gmail.com + + + + + openEHR + http://www.openehr.org/ + + 2007 + Java implementation of openEHR OET Template Parser and Flattener + + UTF-8 + + + + + 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} + + + openehr + openehr-aom + ${project.version} + + + openehr + adl-parser + ${project.version} + + + org.apache.xmlbeans + xmlbeans + 2.3.0 + + + javax.xml.bind + jsr173_api + 1.0 + + + openehr + measure-serv + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + junit + junit + 3.8.1 + test + + + com.thoughtworks.xstream + xstream + 1.3.1 + test + + + openehr + adl-serializer + ${project.version} + + + log4j + log4j + 1.2.13 + + + commons-io + commons-io + 1.4 + + + 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 new file mode 100644 index 00000000..ec5740b8 --- /dev/null +++ b/oet-parser/src/main/java/org/openehr/am/template/Flattener.java @@ -0,0 +1,1732 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Class Flattener" + * keywords: "oet-parser" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2009,2010 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ + +package org.openehr.am.template; + +import java.math.BigInteger; +import java.text.DecimalFormat; +import java.util.*; + +import org.apache.log4j.Logger; + +import openEHR.v1.template.ACTION; +import openEHR.v1.template.ADMINENTRY; +import openEHR.v1.template.Archetyped; +import openEHR.v1.template.COMPOSITION; +import openEHR.v1.template.ContentItem; +import openEHR.v1.template.ENTRY; +import openEHR.v1.template.EVALUATION; +import openEHR.v1.template.INSTRUCTION; +import openEHR.v1.template.ITEMSTRUCTURE; +import openEHR.v1.template.OBSERVATION; +import openEHR.v1.template.QuantityConstraint; +import openEHR.v1.template.QuantityUnitConstraint; +import openEHR.v1.template.SECTION; +import openEHR.v1.template.TEMPLATE; +import openEHR.v1.template.Statement; +import openEHR.v1.template.TextConstraint; +import openEHR.v1.template.ValueConstraint; +import openEHR.v1.template.MultipleConstraint; +import openEHR.v1.template.ITEM; + +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.constraintmodel.*; +import org.openehr.am.archetype.constraintmodel.CAttribute.Existence; +import org.openehr.am.archetype.constraintmodel.primitive.CString; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantity; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantityItem; +import org.openehr.am.openehrprofile.datatypes.text.CCodePhrase; +import org.openehr.rm.common.archetyped.Locatable; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.basic.Interval; + +/** + * A template flattener which can take OET object model generated by + * OET-template parser and join constraints from the parent archetype and + * all included children archetypes, and output the combined constraints + * in pure AOM instance. + * + * @author rong.chen + * + */ +public class Flattener { + + /** + * Constructor + */ + public Flattener() { + archetypeMap = new HashMap(); + termMap = new TermMap(); + } + + /** + * Flatten given template only with archetypes + * + * @param template + * @param archetypeMap + * @return + * @throws Exception + */ + public Archetype toFlattenedArchetype(TEMPLATE template, + Map archetypeMap) throws FlatteningException { + + return toFlattenedArchetype(template, archetypeMap, + new HashMap()); + } + + /** + * Flatten given template with referenced archetypes and sub-templates + * + * @param template + * @param archetypeMap not null + * @param templateMap null if unspecified + * @return + * @throws FlatteningException if null archetypeMap + */ + public Archetype toFlattenedArchetype(TEMPLATE template, + Map archetypeMap, + Map templateMap) throws FlatteningException { + + if(archetypeMap == null) { + throw new FlatteningException("null archetypeMap"); + } + + // make a internal copy of archetypeMap + this.archetypeMap.clear(); + for(String id : archetypeMap.keySet()) { + Archetype a = archetypeMap.get(id); + if(a != null) { + a = a.copy(); + this.archetypeMap.put(id, a); + } + } + // no need to copy templateMap + this.templateMap = templateMap; + + log.debug("Loaded archetype/template maps, total archetypes: " + + archetypeMap.size() + ", total templates: " + + (templateMap == null ? 0 : templateMap.size())); + + return toFlattenedArchetype(template); + } + + /* + * Only used when archetype/template maps are initialized! + */ + private Archetype toFlattenedArchetype(TEMPLATE template) + throws FlatteningException { + + log.debug("Flattening template.. STARTED"); + + Archetyped definition = template.getDefinition(); + + // start flattening + Archetype flattended = flattenArchetyped(definition); + flattended.reloadNodeMaps(); + + log.debug("Flattening template DONE"); + + return flattended; + } + + /** + * Flattening entry point for root class archetyped + * + * @param parentArchetype provides the context of flattening, null for first + * entry of the recursive function + * @param definition + * @throws FlatteningException + */ + private Archetype flattenArchetyped(Archetyped definition) throws FlatteningException { + + log.debug("flattening archetyped on archetype: " + definition.getArchetypeId()); + + // TODO handle template_id + + + if(definition instanceof COMPOSITION) { + + // only exception when parentArchetype is always not set + return flattenComposition((COMPOSITION) definition); + + } else if(definition instanceof ITEMSTRUCTURE) { + + return flattenItemStructure(null, (ITEMSTRUCTURE) definition); + + } else if(definition instanceof ContentItem) { + + return flattenContentItem(null, (ContentItem) definition); + + } else if(definition instanceof ITEM) { + + return flattenItem(null, (ITEM) definition); + + } else { + throw new FlatteningException("Unkown archetyped sub-type"); + } + } + + /* + * Flatten an item + */ + private Archetype flattenItem(Archetype parentArchetype, ITEM item) + throws FlatteningException { + + log.debug("flattening item on parentArchetype " + + parentArchetype.getArchetypeId() + " at path " + + item.getPath()); + + Archetype archetype = retrieveArchetype(item.getArchetypeId()); + + applyTemplateConstraints(archetype, item); + + fillArchetypeSlot(parentArchetype, archetype, item.getPath(), + item.getName()); + + return archetype; + } + + private Archetype flattenComposition(COMPOSITION composition) throws FlatteningException { + + log.debug("flattening composition on archetype: " + composition.getArchetypeId()); + + Archetype archetype = retrieveArchetype(composition.getArchetypeId()); + CComplexObject root = archetype.getDefinition(); + CAttribute contentAttribute = root.getAttribute(CONTENT); + + removeArchetypeSlots(contentAttribute); + + // handle "/content" attribute + ContentItem[] items = composition.getContentArray(); + if(items != null && items.length > 0) { + String path = "/" + CONTENT; + + if(contentAttribute == null) { + List alternatives = new ArrayList(); + contentAttribute = new CMultipleAttribute(path, CONTENT, + Existence.OPTIONAL, Cardinality.LIST, alternatives); + archetype.getDefinition().addAttribute(contentAttribute); + } + + for(ContentItem item : items) { + + log.debug("flattening composition.content.."); + + flattenContentItem(archetype, item); + } + } + + // TODO handle "/context" attribute + // log.warn("flattening composition.context..not implemented"); + + applyRules(archetype, composition.getRuleArray()); + applyNameConstraint(archetype, archetype.getDefinition(), + composition.getName(), "/"); + + return archetype; + } + + private Archetype flattenContentItem(Archetype parentArchetype, + ContentItem definition) throws FlatteningException { + + log.debug("flattening content_item on archetype: " + + definition.getArchetypeId() + " on path: " + definition.getPath()); + + Archetype archetype = null; + String templateId = definition.getTemplateId(); + + if(templateId == null) { + + archetype = retrieveArchetype(definition.getArchetypeId()); + + } else { + + // TODO only needed at SECTION level so far for ifk2 + TEMPLATE template = retrieveTemplate(templateId); + archetype = toFlattenedArchetype(template); + } + + applyTemplateConstraints(archetype, definition); + + if(definition instanceof ENTRY) { + + flattenEntry(parentArchetype, archetype, (ENTRY) definition); + + } else if(definition instanceof SECTION) { + + flattenSection(parentArchetype, archetype, (SECTION) definition); + + } else { + throw new FlatteningException( + "Unexpected subtype of ContentItem: " + definition); + } + return archetype; + } + + /* + * Apply common template constraints + */ + private void applyTemplateConstraints(Archetype archetype, + Archetyped definition) throws FlatteningException { + + log.debug("applying common template constraints.. "); + + if(archetype == null) { + return; + } + + String name = null; + Statement[] rules = null; + BigInteger max = null; + BigInteger min = null; + boolean hideOnForm = false; + String annotation = null; + + if(definition instanceof ContentItem) { + + ContentItem item = (ContentItem) definition; + name = item.getName(); + rules = item.getRuleArray(); + max = item.getMax(); + min = item.getMin(); + hideOnForm = item.getHideOnForm(); + annotation = item.getAnnotation(); + + } else if(definition instanceof ITEMSTRUCTURE) { + + ITEMSTRUCTURE item = (ITEMSTRUCTURE) definition; + name = item.getName(); + rules = item.getRuleArray(); + max = item.getMax(); + min = item.getMin(); + hideOnForm = item.getHideOnForm(); + annotation = item.getAnnotation(); + + } else if(definition instanceof ITEM) { + + ITEM item = (ITEM) definition; + name = item.getName(); + rules = item.getRuleArray(); + max = item.getMax(); + min = item.getMin(); + hideOnForm = item.getHideOnForm(); + annotation = item.getAnnotation(); + + } else { + log.warn("unsupported definition type: " + definition); + } + + applyNameConstraint(archetype, archetype.getDefinition(), name , "/"); + + applyRules(archetype, rules); + + applyOccurrencesConstraint(archetype, archetype.getDefinition(), max, min); + + applyHideOnFormConstraint(archetype.getDefinition(), hideOnForm); + + applyAnnotationConstraint(archetype.getDefinition(), annotation); + } + + private void setPathPrefixOnCObjectTree(CObject cobj, String prefix) + throws FlatteningException { + + // TODO shouldn't happen + if(cobj == null) { + log.warn("null cobj encountered at setPathPrefix(): " + prefix); + return; + } + + String path = cobj.path(); + if("/".equals(path)) { + path = prefix; + } else { + path = prefix + path; + } + cobj.setPath(path); + + if(path.endsWith(VALUE)) { + // log.debug("setPathPrefixOnCObjectTree - value path: " + path); + } + + if(cobj instanceof CComplexObject) { + CComplexObject ccobj = (CComplexObject) cobj; + for(CAttribute cattr : ccobj.getAttributes()) { + path = cattr.path(); + cattr.setPath(prefix + path); + for(Iterator it = cattr.getChildren().iterator(); + it.hasNext();) { + + CObject child = it.next(); + // TODO + if(child == null) { + it.remove(); + log.warn("null child encountered remove in setPathPrefix().."); + } + setPathPrefixOnCObjectTree(child, prefix); + } + } + } + } + + private void updatePathWithNamedNodeOnCObjectTree(CObject cobj, + String nodeId, String name) throws FlatteningException { + + // TODO shouldn't happen + if (cobj == null) { + log.warn("null cobj in updatePathWithNamedNodeOnCObjectTree(): " + + nodeId + "/" + name); + return; + } + + String path = cobj.path(); + path = replaceNodeIdWithNamedNode(path, nodeId, name); + cobj.setPath(path); + + //log.debug("cobj.path: " + cobj.path()); + + if (cobj instanceof CComplexObject) { + CComplexObject ccobj = (CComplexObject) cobj; + + for (CAttribute cattr : ccobj.getAttributes()) { + + path = cattr.path(); + path = replaceNodeIdWithNamedNode(path, nodeId, name); + cattr.setPath(path); + + //log.debug("cattr.path: " + cattr.path()); + + for (Iterator it = cattr.getChildren().iterator(); it + .hasNext();) { + + CObject child = it.next(); + // TODO + if (child == null) { + it.remove(); + log.warn("null child encountered remove in setPathPrefix().."); + } + updatePathWithNamedNodeOnCObjectTree(child, nodeId, name); + } + } + } + } + + private String replaceNodeIdWithNamedNode(String path, String nodeId, + String name) { + return path.replaceFirst("\\[" + nodeId + "\\]", + "\\[" + namedNodeSegment(nodeId, name) + "\\]"); + } + + private String namedNodeSegment(String nodeId, String name) { + return nodeId + " and name/value='" + name + "'"; + } + + private Archetype flattenSection(Archetype parentArchetype, + Archetype archetype, SECTION section) throws FlatteningException { + + log.debug("flattening section on archetype " + section.getArchetypeId() + + " at path " + section.getPath()); + + ContentItem[] items = section.getItemArray(); + String path = section.getPath(); + CComplexObject root = archetype.getDefinition(); + + fillArchetypeSlot(parentArchetype, archetype, path, section.getName()); + + CAttribute itemsAttribute = root.getAttribute(ITEMS); + + // handle SECTION.items + if(items != null && items.length > 0) { + + // TODO shouldn't be necessary if the archetype has + // proper archetype_slots + if(itemsAttribute == null) { + + if(parentArchetype == null) { + path = ""; + } else { + path = root.path(); + } + path += "/" + ITEMS; + + List alternatives = new ArrayList(); + itemsAttribute = new CMultipleAttribute(path, ITEMS, + Existence.OPTIONAL, Cardinality.LIST, alternatives); + root.addAttribute(itemsAttribute); + } + + // flatten each item in the list + for(ContentItem item : items) { + + log.debug("flattening section.items.. "); + + flattenContentItem(archetype, item); + } + } + return archetype; + } + + // validity check of node_id (archetype_id) and name among siblings + private void checkSiblingNodeIdAndName(CAttribute parent, + String nodeId, String name) throws FlatteningException { + + for(CObject cobj : parent.getChildren()) { + if(nodeId.equals(cobj.path()) && name.equals(cobj.getNodeId())) { + throw new FlatteningException("duplicated node_id/name: " + + nodeId + "/" + name + "at path: " + parent.path()); + } + } + } + + private int countChildOfArchetypeId(CAttribute cattr, String archetypeId) { + int count = 0; + for(CObject cobj : cattr.getChildren()) { + String nodeId = cobj.getNodeId(); + if(nodeId == null) { + continue; + } + if(nodeId.startsWith(archetypeId)) { + count++; + } + } + return count; + } + + /** + * Overwrite recursively all the nodeIds in the given cobj tree with + * incremental number starting with given count value + * + * @param ccobj + * @param diff + * @return total number of nodeIds adjusted, used to update nodeId counter + */ + protected long adjustNodeIds(CObject cobj, long count) + throws FlatteningException { + + if(cobj.getNodeId() != null) { + count++; + cobj.setNodeId(formatNodeId(count)); + } + if(cobj instanceof CComplexObject) { + for(CAttribute attr : ((CComplexObject) cobj).getAttributes()) { + for(CObject child : attr.getChildren()) { + count = adjustNodeIds(child, count); + } + } + } + return count; + } + + // TODO until this is in sync with pathNodeMap, this shouldn't be used + protected void adjustNodeIds(CObject root) throws FlatteningException { + this.nodeCount = adjustNodeIds(root, this.nodeCount); + } + + // "/content" => "content" + // "/content/name" => "name" + // "/data[at0001]/items[at0002]" => "items" + private String lastAttribute(String path) { + int i = path.lastIndexOf("/"); + String attr = path.substring(i + 1, path.length()); + i = attr.indexOf("["); + if(i >= 0) { + attr = attr.substring(0, i); + } + log.debug("attribute name: " + attr); + return attr; + } + + private Archetype flattenEntry(Archetype parentArchetype, + Archetype archetype, ENTRY definition) throws FlatteningException { + + log.debug("flattening entry on archetype: " + definition.getArchetypeId() + + ", path: " + ((ENTRY) definition).getPath()); + + String path = definition.getPath(); + + // bind current archetype to the parent + fillArchetypeSlot(parentArchetype, archetype, path, definition.getName()); + + // common part for all entries + ENTRY entry = (ENTRY) definition; + ITEM[] items = entry.getItemsArray(); + if(items != null) { + for(ITEM item : items) { + flattenItem(archetype, item); + } + } + + // more specialized handling of sub-entry + if(definition instanceof EVALUATION) { + + // no special handling + + } else if(definition instanceof OBSERVATION) { + + // no special handling + + } else if(definition instanceof ACTION) { + + // TODO handle description item + ACTION action = (ACTION) definition; + + parentArchetype = retrieveArchetype(action.getArchetypeId()); + ITEMSTRUCTURE description = action.getDescription(); + if(description != null) { + flattenItemStructure(archetype, description); + } + + } else if(definition instanceof INSTRUCTION) { + + flattenInstruction(parentArchetype, archetype, (INSTRUCTION) definition); + + } else if(definition instanceof ADMINENTRY) { + + // no special handling + } + + return archetype; + } + + /** + * Fill archetype_slot at specified path of parentArchetype + * and remove all slots + * + * @param parentArchetype + * @param archetype + * @param path + * @throws FlatteningException + */ + private void fillArchetypeSlot(Archetype parentArchetype, + Archetype archetype, String path, String name) throws FlatteningException { + + String archetypeId = archetype.getArchetypeId().toString(); + CComplexObject root = archetype.getDefinition(); + + if(parentArchetype != null ) { + + // TODO has a quick-fix for the following path syntax + // "/activities[at0001 and name/value='Medication activity']/description" + // WILL NOT WORK IN OTHER CASES!! + + int hybridStart = path.indexOf(" and name/value='"); + if( hybridStart > 0) { + int i = path.indexOf("]"); + path = path.substring(0, hybridStart) + path.substring(i); + + log.debug("hybrid path detected, converted physical path: " + path); + } + + CAttribute attribute = getParentAttribute(parentArchetype, path); + if(attribute == null) { + throw new FlatteningException("CAttribute not found at " + path); + } + removeArchetypeSlots(attribute); + + root.setNodeId(archetypeId); + String pathSegment = archetypeId; + if(name != null) { + checkSiblingNodeIdAndName(attribute, archetypeId, name); + pathSegment = namedNodeSegment(archetypeId, name); + } + setPathPrefixOnCObjectTree(root, attribute.path() + "[" + + pathSegment + "]"); + + attribute.addChild(root); + } + } + + private CAttribute getParentAttribute(Archetype archetype, String path) + throws FlatteningException { + + String parentPath = Locatable.parentPath(path); + ArchetypeConstraint ac = archetype.node(parentPath); + + if( ! (ac instanceof CComplexObject)) { + throw new FlatteningException("Parent node not found at " + path + + ", computed parentPath: " + parentPath); + } + CComplexObject parentNode = (CComplexObject) ac; + String attributeName = lastAttribute(path); + CAttribute attribute = parentNode.getAttribute(attributeName); + return attribute; + } + + private void flattenInstruction(Archetype parentArchetype, + Archetype archetype, INSTRUCTION instruction) + throws FlatteningException { + + log.debug("flattening instruction on archetype: " + instruction.getArchetypeId() + + ", path: " + ((ENTRY) instruction).getPath()); + + ITEMSTRUCTURE[] descriptions = instruction.getActivityDescriptionArray(); + + if(descriptions != null) { + for(ITEMSTRUCTURE item : descriptions) { + flattenItemStructure(archetype, item); + } + } + } + + private void removeArchetypeSlots(CAttribute cattr) { + if(cattr == null) { + return; + } + // TODO verify slots by RM types + for(Iterator it = cattr.getChildren().iterator(); + it.hasNext();) { + CObject cobj = it.next(); + if(cobj instanceof ArchetypeSlot) { + it.remove(); + log.debug("archetype_slot removed from attribute " + + cattr.getRmAttributeName()); + } + } + } + + /* + * Flatten any subclass of item_structure + * + * @param parentArchetype + * @param structure + * @return + * @throws FlatteningException + */ + private Archetype flattenItemStructure(Archetype parentArchetype, + ITEMSTRUCTURE structure) throws FlatteningException { + + log.debug("flattening item_structure on archetype: " + + structure.getArchetypeId() + " on path: " + structure.getPath()); + + Archetype archetype = retrieveArchetype(structure.getArchetypeId()); + + applyTemplateConstraints(archetype, structure); + + fillArchetypeSlot(parentArchetype, archetype, structure.getPath(), + structure.getName()); + + ITEM[] items = structure.getItemsArray(); + if(items != null) { + for(ITEM item : items) { + flattenItem(archetype, item); + } + } + return archetype; + } + + /** + * Apply a set of rules in the context of given archetype + * + * Important to keep passing the same archetype reference + * and keep the archetype updated when each rule is applied + * + * @param archetype + * @param rules + * @throws FlatteningException + */ + void applyRules(Archetype archetype, Statement[] rules) + throws FlatteningException { + + if(rules == null) { + return; + } + String name = null; + String leadingPath = null; + + for(Statement rule : rules) { + if(rule.getName() != null) { + if(name == null) { + name = rule.getName(); + leadingPath = rule.getPath(); + + } else if(rule.getPath().equals(leadingPath)) { + + // more than one named node for the same path, + // thus no need to rewrite the paths + log.debug("more than one named node [" + name + + "] on path: " + leadingPath ); + + name = null; + break; + } + } + } + + // rewrite rule path for named nodes + // ASUMMING order is respected!! + for(Statement rule : rules) { + if(name != null && rule.getPath().startsWith(leadingPath) + && rule.getPath().length() > leadingPath.length()) { + int len = leadingPath.length(); + String path = rule.getPath(); + path = path.substring(0, len - 1) + " and name/value='" + + name + "'" + path.substring(len - 1); + + rule.setPath(path); + + log.debug("rewrote path with named node: " + path); + } + applyRule(archetype, rule); + } + } + + /** + * Apply a single rule on given archetype + * + * @param archetype + * @param rule + * @throws FlatteningException + */ + void applyRule(Archetype archetype, Statement rule) + throws FlatteningException { + + log.debug("apply rule [" + rule + "] on archetype: " + + archetype.getArchetypeId().toString()); + + String path = rule.getPath(); + + ArchetypeConstraint constraint = archetype.node(rule.getPath()); + + if(constraint == null) { + throw new FlatteningException("no constraint on path: " + + path + " of " + archetype.getArchetypeId()); + } + + constraint = applyNameConstraint(archetype, constraint, rule.getName(), + path); + + applyOccurrencesConstraints(archetype, constraint, rule); + + applyDefaultValueConstraint(constraint, rule.getDefault()); + + applyHideOnFormConstraint(constraint, rule.getHideOnForm()); + + applyAnnotationConstraint(constraint, rule.getAnnotation()); + + applyValueConstraint(archetype, constraint, rule); + + archetype.updatePathNodeMap((CObject) constraint); + + if(constraint instanceof CObject) { + log.debug("newly set Occurrences: " + ((CObject) constraint).getOccurrences() ); + } + + } + + // TODO + protected void applyHideOnFormConstraint(ArchetypeConstraint constraint, + boolean hideOnForm) { + return; + } + + // TODO + protected void applyAnnotationConstraint(ArchetypeConstraint constraint, + String annotation) { + if(annotation == null || annotation.length() == 0) { + return; + } + constraint.setAnnotation(annotation); + } + + /** + * Apply a default value rule constraint + * + * Example: + * + * * + * + * @param constraint + * @param rule + * @throws FlatteningException if rmType doesn't fit + */ + protected void applyDefaultValueConstraint(ArchetypeConstraint constraint, + String defaultValue) throws FlatteningException { + + if(defaultValue == null) { + return; + } + + log.debug("applying default value on path: " + constraint.path()); + + if( ! (constraint instanceof CComplexObject)) { + + throw new FlatteningException("failed to apply default constraint," + + "unexpected constraint node: " + constraint.getClass()); + } + + CComplexObject ccobj = (CComplexObject) constraint; + + if( ! ccobj.getRmTypeName().equalsIgnoreCase(ELEMENT)) { + + throw new FlatteningException("failed to apply default constraint," + + "unexpected rmType[" + ccobj.getRmTypeName() + + "] on node: " + ccobj.path()); + } + + // handles case like: + // + // ELEMENT match { + // value match { + // DV_TEXT matches {*} + // } + // } + // or + // ELEMENT match { + // value match { + // DV_CODED_TEXT matches {*} + // } + // } + // + // replace it with + // CPrimitiveObject.cString or CCodePhrase + // + // TODO: an alternative is to use the term_definition + // in archetype_ontology + // + + CAttribute cattr = ccobj.getAttribute(VALUE); + + if(cattr == null) { + cattr = new CSingleAttribute(ccobj.path() + "/" + VALUE, + VALUE, Existence.REQUIRED); + + } else if (cattr != null && cattr.getChildren().size() == 1) { + CObject child = cattr.getChildren().get(0); + + if(child instanceof CComplexObject) { + CComplexObject childCCObj = (CComplexObject) child; + String rmType = childCCObj.getRmTypeName(); + if(DV_TEXT.equals(rmType) || DV_CODED_TEXT.equals(rmType)) { + cattr.removeChild(child); + } + } + } + + Interval occurrences = new Interval(1,1); + + // simple text value + if(defaultValue.indexOf("::") < 0) { + + String path = cattr.path() + "/" + VALUE; + CComplexObject valueObj = CComplexObject.createSingleRequired(path, DV_TEXT); + CAttribute valueAttr = CSingleAttribute.createRequired(path, VALUE); + cattr.addChild(valueObj); + valueObj.addAttribute(valueAttr); + + CString cstring = new CString(null, null, null, defaultValue); + CPrimitiveObject cpo = CPrimitiveObject.createSingleRequired(path, cstring); + valueAttr.addChild(cpo); + + log.debug("c_string applied on path: " + constraint.path()); + + } else { + // or coded_text value + String path = ccobj.path() + "/" + VALUE; + CodePhrase codePhrase = parseCodePhraseAndCollectText(defaultValue, + path); + CCodePhrase ccp = new CCodePhrase(path, occurrences, null, cattr, + null, null, codePhrase, null); + cattr.addChild(ccp); + + log.debug("c_code_phrase constraint applied on path: " + constraint.path()); + } + } + + protected void applyOccurrencesConstraints(Archetype archetype, + ArchetypeConstraint constraint, Statement rule) throws FlatteningException { + + BigInteger max = rule.getMax(); + BigInteger min = rule.getMin(); + + if(max != null || min != null) { + if(constraint instanceof CObject) { + applyOccurrencesConstraint(archetype, (CObject) constraint, rule.getMax(), + rule.getMin()); + } + } + } + + protected void applyOccurrencesConstraint(Archetype archetype, + CObject cobj, BigInteger max, BigInteger min) throws FlatteningException { + + log.debug("applyOccurrencesConstraint, min: " + min + ", max: " + max + + ", at: " + cobj.path()); + + if( !cobj.isRoot() ) { + //assert(cobj.getParent() != null); + } + + String path = cobj.path(); + + Interval occurrences = cobj.getOccurrences(); + + // default occurrences, required [1,1] + // special-case in archetype root, then the default occurrences + // can be overriden + if(( !"/".equals(path)) && occurrences == null) { + + log.warn("try to set occurrences constraint on default(null)" + + " occurrences: " + cobj.path()); + return; + } + + if(max != null && occurrences.getUpper() != null + && max.intValue() > occurrences.getUpper().intValue()) { + throw new FlatteningException("more permissive max occurrences, " + path); + } + + if(max != null && occurrences.getLower() != null + && max.intValue() < occurrences.getLower().intValue()) { + throw new FlatteningException("contradicting max occurrences [max: " + + max.intValue() + ", occurrences.lower: " + + occurrences.getLower().intValue() + "] at path: " + path); + } + + if(min != null && occurrences.getLower() != null + && min.intValue() < occurrences.getLower().intValue()) { + throw new FlatteningException("more permissive min occurrences, " + path); + } + + if(min != null && occurrences.getUpper() != null + && min.intValue() > occurrences.getUpper().intValue()) { + throw new FlatteningException("contradicting min occurrences, " + path); + } + + // it's required already + // special case for archetype node! + if(( !"/".equals(path)) && occurrences.getUpper() != null && occurrences.getLower() != null + && occurrences.getUpper().intValue() == 1 + && occurrences.getLower().intValue() == 1) { + log.warn("try to set occurrences constraint on required node: " + + cobj.path()); + return; + } + + // TODO temp fix for missing min=0 when setting + // optional occurrences in template designer + if(min == null && max != null) { + min = BigInteger.valueOf(0L); + } + + Integer lower = null; + Integer upper = null; + + if(occurrences != null) { + lower = occurrences.getLower(); + upper = occurrences.getUpper(); + } + if(min != null) { + lower = min.intValue(); + if(upper != null && lower > upper) { + upper = lower; + } + } + if(max != null) { + upper = max.intValue(); + if(lower != null && lower > upper) { + lower = upper; + } + } + + Interval newOccurrences = + new Interval(lower, upper, lower != null, upper != null); + + + log.debug("newOccurrences: " + newOccurrences); + + if(newOccurrences.getLower() != null + && newOccurrences.getLower().intValue() > 0 + && !"/".equals(path)) { + + CAttribute parent = getParentAttribute(archetype, path); + + if(parent instanceof CMultipleAttribute) { + CMultipleAttribute cma = (CMultipleAttribute) parent; + + log.debug("setting parent.cardinality: " + cma.getCardinality()); + + // TODO temporarily switched off + cma.getCardinality().getInterval().setLower(newOccurrences.getLower()); + + log.debug("AFTER parent.cardinality: " + cma.getCardinality()); + } else { + if(parent == null) { + log.debug("parent null at " + cobj.path()); + } + } + } + cobj.setOccurrences(newOccurrences); + } + + // TODO add support for name-based hybrid path + // At least for Rule-based name constraint, if the node doesn't + // exist before, a copy of the node should be created with given name + protected CComplexObject applyNameConstraint(Archetype archetype, + ArchetypeConstraint constraint, String name, String localPath) + throws FlatteningException { + + log.debug("applying name constraint [" + name + "] on path: " + + localPath + "constraint: " + constraint.path()); + + // preconditions + assert(constraint instanceof CComplexObject); + + CComplexObject ccobj = (CComplexObject) constraint; + if(name == null) { + return ccobj; + } + + //String path = ccobj.path(); + String path = localPath; + + if(! "/".equals(path)) { + CAttribute parent = getParentAttribute(archetype, path); + assert(parent != null); + + // add a copy of the ccobj if sibling with same node_id exists + // this is the key to enable named-node path in template + if(hasSiblingNodeWithNodeId(parent, ccobj.getNodeId())) { + removeUnnamedSiblingNode(archetype, parent, ccobj.getNodeId()); + + ccobj = (CComplexObject) ccobj.copy(); + parent.addChild(ccobj); + ccobj.setParent(parent); + checkSiblingNodeIdAndName(parent, ccobj.getNodeId(), name); + + log.debug("sibling node with same node_id added, " + name); + } + } + + // TODO check physicalPath needed + path = ccobj.path(); + + log.debug("applyNameConstraint - middle ccobj.path: " + ccobj.path()); + + // perhaps unnecessary + CAttribute nameAttr = ccobj.getAttribute(NAME); + CPrimitiveObject cpo = null; + + if(nameAttr == null) { + + CString cstring = cString(name); + + if("/".equals(path)) { + path = path + NAME; + } else { + path = path+ "/" + NAME; + } + CComplexObject nameObj = CComplexObject.createSingleRequired(path, DV_TEXT); + nameAttr = CSingleAttribute.createRequired(path, NAME); + nameAttr.addChild(nameObj); + + path = path + "/" + VALUE; + CAttribute valueAttr = CSingleAttribute.createRequired(path, VALUE); + nameObj.addAttribute(valueAttr); + cpo = CPrimitiveObject.createSingleRequired(path, cstring); + valueAttr.addChild(cpo); + } + ccobj.addAttribute(nameAttr); + updatePathWithNamedNodeOnCObjectTree(ccobj, ccobj.getNodeId(), name); + archetype.updatePathNodeMapRecursively(ccobj); + + log.debug("after setting name, cobj.path: " + ccobj.path()); + + return ccobj; + } + + private void removeUnnamedSiblingNode(Archetype archetype, + CAttribute parent, String nodeId) throws FlatteningException { + + for(Iterator it = parent.getChildren().iterator(); + it.hasNext();) { + CObject cobj = it.next(); + if(nodeId.equals(cobj.getNodeId())) { + if( ! (cobj instanceof CComplexObject)) { + throw new FlatteningException("unexpected constraint type: " + + cobj.getClass() + " for node_id[" + nodeId + "] at " + + parent.path()); + } + CComplexObject ccobj = (CComplexObject) cobj; + + if( ! ccobj.hasAttribute(NAME)) { + + it.remove(); + + // seems unnecessary + // archetype.reloadNodeMaps(); + + log.debug("Unnamed sibling node[" + nodeId + "] removed.."); + + break; + } + } + } + } + + /* + * Check if given path is a hybrid of physical and runtime path + * + * Example: + * "/data[at0001]/items[at0002 and name/value='one']/items[at0003]" + */ + private boolean isHybridPath(String path) { + // TODO validity check + return path.indexOf(" and name") > 0; + } + + // temporary solution until a proper + // archetype-terminology based solution is specified + protected void __applyNameConstraint(ArchetypeConstraint constraint, + String name) throws FlatteningException { + + + } + + /** + * Checks if there is any sibling node with the same node_id + * + * @param parent + * @param nodeId + * @return + */ + private boolean hasSiblingNodeWithNodeId(CAttribute parent, String nodeId) { + for(CObject cobj : parent.getChildren()) { + if(nodeId.equals(cobj.getNodeId())) { + return true; + } + } + return false; + } + + protected void applyValueConstraint(Archetype archetype, + ArchetypeConstraint constraint, Statement rule) + throws FlatteningException { + + if(rule.getConstraint() == null) { + return; + } + + log.debug("applying value constraint on path: " + constraint.path()); + + if( ! (constraint instanceof CComplexObject)) { + throw new FlatteningException("Unexpected constraint type: " + + (constraint == null ? "null" : constraint.getClass())); + } + + CComplexObject ccobj = (CComplexObject) constraint; + if( ! ccobj.getRmTypeName().equalsIgnoreCase(ELEMENT)) { + throw new FlatteningException("Unexpected constraint rmType: " + + ccobj.getRmTypeName()); + } + ValueConstraint vc = rule.getConstraint(); + + if(vc instanceof TextConstraint) { + + TextConstraint tc = (TextConstraint) vc; + applyTextConstraint(ccobj, tc); + + } if(vc instanceof QuantityConstraint) { + + QuantityConstraint tc = (QuantityConstraint) vc; + applyQuantityConstraint(ccobj, tc); + archetype.updatePathNodeMapRecursively(ccobj); + + } else if(vc instanceof MultipleConstraint) { + + MultipleConstraint mc = (MultipleConstraint) vc; + applyMultipleConstraint(ccobj, mc); + } + } + + protected void applyQuantityConstraint(CComplexObject ccobj, + QuantityConstraint qc) throws FlatteningException { + + log.debug("applying quantity constraint on path: " + ccobj.path()); + + String[] includedUnits = qc.getIncludedUnitsArray(); + String[] excludedUnits = qc.getExcludedUnitsArray(); + QuantityUnitConstraint[] magnitudeUnits = qc.getUnitMagnitudeArray() ; + CDvQuantityItem item = null; + CAttribute valueAttr = ccobj.getAttribute(VALUE); + String valuePath = ccobj.path() + "/" + VALUE; + + if(magnitudeUnits != null && magnitudeUnits.length == 1) { + + log.debug("setting unit_magnitude quantity constraint"); + + QuantityUnitConstraint quc = magnitudeUnits[0]; + Interval magnitude = new Interval( + quc.getMinMagnitude(), quc.getMaxMagnitude(), + quc.getIncludesMinimum(), quc.getIncludesMaximum()); + + item = new CDvQuantityItem(magnitude, quc.getUnit()); + if(valueAttr != null) { + valueAttr.removeAllChildren(); + CDvQuantity cdq = CDvQuantity.singleRequired(valuePath, item); + valueAttr.addChild(cdq); + } + + } else if(includedUnits != null && includedUnits.length == 1) { + // + // mmol/L + // + + log.debug("setting included_units quantity constraint"); + + item = new CDvQuantityItem(includedUnits[0]); + + } else if(excludedUnits != null && excludedUnits.length > 0) { + + log.debug("setting excluded_units quantity constraint"); + + // + // in + // + + if(valueAttr == null) { + throw new FlatteningException( + "Missing value attribute for quantityConstraint.excludedUnits"); + } + if(valueAttr.getChildren() == null || valueAttr.getChildren().isEmpty()) { + throw new FlatteningException( + "Missing child obj for quantityConstraint.excludedUnits"); + } + if(valueAttr.getChildren().size() > 1) { + throw new FlatteningException( + "More than one child obj for quantityConstraint.excludedUnits"); + } + CObject child = valueAttr.getChildren().get(0); + if( ! (child instanceof CDvQuantity)) { + throw new FlatteningException( + "Non-CDvQuantity child obj for quantityConstraint.excludedUnits"); + } + CDvQuantity cdq = (CDvQuantity) child; + if(cdq.getList() == null || cdq.getList().isEmpty()) { + throw new FlatteningException( + "Empty CDvQuantity.list for quantityConstraint.excludedUnits"); + } + + cdq.removeItemByUnitsList(excludedUnits); + return; + + } else { + // TODO > 1 in the array etc + throw new FlatteningException( + "Unsupported quantityConstraint in Template: " + qc); + } + + + if(valueAttr == null) { + + valueAttr = new CSingleAttribute(valuePath, VALUE, Existence.REQUIRED); + CDvQuantity cdq = CDvQuantity.singleRequired(valuePath, item); + valueAttr.addChild(cdq); + ccobj.addAttribute(valueAttr); + + } else { + + // deal with empty c_dv_quantity to add new items + if(valueAttr.getChildren() == null || valueAttr.getChildren().isEmpty()) { + throw new FlatteningException( + "Missing child obj for quantityConstraint.excludedUnits"); + } + if(valueAttr.getChildren().size() > 1) { + throw new FlatteningException( + "More than one child obj for quantityConstraint.excludedUnits"); + } + CObject child = valueAttr.getChildren().get(0); + if( ! (child instanceof CDvQuantity)) { + throw new FlatteningException( + "Non-CDvQuantity child obj for quantityConstraint.excludedUnits"); + } + CDvQuantity cdq = (CDvQuantity) child; + cdq.addItem(item); + } + } + + protected void applyTextConstraint(CComplexObject ccobj, + TextConstraint tc) throws FlatteningException { + + log.debug("applying text constraint on path: " + ccobj.path()); + + String[] includedValues = tc.getIncludedValuesArray(); + String[] excludedValues = tc.getExcludedValuesArray(); + + CAttribute valueAttr = ccobj.getAttribute(VALUE); + String valuePath = ccobj.path() + "/" + VALUE; + String definingCodePath = valuePath + "/" + DEFINING_CODE; + + if(includedValues != null && includedValues.length > 0) { + if(valueAttr == null) { + valueAttr = new CSingleAttribute(valuePath, VALUE, + Existence.REQUIRED); + ccobj.addAttribute(valueAttr); + } else if (valueAttr.getChildren().size() > 0) { + valueAttr.removeAllChildren(); + } + + CComplexObject valueObj = CComplexObject.createSingleRequired( + valuePath, DV_CODED_TEXT); + valueAttr.addChild(valueObj); + + CAttribute definingCode = CSingleAttribute.createRequired( + definingCodePath, DEFINING_CODE); + valueObj.addAttribute(definingCode); + + List codeList = new ArrayList(); + String terminology = null; + String text = null; + String code = null; + for(String value : includedValues) { + int i = value.indexOf("::"); + int j = value.lastIndexOf("::"); + if(i == j || j > value.length() - 2) { + throw new FlatteningException( + "wrong syntax for coded text: " + value); + } + terminology = value.substring(0, i); + code = value.substring(i + 2, j); + text = value.substring(j + 2); + codeList.add(code); + termMap.addTerm(terminology, code, text, valuePath); + } + + CCodePhrase ccp = CCodePhrase.singleRequired(definingCodePath, + terminology, codeList); + definingCode.addChild(ccp); + + } else if(excludedValues != null && excludedValues.length > 0) { + if(valueAttr == null) { + throw new FlatteningException( + "failed to set excluded values on text constraint, " + + "VALUE attribute missing"); + } + if (valueAttr.getChildren().size() == 1) { + CObject child = valueAttr.getChildren().get(0); + if(child instanceof CComplexObject) { + CComplexObject childCCObj = (CComplexObject) child; + if(childCCObj.getRmTypeName().equals(DV_CODED_TEXT)) { + CAttribute definingCodeAttr = + childCCObj.getAttribute(DEFINING_CODE); + + if(definingCodeAttr == null) { + throw new FlatteningException( + "Missing defining_code attribute"); + } + + CCodePhrase ccp = + (CCodePhrase) definingCodeAttr.getChildren().get(0); + + log.debug("before codeList.size: " + ccp.getCodeList().size()); + + for(Iterator it = ccp.getCodeList().iterator(); + it.hasNext();) { + String code = it.next(); + for(String value : excludedValues) { + int i = value.indexOf("::"); + if(code.equals(value.substring(i + 2))) { + it.remove(); + } + } + } + log.debug("after codeList.size: " + ccp.getCodeList().size()); + + } else { + // TODO other data types? + } + } else { + throw new FlatteningException( + "Unexpected VALUE.child constrainType: " + + (child == null ? "null" : child.getClass())); + } + } else { + throw new FlatteningException("Unexpected VALUE.children.size: " + + valueAttr.getChildren().size()); + } + } + } + + protected void applyMultipleConstraint(CComplexObject ccobj, + MultipleConstraint mc) throws FlatteningException { + + log.debug("applying multiple constraint on path: " + ccobj.path()); + + String[] includedTypes = mc.getIncludedTypesArray(); + CAttribute cattr = ccobj.getAttribute(VALUE); + + if(cattr != null) { + if(cattr.getChildren() == null || cattr.getChildren().isEmpty()) { + throw new FlatteningException( + "failed to set value constraint, null/empty children list"); + } + + List newChildrenList = new ArrayList(); + for(CObject child : cattr.getChildren()) { + String childType = child.getRmTypeName(); + for(String type : includedTypes) { + if((DATA_TYPES_PREFIX + type).equalsIgnoreCase(childType) + || type.equalsIgnoreCase(childType)) { + newChildrenList.add(child); + break; + } + } + } + cattr.removeAllChildren(); + for(CObject child : newChildrenList) { + cattr.addChild(child); + } + log.debug("total " + newChildrenList.size() + " children left"); + + } else { + // in case value attribute doesn't exist in archetype + String valuePath = ccobj.path() + "/" + VALUE; + cattr = new CSingleAttribute(valuePath, VALUE, Existence.REQUIRED); + ccobj.addAttribute(cattr); + + for(String rmType : includedTypes) { + rmType = rmType.toUpperCase(); + if( ! rmType.startsWith("DV_")) { + rmType = DATA_TYPES_PREFIX + rmType; + } + CComplexObject child = + CComplexObject.createSingleRequired(valuePath, rmType); + cattr.addChild(child); + } + log.debug("value attribute added with total " + + cattr.getChildren().size() + "child(s)"); + } + } + + /* + * Returns next unique nodeId in "at0001" format + */ + protected String formatNodeId(long count) { + String nextId = AT + format.format(count); + return nextId; + } + + /* + * Gets next unique id and increase the counter + */ + private String nextNodeId() { + nodeCount++; + String nextId = formatNodeId(nodeCount); + //log.debug("next nodeId: " + nextId); + return nextId; + } + + /* + * Parse coded text like 'SNOMED-CT::258835005::mg/dygn' + * the last segment of actual text value + * is now collected in termMap as a quick fix + * + */ + private CodePhrase parseCodePhraseAndCollectText(String value, String path) + throws FlatteningException { + + int i = value.indexOf("::"); + int j = value.lastIndexOf("::"); + if(i == j) { + throw new FlatteningException( + "wrong syntax for coded text: " + value); + } + String terminology = value.substring(0, i); + String code = value.substring(i + 2, j); + String text = value.substring(j + 2); + CodePhrase codePhrase = new CodePhrase(terminology, code); + + termMap.addTerm(terminology, code, text, path); + return codePhrase; + } + + private CString cString(String value) { + List values = new ArrayList(); + values.add(value); + CString cstring = new CString(null, values, null); + return cstring; + } + + /** + * Finds and replaces according archetypeSlot with fully flattened cobj + * + * @param cattr + * @param definition + * @param cobj + */ + void replaceSlotWithFlattened(CAttribute cattr, Archetyped definition, + CObject cobj) { + + List children = cattr.getChildren(); + if(children == null) { + return; + } + for(int i = 0, j = children.size(); i < j; i++) { + CObject child = children.get(i); + if(child instanceof ArchetypeSlot) { + // if the slot matches the template def + children.remove(i); + + cobj.setPath(child.path()); + children.add(i, cobj); + } + } + } + + private TEMPLATE retrieveTemplate(String templateId) + throws FlatteningException { + TEMPLATE template = templateMap.get(templateId); + if(template == null) { + throw new FlatteningException("Unknown template: " + templateId); + } + return template; + } + + private Archetype retrieveArchetype(String archetypeId) + throws FlatteningException { + + Archetype archetype = archetypeMap.get(archetypeId); + if(archetype == null) { + throw new FlatteningException("Unknown archetype: " + archetypeId); + } + // make a deep copy + archetype = archetype.copy(); + return archetype; + } + + /** + * Find the largest node id + * + * @param archetype + * @return + */ + protected int findLargestNodeId(Archetype archetype) + throws FlatteningException { + + return findLargestNodeId(archetype.getDefinition(), 0); + } + + // Traverse given cobj tree and find the largest node id + protected int findLargestNodeId(CObject cobj, int largest) + throws FlatteningException { + int current = largest; + int last = 0; + + current = parseNodeId(cobj.getNodeID()); + if(largest > current) { + current = largest; + } + if(cobj instanceof CComplexObject) { + CComplexObject ccobj = (CComplexObject) cobj; + + for(CAttribute cattr : ccobj.getAttributes()) { + for(CObject child : cattr.getChildren()) { + last = findLargestNodeId(child, current); + if(last > current) { + current = last; + } + } + } + } + return current; + } + + /* + * Parses given nodeId and returns the integer value + */ + protected int parseNodeId(String nodeId) throws FlatteningException { + if(nodeId == null) { + return 0; + } + if(nodeId.length() <= AT.length()) { + throw new FlatteningException("Too short nodeId: " + nodeId); + } + nodeId = nodeId.substring(AT.length()); + int dot = nodeId.indexOf("."); + if(dot > 0) { + nodeId = nodeId.substring(0, dot); + } else if(dot == 0) { + throw new FlatteningException("Bad format of nodeId: " + nodeId); + } + int value = 0; + try { + value = Integer.parseInt(nodeId); + } catch(NumberFormatException nfe) { + throw new FlatteningException("Bad format of nodeId: " + nodeId); + } + return value; + } + + protected ArchetypeConstraint nodeAtHybridPath(String path) + throws FlatteningException { + return null; + } + + public TermMap getTermMap() { + return termMap; + } + + /* constant values */ + private static final String DV_TEXT = "DV_TEXT"; + private static final String DV_CODED_TEXT = "DV_CODED_TEXT"; + private static final String ELEMENT = "ELEMENT"; + private static final String NAME = "name"; + private static final String VALUE = "value"; + private static final String ITEMS = "items"; + private static final String CONTENT = "content"; + private static final String DESCRIPTION = "description"; + private static final String DEFINING_CODE = "defining_code"; + private static final String AT = "at"; + private static final String DATA_TYPES_PREFIX = "DV_"; + + /* static fields */ + private static DecimalFormat format = new DecimalFormat("####"); + static { + // number of digits is not limited according to the specs + // using 4 as minimum is by convention + format.setMinimumIntegerDigits(4); + format.setMaximumIntegerDigits(8); + } + + private static Logger log = Logger.getLogger(Flattener.class); + + /* fields */ + private Map archetypeMap; + private Map templateMap; + private TermMap termMap; + private long nodeCount; +} +/* + * ***** 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 Flattener.java + * + * The Initial Developer of the Original Code is Rong Chen. Portions created by + * the Initial Developer are Copyright (C) 2009-2010 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/oet-parser/src/main/java/org/openehr/am/template/FlatteningException.java b/oet-parser/src/main/java/org/openehr/am/template/FlatteningException.java new file mode 100644 index 00000000..2b625f72 --- /dev/null +++ b/oet-parser/src/main/java/org/openehr/am/template/FlatteningException.java @@ -0,0 +1,47 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Class FlatteningException" + * keywords: "oet-parser" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2009,2010 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ + +package org.openehr.am.template; + +public class FlatteningException extends Exception { + + public FlatteningException(String message) { + super(message); + } +} +/* + * ***** 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 FlatteningException.java + * + * The Initial Developer of the Original Code is Rong Chen. Portions created by + * the Initial Developer are Copyright (C) 2009-2010 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/oet-parser/src/main/java/org/openehr/am/template/OETParser.java b/oet-parser/src/main/java/org/openehr/am/template/OETParser.java new file mode 100644 index 00000000..769d41a0 --- /dev/null +++ b/oet-parser/src/main/java/org/openehr/am/template/OETParser.java @@ -0,0 +1,58 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Class OETParser" + * keywords: "oet-parser" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2009,2010 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ + +package org.openehr.am.template; + +import java.io.*; + +import openEHR.v1.template.*; +import org.apache.xmlbeans.XmlOptions; + +/** + * Thin wrapper around generated OET XML parser + */ + +public class OETParser { + + public TemplateDocument parseTemplate(InputStream input) throws Exception { + XmlOptions options = new XmlOptions(); + options.setCharacterEncoding("UTF-8"); + return TemplateDocument.Factory.parse(input, options); + } +} +/* + * ***** 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 OETParser.java + * + * The Initial Developer of the Original Code is Rong Chen. Portions created by + * the Initial Developer are Copyright (C) 2009-2010 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/oet-parser/src/main/java/org/openehr/am/template/PathMap.java b/oet-parser/src/main/java/org/openehr/am/template/PathMap.java new file mode 100644 index 00000000..e04927be --- /dev/null +++ b/oet-parser/src/main/java/org/openehr/am/template/PathMap.java @@ -0,0 +1,196 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Class PathMap" + * keywords: "oet-parser" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2009,2010 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ + +package org.openehr.am.template; + +import java.io.*; +import java.text.DateFormat; +import java.util.*; + +import org.apache.commons.io.FileUtils; +import org.apache.log4j.Logger; + +/** + * A utility class to load path map generated in the template + * flattening process with the following format: + * + * [key]=[path] + * + * NOTE char '=' is not allowed in the key + * + * @author rong.chen + * + */ +public class PathMap { + + PathMap() { + this.keyPathMap = new HashMap(); + } + + /** + * Loads an in-memory termMap by given file + * + * @param input + * @return + * @throws IOException + */ + public static PathMap load(String filename) throws IOException { + List lines = FileUtils.readLines(new File(filename), UTF8); + return fromLines(lines); + } + + /** + * Loads an in-memory termMap by given inputStream + * + * @param input + * @return + * @throws IOException + */ + public static PathMap load(InputStream input) throws IOException { + BufferedReader reader = new BufferedReader(new InputStreamReader(input, UTF8)); + String line = reader.readLine(); + List lines = new ArrayList(); + while(line != null) { + lines.add(line); + line = reader.readLine(); + } + return fromLines(lines); + } + + /** + * Parses given lines and loads a termMap + * + * @param lines + * @return + */ + static PathMap fromLines(List lines) { + PathMap pathMap = new PathMap(); + pathMap.addAll(lines); + return pathMap; + } + + /** + * Adds all given lines into this path map + * + * @param lines + */ + public void addAll(List lines) { + String key = null; + String path = null; + int i = 0; + + for(String line : lines) { + if(line.startsWith("#")) { // skip comment + continue; + } + i = line.indexOf(DELIMITER); + if(i <= 0) { + log.warn("Wrong formatted line skipped: " + line); + continue; + } + key = line.substring(0, i).trim(); + path = line.substring(i + 1).trim(); + addPath(key, path); + } + } + + public void addPath(String key, String path) { + if(key == null || path == null) { + throw new IllegalArgumentException("null key or path"); + } + + if( ! keyPathMap.containsKey(key)) { + + keyPathMap.put(key, path); + + } else if( ! path.equals(keyPathMap.get(key))) { + + log.warn("tried to add duplicated key [" + key + + "] with different path: " + path); + } + } + + public int countPaths() { + return keyPathMap.keySet().size(); + } + + public String getPath(String key) { + return keyPathMap.get(key); + } + + public SortedSet getKeys() { + return new TreeSet(keyPathMap.keySet()); + } + + /** + * Writes this path map to file + * + * @param filename + * @throws IOException + */ + public void writeToFile(String filename) throws IOException { + List paths = new ArrayList(); + DateFormat df = DateFormat.getDateTimeInstance(); + paths.add("# Generated path map on " + df.format(new Date())); + + int maxLen = 0; + String maxLenKey = null; + for(String key : keyPathMap.keySet()) { + String path = keyPathMap.get(key); + if(key.length() > maxLen) { + maxLen = key.length(); + maxLenKey = key; + } + paths.add(key + DELIMITER + path); + } + + log.debug("max length of key: " + maxLen + ", key: " + maxLenKey); + + File pathMapFile = new File(filename); + FileUtils.writeLines(pathMapFile, UTF8, paths); + + log.info("total " + (paths.size() - 1) + + " line(s) of path written to file"); + } + + private static final String UTF8 = "UTF-8"; + private static final String DELIMITER = "="; + private Map keyPathMap; + private Logger log = Logger.getLogger(PathMap.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 PathMap.java + * + * The Initial Developer of the Original Code is Rong Chen. Portions created by + * the Initial Developer are Copyright (C) 2009-2010 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/oet-parser/src/main/java/org/openehr/am/template/TermMap.java b/oet-parser/src/main/java/org/openehr/am/template/TermMap.java new file mode 100644 index 00000000..43ff7eb4 --- /dev/null +++ b/oet-parser/src/main/java/org/openehr/am/template/TermMap.java @@ -0,0 +1,342 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Class TermMap" + * keywords: "oet-parser" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2009,2010 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ + +package org.openehr.am.template; + +import java.io.*; +import java.util.*; + +import org.apache.commons.io.FileUtils; +import org.apache.log4j.Logger; +import org.openehr.rm.datatypes.text.CodePhrase; + +/** + * An in-memory term serving component that can be used as alternative + * to full-blown terminology service. It can load from and write to text + * file using the following syntax for each line. The path item is optional + * and only required if different texts are needed for the same terminology + * and code combination. + * + * {terminology}::{code}::{text}[::{path}] + * + * @author rong.chen + * + */ +public class TermMap { + + public TermMap() { + termMap = new TreeMap>>(); + } + + /** + * Loads an in-memory termMap by given file + * + * @param input + * @return + * @throws IOException + */ + public static TermMap load(String filename) throws IOException { + List lines = FileUtils.readLines(new File(filename), UTF8); + return fromLines(lines); + } + + /** + * Loads an in-memory termMap by given inputStream + * + * @param input + * @return + * @throws IOException + */ + public static TermMap load(InputStream input) throws IOException { + BufferedReader reader = new BufferedReader(new InputStreamReader(input, UTF8)); + String line = reader.readLine(); + List lines = new ArrayList(); + while(line != null) { + lines.add(line); + line = reader.readLine(); + } + return fromLines(lines); + } + + /** + * Parses given lines and loads a termMap + * + * @param lines + * @return + */ + static TermMap fromLines(List lines) { + TermMap termMap = new TermMap(); + termMap.addAll(lines); + return termMap; + } + + /** + * Adds all content from given inputStream + * + * @param input + * @throws Exception + */ + public void addAll(InputStream input) throws Exception { + BufferedReader reader = new BufferedReader(new InputStreamReader(input, UTF8)); + String line = reader.readLine(); + List lines = new ArrayList(); + while(line != null) { + lines.add(line); + line = reader.readLine(); + } + addAll(lines); + } + + /** + * Adds all given lines into this termMap + * + * @param lines + */ + public void addAll(List lines) { + String text = null; + String terminology = null; + String code = null; + String path = null; + StringTokenizer tokens = null; + int totalTokens = 0; + + for(String line : lines) { + tokens = new StringTokenizer(line, DELIMITER); + totalTokens = tokens.countTokens(); + + if(totalTokens != 3 && totalTokens != 4) { + + log.debug("Wrong formatted line skipped: " + line); + + continue; + } + terminology = tokens.nextToken(); + code = tokens.nextToken(); + text = tokens.nextToken(); + if(totalTokens == 4) { + path = tokens.nextToken(); + } else { + path = ""; // default for all paths + } + addTerm(terminology, code, text, path); + } + } + + /** + * Clears all terms from this termMap + * + */ + public void clear() { + termMap.clear(); + } + + /** + * Adds a new term and its text into this termMap + * + * @param terminology + * @param code + * @param text + * @param path + */ + public void addTerm(String terminology, String code, String text, + String path) { + + if(log.isDebugEnabled()) { + log.debug("adding term: " + terminology + DELIMITER + code + + DELIMITER + text + DELIMITER + path); + } + + Map> terms = termMap.get(terminology); + if( terms == null) { + terms = new TreeMap>(); + termMap.put(terminology, terms); + + log.debug("new terminology: " + terminology + " added.."); + + } + Map paths = terms.get(code); + if( paths == null) { + paths = new TreeMap(); + terms.put(code, paths); + } + paths.put(path, text); + } + + /** + * Retrieves the text for given terminology and code + * + * @param terminology + * @param code + * @param path + * @return null if not found + */ + public String getText(String terminology, String code, String path) { + Map paths = null; + String text = null; + + Map> terms = termMap.get(terminology); + + if(terms != null) { + paths = terms.get(code); + if(paths != null) { + if(paths.size() == 1 + && "".equals(paths.keySet().iterator().next())) { + text = paths.get(""); + } else { + text = paths.get(path); + + // TODO temp fix if no direct match + if(text == null) { + for(String p : paths.keySet()) { + if(path.endsWith(p)) { + text = paths.get(p); + } + } + } + } + } + } + + log.debug("Retrieved text '" + text + "' for [" + terminology + "::" + + code + "] at path: " + path); + + return text; + } + + /** + * Retrieves the text for given code_prhase in syntax: + * {terminology}::{code} + * + * @param codePhrase + * @return + */ + public String getText(String codePhrase, String path) { + int i = codePhrase.indexOf(DELIMITER); + if(i <= 0 || i == codePhrase.length()) { + throw new IllegalArgumentException( + "wrong format, expected {terminology}::{code}"); + } + String terminology = codePhrase.substring(0, i); + String code = codePhrase.substring(i + 2); + return getText(terminology, code, path); + } + + /** + * Retrieves the text for given code_prhase + * + * @param codePhrase + * @return + */ + public String getText(CodePhrase codePhrase, String path) { + return getText(codePhrase.getTerminologyId().toString(), + codePhrase.getCodeString(), path); + } + + /** + * Counts the total number of terminologies + * + * @return 0 if empty + */ + public int countTerminologies() { + return termMap.size(); + } + + /** + * Gets the internal representation of terms, mainly for testing purpose + * + * @return + */ + public Map>> getTermMap() { + return termMap; + } + + /** + * Writes this termMap into external file using the following syntax: + * {terminology}::{code}::{text} for each line + * + * @param filename + * @throws IOException + */ + public void writeTermMap(String filename) throws IOException { + StringBuffer buf = new StringBuffer(); + String terminology = null; + String code = null; + String text = null; + String path = null; + Map texts = null; + Map> terms = null; + + for(Iterator it = termMap.keySet().iterator(); it.hasNext();) { + terminology = it.next(); + terms = termMap.get(terminology); + + for(Iterator codes = terms.keySet().iterator(); + codes.hasNext();) { + + code = codes.next(); + texts = terms.get(code); + + for(Iterator paths = texts.keySet().iterator(); + paths.hasNext();) { + + path = paths.next(); + text = texts.get(path); + buf.append(terminology); + buf.append(DELIMITER); + buf.append(code); + buf.append(DELIMITER); + buf.append(text); + buf.append(DELIMITER); + buf.append(path); + if(codes.hasNext() || it.hasNext()) { + buf.append("\r\n"); + } + } + } + } + FileUtils.writeStringToFile(new File(filename), buf.toString(), UTF8); + } + + private static final String UTF8 = "UTF-8"; + private static final String DELIMITER = "::"; + private static final Logger log = Logger.getLogger(TermMap.class); + + // in-memory representation as [terminology, [code, [path, text]] + private Map>> termMap; +} +/* + * ***** 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 TermMap.java + * + * The Initial Developer of the Original Code is Rong Chen. Portions created by + * the Initial Developer are Copyright (C) 2009-2010 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/oet-parser/src/main/xsd/Archetype.xsd b/oet-parser/src/main/xsd/Archetype.xsd new file mode 100644 index 00000000..76efea0d --- /dev/null +++ b/oet-parser/src/main/xsd/Archetype.xsd @@ -0,0 +1,394 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/oet-parser/src/main/xsd/BaseTypes.xsd b/oet-parser/src/main/xsd/BaseTypes.xsd new file mode 100644 index 00000000..6aad6003 --- /dev/null +++ b/oet-parser/src/main/xsd/BaseTypes.xsd @@ -0,0 +1,594 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/oet-parser/src/main/xsd/CharacterMapping.xsd b/oet-parser/src/main/xsd/CharacterMapping.xsd new file mode 100644 index 00000000..c08d916f --- /dev/null +++ b/oet-parser/src/main/xsd/CharacterMapping.xsd @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/oet-parser/src/main/xsd/Composition.xsd b/oet-parser/src/main/xsd/Composition.xsd new file mode 100644 index 00000000..8da5768d --- /dev/null +++ b/oet-parser/src/main/xsd/Composition.xsd @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/oet-parser/src/main/xsd/CompositionTemplate.xsd b/oet-parser/src/main/xsd/CompositionTemplate.xsd new file mode 100644 index 00000000..5ed770c2 --- /dev/null +++ b/oet-parser/src/main/xsd/CompositionTemplate.xsd @@ -0,0 +1,487 @@ + + + + + + openEHR schema base types for the default values + DEFAULT_VALUE <== is a ==> DEFAULT_DV_BOOLEAN == has a ==> DV_BOOLEAN + + use AOM constraint objects for the DV constraints + + + + + + + + + + 1. Is authored Resource + 2. Uid [1..1]: Add UID which is a GUID (fulfils AuthoredResource req for optional ID) + 3. TemplateId [1..1]: id now called TemplateId (fulfils AuthoredResource req for ID) + 4. Name [1..1]: Has logical name + + + + + + + + + + + + + 1. Remove 'from_template' is not needed + 2. Otherwise is same. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + termQueryId discussion + ====================== + termQueryId --> TSU - terminology subset URI + eg. terminology://Snomed?language=en-GB&subset=AllBacteria + TSU should be (subsetName{terminologyId+queryName})?language=en-GB&terminologyVersion=2007.1 + eg. TSU = Snomed_BloodPhenotype?langauge=en-GB&terminologyVersion=2007.1 + + the combination of terminology name and term subset query name is like a GUID + to refer to a particular term query in the OTS query register + therefore the TSU should be something like: + Snomed[version=2007.1, langauge=en-GB]/BloodPhenotype + + limitTolist, includedValues, excludedValues discussion + ====================================================== + When the included/excluded values include values no longer returned by the TSU + these are simply ignored, so only the intersection of TSU-return terms and includedTerms + are considered for inclusion. Similarly the terms excluded by excludedValues which + are not present in the TSU-return terms are ingored. + + LimitToList is relevant for free text (functions as list_open on C_STRING) + LimitToList is relevant for MOST ext coded text (functions as list_open on C_CODE_REFERENCE) + LimitToList not relevant for internally coded text (where archetype has restricted + codes to internally-defined list; could include list of ext codes in AC binding). + + Included values - + - relevant to include free text values (much as in list in C_STRING) + - relevant to include ext coded text values (might need includedCodes property on a C_CODE_REFERENCE) + + Excluded values - + - relevant to remove internal term codes + - relevant to remove terms from external term subset + - relevant to remove included text values in embedded templates + - relevant to remove terms from external term subsets in embedded templates + + AllowTerminologyLookup moved out and into form definition. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/oet-parser/src/main/xsd/Content.xsd b/oet-parser/src/main/xsd/Content.xsd new file mode 100644 index 00000000..dedc49d0 --- /dev/null +++ b/oet-parser/src/main/xsd/Content.xsd @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/oet-parser/src/main/xsd/Extract.xsd b/oet-parser/src/main/xsd/Extract.xsd new file mode 100644 index 00000000..1b8a49b1 --- /dev/null +++ b/oet-parser/src/main/xsd/Extract.xsd @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/oet-parser/src/main/xsd/OpenehrProfile.xsd b/oet-parser/src/main/xsd/OpenehrProfile.xsd new file mode 100644 index 00000000..446ff5af --- /dev/null +++ b/oet-parser/src/main/xsd/OpenehrProfile.xsd @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/oet-parser/src/main/xsd/Resource.xsd b/oet-parser/src/main/xsd/Resource.xsd new file mode 100644 index 00000000..51a21ade --- /dev/null +++ b/oet-parser/src/main/xsd/Resource.xsd @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/oet-parser/src/main/xsd/Structure.xsd b/oet-parser/src/main/xsd/Structure.xsd new file mode 100644 index 00000000..bd11ade1 --- /dev/null +++ b/oet-parser/src/main/xsd/Structure.xsd @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/oet-parser/src/main/xsd/Template.xsd b/oet-parser/src/main/xsd/Template.xsd new file mode 100644 index 00000000..72874884 --- /dev/null +++ b/oet-parser/src/main/xsd/Template.xsd @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/oet-parser/src/main/xsd/Version.xsd b/oet-parser/src/main/xsd/Version.xsd new file mode 100644 index 00000000..a4cb0908 --- /dev/null +++ b/oet-parser/src/main/xsd/Version.xsd @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 new file mode 100644 index 00000000..a5107b9f --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/ActionDescriptionTest.java @@ -0,0 +1,21 @@ +package org.openehr.am.template; + +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; + +public class ActionDescriptionTest extends TemplateTestBase { + + /** + * Verify flattened section with a single evaluation + * + * @throws Exception + */ + public void testActionDescriptionSlotFilling() throws Exception { + flattenTemplate("test_action_description.oet"); + + // section level + ac = flattened.node("/description[openEHR-EHR-ITEM_TREE.medication.v1]"); + assertItemTreeConstraint(ac); + } + + private ArchetypeConstraint ac; +} 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 new file mode 100644 index 00000000..ff8383f6 --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/AnnotationTest.java @@ -0,0 +1,13 @@ +package org.openehr.am.template; + +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; + +public class AnnotationTest extends TemplateTestBase { + + public void testSingleSectionWithName() throws Exception { + flattenTemplate("test_annotation.oet"); + + ArchetypeConstraint ac = flattened.node("/items[at0001]"); + assertEquals("status", ac.getAnnotation()); + } +} 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 new file mode 100644 index 00000000..b4ca99bc --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/ArchetypeSlotTest.java @@ -0,0 +1,50 @@ +package org.openehr.am.template; + +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; +import org.openehr.am.archetype.constraintmodel.CComplexObject; + +public class ArchetypeSlotTest extends TemplateTestBase { + + /* + * Essentially test the slot filling as the following order + * composition / section / instruction / item_tree + */ + public void testExapandNestedArchetypeSlots() throws Exception { + flattenTemplate("prescription.oet"); + + // unfortunately the parser cannot handle archetype_id as node_id + // therefore impossible to perform a complete tree-based comparison + archetype = loadArchetype( + "openEHR-EHR-COMPOSITION.prescription_flattened.v1.adl"); + + // verify major RM structure are in place + ac = flattened.node("/"); + assertCompositionConstraint(ac); + + ac = flattened.node("/content[openEHR-EHR-SECTION.medications.v1]"); + assertSectionConstraint(ac); + + ac = flattened.node("/content[openEHR-EHR-SECTION.medications.v1]" + + "/items[openEHR-EHR-INSTRUCTION.medication.v1]"); + assertInstructionConstraint(ac); + + ac = flattened.node("/content[openEHR-EHR-SECTION.medications.v1]" + + "/items[openEHR-EHR-INSTRUCTION.medication.v1]/activities" + + "[at0001]/description[openEHR-EHR-ITEM_TREE.medication_mod.v1]"); + assertItemTreeConstraint(ac); + + // verify details using hand-made archetype + CComplexObject expected = (CComplexObject) archetype.node( + "/content[at0000]/items[at0000]/activities[at0001]" + + "/description[at0000]"); + + CComplexObject details = (CComplexObject) ac; + + // needed modification before tree comparison + details.setNodeId("at0000"); + assertCComplexObjectEquals("Unexpected flattening result", + expected, (CComplexObject) ac); + } + + private ArchetypeConstraint ac; +} 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 new file mode 100644 index 00000000..55e5f586 --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/CompositionTemplateTest.java @@ -0,0 +1,111 @@ +package org.openehr.am.template; + +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; +import org.openehr.am.archetype.constraintmodel.CComplexObject; + +public class CompositionTemplateTest extends TemplateTestBase { + + public void setUp() throws Exception { + super.setUp(); + } + + public void testContentSlotWithSingleEmptySection() throws Exception { + flattenTemplate("test_composition.oet"); + + constraint = flattened.node("/content[openEHR-EHR-SECTION.ad_hoc_heading.v1]"); + assertSectionConstraint(constraint); + } + + public void testContentSlotWithSingleNamedSection() throws Exception { + flattenTemplate("test_composition2.oet"); + + constraint = flattened.node( + "/content[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='header']"); + assertSectionConstraint(constraint); + + constraint = flattened.node( + "/content[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='header']/name/value"); + assertCStringWithSingleValue(constraint, "header"); + } + + public void testContentSlotWithMaxOccurrences() throws Exception { + flattenTemplate("test_composition4.oet"); + + constraint = flattened.node( + "/content[openEHR-EHR-SECTION.ad_hoc_heading.v1]"); + assertSectionConstraint(constraint); + CComplexObject ccobj = (CComplexObject) constraint; + assertEquals("wrong max occurrences", 1, + ccobj.getOccurrences().getUpper().intValue()); + } + + /** + * Verify an incremental number appended to archetype_id inside node_id + * for duplicated sibling archetypes on the same level + * + * @throws Exception + */ + public void testContentSlotWithTwoNamedSections() throws Exception { + flattenTemplate("test_composition3.oet"); + + // first section + constraint = flattened.node( + "/content[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='one']"); + assertSectionConstraint(constraint); + + constraint = flattened.node( + "/content[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='one']/name/value"); + assertCStringWithSingleValue(constraint, "one"); + + // second section, NOTE the "_1" suffix after archetype_id + constraint = flattened.node( + "/content[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='two']"); + assertSectionConstraint(constraint); + + constraint = flattened.node( + "/content[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='two']/name/value"); + assertCStringWithSingleValue(constraint, "two"); + } + + public void testContentSlotWithFiveNamedSections() throws Exception { + flattenTemplate("test_composition5.oet"); + + // first section + constraint = flattened.node("/content" + + "[openEHR-EHR-SECTION.ad_hoc_heading.v1 and name/value='one']"); + assertSectionConstraint(constraint); + + constraint = flattened.node("/content" + + "[openEHR-EHR-SECTION.ad_hoc_heading.v1 and name/value='one']" + + "/name/value"); + assertCStringWithSingleValue(constraint, "one"); + + // 3rd section + constraint = flattened.node("/content" + + "[openEHR-EHR-SECTION.ad_hoc_heading.v1 and name/value='three']"); + assertSectionConstraint(constraint); + + constraint = flattened.node("/content" + + "[openEHR-EHR-SECTION.ad_hoc_heading.v1 and name/value='three']" + + "/name/value"); + assertCStringWithSingleValue(constraint, "three"); + + // 5th section + constraint = flattened.node("/content" + + "[openEHR-EHR-SECTION.ad_hoc_heading.v1 and name/value='five']"); + assertSectionConstraint(constraint); + + constraint = flattened.node("/content" + + "[openEHR-EHR-SECTION.ad_hoc_heading.v1 and name/value='five']" + + "/name/value"); + assertCStringWithSingleValue(constraint, "five"); + } + + private ArchetypeConstraint constraint; +} 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 new file mode 100644 index 00000000..207095d8 --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/MultipleConstraintTest.java @@ -0,0 +1,79 @@ +package org.openehr.am.template; + +import openEHR.v1.template.MultipleConstraint; +import openEHR.v1.template.Statement; + +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; +import org.openehr.am.archetype.constraintmodel.CComplexObject; + +public class MultipleConstraintTest extends TemplateTestBase { + + public void setUp() throws Exception { + + super.setUp(); + + archetype = loadArchetype( + "openEHR-EHR-ITEM_TREE.medication_multiple_constraint_test.v1.adl"); + + constraint = archetype.node(PATH); + + rule = Statement.Factory.newInstance(); + rule.setPath(PATH); + } + + public void tearDown() { + constraint = null; + } + + /** + * Test multiple constraint in choosing specific data types + * + * @throws Exception + */ + public void testSetMultipleConstraintIncludedTypes() throws Exception { + MultipleConstraint mc = MultipleConstraint.Factory.newInstance(); + mc.addIncludedTypes("Count"); + rule.setConstraint(mc); + + ccobj = (CComplexObject) constraint; + flattener.applyValueConstraint(archetype, ccobj, rule); + + archetype.reloadNodeMaps(); + + constraint = archetype.node(PATH); + assertTrue("expected CComplexObject", constraint instanceof CComplexObject); + CComplexObject ccobj = (CComplexObject) constraint; + assertEquals(1, ccobj.getAttributes().size()); + + constraint = archetype.node(PATH + "/value"); + assertTrue("expected CComplexObject", constraint instanceof CComplexObject); + ccobj = (CComplexObject) constraint; + assertEquals(1, ccobj.getAttributes().size()); + assertEquals("DV_COUNT", ccobj.getRmTypeName()); + + } + + public void testMultipleConstraintWithinTemplate() throws Exception { + flattenTemplate("test_multiple_constraint.oet"); + constraint = flattened.node("/items[at0033]/items[at0034]/items[at0005]/value"); + assertDvCountConstraint(constraint); + } + + public void testMultipleConstraintWithinNestedTemplate() throws Exception { + flattenTemplate("test_multiple_constraint2.oet"); + //printADL(flattened); + constraint = flattened.node("/description[openEHR-EHR-ITEM_TREE.medication.v1]/items[at0033]/items[at0034]/items[at0005]/value"); + assertDvCountConstraint(constraint); + } + + public void testMultipleConstraintWithoutValueAttribute() throws Exception { + flattenTemplate("test_multiple_constraint3.oet"); + constraint = flattened.node(PATH + "/value"); + assertDvCountConstraint(constraint); + } + + private static final String PATH = "/items[at0001]"; + private Statement rule; + private ArchetypeConstraint constraint; + private CComplexObject ccobj; +} 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 new file mode 100644 index 00000000..ad83aa43 --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/PathMapTest.java @@ -0,0 +1,28 @@ +package org.openehr.am.template; + +public class PathMapTest extends TemplateTestBase { + + public void tearDown() { + map = null; + } + + public void testCreateNewAndWriteToFile() throws Exception { + map = new PathMap(); + map.addPath("key1", "path1"); + map.addPath("key2", "path2"); + map.addPath("key2", "path2"); + map.writeToFile("test_paths.txt"); + } + + public void testLoadPathMapAndGetPath() throws Exception { + map= PathMap.load(fromClasspath("test_path_map.txt")); + + assertEquals("unexpected total paths", 2, + map.countPaths()); + + assertEquals("/path1", map.getPath("key1")); + assertEquals("/path2[at0001 and name/value='text']", map.getPath("key2")); + } + + private PathMap map; +} 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 new file mode 100644 index 00000000..a88a2bf3 --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/QuantityConstraintTest.java @@ -0,0 +1,113 @@ +package org.openehr.am.template; + +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; +import org.openehr.am.archetype.constraintmodel.CComplexObject; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantity; +import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantityItem; +import org.openehr.rm.support.basic.Interval; + +import openEHR.v1.template.QuantityConstraint; +import openEHR.v1.template.QuantityUnitConstraint; +import openEHR.v1.template.Statement; + +public class QuantityConstraintTest extends TemplateTestBase { + + public void setUp() throws Exception { + super.setUp(); + archetype = loadArchetype( + "openEHR-EHR-ITEM_TREE.medication_quantity_test.v1.adl"); + + constraint = archetype.node(PATH); + ccobj = (CComplexObject) constraint; + rule = Statement.Factory.newInstance(); + rule.setPath(PATH); + } + + public void tearDown() { + constraint = null; + flattened = null; + archetype = null; + } + + public void testSetQuantityConstraintWithMagnitudeAndUnits() throws Exception { + QuantityConstraint qc = QuantityConstraint.Factory.newInstance(); + QuantityUnitConstraint quc = qc.addNewUnitMagnitude(); + quc.setUnit("/min"); + quc.setMaxMagnitude(300); + quc.setMinMagnitude(10); + quc.setIncludesMaximum(true); + quc.setIncludesMinimum(true); + rule.setConstraint(qc); + + flattener.applyValueConstraint(archetype, ccobj, rule); + archetype.reloadNodeMaps(); + + constraint = archetype.node(PATH + "/value"); + CDvQuantityItem item = new CDvQuantityItem( + new Interval(Double.valueOf(10.0), + Double.valueOf(300)), "/min"); + assertCDvQuantityWithSingleItem(constraint, item); + } + + public void testSetQuantityConstraintWithIncludedUnits() throws Exception { + String[] units = { "mmol/L" }; + QuantityConstraint qc = QuantityConstraint.Factory.newInstance(); + qc.setIncludedUnitsArray(units); + rule.setConstraint(qc); + + flattener.applyValueConstraint(archetype, ccobj, rule); + archetype.reloadNodeMaps(); + + constraint = archetype.node(PATH + "/value"); + CDvQuantityItem item = new CDvQuantityItem(units[0]); + assertCDvQuantityWithSingleItem(constraint, item); + } + + public void testSetQuantityConstraintWithIncludedUnitsOnTemplate() throws Exception { + flattenTemplate("test_quantity_constraint_included_units.oet"); + constraint = flattened.node(PATH + "/value"); + CDvQuantityItem item = new CDvQuantityItem("mmol/L"); + assertCDvQuantityWithSingleItem(constraint, item); + } + + public void testIncludedUnitsWithEmptyCDvQuantity() throws Exception { + flattenTemplate("test_quantity_constraint_included_units3.oet"); + String path = "/data[at0001]/items[at0004]"; + ArchetypeConstraint ac = flattened.node(path + "/value"); + CDvQuantityItem item = new CDvQuantityItem("mg/day"); + assertCDvQuantityWithSingleItem(ac, item); + } + + public void testSetQuantityConstraintWithMagnitudeAndUnitsOnTemplate() throws Exception { + flattenTemplate("test_quantity_constraint_magnitude.oet"); + constraint = flattened.node(PATH + "/value"); + CDvQuantityItem item = new CDvQuantityItem( + new Interval(10.0, 300.0), "/min"); + assertCDvQuantityWithSingleItem(constraint, item); + } + + public void testSetQuantityConstraintWithExcludedUnitsOnTemplate() throws Exception { + flattenTemplate("test_quantity_constraint_excluded_units.oet"); + ArchetypeConstraint ac = flattened.node(PATH + "/value"); + CDvQuantityItem item = new CDvQuantityItem( + new Interval(0.0, 1000.0), "cm"); + assertCDvQuantityWithSingleItem(ac, item); + } + + public void testSetQuantityConstraintWithMixedConstraints() throws Exception { + flattenTemplate("test_quantity_constraint_mixed.oet"); + String path = "/items[openEHR-EHR-OBSERVATION.lab_test.v1 and " + + "name/value='B-HB']/data[at0001]/events[at0002]/data[at0003]" + + "/items[at0078]/value"; + ArchetypeConstraint ac = flattened.node(path); + Interval magnitude = new Interval(20.0, 300.0); + CDvQuantityItem item = new CDvQuantityItem(magnitude, "g/L"); + assertCDvQuantityWithSingleItem(ac, item); + } + + private static final String PATH = "/items[at0001]"; + private Statement rule; + private ArchetypeConstraint constraint; + private CComplexObject ccobj; + +} 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 new file mode 100644 index 00000000..d15d6dbf --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/SectionEvaluationTest.java @@ -0,0 +1,178 @@ +package org.openehr.am.template; + +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; + +public class SectionEvaluationTest extends TemplateTestBase { + + /** + * Verify flattened section with a single evaluation + * + * @throws Exception + */ + public void testSectionWithSingleEvaluation() throws Exception { + flattenTemplate("test_section_evaluation.oet"); + + // section level + ac = flattened.node("/"); + assertSectionConstraint(ac); + ac = flattened.node("/name/value"); + assertCStringWithSingleValue(ac, "section header"); + + // evaluation level + ac = flattened.node("/items" + + "[openEHR-EHR-EVALUATION.structured_summary.v1" + + " and name/value='evaluation header']"); + assertEvaluationConstraint(ac); + + ac = flattened.node("/items" + + "[openEHR-EHR-EVALUATION.structured_summary.v1" + + " and name/value='evaluation header']/name/value"); + assertCStringWithSingleValue(ac, "evaluation header"); + + // insider newly embedded evaluation + ac = flattened.node("/items" + + "[openEHR-EHR-EVALUATION.structured_summary.v1" + + " and name/value='evaluation header']/data[at0001]"); + assertItemTreeConstraint(ac); + + ac = flattened.node("/items" + + "[openEHR-EHR-EVALUATION.structured_summary.v1" + + " and name/value='evaluation header']/data[at0001]" + + "/items[at0002]"); + assertElementConstraint(ac); + + ac = flattened.node("/items" + + "[openEHR-EHR-EVALUATION.structured_summary.v1" + + " and name/value='evaluation header']/data[at0001]" + + "/items[at0005]"); + assertElementConstraint(ac); + + ac = flattened.node("/items" + + "[openEHR-EHR-EVALUATION.structured_summary.v1" + + " and name/value='evaluation header']/data[at0001]" + + "/items[at0003]"); + assertElementConstraint(ac); + } + + /** + * Verify flattened section with two evaluations + * + * @throws Exception + */ + public void testSectionWithTwoEvaluations() throws Exception { + flattenTemplate("test_section_evaluation2.oet"); + + // section level + ac = flattened.node("/"); + assertSectionConstraint(ac); + ac = flattened.node("/name/value"); + assertCStringWithSingleValue(ac, "section header"); + + // first evaluation + ac = flattened.node("/items" + + "[openEHR-EHR-EVALUATION.structured_summary.v1" + + " and name/value='evaluation one']"); + assertEvaluationConstraint(ac); + + ac = flattened.node("/items" + + "[openEHR-EHR-EVALUATION.structured_summary.v1" + + " and name/value='evaluation one']/name/value"); + assertCStringWithSingleValue(ac, "evaluation one"); + + // second evaluation + ac = flattened.node("/items" + + "[openEHR-EHR-EVALUATION.structured_summary.v1" + + " and name/value='evaluation two']"); + assertEvaluationConstraint(ac); + + ac = flattened.node("/items" + + "[openEHR-EHR-EVALUATION.structured_summary.v1" + + " and name/value='evaluation two']/name/value"); + assertCStringWithSingleValue(ac, "evaluation two"); + + // insider 1st evaluation + ac = flattened.node("/items" + + "[openEHR-EHR-EVALUATION.structured_summary.v1" + + " and name/value='evaluation one']/data[at0001]"); + assertItemTreeConstraint(ac); + + ac = flattened.node("/items" + + "[openEHR-EHR-EVALUATION.structured_summary.v1" + + " and name/value='evaluation one']/data[at0001]/items[at0002]"); + assertElementConstraint(ac); + + // insider 2nd evaluation + ac = flattened.node("/items" + + "[openEHR-EHR-EVALUATION.structured_summary.v1" + + " and name/value='evaluation two']/data[at0001]"); + assertItemTreeConstraint(ac); + + ac = flattened.node("/items" + + "[openEHR-EHR-EVALUATION.structured_summary.v1" + + " and name/value='evaluation two']/data[at0001]/items[at0002]"); + assertElementConstraint(ac); + } + + public void testNestedSectionWithEvaluation() throws Exception { + template = loadTemplate("test_nested_section_evaluation.oet"); + flattened = flattener.toFlattenedArchetype(template, archetypeMap); + + // section level one + ac = flattened.node("/"); + assertSectionConstraint(ac); + ac = flattened.node("/name/value"); + assertCStringWithSingleValue(ac, "section level one"); + + // section level two + ac = flattened.node("/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='section level two']"); + assertSectionConstraint(ac); + + ac = flattened.node("/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='section level two']/name/value"); + assertCStringWithSingleValue(ac, "section level two"); + + // evaluation level + ac = flattened.node("/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='section level two']" + + "/items[openEHR-EHR-EVALUATION.structured_summary.v1" + + " and name/value='evaluation header']"); + assertEvaluationConstraint(ac); + + ac = flattened.node("/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='section level two']" + + "/items[openEHR-EHR-EVALUATION.structured_summary.v1" + + " and name/value='evaluation header']/name/value"); + assertCStringWithSingleValue(ac, "evaluation header"); + + // insider newly embedded evaluation + ac = flattened.node("/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='section level two']" + + "/items[openEHR-EHR-EVALUATION.structured_summary.v1" + + " and name/value='evaluation header']/data[at0001]"); + assertItemTreeConstraint(ac); + + ac = flattened.node("/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='section level two']" + + "/items[openEHR-EHR-EVALUATION.structured_summary.v1" + + " and name/value='evaluation header']" + + "/data[at0001]/items[at0002]"); + assertElementConstraint(ac); + + ac = flattened.node("/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='section level two']" + + "/items[openEHR-EHR-EVALUATION.structured_summary.v1" + + " and name/value='evaluation header']" + + "/data[at0001]/items[at0005]"); + assertElementConstraint(ac); + + ac = flattened.node("/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='section level two']" + + "/items[openEHR-EHR-EVALUATION.structured_summary.v1" + + " and name/value='evaluation header']" + + "/data[at0001]/items[at0003]"); + assertElementConstraint(ac); + } + + ArchetypeConstraint ac; +} 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 new file mode 100644 index 00000000..168979c9 --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/SectionInstructionTest.java @@ -0,0 +1,75 @@ +package org.openehr.am.template; + +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; + +public class SectionInstructionTest extends TemplateTestBase { + + /** + * Verify flattened section with a single evaluation + * + * @throws Exception + */ + public void testSectionWithSingleInstruction() throws Exception { + flattenTemplate("test_section_instruction.oet"); + + // section level + ac = flattened.node("/"); + assertSectionConstraint(ac); + + ac = flattened.node("/name/value"); + assertCStringWithSingleValue(ac, "medication"); + + // instruction level + ac = flattened.node("/items[openEHR-EHR-INSTRUCTION.medication.v1" + + " and name/value='medication instruction']"); + assertInstructionConstraint(ac); + + ac = flattened.node("/items[openEHR-EHR-INSTRUCTION.medication.v1" + + " and name/value='medication instruction']/name/value"); + assertCStringWithSingleValue(ac, "medication instruction"); + } + + /** + * Verify flattened section with a single evaluation and + * an embedded ItemTree archetype + * + * @throws Exception + */ + public void testSectionWithInstructionAndItemTree() throws Exception { + flattenTemplate("test_section_instruction_tree.oet"); + + // section level + ac = flattened.node("/"); + assertSectionConstraint(ac); + + ac = flattened.node("/name/value"); + assertCStringWithSingleValue(ac, "medication"); + + // instruction level + ac = flattened.node("/items[openEHR-EHR-INSTRUCTION.medication.v1" + + " and name/value='medication instruction']"); + assertInstructionConstraint(ac); + + ac = flattened.node("/items[openEHR-EHR-INSTRUCTION.medication.v1" + + " and name/value='medication instruction']/name/value"); + assertCStringWithSingleValue(ac, "medication instruction"); + + // item_tree level + ac = flattened.node("/items[openEHR-EHR-INSTRUCTION.medication.v1" + + " and name/value='medication instruction']" + + "/activities[at0001]/description" + + "[openEHR-EHR-ITEM_TREE.medication.v1" + + " and name/value='medication details']"); + assertItemTreeConstraint(ac); + + ac = flattened.node("/items[openEHR-EHR-INSTRUCTION.medication.v1" + + " and name/value='medication instruction']" + + "/activities[at0001]/description" + + "[openEHR-EHR-ITEM_TREE.medication.v1" + + " and name/value='medication details']/name/value"); + + assertCStringWithSingleValue(ac, "medication details"); + } + + ArchetypeConstraint ac; +} 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 new file mode 100644 index 00000000..c7b2370d --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/SectionTemplateTest.java @@ -0,0 +1,114 @@ +package org.openehr.am.template; + +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; + +public class SectionTemplateTest extends TemplateTestBase { + + public void testSingleSectionWithName() throws Exception { + flattenTemplate("test_simple_section.oet"); + expected = loadArchetype("openEHR-EHR-SECTION.simple_section_name.v1.adl"); + + assertCComplexObjectEquals("failed to flatten simple section template", + expected.getDefinition(), flattened.getDefinition()); + + // verify node.path + ac = flattened.node("/"); + assertSectionConstraint(ac); + + ac = flattened.node("/name/value"); + assertCStringWithSingleValue(ac, "single"); + } + + public void testTwoNestedSections() throws Exception { + flattenTemplate("test_nested_section.oet"); + + // verify node.path + ac = flattened.node("/"); + assertSectionConstraint(ac); + + ac = flattened.node("/name/value"); + assertCStringWithSingleValue(ac, "one"); + + // use archetype_id instead of at0000 + ac = flattened.node("/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='two']"); + assertSectionConstraint(ac); + + ac = flattened.node("/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='two']/name/value"); + assertCStringWithSingleValue(ac, "two"); + } + + public void testFiveNestedSections() throws Exception { + flattenTemplate("test_more_nested_section.oet"); + + // first object level, equivalent to "/[at0000]" + ac = flattened.node("/"); + assertSectionConstraint(ac); + + ac = flattened.node("/name/value"); + assertCStringWithSingleValue(ac, "one"); + + // second object level + ac = flattened.node("/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='two']"); + assertSectionConstraint(ac); + + ac = flattened.node("/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='two']/name/value"); + assertCStringWithSingleValue(ac, "two"); + + // third object level + ac = flattened.node("/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='two']" + + "/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='three']"); + assertSectionConstraint(ac); + + ac = flattened.node("/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='two']" + + "/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='three']/name/value"); + assertCStringWithSingleValue(ac, "three"); + + // fourth object level + ac = flattened.node("/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='two']" + + "/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='three']" + + "/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='four']"); + assertSectionConstraint(ac); + + ac = flattened.node("/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='two']" + + "/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='three']" + + "/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='four']/name/value"); + assertCStringWithSingleValue(ac, "four"); + + // fifth object level + ac = flattened.node("/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='two']" + + "/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='three']" + + "/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='four']" + + "/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='five']"); + assertSectionConstraint(ac); + + ac = flattened.node("/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='two']" + + "/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='three']" + + "/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='four']" + + "/items[openEHR-EHR-SECTION.ad_hoc_heading.v1" + + " and name/value='five']/name/value"); + assertCStringWithSingleValue(ac, "five"); + } + + ArchetypeConstraint ac; +} 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 new file mode 100644 index 00000000..e8bf71df --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/SetCardinalityConstraintsTest.java @@ -0,0 +1,52 @@ +package org.openehr.am.template; + +import org.openehr.am.archetype.constraintmodel.*; + +/** + * The cardinality of the parent container is calculated based on + * occurrences of the child elements + * + * @author Rong.Chen + */ +public class SetCardinalityConstraintsTest extends TemplateTestBase { + + public void setUp() throws Exception { + super.setUp(); + } + + public void testWithTwoOptionalNodesAndOneProhibitedNode() throws Exception { + flattenTemplate("test_set_cardinality_with_prohibited_node.oet"); + path = "/items[openEHR-EHR-OBSERVATION.waist_hip.v2]/" + + "data[at0001]/events[at0002]/data[at0003]"; + + CMultipleAttribute itemsAttr = (CMultipleAttribute) ((CComplexObject) + flattened.node(path)).getAttribute("items"); + assertEquals(0, itemsAttr.getCardinality().getInterval().getLower().intValue()); + } + + public void testWithOneRequiredOneOptionalAndOneProhibitedNode() throws Exception { + flattenTemplate("test_set_cardinality_with_prohibited_node3.oet"); + path = "/items[openEHR-EHR-OBSERVATION.waist_hip.v2]/" + + "data[at0001]/events[at0002]/data[at0003]"; + + //printADL(flattened); + + CMultipleAttribute itemsAttr = (CMultipleAttribute) ((CComplexObject) + flattened.node(path)).getAttribute("items"); + assertEquals(1, itemsAttr.getCardinality().getInterval().getLower().intValue()); + } + + // Near IFK2 condition to trigger the issue + public void testWithTwoOptionalNodesAndOneProhibitedNode2() throws Exception { + flattenTemplate("test_set_cardinality_with_prohibited_node2.oet"); + path = "/items[openEHR-EHR-OBSERVATION.heart_failure_stage.v2]/" + + "data[at0001]/events[at0002]/data[at0003]"; + + CMultipleAttribute itemsAttr = (CMultipleAttribute) ((CComplexObject) + flattened.node(path)).getAttribute("items"); + assertEquals(0, itemsAttr.getCardinality().getInterval().getLower().intValue()); + } + + private String path; +} + 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 new file mode 100644 index 00000000..af110175 --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/SetConstraintOnNamedNodeWithoutNameTest.java @@ -0,0 +1,25 @@ +package org.openehr.am.template; + +public class SetConstraintOnNamedNodeWithoutNameTest extends TemplateTestBase { + + public void setUp() throws Exception { + super.setUp(); + } + + /* + * Test to set a constraint on named node, at0002 in this case, + * without using the actual name in the following rule + * + * + */ + public void testSeNodeOccurrencesAndNameConstraint() throws Exception { + flattenTemplate("test_set_named_node_constraint_without_name.oet"); + + path = "/items[openEHR-EHR-EVALUATION.review_of_procedures.v1]/" + + "data[at0001]/items[at0002 and name/value='named']/items[at0005]"; + + assertRequired(path); + } + + private String path; +} 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 new file mode 100644 index 00000000..fcafc673 --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/SetMaxOccurrencesWithoutMinTest.java @@ -0,0 +1,36 @@ +package org.openehr.am.template; + +import org.openehr.am.archetype.constraintmodel.CObject; + +public class SetMaxOccurrencesWithoutMinTest extends TemplateTestBase { + + public void __testSetMaxOccurrencesOnInternalNode() throws Exception { + flattenTemplate("test_set_occurrences_without_min.oet"); + + String path = "/items[at0001]"; + + CObject constraint = (CObject) flattened.node(path); + + assertEquals("unexpected min occurrences", 0, + constraint.getOccurrences().getLower().intValue()); + + assertEquals("unexpected max occurrences", 1, + constraint.getOccurrences().getUpper().intValue()); + + } + + public void testSetMaxOccurrencesOnArchetypeSlot() throws Exception { + flattenTemplate("test_set_occurrences_without_min2.oet"); + + String path = "/items[openEHR-EHR-EVALUATION.structured_summary.v1]"; + + CObject constraint = (CObject) flattened.node(path); + + assertEquals("unexpected min occurrences", 0, + constraint.getOccurrences().getLower().intValue()); + + assertEquals("unexpected max occurrences", 1, + constraint.getOccurrences().getUpper().intValue()); + + } +} 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 new file mode 100644 index 00000000..de327e15 --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/SetMixedConstraintsTest.java @@ -0,0 +1,36 @@ +package org.openehr.am.template; + +import org.openehr.am.archetype.constraintmodel.*; + +public class SetMixedConstraintsTest extends TemplateTestBase { + + public void setUp() throws Exception { + super.setUp(); + } + + /* + * Test setting name, occurrences and c_dv_quantity at same time + * that can trigger 1) missed mandatory node; + */ + public void testSeNodeOccurrencesAndNameConstraint() throws Exception { + flattenTemplate("test_set_mixed_constraints.oet"); + path = "/items[openEHR-EHR-OBSERVATION.waist_hip.v2]/" + + "data[at0001]/events[at0002]/data[at0003]/" + + "items[at0004 and name/value='Bukomfång']"; + + CComplexObject element = (CComplexObject) flattened.node(path); + assertEquals("unexpected num of attributes", 2, + element.getAttributes().size()); + } + + public void testTopNodeNameConstraint() throws Exception { + flattenTemplate("test_set_mixed_constraints.oet"); + + // name attribute + ArchetypeConstraint nameConstraint = flattened.node("/name/value"); + this.assertCStringWithSingleValue(nameConstraint, "STATUS"); + } + + private String path; +} + 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 new file mode 100644 index 00000000..3176ffb3 --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/SetMultipleEvaluationNameTest.java @@ -0,0 +1,29 @@ +package org.openehr.am.template; + +import org.openehr.am.archetype.constraintmodel.*; + +public class SetMultipleEvaluationNameTest extends TemplateTestBase { + + public void setUp() throws Exception { + super.setUp(); + } + + public void testTopNodeNameConstraint() throws Exception { + flattenTemplate("test_set_multiple_evaluation_name.oet"); + + String path = "/items[openEHR-EHR-EVALUATION.review_of_procedures.v1" + + " and name/value='eval_1']/name/value"; + + // name attribute + ArchetypeConstraint nameConstraint = flattened.node(path); + assertCStringWithSingleValue(nameConstraint, "eval_1"); + + path = "/items[openEHR-EHR-EVALUATION.review_of_procedures.v1" + + " and name/value='eval_2']/name/value"; + + nameConstraint = flattened.node(path); + assertCStringWithSingleValue(nameConstraint, "eval_2"); + + } +} + 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 new file mode 100644 index 00000000..512fcbc5 --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/SetNestedEvaluationNameTest.java @@ -0,0 +1,24 @@ +package org.openehr.am.template; + +import org.openehr.am.archetype.constraintmodel.*; + +public class SetNestedEvaluationNameTest extends TemplateTestBase { + + public void setUp() throws Exception { + super.setUp(); + } + + public void testTopNodeNameConstraint() throws Exception { + flattenTemplate("test_set_evaluation_name.oet"); + + String path = "/items[openEHR-EHR-EVALUATION.review_of_procedures.v1" + + " and name/value='eval']/name/value"; + + // name attribute + ArchetypeConstraint nameConstraint = flattened.node(path); + this.assertCStringWithSingleValue(nameConstraint, "eval"); + } + + private String path; +} + 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 new file mode 100644 index 00000000..82c675ba --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/SetNodeNameTest.java @@ -0,0 +1,60 @@ +package org.openehr.am.template; + +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; +import org.openehr.am.archetype.constraintmodel.CComplexObject; + +public class SetNodeNameTest extends TemplateTestBase { + + /* + * Setting leaf-level node name doesn't involving copying nodes + */ + public void testSetLeafNodeNameConstraint() throws Exception { + flattenTemplate("test_text_name.oet"); + + String path = "/data[at0001]/items[at0002]/items" + + "[at0003 and name/value='Typ']"; + + ac = flattened.node(path); + assertElementConstraint(ac); + + ac = flattened.node(path + "/name/value"); + assertCStringWithSingleValue(ac, "Typ"); + } + + /* + * Setting object-level node name involves copying the node and its entire + * tree and updating the path to [node_id and name/value='xxx'] for named + * path to work + */ + public void testSetSingleObjectNodeNameConstraint() throws Exception { + String path = "/data[at0001]/items[at0002 and name/value='insats']" + + "/items[at0003]"; + + flattenTemplate("test_named_path.oet"); + + ac = flattened.node(path); + assertElementConstraint(ac); + + ac = flattened.node(path + "/value"); + assertDvTextConstraint(ac); + } + + /* + * Test named-node path following node name is set + */ + public void testRuleWithNamedNodePath() throws Exception { + String path = "/data[at0001]/items[at0002 and name/value='one']" + + "/items[at0003]"; + + flattenTemplate("test_named_path3.oet"); + + ac = flattened.node(path); + assertElementConstraint(ac); + + CComplexObject ccobj = (CComplexObject) ac; + assertEquals("expected max occurrences", 0, + ccobj.getOccurrences().getUpper().intValue()); + } + + private ArchetypeConstraint ac; +} 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 new file mode 100644 index 00000000..b1f3babe --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/SetNodeOccurrencesTest.java @@ -0,0 +1,190 @@ +package org.openehr.am.template; + +import java.math.BigInteger; + +import openEHR.v1.template.Statement; + +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; +import org.openehr.am.archetype.constraintmodel.CObject; +import org.openehr.rm.support.basic.Interval; + +public class SetNodeOccurrencesTest extends TemplateTestBase { + + public void setUp() throws Exception { + + super.setUp(); + + archetype = loadArchetype( + "openEHR-EHR-ITEM_TREE.medication_test_three.v1.adl"); + + rule = Statement.Factory.newInstance(); + rule.setPath(PATH); + rule.setMax(null); + rule.setMin(null); + } + + public void testSetMaxOccurrencesToZeroOnOptionalNode() throws Exception { + constraint = archetype.node(PATH); + CObject cobj = (CObject) constraint; + cobj.setOccurrences(new Interval(0, null)); + + flattener.applyOccurrencesConstraint(archetype, cobj, BigInteger.valueOf(0), null); + constraint = archetype.node(PATH); + + assertTrue("unexpected constraint", constraint instanceof CObject); + + assertEquals("unexpected max occurrences", 0, + cobj.getOccurrences().getUpper().intValue()); + + assertEquals("unexpected min occurrences", 0, + cobj.getOccurrences().getLower().intValue()); + } + + // make optional node required + public void testSetMinOccurrencesToOneOnOptionalNode() throws Exception { + constraint = archetype.node(PATH); + CObject cobj = (CObject) constraint; + cobj.setOccurrences(new Interval(0, 1)); + + flattener.applyOccurrencesConstraint(archetype, cobj, null, BigInteger.valueOf(1)); + constraint = archetype.node(PATH); + + assertTrue("unexpected constraint", constraint instanceof CObject); + + assertEquals("unexpected max occurrences", 1, + cobj.getOccurrences().getUpper().intValue()); + + assertEquals("unexpected min occurrences", 1, + cobj.getOccurrences().getLower().intValue()); + } + + // make optional node not allowed + public void testSetMaxOccurrencesTozeroOnOptionalNode() throws Exception { + constraint = archetype.node(PATH); + CObject cobj = (CObject) constraint; + cobj.setOccurrences(new Interval(0, 1)); + + flattener.applyOccurrencesConstraint(archetype, cobj, BigInteger.valueOf(0), null); + constraint = archetype.node(PATH); + + assertTrue("unexpected constraint", constraint instanceof CObject); + + assertEquals("unexpected max occurrences", 0, + cobj.getOccurrences().getUpper().intValue()); + + assertEquals("unexpected min occurrences", 0, + cobj.getOccurrences().getLower().intValue()); + } + + public void testSetMaxOccurrencesToZeroOnRequiredNode() throws Exception { + constraint = archetype.node(PATH); + CObject cobj = (CObject) constraint; + cobj.setOccurrences(new Interval(1, 1)); + + try { + flattener.applyOccurrencesConstraint(archetype, cobj, BigInteger.valueOf(0), null); + fail("expect flattening exception on contradicting occurrences"); + } catch(FlatteningException e) {} + } + + public void testSetMaxOccurrencesToTwoOnRequiredNode() throws Exception { + constraint = archetype.node(PATH); + CObject cobj = (CObject) constraint; + cobj.setOccurrences(new Interval(1, 1)); + + try { + flattener.applyOccurrencesConstraint(archetype, cobj, BigInteger.valueOf(2), null); + fail("expect flattening exception on too permissive occurrences"); + } catch(FlatteningException e) {} + } + + public void testSetMaxOccurrencesToOneOnRequiredNode() throws Exception { + constraint = archetype.node(PATH); + CObject cobj = (CObject) constraint; + cobj.setOccurrences(new Interval(1, 1)); + + flattener.applyOccurrencesConstraint(archetype, cobj, BigInteger.valueOf(1), null); + constraint = archetype.node(PATH); + + assertTrue("unexpected constraint", constraint instanceof CObject); + + assertEquals("unexpected max occurrences", 1, + cobj.getOccurrences().getUpper().intValue()); + + assertEquals("unexpected min occurrences", 1, + cobj.getOccurrences().getLower().intValue()); + } + + public void testSetMinOccurrencesToZeroOnRequiredNode() throws Exception { + constraint = archetype.node(PATH); + CObject cobj = (CObject) constraint; + cobj.setOccurrences(new Interval(1, 1)); + + try { + flattener.applyOccurrencesConstraint(archetype, cobj, null, BigInteger.valueOf(0)); + fail("expect flattening exception on too permissive occurrences"); + } catch(FlatteningException e) {} + } + + public void testSetMinOccurrencesToTwoOnRequiredNode() throws Exception { + constraint = archetype.node(PATH); + CObject cobj = (CObject) constraint; + cobj.setOccurrences(new Interval(1, 1)); + + try { + flattener.applyOccurrencesConstraint(archetype, cobj, null, BigInteger.valueOf(2)); + fail("expect flattening exception on contradicting occurrences"); + } catch(FlatteningException e) {} + } + + public void testSetMinOccurrencesToOneOnOptionalNode2() throws Exception { + constraint = archetype.node(PATH); + CObject cobj = (CObject) constraint; + cobj.setOccurrences(new Interval(0, null)); + + flattener.applyOccurrencesConstraint(archetype, cobj, null, BigInteger.valueOf(1)); + constraint = archetype.node(PATH); + + assertTrue("unexpected constraint", constraint instanceof CObject); + + assertEquals("unexpected min occurrences", 1, + cobj.getOccurrences().getLower().intValue()); + + assertNull("unexpected max occurrences", + cobj.getOccurrences().getUpper()); + } + + public void testSetMinOccurrencesToTwoOnOptionalNode() throws Exception { + constraint = archetype.node(PATH); + CObject cobj = (CObject) constraint; + cobj.setOccurrences(new Interval(0, null)); + + flattener.applyOccurrencesConstraint(archetype, cobj, null, BigInteger.valueOf(2)); + constraint = archetype.node(PATH); + + assertEquals("unexpected min occurrences", 2, + cobj.getOccurrences().getLower().intValue()); + + assertNull("unexpected max occurrences", + cobj.getOccurrences().getUpper()); + } + + public void testSetMaxOccurrencesToOneOnOptionalNodeWithoutMinimum() throws Exception { + constraint = archetype.node(PATH); + CObject cobj = (CObject) constraint; + cobj.setOccurrences(new Interval(0, null)); + + flattener.applyOccurrencesConstraint(archetype, cobj, BigInteger.valueOf(1), null); + constraint = archetype.node(PATH); + + assertEquals("unexpected min occurrences", 0, + cobj.getOccurrences().getLower().intValue()); + + assertEquals("unexpected max occurrences", 1, + cobj.getOccurrences().getUpper().intValue()); + } + + private static final String PATH = "/items[at0001]"; + private Statement rule; + private ArchetypeConstraint constraint; +} 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 new file mode 100644 index 00000000..1f819aff --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/SetOccurrencesAndNameTest.java @@ -0,0 +1,22 @@ +package org.openehr.am.template; + +public class SetOccurrencesAndNameTest extends TemplateTestBase { + + /* + * Setting leaf-level node name doesn't involving copying nodes + */ + public void testSeNodeOccurrencesAndNameConstraint() throws Exception { + flattenTemplate("test_set_occurrences_and_name.oet"); + + String path = "/description[openEHR-EHR-ITEM_TREE.medication.v1]/"; + + assertNotAllowed(path + "items[at0003]"); + assertNotAllowed(path + "items[at0004]"); + + path += "items[at0033 and name/value='dos']/items[at0035]"; + + assertRequired(path); + assertNotAllowed(path + "/items[at0036]"); + assertRequired(path + "/items[at0037]"); + } +} 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 new file mode 100644 index 00000000..9d162a09 --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/TemplateParseTest.java @@ -0,0 +1,69 @@ +package org.openehr.am.template; + +import openEHR.v1.template.Archetyped; +import openEHR.v1.template.COMPOSITION; +import openEHR.v1.template.INSTRUCTION; +import openEHR.v1.template.ITEMTREE; +import openEHR.v1.template.SECTION; +import openEHR.v1.template.TEMPLATE; +import openEHR.v1.template.TemplateDocument; + +public class TemplateParseTest extends TemplateTestBase { + + /** + * Test 'raw' parsing of OET template + * + * @throws Exception + */ + public void testParseSimpleTemplate() throws Exception { + TemplateDocument templateDoc = parser.parseTemplate(fromClasspath( + "templates/prescription.oet")); + + assertNotNull("passed template null", templateDoc); + assertTrue("template type wrong", templateDoc instanceof TemplateDocument); + + TEMPLATE template = templateDoc.getTemplate(); + + assertEquals("template name wrong", "Prescription", template.getName()); + + Archetyped def = template.getDefinition(); + + assertTrue("type wrong", def instanceof COMPOSITION); + + COMPOSITION composition = (COMPOSITION) def; + + assertEquals("composition archetypeId wrong", + "openEHR-EHR-COMPOSITION.prescription.v1", + composition.getArchetypeId()); + + assertTrue("type wrong", composition.getContentArray()[0] instanceof SECTION); + + SECTION section = (SECTION) composition.getContentArray()[0]; + + assertEquals("section archetypeId wrong", + "openEHR-EHR-SECTION.medications.v1", + section.getArchetypeId()); + + assertEquals("section path wrong", "/content", section.getPath()); + assertTrue("type wrong", section.getItemArray()[0] instanceof INSTRUCTION); + + INSTRUCTION instruction = (INSTRUCTION) section.getItemArray()[0]; + + assertEquals("instruction archetypeId wrong", + "openEHR-EHR-INSTRUCTION.medication.v1", instruction.getArchetypeId()); + + assertEquals("instruction path wrong", "/items", instruction.getPath()); + + assertTrue("itemTree type wrong", + instruction.getActivityDescriptionArray()[0] instanceof ITEMTREE); + + ITEMTREE itemtree = (ITEMTREE) instruction.getActivityDescriptionArray()[0]; + + assertEquals("itemTree archetypeId wrong", + "openEHR-EHR-ITEM_TREE.medication_mod.v1", itemtree.getArchetypeId()); + + assertEquals("itemTree path wrong", "/activities[at0001]/description", + itemtree.getPath()); + } +} + 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 new file mode 100644 index 00000000..434e98ab --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/TemplateTestBase.java @@ -0,0 +1,652 @@ +package org.openehr.am.template; + +import java.io.File; +import java.io.FileWriter; +import java.io.InputStream; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import openEHR.v1.template.TEMPLATE; + +import org.apache.commons.io.FileUtils; +import org.apache.log4j.Logger; +import org.openehr.am.archetype.Archetype; +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.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.CPrimitive; +import org.openehr.am.archetype.constraintmodel.primitive.CString; +import org.openehr.am.openehrprofile.datatypes.basic.CDvState; +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.text.CCodePhrase; +import org.openehr.am.serialize.ADLSerializer; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.basic.Interval; + +import com.thoughtworks.xstream.XStream; + +import se.acode.openehr.parser.ADLParser; + +import junit.framework.TestCase; + +public class TemplateTestBase extends TestCase { + + TemplateTestBase() { + try { + loadArchetypeMap(); + parser = new OETParser(); + } catch(Exception e) { + throw new RuntimeException(e); + } + } + + public void setUp() throws Exception { + flattener = new Flattener(); + serializer = new ADLSerializer(); + } + + public void tearDown() throws Exception { + template = null; + } + + protected void flattenTemplate(String templateFilename) throws Exception { + template = loadTemplate(templateFilename); + flattened = flattener.toFlattenedArchetype(template, + archetypeMap, templateMap); + } + + protected void printPaths(String filter) { + for (String key : flattened.getPathNodeMap().keySet()) { + if (filter == null || (filter != null && key.contains(filter))) { + System.out.println(key); + } + } + } + + protected void assertRequired(String path) throws Exception { + CObject cobj = assertCObject(path); + assertTrue("expected to be required", cobj.isRequired()); + } + + protected void assertNotAllowed(String path) throws Exception { + CObject cobj = assertCObject(path); + Interval notAllowed = new Interval(0,0); + assertEquals(notAllowed, cobj.getOccurrences()); + } + + protected CObject assertCObject(String path, Archetype archetype) { + ArchetypeConstraint ac = archetype.node(path); + assertTrue("unexpected non-CObject: " + + (ac == null ? null : ac.getClass()) + " on path: [" + path + "]", + ac instanceof CObject); + CObject cobj = (CObject) ac; + return cobj; + } + + protected CObject assertCObject(String name, String path, Archetype archetype) { + ArchetypeConstraint ac = archetype.node(path); + assertTrue("unexpected non-CObject[ " + name + "] " + + (ac == null ? null : ac.getClass()) + " on path: " + path, + ac instanceof CObject); + CObject cobj = (CObject) ac; + return cobj; + } + + protected CObject assertCObject(String path) { + return assertCObject(path, flattened); + } + + protected Archetype loadArchetype(String id) throws Exception { + ADLParser adlParser = new ADLParser(fromClasspath(ARCHETYPE_PATH + + id)); + return adlParser.parse(); + } + + /** + * Load all archetypes from predefined path + * + * @throws Exception + */ + protected void loadAllArchetypes() throws Exception { + archetypeMap = new HashMap(); + + File[] files = new File(ARCHETYPE_PATH).listFiles(); + for(File file : files) { + if(file.getName().contains(".adl")) { + ADLParser adlParser = new ADLParser(file); + Archetype archetype = adlParser.parse(); + archetypeMap.put(archetype.getArchetypeId().toString(), archetype); + } + } + } + + protected TEMPLATE loadTemplate(String id) throws Exception { + template = parser.parseTemplate( + fromClasspath(TEMPLATE_PATH + id)).getTemplate(); + return template; + } + + protected InputStream fromClasspath(String filename) throws Exception { + return this.getClass().getClassLoader().getResourceAsStream(filename); + } + + /** + * Compares two CComplexObject by values + * + * The reason not to use the built-in equals() directly is + * the path can be different between flattened archetype and expected + * one directly loaded from ADL. + */ + protected void assertCComplexObjectEquals(String message, + CComplexObject ccobj1, CComplexObject ccobj2) { + + assertEquals(message + ", ccobj.rmTypeName not equals at path: " + ccobj1.path(), + ccobj1.getRmTypeName(), ccobj2.getRmTypeName()); + + assertEquals(message + "ccobj.nodeId not equals at path: " + ccobj1.path(), + ccobj1.getNodeId(), ccobj2.getNodeId()); + + assertEquals(message + "ccobj.occurrences not equals at path: " + ccobj1.path(), + ccobj1.getOccurrences(), ccobj2.getOccurrences()); + + assertEquals(message + + ", ccobj.attributes total number not equals at path: " + ccobj1.path(), + ccobj1.getAttributes().size(), ccobj2.getAttributes().size()); + + for(int i = 0, j = ccobj2.getAttributes().size(); i < j; i++) { + CAttribute cattr1 = ccobj1.getAttributes().get(i); + CAttribute cattr2 = ccobj2.getAttributes().get(i); + assertCAttributeEquals(message, cattr1, cattr2); + } + } + + protected void assertCComplexObjectOfRmType(String message, + ArchetypeConstraint ac, String rmType) throws Exception { + assertTrue(message + ", unexpected constraint: " + ac, + ac instanceof CComplexObject); + CComplexObject ccobj = (CComplexObject) ac; + assertEquals(message + ", unexpected rmType: " + ccobj.getRmTypeName(), + rmType, ccobj.getRmTypeName()); + } + + protected void assertCComplexObjectOfRmType(ArchetypeConstraint ac, + String rmType) throws Exception { + assertCComplexObjectOfRmType("Unexpected constraint type " + + (ac == null ? "null" : ac.getClass() + " at " + ac.path()), + ac, rmType); + } + + protected void assertCompositionConstraint(ArchetypeConstraint ac) + throws Exception { + assertCComplexObjectOfRmType(ac, COMPOSITION); + } + + protected void assertItemTreeConstraint(ArchetypeConstraint ac) + throws Exception { + assertCComplexObjectOfRmType(ac, ITEM_TREE); + } + + protected void assertItemListConstraint(ArchetypeConstraint ac) + throws Exception { + assertCComplexObjectOfRmType(ac, ITEM_LIST); + } + + protected void assertElementConstraint(ArchetypeConstraint ac) + throws Exception { + assertCComplexObjectOfRmType(ac, ELEMENT); + } + + protected void assertSectionConstraint(ArchetypeConstraint ac) + throws Exception { + assertCComplexObjectOfRmType(ac, SECTION); + } + + protected void assertObservationConstraint(ArchetypeConstraint ac) + throws Exception { + assertCComplexObjectOfRmType(ac, OBSERVATION); + } + + protected void assertInstructionConstraint(ArchetypeConstraint ac) + throws Exception { + assertCComplexObjectOfRmType(ac, INSTRUCTION); + } + + protected void assertEvaluationConstraint(ArchetypeConstraint ac) + throws Exception { + assertCComplexObjectOfRmType(ac, EVALUATION); + } + + protected void assertActionConstraint(ArchetypeConstraint ac) + throws Exception { + assertCComplexObjectOfRmType(ac, ACTION); + } + + protected void assertActivityConstraint(ArchetypeConstraint ac) + throws Exception { + assertCComplexObjectOfRmType(ac, ACTIVITY); + } + + protected void assertDvTextConstraint(ArchetypeConstraint ac) + throws Exception { + assertCComplexObjectOfRmType(ac, DV_TEXT); + } + + protected void assertDvCodedTextConstraint(ArchetypeConstraint ac) + throws Exception { + assertCComplexObjectOfRmType(ac, DV_TEXT); + } + + protected void assertDvCountConstraint(ArchetypeConstraint ac) + throws Exception { + assertCComplexObjectOfRmType(ac, DV_COUNT); + } + + protected void assertCDomainTypeEquals(String message, CDomainType cobj1, + CDomainType cobj2) { + + if(cobj1 instanceof CDvQuantity) { + + assertTrue(message, cobj2 instanceof CDvQuantity); + + CDvQuantity cdq1 = (CDvQuantity) cobj1; + CDvQuantity cdq2 = (CDvQuantity) cobj2; + assertEquals(message, cdq1.getAssumedValue(), cdq2.getAssumedValue()); + assertEquals(message, cdq1.getDefaultValue(), cdq2.getDefaultValue()); + assertEquals(message, cdq1.getList(), cdq2.getList()); + assertEquals(message, cdq1.getProperty(), cdq2.getProperty()); + assertEquals(message, cdq1.getOccurrences(), cdq1.getOccurrences()); + + } else if(cobj1 instanceof CDvOrdinal) { + + assertTrue(message, cobj2 instanceof CDvOrdinal); + + CDvOrdinal cdq1 = (CDvOrdinal) cobj1; + CDvOrdinal cdq2 = (CDvOrdinal) cobj2; + assertEquals(message, cdq1.getAssumedValue(), cdq2.getAssumedValue()); + assertEquals(message, cdq1.getDefaultValue(), cdq2.getDefaultValue()); + assertEquals(message, cdq1.getList(), cdq2.getList()); + assertEquals(message, cdq1.getOccurrences(), cdq1.getOccurrences()); + + } else if(cobj1 instanceof CCodePhrase) { + + assertTrue(message, cobj2 instanceof CCodePhrase); + + CCodePhrase cdq1 = (CCodePhrase) cobj1; + CCodePhrase cdq2 = (CCodePhrase) cobj2; + assertEquals(message, cdq1.getAssumedValue(), cdq2.getAssumedValue()); + assertEquals(message, cdq1.getDefaultValue(), cdq2.getDefaultValue()); + assertEquals(message, cdq1.getTerminologyId(), cdq2.getTerminologyId()); + assertEquals(message, cdq1.getCodeList(), cdq2.getCodeList()); + assertEquals(message, cdq1.getOccurrences(), cdq1.getOccurrences()); + + } else if(cobj1 instanceof CDvState) { + + assertTrue(message, cobj2 instanceof CDvState); + + CDvState cdq1 = (CDvState) cobj1; + CDvState cdq2 = (CDvState) cobj2; + assertEquals(message, cdq1.getAssumedValue(), cdq2.getAssumedValue()); + assertEquals(message, cdq1.getDefaultValue(), cdq2.getDefaultValue()); + assertEquals(message, cdq1.getValue(), cdq2.getValue()); + assertEquals(message, cdq1.getOccurrences(), cdq1.getOccurrences()); + } + } + + protected void assertCAttributeEquals(String message, CAttribute cattr1, + CAttribute cattr2) { + + assertEquals(message + ", cattribute.rmAttributeName not equal at path: " + + cattr1.path(), cattr1.getRmAttributeName(), cattr2.getRmAttributeName()); + + assertEquals(message + ", cattribute.existence not equal at path: " + + cattr1.path(), cattr1.getExistence(), cattr2.getExistence()); + + assertEquals(message + ", cattribute.children size not equal at path: " + + cattr1.path(), cattr1.getChildren().size(), cattr2.getChildren().size()); + + for(int i = 0, j = cattr1.getChildren().size(); i < j; i++) { + CObject cobj1 = cattr1.getChildren().get(i); + CObject cobj2 = cattr2.getChildren().get(i); + + + assertEquals(message + ", different cobj types at path: " + + cobj1.path(),cobj1.getClass(), cobj2.getClass()); + + // Both complex types + if(cobj1 instanceof CComplexObject && cobj2 instanceof CComplexObject) { + + assertCComplexObjectEquals(message, (CComplexObject) cobj1, (CComplexObject) cobj2); + + } else if(cobj1 instanceof CPrimitiveObject){ + + assertTrue(message, cobj2 instanceof CPrimitiveObject); + + CPrimitiveObject cpo1 = (CPrimitiveObject) cobj1; + CPrimitiveObject cpo2 = (CPrimitiveObject) cobj2; + + assertEquals(message, cpo1.getItem(), cpo2.getItem()); + assertEquals(message, cpo1.getOccurrences(), cpo2.getOccurrences()); + + } else if(cobj1 instanceof ConstraintRef){ + + assertTrue(message, cobj2 instanceof ConstraintRef); + + } else if(cobj1 instanceof CDomainType){ + + assertTrue(message, cobj2 instanceof CDomainType); + + CDomainType cdt1 = (CDomainType) cobj1; + CDomainType cdt2 = (CDomainType) cobj2; + assertCDomainTypeEquals(message, cdt1, cdt2); + + } else { + // use the built-in equals + assertEquals(message, cobj1, cobj2); + } + } + } + + /** + * Assert that the given ArchetypeConstraint is a CPrimitiveObject + * with single string valued c_string item + * + * @param ac + * @param onlyValue + */ + protected void assertCStringWithSingleValue(ArchetypeConstraint ac, String onlyValue) { + CString cs = assertCString(ac); + assertTrue("expected only value in CString", cs.getList().size() == 1); + assertEquals(onlyValue, cs.getList().get(0)); + } + + /** + * Assert that the given ArchetypeConstraint is a CPrimitiveObject + * with a default valued c_string item + * + * @param ac + * @param defaultValue + */ + protected void assertCStringWithDefaultValue(ArchetypeConstraint ac, + String defaultValue) { + CString cs = assertCString(ac); + assertEquals("wrong default value in c_string", defaultValue, + cs.defaultValue()); + } + + /** + * Assert that the given ArchetypeConstraint is a CPrimitiveObject + * with c_string item, then return c_string for further inspection + * + * @param ac + * @param onlyValue + */ + protected CString assertCString(ArchetypeConstraint ac) { + assertNotNull("null instead of CPrimitiveObject", ac); + assertTrue("expected CPrimitiveObject instead of " + ac.getClass(), + ac instanceof CPrimitiveObject); + CPrimitiveObject cop = (CPrimitiveObject) ac; + CPrimitive cp = cop.getItem(); + assertTrue("expected CString instead of " + cp.getClass(), + cp instanceof CString); + CString cstring = (CString) cp; + return cstring; + } + + protected void assertCCodePhraseWithDefaultValue( + ArchetypeConstraint ac, String terminologyId, String code) { + assertTrue("unexpected constraint instead of CCodePhrase: " + + (ac == null ? "null" : ac.getClass()), + ac instanceof CCodePhrase); + CCodePhrase ccp = (CCodePhrase) ac; + CodePhrase cp = new CodePhrase(terminologyId, code); + assertEquals("unexpected CCodePhrase.defaultValue", cp, + ccp.getDefaultValue()); + } + + protected void assertCDvQuantityWithSingleItem(ArchetypeConstraint ac, + CDvQuantityItem item) throws Exception { + assertTrue("unexpected constraint instead of CDvQuantity: " + + (ac == null ? "null" : ac.getClass()), + ac instanceof CDvQuantity); + CDvQuantity cdq = (CDvQuantity) ac; + assertNotNull("expecting non-empty list", cdq.getList()); + assertEquals("expecting only one item", 1, cdq.getList().size()); + assertEquals("cDvQuantityItem diff", item, cdq.getList().get(0)); + } + + protected void assertCCodePhraseWithCodeList( + ArchetypeConstraint ac, String terminologyId, + List codeList) { + assertTrue("unexpected constraint instead of CCodePhrase: " + + (ac == null ? "null" : ac.getClass()), + ac instanceof CCodePhrase); + CCodePhrase ccp = (CCodePhrase) ac; + assertEquals("unexpected CCodePhrase.defaultValue", terminologyId, + ccp.getTerminologyId().toString()); + assertEquals("unexpected CCodePhrase.codeList", codeList, + ccp.getCodeList()); + } + + protected void loadArchetypeMap() throws Exception { + String[] ids = { + "openEHR-EHR-COMPOSITION.prescription.v1", + "openEHR-EHR-INSTRUCTION.medication.v1", + "openEHR-EHR-ITEM_TREE.medication.v1", + "openEHR-EHR-ITEM_TREE.medication_mod.v1", + "openEHR-EHR-SECTION.medications.v1", + "openEHR-EHR-ITEM_TREE.medication_test_one.v1", + "openEHR-EHR-ITEM_TREE.medication_test_three.v1", + "openEHR-EHR-ITEM_TREE.medication_multiple_constraint_test.v1", + "openEHR-EHR-ITEM_TREE.medication_multiple_constraint_test2.v1", + "openEHR-EHR-SECTION.ad_hoc_heading.v1", + "openEHR-EHR-SECTION.simple_section_name.v1", + "openEHR-EHR-COMPOSITION.test.v1", + "openEHR-EHR-EVALUATION.structured_summary.v1", + "openEHR-EHR-EVALUATION.review_of_procedures.v1", + "openEHR-EHR-ACTION.medication.v1", + "openEHR-EHR-ITEM_TREE.medication.v1", + "openEHR-EHR-ITEM_TREE.medication_quantity_test.v1", + "openEHR-EHR-ITEM_TREE.medication_quantity_test2.v1", + "openEHR-EHR-OBSERVATION.waist_hip.v2", + "openEHR-EHR-OBSERVATION.lab_test.v1", + "openEHR-EHR-OBSERVATION.heart_failure_stage.v2", + "openEHR-EHR-EVALUATION.medication_review.v1" + }; + + archetypeMap = new HashMap(); + + for(String id : ids) { + Archetype archetype = loadArchetype(id + ".adl"); + archetypeMap.put(archetype.getArchetypeId().toString(), archetype); + } + } + + /** + * Print out given archetype in ADL for debugging purpose + * + * @param toPrint + * @throws Exception + */ + protected void printADL(Archetype toPrint) throws Exception { + serializer.output(toPrint, System.out); + } + + /** + * Print out given archetype in XML for debugging purpose + * + * @param toPrint + * @throws Exception + */ + protected void printXML(Object toPrint) throws Exception { + XStream xstream = new XStream(); + String xml = xstream.toXML(toPrint); + System.out.println(xml); + } + + protected String toXML(Archetype toPrint) throws Exception { + XStream xstream = new XStream(); + String xml = xstream.toXML(toPrint); + return xml; + } + + protected void writeXML(Archetype archetype, String filename) + throws Exception { + FileUtils.writeStringToFile(new File(filename), toXML(archetype), "UTF-8"); + } + + protected void writeADL(Archetype archetype, String filename) + throws Exception { + + FileWriter writer = new FileWriter(filename); + try { + serializer.output(archetype, writer); + } finally { + writer.close(); + } + } + + /** + * Assert all c_objects and named c_attributed on the path are required + * + * @param pathvalue + * @throws Exception + */ + protected void assertTemplateLevelRequired(String key, String pathvalue) + throws Exception { + + // check the occurrences of c_object + assertSingleRequired(key, pathvalue); + + int i = pathvalue.lastIndexOf("/"); + if(pathvalue.endsWith("']")) { + int j = pathvalue.substring(0, pathvalue.length() - 2).lastIndexOf("'"); + if(j > 0 && i > j) { // '/' inside name + i = pathvalue.substring(0, i).lastIndexOf("/"); + } + } + String attr = pathvalue.substring(i + 1); + String newpath = null; + if(i > 0) { + newpath = pathvalue.substring(0, i); + } else { + newpath = "/"; + } + if(newpath.endsWith("name")) { + i = newpath.lastIndexOf("/"); + if(i > 0) { // name/value + attr = newpath.substring(i + 1) + attr; + newpath = newpath.substring(0, i); + } + } + i = attr.indexOf("["); + if(i > 0) { + attr = attr.substring(0, i); + } + + // check the existence and cardinality on c_attribute + CObject cobj = assertCObject(newpath); + if(cobj instanceof CComplexObject) { + CComplexObject ccobj = (CComplexObject) cobj; + CAttribute cattr = ccobj.getAttribute(attr); + if(cattr == null) { + fail("c_attribute of name " + attr + " not found on path: " + pathvalue); + } + assertTrue("unexpected optional attribute on path: " + cattr.path(), cattr.isRequired()); + + // No need to check cardinality + //if(cattr instanceof CMultipleAttribute) { + // CMultipleAttribute cma = (CMultipleAttribute) cattr; + // Cardinality cardinality = cma.getCardinality(); + // assertNotNull("unexpected null lower limit of cardinality on: " + // + pathvalue, cardinality.getInterval().getLower()); + // assertEquals("unexpected lower limit of cardinality on : " + // + pathvalue, 1, cardinality.getInterval().getLower().intValue()); + //} + } + + if( ! "/".equals(newpath)) { // recursive + assertTemplateLevelRequired(key, newpath); + } + } + + protected void assertTemplateLevelRequired(String path) throws Exception { + assertTemplateLevelRequired(null, path); + } + + protected void assertSingleRequired(String name, String path) throws Exception { + assertMaxOccurrences(name, path, 1); + assertMinOccurrences(name, path, 1); + } + + protected void assertMaxOccurrences(String name, String path, int max) throws Exception { + assertMaxOccurrences(null, path, max, flattened); + } + + protected void assertMaxOccurrences(String name, String path, int max, Archetype archetype) throws Exception { + CObject cobj = assertCObject(name, path, archetype); + assertNotNull("unexpected null maximum occurrences at path [" + name + "] "+ path, + cobj.getOccurrences().getUpper()); + assertEquals("unexpected maximum occurrences at path [" + name + "] "+ path, max, + cobj.getOccurrences().getUpper().intValue()); + } + + protected void assertMinOccurrences(String path, int min, Archetype archetype) throws Exception { + assertMinOccurrences(null, path, min, archetype); + } + + protected void assertMinOccurrences(String name, String path, int min, Archetype archetype) throws Exception { + CObject cobj = assertCObject(path, archetype); + assertNotNull("unexpected null minimum occurrences at path [" + name + "] "+ path, + cobj.getOccurrences().getLower()); + assertEquals("unexpected minimum occurrences at path [" + name + "] "+ path, min, + cobj.getOccurrences().getLower().intValue()); + } + + protected void assertMinOccurrences(String name, String path, int min) throws Exception { + assertMinOccurrences(name, path, min, flattened); + } + + + + /* static constant fields */ + protected static final String COMPOSITION = "COMPOSITION"; + protected static final String SECTION = "SECTION"; + protected static final String EVALUATION = "EVALUATION"; + protected static final String OBSERVATION = "OBSERVATION"; + protected static final String INSTRUCTION = "INSTRUCTION"; + protected static final String ACTIVITY = "ACTIVITY"; + protected static final String ACTION = "ACTION"; + protected static final String ITEM_TREE = "ITEM_TREE"; + protected static final String ITEM_LIST = "ITEM_LIST"; + protected static final String ELEMENT = "ELEMENT"; + protected static final String DV_TEXT = "DV_TEXT"; + protected static final String DV_COUNT = "DV_COUNT"; + protected static final String DV_CODED_TEXT = "DV_CODED_TEXT"; + + + /* path for test fixtures */ + private static final String ARCHETYPE_PATH = "archetypes/"; + private static final String TEMPLATE_PATH = "templates/"; + + /* member fields */ + protected TEMPLATE template; + protected OETParser parser; + protected Flattener flattener; + protected ADLSerializer serializer; + protected Map archetypeMap; + protected Map templateMap; + protected Archetype flattened; + protected Archetype archetype; + protected Archetype expected; + + private static final Logger log = Logger.getLogger(TemplateTestBase.class); +} 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 new file mode 100644 index 00000000..f478fd8f --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/TermMapTest.java @@ -0,0 +1,31 @@ +package org.openehr.am.template; + +public class TermMapTest extends TemplateTestBase { + + public void testWriteTermMap() throws Exception { + flattenTemplate("test_text_constraints.oet"); + flattener.getTermMap().writeTermMap("term_map.txt"); + } + + public void testLoadTermMapAndGetTerms() throws Exception { + TermMap termMap = TermMap.load(fromClasspath("terms_path.txt")); + + assertEquals("unexpected total terminologies", 2, + termMap.countTerminologies()); + + String path = "/path1"; + assertEquals("Sotalol", termMap.getText("ATC::C07AA07", path)); + assertEquals("Thiazider", termMap.getText("SNOMED-CT::10019", path)); + } + + public void testLoadTermMapAndGetTermsWithoutPath() throws Exception { + TermMap termMap = TermMap.load(fromClasspath("terms.txt")); + + assertEquals("unexpected total terminologies", 2, + termMap.countTerminologies()); + + String path = "/any/path"; + assertEquals("Sotalol", termMap.getText("ATC::C07AA07", path)); + assertEquals("Thiazider", termMap.getText("SNOMED-CT::10019", path)); + } +} 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 new file mode 100644 index 00000000..83ef2f1b --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/TextConstraintTest.java @@ -0,0 +1,187 @@ +package org.openehr.am.template; + +import java.util.*; + +import openEHR.v1.template.Statement; +import openEHR.v1.template.TextConstraint; + +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.CObject; + +public class TextConstraintTest extends TemplateTestBase { + + public void setUp() throws Exception { + super.setUp(); + + archetype = loadArchetype( + "openEHR-EHR-ITEM_TREE.medication_test_one.v1.adl"); + + constraint = archetype.node(PATH); + + rule = Statement.Factory.newInstance(); + rule.setPath(PATH); + } + + // + public void testSetDefaultTextConstraint() throws Exception { + String defaultValue = "Ipren"; + flattener.applyDefaultValueConstraint(constraint, defaultValue); + + archetype.reloadNodeMaps(); + constraint = archetype.node(PATH + "/value/value"); + assertCStringWithDefaultValue(constraint, defaultValue); + } + + // test the combination of coded_text and name constraint + // which triggered a bug once + public void testSetDefaultCodedTextAndName() throws Exception { + flattenTemplate("test_default_coded_name.oet"); + + constraint = flattened.node("/data[at0001]/items[at0002]/items" + + "[at0003 and name/value='Dose Units']/value"); + assertCCodePhraseWithDefaultValue(constraint, "SNOMED-CT", "258835005"); + + constraint = flattened.node("/data[at0001]/items[at0002]/items" + + "[at0003 and name/value='Dose Units']/name/value"); + assertCStringWithSingleValue(constraint, "Dose Units"); + } + + public void testTermMapAfterSetDefaultCodedTextAndName() throws Exception { + flattenTemplate("test_default_coded_name.oet"); + String path = "/data[at0001]/items[at0002]/items" + + "[at0003 and name/value='Dose Units']/value"; + constraint = flattened.node(path); + assertCCodePhraseWithDefaultValue(constraint, "SNOMED-CT", "258835005"); + + TermMap termMap = flattener.getTermMap(); + assertEquals(1, termMap.countTerminologies()); + assertEquals("units", termMap.getText("SNOMED-CT", "258835005", path)); + } + + // + + public void testSetDefaultCodedTextConstraint() throws Exception { + String defaultValue = "SNOMED-CT::258835005::mg/dygn"; + flattener.applyDefaultValueConstraint(constraint, defaultValue); + + archetype.reloadNodeMaps(); + constraint = archetype.node(PATH + "/value"); + assertCCodePhraseWithDefaultValue(constraint, "SNOMED-CT", "258835005"); + } + + // + // + // SNOMED-CT::10036::Nej + // SNOMED-CT::10035::Ja + // SNOMED-CT::10037::Ok�nt + // + // + public void testSetTextConstraintWithCodedIncludedValues() throws Exception { + TextConstraint tc = TextConstraint.Factory.newInstance(); + tc.addIncludedValues("SNOMED-CT::10036::Nej"); + tc.addIncludedValues("SNOMED-CT::10035::Ja"); + tc.addIncludedValues("SNOMED-CT::10037::Uknown"); + rule.setConstraint(tc); + + ccobj = (CComplexObject) constraint; + flattener.applyValueConstraint(archetype, ccobj, rule); + + archetype.reloadNodeMaps(); + constraint = archetype.node(PATH + "/value/defining_code"); + String[] expectedCodes = { "10036", "10035", "10037" }; + List codeList = Arrays.asList(expectedCodes); + assertCCodePhraseWithCodeList(constraint, "SNOMED-CT", codeList); + } + + public void testAggregatedTermMapAfterSetCodedIncludedValues() throws Exception { + TextConstraint tc = TextConstraint.Factory.newInstance(); + tc.addIncludedValues("SNOMED-CT::10036::Nej"); + tc.addIncludedValues("SNOMED-CT::10035::Ja"); + tc.addIncludedValues("SNOMED-CT::10037::Uknown"); + rule.setConstraint(tc); + + ccobj = (CComplexObject) constraint; + flattener.applyValueConstraint(archetype, ccobj, rule); + TermMap termMap = flattener.getTermMap(); + assertEquals(1, termMap.countTerminologies()); + String path = ccobj.path() + "/value"; + assertEquals("Nej", termMap.getText("SNOMED-CT", "10036", path)); + } + + public void testExistingTypesRemovedAfterSetTextConstraint() throws Exception { + archetype = loadArchetype( + "openEHR-EHR-ITEM_TREE.medication_test_one.v2.adl"); + constraint = archetype.node(PATH); + + TextConstraint tc = TextConstraint.Factory.newInstance(); + tc.addIncludedValues("SNOMED-CT::10036::Nej"); + rule.setConstraint(tc); + + ccobj = (CComplexObject) constraint; + flattener.applyValueConstraint(archetype, ccobj, rule); + archetype.reloadNodeMaps(); + constraint = archetype.node(PATH); + CComplexObject cobj = (CComplexObject) constraint; + CAttribute cattr = cobj.getAttribute("value"); + assertEquals("unexpected multiple children", 1, + cattr.getChildren().size()); + } + + public void testSetNameAndDefaultOnCodedTextNode() throws Exception { + + // bug on set the following on dv_coded_text + // + archetype = loadArchetype( + "openEHR-EHR-ITEM_TREE.medication_test_two.v1.adl"); + + rule.setDefault("SNOMED-CT::258835005::mg/dygn"); + rule.setName("dosenhet"); + + flattener.applyRule(archetype, rule); + archetype.reloadNodeMaps(); + + // verify default value + constraint = archetype.node("/items" + + "[at0001 and name/value='dosenhet']/value"); + assertCCodePhraseWithDefaultValue(constraint, "SNOMED-CT", "258835005"); + + // verify the original dv_coded_text is gone + CComplexObject cobj = (CComplexObject) archetype.node("/items" + + "[at0001 and name/value='dosenhet']"); + CAttribute attr = cobj.getAttribute("value"); + assertEquals("unexpected duplicated child", 1, attr.getChildren().size()); + + // verify name + constraint = archetype.node("/items" + + "[at0001 and name/value='dosenhet']/name/value"); + assertCStringWithSingleValue(constraint, "dosenhet"); + } + + public void testSetTextConstraintWithExcludedValues() throws Exception { + archetype = loadArchetype( + "openEHR-EHR-ADMIN_ENTRY.heart_failure_contact.v1.adl"); + String path = "/data[at0001]/items[at0009]/items[at0010]"; + constraint = archetype.node(path); + + TextConstraint tc = TextConstraint.Factory.newInstance(); + tc.addExcludedValues("local::at0022"); + rule.setConstraint(tc); + + ccobj = (CComplexObject) constraint; + flattener.applyValueConstraint(archetype, ccobj, rule); + + archetype.reloadNodeMaps(); + constraint = archetype.node(path + "/value/defining_code" ); + String[] expectedCodes = { "at0020", "at0021"}; + List codeList = Arrays.asList(expectedCodes); + assertCCodePhraseWithCodeList(constraint, "local", codeList); + } + + private static final String PATH = "/items[at0001]"; + private Statement rule; + private ArchetypeConstraint constraint; + private CComplexObject ccobj; +} 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 new file mode 100644 index 00000000..0bc19a0e --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/UTF8EncodingTest.java @@ -0,0 +1,30 @@ +package org.openehr.am.template; + +import java.nio.charset.Charset; + +import org.openehr.am.archetype.constraintmodel.ArchetypeConstraint; +import org.openehr.am.archetype.constraintmodel.primitive.CString; + +public class UTF8EncodingTest extends TemplateTestBase { + + public void setUp() throws Exception { + super.setUp(); + + archetype = loadArchetype( + "openEHR-EHR-ITEM_TREE.medication_test_one.v1.adl"); + } + + public void testSwedishSpecialChars() throws Exception { + flattenTemplate("test_utf8_encoding.oet"); + + constraint = flattened.node("/data[at0001]/items[at0002]/" + + "items[at0003]/value/value"); + + CString cs = assertCString(constraint); + + // compare to string value "åäö" in unicode + assertCStringWithDefaultValue(constraint, "\u00e5\u00e4\u00f6"); + } + + private ArchetypeConstraint constraint; +} 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 new file mode 100644 index 00000000..d8541aeb --- /dev/null +++ b/oet-parser/src/test/java/org/openehr/am/template/UtilityTest.java @@ -0,0 +1,49 @@ + package org.openehr.am.template; + +import org.openehr.am.archetype.constraintmodel.CComplexObject; + +public class UtilityTest extends TemplateTestBase { + + public void testNextNodeId() throws Exception { + assertEquals("at0001", flattener.formatNodeId(1)); + assertEquals("at0010", flattener.formatNodeId(10)); + assertEquals("at0100", flattener.formatNodeId(100)); + assertEquals("at1000", flattener.formatNodeId(1000)); + assertEquals("at9999", flattener.formatNodeId(9999)); + assertEquals("at10000", flattener.formatNodeId(10000)); + assertEquals("at100000", flattener.formatNodeId(100000)); + } + + public void testParseNodeId() throws Exception { + assertEquals(1, flattener.parseNodeId("at0001")); + assertEquals(10, flattener.parseNodeId("at0010")); + assertEquals(100, flattener.parseNodeId("at0100")); + assertEquals(1000, flattener.parseNodeId("at1000")); + assertEquals(9999, flattener.parseNodeId("at9999")); + assertEquals(10000, flattener.parseNodeId("at10000")); + assertEquals(1, flattener.parseNodeId("at0001.1")); + assertEquals(100, flattener.parseNodeId("at0100.2")); + } + + public void testFindLargestNodeId() throws Exception { + archetype = loadArchetype("openEHR-EHR-SECTION.find_largest_node_id.v1.adl"); + assertEquals(4, flattener.findLargestNodeId(archetype)); + } + + public void testFindLargestNodeId2() throws Exception { + archetype = loadArchetype("openEHR-EHR-SECTION.find_largest_node_id_2.v1.adl"); + assertEquals(10, flattener.findLargestNodeId(archetype)); + } + + public void testAdjustNodeIds() throws Exception { + archetype = loadArchetype("openEHR-EHR-EVALUATION.structured_summary.v1.adl"); + expected = loadArchetype("openEHR-EHR-EVALUATION.adjusted_node_ids.v1.adl"); + + CComplexObject root = archetype.getDefinition(); + long count = flattener.adjustNodeIds(root, 10); + + assertEquals("Unexpected total adjusted nodeIds", 15, count); + assertCComplexObjectEquals("failed to adjust nodeIds", + expected.getDefinition(), root); + } +} 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 new file mode 100644 index 00000000..e0b166ce --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ACTION.medication.v1.adl @@ -0,0 +1,319 @@ +archetype (adl_version=1.4) + openEHR-EHR-ACTION.medication.v1 + +concept + [at0000] -- Medication action +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"Sam Heard"> + ["organisation"] = <"Ocean Informatics"> + ["email"] = <"sam.heard@oceaninformatics.com"> + ["date"] = <"23/03/2006"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"This ACTION enables the recording of actions taken with regard to medication. This will usually be in response to a medication order or prescription, but may be self administered or supplied by a pharmacy. There is no timing information as use of this archetype indicates that some action has actually occurred."> + use = <""> + misuse = <""> + copyright = <"copyright (c) 2009 openEHR Foundation"> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <> + other_details = < + ["references"] = <""> + > + +definition + ACTION[at0000] matches { -- Medication 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]} -- Plan + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::527]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0013]} -- Plan suspended + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::528]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0012]} -- Cancelled + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::529]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0016]} -- Start time set + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches { + [openehr:: + 245, + 524] + } + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0002]} -- Prescribe + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches { + [openehr:: + 245, + 524] + } + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0003]} -- Dispense + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::245]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0004]} -- Commence administration + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::245]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0005]} -- Review + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::245]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0006]} -- Administer (point in time) + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::245]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0010]} -- Re-issue prescription + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::530]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0008]} -- Delayed supply + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::530]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0009]} -- Suspended administration + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::530]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0011]} -- Suspended re-order + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::531]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0015]} -- Cancelled administration + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::531]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0014]} -- Cancelled prescription + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::532]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0007]} -- Completed + } + } + } + } + description matches { + allow_archetype ITEM_TREE matches { + include + archetype_id/value matches {/openEHR-EHR-ITEM_TREE\.medication\.v1|openEHR-EHR-ITEM_TREE\.medication-vaccine\.v1/} + exclude + archetype_id/value matches {/.*/} + } + } + } + + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication action"> + description = <"An action arising from a medication order created by a clinician which specifies which medication to take, when, for how long etc."> + > + ["at0001"] = < + text = <"Plan"> + description = <"The medication is planned but no execution has taken place"> + > + ["at0002"] = < + text = <"Prescribe"> + description = <"The order has been transfered to the dispensary"> + > + ["at0003"] = < + text = <"Dispense"> + description = <"The medication has been dispensed"> + > + ["at0004"] = < + text = <"Commence administration"> + description = <"The medication has been taken by the patient"> + > + ["at0005"] = < + text = <"Review"> + description = <"The medication has been reviewed"> + > + ["at0006"] = < + text = <"Administer (point in time)"> + description = <"The medication has been administered"> + > + ["at0007"] = < + text = <"Completed"> + description = <"The medication has been completed as prescribed"> + > + ["at0008"] = < + text = <"Delayed supply"> + description = <"The medication will not been dispensed as supply is not available"> + > + ["at0009"] = < + text = <"Suspended administration"> + description = <"The administration of the medication has been suspended"> + > + ["at0010"] = < + text = <"Re-issue prescription"> + description = <"The medication has been re-ordered or prescribed"> + > + ["at0011"] = < + text = <"Suspended re-order"> + description = <"Reordering of this medication is not available"> + > + ["at0012"] = < + text = <"Cancelled"> + description = <"The planned administration has been cancelled"> + > + ["at0013"] = < + text = <"Plan suspended"> + description = <"The plan to order medication has been suspended"> + > + ["at0014"] = < + text = <"Cancelled prescription"> + description = <"The prescription has been cancelled"> + > + ["at0015"] = < + text = <"Cancelled administration"> + description = <"The administration has been cancelled"> + > + ["at0016"] = < + text = <"Start time set"> + description = <"The time to start this medication has been set"> + > + > + > + > 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 new file mode 100644 index 00000000..edc82aa1 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ADMIN_ENTRY.heart_failure_contact.v1.adl @@ -0,0 +1,281 @@ +archetype (adl_version=1.4) + openEHR-EHR-ADMIN_ENTRY.heart_failure_contact.v1 + +concept + [at0000] -- Heart Failure Contact +language + original_language = <[ISO_639-1::sv]> +description + original_author = < + ["name"] = <"Rong Chen"> + ["date"] = <"10/18/2009"> + > + details = < + ["sv"] = < + language = <[ISO_639-1::sv]> + purpose = <"Heart Failure Contact"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"B3F75F27B4DC94A69659DBAF31F92C03"> + > + +definition + ADMIN_ENTRY[at0000] matches { -- Heart Failure Contact + data matches { + ITEM_TREE[at0001] matches { -- Tree + items cardinality matches {2..*; ordered} matches { + CLUSTER[at0009] matches { -- Inskrivning + items cardinality matches {8; ordered} matches { + ELEMENT[at0010] matches { -- Vårdgivare + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0020, -- Slutenvård + at0021, -- Enskilt öppenvårdbesök hos läkare + at0022] -- Sviktmottagning (besök vårdteam) + } + } + } + } + ELEMENT[at0040] occurrences matches {0..1} matches { -- Klinik + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0041, -- Medicinklinik + at0042, -- Kardiologklinik + at0043] -- Geriatrisk klinik + } + } + } + } + ELEMENT[at0011] matches { -- Orsak till inläggning / besök + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0044, -- Förvärrad hjärtsvikt + at0045, -- Nydebuterad hjärtsvikt + at0046] -- Oförändrad hjärtsvikt (rutinbesök) + } + } + } + } + ELEMENT[at0012] matches { -- Utlösande faktorer + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0047, -- Ischemi + at0048, -- Arytmi + at0049, -- Annan kardiovaskulär orsak + at0050, -- Annat + at0051] -- Okänt + } + } + } + } + ELEMENT[at0013] matches { -- Tidigare vårdtillfälle/inläggning för hjärtsvikt + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0034, -- Ja >= 6 mån + at0035, -- Ja < 6 mån + at0036, -- Nej + at0037] -- Okänt + } + } + } + } + ELEMENT[at0014] matches { -- Duration av hjärtsvikt + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0038, -- < 6mån + at0039] -- >= 6mån + } + } + } + } + ELEMENT[at0015] matches { -- Inskrivnings-/besöksdatum + value matches { + DV_DATE matches { + value matches {yyyy-mm-dd} + } + } + } + ELEMENT[at0016] occurrences matches {0..1} matches { -- Utskrivningsdatum + value matches { + DV_DATE matches { + value matches {yyyy-mm-dd} + } + } + } + } + } + } + } + } + } + +ontology + terminologies_available = <"SNOMED-CT", ...> + term_definitions = < + ["sv"] = < + items = < + ["at0000"] = < + text = <"Heart Failure Contact"> + description = <"Administrative and demographic information required by the quality report"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0009"] = < + text = <"Inskrivning"> + description = <"Inskrivning"> + > + ["at0010"] = < + text = <"Vårdgivare"> + description = <"Vårdgivare"> + > + ["at0011"] = < + text = <"Orsak till inläggning / besök"> + description = <"Orsak till inläggning / besök"> + > + ["at0012"] = < + text = <"Utlösande faktorer"> + description = <"Utlösande faktorer"> + > + ["at0013"] = < + text = <"Tidigare vårdtillfälle/inläggning för hjärtsvikt"> + description = <"Tidigare vårdtillfälle/inläggning för hjärtsvikt"> + > + ["at0014"] = < + text = <"Duration av hjärtsvikt"> + description = <"Duration av hjärtsvikt"> + > + ["at0015"] = < + text = <"Inskrivnings-/besöksdatum"> + description = <"Inskrivnings-/besöksdatum"> + > + ["at0016"] = < + text = <"Utskrivningsdatum"> + description = <"Utskrivningsdatum"> + > + ["at0020"] = < + text = <"Slutenvård"> + description = <"Slutenvård"> + > + ["at0021"] = < + text = <"Enskilt öppenvårdbesök hos läkare"> + description = <"Enskilt öppenvårdbesök hos läkare"> + > + ["at0022"] = < + text = <"Sviktmottagning (besök vårdteam)"> + description = <"Sviktmottagning (besök vårdteam)"> + > + ["at0034"] = < + text = <"Ja >= 6 mån"> + description = <"Ja >= 6 mån"> + > + ["at0035"] = < + text = <"Ja < 6 mån"> + description = <"Ja < 6 mån"> + > + ["at0036"] = < + text = <"Nej"> + description = <"Nej"> + > + ["at0037"] = < + text = <"Okänt"> + description = <"Okänt"> + > + ["at0038"] = < + text = <"< 6mån"> + description = <"< 6mån"> + > + ["at0039"] = < + text = <">= 6mån"> + description = <">= 6mån"> + > + ["at0040"] = < + text = <"Klinik"> + description = <"Klinik"> + > + ["at0041"] = < + text = <"Medicinklinik"> + description = <"Medicinklinik"> + > + ["at0042"] = < + text = <"Kardiologklinik"> + description = <"Kardiologklinik"> + > + ["at0043"] = < + text = <"Geriatrisk klinik"> + description = <"Geriatrisk klinik"> + > + ["at0044"] = < + text = <"Förvärrad hjärtsvikt"> + description = <"Förvärrad hjärtsvikt"> + > + ["at0045"] = < + text = <"Nydebuterad hjärtsvikt"> + description = <"Nydebuterad hjärtsvikt"> + > + ["at0046"] = < + text = <"Oförändrad hjärtsvikt (rutinbesök)"> + description = <"Oförändrad hjärtsvikt (rutinbesök)"> + > + ["at0047"] = < + text = <"Ischemi"> + description = <"Ischemi"> + > + ["at0048"] = < + text = <"Arytmi"> + description = <"Arytmi"> + > + ["at0049"] = < + text = <"Annan kardiovaskulär orsak"> + description = <"Annan kardiovaskulär orsak"> + > + ["at0050"] = < + text = <"Annat"> + description = <"Annat"> + > + ["at0051"] = < + text = <"Okänt"> + description = <"Okänt"> + > + > + > + > + term_bindings = < + ["SNOMED-CT"] = < + items = < + ["at0020"] = <[SNOMED-CT::10118]> + ["at0021"] = <[SNOMED-CT::10119]> + ["at0022"] = <[SNOMED-CT::10120]> + ["at0041"] = <[SNOMED-CT::309912009]> + ["at0042"] = <[SNOMED-CT::309915006]> + ["at0043"] = <[SNOMED-CT::309933000]> + ["at0044"] = <[SNOMED-CT::10078]> + ["at0045"] = <[SNOMED-CT::10079]> + ["at0046"] = <[SNOMED-CT::10080]> + ["at0047"] = <[SNOMED-CT::414795007]> + ["at0048"] = <[SNOMED-CT::44808001]> + ["at0049"] = <[SNOMED-CT::10116]> + ["at0050"] = <[SNOMED-CT::10117]> + ["at0051"] = <[SNOMED-CT::3219008]> + > + > + > 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 new file mode 100644 index 00000000..d3a2785a --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-COMPOSITION.prescription.v1.adl @@ -0,0 +1,97 @@ +archetype (adl_version=1.4) + openEHR-EHR-COMPOSITION.prescription.v1 + +concept + [at0000] -- Prescription +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"Sam Heard"> + ["organisation"] = <"Ocean Informatics"> + ["date"] = <"23/03/2006"> + ["email"] = <"sam.heard@oceaninformatics.com"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"A composition for transfering medication orders to the pharmacy."> + use = <"This composition is only required for transfer of medications to the pharmacy."> + keywords = <"medication", "prescribe", "order"> + misuse = <"Medication orders, as instructions, have a prescribe action that records prescription and communication to the pharmacy. This composition is only required if the medication orders are required to be transmitted within openEHR to the pharmacy."> + copyright = <"copyright (c) 2008 openEHR Foundation"> + > + > + lifecycle_state = <"Initial"> + other_contributors = <> + +definition + COMPOSITION[at0000] matches { -- Prescription + category matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::433]} + } + } + context matches { + EVENT_CONTEXT matches { + other_context matches { + ITEM_TREE[at0001] matches { -- Tree + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0002] occurrences matches {0..1} matches { -- Prescription category + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0003, -- PBS + at0004, -- RPBS + at0005] -- Private + } + } + } + } + } + } + } + } + } + content cardinality matches {0..*; unordered} matches { + allow_archetype SECTION matches { + include + archetype_id/value matches {/medications\.v1/} + exclude + archetype_id/value matches {/.*/} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Prescription"> + description = <"Set of medication orders communicated to pharmacy"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Prescription category"> + description = <"Australian prescription category"> + > + ["at0003"] = < + text = <"PBS"> + description = <"Australian pharmaceutical benefits scheme"> + > + ["at0004"] = < + text = <"RPBS"> + description = <"Repatriation pharmaceutical benefits scheme (ADF)"> + > + ["at0005"] = < + text = <"Private"> + description = <"Entire cost met by patient or agent"> + > + > + > + > 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 new file mode 100644 index 00000000..fe6654b0 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-COMPOSITION.prescription_flattened.v1.adl @@ -0,0 +1,713 @@ +archetype (adl_version=1.4) + openEHR-EHR-COMPOSITION.prescription_flattened.v1 + +concept + [at0000] -- Prescription (flattened) +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"Rong Chen"> + ["organisation"] = <"Cambio Healthcare Systems"> + ["date"] = <"23/07/2009"> + ["email"] = <"rong.chen@cambio.se"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"testing purpose"> + use = <"testing"> + keywords = <"medication", "prescribe", "order"> + misuse = <"Medication orders, as instructions"> + copyright = <"copyright (c) 2009 openEHR Foundation"> + > + > + lifecycle_state = <"Initial"> + other_contributors = <> + +definition + COMPOSITION[at0000] matches { -- Prescription + category matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::433]} + } + } + context matches { + EVENT_CONTEXT matches { + other_context matches { + ITEM_TREE[at0001] matches { -- Tree + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0002] occurrences matches {0..1} matches { -- Prescription category + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0003, -- PBS + at0004, -- RPBS + at0005] -- Private + } + } + } + } + } + } + } + } + } + content cardinality matches {0..*; unordered} matches { + SECTION[at0000] matches { -- Medications + items cardinality matches {0..*; unordered} matches { + INSTRUCTION[at0000] matches { -- Medication order + activities cardinality matches {0..*; unordered} matches { + ACTIVITY[at0001] occurrences matches {0..*} matches { -- Medication activity + action_archetype_id matches {/medication\.v1/} + description matches { + ITEM_TREE[at0000] occurrences matches {0..*} matches { -- Medication description + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0001] matches { -- Name of medication + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0012] occurrences matches {0..1} matches { -- Generic name + name matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0003]} -- =Generic name OR Brand name + } + } + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0003] occurrences matches {0..1} matches { -- Strength per dose unit + value matches { + C_DV_QUANTITY < + property = <[openehr::124]> + list = < + ["1"] = < + units = <"pg"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"µg"> + magnitude = <|>=0.0|> + > + ["3"] = < + units = <"mg"> + magnitude = <|>=0.0|> + > + ["4"] = < + units = <"gm"> + magnitude = <|>=0.0|> + > + > + > + C_DV_QUANTITY < + property = <[openehr::385]> + list = < + ["1"] = < + units = <"IU"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"mIU"> + magnitude = <|>=0.0|> + > + > + > + C_DV_QUANTITY < + property = <[openehr::445]> + list = < + ["1"] = < + units = <"mU"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"U"> + magnitude = <|>=0.0|> + > + > + > + } + } + ELEMENT[at0006] matches { -- Dose unit + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0001]} -- any term that 'is a' Dose unit for this form + } + } + } + ELEMENT[at0004] occurrences matches {0..1} matches { -- Form + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' form of medication + } + } + } + CLUSTER[at0033] occurrences matches {0..1} matches { -- Dose + items cardinality matches {1; unordered} matches { + CLUSTER[at0035] occurrences matches {0..1} matches { -- By absolute quantity + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0036] occurrences matches {1..2} matches { -- Quantity by volume + value matches { + C_DV_QUANTITY < + property = <[openehr::129]> + list = < + ["1"] = < + units = <"ml"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"l"> + magnitude = <|>=0.0|> + > + > + > + DV_INTERVAL matches { + upper matches { + C_DV_QUANTITY < + property = <[openehr::129]> + list = < + ["1"] = < + units = <"ml"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"l"> + magnitude = <|>=0.0|> + > + > + > + } + lower matches { + C_DV_QUANTITY < + property = <[openehr::129]> + list = < + ["1"] = < + units = <"ml"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"l"> + magnitude = <|>=0.0|> + > + > + > + } + } + } + } + ELEMENT[at0037] occurrences matches {0..1} matches { -- Quantity by mass + value matches { + C_DV_QUANTITY < + property = <[openehr::124]> + list = < + ["1"] = < + units = <"µg"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"mg"> + > + ["3"] = < + units = <"gm"> + > + > + > + DV_INTERVAL matches { + upper matches { + C_DV_QUANTITY < + property = <[openehr::124]> + list = < + ["1"] = < + units = <"µg"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"mg"> + magnitude = <|>=0.0|> + > + ["3"] = < + units = <"gm"> + magnitude = <|>=0.0|> + > + > + > + } + lower matches { + C_DV_QUANTITY < + property = <[openehr::124]> + list = < + ["1"] = < + units = <"µg"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"mg"> + magnitude = <|>=0.0|> + > + ["3"] = < + units = <"gm"> + magnitude = <|>=0.0|> + > + > + > + } + } + } + } + } + } + CLUSTER[at0034] occurrences matches {0..1} matches { -- By dose units + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0005] matches { -- Number or fraction + value matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + DV_INTERVAL matches { + upper matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + } + lower matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + } + } + DV_PROPORTION matches { + numerator matches {|>=1.0|} + denominator matches {|1.0..4.0|} + type matches {1, 2, 4} + } + } + } + } + } + } + } + ELEMENT[at0007] occurrences matches {0..1} matches { -- Dose duration + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"d"> + > + ["2"] = < + units = <"h"> + > + ["3"] = < + units = <"min"> + > + ["4"] = < + units = <"s"> + magnitude = <|>=0.0|> + > + > + > + } + } + ELEMENT[at0008] occurrences matches {0..1} matches { -- Route + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0002]} -- Any term that 'is_a' route of administration + } + } + } + CLUSTER[at0057] occurrences matches {0..1} matches { -- Timing + items cardinality matches {0..*; unordered} matches { + CLUSTER[at0061] occurrences matches {0..1} matches { -- Approximate + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0052] occurrences matches {0..1} matches { -- Frequency + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0053, -- Once + at0054, -- Twice + at0055, -- Three times + at0056, -- Four times + at0058] -- Five times + } + } + DV_CODED_TEXT matches { + defining_code matches {[ac0005]} -- Frequency + } + } + } + ELEMENT[at0059] occurrences matches {0..1} matches { -- Unit time + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"a"> + > + ["2"] = < + units = <"d"> + > + ["3"] = < + units = <"h"> + > + ["4"] = < + units = <"min"> + > + ["5"] = < + units = <"mo"> + > + ["6"] = < + units = <"wk"> + > + > + > + } + } + } + } + CLUSTER[at0062] occurrences matches {0..1} matches { -- Exact + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0063] occurrences matches {0..1} matches { -- Exact time of administration + value matches { + DV_DATE_TIME matches { + value matches {yyyy-??-??T??:??:??} + } + } + } + } + } + CLUSTER[at0064] occurrences matches {0..1} matches { -- Relative + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0065] occurrences matches {0..1} matches { -- Timing + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"a"> + > + ["2"] = < + units = <"d"> + > + ["3"] = < + units = <"h"> + > + ["4"] = < + units = <"mo"> + > + ["5"] = < + units = <"s"> + > + ["6"] = < + units = <"min"> + > + ["7"] = < + units = <"wk"> + > + > + > + } + } + ELEMENT[at0066] occurrences matches {0..1} matches { -- Qualifier + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0068, -- before + at0069, -- after + at0070, -- with + at0073] -- at + } + } + } + } + ELEMENT[at0067] occurrences matches {0..1} matches { -- Event + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + ELEMENT[at0060] occurrences matches {0..1} matches { -- Instruction qualifiers + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0050] occurrences matches {0..1} matches { -- Reason for commencement + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0051] occurrences matches {0..1} matches { -- Reason for ceasing + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0009] occurrences matches {0..1} matches { -- Is long term + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + CLUSTER[at0010] occurrences matches {0..1} matches { -- Indications + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0011] occurrences matches {0..*} matches { -- Indication + value matches { + DV_TEXT matches {*} + DV_URI matches {*} + } + } + } + } + CLUSTER[at0013] occurrences matches {0..1} matches { -- Safety limits + items cardinality matches {1..4; ordered} matches { + ELEMENT[at0014] occurrences matches {0..1} matches { -- Maximum dose unit frequency + value matches { + C_DV_QUANTITY < + property = <[openehr::382]> + list = < + ["1"] = < + units = <"{QUALIFIED REAL/TIME}"> + magnitude = <|>0.0|> + > + > + assumed_value = < + precision = <-1> + magnitude = <0.0> + units = <"{QUALIFIED REAL/TIME}"> + > + > + } + } + ELEMENT[at0015] 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[at0016] occurrences matches {0..1} matches { -- Minimum dose interval + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"min"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"h"> + magnitude = <|>=0.0|> + > + ["3"] = < + units = <"d"> + magnitude = <|>=0.0|> + > + ["4"] = < + units = <"wk"> + magnitude = <|>=0.0|> + > + ["5"] = < + units = <"mo"> + magnitude = <|>=0.0|> + > + > + > + } + } + ELEMENT[at0017] occurrences matches {0..1} matches { -- Maximum dose interval + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"d"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"h"> + magnitude = <|>=0.0|> + > + ["3"] = < + units = <"min"> + magnitude = <|>=0.0|> + > + ["4"] = < + units = <"wk"> + magnitude = <|>=0.0|> + > + ["5"] = < + units = <"mo"> + magnitude = <|>=0.0|> + > + > + > + } + } + ELEMENT[at0002] occurrences matches {0..1} matches { -- Administration instructions + value matches { + DV_TEXT matches {*} + } + } + } + } + CLUSTER[at0018] occurrences matches {0..1} matches { -- Administration information + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0019] occurrences matches {0..1} matches { -- Date (time) of first administration + value matches { + DV_DATE_TIME matches { + value matches {yyyy-??-??T??:??:??} + } + } + } + ELEMENT[at0020] occurrences matches {0..1} matches { -- Batch number + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0021] occurrences matches {0..1} matches { -- Site of administration + value matches { + DV_CODED_TEXT matches { + defining_code matches {[local::]} + } + } + } + ELEMENT[at0022] occurrences matches {0..1} matches { -- Sequence number + value matches { + DV_COUNT matches {*} + } + } + ELEMENT[at0032] occurrences matches {0..1} matches { -- Date (time) of last administration + value matches { + DV_DATE_TIME matches { + value matches {yyyy-??-??T??:??:??} + } + } + } + } + } + CLUSTER[at0023] occurrences matches {0..1} matches { -- Dispensing information + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0024] occurrences matches {0..1} matches { -- Quantity to be dispensed + value matches { + C_DV_QUANTITY < + property = <[openehr::445]> + > + DV_COUNT matches { + magnitude matches {|>0|; 1} + } + DV_TEXT matches {*} + } + } + ELEMENT[at0025] occurrences matches {0..1} matches { -- Number of authorised repeat dispensing + value matches { + DV_COUNT matches { + magnitude matches {|>=0|} + } + } + } + ELEMENT[at0026] occurrences matches {0..1} matches { -- Dispensed product + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0027] occurrences matches {0..1} matches { -- Brand substitution allowed + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + ELEMENT[at0028] occurrences matches {0..1} matches { -- Authority approval number + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0029] occurrences matches {0..1} matches { -- Patient counselled on CMI + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + ELEMENT[at0030] occurrences matches {0..1} matches { -- Deferred supply + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + ELEMENT[at0031] occurrences matches {0..1} matches { -- Reason for deferred supply + value matches { + DV_TEXT matches {*} + } + } + } + } + CLUSTER[at0049] occurrences matches {0..1} matches { -- Admission information + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0048] occurrences matches {0..1} matches { -- Own Medication + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Prescription"> + description = <"Set of medication orders communicated to pharmacy"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Prescription category"> + description = <"Australian prescription category"> + > + ["at0003"] = < + text = <"PBS"> + description = <"Australian pharmaceutical benefits scheme"> + > + ["at0004"] = < + text = <"RPBS"> + description = <"Repatriation pharmaceutical benefits scheme (ADF)"> + > + ["at0005"] = < + text = <"Private"> + description = <"Entire cost met by patient or agent"> + > + > + > + > 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 new file mode 100644 index 00000000..43d76ff9 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-COMPOSITION.test.v1.adl @@ -0,0 +1,31 @@ +archetype (adl_version=1.4) + openEHR-EHR-COMPOSITION.test.v1 + +concept + [at0000] -- test +language + original_language = <[ISO_639-1::en]> + +definition + COMPOSITION[at0000] matches { -- template test + content cardinality matches {0..*; unordered} matches { + allow_archetype SECTION matches { + include + archetype_id/value matches {/medications\.v1/} + exclude + archetype_id/value matches {/.*/} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"test"> + description = <"test"> + > + > + > + > 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 new file mode 100644 index 00000000..a260fb0d --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-EVALUATION.adjusted_node_ids.v1.adl @@ -0,0 +1,61 @@ +archetype (adl_version=1.4) + openEHR-EHR-EVALUATION.adjusted_node_ids.v1 + +concept + [at0000] -- summary +language + original_language = <[ISO_639-1::sv]> + +definition + EVALUATION[at0011] matches { -- summary + data matches { + ITEM_TREE[at0012] matches { -- Träd + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0013] occurrences matches {0..1} matches { -- summary + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0014] occurrences matches {0..1} matches { -- total + value matches { + C_DV_QUANTITY < + > + } + } + ELEMENT[at0015] occurrences matches {0..1} matches { -- comment + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["sv"] = < + items = < + ["at0000"] = < + text = <"summary"> + description = <"Structured summary"> + > + ["at0001"] = < + text = <"Träd"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"summary"> + description = <"*"> + > + ["at0003"] = < + text = <"comment"> + description = <"*"> + > + ["at0005"] = < + text = <"total"> + description = <"*"> + > + > + > + > 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 new file mode 100644 index 00000000..d2b561cc --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-EVALUATION.hybrid_path_test.v1.adl @@ -0,0 +1,89 @@ +archetype (adl_version=1.4) + openEHR-EHR-EVALUATION.hybrid_path_test.v1 + +concept + [at0000] -- hand-made expected flattening reesult +language + original_language = <[ISO_639-1::sv]> + +definition + EVALUATION[at0000] matches { -- Genomgång av insatser + data matches { + ITEM_TREE[at0001] matches { -- Träd + items cardinality matches {0..*; unordered} matches { + CLUSTER[at0002] occurrences matches {0..*} matches { -- one + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0003] occurrences matches {0..1} matches { -- Typ av insats + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0004] occurrences matches {0..1} matches { -- Tidpunkt + value matches { + DV_DATE_TIME matches {*} + } + } + ELEMENT[at0005] occurrences matches {0..*} matches { -- Genomförandestatus + value matches { + DV_TEXT matches {*} + } + } + } + name matches { "one"} + } + CLUSTER[at0002] occurrences matches {0..*} matches { -- two + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0003] occurrences matches {0..1} matches { -- Typ av insats + value matches { + DV_CODED_TEXT matches {*} -- changed to different type to facilitate testing + } + } + ELEMENT[at0004] occurrences matches {0..1} matches { -- Tidpunkt + value matches { + DV_DATE_TIME matches {*} + } + } + ELEMENT[at0005] occurrences matches {0..*} matches { -- Genomförandestatus + value matches { + DV_TEXT matches {*} + } + } + } + name matches { "two"} + } + } + } + } + } + +ontology + term_definitions = < + ["sv"] = < + items = < + ["at0000"] = < + text = <"Genomgång av insatser"> + description = <"Review of a list of procedure in the same context"> + > + ["at0001"] = < + text = <"Träd"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Insats"> + description = <"*"> + > + ["at0003"] = < + text = <"Typ av insats"> + description = <"*"> + > + ["at0004"] = < + text = <"Tidpunkt"> + description = <"*"> + > + ["at0005"] = < + text = <"Genomförandestatus"> + description = <"*"> + > + > + > + > 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 new file mode 100644 index 00000000..09e200af --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-EVALUATION.medication_review.v1.adl @@ -0,0 +1,136 @@ +archetype (adl_version=1.4) + openEHR-EHR-EVALUATION.medication_review.v1 + +concept + [at0000] -- Medication Review +language + original_language = <[ISO_639-1::sv]> +description + original_author = < + ["name"] = <"Rong Chen"> + ["organisation"] = <"Cambio Healthcare Systems"> + ["email"] = <"rong.chen@cambio.se"> + ["date"] = <"4/22/2010"> + > + details = < + ["en"] = < + language = <[ISO_639-1::sv]> + purpose = <"Used for review of medications"> + use = <""> + misuse = <""> + > + ["sv"] = < + language = <[ISO_639-1::sv]> + purpose = <"This archetype should be used to record a structure summary of a given medication in the source EHR system"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"6408A16C059024B883AEC44670A78DBE"> + > + +definition + EVALUATION[at0000] matches { -- Medication Review + data matches { + ITEM_TREE[at0001] matches { -- Tree + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0002] occurrences matches {0..1} matches { -- Name + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0005] occurrences matches {0..1} matches { -- Status + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0003] occurrences matches {0..1} matches { -- Generic + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0004] occurrences matches {0..1} matches { -- Total dose + value matches { + C_DV_QUANTITY < + property = <[openehr::118]> + > + } + } + ELEMENT[at0006] occurrences matches {0..1} matches { -- Reason target dose not reached + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0007] occurrences matches {0..1} matches { -- Reason medicine not given + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0008] occurrences matches {0..1} matches { -- Base daily dose + value matches { + C_DV_QUANTITY < + > + } + } + ELEMENT[at0009] occurrences matches {0..1} matches { -- Extra dose when needed + value matches { + C_DV_QUANTITY < + > + } + } + } + } + } + } + +ontology + term_definitions = < + ["sv"] = < + items = < + ["at0000"] = < + text = <"Medication Review"> + description = <"Used to represent review of a medication"> + > + ["at0001"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Name"> + description = <"*"> + > + ["at0003"] = < + text = <"Generic"> + description = <"*"> + > + ["at0004"] = < + text = <"Total dose"> + description = <"*"> + > + ["at0005"] = < + text = <"Status"> + description = <"*"> + > + ["at0006"] = < + text = <"Reason target dose not reached"> + description = <"*"> + > + ["at0007"] = < + text = <"Reason medicine not given"> + description = <"*"> + > + ["at0008"] = < + text = <"Base daily dose"> + description = <"*"> + > + ["at0009"] = < + text = <"Extra dose when needed"> + description = <"*"> + > + > + > + > 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 new file mode 100644 index 00000000..1c818c79 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-EVALUATION.review_of_procedures.v1.adl @@ -0,0 +1,88 @@ +archetype (adl_version=1.4) + openEHR-EHR-EVALUATION.review_of_procedures.v1 + +concept + [at0000] -- Genomgång av insatser +language + original_language = <[ISO_639-1::sv]> +description + original_author = < + ["name"] = <"Daniel Karlsson"> + ["date"] = <"10/16/2009"> + > + details = < + ["sv"] = < + language = <[ISO_639-1::sv]> + purpose = <"For recording structured review of a list of procedures in the same context"> + use = <""> + keywords = <"review", "procedure"> + misuse = <""> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <"Rong Chen", ...> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"158A0A8279F55279915585C3BC84FDF6"> + > + +definition + EVALUATION[at0000] matches { -- Genomgång av insatser + data matches { + ITEM_TREE[at0001] matches { -- Träd + items cardinality matches {0..*; unordered} matches { + CLUSTER[at0002] occurrences matches {0..*} matches { -- Insats + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0003] occurrences matches {0..1} matches { -- Typ av insats + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0004] occurrences matches {0..1} matches { -- Tidpunkt + value matches { + DV_DATE_TIME matches {*} + } + } + ELEMENT[at0005] occurrences matches {0..*} matches { -- Genomförandestatus + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["sv"] = < + items = < + ["at0000"] = < + text = <"Genomgång av insatser"> + description = <"Review of a list of procedure in the same context"> + > + ["at0001"] = < + text = <"Träd"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Insats"> + description = <"*"> + > + ["at0003"] = < + text = <"Typ av insats"> + description = <"*"> + > + ["at0004"] = < + text = <"Tidpunkt"> + description = <"*"> + > + ["at0005"] = < + text = <"Genomförandestatus"> + description = <"*"> + > + > + > + > 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 new file mode 100644 index 00000000..f9686b42 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-EVALUATION.structured_summary.v1.adl @@ -0,0 +1,81 @@ +archetype (adl_version=1.4) + openEHR-EHR-EVALUATION.structured_summary.v1 + +concept + [at0000] -- summary +language + original_language = <[ISO_639-1::sv]> +description + original_author = < + ["name"] = <"Rong Chen"> + ["date"] = <"10/19/2009"> + > + details = < + ["sv"] = < + language = <[ISO_639-1::sv]> + purpose = <"for structured summary"> + use = <""> + keywords = <"summary", ...> + misuse = <""> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <"Daniel Karlsson", ...> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"4DDD765A9C44C9A9602DEB00E1FAE40F"> + > + +definition + EVALUATION[at0000] matches { -- summary + data matches { + ITEM_TREE[at0001] matches { -- Träd + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0002] occurrences matches {0..1} matches { -- summary + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0005] occurrences matches {0..1} matches { -- total + value matches { + C_DV_QUANTITY < + > + } + } + ELEMENT[at0003] occurrences matches {0..1} matches { -- comment + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["sv"] = < + items = < + ["at0000"] = < + text = <"summary"> + description = <"Structured summary"> + > + ["at0001"] = < + text = <"Träd"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"summary"> + description = <"*"> + > + ["at0003"] = < + text = <"comment"> + description = <"*"> + > + ["at0005"] = < + text = <"total"> + description = <"*"> + > + > + > + > 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 new file mode 100644 index 00000000..0d4cad1a --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-INSTRUCTION.medication.v1.adl @@ -0,0 +1,90 @@ +archetype (adl_version=1.4) + openEHR-EHR-INSTRUCTION.medication.v1 + +concept + [at0000] -- Medication order +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"] = <"21/04/2006"> + ["email"] = <"sam.heard@oceaninformatics.biz"> + > + details = < + ["de"] = < + language = <[ISO_639-1::de]> + purpose = <"Zur Dokumentation einer Medikationsverordnung, kann mehr als eine Aktivität enthalten, aber immer mit der selben Struktur"> + use = <"Zur Dokumentation von Anweisungen bezüglich eines Medikaments"> + keywords = <"Verschreibung", "Medikationsverordnung", "Verordnung"> + misuse = <"Nicht zur Dokumentation der Verabreichung, der Gabe usw. benutzen. Für diese Dokumentation openEHR-EHR-ACTION.medication benutzen."> + copyright = <"copyright (c) 2008 openEHR Foundation"> + > + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"For recording a medication order, which may involve more than one activity, but all have the same structure."> + use = <"For recording an instruction about medication."> + keywords = <"prescribe", "medication order", "order"> + misuse = <"Do not use for recording administration, dispensing etc. Use openEHR-EHR-ACTION.medication for these recordings."> + copyright = <"copyright (c) 2008 openEHR Foundation"> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <"NEHTA (Australia) data groups", ...> + +definition + INSTRUCTION[at0000] matches { -- Medication order + activities cardinality matches {0..*; unordered} matches { + ACTIVITY[at0001] occurrences matches {0..*} matches { -- Medication activity + action_archetype_id matches {/medication\.v1/} + description matches { + allow_archetype ITEM_TREE occurrences matches {0..1} matches { + include + archetype_id/value matches {/medication\.v1/} + archetype_id/value matches {/medication-formulation\.v1/} + archetype_id/value matches {/medication-vaccine\.v1/} + exclude + archetype_id/value matches {/.*/} + } + } + } + } + } + +ontology + term_definitions = < + ["de"] = < + items = < + ["at0000"] = < + text = <"Medikationsverordnung"> + description = <"Eine von einem Klinikarzt verfasste Verordnung oder Anweisung, die beschreibt welches Medikament wann, für wie lange usw. eingenommen werden soll"> + > + ["at0001"] = < + text = <"Medikationshandlung"> + description = <"Informationen über die auszuführende Medikationshandlung"> + > + > + > + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication order"> + description = <"An order or instruction created by a clinician which specifies which medication to take, when, for how long etc."> + > + ["at0001"] = < + text = <"Medication activity"> + description = <"Information about the medication action(s) to be carried out"> + > + > + > + > 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 new file mode 100644 index 00000000..e40e9804 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication.v1.adl @@ -0,0 +1,919 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication.v1 + +concept + [at0000] -- Medication description +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"Sam Heard"> + ["organisation"] = <"Ocean Informatics"> + ["email"] = <"sam.heard@oceaninformatics.com"> + ["date"] = <"12/03/2006"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"Specifies the description of the medication as part of an INSTRUCTION or ACTION recording taken with regard to medication. This will usually be in response to a medication order or prescription, but may be self administered or supplied by a pharmacy."> + use = <"For use with INSTRUCTION.medication and ACTION.medication to describe the medication"> + keywords = <"medication", "description"> + misuse = <""> + copyright = <"copyright (c) 2009 openEHR Foundation"> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"E28D648F74019897EC390F43785C68F4"> + > + +definition + ITEM_TREE[at0000] occurrences matches {0..*} matches { -- Medication description + items cardinality matches {2..*; ordered} matches { + ELEMENT[at0001] matches { -- Name of medication + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0012] occurrences matches {0..1} matches { -- Generic name + name matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0003]} -- =Generic name OR Brand name + } + } + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0003] occurrences matches {0..1} matches { -- Strength per dose unit + value matches { + C_DV_QUANTITY < + property = <[openehr::124]> + list = < + ["1"] = < + units = <"pg"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"µg"> + magnitude = <|>=0.0|> + > + ["3"] = < + units = <"mg"> + magnitude = <|>=0.0|> + > + ["4"] = < + units = <"gm"> + magnitude = <|>=0.0|> + > + > + > + C_DV_QUANTITY < + property = <[openehr::385]> + list = < + ["1"] = < + units = <"IU"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"mIU"> + magnitude = <|>=0.0|> + > + > + > + C_DV_QUANTITY < + property = <[openehr::445]> + list = < + ["1"] = < + units = <"mU"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"U"> + magnitude = <|>=0.0|> + > + > + > + } + } + ELEMENT[at0006] matches { -- Dose unit + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0001]} -- any term that 'is a' Dose unit for this form + } + } + } + ELEMENT[at0004] occurrences matches {0..1} matches { -- Form + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' form of medication + } + } + } + CLUSTER[at0033] occurrences matches {0..1} matches { -- Dose + items cardinality matches {1; unordered} matches { + CLUSTER[at0035] occurrences matches {0..1} matches { -- By absolute quantity + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0036] occurrences matches {0..2} matches { -- Quantity by volume + value matches { + C_DV_QUANTITY < + property = <[openehr::129]> + list = < + ["1"] = < + units = <"ml"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"l"> + magnitude = <|>=0.0|> + > + > + > + DV_INTERVAL matches { + upper matches { + C_DV_QUANTITY < + property = <[openehr::129]> + list = < + ["1"] = < + units = <"ml"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"l"> + magnitude = <|>=0.0|> + > + > + > + } + lower matches { + C_DV_QUANTITY < + property = <[openehr::129]> + list = < + ["1"] = < + units = <"ml"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"l"> + magnitude = <|>=0.0|> + > + > + > + } + } + } + } + ELEMENT[at0037] occurrences matches {0..1} matches { -- Quantity by mass + value matches { + C_DV_QUANTITY < + property = <[openehr::124]> + list = < + ["1"] = < + units = <"µg"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"mg"> + > + ["3"] = < + units = <"gm"> + > + > + > + DV_INTERVAL matches { + upper matches { + C_DV_QUANTITY < + property = <[openehr::124]> + list = < + ["1"] = < + units = <"µg"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"mg"> + magnitude = <|>=0.0|> + > + ["3"] = < + units = <"gm"> + magnitude = <|>=0.0|> + > + > + > + } + lower matches { + C_DV_QUANTITY < + property = <[openehr::124]> + list = < + ["1"] = < + units = <"µg"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"mg"> + magnitude = <|>=0.0|> + > + ["3"] = < + units = <"gm"> + magnitude = <|>=0.0|> + > + > + > + } + } + } + } + } + } + CLUSTER[at0034] occurrences matches {0..1} matches { -- By dose units + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0005] matches { -- Number or fraction + value matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + DV_INTERVAL matches { + upper matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + } + lower matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + } + } + DV_PROPORTION matches { + numerator matches {|>=1.0|} + denominator matches {|1.0..4.0|} + type matches {1, 2, 4} + } + } + } + } + } + } + } + ELEMENT[at0007] occurrences matches {0..1} matches { -- Dose duration + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"d"> + > + ["2"] = < + units = <"h"> + > + ["3"] = < + units = <"min"> + > + ["4"] = < + units = <"s"> + magnitude = <|>=0.0|> + > + > + > + } + } + ELEMENT[at0008] occurrences matches {0..1} matches { -- Route + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0002]} -- Any term that 'is_a' route of administration + } + } + } + CLUSTER[at0057] occurrences matches {0..1} matches { -- Timing + items cardinality matches {0..*; unordered} matches { + CLUSTER[at0061] occurrences matches {0..1} matches { -- Approximate + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0052] occurrences matches {0..1} matches { -- Frequency + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0053, -- Once + at0054, -- Twice + at0055, -- Three times + at0056, -- Four times + at0058] -- Five times + } + } + DV_CODED_TEXT matches { + defining_code matches {[ac0005]} -- Frequency + } + } + } + ELEMENT[at0059] occurrences matches {0..1} matches { -- Unit time + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"a"> + > + ["2"] = < + units = <"d"> + > + ["3"] = < + units = <"h"> + > + ["4"] = < + units = <"min"> + > + ["5"] = < + units = <"mo"> + > + ["6"] = < + units = <"wk"> + > + > + > + } + } + } + } + CLUSTER[at0062] occurrences matches {0..1} matches { -- Exact + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0063] occurrences matches {0..1} matches { -- Exact time of administration + value matches { + DV_DATE_TIME matches {*} + } + } + } + } + CLUSTER[at0064] occurrences matches {0..1} matches { -- Relative + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0065] occurrences matches {0..1} matches { -- Timing + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"a"> + > + ["2"] = < + units = <"d"> + > + ["3"] = < + units = <"h"> + > + ["4"] = < + units = <"mo"> + > + ["5"] = < + units = <"s"> + > + ["6"] = < + units = <"min"> + > + ["7"] = < + units = <"wk"> + > + > + > + } + } + ELEMENT[at0066] occurrences matches {0..1} matches { -- Qualifier + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0068, -- before + at0069, -- after + at0070, -- with + at0073] -- at + } + } + } + } + ELEMENT[at0067] occurrences matches {0..1} matches { -- Event + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + ELEMENT[at0060] occurrences matches {0..1} matches { -- Instruction qualifiers + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0050] occurrences matches {0..1} matches { -- Reason for commencement + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0051] occurrences matches {0..1} matches { -- Reason for ceasing + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0009] occurrences matches {0..1} matches { -- Is long term + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + CLUSTER[at0010] occurrences matches {0..1} matches { -- Indications + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0011] occurrences matches {0..*} matches { -- Indication + value matches { + DV_TEXT matches {*} + DV_URI matches {*} + } + } + } + } + CLUSTER[at0013] occurrences matches {0..1} matches { -- Safety limits + items cardinality matches {1..4; ordered} matches { + ELEMENT[at0014] occurrences matches {0..1} matches { -- Maximum dose unit frequency + value matches { + C_DV_QUANTITY < + property = <[openehr::382]> + list = < + ["1"] = < + units = <"{QUALIFIED REAL/TIME}"> + magnitude = <|>0.0|> + > + > + assumed_value = < + magnitude = <0.0> + units = <"{QUALIFIED REAL/TIME}"> + precision = <-1> + > + > + } + } + ELEMENT[at0015] 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[at0016] occurrences matches {0..1} matches { -- Minimum dose interval + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"min"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"h"> + magnitude = <|>=0.0|> + > + ["3"] = < + units = <"d"> + magnitude = <|>=0.0|> + > + ["4"] = < + units = <"wk"> + magnitude = <|>=0.0|> + > + ["5"] = < + units = <"mo"> + magnitude = <|>=0.0|> + > + > + > + } + } + ELEMENT[at0017] occurrences matches {0..1} matches { -- Maximum dose interval + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"d"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"h"> + magnitude = <|>=0.0|> + > + ["3"] = < + units = <"min"> + magnitude = <|>=0.0|> + > + ["4"] = < + units = <"wk"> + magnitude = <|>=0.0|> + > + ["5"] = < + units = <"mo"> + magnitude = <|>=0.0|> + > + > + > + } + } + ELEMENT[at0002] occurrences matches {0..1} matches { -- Administration instructions + value matches { + DV_TEXT matches {*} + } + } + } + } + CLUSTER[at0018] occurrences matches {0..1} matches { -- Administration information + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0019] occurrences matches {0..1} matches { -- Date (time) of first administration + value matches { + DV_DATE_TIME matches {*} + } + } + ELEMENT[at0020] occurrences matches {0..1} matches { -- Batch number + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0021] occurrences matches {0..1} matches { -- Site of administration + value matches { + DV_CODED_TEXT matches { + defining_code matches {[local::]} + } + } + } + ELEMENT[at0022] occurrences matches {0..1} matches { -- Sequence number + value matches { + DV_COUNT matches {*} + } + } + ELEMENT[at0032] occurrences matches {0..1} matches { -- Date (time) of last administration + value matches { + DV_DATE_TIME matches {*} + } + } + } + } + CLUSTER[at0023] occurrences matches {0..1} matches { -- Dispensing information + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0024] occurrences matches {0..1} matches { -- Quantity to be dispensed + value matches { + C_DV_QUANTITY < + property = <[openehr::445]> + > + DV_COUNT matches { + magnitude matches {|>0|; 1} + } + DV_TEXT matches {*} + } + } + ELEMENT[at0025] occurrences matches {0..1} matches { -- Number of authorised repeat dispensing + value matches { + DV_COUNT matches { + magnitude matches {|>=0|} + } + } + } + ELEMENT[at0026] occurrences matches {0..1} matches { -- Dispensed product + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0027] occurrences matches {0..1} matches { -- Brand substitution allowed + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + ELEMENT[at0028] occurrences matches {0..1} matches { -- Authority approval number + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0029] occurrences matches {0..1} matches { -- Patient counselled on CMI + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + ELEMENT[at0030] occurrences matches {0..1} matches { -- Deferred supply + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + ELEMENT[at0031] occurrences matches {0..1} matches { -- Reason for deferred supply + value matches { + DV_TEXT matches {*} + } + } + } + } + CLUSTER[at0049] occurrences matches {0..1} matches { -- Admission information + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0048] occurrences matches {0..1} matches { -- Own Medication + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication for recording as part of an ACTION or INSTRUCTION"> + > + ["at0001"] = < + text = <"Name of medication"> + description = <"The name of the intervention - which may be coded"> + > + ["at0002"] = < + text = <"Administration instructions"> + description = <"Detailed instructions about how to administer this medication"> + > + ["at0003"] = < + text = <"Strength per dose unit"> + description = <"The strength of the medication"> + > + ["at0004"] = < + text = <"Form"> + description = <"The form of the medication"> + > + ["at0005"] = < + text = <"Number or fraction"> + description = <"The number of dose units to be taken at any time"> + > + ["at0006"] = < + text = <"Dose unit"> + description = <"The dose unit that is given for this type of medication"> + > + ["at0007"] = < + text = <"Dose duration"> + description = <"The time over which an individual dose is to be administered"> + > + ["at0008"] = < + text = <"Route"> + description = <"The route of administration"> + > + ["at0009"] = < + text = <"Is long term"> + description = <"Included and set to true if this medication is to be used continuously or repeatedly over a significant period of time."> + > + ["at0010"] = < + text = <"Indications"> + description = <"Indications including related problems and diagnoses, abnormal test results etc"> + > + ["at0011"] = < + text = <"Indication"> + description = <"The indication for the intervention"> + > + ["at0012"] = < + text = <"Generic name"> + description = <"The generic name of the drug which is an alternative name to the name of medication"> + > + ["at0013"] = < + text = <"Safety limits"> + description = <"*"> + > + ["at0014"] = < + text = <"Maximum dose unit frequency"> + description = <"The maximum number of dose units to be taken in a particular time"> + > + ["at0015"] = < + text = <"Dosage per kg body weight"> + description = <"The dose per kg of body weight"> + > + ["at0016"] = < + text = <"Minimum dose interval"> + description = <"The minimum safe interval between doses"> + > + ["at0017"] = < + text = <"Maximum dose interval"> + description = <"The maximum safe interval between doses"> + > + ["at0018"] = < + text = <"Administration information"> + description = <"Information relating to the administration of the medication order"> + > + ["at0019"] = < + text = <"Date (time) of first administration"> + description = <"The date and time (if required) the medication is/was first administered"> + > + ["at0020"] = < + text = <"Batch number"> + description = <"Manufacturer's identification number"> + > + ["at0021"] = < + text = <"Site of administration"> + description = <"The site of administration e.g. outer thigh if intramuscular, via PEG if patient is nil orally"> + > + ["at0022"] = < + text = <"Sequence number"> + description = <"The dose number or sequence"> + > + ["at0023"] = < + text = <"Dispensing information"> + description = <"Data relating to dispensing"> + > + ["at0024"] = < + text = <"Quantity to be dispensed"> + description = <"The total quantity to be dispensed"> + > + ["at0025"] = < + text = <"Number of authorised repeat dispensing"> + description = <"The number of times this quantity of medication may be dispensed before a further prescription is required"> + > + ["at0026"] = < + text = <"Dispensed product"> + description = <"The name of the product dispensed"> + > + ["at0027"] = < + text = <"Brand substitution allowed"> + description = <"True if an alternative brand may be substituted when dispensing"> + > + ["at0028"] = < + text = <"Authority approval number"> + description = <"*"> + > + ["at0029"] = < + text = <"Patient counselled on CMI"> + description = <"Dispenser counselled the patient with regard to the Consumer Medicines Information"> + > + ["at0030"] = < + text = <"Deferred supply"> + description = <"True if the supply of the medication has been deferred"> + > + ["at0031"] = < + text = <"Reason for deferred supply"> + description = <"Information relating to the reason for deferred supply"> + > + ["at0032"] = < + text = <"Date (time) of last administration"> + description = <"The date and time (if required) the medication is to be administered for the last time"> + > + ["at0033"] = < + text = <"Dose"> + description = <"The dose to be administered at one time"> + > + ["at0034"] = < + text = <"By dose units"> + description = <"Dose as number (or fraction) of the dose units"> + > + ["at0035"] = < + text = <"By absolute quantity"> + description = <"Dosage by absolute quantity"> + > + ["at0036"] = < + text = <"Quantity by volume"> + description = <"The quantity (or range) to be administered as a single dose"> + > + ["at0037"] = < + text = <"Quantity by mass"> + description = <"*"> + > + ["at0048"] = < + text = <"Own Medication"> + description = <"On admission to hospital, medication is from subject's own supply."> + > + ["at0049"] = < + text = <"Admission information"> + description = <"*"> + > + ["at0050"] = < + text = <"Reason for commencement"> + description = <"Reason for commencement of medication"> + > + ["at0051"] = < + text = <"Reason for ceasing"> + description = <"Reason for ceasing of medication"> + > + ["at0052"] = < + text = <"Frequency"> + description = <"The frequency of administration"> + > + ["at0053"] = < + text = <"Once"> + description = <"Administer once per unit time"> + > + ["at0054"] = < + text = <"Twice"> + description = <"Administer twice per unit time"> + > + ["at0055"] = < + text = <"Three times "> + description = <"Administer three times per unit time"> + > + ["at0056"] = < + text = <"Four times "> + description = <"Adminiter four times per unit time"> + > + ["at0057"] = < + text = <"Timing"> + description = <"*"> + > + ["at0058"] = < + text = <"Five times"> + description = <"Administer five times per unit time"> + > + ["at0059"] = < + text = <"Unit time"> + description = <"*"> + > + ["at0060"] = < + text = <"Instruction qualifiers"> + description = <"Instruction for administration"> + > + ["at0061"] = < + text = <"Approximate"> + description = <"*"> + > + ["at0062"] = < + text = <"Exact"> + description = <"*"> + > + ["at0063"] = < + text = <"Exact time of administration"> + description = <"*"> + > + ["at0064"] = < + text = <"Relative"> + description = <"*"> + > + ["at0065"] = < + text = <"Timing"> + description = <"*"> + > + ["at0066"] = < + text = <"Qualifier"> + description = <"Qualifier eg before or after meals (event); with food; at bedtime"> + > + ["at0067"] = < + text = <"Event"> + description = <"*"> + > + ["at0068"] = < + text = <"before"> + description = <"*"> + > + ["at0069"] = < + text = <"after"> + description = <"*"> + > + ["at0070"] = < + text = <"with"> + description = <"*"> + > + ["at0073"] = < + text = <"at"> + description = <"*"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + text = <"Any term that 'is_a' form of medication"> + description = <"Terms such as tablet, inhaler, liquid...."> + > + ["ac0001"] = < + text = <"any term that 'is a' Dose unit for this form"> + description = <"A set of terms that describes the dose units for medication - e.g. tablet, puff, ampule etc - which allow the dose to be expressed as a number."> + > + ["ac0002"] = < + text = <"Any term that 'is_a' route of administration"> + description = <"The route by which the medication is administered"> + > + ["ac0003"] = < + text = <"=Generic name OR Brand name"> + description = <"*"> + > + ["ac0005"] = < + text = <"Frequency"> + description = <"Subset of frequencies of medication administration + +"> + > + > + > + > 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 new file mode 100644 index 00000000..c53c96b7 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_mod.v1.adl @@ -0,0 +1,921 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_mod.v1 + +concept + [at0000] -- Medication description +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"Sam Heard"> + ["organisation"] = <"Ocean Informatics"> + ["date"] = <"12/03/2006"> + ["email"] = <"sam.heard@oceaninformatics.com"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"Specifies the description of the medication as part of an INSTRUCTION or ACTION recording taken with regard to medication. This will usually be in response to a medication order or prescription, but may be self administered or supplied by a pharmacy."> + use = <"For use with INSTRUCTION.medication and ACTION.medication to describe the medication"> + keywords = <"medication", "description"> + misuse = <""> + copyright = <"copyright (c) 2008 openEHR Foundation"> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <> + +definition + ITEM_TREE[at0000] occurrences matches {0..*} matches { -- Medication description + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0001] matches { -- Name of medication + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0012] occurrences matches {0..1} matches { -- Generic name + name matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0003]} -- =Generic name OR Brand name + } + } + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0003] occurrences matches {0..1} matches { -- Strength per dose unit + value matches { + C_DV_QUANTITY < + property = <[openehr::124]> + list = < + ["1"] = < + units = <"pg"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"µg"> + magnitude = <|>=0.0|> + > + ["3"] = < + units = <"mg"> + magnitude = <|>=0.0|> + > + ["4"] = < + units = <"gm"> + magnitude = <|>=0.0|> + > + > + > + C_DV_QUANTITY < + property = <[openehr::385]> + list = < + ["1"] = < + units = <"IU"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"mIU"> + magnitude = <|>=0.0|> + > + > + > + C_DV_QUANTITY < + property = <[openehr::445]> + list = < + ["1"] = < + units = <"mU"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"U"> + magnitude = <|>=0.0|> + > + > + > + } + } + ELEMENT[at0006] matches { -- Dose unit + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0001]} -- any term that 'is a' Dose unit for this form + } + } + } + ELEMENT[at0004] occurrences matches {0..1} matches { -- Form + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' form of medication + } + } + } + CLUSTER[at0033] occurrences matches {0..1} matches { -- Dose + items cardinality matches {1; unordered} matches { + CLUSTER[at0035] occurrences matches {0..1} matches { -- By absolute quantity + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0036] occurrences matches {1..2} matches { -- Quantity by volume + value matches { + C_DV_QUANTITY < + property = <[openehr::129]> + list = < + ["1"] = < + units = <"ml"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"l"> + magnitude = <|>=0.0|> + > + > + > + DV_INTERVAL matches { + upper matches { + C_DV_QUANTITY < + property = <[openehr::129]> + list = < + ["1"] = < + units = <"ml"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"l"> + magnitude = <|>=0.0|> + > + > + > + } + lower matches { + C_DV_QUANTITY < + property = <[openehr::129]> + list = < + ["1"] = < + units = <"ml"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"l"> + magnitude = <|>=0.0|> + > + > + > + } + } + } + } + ELEMENT[at0037] occurrences matches {0..1} matches { -- Quantity by mass + value matches { + C_DV_QUANTITY < + property = <[openehr::124]> + list = < + ["1"] = < + units = <"µg"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"mg"> + > + ["3"] = < + units = <"gm"> + > + > + > + DV_INTERVAL matches { + upper matches { + C_DV_QUANTITY < + property = <[openehr::124]> + list = < + ["1"] = < + units = <"µg"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"mg"> + magnitude = <|>=0.0|> + > + ["3"] = < + units = <"gm"> + magnitude = <|>=0.0|> + > + > + > + } + lower matches { + C_DV_QUANTITY < + property = <[openehr::124]> + list = < + ["1"] = < + units = <"µg"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"mg"> + magnitude = <|>=0.0|> + > + ["3"] = < + units = <"gm"> + magnitude = <|>=0.0|> + > + > + > + } + } + } + } + } + } + CLUSTER[at0034] occurrences matches {0..1} matches { -- By dose units + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0005] matches { -- Number or fraction + value matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + DV_INTERVAL matches { + upper matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + } + lower matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + } + } + DV_PROPORTION matches { + numerator matches {|>=1.0|} + denominator matches {|1.0..4.0|} + type matches {1, 2, 4} + } + } + } + } + } + } + } + ELEMENT[at0007] occurrences matches {0..1} matches { -- Dose duration + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"d"> + > + ["2"] = < + units = <"h"> + > + ["3"] = < + units = <"min"> + > + ["4"] = < + units = <"s"> + magnitude = <|>=0.0|> + > + > + > + } + } + ELEMENT[at0008] occurrences matches {0..1} matches { -- Route + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0002]} -- Any term that 'is_a' route of administration + } + } + } + CLUSTER[at0057] occurrences matches {0..1} matches { -- Timing + items cardinality matches {0..*; unordered} matches { + CLUSTER[at0061] occurrences matches {0..1} matches { -- Approximate + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0052] occurrences matches {0..1} matches { -- Frequency + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0053, -- Once + at0054, -- Twice + at0055, -- Three times + at0056, -- Four times + at0058] -- Five times + } + } + DV_CODED_TEXT matches { + defining_code matches {[ac0005]} -- Frequency + } + } + } + ELEMENT[at0059] occurrences matches {0..1} matches { -- Unit time + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"a"> + > + ["2"] = < + units = <"d"> + > + ["3"] = < + units = <"h"> + > + ["4"] = < + units = <"min"> + > + ["5"] = < + units = <"mo"> + > + ["6"] = < + units = <"wk"> + > + > + > + } + } + } + } + CLUSTER[at0062] occurrences matches {0..1} matches { -- Exact + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0063] occurrences matches {0..1} matches { -- Exact time of administration + value matches { + DV_DATE_TIME matches { + value matches {yyyy-??-??T??:??:??} + } + } + } + } + } + CLUSTER[at0064] occurrences matches {0..1} matches { -- Relative + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0065] occurrences matches {0..1} matches { -- Timing + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"a"> + > + ["2"] = < + units = <"d"> + > + ["3"] = < + units = <"h"> + > + ["4"] = < + units = <"mo"> + > + ["5"] = < + units = <"s"> + > + ["6"] = < + units = <"min"> + > + ["7"] = < + units = <"wk"> + > + > + > + } + } + ELEMENT[at0066] occurrences matches {0..1} matches { -- Qualifier + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0068, -- before + at0069, -- after + at0070, -- with + at0073] -- at + } + } + } + } + ELEMENT[at0067] occurrences matches {0..1} matches { -- Event + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + ELEMENT[at0060] occurrences matches {0..1} matches { -- Instruction qualifiers + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0050] occurrences matches {0..1} matches { -- Reason for commencement + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0051] occurrences matches {0..1} matches { -- Reason for ceasing + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0009] occurrences matches {0..1} matches { -- Is long term + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + CLUSTER[at0010] occurrences matches {0..1} matches { -- Indications + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0011] occurrences matches {0..*} matches { -- Indication + value matches { + DV_TEXT matches {*} + DV_URI matches {*} + } + } + } + } + CLUSTER[at0013] occurrences matches {0..1} matches { -- Safety limits + items cardinality matches {1..4; ordered} matches { + ELEMENT[at0014] occurrences matches {0..1} matches { -- Maximum dose unit frequency + value matches { + C_DV_QUANTITY < + property = <[openehr::382]> + list = < + ["1"] = < + units = <"{QUALIFIED REAL/TIME}"> + magnitude = <|>0.0|> + > + > + assumed_value = < + precision = <-1> + magnitude = <0.0> + units = <"{QUALIFIED REAL/TIME}"> + > + > + } + } + ELEMENT[at0015] 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[at0016] occurrences matches {0..1} matches { -- Minimum dose interval + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"min"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"h"> + magnitude = <|>=0.0|> + > + ["3"] = < + units = <"d"> + magnitude = <|>=0.0|> + > + ["4"] = < + units = <"wk"> + magnitude = <|>=0.0|> + > + ["5"] = < + units = <"mo"> + magnitude = <|>=0.0|> + > + > + > + } + } + ELEMENT[at0017] occurrences matches {0..1} matches { -- Maximum dose interval + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"d"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"h"> + magnitude = <|>=0.0|> + > + ["3"] = < + units = <"min"> + magnitude = <|>=0.0|> + > + ["4"] = < + units = <"wk"> + magnitude = <|>=0.0|> + > + ["5"] = < + units = <"mo"> + magnitude = <|>=0.0|> + > + > + > + } + } + ELEMENT[at0002] occurrences matches {0..1} matches { -- Administration instructions + value matches { + DV_TEXT matches {*} + } + } + } + } + CLUSTER[at0018] occurrences matches {0..1} matches { -- Administration information + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0019] occurrences matches {0..1} matches { -- Date (time) of first administration + value matches { + DV_DATE_TIME matches { + value matches {yyyy-??-??T??:??:??} + } + } + } + ELEMENT[at0020] occurrences matches {0..1} matches { -- Batch number + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0021] occurrences matches {0..1} matches { -- Site of administration + value matches { + DV_CODED_TEXT matches { + defining_code matches {[local::]} + } + } + } + ELEMENT[at0022] occurrences matches {0..1} matches { -- Sequence number + value matches { + DV_COUNT matches {*} + } + } + ELEMENT[at0032] occurrences matches {0..1} matches { -- Date (time) of last administration + value matches { + DV_DATE_TIME matches { + value matches {yyyy-??-??T??:??:??} + } + } + } + } + } + CLUSTER[at0023] occurrences matches {0..1} matches { -- Dispensing information + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0024] occurrences matches {0..1} matches { -- Quantity to be dispensed + value matches { + C_DV_QUANTITY < + property = <[openehr::445]> + > + DV_COUNT matches { + magnitude matches {|>0|; 1} + } + DV_TEXT matches {*} + } + } + ELEMENT[at0025] occurrences matches {0..1} matches { -- Number of authorised repeat dispensing + value matches { + DV_COUNT matches { + magnitude matches {|>=0|} + } + } + } + ELEMENT[at0026] occurrences matches {0..1} matches { -- Dispensed product + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0027] occurrences matches {0..1} matches { -- Brand substitution allowed + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + ELEMENT[at0028] occurrences matches {0..1} matches { -- Authority approval number + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0029] occurrences matches {0..1} matches { -- Patient counselled on CMI + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + ELEMENT[at0030] occurrences matches {0..1} matches { -- Deferred supply + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + ELEMENT[at0031] occurrences matches {0..1} matches { -- Reason for deferred supply + value matches { + DV_TEXT matches {*} + } + } + } + } + CLUSTER[at0049] occurrences matches {0..1} matches { -- Admission information + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0048] occurrences matches {0..1} matches { -- Own Medication + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication for recording as part of an ACTION or INSTRUCTION"> + > + ["at0001"] = < + text = <"Name of medication"> + description = <"The name of the intervention - which may be coded"> + > + ["at0002"] = < + text = <"Administration instructions"> + description = <"Detailed instructions about how to administer this medication"> + > + ["at0003"] = < + text = <"Strength per dose unit"> + description = <"The strength of the medication"> + > + ["at0004"] = < + text = <"Form"> + description = <"The form of the medication"> + > + ["at0005"] = < + text = <"Number or fraction"> + description = <"The number of dose units to be taken at any time"> + > + ["at0006"] = < + text = <"Dose unit"> + description = <"The dose unit that is given for this type of medication"> + > + ["at0007"] = < + text = <"Dose duration"> + description = <"The time over which an individual dose is to be administered"> + > + ["at0008"] = < + text = <"Route"> + description = <"The route of administration"> + > + ["at0009"] = < + text = <"Is long term"> + description = <"Included and set to true if this medication is to be used continuously or repeatedly over a significant period of time."> + > + ["at0010"] = < + text = <"Indications"> + description = <"Indications including related problems and diagnoses, abnormal test results etc"> + > + ["at0011"] = < + text = <"Indication"> + description = <"The indication for the intervention"> + > + ["at0012"] = < + text = <"Generic name"> + description = <"The generic name of the drug which is an alternative name to the name of medication"> + > + ["at0013"] = < + text = <"Safety limits"> + description = <"*"> + > + ["at0014"] = < + text = <"Maximum dose unit frequency"> + description = <"The maximum number of dose units to be taken in a particular time"> + > + ["at0015"] = < + text = <"Dosage per kg body weight"> + description = <"The dose per kg of body weight"> + > + ["at0016"] = < + text = <"Minimum dose interval"> + description = <"The minimum safe interval between doses"> + > + ["at0017"] = < + text = <"Maximum dose interval"> + description = <"The maximum safe interval between doses"> + > + ["at0018"] = < + text = <"Administration information"> + description = <"Information relating to the administration of the medication order"> + > + ["at0019"] = < + text = <"Date (time) of first administration"> + description = <"The date and time (if required) the medication is/was first administered"> + > + ["at0020"] = < + text = <"Batch number"> + description = <"Manufacturer's identification number"> + > + ["at0021"] = < + text = <"Site of administration"> + description = <"The site of administration e.g. outer thigh if intramuscular, via PEG if patient is nil orally"> + > + ["at0022"] = < + text = <"Sequence number"> + description = <"The dose number or sequence"> + > + ["at0023"] = < + text = <"Dispensing information"> + description = <"Data relating to dispensing"> + > + ["at0024"] = < + text = <"Quantity to be dispensed"> + description = <"The total quantity to be dispensed"> + > + ["at0025"] = < + text = <"Number of authorised repeat dispensing"> + description = <"The number of times this quantity of medication may be dispensed before a further prescription is required"> + > + ["at0026"] = < + text = <"Dispensed product"> + description = <"The name of the product dispensed"> + > + ["at0027"] = < + text = <"Brand substitution allowed"> + description = <"True if an alternative brand may be substituted when dispensing"> + > + ["at0028"] = < + text = <"Authority approval number"> + description = <"*"> + > + ["at0029"] = < + text = <"Patient counselled on CMI"> + description = <"Dispenser counselled the patient with regard to the Consumer Medicines Information"> + > + ["at0030"] = < + text = <"Deferred supply"> + description = <"True if the supply of the medication has been deferred"> + > + ["at0031"] = < + text = <"Reason for deferred supply"> + description = <"Information relating to the reason for deferred supply"> + > + ["at0032"] = < + text = <"Date (time) of last administration"> + description = <"The date and time (if required) the medication is to be administered for the last time"> + > + ["at0033"] = < + text = <"Dose"> + description = <"The dose to be administered at one time"> + > + ["at0034"] = < + text = <"By dose units"> + description = <"Dose as number (or fraction) of the dose units"> + > + ["at0035"] = < + text = <"By absolute quantity"> + description = <"Dosage by absolute quantity"> + > + ["at0036"] = < + text = <"Quantity by volume"> + description = <"The quantity (or range) to be administered as a single dose"> + > + ["at0037"] = < + text = <"Quantity by mass"> + description = <"*"> + > + ["at0048"] = < + text = <"Own Medication"> + description = <"On admission to hospital, medication is from subject's own supply."> + > + ["at0049"] = < + text = <"Admission information"> + description = <"*"> + > + ["at0050"] = < + text = <"Reason for commencement"> + description = <"Reason for commencement of medication"> + > + ["at0051"] = < + text = <"Reason for ceasing"> + description = <"Reason for ceasing of medication"> + > + ["at0052"] = < + text = <"Frequency"> + description = <"The frequency of administration"> + > + ["at0053"] = < + text = <"Once"> + description = <"Administer once per unit time"> + > + ["at0054"] = < + text = <"Twice"> + description = <"Administer twice per unit time"> + > + ["at0055"] = < + text = <"Three times "> + description = <"Administer three times per unit time"> + > + ["at0056"] = < + text = <"Four times "> + description = <"Adminiter four times per unit time"> + > + ["at0057"] = < + text = <"Timing"> + description = <"*"> + > + ["at0058"] = < + text = <"Five times"> + description = <"Administer five times per unit time"> + > + ["at0059"] = < + text = <"Unit time"> + description = <"*"> + > + ["at0060"] = < + text = <"Instruction qualifiers"> + description = <"Instruction for administration"> + > + ["at0061"] = < + text = <"Approximate"> + description = <"*"> + > + ["at0062"] = < + text = <"Exact"> + description = <"*"> + > + ["at0063"] = < + text = <"Exact time of administration"> + description = <"*"> + > + ["at0064"] = < + text = <"Relative"> + description = <"*"> + > + ["at0065"] = < + text = <"Timing"> + description = <"*"> + > + ["at0066"] = < + text = <"Qualifier"> + description = <"Qualifier eg before or after meals (event); with food; at bedtime"> + > + ["at0067"] = < + text = <"Event"> + description = <"*"> + > + ["at0068"] = < + text = <"before"> + description = <"*"> + > + ["at0069"] = < + text = <"after"> + description = <"*"> + > + ["at0070"] = < + text = <"with"> + description = <"*"> + > + ["at0073"] = < + text = <"at"> + description = <"*"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + text = <"Any term that 'is_a' form of medication"> + description = <"Terms such as tablet, inhaler, liquid...."> + > + ["ac0001"] = < + text = <"any term that 'is a' Dose unit for this form"> + description = <"A set of terms that describes the dose units for medication - e.g. tablet, puff, ampule etc - which allow the dose to be expressed as a number."> + > + ["ac0002"] = < + text = <"Any term that 'is_a' route of administration"> + description = <"The route by which the medication is administered"> + > + ["ac0003"] = < + text = <"=Generic name OR Brand name"> + description = <"*"> + > + ["ac0005"] = < + text = <"Frequency"> + description = <"Subset of frequencies of medication administration + +"> + > + > + > + > 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 new file mode 100644 index 00000000..a8a589b3 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_multiple_constraint_expected.v1.adl @@ -0,0 +1,33 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_multiple_constraint_expected.v1 + +concept + [at0000] -- Medication description + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] occurrences matches {0..*} matches { + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0001] matches { -- Name of medication + value matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..5549ee95 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_multiple_constraint_test.v1.adl @@ -0,0 +1,50 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_multiple_constraint_test.v1 + +concept + [at0000] -- Medication description + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] occurrences matches {0..*} matches { + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0001] matches { -- Name of medication + value matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + DV_INTERVAL matches { + upper matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + } + lower matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + } + } + 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 = <"Medication description"> + description = <"The description of a medication"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..eb9a54a7 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_multiple_constraint_test2.v1.adl @@ -0,0 +1,27 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_multiple_constraint_test2.v1 + +concept + [at0000] -- Medication description + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] occurrences matches {0..*} matches { + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0001] occurrences matches {0..*} matches {*} + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..fa238b0e --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_quantity_test.v1.adl @@ -0,0 +1,31 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_quantity_test.v1 + +concept + [at0000] -- Medication description + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] occurrences matches {0..*} matches { + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0001] occurrences matches {0..*} matches {*} + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication"> + > + ["at0001"] = < + text = <"Result"> + description = <"The description of a medication"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..1eb197d3 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_quantity_test2.v1.adl @@ -0,0 +1,47 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_quantity_test2.v1 + +concept + [at0000] -- Medication description + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] occurrences matches {0..*} matches { + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0001] occurrences matches {0..*} matches { + value matches { + C_DV_QUANTITY < + property = <[openehr::122]> + list = < + ["1"] = < + units = <"cm"> + magnitude = <|0.0..1000.0|> + > + ["2"] = < + units = <"in"> + magnitude = <|0.0..250.0|> + > + > + > + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication"> + > + ["at0001"] = < + text = <"Result"> + description = <"The description of a medication"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..b95db57c --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_one.v1.adl @@ -0,0 +1,31 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_test_one.v1 + +concept + [at0000] -- Medication description + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] occurrences matches {0..*} matches { + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0001] matches { -- Name of medication + value matches { + DV_TEXT matches {*} + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..f5a15861 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_one.v2.adl @@ -0,0 +1,32 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_test_one.v2 + +concept + [at0000] -- Medication description + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] occurrences matches {0..*} matches { + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0001] matches { -- Name of medication + value matches { + DV_TEXT matches {*} + DV_URI matches {*} + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..b31072ea --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_text_default.v1.adl @@ -0,0 +1,29 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_test_one.v1 + +concept + [at0000] -- Medication description + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] occurrences matches {0..*} matches { + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0001] matches { -- Name of medication + value matches { "Ipren"} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..c0efe86f --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_text_name.v1.adl @@ -0,0 +1,32 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_test_one.v1 + +concept + [at0000] -- Medication description + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] occurrences matches {0..*} matches { + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0001] matches { -- Name of medication + value matches { + DV_TEXT matches {*} + } + name matches { "Drug Name"} + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..95c8bdda --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_three.v1.adl @@ -0,0 +1,31 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_test_three.v1 + +concept + [at0000] -- Medication description + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] matches { + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0001] occurrences matches {0..*} matches { -- Name of medication + value matches { + DV_TEXT matches {*} + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..3a98c58b --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-ITEM_TREE.medication_test_two.v1.adl @@ -0,0 +1,31 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_test_two.v1 + +concept + [at0000] -- Medication description + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] occurrences matches {0..*} matches { + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0001] matches { -- Name of medication + value matches { + DV_CODED_TEXT matches {*} + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication"> + > + > + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..0ddd2eda --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-OBSERVATION.heart_failure_stage.v2.adl @@ -0,0 +1,173 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.heart_failure_stage.v2 + +concept + [at0000] -- hjärtsvikt-allvarlighetsgrad +language + original_language = <[ISO_639-1::sv]> +description + original_author = < + ["name"] = <"Rong Chen"> + ["date"] = <"10/12/2009"> + > + details = < + ["sv"] = < + language = <[ISO_639-1::sv]> + purpose = <"*In order to determine the best course of of therapy, physicians often assess the stage of heart failure according to the New York Heart Association (NYHA) functional classification system. This system relates symptoms to everyday activities and the patient's quality of life.(en)"> + use = <"*(en)"> + keywords = <"*heart failure stage(en)", "*NYHA classification(en)", "*shortness of breath(en)", "*fatigue(en)", "*heart failure(en)"> + misuse = <"*(en)"> + > + > + lifecycle_state = <"0"> + other_contributors = <> + other_details = < + ["references"] = <"The Stages of Heart Failure – NYHA Classification, http://www.abouthf.org/questions_stages.htm"> + ["MD5-CAM-1.0.1"] = <"A558D6782E28544866B0503C7E9D260B"> + > + +definition + OBSERVATION[at0000] matches { -- hjärtsvikt-allvarlighetsgrad + data matches { + HISTORY[at0001] matches { -- *Event Series(en) + events cardinality matches {1..*; unordered} matches { + EVENT[at0002] occurrences matches {0..1} matches { -- *Any event(en) + data matches { + ITEM_LIST[at0003] matches { -- *List(en) + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0010] occurrences matches {0..1} matches { -- Trötthet + value matches { + 1|[local::at0005], -- Helt opåverkad + 2|[local::at0006], -- Trötthet vid mer är måttlig ansträngning tex. vid hastig promenad eller i backar + 3|[local::at0007], -- Trötthet vid lättare ansträngning, tex. på plan mark eller när Du klär av/på dig + 4|[local::at0008] -- Trötthet i vila + } + } + ELEMENT[at0009] occurrences matches {0..1} matches { -- Andfåddhet + value matches { + 1|[local::at0012], -- Helt opåverkad + 2|[local::at0013], -- Andfåddhet vid mer är måttlig ansträngning tex. vid hastig promenad eller i backar + 3|[local::at0014], -- Andfåddhet vid lättare ansträngning, tex. på plan mark eller när Du klär av/på dig + 4|[local::at0015] -- Andfåddhet i vila + } + } + ELEMENT[at0004] occurrences matches {0..1} matches { -- Allvarlighetsgrad, NYHA + value matches { + 1|[local::at0016], -- NYHA I + 2|[local::at0017], -- NYHA II + 3|[local::at0018], -- NYHA III + 4|[local::at0019], -- NYHA IV + 5|[local::at0011] -- Okänt + } + } + } + } + } + } + } + } + } + } + +ontology + terminologies_available = <"SNOMED-CT", ...> + term_definitions = < + ["sv"] = < + items = < + ["at0000"] = < + text = <"hjärtsvikt-allvarlighetsgrad"> + description = <"Funktionsbedömning vid hjärtsvikt graderad i fyra klasser enligt New York Heart Association (NYHA) +"> + > + ["at0001"] = < + text = <"*Event Series(en)"> + description = <"*@ internal @(en)"> + > + ["at0002"] = < + text = <"*Any event(en)"> + description = <"**(en)"> + > + ["at0003"] = < + text = <"*List(en)"> + description = <"*@ internal @(en)"> + > + ["at0004"] = < + text = <"Allvarlighetsgrad, NYHA"> + description = <"**(en)"> + > + ["at0005"] = < + text = <"Helt opåverkad"> + description = <"Nedsatt vänsterkammarfunktion utan symtom."> + > + ["at0006"] = < + text = <"Trötthet vid mer är måttlig ansträngning tex. vid hastig promenad eller i backar"> + description = <"Symtom vid mer än måttlig ansträngning."> + > + ["at0007"] = < + text = <"Trötthet vid lättare ansträngning, tex. på plan mark eller när Du klär av/på dig "> + description = <"Symtom vid lätt till måttlig ansträngning (från gång i lätt uppförsbacke till av- och påklädning)."> + > + ["at0008"] = < + text = <"Trötthet i vila"> + description = <"Symtom i vila. Ökande symtom vid minsta aktivitet. Individer i denna funktionsgrupp är sängliggande större delen av tiden."> + > + ["at0009"] = < + text = <"Andfåddhet"> + description = <"Andfåddhet"> + > + ["at0010"] = < + text = <"Trötthet"> + description = <"Trötthet"> + > + ["at0011"] = < + text = <"Okänt"> + description = <"NYHA-klass okänd"> + > + ["at0012"] = < + text = <"Helt opåverkad"> + description = <"Nedsatt vänsterkammarfunktion utan symtom."> + > + ["at0013"] = < + text = <"Andfåddhet vid mer är måttlig ansträngning tex. vid hastig promenad eller i backar"> + description = <"Symtom vid mer än måttlig ansträngning."> + > + ["at0014"] = < + text = <"Andfåddhet vid lättare ansträngning, tex. på plan mark eller när Du klär av/på dig "> + description = <"Symtom vid lätt till måttlig ansträngning (från gång i lätt uppförsbacke till av- och påklädning)."> + > + ["at0015"] = < + text = <"Andfåddhet i vila"> + description = <"Symtom i vila. Ökande symtom vid minsta aktivitet. Individer i denna funktionsgrupp är sängliggande större delen av tiden."> + > + ["at0016"] = < + text = <"NYHA I"> + description = <"Nedsatt vänsterkammarfunktion utan symtom."> + > + ["at0017"] = < + text = <"NYHA II"> + description = <"Symtom vid mer än måttlig ansträngning."> + > + ["at0018"] = < + text = <"NYHA III"> + description = <"Symtom vid lätt till måttlig ansträngning (från gång i lätt uppförsbacke till av- och påklädning)."> + > + ["at0019"] = < + text = <"NYHA IV"> + description = <"Symtom i vila. Ökande symtom vid minsta aktivitet. Individer i denna funktionsgrupp är sängliggande större delen av tiden."> + > + > + > + > + term_bindings = < + ["SNOMED-CT"] = < + items = < + ["at0005"] = <[SNOMED-CT::420300004]> + ["at0006"] = <[SNOMED-CT::421704003]> + ["at0007"] = <[SNOMED-CT::420913000]> + ["at0008"] = <[SNOMED-CT::422293003]> + ["at0009"] = <[SNOMED-CT::831000053909]> + ["at0010"] = <[SNOMED-CT::841000053901]> + ["at0011"] = <[SNOMED-CT::821000053907]> + > + > + > 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 new file mode 100644 index 00000000..855cb770 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-OBSERVATION.lab_test.v1.adl @@ -0,0 +1,250 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.lab_test.v1 + +concept + [at0000] -- Laboratory test result +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"Dr Ian McNicoll"> + ["organisation"] = <"openEHR Archetype Editorial Group / Ocean Informatics"> + ["email"] = <"ian.mcnicoll@oceaninformatics.com"> + ["date"] = <"27/01/2009"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"Generic entry to contain a laboratory test. This is abstract archetype which will normally be specialised but may be used for very simple reporting formats. + + + +"> + use = <"Normally used only as the basis for further specialisation but is suitable for very simple tests with only a free text conclusion. Will generally be used in combination with archetypes representing other parts of the laboratory test ordering and processing process to form a full lab test report."> + keywords = <"lab", "pathology", "biochemistry", "haematology", "microbiology", "immunology", "laboratory"> + misuse = <"Do not use for standard value-driven lab tests such as haematology and biochemistry tests. OBSERVATION.lab_test-itemised.v1. Other specialisations may be more appropriate for structured reports such as for microbiology or histopathology."> + copyright = <"copyright (c) 2009 openEHR Foundation"> + > + > + lifecycle_state = <"Initial"> + other_contributors = <"Heather Leslie AEG / Ocean Infomatics", "Sam Heard Ocean Informatics"> + other_details = < + ["MD5-CAM-1.0.1"] = <"3F7F820218B30C49034A1974FBE85505"> + ["references"] = <""> + > + +definition + OBSERVATION[at0000] matches { -- Laboratory test result + 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 { + ELEMENT[at0005] occurrences matches {0..1} matches { -- Test name + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0077] occurrences matches {0..1} matches { -- Diagnostic service + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0073] occurrences matches {0..1} matches { -- Test status + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0037, -- Interim + at0038, -- Final + at0039, -- Supplementary + at0040, -- Corrected (amended) + at0074] -- Aborted + } + } + } + } + allow_archetype CLUSTER[at0065] occurrences matches {0..*} matches { -- Test specimen detail + include + archetype_id/value matches {/openEHR-EHR-CLUSTER\.specimen\.v1/} + exclude + archetype_id/value matches {/.*/} + } + ELEMENT[at0078] occurrences matches {0..*} matches {*} + ELEMENT[at0076] occurrences matches {0..1} matches { -- Additional comment + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0057] occurrences matches {0..1} matches { -- Overall conclusion + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0010] occurrences matches {0..*} matches { -- Multimedia representation + value matches { + DV_MULTIMEDIA matches { + media_type matches {[openEHR::]} + } + } + } + ELEMENT[at0070] occurrences matches {0..1} matches {*} + } + } + } + } + } + } + } + protocol matches { + ITEM_TREE[at0004] matches { -- Tree + items cardinality matches {0..*; unordered} matches { + CLUSTER[at0013] occurrences matches {0..1} matches { -- Test identification + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0062] occurrences matches {0..1} matches { -- Requester order ID + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0063] occurrences matches {0..1} matches { -- Provider order ID + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0068] occurrences matches {0..1} matches { -- Laboratory test ID + value matches { + DV_TEXT matches {*} + } + } + allow_archetype CLUSTER[at0017] occurrences matches {0..*} matches { -- Laboratory details + include + archetype_id/value matches {/openEHR-EHR-CLUSTER\.organisation\.v1/} + exclude + archetype_id/value matches {/.*/} + } + } + } + ELEMENT[at0075] occurrences matches {0..1} matches { -- Datetime result issued + value matches { + DV_DATE_TIME matches {*} + } + } + } + } + } + } + + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Laboratory test result"> + description = <"Abstract laboratory test archetype which should not generally be used directly but acts as a parent for a number of specialised archetypes to represent typical test types e.g histopathology, microbiology and generic itemised test results such as haematology and biochemistry. "> + > + ["at0001"] = < + text = <"Event Series"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Any event"> + description = <"*"> + > + ["at0003"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0004"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0005"] = < + text = <"Test name"> + description = <"A specific identifier for this result - often a coded term e.g from LOINC or SNOMED"> + > + ["at0010"] = < + text = <"Multimedia representation"> + description = <"Representations of the whole test in mutlimedia e.g image, audio, video."> + > + ["at0013"] = < + text = <"Test identification"> + description = <"Unique identifiers used in delivery of the care process."> + > + ["at0017"] = < + text = <"Laboratory details "> + description = <"Demographic details of the laboratory with responsibility for the test. Details of secondary laboratories may also be included."> + > + ["at0037"] = < + text = <"Interim"> + description = <"This is an initial or interim result - further updates are anticipated"> + > + ["at0038"] = < + text = <"Final"> + description = <"This is the final result. No further alterations are anticipated"> + > + ["at0039"] = < + text = <"Supplementary"> + description = <"This is a supplememtary result in addition to the Interim result"> + > + ["at0040"] = < + text = <"Corrected (amended)"> + description = <"This is a Correction which should replace any previous results"> + > + ["at0057"] = < + text = <"Overall conclusion"> + description = <"An overall interpretative comment on this test."> + > + ["at0062"] = < + text = <"Requester order ID"> + description = <"The ID assigned to the test order by the order filler, usually by the (LIS) Laboratory Information System. Equivalent to the DICOM Accession Number and NEHTA Laboratory Request Identifier."> + > + ["at0063"] = < + text = <"Provider order ID"> + description = <"The ID assigned to the order by the order requester. Equivalent to the NEHTA Requester Order Identifier"> + > + ["at0065"] = < + text = <"Test specimen detail "> + description = <"Details of the specimen being reported where all individual results are derived from the same specimen"> + > + ["at0068"] = < + text = <"Laboratory test ID"> + description = <"The identifier given to the laboratory test result of a pathology +investigation."> + > + ["at0070"] = < + text = <"Structured narrative representation"> + description = <"A parsable representation of the entire test result. Equvalent to the NEHTA report or CDA narrative block,, and may contain references to paths within the archetype"> + > + ["at0073"] = < + text = <"Test status"> + description = <"The status of the test as a whole."> + > + ["at0074"] = < + text = <"Aborted"> + description = <"*"> + > + ["at0075"] = < + text = <"Datetime result issued"> + description = <"The date or date and time that the result was issued for the current +‘results status’. "> + comment = <"The date and time related to the results status is +useful for version control and cumulative results for the report."> + > + ["at0076"] = < + text = <"Additional comment"> + description = <"General comments on the test e.g. complicating factors. Any 'diagnostic' or interpretive commetns should be recorded under ' Overall Conclusion'."> + > + ["at0077"] = < + text = <"Diagnostic service"> + description = <"The type of diagnostic service"> + > + ["at0078"] = < + text = <"Test result"> + description = <"The result of the test."> + > + > + > + > 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 new file mode 100644 index 00000000..d2816d01 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-OBSERVATION.waist_hip.v2.adl @@ -0,0 +1,129 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.waist_hip.v2 + +concept + [at0000] -- Waist and hip circumference +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["organisation"] = <"Ocean Informatics"> + ["name"] = <"Heather Leslie"> + ["date"] = <"12/10/2007"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"To record the waist (or girth) and hip circumference and waist/hip ratio"> + use = <""> + keywords = <"waist", "hip"> + misuse = <""> + copyright = <"copyright (c) 2009 openEHR Foundation"> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"9DA698CBBBF5EDDDCF52C7D2E4E69BDD"> + > + +definition + OBSERVATION[at0000] matches { -- Waist and hip circumference + 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_LIST[at0003] matches { -- List + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0004] occurrences matches {0..1} matches { -- Waist circumference + value matches { + C_DV_QUANTITY < + property = <[openehr::122]> + list = < + ["1"] = < + units = <"cm"> + > + ["2"] = < + units = <"in"> + > + > + > + } + } + ELEMENT[at0005] occurrences matches {0..1} matches { -- Hip circumference + value matches { + C_DV_QUANTITY < + property = <[openehr::122]> + list = < + ["1"] = < + units = <"cm"> + magnitude = <|>=0.0|> + precision = <|1|> + > + > + > + } + } + ELEMENT[at0006] occurrences matches {0..1} matches { -- Waist:hip ratio + value matches { + DV_PROPORTION matches { + type matches {1} + } + } + } + } + } + } + } + } + } + } + } + +ontology + terminologies_available = <"SNOMED-CT", ...> + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Waist and hip circumference"> + description = <"The waist (or girth) and hip circumference"> + > + ["at0001"] = < + text = <"Event Series"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Any event"> + description = <"Timing event"> + > + ["at0003"] = < + text = <"List"> + description = <"@ internal @"> + > + ["at0004"] = < + text = <"Waist circumference"> + description = <"The waist circumference measured at or above the umbilicus"> + > + ["at0005"] = < + text = <"Hip circumference"> + description = <"Measurement of body circumference at the widest point of the buttocks"> + > + ["at0006"] = < + text = <"Waist:hip ratio"> + description = <"Ratio with unitary denominator"> + > + > + > + > + term_bindings = < + ["SNOMED-CT"] = < + items = < + ["at0004"] = <[SNOMED-CT::396552003]> + ["at0005"] = <[SNOMED-CT::284472007]> + ["at0006"] = <[SNOMED-CT::248367009]> + > + > + > 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 new file mode 100644 index 00000000..ec030d28 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.ad_hoc_heading.v1.adl @@ -0,0 +1,40 @@ +archetype (adl_version=1.4) + openEHR-EHR-SECTION.ad_hoc_heading.v1 + +concept + [at0000] -- Heading +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <""> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"ad hoc heading"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"0"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"6211E600D00A019604319C19B8303CF6"> + > + +definition + SECTION[at0000] matches {*} + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Heading"> + description = <"An ad-hoc heading"> + > + > + > + > 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 new file mode 100644 index 00000000..580d68a0 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.find_largest_node_id.v1.adl @@ -0,0 +1,62 @@ +archetype (adl_version=1.4) + openEHR-EHR-SECTION.find_largest_node_id.v1 + +concept + [at0000] -- Heading +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <""> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"ad hoc heading"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"0"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"6211E600D00A019604319C19B8303CF6"> + > + +definition + SECTION[at0000] matches { + items cardinality matches {0..*; ordered} matches { + SECTION[at0001] matches { + items cardinality matches {0..*; ordered} matches { + SECTION[at0002] matches { + items cardinality matches {0..*; ordered} matches { + SECTION[at0003] matches { + items cardinality matches {0..*; ordered} matches { + SECTION[at0004] matches { + name matches {"five"} + } + } + name matches {"four"} + } + } + name matches {"three"} + } + } + name matches {"two"} + } + } + name matches {"one"} + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Heading"> + description = <"An ad-hoc heading"> + > + > + > + > 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 new file mode 100644 index 00000000..a9d87910 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.find_largest_node_id_2.v1.adl @@ -0,0 +1,62 @@ +archetype (adl_version=1.4) + openEHR-EHR-SECTION.find_largest_node_id.v1 + +concept + [at0000] -- Heading +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <""> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"ad hoc heading"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"0"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"6211E600D00A019604319C19B8303CF6"> + > + +definition + SECTION[at0000] matches { + items cardinality matches {0..*; ordered} matches { + SECTION[at0010] matches { + items cardinality matches {0..*; ordered} matches { + SECTION[at0002] matches { + items cardinality matches {0..*; ordered} matches { + SECTION[at0003] matches { + items cardinality matches {0..*; ordered} matches { + SECTION[at0004] matches { + name matches {"five"} + } + } + name matches {"four"} + } + } + name matches {"three"} + } + } + name matches {"two"} + } + } + name matches {"one"} + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Heading"> + description = <"An ad-hoc heading"> + > + > + > + > 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 new file mode 100644 index 00000000..1f89f974 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.medications.v1.adl @@ -0,0 +1,52 @@ +archetype (adl_version=1.4) + openEHR-EHR-SECTION.medications.v1 + +concept + [at0000] -- Medications + +language + original_language = <[ISO_639-1::en]> + +description + original_author = < + ["name"] = <"Sam Heard"> + ["organisation"] = <"Ocean Informatics"> + ["date"] = <"9/01/2007"> + ["email"] = <"sam.heard@oceaninformatics.biz"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"A heading for medications"> + use = <"Only contains medications by constraint"> + misuse = <""> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <> + +definition + SECTION[at0000] matches { -- Medications + items cardinality matches {0..*; unordered} matches { + allow_archetype INSTRUCTION occurrences matches {0..1} matches { + include + domain_concept matches {/medication\.v1/} + exclude + domain_concept matches {/.*/} + } + } + } + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + description = <"A section containing medication orders only"> + text = <"Medications"> + > + > + > + > 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 new file mode 100644 index 00000000..2dc22cd9 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.more_nested_sections.v1.adl @@ -0,0 +1,62 @@ +archetype (adl_version=1.4) + openEHR-EHR-SECTION.nested_sections.v1 + +concept + [at0000] -- Heading +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <""> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"ad hoc heading"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"0"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"6211E600D00A019604319C19B8303CF6"> + > + +definition + SECTION[at0000] matches { + items cardinality matches {0..*; ordered} matches { + SECTION[openEHR-EHR-SECTION.ad_hoc_heading.v1] matches { + items cardinality matches {0..*; ordered} matches { + SECTION[openEHR-EHR-SECTION.ad_hoc_heading.v1] matches { + items cardinality matches {0..*; ordered} matches { + SECTION[openEHR-EHR-SECTION.ad_hoc_heading.v1] matches { + items cardinality matches {0..*; ordered} matches { + SECTIONopenEHR-EHR-SECTION.ad_hoc_heading.v1] matches { + name matches {"five"} + } + } + name matches {"four"} + } + } + name matches {"three"} + } + } + name matches {"two"} + } + } + name matches {"one"} + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Heading"> + description = <"An ad-hoc heading"> + > + > + > + > 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 new file mode 100644 index 00000000..a13f55f6 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.nested_sections.v1.adl @@ -0,0 +1,48 @@ +archetype (adl_version=1.4) + openEHR-EHR-SECTION.nested_sections.v1 + +concept + [at0000] -- Heading +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <""> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"ad hoc heading"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"0"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"6211E600D00A019604319C19B8303CF6"> + > + +definition + SECTION[at0000] matches { + items cardinality matches {0..*; ordered} matches { + SECTION[openEHR-EHR-SECTION.ad_hoc_heading.v1] matches { + name matches {"two"} + } + } + name matches {"one"} + } + + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Heading"> + description = <"An ad-hoc heading"> + > + > + > + > 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 new file mode 100644 index 00000000..74a93340 --- /dev/null +++ b/oet-parser/src/test/resources/archetypes/openEHR-EHR-SECTION.simple_section_name.v1.adl @@ -0,0 +1,46 @@ +archetype (adl_version=1.4) + openEHR-EHR-SECTION.simple_section_name.v1 + +concept + [at0000] -- Heading +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <""> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"ad hoc heading"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"0"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"6211E600D00A019604319C19B8303CF6"> + > + +definition + SECTION[at0000] matches { + name matches { + DV_TEXT matches { + value matches { "single" } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Heading"> + description = <"An ad-hoc heading"> + > + > + > + > diff --git a/oet-parser/src/test/resources/log4j.properties b/oet-parser/src/test/resources/log4j.properties new file mode 100644 index 00000000..1fd90dee --- /dev/null +++ b/oet-parser/src/test/resources/log4j.properties @@ -0,0 +1,11 @@ +# Set root logger level to ERROR and its only appender to stdout. +log4j.rootLogger=ERROR, 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 + +# logging level +log4j.logger.org.openehr.am.template.Flattener= +log4j.logger.org.openehr.am.template.TermMap= +log4j.logger.org.openehr.am.template.PathMap= \ No newline at end of file diff --git a/oet-parser/src/test/resources/templates/prescription.oet b/oet-parser/src/test/resources/templates/prescription.oet new file mode 100644 index 00000000..d60d235c --- /dev/null +++ b/oet-parser/src/test/resources/templates/prescription.oet @@ -0,0 +1,12 @@ + + diff --git a/oet-parser/src/test/resources/templates/test_action_description.oet b/oet-parser/src/test/resources/templates/test_action_description.oet new file mode 100644 index 00000000..d32e5954 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_action_description.oet @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/oet-parser/src/test/resources/templates/test_annotation.oet b/oet-parser/src/test/resources/templates/test_annotation.oet new file mode 100644 index 00000000..fe638927 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_annotation.oet @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/oet-parser/src/test/resources/templates/test_composition.oet b/oet-parser/src/test/resources/templates/test_composition.oet new file mode 100644 index 00000000..6fbd035d --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_composition.oet @@ -0,0 +1,9 @@ + + diff --git a/oet-parser/src/test/resources/templates/test_composition2.oet b/oet-parser/src/test/resources/templates/test_composition2.oet new file mode 100644 index 00000000..8f9312a2 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_composition2.oet @@ -0,0 +1,9 @@ + + diff --git a/oet-parser/src/test/resources/templates/test_composition3.oet b/oet-parser/src/test/resources/templates/test_composition3.oet new file mode 100644 index 00000000..09463472 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_composition3.oet @@ -0,0 +1,11 @@ + + diff --git a/oet-parser/src/test/resources/templates/test_composition4.oet b/oet-parser/src/test/resources/templates/test_composition4.oet new file mode 100644 index 00000000..4dc41e5b --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_composition4.oet @@ -0,0 +1,9 @@ + + diff --git a/oet-parser/src/test/resources/templates/test_composition5.oet b/oet-parser/src/test/resources/templates/test_composition5.oet new file mode 100644 index 00000000..0e755924 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_composition5.oet @@ -0,0 +1,12 @@ + + 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 new file mode 100644 index 00000000..5d26a8be --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_default_coded_name.oet @@ -0,0 +1,8 @@ + + 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 new file mode 100644 index 00000000..626e71c4 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_default_coded_text.oet @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/oet-parser/src/test/resources/templates/test_default_text.oet b/oet-parser/src/test/resources/templates/test_default_text.oet new file mode 100644 index 00000000..62ee5ba3 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_default_text.oet @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/oet-parser/src/test/resources/templates/test_hybrid_path.oet b/oet-parser/src/test/resources/templates/test_hybrid_path.oet new file mode 100644 index 00000000..48ed702d --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_hybrid_path.oet @@ -0,0 +1,12 @@ + + diff --git a/oet-parser/src/test/resources/templates/test_max_value.oet b/oet-parser/src/test/resources/templates/test_max_value.oet new file mode 100644 index 00000000..a7ec9468 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_max_value.oet @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/oet-parser/src/test/resources/templates/test_min_value.oet b/oet-parser/src/test/resources/templates/test_min_value.oet new file mode 100644 index 00000000..e9df7780 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_min_value.oet @@ -0,0 +1,8 @@ + + \ No newline at end of file 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 new file mode 100644 index 00000000..de227d5a --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_more_nested_section.oet @@ -0,0 +1,14 @@ + + \ No newline at end of file diff --git a/oet-parser/src/test/resources/templates/test_multiple_constraint.oet b/oet-parser/src/test/resources/templates/test_multiple_constraint.oet new file mode 100644 index 00000000..02dfffed --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_multiple_constraint.oet @@ -0,0 +1,12 @@ + + \ No newline at end of file diff --git a/oet-parser/src/test/resources/templates/test_multiple_constraint2.oet b/oet-parser/src/test/resources/templates/test_multiple_constraint2.oet new file mode 100644 index 00000000..a2ebdc2b --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_multiple_constraint2.oet @@ -0,0 +1,14 @@ + + \ No newline at end of file diff --git a/oet-parser/src/test/resources/templates/test_multiple_constraint3.oet b/oet-parser/src/test/resources/templates/test_multiple_constraint3.oet new file mode 100644 index 00000000..1b06e03d --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_multiple_constraint3.oet @@ -0,0 +1,12 @@ + + \ No newline at end of file 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 new file mode 100644 index 00000000..4e42b78d --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_name_default_coded_text.oet @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/oet-parser/src/test/resources/templates/test_named_path.oet b/oet-parser/src/test/resources/templates/test_named_path.oet new file mode 100644 index 00000000..37a5d7f5 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_named_path.oet @@ -0,0 +1,8 @@ + + diff --git a/oet-parser/src/test/resources/templates/test_named_path2.oet b/oet-parser/src/test/resources/templates/test_named_path2.oet new file mode 100644 index 00000000..04cc1a30 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_named_path2.oet @@ -0,0 +1,9 @@ + + diff --git a/oet-parser/src/test/resources/templates/test_named_path3.oet b/oet-parser/src/test/resources/templates/test_named_path3.oet new file mode 100644 index 00000000..be668381 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_named_path3.oet @@ -0,0 +1,9 @@ + + diff --git a/oet-parser/src/test/resources/templates/test_nested_section.oet b/oet-parser/src/test/resources/templates/test_nested_section.oet new file mode 100644 index 00000000..66d6eaec --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_nested_section.oet @@ -0,0 +1,8 @@ + + \ No newline at end of file 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 new file mode 100644 index 00000000..035636d5 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_nested_section_evaluation.oet @@ -0,0 +1,10 @@ + + \ No newline at end of file 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 new file mode 100644 index 00000000..0ab72711 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_quantity_constraint_excluded_units.oet @@ -0,0 +1,12 @@ + + \ No newline at end of file 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 new file mode 100644 index 00000000..f7fb4704 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_quantity_constraint_included_units.oet @@ -0,0 +1,12 @@ + + \ No newline at end of file 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 new file mode 100644 index 00000000..f7fb4704 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_quantity_constraint_included_units2.oet @@ -0,0 +1,12 @@ + + \ No newline at end of file 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 new file mode 100644 index 00000000..dfaab7da --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_quantity_constraint_included_units3.oet @@ -0,0 +1,12 @@ + + \ No newline at end of file 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 new file mode 100644 index 00000000..28d0d64c --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_quantity_constraint_magnitude.oet @@ -0,0 +1,18 @@ + + \ No newline at end of file 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 new file mode 100644 index 00000000..49f8a982 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_quantity_constraint_mixed.oet @@ -0,0 +1,21 @@ + + 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 new file mode 100644 index 00000000..0005b4d6 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_quantity_constraint_precision.oet @@ -0,0 +1,16 @@ + + \ No newline at end of file diff --git a/oet-parser/src/test/resources/templates/test_section_evaluation.oet b/oet-parser/src/test/resources/templates/test_section_evaluation.oet new file mode 100644 index 00000000..96ac559c --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_section_evaluation.oet @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/oet-parser/src/test/resources/templates/test_section_evaluation2.oet b/oet-parser/src/test/resources/templates/test_section_evaluation2.oet new file mode 100644 index 00000000..aaacc3c6 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_section_evaluation2.oet @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/oet-parser/src/test/resources/templates/test_section_instruction.oet b/oet-parser/src/test/resources/templates/test_section_instruction.oet new file mode 100644 index 00000000..77131151 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_section_instruction.oet @@ -0,0 +1,8 @@ + + \ No newline at end of file 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 new file mode 100644 index 00000000..4aa48028 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_section_instruction_tree.oet @@ -0,0 +1,10 @@ + + \ No newline at end of file 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 new file mode 100644 index 00000000..15606f8f --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_set_cardinality_with_prohibited_node.oet @@ -0,0 +1,12 @@ + + \ No newline at end of file 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 new file mode 100644 index 00000000..e166a7f9 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_set_cardinality_with_prohibited_node2.oet @@ -0,0 +1,15 @@ + + \ No newline at end of file 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 new file mode 100644 index 00000000..40073962 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_set_cardinality_with_prohibited_node3.oet @@ -0,0 +1,12 @@ + + \ No newline at end of file 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 new file mode 100644 index 00000000..f4a814f9 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_set_evaluation_name.oet @@ -0,0 +1,8 @@ + + \ No newline at end of file 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 new file mode 100644 index 00000000..f4a814f9 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_set_evaluation_name_.oet @@ -0,0 +1,8 @@ + + \ No newline at end of file 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 new file mode 100644 index 00000000..077da071 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_set_mixed_constraints.oet @@ -0,0 +1,28 @@ + + + + + + \ No newline at end of file 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 new file mode 100644 index 00000000..2050b00f --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_set_multiple_evaluation_name.oet @@ -0,0 +1,10 @@ + + \ No newline at end of file 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 new file mode 100644 index 00000000..45aa227c --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_set_named_node_constraint_without_name.oet @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file 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 new file mode 100644 index 00000000..61393cf4 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_set_occurrences_and_name.oet @@ -0,0 +1,15 @@ + + \ No newline at end of file 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 new file mode 100644 index 00000000..c3f6fc6f --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_set_occurrences_without_min.oet @@ -0,0 +1,8 @@ + + \ No newline at end of file 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 new file mode 100644 index 00000000..bffae1e5 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_set_occurrences_without_min2.oet @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/oet-parser/src/test/resources/templates/test_simple_section.oet b/oet-parser/src/test/resources/templates/test_simple_section.oet new file mode 100644 index 00000000..9c54b30f --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_simple_section.oet @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/oet-parser/src/test/resources/templates/test_text_constraints.oet b/oet-parser/src/test/resources/templates/test_text_constraints.oet new file mode 100644 index 00000000..08bdcb32 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_text_constraints.oet @@ -0,0 +1,14 @@ + + \ No newline at end of file diff --git a/oet-parser/src/test/resources/templates/test_text_name.oet b/oet-parser/src/test/resources/templates/test_text_name.oet new file mode 100644 index 00000000..2b800907 --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_text_name.oet @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/oet-parser/src/test/resources/templates/test_utf8_encoding.oet b/oet-parser/src/test/resources/templates/test_utf8_encoding.oet new file mode 100644 index 00000000..1e50355a --- /dev/null +++ b/oet-parser/src/test/resources/templates/test_utf8_encoding.oet @@ -0,0 +1,8 @@ + + diff --git a/oet-parser/src/test/resources/terms.txt b/oet-parser/src/test/resources/terms.txt new file mode 100644 index 00000000..9b1b15cf --- /dev/null +++ b/oet-parser/src/test/resources/terms.txt @@ -0,0 +1,7 @@ +ATC::C07AA03::Pindolol +ATC::C07AA05::Propranolol +ATC::C07AA06::Timolol +ATC::C07AA07::Sotalol +ATC::C07AA28::Karvedilol +SNOMED-CT::10018::Loopdiuretika +SNOMED-CT::10019::Thiazider \ No newline at end of file diff --git a/oet-parser/src/test/resources/terms_path.txt b/oet-parser/src/test/resources/terms_path.txt new file mode 100644 index 00000000..9f8bc8f5 --- /dev/null +++ b/oet-parser/src/test/resources/terms_path.txt @@ -0,0 +1,7 @@ +ATC::C07AA03::Pindolol::/path1 +ATC::C07AA05::Propranolol::/path1 +ATC::C07AA06::Timolol::/path1 +ATC::C07AA07::Sotalol::/path1 +ATC::C07AA28::Karvedilol::/path1 +SNOMED-CT::10018::Loopdiuretika::/path1 +SNOMED-CT::10019::Thiazider::/path1 \ No newline at end of file diff --git a/oet-parser/src/test/resources/test_path_map.txt b/oet-parser/src/test/resources/test_path_map.txt new file mode 100644 index 00000000..a8384254 --- /dev/null +++ b/oet-parser/src/test/resources/test_path_map.txt @@ -0,0 +1,3 @@ +# some comment +key1=/path1 +key2=/path2[at0001 and name/value='text'] \ No newline at end of file diff --git a/openehr-aom/docs/changes.txt b/openehr-aom/docs/changes.txt new file mode 100644 index 00000000..3ae58e9f --- /dev/null +++ b/openehr-aom/docs/changes.txt @@ -0,0 +1,25 @@ +2006/1/20 +.updated CDomainType to add default and assumed value +.removed CCount and domain package + +2006/1/09 +.take away unnecessary rmTypeName from CPrimitiveObject constructor + +2006/1/07 +.Archetype extends AuthoredResource + +2006/12/30 +.added parent attribute to CObject and its children +.adjusted the constructor of CDomainType to support allowAny +.removed obsolete CDomainType concrete classes in the AOM package + +2006/12/16 +.added convenient factory methods in ExpressionLeaf +.added STRING as constant type in ExpressionItem + +2007/04/18 +.added class ArchetypeTerm +.added constraintDefinition() and termDefinition() in ArchetypeOntology + +2007/05/29 +.fixed a path related issue in CAttribute \ No newline at end of file diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml new file mode 100644 index 00000000..862b9fad --- /dev/null +++ b/openehr-aom/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5-SNAPSHOT + + openehr-aom + jar + openEHR Archetype Object Model + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2004 + + Java implementation of the openEHR Archetype Object Model + + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + commons-lang + commons-lang + 2.6 + + + junit + junit + 3.8.1 + test + + + 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 new file mode 100644 index 00000000..3ede3ff4 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/Archetype.java @@ -0,0 +1,521 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Archetype" + * keywords: "archetype" + * + * 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/am/archetype/Archetype.java $" + * revision: "$LastChangedRevision: 54 $" + * last_change: "$LastChangedDate: 2006-08-11 16:37:33 +0200 (Fri, 11 Aug 2006) $" + */ +package org.openehr.am.archetype; + +import java.util.*; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; +import org.openehr.am.archetype.assertion.Assertion; +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.CComplexObject; +import org.openehr.am.archetype.constraintmodel.CObject; +import org.openehr.am.archetype.ontology.ArchetypeOntology; +import org.openehr.am.archetype.ontology.ArchetypeTerm; +import org.openehr.rm.common.generic.RevisionHistory; +import org.openehr.rm.common.resource.AuthoredResource; +import org.openehr.rm.common.resource.ResourceDescription; +import org.openehr.rm.common.resource.TranslationDetails; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.identification.ArchetypeID; +import org.openehr.rm.support.identification.HierObjectID; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * Archetype equivalent to ARCHETYPED class in Common reference model. Defines + * semantics of identfication, lifecycle, versioning, composition and + * specialisation. Instances of this class are immutable. + *

+ * Also has logic for construction and validation of reference model instance + * constrained by this archetype + * + * @author Rong Chen + * @version 1.0 + */ + +public final class Archetype extends AuthoredResource { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Constructs an Archetype + * + * @param adlVersion null if unspecified + * @param id + * @param parentId + * @param concept + * @param originalLanguage + * @param translations + * @param description + * @param revisionHistory + * @param isControlled + * @param uid + * @param definition + * @param ontology + * @throws IllegalArgumentException if description null or ontology null + */ +public Archetype(String adlVersion, String id, String parentId, String concept, + CodePhrase originalLanguage, + Map translations, + ResourceDescription description, RevisionHistory revisionHistory, + boolean isControlled, HierObjectID uid, CComplexObject definition, + ArchetypeOntology ontology, Set invariants, + TerminologyService terminologyService) { + + super(originalLanguage, translations, description, revisionHistory, + isControlled, terminologyService); + + if (id == null) { + throw new IllegalArgumentException("archetypeId null"); + } + if (ontology == null) { + throw new IllegalArgumentException("ontology null"); + } + if (definition == null) { + throw new IllegalArgumentException("definition null"); + } + this.adlVersion = adlVersion; + this.archetypeId = new ArchetypeID(id); + this.uid = uid; + this.concept = concept; + this.parentArchetypeId = (parentId == null ? null : new ArchetypeID( + parentId)); + this.definition = definition; + this.ontology = ontology; + this.invariants = invariants; + this.pathNodeMap = new HashMap(); + this.pathInputMap = new HashMap(); + this.inputPathMap = new HashMap(); + this.nodeIdPathMap = new HashMap(); + reloadNodeMaps(); + } + + public Archetype copy() { + String parentId = + parentArchetypeId == null ? null : parentArchetypeId.toString(); + + Archetype archetype = new Archetype(adlVersion, archetypeId.toString(), + parentId, concept, getOriginalLanguage(), getTranslations(), + null, getRevisionHistory(), isControlled(), uid, + (CComplexObject) definition.copy(), ontology, invariants, null); + + reloadNodeMaps(); + + // set c_obj.parent()? + + return archetype; + } + + /** + * Reload node maps. It's required when archetype definition is + * modified after it's constructed by the parser. + */ + public void reloadNodeMaps() { + pathNodeMap.clear(); + pathInputMap.clear(); + inputPathMap.clear(); + nodeIdPathMap.clear(); + loadMaps(definition, true); + loadInternalRefs(definition, true, null, null); + } + + /** + * Set of language-independent paths extracted + * from archetype. Paths obey Xpath-like syntax + * and are formed from alternations of + * C_OBJECT.node_id and + * C_ATTRIBUTE.rm_attribute_name values. + * + * @return set of paths + */ + public Set physicalPaths() { + return pathNodeMap.keySet(); + } + + /** + * Set of language-dependent paths extracted + * from archetype. Paths obey the same syntax as + * physical_paths, but with node_ids replaced by + * their meanings from the ontology. + * + * @param language + * @return set of paths + */ + public Set logicalPaths(String language) { + // TODO + throw new org.apache.commons.lang.NotImplementedException(); + + } + + private void loadMaps(CObject node, boolean required) { + + if(node != null && node.path() != null) { + pathNodeMap.put(node.path(), node); + nodeIdPathMap.put(node.getNodeId(), node.path()); + } + if (!(node instanceof CComplexObject)) { + return; // other types of cobject + } + CComplexObject parent = (CComplexObject) node; + + if (parent.getAttributes() == null) { + return; // no attribute + } + for (CAttribute attribute : parent.getAttributes()) { + + + // pathNodeMap.put(attribute.path(), attribute); + + if (attribute.getExistence().equals( + CAttribute.Existence.NOT_ALLOWED)) { + continue; + } + if (attribute.getChildren() == null) { + continue; // no child + } + for (CObject child : attribute.getChildren()) { + loadMaps(child, required && node.isRequired() + && attribute.isRequired()); + } + } + } + + public Map getPathNodeMap() { + return pathNodeMap; + } + + public String getPathByNodeId(String nodeId) { + return nodeIdPathMap.get(nodeId); + } + + private void loadInternalRefs(CObject node, boolean required, String refPath, String baseTargetPath ) { + + if (node == null) { + return; // if the target wasn't found + } + if (refPath!= null && baseTargetPath != null && node.path() != null) { + String usenodePath = refPath + node.path().substring(baseTargetPath.length()); + pathNodeMap.put(usenodePath, node); + } + + if (node instanceof ArchetypeInternalRef) { + ArchetypeInternalRef ref = (ArchetypeInternalRef) node; + + ArchetypeConstraint target = node(ref.getTargetPath()); + if(target instanceof CObject) { + + String atpart =""; + if (!ref.path().endsWith("]" ) && ref.getTargetPath().endsWith("]")) { + atpart+= ref.getTargetPath().substring(ref.getTargetPath().lastIndexOf("[")); + } + loadInternalRefs((CObject)node(ref.getTargetPath()), required + && node.isRequired(), ref.path()+atpart, ref.getTargetPath()); + + } + } + + if (!(node instanceof CComplexObject)) { + return; // other types of cobject + } + CComplexObject parent = (CComplexObject) node; + + if (parent.getAttributes() == null) { + return; // no attribute + } + for (CAttribute attribute : parent.getAttributes()) { + if (attribute.getExistence().equals( + CAttribute.Existence.NOT_ALLOWED)) { + continue; + } + if (attribute.getChildren() == null) { + continue; // no child + } + for (CObject child : attribute.getChildren()) { + loadInternalRefs(child, required && node.isRequired() + && attribute.isRequired(), refPath, baseTargetPath); + + } + } + } + + /** + * ADL version if archteype was read in from an ADL sharable + * archetype. + * + * @return null if unspecified + */ + public String getAdlVersion() { + return adlVersion; + } + + /** + * Multi-axial identifier of this archetype in archetype space. + * + * @return archetypeId + */ + public ArchetypeID getArchetypeId() { + return archetypeId; + } + + /** + * OID identifier of this archetype. + * + * @return uid + */ + public HierObjectID getUid() { + return uid; + } + + /** + * The normative meaning of the archetype as a whole. + * + * @return concept code + */ + public String getConcept() { + return concept; + } + + /** + * The concept name of the archetype in language + * language; corresponds to the term definition of + * the concept attribute in the archetype ontology. + * + * @param language the language of the concept name + * @return concept name in the requested language or + * null if the language as a whole or the concept + * in that language does not exist. + */ + public String getConceptName(String language) { + ArchetypeTerm term = null; + + String conceptCode = this.getConcept(); + term = this.getOntology().termDefinition(language, conceptCode); + if (term == null) { + return null; + } + return term.getItem(ArchetypeTerm.TEXT); + } + + /** + * Identifier of the specialisation parent of this archetype. + * + * @return parent id + */ + public ArchetypeID getParentArchetypeId() { + return parentArchetypeId; + } + + /** + * Root node of this archetype + * + * @return definition + */ + public CComplexObject getDefinition() { + return definition; + } + + /** + * Invariant statements about this object. Statements are expressed in + * first order predicate logic, and usually refer to at least two + * attributes. + * + * @return invariants + */ + public Set getInvariants() { + return invariants == null ? null : Collections + .unmodifiableSet(invariants); + } + + /** + * Ontology definition of this archetype + * + * @return ontology + */ + public ArchetypeOntology getOntology() { + return ontology; + } + + /** + * Version of this archetype, extracted from id. + * + * @return version + */ + public String version() { + return archetypeId.versionID(); + } + + /** + * Version of predecessor archetype of this archetype, if any. + * + * @return previous version + */ + public String previousVersion() { + // todo: how to find the previous version? + return null; + } + + /** + * Return an object node or attribute at given path + * + * @param path + * @return null if node not found + */ + public ArchetypeConstraint node(String path) { + + // TODO complete new implementation of path-based node retrieval + // based on runtime object tree traverse. Map-based path retrieval + // need to be removed from the code + + return pathNodeMap.get(path); + } + + /** + * Updates the pathNodeMap with given cobj + * + * @param cobj + */ + public void updatePathNodeMap(CObject cobj) { + if(cobj != null) { + pathNodeMap.put(cobj.path(), cobj); + } + } + + /** + * Updates the pathNodeMap with given path and cobj + * + * @param path + * @param cobj + */ + public void updatePathNodeMap(String path, CObject cobj) { + if(cobj != null && path != null) { + pathNodeMap.put(path, cobj); + } + } + + /** + * Updates the pathNodeMap with given cobj + * + * @param cobj + */ + public void updatePathNodeMapRecursively(CObject cobj) { + updatePathNodeMap(cobj); + if(cobj instanceof CComplexObject) { + CComplexObject ccobj = (CComplexObject) cobj; + if(ccobj.getAttributes() == null) { + return; + } + for(CAttribute cattr : ccobj.getAttributes()) { + if(cattr.getChildren() != null) { + for(CObject child : cattr.getChildren()) { + updatePathNodeMapRecursively(child); + } + } + } + } + } + + /** + * String representation of this object + * + * @return string form + */ + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, + ToStringStyle.MULTI_LINE_STYLE); + } + + /** + * Find input name by node path + * + * @param path + * @return null if path unknown + */ + public String inputByPath(String path) { + return pathInputMap.get(path); + } + + /** + * Find node path by input name + * + * @param input + * @return null if input unknown + */ + public String pathByInput(String input) { + return inputPathMap.get(input); + } + + /* fields */ + private final String adlVersion; + + private final ArchetypeID archetypeId; + + private final HierObjectID uid; // added to adl in the same way as adl_version + + private final String concept; + + private final ArchetypeID parentArchetypeId; + + private final CComplexObject definition; + + private final ArchetypeOntology ontology; + + private final Set invariants; + + /* calculated fields */ + private final Map pathNodeMap; + + private final Map pathInputMap; + + private final Map inputPathMap; + + private final Map nodeIdPathMap; +} + +/* + * ***** 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) 2003-2009 + * 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-aom/src/main/java/org/openehr/am/archetype/assertion/Assertion.java b/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/Assertion.java new file mode 100644 index 00000000..6f78d470 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/Assertion.java @@ -0,0 +1,164 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Assertion" + * keywords: "archetype assertion" + * + * 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.archetype.assertion; + +import java.io.Serializable; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +/** + * Structural model of a typed first order predicate logic assertion, in the + * form of an expression tree, including optional variable definitions. + * + * @author Rong Chen + */ +public class Assertion implements Serializable{ + + /** + * Creates an Assertion with tag and expression + * + * @param tag optional null if unspecified + * @param expression not null + * @param stringExpression + * @param variables null if unspecified + * @throws IllegalArgumentException if tag empty, expression null, + * expression not boolean type + */ + public Assertion(String tag, ExpressionItem expression, + String stringExpression, List variables) { + + if(tag != null && StringUtils.isEmpty(tag)) { + throw new IllegalArgumentException("tag empty"); + } + if(expression == null) { + throw new IllegalArgumentException("expression null"); + } + + if( ! expression.isTypeBoolean()) { + throw new IllegalArgumentException("expression not boolean type"); + } + this.tag = tag; + this.expression = expression; + this.stringExpression = stringExpression; + this.variables = variables; + } + + /** + * Creates an Assertion without tag + * + * @param expression not null + * @param stringExpression + * @throws IllegalArgumentException if tag empty, expression null, + * expression not boolean type + */ + public Assertion(ExpressionItem expression, + String stringExpression) { + this(null, expression, stringExpression, null); + } + + public ExpressionItem getExpression() { + return expression; + } + + public String getStringExpression() { + return stringExpression; + } + + public String getTag() { + return tag; + } + + public List getVariables() { + return variables; + } + + /** + * Returns string expression of this assertion + * + * @return string expression + */ + public String toString() { + return stringExpression; + } + + /** + * Equals if two Assertion Objects have same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof Assertion )) return false; + + final Assertion cobj = (Assertion) o; + return new EqualsBuilder() + .append(tag, cobj.tag) + .append(expression, cobj.expression) + .append(stringExpression, cobj.stringExpression) + .append(variables, cobj.variables) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(7, 19) + .append(tag) + .append(expression) + .append(stringExpression) + .append(variables) + .toHashCode(); + } + + /* fields */ + private String tag; + private ExpressionItem expression; + private String stringExpression; + private List variables; +} + +/* + * ***** 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 Assertion.java + * + * The Initial Developer of the Original Code is Rong Chen. Portions created by + * the Initial Developer are Copyright (C) 2003-2010 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/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 new file mode 100644 index 00000000..8f3cadfc --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/AssertionVariable.java @@ -0,0 +1,97 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class AssertionVariable" + * keywords: "archetype assertion" + * + * 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.archetype.assertion; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +public class AssertionVariable { + + public AssertionVariable(String name, String definition) { + this.name = name; + this.definition = definition; + } + + public String getDefinition() { + return definition; + } + + public String getName() { + return name; + } + + /** + * Equals if two AssertionVariable Objects have same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof AssertionVariable )) return false; + + final AssertionVariable cobj = (AssertionVariable) o; + + return new EqualsBuilder() + .append(name, cobj.name) + .append(definition, cobj.definition) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder() + .append(name) + .append(definition) + .toHashCode(); + } + + private String name; + private String definition; +} +/* + * ***** 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 AssertionVariable.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2010 + * 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/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 new file mode 100644 index 00000000..94ca8991 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionBinaryOperator.java @@ -0,0 +1,121 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ExpressionBinaryOperator" + * keywords: "archetype assertion" + * + * 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.archetype.assertion; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +public class ExpressionBinaryOperator extends ExpressionOperator { + + public ExpressionBinaryOperator(String type, OperatorKind operator, + boolean precedenceOverridden, ExpressionItem leftOperand, + ExpressionItem rightOperand) { + super(type, operator, precedenceOverridden); + this.leftOperand = leftOperand; + this.rightOperand = rightOperand; + } + + public ExpressionItem getLeftOperand() { + return leftOperand; + } + + public ExpressionItem getRightOperand() { + return rightOperand; + } + + /** + * Equals if two ExpressionBinaryOperator Objects have same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof ExpressionBinaryOperator )) return false; + + final ExpressionBinaryOperator cobj = (ExpressionBinaryOperator) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(leftOperand, cobj.leftOperand) + .append(rightOperand, cobj.rightOperand) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(5, 23) + .appendSuper(super.hashCode()) + .append(leftOperand) + .append(rightOperand) + .toHashCode(); + } + + public String toString() { + StringBuffer buf = new StringBuffer(leftOperand.toString()); + buf.append(" "); + buf.append(getOperator().toString()); + + buf.append(" "); + + if(OperatorKind.OP_MATCHES.equals(getOperator())) { + buf.append("{"); + } + + buf.append(rightOperand.toString()); + + if(OperatorKind.OP_MATCHES.equals(getOperator())) { + buf.append("}"); + } + return buf.toString(); + } + + private ExpressionItem leftOperand; + private ExpressionItem rightOperand; +} +/* + * ***** 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 ExpressionBinaryOperator.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2010 + * 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/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 new file mode 100644 index 00000000..c0e8532d --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionItem.java @@ -0,0 +1,123 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ExpressionItem" + * keywords: "archetype assertion" + * + * 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.archetype.assertion; + +import java.io.Serializable; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +public abstract class ExpressionItem implements Serializable{ + + /** + * + */ + private static final long serialVersionUID = 1L; + //Possible type names of this item in the mathematical sense. For leaf nodes, must be the name of a + //primitive type, or else a reference model type. The type for any relational or boolean + //operator will be “Boolean”, while the type for any arithmetic operator, will be “Real” or “Integer”. (AOM spec for EXPR_ITEM) + public final static String BOOLEAN = "Boolean"; + public final static String REAL = "Real"; + public final static String INTEGER = "Integer"; + public final static String STRING = "String"; + public final static String ARCHETYPE = "Archetype"; //SG: Not sure this type makes sense? + public final static String RM = "RM"; //SG: Not sure this type makes sense? + + public ExpressionItem(String type) { + this.type = type; + } + + public String getType() { + return type; + } + + /** + * Checks if type is BOOLEAN + * + * @return true if type is BOOLEAN + */ + public boolean isTypeBoolean() { + return BOOLEAN.equals(type); + } + + /** + * Equals if two ExpressionItem Objects have same values + * + * @param o + * @return true if equals + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof ExpressionItem )) { + return false; + } + + final ExpressionItem cobj = (ExpressionItem) o; + + return new EqualsBuilder() + .append(type, cobj.type) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + @Override + public int hashCode() { + return new HashCodeBuilder(7, 19) + .append(type) + .toHashCode(); + } + + @Override + public abstract String toString(); + + private String type; +} +/* + * ***** 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 ExpressionItem.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2010 + * 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/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 new file mode 100644 index 00000000..3236a149 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionLeaf.java @@ -0,0 +1,179 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ExpressionLeaf" + * keywords: "archetype assertion" + * + * 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.archetype.assertion; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.am.archetype.constraintmodel.primitive.CString; + +public class ExpressionLeaf extends ExpressionItem { + + /** + * ReferenceType enum + */ + public enum ReferenceType { CONSTANT, ATTRIBUTE, FUNCTION, CONSTRAINT }; + + public ExpressionLeaf(String type, Object item, ReferenceType referenceType) { + super(type); + this.item = item; + this.referenceType = referenceType; + } + public Object getItem() { + return item; + } + public ReferenceType getReferenceType() { + return referenceType; + } + + /** + * Creates an expression leaf with integer constant + * + * @param i + * @return + */ + public static final ExpressionLeaf intConstant(int i) { + return new ExpressionLeaf(ExpressionItem.INTEGER, new Integer(i), + ExpressionLeaf.ReferenceType.CONSTANT); + } + + /** + * Creates an expression leaf with real constant + * + * @param d + * @return + */ + public static final ExpressionLeaf realConstant(double d) { + return new ExpressionLeaf(ExpressionItem.REAL, new Double(d), + ExpressionLeaf.ReferenceType.CONSTANT); + } + + /** + * Creates an expression leaf with string constant + * + * @param s + * @return + */ + public static final ExpressionLeaf stringConstant(String str) { + return new ExpressionLeaf(ExpressionItem.STRING, str, + ExpressionLeaf.ReferenceType.CONSTANT); + } + + /** + * Creates an expression leaf with path constant + * + * @param s + * @return + */ + public static final ExpressionLeaf pathConstant(String path) { + return new ExpressionLeaf(ExpressionItem.RM, path, + ExpressionLeaf.ReferenceType.CONSTANT); + } + + /** + * Creates an expression leaf with boolean constant + * + * @param s + * @return + */ + public static final ExpressionLeaf booleanConstant(boolean b) { + return new ExpressionLeaf(ExpressionItem.BOOLEAN, new Boolean(b), + ExpressionLeaf.ReferenceType.CONSTANT); + } + + /** + + * Equals if two ExpressionLeaf Objects have same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof ExpressionLeaf )) return false; + + final ExpressionLeaf cobj = (ExpressionLeaf) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(item, cobj.item) + .append(referenceType, cobj.referenceType) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(5, 23) + .appendSuper(super.hashCode()) + .append(item) + .append(referenceType) + .toHashCode(); + } + + /** + * The string representation of this expression leaf + * + * @return string + */ + public String toString() { + String value; + + /* special case with CString */ + if(item instanceof CString) { + CString cstr = (CString) item; + value = "/" + cstr.getPattern() + "/"; + } else { + value = item.toString(); + } + return value; + } + + private Object item; + private ReferenceType referenceType; +} + +/* + * ***** 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 ExpressionLeaf.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2010 + * 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/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 new file mode 100644 index 00000000..1512937f --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionOperator.java @@ -0,0 +1,97 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ExpressionOperator" + * keywords: "archetype assertion" + * + * 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.archetype.assertion; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +public abstract class ExpressionOperator extends ExpressionItem { + private OperatorKind operator; + private boolean precedenceOverridden; + public OperatorKind getOperator() { + return operator; + } + public boolean isPrecedenceOverridden() { + return precedenceOverridden; + } + + public ExpressionOperator(String type, OperatorKind operator, boolean precedenceOverridden) { + super(type); + this.operator = operator; + this.precedenceOverridden = precedenceOverridden; + } + + /** + * Equals if two ExpressionOperator Objects have same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof ExpressionOperator )) return false; + + final ExpressionOperator cobj = (ExpressionOperator) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(operator, cobj.operator) + .append(precedenceOverridden, cobj.precedenceOverridden) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(5, 23) + .appendSuper(super.hashCode()) + .append(operator) + .append(precedenceOverridden) + .toHashCode(); + } +} +/* + * ***** 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 ExpressionOperator.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2010 + * 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/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 new file mode 100644 index 00000000..43e5a628 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionUnaryOperator.java @@ -0,0 +1,102 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ExpressionUnaryOperator" + * keywords: "archetype assertion" + * + * 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.archetype.assertion; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +public class ExpressionUnaryOperator extends ExpressionOperator { + + public ExpressionUnaryOperator(String type, OperatorKind operator, + boolean precedenceOverridden, ExpressionItem operand) { + super(type, operator, precedenceOverridden); + this.operand = operand; + } + + public ExpressionItem getOperand() { + return operand; + } + + /** + * Equals if two ExpressionUnaryOperator Objects have same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof ExpressionUnaryOperator )) return false; + + final ExpressionUnaryOperator cobj = (ExpressionUnaryOperator) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(operand, cobj.operand) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(5, 23) + .appendSuper(super.hashCode()) + .append(operand) + .toHashCode(); + } + + /** + * Returns the String representation of this unary operator + * + * @return string + */ + public String toString() { + return getOperator() + " " + operand.toString(); + } + + private ExpressionItem operand; +} +/* + * ***** 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 ExpressionUnaryOperator.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2010 + * 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/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 new file mode 100644 index 00000000..68f3727f --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/assertion/OperatorKind.java @@ -0,0 +1,158 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class OperatorKind" + * keywords: "archetype assertion" + * + * 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.archetype.assertion; + +public enum OperatorKind { + /** + * Equals operator ("=" or "==") + */ + OP_EQ(2001, "="), + + /** + * Not equals operator ("!=" or "/=" or "<>") + */ + OP_NE(2002, "!="), + + /** + * Less-than or equals operator ("<=") + */ + OP_LE(2003, "<="), + + /** + * Less-than operator ("<") + */ + OP_LT(2004, "<"), + + /** + * Grater-than or equals operator (">=") + */ + OP_GE(2005, ">="), + + /** + * Grater-than operator (">") + */ + OP_GT(2006, ">"), + + /** + * Matches operator ("matches" or "is_in") + */ + OP_MATCHES(2007, "matches"), + + /** + * Not logical operator + */ + OP_NOT(2010, "not"), + + /** + * And logical operator + */ + OP_AND(2011, "and"), + + /** + * Or logical operator + */ + OP_OR(2012, "or"), + + /** + * Xor logical operator + */ + OP_XOR(2013, "xor"), + + /** + * Implies logical operator + */ + OP_IMPLIES(2014, "implies"), + + /** + * For-all quantifier operator + */ + OP_FOR_ALL(2015, "for_all"), + + /** + * Exists quantifier operator + */ + OP_EXISTS(2016, "exists"), + + /** + * Plus operator ("+") + */ + OP_PLUS(2020, "+"), + + /** + * Minus operator ("-") + */ + OP_MINUS(2021, "-"), + + /** + * Multiply operator ("*") + */ + OP_MULTIPLY(2022, "*"), + + /** + * Divide operator ("/") + */ + OP_DIVIDE(2023, "/"), + + /** + * Exponent operator ("^") + */ + OP_EXP(2024, "^"); + + private int value; + private String sign; + + OperatorKind(int value, String sign) { + this.value = value; + this.sign = sign; + } + + public int getValue() { + return value; + } + + public String toString() { + return sign; + } +} +/* + * ***** 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 OperatorKind.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-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 ***** + */ \ No newline at end of file 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 new file mode 100644 index 00000000..018890f4 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/ArchetypeConstraint.java @@ -0,0 +1,216 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ArchetypeConstraint" + * keywords: "archetype" + * + * 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/am/archetype/constraintmodel/ArchetypeConstraint.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.am.archetype.constraintmodel; + +import java.io.Serializable; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; + +/** + * Purpose Archetype equivalent to LOCATABLE class in openEHR Common reference + * model. Defines common constraints for any inheritor of LOCATABLE in any + * reference model. + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class ArchetypeConstraint implements Serializable{ + + /** + * Path separator in archetype path + */ + public static final String PATH_SEPARATOR = "/"; + + /** + * Constructor + * + * @param anyAllowed + */ + protected ArchetypeConstraint(boolean anyAllowed, String path) { + if (StringUtils.isEmpty(path)) { + throw new IllegalArgumentException("path null"); + } + this.anyAllowed = anyAllowed; + this.path = path; + } + + /** + * Path of this node relative to root of archetype. + * + * @return path + */ + public String path() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + /** + * True if this node is a valid archetype node. + * + * @return true if valid + */ + public abstract boolean isValid(); + + /** + * Returns true if the constraint is a root node + * + * @return + */ + public boolean isRoot() { + return PATH_SEPARATOR.equals(path); + } + + /** + * True if the relative path exists at this node. + * + * @param path + * @return true if has + * @throws IllegalArgumentException if path null + */ + public abstract boolean hasPath(String path); + + /** + * True if constraints represented by other are narrower than this node. + * + * @param constraint + * @return true if subset + * @throws IllegalArgumentException if constraint null + */ + public abstract boolean isSubsetOf(ArchetypeConstraint constraint); + + /** + * True if any possible instance value of this type is considered valid + * + * @return anyAllowed + */ + public boolean isAnyAllowed() { + return anyAllowed; + } + + public void setAnyAllowed(boolean anyAllowed) { + this.anyAllowed = anyAllowed; + } + + /** + * True if hide_on_form is set on the template + * + * @return + */ + public boolean isHiddenOnForm() { + return hiddenOnForm; + } + + public String getAnnotation() { + return annotation; + } + + public void setAnnotation(String annotation) { + this.annotation = annotation; + } + + /** + * String representation of this object + * + * @return string form + */ + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, + ToStringStyle.MULTI_LINE_STYLE); + } + + /** + * Equals if two ArchetypeConstraint have same value + * + * @param o + * @return true if equals + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof ArchetypeConstraint )) { + return false; + } + + final ArchetypeConstraint ac = (ArchetypeConstraint) o; + + return new EqualsBuilder() + .append(anyAllowed, ac.anyAllowed) + .append(path, ac.path) + // .append(hiddenOnForm, ac.hiddenOnForm) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + @Override + public int hashCode() { + return new HashCodeBuilder() + .append(anyAllowed) + .append(path) + // .append(hiddenOnForm) + .toHashCode(); + } + + /* fields */ + private boolean anyAllowed; + private String path; + + // TODO experimental feature in ADL 1.5 + private boolean hiddenOnForm; + private String annotation; +} + +/* + * ***** 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 ArchetypeConstraint.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-aom/src/main/java/org/openehr/am/archetype/constraintmodel/ArchetypeInternalRef.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/ArchetypeInternalRef.java new file mode 100644 index 00000000..2b836f4c --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/ArchetypeInternalRef.java @@ -0,0 +1,138 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ArchetypeInternalRef" + * keywords: "archetype" + * + * 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/am/archetype/constraintmodel/ArchetypeInternalRef.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.am.archetype.constraintmodel; + +import org.apache.commons.lang.StringUtils; +import org.openehr.rm.support.basic.Interval; + +/** + * A constraint defined by proxy, using a reference to an object constraint + * defined elsewhere in the same archetype. + * + * @author Rong Chen + * @version 1.0 + */ +public class ArchetypeInternalRef extends CReferenceObject { + + /** + * Creates an ObjectConstraint + * + * @param path + * @param rmTypeName + * @param occurrences null indicates {1..1} + * @param nodeID + * @param parent + * @param targetPath not null or empty + * @throws IllegalArgumentException if rmTypeName null or empty, + * or nodeID null or empty + */ + public ArchetypeInternalRef(String path, String rmTypeName, + Interval occurrences, String nodeID, + CAttribute parent, String targetPath) { + + super(false, path, rmTypeName, occurrences, nodeID, parent); + + if (StringUtils.isEmpty(targetPath)) { + throw new IllegalArgumentException("null or emtpy targetPath"); + } + // TODO: and then ultimate_root.has_path(target_path) + this.targetPath = targetPath; + } + + @Override + public CObject copy() { + return new ArchetypeInternalRef(path(), getRmTypeName(), getOccurrences(), + getNodeId(), getParent(), targetPath); + } + + /** + * Reference to an object node using archetype path notation. + * + * @return target path + */ + public String getTargetPath() { + return targetPath; + } + + /** + * True if this node is a valid archetype node. + * + * @return ture if valid + */ + @Override + public boolean isValid() { + return false; // todo: implement this method + } + + /** + * 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; // todo: implement this method + } + + /** + * True if constraints represented by other are narrower than this node. + * + * @param constraint + * @return true if subset + * @throws IllegalArgumentException if constraint null + */ + @Override + public boolean isSubsetOf(ArchetypeConstraint constraint) { + return false; // todo: implement this method + } + + /* fields */ + private String targetPath; + + /* static fields */ + public static final String USE_NODE = " use_node "; +} + +/* + * ***** 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 ArchetypeInternalRef.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-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 ***** + */ \ No newline at end of file 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 new file mode 100644 index 00000000..ea74971c --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/ArchetypeSlot.java @@ -0,0 +1,193 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ArchetypeSlot" + * keywords: "archetype" + * + * 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/am/archetype/constraintmodel/ArchetypeSlot.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.am.archetype.constraintmodel; + +import java.util.Set; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.am.archetype.assertion.Assertion; +import org.openehr.rm.support.basic.Interval; + +/** + * ArchetypeSlot + * + * @author Rong Chen + * @version 1.0 + */ +public class ArchetypeSlot extends CReferenceObject { + + /** + * Constructs an ArchetypeSlot + * + * @param path + * @param rmTypeName + * @param occurrences + * @param nodeID + * @param parent + * @param includes + * @param excludes + * @throws IllegalArgumentException if includes not null and empty + * or if excludes not null and empty or both are null + */ + public ArchetypeSlot(String path, String rmTypeName, + Interval occurrences, + String nodeID, CAttribute parent, + Set includes, Set excludes) { + + super(includes == null && excludes == null, path, rmTypeName, + occurrences, nodeID, parent); + + if(includes != null && includes.isEmpty()) { + throw new IllegalArgumentException("empty includes"); + } + if(excludes != null && excludes.isEmpty()) { + throw new IllegalArgumentException("empty excludes"); + } + this.includes = includes; + this.excludes = excludes; + } + + @Override + public CObject copy() { + return new ArchetypeSlot(path(), getRmTypeName(), getOccurrences(), + getNodeId(), getParent(), includes, excludes); + } + + /** + * List of constraints defining other archetypes which could be included + * at this point. + * + * @return List of Assertion + */ + public Set getIncludes() { + return includes; + } + + /** + * List of constraints defining other archetypes which cannot be included + * at this point. + * + * @return List of Assertion + */ + public Set getExcludes() { + return excludes; + } + + /** + * True if this node is a valid archetype node. + * + * @return true if valid + */ + @Override + public boolean isValid() { + return false; // todo: implement this method + } + + /** + * 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; // todo: implement this method + } + + /** + * True if constraints represented by other are narrower than this node. + * + * @param constraint + * @return true if subset + * @throws IllegalArgumentException if constraint null + */ + @Override + public boolean isSubsetOf(ArchetypeConstraint constraint) { + return false; // todo: implement this method + } + + /** + * Equals if two ArchetypeConstraint have same value + * + * @param o + * @return true if equals + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof ArchetypeSlot )) { + return false; + } + final ArchetypeSlot as = (ArchetypeSlot) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(includes, as.includes) + .append(excludes, as.excludes) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + @Override + public int hashCode() { + return new HashCodeBuilder(7, 19) + .appendSuper(super.hashCode()) + .append(includes) + .append(excludes) + .toHashCode(); + } + + /* fields */ + private Set includes; + private Set excludes; +} + +/* + * ***** 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 ArchetypeSlot.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2010 + * 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/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 new file mode 100644 index 00000000..c1154a8b --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CAttribute.java @@ -0,0 +1,282 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CAttribute" + * keywords: "archetype" + * + * 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/am/archetype/constraintmodel/CAttribute.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.am.archetype.constraintmodel; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import java.util.*; + +/** + * This class represents a constraint on any kind of attribute node. + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class CAttribute extends ArchetypeConstraint { + + /** + * enumeration of attribute existence + */ + public enum Existence { + REQUIRED, OPTIONAL, NOT_ALLOWED + }; + + /** + * Constructs an AttributeConstraint + * + * @param path + * @param rmAttributeName + * @param existence + * @param children List + * @throws IllegalArgumentException if rmAttributeName empty + * or existence null or children null + */ + public CAttribute(String path, String rmAttributeName, + Existence existence, List children) { + + super(children == null, path); + + if (StringUtils.isEmpty(rmAttributeName)) { + throw new IllegalArgumentException("rmTypeName null"); + } + if (existence == null) { + throw new IllegalArgumentException("existence null"); + } + this.rmAttributeName = rmAttributeName; + this.existence = existence; + this.children = new ArrayList(); + if(children != null) { + this.children.addAll(children); + } + } + + public abstract CAttribute copy(); + + protected List copyChildren() { + + if(children == null) { + return null; + } + List list = new ArrayList(); + for(CObject cobj : children) { + if(cobj == null) { + System.out.println("null cobj while copying c_attr: " + rmAttributeName + ", " + path()); + } + list.add(cobj.copy()); + } + return list; + } + + /** + * Creates a CAttribute without child + * + * @param path + * @param rmAttributeName + * @param existence + */ + public CAttribute(String path, String rmAttributeName, + Existence existence) { + this(path, rmAttributeName, existence, null); + } + + /** + * Reference model attribute within the enclosing type represented by + * a object constraint + * + * @return reference model attribute name + */ + public String getRmAttributeName() { + return rmAttributeName; + } + + /** + * Existence of this attribute constaint + * + * @return existence + */ + public Existence getExistence() { + return existence; + } + + /** + * Returns true if this attribute is required + * + * @return true if required + */ + public boolean isRequired() { + return Existence.REQUIRED.equals(existence); + } + + /** + * Returns true if this attribute should be allowed + * + * @return + */ + public boolean isAllowed() { + return ! Existence.NOT_ALLOWED.equals(existence); + } + + /** + * Return true if this attribute is required + * or there is any submitted input value for its descendants + * + * @return true if required + */ + public boolean isRequired(Set paths) { + if (isRequired()) { + return true; + } + + // if any submitted value for descendant nodes + for (String path : paths) { + if (path.startsWith(childNodePathBase())) { + return true; + } + } + return false; + } + + /** + * List of children object constraint + * + * @return List or null if not present + */ + public List getChildren() { + return children; + } + + /** + * Adds a child to the children list + * + * @param child not null + */ + public void addChild(CObject child) { + if(child == null) { + throw new IllegalArgumentException("null child"); + } + children.add(child); + child.setParent(this); + } + + public void removeChild(CObject child) { + children.remove(child); + } + + public void removeAllChildren() { + children.clear(); + } + + /** + * True if constraints represented by other are narrower than this node. + * + * @param constraint + * @return true if subset + * @throws IllegalArgumentException if constraint null + */ + public abstract boolean isSubsetOf(ArchetypeConstraint constraint); + + /** + * Return path of parent object node + * + * @return parent node path + */ + public String parentNodePath() { + + // remove both "/" and attribute name + return path().substring(0, + path().length() - rmAttributeName.length() - 1); + } + + /** + * Return path base for the children nodes + * + * @return child node path base + */ + public String childNodePathBase() { + return parentNodePath() + PATH_SEPARATOR + rmAttributeName; + } + + /** + * Two CAttributes equals if have same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof CAttribute )) return false; + + final CAttribute cattr = (CAttribute) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(rmAttributeName, cattr.rmAttributeName) + .append(existence, cattr.existence) + .append(children, cattr.children) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(7, 19) + .appendSuper(super.hashCode()) + .append(rmAttributeName) + .append(existence) + .append(children) + .toHashCode(); + } + + + /* fields */ + private final String rmAttributeName; + private final Existence existence; + final List children; +} + +/* + * ***** 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 CAttribute.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Bert Verhees + * + * 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-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CComplexObject.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CComplexObject.java new file mode 100644 index 00000000..58621e43 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CComplexObject.java @@ -0,0 +1,254 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CComplexObject" + * keywords: "archetype" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2006 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/am/archetype/constraintmodel/CComplexObject.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.am.archetype.constraintmodel; + +import org.openehr.rm.support.basic.Interval; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import java.io.Serializable; +import java.util.*; + +/** + * Constraint on complex objects, ie any object which consists of other object + * constraints. Instances of this class are mutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class CComplexObject extends CDefinedObject implements Serializable{ + + /** + * Constructs a complexObjectConstraint + * + * @param path + * @param rmTypeName + * @param occurrences + * @param nodeID + * @param attributes + * @param invariants + */ + public CComplexObject(String path, String rmTypeName, + Interval occurrences, String nodeID, + List attributes, CAttribute parent) { + + // TODO probably need to inherit from CObject directly + super(attributes == null, path, rmTypeName, occurrences, nodeID, + parent, null); + + this.attributes = new ArrayList(); + if(attributes != null) { + this.attributes.addAll(attributes); + } + } + + /** + * Create a single required node constrained only by given RM type + * + * @param path + * @param rmTypeName + * @return + */ + public static CComplexObject createSingleRequired(String path, String rmTypeName) { + Interval occurrences = new Interval(1, 1); + return new CComplexObject(path, rmTypeName, occurrences, null, null, null); + } + + /** + * Make a copy of this instance + * + * @return + */ + public CObject copy() { + + //System.out.println("copying " + getRmTypeName() + ", " + path()); + + List list = new ArrayList(); + for(CAttribute attr : attributes) { + list.add(attr.copy()); + } + return new CComplexObject(path(), getRmTypeName(), getOccurrences(), + getNodeId(), list, getParent()); + } + + /** + * Adds an attribute constraint to this CComplexObject + * + * @param attribute not null + */ + public void addAttribute(CAttribute attribute) { + if(attribute == null) { + throw new IllegalArgumentException("null cattribute"); + } + attributes.add(attribute); + setAnyAllowed(false); + } + + /** + * Removes the attribute of given name + * + * @param name + */ + public void removeAttribute(String name) { + if(name == null) { + return; + } + for(Iterator it = getAttributes().iterator(); + it.hasNext();) { + CAttribute cattr = it.next(); + if(name.equals(cattr.getRmAttributeName())) { + it.remove(); + } + } + } + + /** + * List of constraints on attributes of the reference model type + * represented by this object. + * + * @return null if allow any + */ + public List getAttributes() { + return attributes; + } + + /** + * Get a specific attribute constraint identified by its rmAttributeName. + * @param rmAttributeName the attribute name of the attribute to be retrieved + * @return the attribute or null if no specific constraint with that rmAttributeName exists + */ + public CAttribute getAttribute(String rmAttributeName) { + if (attributes == null) return null; + for (CAttribute attribute : attributes) { + if (attribute.getRmAttributeName().equals(rmAttributeName)) { + return attribute; + } + } + return null; + } + + /** + * Checks if a specific attribute constraint identified by its rmAttributeName. + * @param rmAttributeName the attribute name of the attribute to be retrieved + * @return the attribute or null if no specific constraint with that rmAttributeName exists + */ + public boolean hasAttribute(String rmAttributeName) { + if (attributes == null) return false; + for (CAttribute attribute : attributes) { + if (attribute.getRmAttributeName().equals(rmAttributeName)) { + return true; + } + } + return false; + } + + + /** + * True if this node is a valid archetype node. + * + * @return true if valid + */ + public boolean isValid() { + if (attributes == null) { + return true; + } + return false; // todo: implement this method + } + + /** + * 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; // todo fix it + } + + /** + * 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; // todo: implement this method + } + + /** + * Equals if two CComplexObject have same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof CComplexObject )) return false; + + final CComplexObject ccobj = (CComplexObject) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(attributes, ccobj.attributes) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(13, 29) + .appendSuper(super.hashCode()) + .append(attributes) + .toHashCode(); + } + + /* fields */ + private List attributes; +} + +/* + * ***** 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 CComplexObject.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-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 ***** + */ \ No newline at end of file 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 new file mode 100644 index 00000000..07a1429c --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CDefinedObject.java @@ -0,0 +1,153 @@ +/* + * component: "openEHR Reference Java Implementation" + * description: "Class CDefinedObject" + * keywords: "archetype" + * + * author: "Rong Chen " + * support: "Rong Chen " + * copyright: "Copyright (c) 2007 Cambio Healthcare System, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.am.archetype.constraintmodel; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.support.basic.Interval; + +/** + * Abstract parent type of C_OBJECT subtypes that are defined by value, i.e. + * whose definitions are actually in the archetype rather than being by + * reference. + * + * @author Rong Chen + */ +public abstract class CDefinedObject extends CObject { + + /** + * Create a CDefinedObject + * + * @param anyAllowed + * @param path + * @param rmTypeName + * @param occurrences + * @param nodeID + * @param parent + * @param assumedValue + */ + protected CDefinedObject(boolean anyAllowed, String path, String rmTypeName, + Interval occurrences, String nodeID, CAttribute parent, + Object assumedValue) { + + this(anyAllowed, path, rmTypeName, occurrences, nodeID, parent, + assumedValue, null); + } + + /** + * Create a CDefinedObject + * + * @param anyAllowed + * @param path + * @param rmTypeName + * @param occurrences + * @param nodeID + * @param parent + * @param assumedValue + * @param defaultValue + */ + protected CDefinedObject(boolean anyAllowed, String path, String rmTypeName, + Interval occurrences, String nodeID, CAttribute parent, + Object assumedValue, Object defaultValue) { + super(anyAllowed, path, rmTypeName, occurrences, nodeID, parent); + this.assumedValue = assumedValue; + this.defaultValue = defaultValue; + } + + /** + * True if there is an assumed value + * + * @return if there is an assumed value + */ + public boolean hasAssumedValue() { + return assumedValue != null; + } + + /** + * True if there is a default value + * + * @return default value or null + */ + public boolean hasDefaultValue() { + return defaultValue != null; + } + + /** + * Equals if two CObject has same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof CDefinedObject )) return false; + + final CDefinedObject cobj = (CDefinedObject) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(assumedValue, cobj.assumedValue) + .append(defaultValue, cobj.defaultValue) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(7, 23) + .appendSuper(super.hashCode()) + .append(assumedValue) + .append(defaultValue) + .toHashCode(); + } + + /* fields */ + private Object assumedValue; + private Object defaultValue; + +} + +/* + * ***** 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 CDefinedObject.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2007 + * 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-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CDomainType.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CDomainType.java new file mode 100644 index 00000000..f1d17254 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CDomainType.java @@ -0,0 +1,169 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CDomainType" + * keywords: "archetype" + * + * 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/am/archetype/constraintmodel/CDomainType.java $" + * revision: "$LastChangedRevision: 43 $" + * last_change: "$LastChangedDate: 2006-08-08 12:54:07 +0200 (Tue, 08 Aug 2006) $" + */ +package org.openehr.am.archetype.constraintmodel; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.support.basic.Interval; + +/** + * Abstract parent type of domain-specific constrainer types, to be defined in + * external packages. + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class CDomainType extends CObject { + + /** + * Constructs a DomainTypeConstraint without default value or assumed value + * + * @param path + * @param rmTypeName + * @param occurrences + * @param nodeID + */ + protected CDomainType(boolean anyAllowed, String path, String rmTypeName, + Interval occurrences, String nodeID, CAttribute parent) { + this(anyAllowed, path, rmTypeName, occurrences, nodeID, null, null, + parent); + } + + /** + * Constructs a DomainTypeConstraint without default value or assumed value + * + * @param path + * @param rmTypeName + * @param occurrences + * @param nodeID + * @param defaultValue + * @param assumedValue + */ + protected CDomainType(boolean anyAllowed, String path, String rmTypeName, + Interval occurrences, String nodeID, + T defaultValue, T assumedValue, CAttribute parent) { + + super(anyAllowed, path, rmTypeName, occurrences, nodeID, parent); + + if(assumedValue != null && !validValue(assumedValue)) { + throw new IllegalArgumentException("invalid assumedValue"); + } + + this.defaultValue = defaultValue; + this.assumedValue = assumedValue; + } + + /** + * Returns true if a_value is valid with respect to constraint expressed in + * concrete instance of this type. + * + * @param value + * @return + */ + public abstract boolean validValue(T value); + + /** + * Standard form of constraint + * + * @return Standard form of constraint + */ + public abstract CComplexObject standardEquivalent(); + + /** + * Returns true if there is an assumed value + * + * @return + */ + public boolean hasAssumedValue() { + return assumedValue != null; + } + + /** + * @return Returns the assumedValue. + */ + public T getAssumedValue() { + return assumedValue; + } + + /** + * @return Returns the defaultValue. + */ + public T getDefaultValue() { + return defaultValue; + } + + /** + * Returns true if fields are the same + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof CDomainType )) return false; + + final CDomainType cdomain = (CDomainType) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(assumedValue, cdomain.assumedValue) + .append(defaultValue, cdomain.defaultValue) + .isEquals(); + } + + /** + * Returns the hashcode of this object + * + * @return hashcode + */ + public int hashCode() { + return new HashCodeBuilder(7, 19) + .appendSuper(super.hashCode()) + .append(assumedValue) + .append(defaultValue) + .toHashCode(); + } + + private final T defaultValue; + private final T assumedValue; + +} + +/* + * ***** 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 CDomainType.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-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CMultipleAttribute.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CMultipleAttribute.java new file mode 100644 index 00000000..895941ea --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CMultipleAttribute.java @@ -0,0 +1,134 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CMultipleAttribute" + * keywords: "archetype" + * + * 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/am/archetype/constraintmodel/CMultipleAttribute.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.am.archetype.constraintmodel; + +import java.io.Serializable; +import java.util.*; + +/** + * Concrete model of constraint on a multiple-valued attribute node. Instances + * of this class are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class CMultipleAttribute extends CAttribute implements Serializable{ + + /** + * Create a constraint for mulple-valued attribute node + * + * @param path + * @param rmAttributeName + * @param existence + * @param children + * @param cardinality + */ + public CMultipleAttribute(String path, String rmAttributeName, + Existence existence, Cardinality cardinality, + List children) { + super(path, rmAttributeName, existence, children); + this.cardinality = cardinality; + } + + @Override + public CAttribute copy() { + return new CMultipleAttribute(path(), getRmAttributeName(), + getExistence(), cardinality, copyChildren()); + } + + /** + * List of constraints representing members of the container value of this + * attribute within the data. Semantics of the container uniqueness and + * ordering given by the cardinality. + * + * @return unmodifiable list of CObject + */ + public List members() { + return getChildren(); + } + + /** + * The cardinality of this attribute + * + * @return not null + */ + public Cardinality getCardinality() { + return cardinality; + } + + /** + * True if this node is a valid archetype node. + * + * @return ture if valid + */ + public boolean isValid() { + return false; // todo: implement this method + } + + /** + * 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; // todo: implement this method + } + + /** + * 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; // todo: implement this method + } + + /* fields */ + private final Cardinality cardinality; +} + +/* + * ***** 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 CMultipleAttribute.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-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CObject.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CObject.java new file mode 100644 index 00000000..ab7f8c5a --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CObject.java @@ -0,0 +1,255 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CObject" + * keywords: "archetype" + * + * 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/am/archetype/constraintmodel/CObject.java $" + * revision: "$LastChangedRevision: 43 $" + * last_change: "$LastChangedDate: 2006-08-08 12:54:07 +0200 (Tue, 08 Aug 2006) $" + */ +package org.openehr.am.archetype.constraintmodel; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.support.basic.Interval; + +import java.util.Set; + +/** + * Abstract model of constraint on any kind of object node. + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class CObject extends ArchetypeConstraint { + + /** + * Creates an ObjectConstraint + * + * @param anyAllowed + * @param path + * @param rmTypeName + * @param occurrences not null + * @param nodeID + * @param parent null if no parent + * @throws IllegalArgumentException if rmTypeName null or empty, + * or occurrences null, + * or nodeID null or empty + */ + protected CObject(boolean anyAllowed, String path, String rmTypeName, + Interval occurrences, String nodeID, + CAttribute parent) { + + super(anyAllowed, path); + + if (StringUtils.isEmpty(rmTypeName)) { + throw new IllegalArgumentException("null or empty rmTypeName"); + } + if (nodeID != null && StringUtils.isEmpty(nodeID)) { + throw new IllegalArgumentException("empty nodeID"); + } + if(occurrences == null) { + throw new IllegalArgumentException("null occurrences"); + } + this.rmTypeName = rmTypeName; + this.occurrences = occurrences; + this.nodeID = nodeID; + this.parent = parent; + } + + protected abstract CObject copy(); + + /** + * Reference model type which this node corresponds to. + * + * @return reference model type name + */ + public String getRmTypeName() { + return rmTypeName; + } + + /** + * Occurrences of this object node in the data, under the owning attribute. + * Upper limit can only be greater than 1 if owning attribute has a + * cardinality of more than 1). + * + * @return Interval, null indicates {1..1} + */ + public Interval getOccurrences() { + return occurrences; + } + + public void setOccurrences(Interval occurrences) { + this.occurrences = occurrences; + } + + /** + * Semantic id of this node, used to differentiate sibling nodes of the + * same type. [Previously called meaning ]. + * + * @deprecated + * @return node ids null if unspecified + */ + public String getNodeID() { + return nodeID; + } + + /** + * Semantic id of this node, used to differentiate sibling nodes of the + * same type. [Previously called meaning ]. + * + * @return node ids null if unspecified + */ + public String getNodeId() { + return nodeID; + } + + /** + * Sets nodeId of this cobject + * + * @param nodeId + */ + public void setNodeId(String nodeId) { + if(nodeId == null || StringUtils.isEmpty(nodeID)) { + throw new IllegalArgumentException("null or empty nodeId"); + } + this.nodeID = nodeId; + } + + /** + * Gets CAttribute that owns this CObject + * + * @return the parent of this CObject + */ + public CAttribute getParent() { + return parent; + } + + public void setParent(CAttribute parent) { + this.parent = parent; + } + + /** + * Check if this object node is required by occurrences + * and path of nodes for which values are submitted + * + * @param paths a set of path of nodes for which values submitted + * @return ture if this node is required + */ + public boolean isRequired(Set paths) { + + if (isRequired()) { + return true; + } + + // if any submitted value for descendant nodes + for (String path : paths) { + if (path.startsWith(path())) { + return true; + } + } + return false; + } + + /** + * Equals if two CObject has same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof CObject )) return false; + + final CObject cobj = (CObject) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(rmTypeName, cobj.rmTypeName) + .append(occurrences, cobj.occurrences) + .append(nodeID, cobj.nodeID) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(5, 23) + .appendSuper(super.hashCode()) + .append(rmTypeName) + .append(occurrences) + .append(nodeID) + .toHashCode(); + } + + /** + * Returns true if this object node is required + * + * @return true if required + */ + public boolean isRequired() { + if (occurrences == null) { // default {1..1} + return true; + } + if (occurrences.getLower() != null && occurrences.getLower() > 0) { + return true; + } + return false; // {0..N} + } + + + /** + * Returns true if occurrences doesn't match {0..0} + * + * @return + */ + public boolean isAllowed() { + return ! NOT_ALLOWED.equals(occurrences); + } + + /* fields */ + private final String rmTypeName; + private Interval occurrences; + private String nodeID; + private CAttribute parent; + private static final Interval NOT_ALLOWED = new Interval(0,0); +} + +/* + * ***** 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 CObject.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-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CPrimitiveObject.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CPrimitiveObject.java new file mode 100644 index 00000000..40581ec0 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CPrimitiveObject.java @@ -0,0 +1,188 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CPrimitiveObject" + * keywords: "archetype" + * + * 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/am/archetype/constraintmodel/CPrimitiveObject.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.am.archetype.constraintmodel; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.am.archetype.constraintmodel.primitive.CPrimitive; +import org.openehr.rm.support.basic.Interval; + +/** + * PrimitiveObject Constraint + * + * @author Rong Chen + * @version 1.0 + */ +public class CPrimitiveObject extends CDefinedObject { + + /** + * Constructs a PrimitiveObjectConstraint + * + * @param path + * @param occurrences + * @param nodeId + * @param parent + * @param item + */ + public CPrimitiveObject(String path, Interval occurrences, + String nodeId, CAttribute parent, CPrimitive item) { + + super(item == null, path, item == null ? null : item.getType(), + occurrences, nodeId, parent, + item == null ? null : item.assumedValue()); + this.item = item; + } + + /** + * Create a single required CPrimitiveObject with given primitive item + * + * @param path + * @param item + * @return + */ + public static CPrimitiveObject createSingleRequired(String path, CPrimitive item) { + Interval occurrences = new Interval(1,1); + return new CPrimitiveObject(path, occurrences, null, null, item); + } + + @Override + public CObject copy() { + return new CPrimitiveObject(path(), getOccurrences(), getNodeId(), + getParent(), item); + } + + /** + * Return true if the constraint has limit the possible value to + * be only one, which means the value has been assigned by the archetype + * author at design time + * + * @return true if has + */ + public boolean hasAssignedValue() { + return item.hasAssignedValue(); + } + + /** + * Object actually defining the constraint. + * + * @return primitive constraint null if unspecified + */ + public CPrimitive getItem() { + return item; + } + + /** + * True if this node is a valid archetype node. + * + * @return ture if valid + */ + @Override + public boolean isValid() { + return false; // todo: implement this method + } + + /** + * 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; // todo: implement this method + } + + /** + * True if constraints represented by other are narrower than this node. + * + * @param constraint + * @return true if subset + * @throws IllegalArgumentException if constraint null + */ + @Override + public boolean isSubsetOf(ArchetypeConstraint constraint) { + return false; // todo: implement this method + } + + /** + * Equals if two CObject has same values + * + * @param o + * @return true if equals + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof CPrimitiveObject )) { + return false; + } + + final CPrimitiveObject cobj = (CPrimitiveObject) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(item, cobj.item) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + @Override + public int hashCode() { + return new HashCodeBuilder(17, 31) + .appendSuper(super.hashCode()) + .append(item) + .toHashCode(); + } + + /* fields */ + private CPrimitive item; +} + +/* + * ***** 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 CPrimitiveObject.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-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CReferenceObject.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CReferenceObject.java new file mode 100644 index 00000000..1e4b0b62 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CReferenceObject.java @@ -0,0 +1,71 @@ +/* + * component: "openEHR Reference Java Implementation" + * description: "Class CDReferenceObject" + * keywords: "archetype" + * + * author: "Rong Chen " + * support: "Rong Chen " + * copyright: "Copyright (c) 2007 Cambio Healthcare System, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.am.archetype.constraintmodel; + +import org.openehr.am.archetype.constraintmodel.CObject; +import org.openehr.rm.support.basic.Interval; + +/** + * Abstract parent type of C_OBJECT subtypes that are defined by reference + * + * @author Rong Chen + * + */ +public abstract class CReferenceObject extends CObject { + + /** + * Creates a CReferenceObject + * + * @param anyAllowed + * @param path + * @param rmTypeName + * @param occurrences + * @param nodeID + * @param parent + */ + protected CReferenceObject(boolean anyAllowed, String path, String rmTypeName, Interval occurrences, String nodeID, CAttribute parent) { + super(anyAllowed, path, rmTypeName, occurrences, nodeID, parent); + } +} + +/* + * ***** 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 CReferenceObject.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2007 + * 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-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CSingleAttribute.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CSingleAttribute.java new file mode 100644 index 00000000..9a516389 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CSingleAttribute.java @@ -0,0 +1,144 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CSingleAttribute" + * keywords: "archetype" + * + * 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/am/archetype/constraintmodel/CSingleAttribute.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.am.archetype.constraintmodel; + +import java.util.List; + +/** + * Concrete model of constraint on a single-valued attribute node. The meaning + * of the inherited children attribute is that they are alternatives. + * Instances of this class are mutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class CSingleAttribute extends CAttribute { + + /** + * Create a constraint for single-valued attribute node + * + * @param path + * @param rmAttributeName + * @param existence + * @param alternatives null if allow any + */ + public CSingleAttribute(String path, String rmAttributeName, + Existence existence, List alternatives) { + super(path, rmAttributeName, existence, alternatives); + } + + /** + * Create a single required attribute without children + * + * @param path + * @param rmAttributeName + * @return + */ + public static CSingleAttribute createRequired(String path, String rmAttributeName) { + return new CSingleAttribute(path, rmAttributeName, Existence.REQUIRED); + } + + @Override + public CAttribute copy() { + return new CSingleAttribute(path(), getRmAttributeName(), + getExistence(), copyChildren()); + } + + /** + * Create a cSingleAttribute without children + * + * @param path + * @param rmAttributeName + * @param existence + */ + public CSingleAttribute(String path, String rmAttributeName, + Existence existence) { + super(path, rmAttributeName, existence); + } + + /** + * List of alternative constraints for the single child of this attribute + * within the data. + * + * @return unmodifiable list of alternatives, null if anyAllowed + */ + public List alternatives() { + return getChildren(); + } + + /** + * True if this node is a valid archetype node. + * + * @return true if valid + */ + public boolean isValid() { + if (isAnyAllowed()) { + return true; + } + return false; // todo: implement this method + } + + /** + * 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; // todo: implement this method + } + + /** + * 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; // todo: implement this method + } +} + +/* + * ***** 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 CSingleAttribute.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-aom/src/main/java/org/openehr/am/archetype/constraintmodel/Cardinality.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/Cardinality.java new file mode 100644 index 00000000..a75fb2d7 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/Cardinality.java @@ -0,0 +1,190 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Cardinality" + * keywords: "archetype" + * + * 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/am/archetype/constraintmodel/Cardinality.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.am.archetype.constraintmodel; + +import java.io.Serializable; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.openehr.rm.support.basic.Interval; + +/** + * This class represents the semantic of a container type. Two pre-defined + * types are List and Set. Instances of this class are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class Cardinality implements Serializable{ + + /** + * Creates a cardinality + * + * @param ordered + * @param unique + * @param interval Interval null indicates from 0 to many + * @throws IllegalArgumentException if lower boundary of interval is < 0 + */ + public Cardinality(boolean ordered, boolean unique, + Interval interval) { + + if (interval != null && interval.getLower() != null + && ( (Integer) interval.getLower() ).intValue() < 0) { + throw new IllegalArgumentException("lower boundary less than 0"); + } + this.ordered = ordered; + this.unique = unique; + this.interval = interval; + } + + /** + * True if ordered + * + * @return ordered + */ + public boolean isOrdered() { + return ordered; + } + + /** + * True if unique + * + * @return unique + */ + public boolean isUnique() { + return unique; + } + + /** + * Interval of this cardinality + * + * @return Interval null indicates from 0 to many + */ + public Interval getInterval() { + return interval; + } + + /** + * Returns true if the semantics of this cardinality represents + * a bag, i.e. unordered, non-unique membership. + */ + public boolean isBag() { + return !ordered && !unique; + } + + /** + * Returns true if the semantics of this cardinality represents + * a list, i.e. ordered, non-unique membership. + */ + public boolean isList() { + return ordered && !unique; + } + + /** + * Returns return if the semantics of this cardinality represents + * a set, i.e. unordered, unique membership. + */ + public boolean isSet() { + return !ordered && unique; + } + + /** + * Return ture if two Cardinality has same value + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof Cardinality )) return false; + + final Cardinality cardinality = (Cardinality) o; + + return new EqualsBuilder() + .append(ordered, cardinality.ordered) + .append(unique, cardinality.unique) + .append(interval, cardinality.interval) + .isEquals(); + } + + /** + * Return a hash code of this cardinality + * + * @return hash code + */ + public int hashCode() { + int result; + result = ( ordered ? 1 : 0 ); + result = 29 * result + ( unique ? 1 : 0 ); + result = 29 * result + ( interval != null ? interval.hashCode() : 0 ); + return result; + } + + public String toString() { + return new ToStringBuilder(this). + append("ordered", ordered). + append("unique", unique). + append("interval", interval). + toString(); + + } + + /* fields */ + private final boolean ordered; + private final boolean unique; + private final Interval interval; + + /** + * Pre-defined List cardinality, whoes members are ordered and non-unique + */ + public static final Cardinality LIST = + new Cardinality(true, false, new Interval(0, null)); + + /** + * Pre-defined Set cardinality, whoes members are unordered and unique + */ + public static final Cardinality SET = new Cardinality(false, true, + new Interval(0, 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 Cardinality.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-aom/src/main/java/org/openehr/am/archetype/constraintmodel/ConstraintRef.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/ConstraintRef.java new file mode 100644 index 00000000..b09f0591 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/ConstraintRef.java @@ -0,0 +1,171 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ConstraintRef" + * keywords: "archetype" + * + * 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/am/archetype/constraintmodel/ConstraintRef.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.am.archetype.constraintmodel; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.support.basic.Interval; + +/** + * Reference to a constraint described in the same archetype, but outside + * the main constraint structure. This is used to refer to constraints + * expressed in terms of external resources, such as constraints on terminology + * value sets. + * + * @author Rong Chen + * @version 1.0 + */ +public final class ConstraintRef extends CReferenceObject { + + /** + * Constructs a ConstraintRef + * + * @param path + * @param rmTypeName + * @param occurrences + * @param nodeId + * @param parent + * @param reference + * @throws IllegalArgumentException if reference null + */ + public ConstraintRef(String path, String rmTypeName, + Interval occurrences, String nodeId, CAttribute parent, + String reference) { + + super(false, path, rmTypeName, occurrences, nodeId, parent); + + if(StringUtils.isEmpty(reference)) { + throw new IllegalArgumentException("null reference"); + } + // TODO archetype.ontology.has_constraint(reference) + this.reference = reference; + } + + @Override + public CObject copy() { + return new ConstraintRef(path(), getRmTypeName(), getOccurrences(), + getNodeId(), getParent(), reference); + } + + /** + * Reference to a constraint in the archetype local ontology. + * + * @return reference + */ + public String getReference() { + return reference; + } + + /** + * True if this node is a valid archetype node. + * + * @return ture if valid + */ + @Override + public boolean isValid() { + return false; // todo: implement this method + } + + /** + * 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; // todo: implement this method + } + + /** + * True if constraints represented by other are narrower than this node. + * + * @param constraint + * @return true if subset + * @throws IllegalArgumentException if constraint null + */ + @Override + public boolean isSubsetOf(ArchetypeConstraint constraint) { + return false; // todo: implement this method + } + + /** + * Equals if two CObject has same values + * + * @param o + * @return true if equals + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof ConstraintRef )) { + return false; + } + + final ConstraintRef cobj = (ConstraintRef) o; + + return new EqualsBuilder() + .append(reference, cobj.reference) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + @Override + public int hashCode() { + return new HashCodeBuilder(7, 47) + .append(reference) + .toHashCode(); + } + + private String reference; +} + +/* + * ***** 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 ConstraintRef.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-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 new file mode 100644 index 00000000..417905da --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CBoolean.java @@ -0,0 +1,223 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CBoolean" + * keywords: "archetype" + * + * 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/am/archetype/constraintmodel/primitive/CBoolean.java $" + * revision: "$LastChangedRevision: 23 $" + * last_change: "$LastChangedDate: 2006-03-31 02:40:54 +0200 (Fri, 31 Mar 2006) $" + */ +package org.openehr.am.archetype.constraintmodel.primitive; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.datatypes.basic.DvBoolean; + +/** + * Constraint on instances of Boolean. Immutable. + * + * @author Rong Chen + * @version 1.1 + */ +public final class CBoolean extends CPrimitive { + + /** + * Constructs a BooleanConstraint with an assumed value + * + * @param trueValid + * @param falseValid + * @param assumedValue + * @param hasAssumedValue + * @throws IllegalArgumentException + * either trueValid or falseValid true + */ + public CBoolean(boolean trueValid, boolean falseValid, + boolean assumedValue, boolean hasAssumedValue, + boolean defaultValue, boolean hasDefaultValue) { + if (!trueValid && !falseValid) { + throw new IllegalArgumentException( + "either of trueValid or falseValid, or both need to be true"); + } + this.trueValid = trueValid; + this.falseValid = falseValid; + this.assumedValue = assumedValue; + this.hasAssumedValue = hasAssumedValue; + this.defaultValue = defaultValue; + this.hasDefaultValue = hasDefaultValue; + } + + public CBoolean(boolean trueValid, boolean falseValid, + boolean assumedValue, boolean hasAssumedValue) { + this(trueValid, falseValid, assumedValue, hasAssumedValue, false, false); + } + + + /** + * Constructs a BooleanConstraint without an assumed value + * + * @param trueValid + * @param falseValid + * @throws IllegalArgumentException + * either trueValid or falseValid true + */ + public CBoolean(boolean trueValid, boolean falseValid) { + this(trueValid, falseValid, false, false); + } + + + /** + * Return the primitive type this constraint is applied on + * + * @return name of the type + */ + @Override + public String getType() { + return "Boolean"; + } + + /** + * True if value is valid with respect to constraint + * + * @param value + * @return true if valid + */ + @Override + public boolean validValue(Object value) { + boolean b = ((Boolean) value).booleanValue(); + return ((b && isTrueValid()) || !b && isFalseValid()); + } + + /** + * True if the value True is allowed + * + * @return if true valid + */ + public boolean isTrueValid() { + return trueValid; + } + + /** + * True if the value False is allowed + * + * @return if false valid + */ + public boolean isFalseValid() { + return falseValid; + } + + @Override + public boolean hasAssumedValue() { + return hasAssumedValue; + } + + @Override + public Boolean assumedValue() { + return assumedValue; + } + + @Override + public boolean hasAssignedValue() { + return !(trueValid && falseValid); + } + + @Override + public DvBoolean assignedValue() { + if ((trueValid && falseValid)) { + return null; + } + if(trueValid) { + return DvBoolean.TRUE; + } else { + return DvBoolean.FALSE; + } + } + + @Override + public boolean hasDefaultValue() { + return hasDefaultValue; + } + + @Override + public DvBoolean defaultValue() { + return defaultValue ? DvBoolean.TRUE : DvBoolean.FALSE; + } + + /** + * Equals if two CObject has same values + * + * @param o + * @return true if equals + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof CBoolean )) { + return false; + } + + final CBoolean cobj = (CBoolean) o; + + return new EqualsBuilder() + .append(trueValid, cobj.trueValid) + .append(falseValid, cobj.falseValid) + .append(assumedValue, cobj.assumedValue) + .append(defaultValue, cobj.defaultValue) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + @Override + public int hashCode() { + return new HashCodeBuilder(5, 37) + .append(trueValid) + .append(falseValid) + .append(assumedValue) + .append(defaultValue) + .toHashCode(); + } + + /* fields */ + private final boolean trueValid; + private final boolean falseValid; + private final boolean assumedValue; + private final boolean hasAssumedValue; + private final boolean defaultValue; + private final boolean hasDefaultValue; +} + +/* + * ***** 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 CBoolean.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-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 new file mode 100644 index 00000000..579237e2 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CDate.java @@ -0,0 +1,280 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CDate" + * keywords: "archetype" + * + * 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/am/archetype/constraintmodel/primitive/CDate.java $" + * revision: "$LastChangedRevision: 23 $" + * last_change: "$LastChangedDate: 2006-03-31 02:40:54 +0200 (Fri, 31 Mar 2006) $" + */ +package org.openehr.am.archetype.constraintmodel.primitive; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.datatypes.quantity.datetime.DvDate; +import org.openehr.rm.support.basic.Interval; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Constraint on instances of Date. Immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class CDate extends CPrimitive { + + /** + * Constructs a DateConstraint with an assumed value + * + * @param pattern + * @param interval Interval + * @param list List + * @param assumedValue + * @throws IllegalArgumentException if both pattern and interval null + * or not null + */ + public CDate(String pattern, Interval interval, List list, + DvDate assumedValue, DvDate defaultValue) { + if (interval == null && pattern == null && list == null) { + throw new IllegalArgumentException( + "pattern, interval and list can't be all null"); + } + this.pattern = pattern; + this.interval = interval; + this.list = ( list == null ? null : new ArrayList(list) ); + this.assumedValue = assumedValue; + this.defaultValue = defaultValue; + } + + public CDate(String pattern, Interval interval, List list, + DvDate assumedValue) { + this(pattern, interval, list, assumedValue, null); + } + + /** + * Constructs a DateConstraint no assumed value + * + * @param pattern + * @param interval Interval + * @param list List + * @throws IllegalArgumentException if both pattern and interval null + * or not null + */ + public CDate(String pattern, Interval interval, List list) { + this(pattern, interval, list, null); + } + + /** + * Constructs a CDate with pattern + * + * @param pattern not null + * @throws IllegalArgumentException if pattern null + */ + public CDate(String pattern) { + this(pattern, null, null, null); + } + + /** + * Return the primitive type this constraint is applied on + * + * @return name of the type + */ + public String getType() { + return "DV_DATE"; + } + + /** + * True if value is valid with respect to constraint + * + * @param value + * @return true if valid + */ + public boolean validValue(Object value) { + // todo: validate by pattern ? + if (pattern != null && value instanceof String) { + String str = (String) value; + String pat = ""; + if (str.contains("-")) { + pat = FULL_PATTERN; + if (pattern.endsWith("XX")) { + pat = SHORT_PATTERN; + } + } else { + pat = FULL_PATTERN_WITHOUT_DASHES; + if (pattern.endsWith("XX")) { + pat = SHORT_PATTERN_WITHOUT_DASHES; + } + } + try { + new SimpleDateFormat(pat).parse(str); + return true; + } catch (ParseException pe) { + return false; + } + } else { + final DvDate date = (DvDate) value; + return ( interval != null && interval.has(date) ) + || ( list != null && list.contains(date) ); + } + } + + /** + * Return true if the constraint has limit the possible value to + * be only one, which means the value has been assigned by the archetype + * author at design time + * + * @return true if has + */ + public boolean hasAssignedValue() { + return list != null && list.size() == 1; + } + + /** + * Return assigned value as data value instance + * + * @return DvDate or null if not assigned + */ + public DvDate assignedValue() { + if(list == null || list.size() != 1) { + return null; + } + return list.get(0); + } + + /** + * Syntactic pattern defining constraint on dates. + * + * @return pattern + */ + public String getPattern() { + return pattern; + } + + /** + * Interval of Date specifying constraint + * + * @return Interval or null + */ + public Interval getInterval() { + return interval; + } + + /** + * List of specified values + * + * @return unmodifiable List or null + */ + public List getList() { + return list == null ? null : Collections.unmodifiableList(list); + } + + @Override + public boolean hasAssumedValue() { + return assumedValue != null; + } + + @Override + public Object assumedValue() { + return assumedValue; + } + + @Override + public boolean hasDefaultValue() { + return defaultValue != null; + } + + @Override + public Object defaultValue() { + return defaultValue; + } + + + /** + * Equals if two CObject has same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof CDate )) return false; + + final CDate cobj = (CDate) o; + + return new EqualsBuilder() + .append(pattern, cobj.pattern) + .append(interval, cobj.interval) + .append(list, cobj.list) + .append(assumedValue, cobj.assumedValue) + .append(defaultValue, cobj.defaultValue) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(5, 37) + .append(pattern) + .append(interval) + .append(list) + .append(assumedValue) + .append(defaultValue) + .toHashCode(); + } + + /* static fields */ + public final String FULL_PATTERN = "yyyy-MM-dd"; + public final String SHORT_PATTERN = "yyyy-MM"; + public final String FULL_PATTERN_WITHOUT_DASHES = "yyyyMMdd"; + public final String SHORT_PATTERN_WITHOUT_DASHES = "yyyyMM"; + + /* fields */ + private final String pattern; + private final Interval interval; // Interval + private final List list; // List + private final DvDate assumedValue; + private DvDate defaultValue; +} + +/* + * ***** 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. + *f + * The Original Code is CDate.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-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 new file mode 100644 index 00000000..4b823529 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CDateTime.java @@ -0,0 +1,252 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CDateTime" + * keywords: "archetype" + * + * 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/am/archetype/constraintmodel/primitive/CDateTime.java $" + * revision: "$LastChangedRevision: 23 $" + * last_change: "$LastChangedDate: 2006-03-31 02:40:54 +0200 (Fri, 31 Mar 2006) $" + */ +package org.openehr.am.archetype.constraintmodel.primitive; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.support.basic.Interval; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Constraint on instances of Date. Immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class CDateTime extends CPrimitive { + + /** + * Constructs a DateConstraint with an assumed value + * + * @param pattern + * @param interval Interval + * @param list List + * @param assumedValue + * @throws IllegalArgumentException if both pattern and interval null + * or not null + */ + public CDateTime(String pattern, Interval interval, + List list, DvDateTime assumedValue, + DvDateTime defaultValue) { + if (interval == null && pattern == null && list == null) { + throw new IllegalArgumentException( + "pattern, interval and list can't be all null"); + } + this.pattern = pattern; + this.interval = interval; + this.list = ( list == null ? null : new ArrayList(list) ); + this.assumedValue = assumedValue; + this.defaultValue = defaultValue; + } + + public CDateTime(String pattern, Interval interval, + List list, DvDateTime assumedValue) { + this(pattern, interval, list, assumedValue, null); + } + + /** + * Constructs a DateConstraint without assumed value + * + * @param pattern + * @param interval Interval + * @param list List + * @throws IllegalArgumentException if both pattern and interval null + * or not null + */ + public CDateTime(String pattern, Interval interval, + List list) { + this(pattern, interval, list, null); + } + + /** + * Convenience constructor to create CDateTime with pattern + * + * @param pattern not null + * @throws IllegalArgumentException if pattern null + */ + public CDateTime(String pattern) { + this(pattern, null, null, null); + } + + /** + * Return the primitive type this constraint is applied on + * + * @return name of the type + */ + public String getType() { + return "DV_DATE_TIME"; + } + + /** + * True if value is valid with respect to constraint + * + * @param value + * @return true if valid + */ + public boolean validValue(Object value) { + // todo: validate by pattern + final DvDateTime date = (DvDateTime) value; + return ( interval != null && interval.has(date) ) + || ( list != null && list.contains(date) ); + } + + /** + * Return true if the constraint has limit the possible value to + * be only one, which means the value has been assigned by the archetype + * author at design time + * + * @return true if has + */ + public boolean hasAssignedValue() { + return list != null && list.size() == 1; + } + + /** + * Return assigned value as data value instance + * + * @return DvDateTime or null if not assigned + */ + public DvDateTime assignedValue() { + if(list == null || list.size() != 1) { + return null; + } + return list.get(0); + } + + + /** + * Syntactic pattern defining constraint on dates. + * + * @return pattern + */ + public String getPattern() { + return pattern; + } + + /** + * Interval of Date specifying constraint + * + * @return Interval or null + */ + public Interval getInterval() { + return interval; + } + + /** + * List of specified values + * + * @return unmodifiable List or null + */ + public List getList() { + return list == null ? null : Collections.unmodifiableList(list); + } + + @Override + public boolean hasAssumedValue() { + return assumedValue != null; + } + + @Override + public Object assumedValue() { + return assumedValue; + } + + @Override + public boolean hasDefaultValue() { + return defaultValue != null; + } + + @Override + public Object defaultValue() { + return defaultValue; + } + + /** + * Equals if two CObject has same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof CDateTime )) return false; + + final CDateTime cobj = (CDateTime) o; + + return new EqualsBuilder() + .append(pattern, cobj.pattern) + .append(interval, cobj.interval) + .append(list, cobj.list) + .append(assumedValue, cobj.assumedValue) + .append(defaultValue, cobj.defaultValue) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(17, 37) + .append(pattern) + .append(interval) + .append(list) + .append(assumedValue) + .append(defaultValue) + .toHashCode(); + } + + /* fields */ + private final String pattern; + private final Interval interval; + private final List list; + private final DvDateTime assumedValue; + private DvDateTime defaultValue; +} + +/* + * ***** 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 CDateTime.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-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 new file mode 100644 index 00000000..15b4618c --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CDuration.java @@ -0,0 +1,217 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CDuration" + * keywords: "archetype" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004,2006 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/am/archetype/constraintmodel/primitive/CDuration.java $" + * revision: "$LastChangedRevision: 23 $" + * last_change: "$LastChangedDate: 2006-03-31 02:40:54 +0200 (Fri, 31 Mar 2006) $" + */ +package org.openehr.am.archetype.constraintmodel.primitive; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.datatypes.quantity.datetime.DvDuration; +import org.openehr.rm.support.basic.Interval; + +/** + * Constraint on instances of Duration. Immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class CDuration extends CPrimitive { + + /** + * Constructs a DurationConstraint with an assumed value + * + * @param value + * @param interval + * Interval + * @param assumedValue + * @param pattern null if unspecified + */ + public CDuration(DvDuration value, Interval interval, + DvDuration assumedValue, String pattern, DvDuration defaultValue) { + if (interval != null && value != null) { + throw new IllegalArgumentException( + "both value and interval not null"); + } + if (interval == null && value == null && pattern == null) { + throw new IllegalArgumentException( + "value, interval and pattern all null "); + } + this.value = value; + this.interval = interval; + this.assumedValue = assumedValue; + this.pattern = pattern; + this.defaultValue = defaultValue; + } + + /** + * Constructs a DurationConstraint without assumed value + * + * @param value + * @param interval + * Interval + */ + public CDuration(DvDuration value, Interval interval) { + this(value, interval, null, null); + } + + public CDuration(DvDuration value, Interval interval, + DvDuration assumedValue, String pattern) { + this(value, interval, assumedValue, pattern, null); + } + + + /** + * Return the primitive type this constraint is applied on + * + * @return name of the type + */ + public String getType() { + return "DV_DURATION"; + } + + /** + * True if value is valid with respect to constraint + * + * @param value + * @return true if valid + */ + public boolean validValue(Object value) { + return false; // todo: implement this method + } + + /** + * Syntactic value defining constraint on Times. + * + * @return value + */ + public DvDuration getValue() { + return value; + } + + /** + * Gets the pattern of this duration constraint + * + * @return null if unspecified + */ + public String getPattern() { + return pattern; + } + + /** + * Interval of Durations specifying constraint + * + * @return Interval + */ + public Interval getInterval() { + return interval; + } + + @Override + public boolean hasAssumedValue() { + return assumedValue != null; + } + + @Override + public DvDuration assumedValue() { + return assumedValue; + } + + @Override + public boolean hasDefaultValue() { + return defaultValue != null; + } + + @Override + public DvDuration defaultValue() { + return defaultValue; + } + + @Override + public boolean hasAssignedValue() { + return value != null; + } + + @Override + public DvDuration assignedValue() { + return value; + } + + /** + * Equals if two CObject has same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof CDuration )) return false; + + final CDuration cobj = (CDuration) o; + + return new EqualsBuilder() + .append(pattern, cobj.pattern) + .append(interval, cobj.interval) + .append(value, cobj.value) + .append(assumedValue, cobj.assumedValue) + .append(defaultValue, cobj.defaultValue) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(5, 37) + .append(pattern) + .append(interval) + .append(value) + .append(assumedValue) + .append(defaultValue) + .toHashCode(); + } + + /* fields */ + private final DvDuration value; + private final Interval interval; + private final DvDuration assumedValue; + private final String pattern; + private DvDuration defaultValue; +} + +/* + * ***** 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 CDuration.java + * + * The Initial Developer of the Original Code is Rong Chen. Portions created by + * the Initial Developer are Copyright (C) 2003-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 ***** + */ \ No newline at end of file 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 new file mode 100644 index 00000000..7d15bd57 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CInteger.java @@ -0,0 +1,228 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CInteger" + * keywords: "archetype" + * + * 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/am/archetype/constraintmodel/primitive/CInteger.java $" + * revision: "$LastChangedRevision: 23 $" + * last_change: "$LastChangedDate: 2006-03-31 02:40:54 +0200 (Fri, 31 Mar 2006) $" + */ +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; + +/** + * Constraint on integer values. Immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class CInteger extends CPrimitive { + + /** + * Constructs an IntegerConstraint with an assumed value + * + * @param interval + * @param list + * @param assumedValue + * @throws IllegalArgumentException + * if both null or both non-null + */ + public CInteger(Interval interval, List list, + Integer assumedValue, Integer defaultValue) { + if ((interval != null && list != null) + || (interval == null && list == null)) { + throw new IllegalArgumentException("both null or both not null"); + } + this.interval = interval; + this.list = (list == null ? null : new ArrayList(list)); + this.assumedValue = assumedValue; + this.defaultValue = defaultValue; + } + + public CInteger(Interval interval, List list, + Integer assumedValue) { + this(interval, list, assumedValue, null); + } + + /** + * Constructs an IntegerConstraint + * + * @param interval + * @param list + * @throws IllegalArgumentException + * if both null or both non-null + */ + public CInteger(Interval interval, List list) { + this(interval, list, null); + } + + /** + * Return the primitive type this constraint is applied on + * + * @return name of the type + */ + @Override + public String getType() { + return "Integer"; + } + + /** + * True if value is valid with respect to constraint + * + * @param value + * @return true if valid + */ + @Override + public boolean validValue(Object value) { + Integer integer = (Integer) value; + return (interval != null && interval.has(integer) || list != null + && list.contains(integer)); + } + + /** + * Return true if the constraint has limit the possible value to be only + * one, which means the value has been assigned by the archetype author at + * design time + * + * @return true if has + */ + @Override + public boolean hasAssignedValue() { + return list != null && list.size() == 1; + } + + /** + * Return assigned value as data value instance + * + * @return datavalue or null if not assigned + */ + @Override + public Object assignedValue() { + if (!hasAssignedValue()) { + return null; + } + return list.get(0); + } + + /** + * Interval of Integers specifying constraint + * + * @return Interval + */ + public Interval getInterval() { + return interval; + } + + /** + * List of Integers specifying constraint + * + * @return unmodifiable List or null if not used + */ + public List getList() { + return list == null ? null : Collections.unmodifiableList(list); + } + + @Override + public boolean hasAssumedValue() { + return assumedValue != null; + } + + @Override + public Object assumedValue() { + return assumedValue; + } + + @Override + public boolean hasDefaultValue() { + return defaultValue != null; + } + + @Override + public Object defaultValue() { + return defaultValue; + } + + /** + * Equals if two CObject has same values + * + * @param o + * @return true if equals + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof CInteger )) { + return false; + } + + final CInteger cobj = (CInteger) o; + + return new EqualsBuilder() + .append(list, cobj.list) + .append(interval, cobj.interval) + .append(assumedValue, cobj.assumedValue) + .append(defaultValue, cobj.defaultValue) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + @Override + public int hashCode() { + return new HashCodeBuilder(5, 43) + .append(list) + .append(interval) + .append(assumedValue) + .append(defaultValue) + .toHashCode(); + } + + /* fields */ + private final Interval interval; + private final List list; + private final Integer assumedValue; + private Integer defaultValue; +} + +/* + * ***** 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 CInteger.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-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 new file mode 100644 index 00000000..8ba0e308 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CPrimitive.java @@ -0,0 +1,129 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CPrimitive" + * keywords: "archetype" + * + * 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/am/archetype/constraintmodel/primitive/CPrimitive.java $" + * revision: "$LastChangedRevision: 23 $" + * last_change: "$LastChangedDate: 2006-03-31 02:40:54 +0200 (Fri, 31 Mar 2006) $" + */ +package org.openehr.am.archetype.constraintmodel.primitive; + +import java.io.Serializable; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; + +/** + * Super class of all primitive type constraints + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class CPrimitive implements Serializable{ + + /** + * Return the primitive type this constraint is applied on + * + * @return name of the type + */ + public abstract String getType(); + + /** + * True if value is valid with respect to constraint + * + * @param value + * @return true if valid + */ + public abstract boolean validValue(Object value); + + /** + * Return true if the constraint has limit the possible value to + * be only one, which means the value has been assigned by the archetype + * author at design time + * + * @return true if has + */ + public abstract boolean hasAssignedValue(); + + /** + * Return assigned value as data value instance + * + * @return datavalue or null if not assigned + */ + public abstract Object assignedValue(); + + /** + * Return true if there is an assumed value + * + * @return true if has an assumed value + */ + public abstract boolean hasAssumedValue(); + + /** + * Value to be assumed if none sent in data + * + * @return an assumed value + */ + public abstract Object assumedValue(); + + /** + * Default value to this object + * + * @return + */ + public abstract Object defaultValue(); + + /** + * Return true if there is a default value + * + * @return true if has a default value + */ + public abstract boolean hasDefaultValue(); + + /** + * String representation of this object + * + * @return string form + */ + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, + ToStringStyle.MULTI_LINE_STYLE); + } +} + +/* + * ***** 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 CPrimitive.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-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 new file mode 100644 index 00000000..1530489e --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CReal.java @@ -0,0 +1,205 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CReal" + * keywords: "archetype" + * + * 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/am/archetype/constraintmodel/primitive/CReal.java $" + * revision: "$LastChangedRevision: 23 $" + * last_change: "$LastChangedDate: 2006-03-31 02:40:54 +0200 (Fri, 31 Mar 2006) $" + */ +package org.openehr.am.archetype.constraintmodel.primitive; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.support.basic.Interval; + +import java.util.*; + +/** + * Constraint on instances of Double number. Immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class CReal extends CPrimitive { + + /** + * Constructs a RealConstraint with an assumed value + * + * @param interval Interval + * @param list List + * @param assumedValue + * @throws IllegalArgumentException if boht null or bot not null + */ + public CReal(Interval interval, List list, + Double assumedValue, Double defaultValue) { + if (( interval != null && list != null ) + || ( interval == null && list == null )) { + throw new IllegalArgumentException("both null or both not null"); + } + this.interval = interval; + this.list = ( list == null ? null : new ArrayList(list) ); + this.assumedValue = assumedValue; + this.defaultValue = defaultValue; + } + + public CReal(Interval interval, List list, + Double assumedValue) { + this(interval, list, assumedValue, null); + } + + /** + * Constructs a RealConstraint without assumed value + * + * @param interval Interval + * @param list List + */ + public CReal(Interval interval, List list) { + this(interval, list, null); + } + /** + * Return the primitive type this constraint is applied on + * + * @return name of the type + */ + public String getType() { + return "Double"; + } + + /** + * List of Reals specifying constraint + * + * @return unmodifiable List or null + */ + public List getList() { + return list == null ? null : Collections.unmodifiableList(list); + } + + /** + * True if value is valid with respect to constraint + * + * @param value + * @return true if valid + */ + 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 + * + * @return Interval of Double + */ + public Interval getInterval() { + return interval; + } + + @Override + public boolean hasAssumedValue() { + return assumedValue != null; + } + + @Override + public Object assumedValue() { + return assumedValue; + } + + @Override + public boolean hasDefaultValue() { + return defaultValue != null; + } + + @Override + public Object defaultValue() { + return defaultValue; + } + + /** + * Equals if two CObject has same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof CReal )) return false; + + final CReal cobj = (CReal) o; + + return new EqualsBuilder() + .append(list, cobj.list) + .append(interval, cobj.interval) + .append(assumedValue, cobj.assumedValue) + .append(defaultValue, cobj.defaultValue) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(5, 23) + .append(list) + .append(interval) + .append(assumedValue) + .append(defaultValue) + .toHashCode(); + } + + /* fields */ + private final List list; + private final Interval interval; + private final Double assumedValue; + private Double defaultValue; + + @Override + public boolean hasAssignedValue() { + // TODO Auto-generated method stub + return false; + } + + @Override + public Object assignedValue() { + // 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 CReal.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-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 new file mode 100644 index 00000000..360e0b93 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CString.java @@ -0,0 +1,246 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CString" + * keywords: "archetype" + * + * 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/am/archetype/constraintmodel/primitive/CString.java $" + * revision: "$LastChangedRevision: 23 $" + * last_change: "$LastChangedDate: 2006-03-31 02:40:54 +0200 (Fri, 31 Mar 2006) $" + */ +package org.openehr.am.archetype.constraintmodel.primitive; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +/** + * Constraint on instances of String. + * + * @author Rong Chen + * @version 1.0 + */ +public final class CString extends CPrimitive { + + /** + * Constructs a StringConstraint with an assumed value + * + * @param pattern + * @param list List + * @param assumedValue + * @throws IllegalArgumentException if pattern not null and empty + */ + public CString(String pattern, List list, String assumedValue) { + this(pattern, list, assumedValue, null); + } + + /** + * Constructs a StringConstraint with an assumed value + * + * @param pattern + * @param list List + * @param assumedValue + * @throws IllegalArgumentException if pattern not null and empty + */ + public CString(String pattern, List list, String assumedValue, + String defaultValue) { + if (pattern != null && StringUtils.isEmpty(pattern)) { + throw new IllegalArgumentException("empty pattern"); + } + this.pattern = pattern; + this.list = ( list == null ? null : new ArrayList(list) ); + this.assumedValue = assumedValue; + this.defaultValue = defaultValue; + } + + /** + * Constructs a StringConstraint without assumed value + * + * @param pattern + * @param list List + * @throws IllegalArgumentException if pattern not null and empty + */ + public CString(String pattern, List list) { + this(pattern, list, null); + } + + /** + * Constructs a stringConstraint with pattern + * + * @param pattern + */ + public CString(String pattern) { + this(pattern, null, null); + } + + /** + * Return the primitive type this constraint is applied on + * + * @return name of the type + */ + @Override + public String getType() { + return "String"; + } + + /** + * True if value is valid with respect to constraint + * + * @param value + * @return true if valid + */ + @Override + public boolean validValue(Object value) { + String str = value.toString(); + return ( (pattern == null && list == null) + || (pattern != null && str.matches(pattern)) + || (list != null && list.contains(str)) ); + } + + /** + * Regular expression pattern for proposed instances of String to match. + * + * @return pattern + */ + public String getPattern() { + return pattern; + } + + /** + * List of Strings specifying constraint + * + * @return unmodifiable List or null + */ + public List getList() { + return list == null ? null : Collections.unmodifiableList(list); + } + @Override + public boolean hasAssumedValue() { + return assumedValue != null; + } + + @Override + public Object assumedValue() { + return assumedValue; + } + + @Override + public boolean hasAssignedValue() { + return list != null && list.size() == 1; + } + + @Override + public String assignedValue() { + if (list == null || list.size() != 1) { + return null; + } + return list.get(0); + } + + @Override + public boolean hasDefaultValue() { + return defaultValue != null; + } + + @Override + public String defaultValue() { + return defaultValue; + } + + /** + * Return ture if two CString has same value + * + * @param o + * @return true if equals + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof CString )) { + return false; + } + + final CString cstring = (CString) o; + + return new EqualsBuilder() + .append(pattern, cstring.pattern) + .append(list, cstring.list) + .append(assumedValue, cstring.assumedValue) + .append(defaultValue, cstring.defaultValue) + .isEquals(); + } + + /** + * Return a hash code of this cstring + * + * @return hash code + */ + @Override + public int hashCode() { + return new HashCodeBuilder(13, 29) + // must not appendSuper here! .appendSuper(super.hashCode()) + .append(pattern) + .append(list) + .append(assumedValue) + .append(defaultValue) + .toHashCode(); + } + + @Override + public String toString() { + return new ToStringBuilder(this). + append("pattern", pattern). + append("list", list). + append("assumedValue", assumedValue). + append("defaultValue", defaultValue). + toString(); + } + + + /* fields */ + private final String pattern; + private final List list; + private final String assumedValue; + private final String defaultValue; +} + +/* + * ***** 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 CString.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-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 new file mode 100644 index 00000000..077ddd51 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/primitive/CTime.java @@ -0,0 +1,247 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CTime" + * keywords: "archetype" + * + * 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/am/archetype/constraintmodel/primitive/CTime.java $" + * revision: "$LastChangedRevision: 23 $" + * last_change: "$LastChangedDate: 2006-03-31 02:40:54 +0200 (Fri, 31 Mar 2006) $" + */ +package org.openehr.am.archetype.constraintmodel.primitive; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.datatypes.quantity.datetime.DvTime; +import org.openehr.rm.support.basic.Interval; + +import java.util.*; + +/** + * Constraint on instances of Time. Immutalbe. + * + * @author Rong Chen + * @version 1.0 + */ +public final class CTime extends CPrimitive { + + /** + * Construct a TimeConstraint with an assumed value + * + * @param pattern + * @param interval Interval + * @param list List + * @param assumedValue + * @throws IllegalArgumentException if both pattern and interval + * both null or both not null + */ + public CTime(String pattern, Interval interval, List list, + DvTime assumedValue, DvTime defaultValue) { + if (interval == null && pattern == null && list == null) { + throw new IllegalArgumentException( + "pattern, interval and list can't be all null"); + } + this.pattern = pattern; + this.interval = interval; + this.list = ( list == null ? null : new ArrayList(list) ); + this.assumedValue = assumedValue; + this.defaultValue = defaultValue; + } + + public CTime(String pattern, Interval interval, List list, + DvTime assumedValue) { + this(pattern, interval, list, assumedValue, null); + } + + /** + * Construct a TimeConstraint without assumed value + * + * @param pattern + * @param interval Interval + * @param list List + * @throws IllegalArgumentException if both pattern and interval + * both null or both not null + */ + public CTime(String pattern, Interval interval, List list) { + this(pattern, interval, list, null); + } + + /** + * Convenient constructor to create CTime with a pattern + * + * @param pattern not null + * @throws IllegalArgumentException if pattern null + */ + public CTime(String pattern) { + this(pattern, null, null); + } + + /** + * Return the primitive type this constraint is applied on + * + * @return name of the type + */ + public String getType() { + return "DV_TIME"; + } + + /** + * True if value is valid with respect to constraint + * + * @param value + * @return true if valid + */ + public boolean validValue(Object value) { + // todo: validate by pattern + final DvTime time = (DvTime) value; + return ( interval != null && interval.has(time) ) + || ( list != null && list.contains(time) ); + } + + /** + * Return true if the constraint has limit the possible value to + * be only one, which means the value has been assigned by the archetype + * author at design time + * + * @return true if has + */ + public boolean hasAssignedValue() { + return list != null && list.size() == 1; + } + + /** + * Return assigned value as data value instance + * + * @return DvTime or null if not assigned + */ + public DvTime assignedValue() { + if (list == null || list.size() != 1) { + return null; + } + return list.get(0); + } + + /** + * Syntactic pattern defining constraint on Times. + * + * @return pattern + */ + public String getPattern() { + return pattern; + } + + /** + * Interval of Times specifying constraint + * + * @return Interval + */ + public Interval getInterval() { + return interval; + } + + /** + * List of specified values + * + * @return unmodifiable List or null + */ + public List getList() { + return list == null ? null : Collections.unmodifiableList(list); + } + + @Override + public boolean hasAssumedValue() { + return assumedValue != null; + } + + @Override + public Object assumedValue() { + return assumedValue; + } + + @Override + public boolean hasDefaultValue() { + return defaultValue != null; + } + + @Override + public Object defaultValue() { + return defaultValue; + } + + /** + * Equals if two CObject has same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof CTime )) return false; + + final CTime cobj = (CTime) o; + + return new EqualsBuilder() + .append(pattern, cobj.pattern) + .append(interval, cobj.interval) + .append(list, cobj.list) + .append(assumedValue, cobj.assumedValue) + .append(defaultValue, cobj.defaultValue) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(11, 31) + .append(pattern) + .append(interval) + .append(list) + .append(assumedValue) + .append(defaultValue) + .toHashCode(); + } + + /* fields */ + private final String pattern; + private final Interval interval; + private final List list; + private final DvTime assumedValue; + private DvTime defaultValue; +} + +/* + * ***** 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 CTime.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-aom/src/main/java/org/openehr/am/archetype/ontology/ArchetypeOntology.java b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/ArchetypeOntology.java new file mode 100644 index 00000000..c98a63cf --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/ArchetypeOntology.java @@ -0,0 +1,257 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ArchetypeOntology" + * keywords: "archetype" + * + * 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/am/archetype/ontology/ArchetypeOntology.java $" + * revision: "$LastChangedRevision: 13 $" + * last_change: "$LastChangedDate: 2006-03-21 21:27:55 +0100 (Tue, 21 Mar 2006) $" + */ +package org.openehr.am.archetype.ontology; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * This class represents ontology section from an archetype + * + * @author Rong Chen + * @version 1.0 + */ +public class ArchetypeOntology implements Serializable{ + + /** + * Creates an ArchetypeOntology + * + * @param primaryLanguage + * @param languages + * @param terminologies + * @param termDefinitionsList + * @param constDefinitionsList + * @param termBindingList + * @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; + this.termBindingList = termBindingList; + this.constraintBindingList = constraintBindingList; + + // load defintionsMap + termDefinitionMap = new HashMap>(); + constraintDefinitionMap = new HashMap>(); + loadDefs(termDefinitionMap, termDefinitionsList); + loadDefs(constraintDefinitionMap, constDefinitionsList); + } + + private void loadDefs(Map> map, + List list) { + if (list == null) { + return; + } + Map codeMap = null; + for (OntologyDefinitions defs : list) { + codeMap = map.get(defs.getLanguage()); + if (null == codeMap) { + codeMap = new HashMap(); + } + for (ArchetypeTerm item : defs.getDefinitions()) { + codeMap.put(item.getCode(), item); + } + map.put(defs.getLanguage(), codeMap); + } + } + + public String getPrimaryLanguage() { + return primaryLanguage; + } + + public List getLanguages() { + return languages; + } + + public List getTerminologies() { + return terminologies; + } + + public List getTermDefinitionsList() { + return termDefinitionsList; + } + + public List getConstraintDefinitionsList() { + return constraintDefinitionsList; + } + + public List getTermBindingList() { + return termBindingList; + } + + public List getConstraintBindingList() { + return constraintBindingList; + } + + // null if not found + private ArchetypeTerm definition(String language, String code, + Map> definitionMap) { + Map map = definitionMap.get(language); + if (map == null) { + return null; + } + return map.get(code); + } + + /** + * Constraint definition for a code, in a specified language. + * + * @param language + * @param code + * @return null if not found + */ + public ArchetypeTerm constraintDefinition(String language, String code) { + return definition(language, code, constraintDefinitionMap); + } + + /** + * Term definition for a code, in a specified language. + * + * @param language + * @param code + * @return null if not found + */ + public ArchetypeTerm termDefinition(String language, String code) { + return definition(language, code, termDefinitionMap); + } + + /** + * Term definition for a code in the primary language. + * + * @param code + * @return not null + */ + public ArchetypeTerm termDefinition(String code) { + return definition(primaryLanguage, code, termDefinitionMap); + } + + /** + * String representation of this object + * + * @return string form + */ + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("primaryLanguage", primaryLanguage) + .append("languages", languages) + .append("terminologies", terminologies) + .append("termDefinitionsList", termDefinitionsList) + .append("constraintDefinitionsList", constraintDefinitionsList) + .append("termBindingList", termBindingList) + .append("constraintBindingList", constraintBindingList) + .toString(); + } + + /** + * Equals if two has the same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof ArchetypeOntology )) return false; + + final ArchetypeOntology ao = (ArchetypeOntology) o; + + return new EqualsBuilder() + .append(primaryLanguage, ao.primaryLanguage) + .append(languages, ao.languages) + .append(terminologies, ao.terminologies) + .append(termDefinitionsList, ao.termDefinitionsList) + .append(constraintDefinitionsList, + ao.constraintDefinitionsList) + .append(termBindingList, ao.termBindingList) + .append(constraintBindingList, ao.constraintBindingList) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(7, 29) + .append(primaryLanguage) + .append(languages) + .append(terminologies) + .append(termDefinitionsList) + .append(constraintDefinitionsList) + .append(termBindingList) + .append(constraintBindingList) + .toHashCode(); + } + + /* fields */ + private String primaryLanguage; + private List languages; + private List terminologies; + private List termDefinitionsList; + private List constraintDefinitionsList; + private List termBindingList; + private List constraintBindingList; + + /* calculated fields */ + // outer map language as key, inner map code as key + private Map> termDefinitionMap; + private Map> constraintDefinitionMap; +} + +/* + * ***** 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 ArchetypeOntology.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-aom/src/main/java/org/openehr/am/archetype/ontology/ArchetypeTerm.java b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/ArchetypeTerm.java new file mode 100644 index 00000000..2f2d4b89 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/ArchetypeTerm.java @@ -0,0 +1,187 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ArchetypeTerm" + * keywords: "archetype" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2007 ACODE HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ + +package org.openehr.am.archetype.ontology; + +import java.io.Serializable; +import java.util.*; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +public class ArchetypeTerm implements Serializable{ + + /** + * Constant added for convenience for commonly occuring key value in + * the item map. Actual string content is "text" (without quotes). + */ + public final static String TEXT = "text"; + + /** + * Constant added for convenience for commonly occuring key value in + * the item map. Actual string content is "description" (without quotes). + */ + public final static String DESCRIPTION = "description"; + + + /** + * Creates an ArchetypeTerm + * + * @param code not null or empty (atNNNN or acNNNN codes depening on usage context) + * @throws IllegalArgumentException if null or empty code + */ + public ArchetypeTerm(String code) { + if (StringUtils.isEmpty(code)) { + throw new IllegalArgumentException("null or empty code"); + } + this.code = code; + items = new LinkedHashMap(); + } + + /** + * Convenience constructor that calls the other constructor [ArchetypeTerm(String code)] + * and then adds two items to the hashmap using the keys described in parameters below. + * @param code not null or empty (atNNNN or acNNNN codes depending on usage context) + * @param text the String that will be stored in the item map under the key "text" + * @param description the String that will be stored in the item map under the key "description" + */ + public ArchetypeTerm(String code, String text, String description){ + this(code); + addItem(TEXT, text); + addItem(DESCRIPTION, description); + } + + /** + * Code of this term + * + * @return Returns the code. + */ + public String getCode() { + return code; + } + + /** + * Hash of keys (text, description etc) and corresponding values. + * + * @return Returns the items + */ + public Map getItems() { + return items; + } + + /** + * Adds an item (key, value) to this term + * + * @param key not null or empty + * @param value + */ + public void addItem(String key, String value) { + if(StringUtils.isEmpty(key)) { + throw new IllegalArgumentException("empty key"); + } + items.put(key, value); + } + + /** + * Gets item for given key + * + * @param key + * @return null if not found + */ + public String getItem(String key) { + return items.get(key); + } + + /** + * Convenience method to fetch the text of the archetype term. + * + * @return the text of the archetype term + */ + public String getText() { + return this.getItem(ArchetypeTerm.TEXT); + } + + /** Convenience method to fetch the description of the archetype term. + * + * @return the description of the archetype term + */ + public String getDescription() { + return this.getItem(ArchetypeTerm.DESCRIPTION); + } + + /** + * Equals if two has have same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof ArchetypeTerm )) return false; + + final ArchetypeTerm at = (ArchetypeTerm) o; + + return new EqualsBuilder() + .append(code, at.code) + .append(items, at.items) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(7, 47) + .append(code) + .append(items) + .toHashCode(); + } + + private String code; + + private Map items; +} +/* + * ***** 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 ArchetypeTerm.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): Erik Sundvall + * + * 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-aom/src/main/java/org/openehr/am/archetype/ontology/ConstraintBinding.java b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/ConstraintBinding.java new file mode 100644 index 00000000..9a26bb2c --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/ConstraintBinding.java @@ -0,0 +1,96 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ConstraintBinding" + * keywords: "archetype" + * + * 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/am/archetype/ontology/ConstraintBinding.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.am.archetype.ontology; + +import org.apache.commons.lang.StringUtils; + +/** + * This class represents a term constraint binding defined by a query + * + * @author Rong Chen + * @version 1.0 + */ +public final class ConstraintBinding { + + /** + * Constructs a term constraint binding + * + * @param target + * @param conditions + * @throws IllegalArgumentException if either target or conditions empty + */ + public ConstraintBinding(String target, String conditions) { + if(StringUtils.isEmpty(target)) { + throw new IllegalArgumentException("null or empty target"); + } + if(StringUtils.isEmpty(conditions)) { + throw new IllegalArgumentException("null or empty conditions"); + } + this.target = target; + this.conditions = conditions; + } + + /** + * Target of this binding + * + * @return target + */ + public String getTarget() { + return target; + } + + /** + * Conditions of this constraint + * + * @return conditions + */ + public String getConditions() { + return conditions; + } + + /* fields */ + private String target; + private String conditions; +} + +/* + * ***** 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 ConstraintBinding.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-aom/src/main/java/org/openehr/am/archetype/ontology/DefinitionItem.java b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/DefinitionItem.java new file mode 100644 index 00000000..d8f76c9c --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/DefinitionItem.java @@ -0,0 +1,126 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DefinitionItem" + * keywords: "archetype" + * + * 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/am/archetype/ontology/DefinitionItem.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.am.archetype.ontology; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +/** + * Definition item + * + * @author Rong Chen + * @version 1.0 + */ + +@Deprecated +public class DefinitionItem { + + public DefinitionItem(String code, String text, String description) { + this.code = code; + this.text = text; + this.description = description; + } + + public String getCode() { + return code; + } + + public String getText() { + return text; + } + + public String getDescription() { + return description; + } + + /** + * String representation of this object + * + * @return string form + */ + public String toString() { + return ToStringBuilder.reflectionToString(this, + ToStringStyle.MULTI_LINE_STYLE); + } + + /** + * Equals if two has the same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof DefinitionItem )) return false; + + final DefinitionItem di = (DefinitionItem) o; + + return new EqualsBuilder() + .append(code, di.code) + .append(text, di.text) + .append(description, di.description) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(3, 41) + .append(code) + .append(text) + .append(description) + .toHashCode(); + } + + /* fields */ + private String code; + private String text; + private String 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 DefinitionItem.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-aom/src/main/java/org/openehr/am/archetype/ontology/OntologyBinding.java b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/OntologyBinding.java new file mode 100644 index 00000000..aba0f2ff --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/OntologyBinding.java @@ -0,0 +1,133 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class OntologyBinding" + * keywords: "archetype" + * + * 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/am/archetype/ontology/OntologyBinding.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.am.archetype.ontology; + +import java.util.List; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; + +import java.io.Serializable; +/** + * This class represents a list of binding within a terminology using either + * term binding or query binding + * + * @author Rong Chen + * @version 1.0 + */ +public class OntologyBinding implements Serializable{ + + /** + * + */ + private static final long serialVersionUID = 1L; + public OntologyBinding(String terminology, + List bindingList) { + this.terminology = terminology; + this.bindingList = bindingList; + } + + public String getTerminology() { + return terminology; + } + + public List getBindingList() { + return bindingList; + } + + /** + * String representation of this object + * + * @return string form + */ + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, + ToStringStyle.MULTI_LINE_STYLE); + } + + /** + * Equals if two has have same values + * + * @param o + * @return true if equals + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof OntologyBinding )) { + return false; + } + + final OntologyBinding ob = (OntologyBinding) o; + + return new EqualsBuilder() + .append(terminology, ob.terminology) + .append(bindingList, ob.bindingList) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + @Override + public int hashCode() { + return new HashCodeBuilder(7, 47) + .append(terminology) + .append(bindingList) + .toHashCode(); + } + + + /* fields */ + private String terminology; + private List bindingList; +} + +/* + * ***** 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 OntologyBinding.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-aom/src/main/java/org/openehr/am/archetype/ontology/OntologyBindingItem.java b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/OntologyBindingItem.java new file mode 100644 index 00000000..096dd4e1 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/OntologyBindingItem.java @@ -0,0 +1,126 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class OntologyBindingItem" + * keywords: "archetype" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$Source: /usr/local/cvsroot/acode/openehr-kernel/src/java/org/openehr/am/archetype/ontology/OntologyBindingItem.java,v $" + * revision: "$Revision: 10 $" + * last_change: "$Date: 2005-11-22 22:26:12 +0100 (Tue, 22 Nov 2005) $" + */ +package org.openehr.am.archetype.ontology; + +import java.io.Serializable; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; + +/** + * Super class of QueryBindingItem and TermBindingItem + * + * @author Rong Chen + * @version 1.0 + */ +public class OntologyBindingItem implements Serializable { + + public OntologyBindingItem(String code) { + this.code = code; + } + + /** + * String representation of this object + * + * @return string form + */ + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, + ToStringStyle.MULTI_LINE_STYLE); + } + + /** + * @return the code + */ + public String getCode() { + return code; + } + + /** + * @param code the code to set + */ + public void setCode(String code) { + this.code = code; + } + + /** + * Equals if two has have same values + * + * @param o + * @return true if equals + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof OntologyBindingItem )) { + return false; + } + + final OntologyBindingItem obi = (OntologyBindingItem) o; + + return new EqualsBuilder() + .append(code, obi.code) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37) + .append(code) + .toHashCode(); + } + + /* fields */ + String code; +} + +/* + * ***** 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 OntologyBindingItem.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-aom/src/main/java/org/openehr/am/archetype/ontology/OntologyDefinitions.java b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/OntologyDefinitions.java new file mode 100644 index 00000000..7ba3b95d --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/OntologyDefinitions.java @@ -0,0 +1,126 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class OntologyDefinitions" + * keywords: "archetype" + * + * 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/am/archetype/ontology/OntologyDefinitions.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.am.archetype.ontology; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import java.io.Serializable; +import java.util.List; + +/** + * This class represents definitions for both terms and constraints + * + * @author Rong Chen + * @version 1.0 + */ +public class OntologyDefinitions implements Serializable{ + + /** + * Constructor + * + * @param language + * @param definitions + */ + public OntologyDefinitions(String language, + List definitions) { + this.language = language; + this.definitions = definitions; + } + + public String getLanguage() { + return language; + } + + public List getDefinitions() { + return definitions; + } + + /** + * String representation of this object + * + * @return string form + */ + public String toString() { + return ToStringBuilder.reflectionToString(this, + ToStringStyle.MULTI_LINE_STYLE); + } + + /** + * Equals if two has have same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof OntologyDefinitions )) return false; + + final OntologyDefinitions odefs = (OntologyDefinitions) o; + + return new EqualsBuilder() + .append(language, odefs.language) + .append(definitions, odefs.definitions) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(17, 37) + .append(language) + .append(definitions) + .toHashCode(); + } + + /* fields */ + private String language; + private List definitions; +} + +/* + * ***** 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 OntologyDefinitions.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-aom/src/main/java/org/openehr/am/archetype/ontology/Query.java b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/Query.java new file mode 100644 index 00000000..a4c498d4 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/Query.java @@ -0,0 +1,134 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Query" + * keywords: "archetype" + * + * 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/am/archetype/ontology/Query.java $" + * revision: "$LastChangedRevision: 24 $" + * last_change: "$LastChangedDate: 2006-03-31 17:08:58 +0200 (Fri, 31 Mar 2006) $" + */ +package org.openehr.am.archetype.ontology; + +import java.io.Serializable; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; + +/** + * The class represents a query to external terminology service. Immutable. + * + * @author Rong Chen + * @version 1.1 + */ +public class Query implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -4485822596246262897L; + + +/** + * Constructor + * + * @param url + */ + public Query(String url) { + this.url = url; + } + + /** + * The url of this query + * + * @return url + */ + public String getUrl() { + return url; + } + + /** + * String representation of this object + * + * @return string form + */ + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, + ToStringStyle.MULTI_LINE_STYLE); + } + + /** + * Equals if two has have same values + * + * @param o + * @return true if equals + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof Query )) { + return false; + } + + final Query query = (Query) o; + + return new EqualsBuilder() + .append(url, query.url) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + @Override + public int hashCode() { + return new HashCodeBuilder(7, 47) + .append(url) + .toHashCode(); + } + + + /* fields */ + private String url; +} + +/* + * ***** 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 Query.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-aom/src/main/java/org/openehr/am/archetype/ontology/QueryBindingItem.java b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/QueryBindingItem.java new file mode 100644 index 00000000..f8d9ba80 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/QueryBindingItem.java @@ -0,0 +1,118 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class QueryBindingItem" + * keywords: "archetype" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$Source: /usr/local/cvsroot/acode/openehr-kernel/src/java/org/openehr/am/archetype/ontology/QueryBindingItem.java,v $" + * revision: "$Revision: 10 $" + * last_change: "$Date: 2005-11-22 22:26:12 +0100 (Tue, 22 Nov 2005) $" + */ +package org.openehr.am.archetype.ontology; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +/** + * OntologyBindingItem that defines the binding by a query to external service + * + * @author Rong Chen + * @version 1.0 + */ +public class QueryBindingItem extends OntologyBindingItem { + + /** + * Creates a binding item with a qery + * + * @param code + * @param query + */ + public QueryBindingItem(String code, Query query) { + super(code); + this.query = query; + } + + /** + * Equals if two has have same values + * + * @param o + * @return true if equals + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof QueryBindingItem )) { + return false; + } + + final QueryBindingItem qbi = (QueryBindingItem) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(query, qbi.query) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + @Override + public int hashCode() { + return new HashCodeBuilder(19, 49) + .appendSuper(super.hashCode()) + .append(query) + .toHashCode(); + } + + + + /** + * Query of this binding item + * + * @return the query + */ + public Query getQuery() { + return query; + } + + /* fields */ + private Query query; +} + +/* + * ***** 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 QueryBindingItem.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-aom/src/main/java/org/openehr/am/archetype/ontology/TermBindingItem.java b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/TermBindingItem.java new file mode 100644 index 00000000..d74f3ed6 --- /dev/null +++ b/openehr-aom/src/main/java/org/openehr/am/archetype/ontology/TermBindingItem.java @@ -0,0 +1,119 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TermBindingItem" + * keywords: "archetype" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$Source: /usr/local/cvsroot/acode/openehr-kernel/src/java/org/openehr/am/archetype/ontology/TermBindingItem.java,v $" + * revision: "$Revision: 10 $" + * last_change: "$Date: 2005-11-22 22:26:12 +0100 (Tue, 22 Nov 2005) $" + */ +package org.openehr.am.archetype.ontology; + +import java.util.Collections; +import java.util.List; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +/** + * OntologyBindingItem that defines the binding by a list of external terms + * + * @author Rong Chen + * @version 1.0 + */ +public class TermBindingItem extends OntologyBindingItem { + + /** + * Creates a binding item with a list of terms + * + * @param code + * @param terms + */ + public TermBindingItem(String code, List terms) { + super(code); + this.terms = terms; + } + + + /** + * Equals if two has have same values + * + * @param o + * @return true if equals + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof TermBindingItem )) { + return false; + } + + final TermBindingItem tbi = (TermBindingItem) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(terms, tbi.terms) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + @Override + public int hashCode() { + return new HashCodeBuilder(21, 51) + .appendSuper(super.hashCode()) + .append(terms) + .toHashCode(); + } + + /** + * Gets an unmodifiable list of terms + * + * @return terms + */ + public List getTerms() { + return Collections.unmodifiableList(terms); + } + + private List terms; +} + +/* + * ***** 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 TermBindingItem.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-aom/src/test/java/org/openehr/am/archetype/ArchetypePathTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/ArchetypePathTest.java new file mode 100644 index 00000000..24d38a2b --- /dev/null +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/ArchetypePathTest.java @@ -0,0 +1,5 @@ +package org.openehr.am.archetype; + +public class ArchetypePathTest { + +} 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 new file mode 100644 index 00000000..6f5a9de5 --- /dev/null +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/assertion/AssertionTest.java @@ -0,0 +1,72 @@ +package org.openehr.am.archetype.assertion; + +import junit.framework.TestCase; + +public class AssertionTest extends TestCase { + + /** + * Tests to create a simple invariant assertion from the ADL spec + * + * invariant + * validity: /[at0001]/speed[at0002]/kilometres/magnitude = + * /[at0003]/speed[at0004]/miles/magnitude * 1.6 + * + */ + public void testCreateSimpleInvariantAssertion() { + ExpressionLeaf num = new ExpressionLeaf(ExpressionItem.REAL, + new Double(1.6), ExpressionLeaf.ReferenceType.CONSTANT); + + ExpressionItem miles = new ExpressionLeaf(ExpressionItem.REAL, + "/[at0003]/speed[at0004]/miles/magnitude", + ExpressionLeaf.ReferenceType.ATTRIBUTE); + + ExpressionItem kilometres = new ExpressionLeaf(ExpressionItem.REAL, + "/[at0001]/speed[at0002]/kilometres/magnitude", + ExpressionLeaf.ReferenceType.ATTRIBUTE); + + ExpressionItem calculated = new ExpressionBinaryOperator( + ExpressionItem.REAL, OperatorKind.OP_MULTIPLY, false, + miles, num); + + ExpressionItem whole = new ExpressionBinaryOperator( + ExpressionItem.BOOLEAN, OperatorKind.OP_EQ, false, + kilometres, calculated); + + String stringExpression = + "/[at0001]/speed[at0002]/kilometres/magnitude = " + + "/[at0003]/speed[at0004]/miles/magnitude * 1.6"; + Assertion invariant = new Assertion("validity", whole, + stringExpression, null); + + assertNotNull("failed to create invariant assertion", invariant); + assertNotNull("null expression item of invariant assertion", + invariant.getExpression()); + assertEquals("string expression wrong", stringExpression, + invariant.getStringExpression()); + } + + /** + * Tests to create a simple assertion used by archetype slot + * + * include + * domain_concept matches {/medications.v1/} + */ + public void testCreateSimpleArchetypeSlot() { + ExpressionItem concept = new ExpressionLeaf(ExpressionItem.ARCHETYPE, + "domain_concept", ExpressionLeaf.ReferenceType.ATTRIBUTE); + ExpressionItem aid = new ExpressionLeaf(ExpressionItem.ARCHETYPE, + "/medications.v1/", ExpressionLeaf.ReferenceType.CONSTANT); + ExpressionItem whole = new ExpressionBinaryOperator( + ExpressionItem.BOOLEAN, OperatorKind.OP_MATCHES, false, + concept, aid); + + String stringExpression = "domain_concept matches {/medications.v1/}"; + + Assertion include = new Assertion(whole, stringExpression); + assertNotNull("failed to create invariant assertion", include); + assertNotNull("null expression item of invariant assertion", + include.getExpression()); + assertEquals("string expression wrong", stringExpression, + include.getStringExpression()); + } +} 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 new file mode 100644 index 00000000..15b39933 --- /dev/null +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/assertion/ExpressionToStringTest.java @@ -0,0 +1,73 @@ +package org.openehr.am.archetype.assertion; + +import org.openehr.am.archetype.constraintmodel.primitive.CString; + +import junit.framework.TestCase; + +/** + * Testcases for toString function of expression items + * + * @author rong.chen + * + */ +public class ExpressionToStringTest extends TestCase { + + public void testSimpleInvariantToString() throws Exception { + ExpressionLeaf num = new ExpressionLeaf(ExpressionItem.REAL, + new Double(1.6), ExpressionLeaf.ReferenceType.CONSTANT); + + ExpressionItem miles = new ExpressionLeaf(ExpressionItem.REAL, + "/[at0003]/speed[at0004]/miles/magnitude", + ExpressionLeaf.ReferenceType.ATTRIBUTE); + + ExpressionItem kilometres = new ExpressionLeaf(ExpressionItem.REAL, + "/[at0001]/speed[at0002]/kilometres/magnitude", + ExpressionLeaf.ReferenceType.ATTRIBUTE); + + ExpressionItem calculated = new ExpressionBinaryOperator( + ExpressionItem.REAL, OperatorKind.OP_MULTIPLY, false, + miles, num); + + ExpressionItem whole = new ExpressionBinaryOperator( + ExpressionItem.BOOLEAN, OperatorKind.OP_EQ, false, + kilometres, calculated); + + String expected = + "/[at0001]/speed[at0002]/kilometres/magnitude = " + + "/[at0003]/speed[at0004]/miles/magnitude * 1.6"; + + assertEquals("expressionItem.toString() fails, got " + whole.toString(), + expected, whole.toString()); + } + + public void testSimpleArchetypeSlotToString() { + ExpressionItem concept = new ExpressionLeaf(ExpressionItem.ARCHETYPE, + "domain_concept", ExpressionLeaf.ReferenceType.ATTRIBUTE); + ExpressionItem aid = new ExpressionLeaf(ExpressionItem.ARCHETYPE, + "/medications.v1/", ExpressionLeaf.ReferenceType.CONSTANT); + ExpressionItem whole = new ExpressionBinaryOperator( + ExpressionItem.BOOLEAN, OperatorKind.OP_MATCHES, false, + concept, aid); + + String expected = "domain_concept matches {/medications.v1/}"; + + assertEquals("toString fails, got: " + whole.toString(), + expected, whole.toString()); + } + + public void testSimpleArchetypeSlotToStringUsingCString() { + ExpressionItem concept = new ExpressionLeaf(ExpressionItem.ARCHETYPE, + "domain_concept", ExpressionLeaf.ReferenceType.ATTRIBUTE); + ExpressionItem aid = new ExpressionLeaf(ExpressionItem.ARCHETYPE, + new CString("medications.v1"), + ExpressionLeaf.ReferenceType.CONSTANT); + ExpressionItem whole = new ExpressionBinaryOperator( + ExpressionItem.BOOLEAN, OperatorKind.OP_MATCHES, false, + concept, aid); + + String expected = "domain_concept matches {/medications.v1/}"; + + assertEquals("toString fails, got: " + whole.toString(), + expected, whole.toString()); + } +} 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 new file mode 100644 index 00000000..3a2716d7 --- /dev/null +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/ArchetypeSlotTest.java @@ -0,0 +1,75 @@ +package org.openehr.am.archetype.constraintmodel; + +import org.openehr.am.archetype.assertion.*; +import org.openehr.rm.support.basic.Interval; + +import junit.framework.TestCase; + +import java.util.*; + +/** + * Simple test for ArchetypeSlot + * + * @author Rong Chen + */ +public class ArchetypeSlotTest extends TestCase { + + public void testCreateEmptyArchetypeSlot() { + Interval occurrences = new Interval(1, 1); + ArchetypeSlot slot = new ArchetypeSlot("/path", "Entry", occurrences, + "at001", null, null, null); + assertTrue("anyAllowed expected for empty slot", slot.isAnyAllowed()); + } + + /** + * Tests to create a simple archetype slot + */ + // Sample from ADL spec: + // allow_archetype SECTION occurrences matches {0..*} matches { + // include + // archetype_id matches {/.*\.iso-ehr\.section\..*\..*/} + // exclude + // archetype_id matches {/.*\.iso-ehr\.section\.patient_details\..*/} + // } + public void testCreateSimpleArchetypeSlot() { + ExpressionItem iaid = new ExpressionLeaf(ExpressionItem.ARCHETYPE, + "archetype_id", ExpressionLeaf.ReferenceType.ATTRIBUTE); + ExpressionItem include_aid = new ExpressionLeaf( + ExpressionItem.ARCHETYPE, + "/.*\\.iso-ehr\\.section\\..*\\..*/", ExpressionLeaf.ReferenceType.CONSTANT); + ExpressionItem includeExpr = new ExpressionBinaryOperator( + ExpressionItem.BOOLEAN, OperatorKind.OP_MATCHES, false, + iaid, include_aid); + String include_string = "archetype_id matches {/.*\\.iso-ehr\\.section\\..*\\..*/}"; + Assertion include = new Assertion(includeExpr, include_string); + + ExpressionItem eaid = new ExpressionLeaf(ExpressionItem.ARCHETYPE, + "archetype_id", ExpressionLeaf.ReferenceType.ATTRIBUTE); + ExpressionItem exclude_aid = new ExpressionLeaf( + ExpressionItem.ARCHETYPE, + "/.*\\.iso-ehr\\.section\\.patient_details\\..*/", + ExpressionLeaf.ReferenceType.CONSTANT); + ExpressionItem excludeExpr = new ExpressionBinaryOperator( + ExpressionItem.BOOLEAN, OperatorKind.OP_MATCHES, false, + eaid, exclude_aid); + String exclude_string = "archetype_id matches {/.*\\.iso-ehr\\.section\\.patient_details\\..*/}"; + Assertion exclude = new Assertion(excludeExpr, exclude_string); + + Set includes = new HashSet(); + includes.add(include); + Set excludes = new HashSet(); + excludes.add(exclude); + ArchetypeSlot slot1 = new ArchetypeSlot("/[at001]", "SECTION", + new Interval(0, null), "at001", null, includes, + excludes); + + // create another identical slot and compare + ArchetypeSlot slot2 = new ArchetypeSlot("/[at001]", "SECTION", + new Interval(0, null), "at001", null, includes, + excludes); + + assertEquals(slot1, slot2); + assertEquals(slot1.hashCode(), slot2.hashCode()); + + } +} 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 new file mode 100644 index 00000000..23bae574 --- /dev/null +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/CAttributeTest.java @@ -0,0 +1,140 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CAttributeTest" + * keywords: "archetype" + * + * 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/test/org/openehr/am/archetype/constraintmodel/CAttributeTest.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +/** + * CAttributeTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.am.archetype.constraintmodel; + +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; + } + } + +} +/* + * ***** 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 CAttributeTest.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-aom/src/test/java/org/openehr/am/archetype/constraintmodel/CObjectTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/CObjectTest.java new file mode 100644 index 00000000..b3aec4e0 --- /dev/null +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/CObjectTest.java @@ -0,0 +1,101 @@ +package org.openehr.am.archetype.constraintmodel; + +import org.openehr.rm.support.basic.Interval; + +import junit.framework.TestCase; + +public class CObjectTest extends TestCase { + + public void testCreateCObjectWithNullOccurrences() { + boolean anyAllowed = false; + String path = "/[at001]"; + String rmType = "TEST_OBJECT"; + Interval occurrences = null; + String nodeID = "at001"; + CAttribute parent = null; + + try { + new TestCObject(anyAllowed, path, rmType, occurrences, nodeID, + parent); + fail("should fail to create CObject with null occurrences"); + } catch(Exception e) { + // expected + } + } + + public CObject copy() { + return null; + } + + public void testCreateCObjectWithDefaultOccurrences() { + boolean anyAllowed = false; + String path = "/[at001]"; + String rmType = "TEST_OBJECT"; + Interval occurrences = new Interval(1, 1); + String nodeID = "at001"; + CAttribute parent = null; + + try { + new TestCObject(anyAllowed, path, rmType, occurrences, nodeID, + parent); + } catch(Exception e) { + fail("failed to create CObject with default occurrences"); + } + } + + public void testIsRequiredWithDefaultOccurrences() throws Exception { + boolean anyAllowed = false; + String path = "/[at001]"; + String rmType = "TEST_OBJECT"; + Interval occurrences = new Interval(1, 1); + String nodeID = "at001"; + CAttribute parent = null; + + CObject cobj = new TestCObject(anyAllowed, path, rmType, occurrences, + nodeID, parent); + + assertTrue("expected to be required", cobj.isRequired()); + } + + public void testIsRequiredWithOnlyLowerLimitOccurrences() throws Exception { + boolean anyAllowed = false; + String path = "/[at001]"; + String rmType = "TEST_OBJECT"; + Interval occurrences = new Interval(1, null); + String nodeID = "at001"; + CAttribute parent = null; + + CObject cobj = new TestCObject(anyAllowed, path, rmType, occurrences, + nodeID, parent); + + assertTrue("expected to be required", cobj.isRequired()); + } + + private static class TestCObject extends CObject { + public CObject copy() { + return null; + } + + TestCObject(boolean anyAllowed, String path, String rmTypeName, + Interval occurrences, String nodeID, + CAttribute parent) { + super(anyAllowed, path, rmTypeName, occurrences, nodeID, parent); + } + + @Override + public boolean isValid() { + return false; + } + + @Override + public boolean hasPath(String path) { + return false; + } + + @Override + public boolean isSubsetOf(ArchetypeConstraint constraint) { + return false; + } + + } +} 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 new file mode 100644 index 00000000..04004124 --- /dev/null +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/CPrimitiveObjectTest.java @@ -0,0 +1,15 @@ +package org.openehr.am.archetype.constraintmodel; + +import org.openehr.am.archetype.constraintmodel.primitive.CString; +import org.openehr.rm.support.basic.Interval; + +import junit.framework.TestCase; + +public class CPrimitiveObjectTest extends TestCase { + + public void testConstructorWithItem() { + Interval occurrences = new Interval(1, 1); + CString item = new CString("file.*", null); + new CPrimitiveObject("/path", occurrences, null, null, item); + } +} 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 new file mode 100644 index 00000000..8a881c74 --- /dev/null +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CBooleanTest.java @@ -0,0 +1,101 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CBooleanTest" + * keywords: "archetype" + * + * 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/test/org/openehr/am/archetype/constraintmodel/primitive/CBooleanTest.java $" + * revision: "$LastChangedRevision: 23 $" + * last_change: "$LastChangedDate: 2006-03-31 02:40:54 +0200 (Fri, 31 Mar 2006) $" + */ +/** + * CBooleanTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.am.archetype.constraintmodel.primitive; + +import junit.framework.TestCase; +import org.openehr.rm.datatypes.basic.DvBoolean; + +public class CBooleanTest extends TestCase { + + public CBooleanTest(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 testValidValue() throws Exception { + CBoolean cb = new CBoolean(true, true); + assertTrue(cb.validValue(Boolean.TRUE)); + assertTrue(cb.validValue(Boolean.FALSE)); + + cb = new CBoolean(true, false); + assertTrue(cb.validValue(Boolean.TRUE)); + assertTrue(!cb.validValue(Boolean.FALSE)); + + cb = new CBoolean(false, true); + assertTrue(!cb.validValue(Boolean.TRUE)); + assertTrue(cb.validValue(Boolean.FALSE)); + } + + public void testAssignedValue() throws Exception { + CBoolean cb = new CBoolean(true, true); + assertFalse(cb.hasAssignedValue()); + assertTrue(cb.assignedValue() == null); + + cb = new CBoolean(true, false); + assertTrue(cb.hasAssignedValue()); + assertEquals(DvBoolean.TRUE, cb.assignedValue()); + + cb = new CBoolean(false, true); + assertTrue(cb.hasAssignedValue()); + assertEquals(DvBoolean.FALSE, cb.assignedValue()); + } + + public void testConstructorWithoutAssumedValue() throws Exception { + CBoolean cb = new CBoolean(true, true); + assertFalse("hasAssumedValue() should be false", cb.hasAssumedValue()); + } +} +/* + * ***** 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 CBooleanTest.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-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 new file mode 100644 index 00000000..ed013813 --- /dev/null +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CDateTest.java @@ -0,0 +1,129 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CDateTest" + * keywords: "archetype" + * + * 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/test/org/openehr/am/archetype/constraintmodel/primitive/CDateTest.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +/** + * CDateTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.am.archetype.constraintmodel.primitive; + +import junit.framework.TestCase; +import org.openehr.rm.datatypes.quantity.datetime.DvDate; +import org.openehr.rm.support.basic.Interval; + +import java.util.*; + +public class CDateTest extends TestCase { + + public CDateTest(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 testValidValueWithDateInterval() throws Exception { + CDate cd = new CDate(null, new Interval(dvDate( + "2001-01-01"), dvDate("2001-12-31")), null); + assertTrue(cd.validValue(dvDate("2001-01-01"))); + assertTrue(cd.validValue(dvDate("2001-12-31"))); + assertTrue(cd.validValue(dvDate("2001-03-10"))); + assertTrue(cd.validValue(dvDate("2001-10-30"))); + assertFalse(cd.validValue(dvDate("2000-01-01"))); + assertFalse(cd.validValue(dvDate("2002-01-01"))); + } + + public void testCreateCDateWithPattern() { + CDate cd = new CDate("yyyy-mm-dd"); + assertNotNull(cd); + } + + public void testValidValueWithDateList() throws Exception { + + DvDate[] dates = new DvDate[]{ + dvDate("2001-01-01"), dvDate("2002-10-15"), dvDate("2004-02-10") + }; + + CDate cd = new CDate(null, null, Arrays.asList(dates)); + + for (int i = 0; i < dates.length; i++) { + assertTrue(dates[ i ].toString(), cd.validValue(dates[ i ])); + } + assertFalse(cd.validValue(dvDate("2001-01-02"))); + assertFalse(cd.validValue(dvDate("2002-10-12"))); + assertFalse(cd.validValue(dvDate("2004-03-10"))); + } + + private DvDate dvDate(String value) throws Exception { + return new DvDate(value); + } + + public void testAssignedValue() throws Exception { + CDate cd = new CDate(null, new Interval(dvDate( + "2001-01-01"), dvDate("2001-12-31")), null); + assertFalse(cd.hasAssignedValue()); + assertTrue(cd.assignedValue() == null); + + cd = new CDate("yyyy-MM-dd", null, null); + assertFalse(cd.hasAssignedValue()); + assertTrue(cd.assignedValue() == null); + + List list = new ArrayList(); + list.add(new DvDate("1999-10-11")); + cd = new CDate(null, null, list); + assertTrue(cd.hasAssignedValue()); + assertEquals(new DvDate("1999-10-11"), + cd.assignedValue()); + } +} +/* + * ***** 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 CDateTest.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-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 new file mode 100644 index 00000000..960f7494 --- /dev/null +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CDateTimeTest.java @@ -0,0 +1,164 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CDateTimeTest" + * keywords: "archetype" + * + * 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/test/org/openehr/am/archetype/constraintmodel/primitive/CDateTimeTest.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +/** + * CDateTimeTeset + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.am.archetype.constraintmodel.primitive; + +import junit.framework.TestCase; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.support.basic.Interval; + +import java.util.*; + +public class CDateTimeTest extends TestCase { + + public CDateTimeTest(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 testValidDataWithDateInterval() throws Exception { + + CDateTime cd = new CDateTime(null, new Interval(dvDateTime( + "1999-01-12T01:10:30"), + dvDateTime("2001-10-25T20:05:10")), null); + + String[] values = { + "1999-01-12T01:10:30", "1999-01-12T01:10:31", + "1999-01-12T01:11:30", "1999-01-12T02:10:30", + "1999-01-13T01:10:30", "1999-02-12T01:10:30", + "2000-01-12T01:10:30", "2001-10-25T20:05:10", + "2001-10-25T20:05:09", "2001-10-25T20:04:10", + "2001-10-25T19:05:10", "2001-10-24T20:05:10", + "2001-09-25T20:05:10", "2000-10-25T20:05:10" + }; + assertValues(cd, values, true); + + values = new String[]{ + "1999-01-12T01:10:29", "1999-01-12T01:09:30", + "1999-01-12T00:10:30", "1999-01-11T01:10:30", + "1998-12-12T01:10:30", "1998-01-12T01:10:30", + "2001-10-25T20:05:11", "2001-10-25T20:06:10", + "2001-10-25T21:05:10", "2001-10-26T20:05:10", + "2001-11-25T20:05:10", "2002-10-25T20:05:10" + }; + assertValues(cd, values, false); + } + + public void testCreateCDateTimeWithPattern() { + CDateTime cdatetime = new CDateTime("yyyy-mm-ddTHH:MM:SS"); + assertNotNull(cdatetime); + } + + public void testValidDateWithDateList() throws Exception { + String[] values = { + "2000-10-25T00:00:00", "2001-10-26T20:05:10", + "1998-01-01T23:10:15", "2003-12-31T23:59:59" + }; + CDateTime cd = new CDateTime(null, null, dvDateList(values)); + assertValues(cd, values, true); + + values = new String[]{ + "2002-10-25T00:00:01", "2002-10-26T20:05:10", + "1998-01-01T23:11:15", "2003-12-31T23:00:00" + }; + assertValues(cd, values, false); + } + + public void testAssignedValue() throws Exception { + CDateTime cd = new CDateTime(null, + new Interval(dvDateTime("2001-01-01T00:00:00"), + dvDateTime("2001-12-31T00:00:00")), null); + assertFalse(cd.hasAssignedValue()); + assertTrue(cd.assignedValue() == null); + + cd = new CDateTime("yyyy-MM-ddTHH:mm:ss", null, null); + assertFalse(cd.hasAssignedValue()); + assertTrue(cd.assignedValue() == null); + + List list = new ArrayList(); + list.add(new DvDateTime("1999-10-11T00:00:00")); + cd = new CDateTime(null, null, list); + assertTrue(cd.hasAssignedValue()); + assertEquals(new DvDateTime("1999-10-11T00:00:00"), + cd.assignedValue()); + } + + + private void assertValues(CDateTime cd, String[] values, + boolean expected) throws Exception { + for (int i = 0; i < values.length; i++) { + assertEquals(values[ i ] + " expected " + expected, + expected, cd.validValue(dvDateTime(values[ i ]))); + } + } + + private DvDateTime dvDateTime(String value) throws Exception { + return new DvDateTime(value); + } + + private List dvDateList(String[] values) throws Exception { + List list = new ArrayList(); + for (int i = 0; i < values.length; i++) { + list.add(dvDateTime(values[ i ])); + } + return 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 CDateTimeTest.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-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 new file mode 100644 index 00000000..b6a203e1 --- /dev/null +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CDurationTest.java @@ -0,0 +1,94 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CDurationTest" + * keywords: "archetype" + * + * 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/test/org/openehr/am/archetype/constraintmodel/primitive/CDurationTest.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +/** + * CDurationTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.am.archetype.constraintmodel.primitive; + +import junit.framework.TestCase; + +import org.openehr.rm.datatypes.quantity.datetime.DvDuration; +import org.openehr.rm.support.basic.Interval; + +public class CDurationTest extends TestCase { + + public CDurationTest(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 testAssignedValue() throws Exception { + CDuration cd = new CDuration(null, + new Interval(DvDuration.getInstance("PT1h"), + DvDuration.getInstance("PT3h"))); + assertFalse(cd.hasAssignedValue()); + assertTrue(cd.assignedValue() == null); + + + cd = new CDuration(DvDuration.getInstance("PT1h"), null); + assertTrue(cd.hasAssignedValue()); + assertEquals(DvDuration.getInstance("PT1h"), cd.assignedValue()); + } + + public void testCreateCDurationByPattern() { + CDuration cd = new CDuration(null, null, null, "PDTH"); + assertEquals("pattern wrong", "PDTH", cd.getPattern()); + } +} +/* + * ***** 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 CDurationTest.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-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 new file mode 100644 index 00000000..cb32e2cc --- /dev/null +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CIntegerTest.java @@ -0,0 +1,102 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CIntegerTest" + * keywords: "archetype" + * + * 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/test/org/openehr/am/archetype/constraintmodel/primitive/CIntegerTest.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +/** + * CIntegerTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.am.archetype.constraintmodel.primitive; + +import junit.framework.TestCase; +import org.openehr.rm.support.basic.Interval; + +import java.util.Arrays; + +public class CIntegerTest extends TestCase { + + public CIntegerTest(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 { + } + + /** + * Tests validValue() with a list of integer values or an interval + */ + public void testValidValue() { + CInteger ci = new CInteger(new Interval(null, new Integer(10), + false, false), null); + assertTrue(ci.validValue(new Integer(9))); + assertTrue(ci.validValue(new Integer(-10))); + assertTrue(!ci.validValue(new Integer(10))); + assertTrue(!ci.validValue(new Integer(11))); + + ci = new CInteger(new Interval(new Integer(1), null, true, + false), null); + assertTrue(ci.validValue(new Integer(1))); + assertTrue(ci.validValue(new Integer(2))); + assertTrue(!ci.validValue(new Integer(0))); + assertTrue(!ci.validValue(new Integer(-1))); + + Integer[] values = {new Integer(-2), new Integer(0), new Integer(2)}; + ci = new CInteger(null, Arrays.asList(values)); + assertTrue(ci.validValue(new Integer(-2))); + assertTrue(ci.validValue(new Integer(2))); + assertTrue(ci.validValue(new Integer(0))); + assertTrue(!ci.validValue(new Integer(-1))); + assertTrue(!ci.validValue(new Integer(1))); + } +} + +/* + * ***** 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 CIntegerTest.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-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 new file mode 100644 index 00000000..0a7403d7 --- /dev/null +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CRealTest.java @@ -0,0 +1,99 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CRealTest" + * keywords: "archetype" + * + * 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/test/org/openehr/am/archetype/constraintmodel/primitive/CRealTest.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +/** + * CRealTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.am.archetype.constraintmodel.primitive; + +import junit.framework.TestCase; +import org.openehr.rm.support.basic.Interval; + +import java.util.Arrays; + +public class CRealTest extends TestCase { + + public CRealTest(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 testValidValue() throws Exception { + CReal cr = new CReal(new Interval(null, new Double(10), + false, false), null); + assertTrue(cr.validValue(new Double(9))); + assertTrue(cr.validValue(new Double(-10))); + assertTrue(!cr.validValue(new Double(10))); + assertTrue(!cr.validValue(new Double(11))); + + cr = new CReal(new Interval(new Double(1), + null, true, false), null); + assertTrue(cr.validValue(new Double(1))); + assertTrue(cr.validValue(new Double(2))); + assertTrue(!cr.validValue(new Double(0))); + assertTrue(!cr.validValue(new Double(-1))); + + Double[] values = {new Double(-2), new Double(0), new Double(2)}; + cr = new CReal(null, Arrays.asList(values)); + assertTrue(cr.validValue(new Double(-2))); + assertTrue(cr.validValue(new Double(2))); + assertTrue(cr.validValue(new Double(0))); + assertTrue(!cr.validValue(new Double(-1))); + assertTrue(!cr.validValue(new Double(1))); + } +} + +/* + * ***** 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 CRealTest.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-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 new file mode 100644 index 00000000..3c62f403 --- /dev/null +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CStringTest.java @@ -0,0 +1,120 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CStringTest" + * keywords: "archetype" + * + * 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/test/org/openehr/am/archetype/constraintmodel/primitive/CStringTest.java $" + * revision: "$LastChangedRevision: 23 $" + * last_change: "$LastChangedDate: 2006-03-31 02:40:54 +0200 (Fri, 31 Mar 2006) $" + */ +/** + * CStringTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.am.archetype.constraintmodel.primitive; + +import junit.framework.TestCase; + +import java.util.Arrays; + +public class CStringTest extends TestCase { + + public CStringTest(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 testValidValue() throws Exception { + CString cs = new CString("file.*", null); + assertTrue(cs.validValue("file.txt")); + assertTrue(cs.validValue("file.exe")); + assertTrue(cs.validValue("file.zip")); + assertFalse(cs.validValue("read.zip")); + + cs = new CString("this|that|something else", null); + assertTrue(cs.validValue("this")); + assertTrue(cs.validValue("that")); + assertTrue(cs.validValue("something else")); + assertFalse(cs.validValue("something")); + + String[] values = {"apple", "pear", "orange"}; + cs = new CString(null, Arrays.asList(values)); + assertTrue(cs.validValue("apple")); + assertTrue(cs.validValue("pear")); + assertTrue(cs.validValue("orange")); + assertFalse(cs.validValue("melon")); + } + + public void testAssignedValue() throws Exception { + + // with pattern + CString cs = new CString("file.*", null); + assertFalse(cs.hasAssignedValue()); + assertTrue(cs.assignedValue() == null); + + // with multi item list + String[] values = {"apple", "pear", "orange"}; + cs = new CString(null, Arrays.asList(values)); + assertFalse(cs.hasAssignedValue()); + assertTrue(cs.assignedValue() == null); + + // with single item list + values = new String[] {"apple"}; + cs = new CString(null, Arrays.asList(values)); + assertTrue(cs.hasAssignedValue()); + String text = cs.assignedValue(); + assertEquals("wrong value", "apple", text); + } + + public void testConstructorWithoutAssumedValue() throws Exception { + CString cs = new CString("file.*", null); + assertFalse("shouldn't have an assumed value", cs.hasAssumedValue()); + } +} +/* + * ***** 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 CStringTest.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-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 new file mode 100644 index 00000000..98294f68 --- /dev/null +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CTimeTest.java @@ -0,0 +1,151 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CTimeTest" + * keywords: "archetype" + * + * 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/test/org/openehr/am/archetype/constraintmodel/primitive/CTimeTest.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +/** + * CTimeTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.am.archetype.constraintmodel.primitive; + +import junit.framework.TestCase; +import org.openehr.rm.datatypes.quantity.datetime.DvTime; +import org.openehr.rm.support.basic.Interval; + +import java.util.*; + +public class CTimeTest extends TestCase { + + public CTimeTest(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 testCreateCTimeWithPattern() { + CTime ctime = new CTime("HH:MM:SS"); + assertNotNull(ctime); + } + + public void testValidateByTimeInterval() throws Exception { + CTime ct = new CTime(null, new Interval(dvTime( + "10:20:30"), dvTime("12:10:45")), null); + + String[] values = { + "10:20:30", "10:20:31", "10:21:30", "11:20:30", + "12:10:45", "12:10:44", "12:09:45", "11:10:45" + }; + assertValues(ct, values, true); + + values = new String[] { + "10:20:29", "10:19:30", "09:20:30", + "12:10:46", "12:11:45", "13:10:45" + }; + assertValues(ct, values, false); + } + + public void testValidateByTimeList() throws Exception { + String[] values = { + "00:01:10", "05:10:59", "06:20:50", "22:00:00", + "23:59:59", "00:00:00" + }; + CTime ct = new CTime(null, null, dvTimeList(values)); + assertValues(ct, values, true); + + values = new String[] { + "00:01:11", "05:11:59", "07:20:50", "23:00:00", + "23:59:58", "00:00:01" + }; + assertValues(ct, values, false); + } + + public void testAssignedValue() throws Exception { + CTime cd = new CTime(null, + new Interval(dvTime("00:00:00"), + dvTime("10:00:00")), null); + assertFalse(cd.hasAssignedValue()); + assertTrue(cd.assignedValue() == null); + + cd = new CTime("HH:mm:ss", null, null); + assertFalse(cd.hasAssignedValue()); + assertTrue(cd.assignedValue() == null); + + List list = new ArrayList(); + list.add(new DvTime("08:00:00")); + cd = new CTime(null, null, list); + assertTrue(cd.hasAssignedValue()); + assertEquals(new DvTime("08:00:00"), + cd.assignedValue()); + } + + private void assertValues(CTime ct, String[] values, + boolean expected) throws Exception { + for(int i = 0; i < values.length; i++) { + assertEquals(values[i] + " expected " + expected, expected, + ct.validValue(dvTime(values[i]))); + } + } + + private List dvTimeList(String[] values) throws Exception { + List list = new ArrayList(); + for(int i = 0; i < values.length; i++) { + list.add(dvTime(values[i])); + } + return list; + } + + private DvTime dvTime(String value) throws Exception { + return new DvTime(value); + } +} +/* + * ***** 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 CTimeTest.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-aom/src/test/java/org/openehr/am/archetype/ontology/ArchetypeOntologyTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/ontology/ArchetypeOntologyTest.java new file mode 100644 index 00000000..892dd7fc --- /dev/null +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/ontology/ArchetypeOntologyTest.java @@ -0,0 +1,103 @@ +package org.openehr.am.archetype.ontology; + +import junit.framework.TestCase; +import java.util.*; + +public class ArchetypeOntologyTest extends TestCase { + + public void setUp() { + String primaryLanguage = "en"; + List languages = new ArrayList(); + languages.add("en"); + languages.add("sv"); + + List terminologies = new ArrayList(); + terminologies.add("SNOMED CT"); + + List termDefinitionsList = new ArrayList(); + List items = new ArrayList(); + item0001 = new ArchetypeTerm("at0001"); + item0001.addItem("text", "blood pressure"); + item0001.addItem("description", "description of BP"); + items.add(item0001); + item0003 = new ArchetypeTerm("at0003"); + item0003.addItem("text", "diastolic pressure"); + item0003.addItem("description", "description of DP"); + items.add(item0003); + termDefinitionsList.add(new OntologyDefinitions("en", items)); + + items = new ArrayList(); + item0004 = new ArchetypeTerm("at0004"); + item0004.addItem("text", "diastolic pressure 2"); + item0004.addItem("description", "description of DP 2"); + items.add(item0004); + termDefinitionsList.add(new OntologyDefinitions("sv", items)); + + + List constDefinitionsList = new ArrayList(); + items = new ArrayList(); + item0002 = new ArchetypeTerm("at0002"); + item0002.addItem("text", "systolic pressure"); + item0002.addItem("description", "description SP"); + items.add(item0002); + constDefinitionsList.add(new OntologyDefinitions("sv", items)); + + ontology = new ArchetypeOntology(primaryLanguage, languages, + terminologies, termDefinitionsList, constDefinitionsList, null, null); + } + + public void tearDown() { + ontology = null; + item0001 = null; + item0002 = null; + item0003 = null; + } + + public void testFetchTermDefinitionWithGivenLanguage() { + assertEquals("termDefinition wrong", item0001, + ontology.termDefinition("en", "at0001")); + + assertEquals("termDefinition wrong", item0003, + ontology.termDefinition("en", "at0003")); + + assertEquals("termDefinition of item00004 wrong", item0004, + ontology.termDefinition("sv", "at0004")); + } + + public void testFetchTermDefinitionWithPrimaryLanguage() { + assertEquals("termDefinition wrong", item0001, + ontology.termDefinition("at0001")); + } + + /** + * Verify a bug-fix to do with definitions loading in the constructor + * + * @throws Exception + */ + public void testCreateAndGetDefinitions() throws Exception { + + // check term definition + ArchetypeTerm item = ontology.termDefinition("en", "at0001"); + assertNotNull("definition of [at0001] not found", item); + assertEquals("item wrong", item0001, item); + + // test convenience methods getText and getDescription + assertEquals("item text wrong", item0001.getText(), "blood pressure"); + assertEquals("item text wrong", item0001.getDescription(), "description of BP"); + + assertNull(ontology.termDefinition("en", "at0002")); + + // check constraint definition + item = ontology.constraintDefinition("sv", "at0002"); + assertNotNull("definition of [at0002] not found", item); + assertEquals("item wrong", item0002, item); + + assertNull(ontology.constraintDefinition("en", "at0001")); + } + + private ArchetypeOntology ontology; + private ArchetypeTerm item0001; + private ArchetypeTerm item0002; + private ArchetypeTerm item0003; + private ArchetypeTerm item0004; +} 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 new file mode 100644 index 00000000..fa46af42 --- /dev/null +++ b/openehr-aom/src/test/java/org/openehr/am/archetype/ontology/ArchetypeTermTest.java @@ -0,0 +1,28 @@ +package org.openehr.am.archetype.ontology; + +import junit.framework.TestCase; + +public class ArchetypeTermTest extends TestCase { + + public void setUp() { + term = new ArchetypeTerm("at0001", TEXT, DESC); + } + + public void tearDown() { + term = null; + } + + public void testGetText() { + assertEquals("text wrong", TEXT, term.getText()); + } + + public void testGetDescription() { + assertEquals("description wrong", DESC, term.getDescription()); + } + + private static final String TEXT = "text"; + private static final String DESC = "description"; + + private ArchetypeTerm term; + +} diff --git a/openehr-ap/docs/changes.txt b/openehr-ap/docs/changes.txt new file mode 100644 index 00000000..9f34d1ef --- /dev/null +++ b/openehr-ap/docs/changes.txt @@ -0,0 +1,15 @@ +2007/03/13 +.allow ordinal with negative value + +2007/02/08 +.fixed a bug in the constructor of CDvQuantity + +2007/01/20 +.updated constructors to allow defaultValue and assumedValue + +2006/12/31 +.updated constructors to support parent attribute +.replaced CDvCodedText with CCodePhrase + +2006/12/16 +.updated class CDvCodedText regarding query attribute \ No newline at end of file diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml new file mode 100644 index 00000000..5d1d9027 --- /dev/null +++ b/openehr-ap/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5-SNAPSHOT + + openehr-ap + jar + openEHR Archetype Profile + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2004 + + Java implementation of the openEHR Archetype Profile + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + openehr-aom + ${project.version} + + + openehr + measure-serv + ${project.version} + test + + + commons-lang + commons-lang + 2.6 + + + junit + junit + 3.8.1 + test + + + 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 new file mode 100644 index 00000000..e36af7fd --- /dev/null +++ b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/CDvState.java @@ -0,0 +1,168 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CDvState" + * 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.basic; + +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.datatypes.basic.DvState; +import org.openehr.rm.support.basic.Interval; + +/** + * Constraint type for DV_STATE instances. The attribute c_value defines a + * state/event table which constrains the allowed values of the attribute + * value in a DV_STATE instance, as well as the order of transitions between + * values. + * + * @author Rong Chen + * @version 1.0 + */ +public class CDvState extends CDomainType { + + /** + * Creates a CDvState with path and stateMachine + * + * @param path + * @param value not null + * @throws IllegalArgumentException if value null + */ + public CDvState(String path, Interval occurrences, String nodeId, + CAttribute parent, StateMachine value) { + + super(false, path, "DV_STATE", occurrences, nodeId, parent); + + if(value == null) { + throw new IllegalArgumentException("value null"); + } + this.value = value; + } + + @Override + public CDvState copy() { + return new CDvState(path(), getOccurrences(), getNodeId(), getParent(), + value); + } + + /** + * Equals if two CObject has same values + * + * @param o + * @return true if equals + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof CDvState )) { + return false; + } + + final CDvState cobj = (CDvState) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(value, cobj.value) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + @Override + public int hashCode() { + return new HashCodeBuilder(17, 31) + .appendSuper(super.hashCode()) + .append(value) + .toHashCode(); + } + + /** + * Gets value + * + * @return + */ + public StateMachine getValue() { + return value; + } + + @Override + public CComplexObject standardEquivalent() { + // TODO Auto-generated method stub + return 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; + } + + private StateMachine value; + + @Override + public boolean validValue(DvState arg0) { + // TODO Auto-generated method stub + return false; + } +} +/* + * ***** 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 CDvState.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-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/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 new file mode 100644 index 00000000..690000bb --- /dev/null +++ b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/NonTerminalState.java @@ -0,0 +1,91 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class NonTerminalState" + * 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.basic; + +import java.util.*; + +public class NonTerminalState extends State { + + /** + * Creates a NonTerminalState by name and transitions + * + * @param name not null or empty + * @param transitions not null or empty + * @throws IllegalArgumentException if name null or empty, + * or transitions null or empty + */ + public NonTerminalState(String name, Set transitions) { + super(name); + if(transitions == null || transitions.isEmpty()) { + throw new IllegalArgumentException("transitions null or empty"); + } + this.transitions = new HashSet(transitions); + } + + /** + * Gets transitions of this state + * + * @return an unmodifiable set of transitions + */ + public Set getTransitions() { + return Collections.unmodifiableSet(transitions); + } + + /** + * Adds a transition to this state + * + * @param transition not null + * @throws IllegalArgumentException if transition null + */ + public void addTransition(Transition transition) { + if(transition == null) { + throw new IllegalArgumentException("transition null"); + } + transitions.add(transition); + } + + private Set transitions; +} + +/* + * ***** 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 NonTerminalState.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-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 ***** + */ \ No newline at end of file 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 new file mode 100644 index 00000000..66e73068 --- /dev/null +++ b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/State.java @@ -0,0 +1,113 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class State" + * 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.basic; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +/** + * Abstract definition of one state in a state machine. + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class State { + + /** + * Creates a State by name + * + * @param name not null or empty + * @throws IllegalArgumentException if name null or empty + */ + public State(String name) { + if(StringUtils.isEmpty(name)) { + throw new IllegalArgumentException("name null or empty"); + } + this.name = name; + } + + /** + * Gest name of this state + * + * @return name + */ + public String getName() { + return name; + } + + /** + * Equals if two CObject has same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof State )) return false; + + final State cobj = (State) o; + + return new EqualsBuilder() + .append(name, cobj.name) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(7, 31) + .appendSuper(super.hashCode()) + .append(name) + .toHashCode(); + } + + + private String name; +} + +/* + * ***** 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 State.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-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 ***** + */ \ No newline at end of file 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 new file mode 100644 index 00000000..eb968be8 --- /dev/null +++ b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/StateMachine.java @@ -0,0 +1,117 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class StateMachine" + * 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.basic; + +import java.util.Set; +import java.util.HashSet; +import java.util.Collections; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +/** + * Definition of a state machine in terms of states, transition events and + * outputs, and next states. + * + * @author Rong Chen + * @version 1.0 + */ +public class StateMachine { + + /** + * Creates a StateMachine by a set of states + * + * @param states not null or empty + * @throws IlleglArgumentException if states null or empty + */ + public StateMachine(Set states) { + if(states == null || states.isEmpty()) { + throw new IllegalArgumentException("states null or empty"); + } + this.states = new HashSet(states); + } + + /** + * Gets states of this StateMachine + * + * @return an unmodifiable set of states + */ + public Set getStates() { + return Collections.unmodifiableSet(states); + } + + /** + * Equals if two CObject has same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof StateMachine )) return false; + + final StateMachine cobj = (StateMachine) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(states, cobj.states) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(7, 23) + .append(states) + .toHashCode(); + } + + + private Set states; +} +/* + * ***** 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 StateMachine.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-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/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 new file mode 100644 index 00000000..9fd62b07 --- /dev/null +++ b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/TerminalState.java @@ -0,0 +1,65 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TerminalState" + * 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.basic; + +/** + * Definition of a terminal state in a state machine, i.e. a state with no + * exit transitions. + * + * @author Rong Chen + * @version 1.0 + */ +public class TerminalState extends State { + + /** + * Creates a TerminalState + * + * @param name + */ + public TerminalState(String name) { + super(name); + } +} + +/* + * ***** 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 TerminalState.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-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 ***** + */ \ No newline at end of file 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 new file mode 100644 index 00000000..3ebff486 --- /dev/null +++ b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/basic/Transition.java @@ -0,0 +1,139 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Transition" + * 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.basic; + +import org.apache.commons.lang.StringUtils; + +/** + * Definition of a state machine transition. + * + * @author Rong Chen + * @version 1.0 + */ +public class Transition { + + /** + * Creates a Transition + * + * @param event not null or empty + * @param guard null if unspecified, not empty + * @param action null if unspecified, not empty + * @param nextState not null + * @throws IllegalArgumentException if event null or empty, + * or guard empty, or action emtpy, or nextState null + */ + public Transition(String event, String guard, String action, + State nextState) { + if(StringUtils.isEmpty(event)) { + throw new IllegalArgumentException("event null or empty"); + } + if(guard != null && StringUtils.isEmpty(guard)) { + throw new IllegalArgumentException("guard empty"); + } + if(action != null && StringUtils.isEmpty(action)) { + throw new IllegalArgumentException("action empty"); + } + if(nextState == null) { + throw new IllegalArgumentException("nextState null"); + } + this.event = event; + this.guard = guard; + this.action = action; + this.nextState = nextState; + } + + /** + * Creates a Transition with event and nextState + * + */ + public Transition(String event, State nextState) { + this(event, null, null, nextState); + } + + /** + * Side-effect action to execute during the firing + * of this transition + * + * @return action + */ + public String getAction() { + return action; + } + + /** + * Event which fires this transition + * + * @return event + */ + public String getEvent() { + return event; + } + + /** + * Guard condition which must be true for this + * transition to fire + * + * @return guard + */ + public String getGuard() { + return guard; + } + + /** + * Target state of transition + * + * @return next state + */ + public State getNextState() { + return nextState; + } + + private String event; + private String guard; + private String action; + private State nextState; +} + +/* + * ***** 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 Transition.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-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/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 new file mode 100644 index 00000000..23cca8f7 --- /dev/null +++ b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvOrdinal.java @@ -0,0 +1,187 @@ +/* + * 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.Collections; +import java.util.LinkedHashSet; +import java.util.Set; + +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_ORDINAL. Custom + * constrainer type for instances of DV_ORDINAL. + * + * @author Rong Chen + * @version 1.0 + */ +public class CDvOrdinal extends CDomainType { + + /** + * Creates a CDvOrdinal + * + * @param path + * @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, + 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); + } + + @Override + public CDvOrdinal copy() { + return new CDvOrdinal(path(), getOccurrences(), getNodeId(), getParent(), list, + getDefaultValue(), getAssumedValue()); + } + + /** + * Convenience constructor + * + * @param path + * @param occurrences + * @param nodeID + * @param list + * @throws IllegalArgument if list null or empty + */ + public CDvOrdinal(String path, Interval occurrences, + Set 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 Set getList() { + if (list == null) { + return null; + } + return Collections.unmodifiableSet(list); + } + + /** + * Returns true if fields are the same + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof CDvOrdinal )) { + return false; + } + + final CDvOrdinal ordinal = (CDvOrdinal) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(list, ordinal.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(Ordinal arg0) { + // TODO Auto-generated method stub + return true; + } + + @Override + public CComplexObject standardEquivalent() { + // TODO Auto-generated method stub + return null; + } + + private Set 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 CDvOrdinal.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): 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/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 new file mode 100644 index 00000000..adea374d --- /dev/null +++ b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvQuantity.java @@ -0,0 +1,289 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CDvQuantity" + * 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.*; + +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.datatypes.quantity.DvQuantity; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.basic.Interval; + +/** + * This class represents constrain instances of DV_QUANTITY. + * + * @author Rong Chen + * @version 1.0 + */ +public class CDvQuantity extends CDomainType { + + /** + * Constructor + * + * @param path + * @param list + * null if unspecified + * @param property + * null if unspecified, no empty + * @throws IllegalArgumentException if list is empty + */ + public CDvQuantity(String path, Interval occurrences, + String nodeId, CAttribute parent, List list, + CodePhrase property, DvQuantity defaultValue, + DvQuantity assumedValue) { + + super(list == null && property == null, path, "DV_QUANTITY", + occurrences, nodeId, defaultValue, assumedValue, parent); + + if (list != null && list.isEmpty()) { + throw new IllegalArgumentException("empty list"); + } + this.list = list == null ? list + : new ArrayList(list); + this.property = property; + } + + public CDvQuantity copy() { + return new CDvQuantity(path(), getOccurrences(), getNodeId(), + getParent(), list, property, getDefaultValue(), + getAssumedValue()); + } + + /** + * Convenience constructor + * + * @param path + * @param occurrences + * @param list + */ + public CDvQuantity(String path, Interval occurrences, + List list) { + this(path, occurrences, null, null, list, null, null, null); + } + + /** + * Convenience constructor + * + * @param path + * @param occurrences + * @param list + * @param property + */ + public CDvQuantity(String path, Interval occurrences, + List list, CodePhrase property) { + this(path, occurrences, null, null, list, property, null, null); + } + + /** + * Create a required CDvQuantity with a single item + * + * @param path + * @param item not null + */ + public static CDvQuantity singleRequired(String path, CDvQuantityItem item) { + if(item == null) { + throw new IllegalArgumentException("item null"); + } + Interval occurrences = new Interval(1,1); + List list = new ArrayList(); + list.add(item); + return new CDvQuantity(path, occurrences, list); + } + + /** + * Create a CDvQuantity that would allow any DV_QUANTITY value + * @param path + * @return + */ + public static CDvQuantity anyAllowed(String path) { + Interval occurrences = new Interval(1,1); + return new CDvQuantity(path, occurrences, null); + } + + /** + * List of value/units pairs. + * + * @return + */ + public List getList() { + return list == null ? null + : Collections.unmodifiableList(list); + } + + /** + * Removes the given item from the list + * + * @param item not null + */ + public void removeItem(CDvQuantityItem item) { + if(list != null && item != null) { + list.remove(item); + } + } + + /** + * Removes the items that have the given units + * + * @param item not null + */ + public void removeItemByUnitsList(String[] unitsList) { + if(list == null || unitsList == null) { + return; + } + for(Iterator it = list.iterator(); it.hasNext(); ) { + CDvQuantityItem item = it.next(); + for(String units : unitsList) { + if(units.equals(item.getUnits())) { + it.remove(); + break; + } + } + } + } + + /** + * Adds a c_dv_quantity_item by given units + * + * @param units + */ + public void addItem(CDvQuantityItem item) { + if(list == null) { + list = new ArrayList(); + } + list.add(item); + } + + + /** + * Optional constraint on units property + * + * @return + */ + public CodePhrase getProperty() { + return property; + } + + /** + * Returns true if fields are the same + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof CDvQuantity )) return false; + + final CDvQuantity cq = (CDvQuantity) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(list, cq.list) + .append(property, cq.property) + .isEquals(); + } + + /** + * Returns the hashcode of this object + * + * @return hashcode + */ + public int hashCode() { + return new HashCodeBuilder(11, 37) + .appendSuper(super.hashCode()) + .append(list) + .append(property) + .toHashCode(); + } + + @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; + } + + @Override + public boolean isValid() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean validValue(DvQuantity value) { + if(list == null) { + return true; + } + for(CDvQuantityItem item : list) { + if( ! item.getUnits().equals(value.getUnits())) { + continue; + } + if(item.getMagnitude() != null + && !item.getMagnitude().has(value.getMagnitude())) { + continue; + } + + // TODO precision check + return true; + } + return false; + } + + @Override + public CComplexObject standardEquivalent() { + // TODO Auto-generated method stub + return null; + } + + /* fields */ + private List list; + private CodePhrase property; +} +/* + * ***** 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 CDvQuantity.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-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 ***** + */ \ No newline at end of file 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 new file mode 100644 index 00000000..9cb967b1 --- /dev/null +++ b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvQuantityItem.java @@ -0,0 +1,169 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CDvQuantityItem" + * 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.io.Serializable; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.openehr.rm.support.basic.Interval; + +/** + * Constrain instances of DV_QUANTITY. + * + * @author Rong Chen + */ +public class CDvQuantityItem implements Serializable{ + + /** + * Constructor + * + * @param magnitude + * @param units not null or empty + * @throws IllegalArgumentException if units null or empty + */ + public CDvQuantityItem(Interval magnitude, String units) { + this(magnitude, null, units); + } + + /** + * Constructor using only units + * + * @param units not null or empty + * @throws IllegalArgumentException if units null or empty + */ + public CDvQuantityItem(String units) { + this(null, null, units); + } + + /** + * Constructor + * + * @param magnitude + * @param precision null if unspecified + * @param units not null or empty + * @throws IllegalArgumentException if units null or empty + */ + public CDvQuantityItem(Interval magnitude, Interval precision, + String units) { + if(StringUtils.isEmpty(units)) { + throw new IllegalArgumentException("units null or empty"); + } + this.magnitude = magnitude; + this.precision = precision; + this.units = units; + } + + /** + * Constraint on units + * + * @return units + */ + public String getUnits() { + return units; + } + + /** + * Magnitude must be inside the supplied interval. + * + * @return magnitude interval + */ + public Interval getMagnitude() { + return magnitude; + } + + /** + * Gets precision of this item + * + * @return null if unspecified + */ + public Interval getPrecision() { + return precision; + } + + /** + * Returns true if fields are the same + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof CDvQuantityItem )) return false; + + final CDvQuantityItem item = (CDvQuantityItem) o; + + return new EqualsBuilder() + .append(magnitude, item.magnitude) + .append(precision, item.precision) + .append(units, item.units) + .isEquals(); + } + + /** + * Returns hashcode + */ + public int hashCode() { + return new HashCodeBuilder(7, 23) + .append(magnitude) + .append(precision) + .append(units) + .toHashCode(); + } + + public String toString() { + return new ToStringBuilder(this). + append("magnitude", magnitude). + append("precision", precision). + append("units", units). + toString(); + + } + + /* fields */ + private Interval magnitude; + private Interval precision; + private String units; +} + +/* + * ***** 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 CDvQuantity.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-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 new file mode 100644 index 00000000..02288d16 --- /dev/null +++ b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/Ordinal.java @@ -0,0 +1,146 @@ +/* + * 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; + +/** + * Ordinal item included in the list of ordinal constraint. Immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class Ordinal implements Comparable, Serializable { + + /** + * Constructs an ordinal + * + * @param value no less than 0 + * @param symbol not null + * @throws IllegalArgumentException if symbol null + */ + public Ordinal(int value, CodePhrase symbol) { + if(symbol == null) { + throw new IllegalArgumentException("symbo null"); + } + this.value = value; + this.symbol = symbol; + } + + /** + * The integer value of this ordinal + * + * @return no less than 0 + */ + public int getValue() { + return value; + } + + /** + * The symbol of this ordinal + * + * @return symbol + */ + public CodePhrase getSymbol() { + return symbol; + } + + /** + * Return string presentation of this ordinal + * + * @return string form + */ + public String toString() { + return "[" + symbol.getTerminologyId() + "] " + value + + "|" + symbol.getCodeString(); + } + + /** + * Returns true if fields are the same + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof Ordinal )) return false; + + final Ordinal ordinal = (Ordinal) o; + + return new EqualsBuilder() + .append(value, ordinal.value) + .append(symbol, ordinal.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 Ordinal ordinal = (Ordinal) o; + if (value > ordinal.value) return 1; + if (value < ordinal.value) return -1; + return 0; + } + + public int hashCode() { + return new HashCodeBuilder(7, 17) + .append(value) + .append(symbol) + .toHashCode(); + } + + /* fields */ + private final int value; + 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 new file mode 100644 index 00000000..755017f6 --- /dev/null +++ b/openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/text/CCodePhrase.java @@ -0,0 +1,237 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CDvCodedText" + * 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.text; + +import java.util.ArrayList; +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.datatypes.text.CodePhrase; +import org.openehr.rm.support.basic.Interval; +import org.openehr.rm.support.identification.TerminologyID; + +/** + * Express constraints on instances of DV_CODED_TEXT. + * + * @author Rong Chen + * + */ +public class CCodePhrase extends CDomainType { + + /** + * Creates a CDvCodedText + * + * @param path + * @param rmTypeName + * @param occurrences + * @param nodeID + * @param parent + * @param terminologyId + * null if unspecified + * @param codeList + * null if unspecified + * @throws IllegalArgumentException + */ + public CCodePhrase(String path, Interval occurrences, + String nodeID, CAttribute parent, TerminologyID terminologyId, + List codeList, CodePhrase defaultValue, + CodePhrase assumedValue) { + + super(terminologyId == null && codeList == null, + path, CODE_PHRASE, occurrences, nodeID, defaultValue, + assumedValue, parent); + + if (codeList != null) { + if(codeList.isEmpty()) { + throw new IllegalArgumentException("codeList empty"); + } + if (terminologyId == null) { + throw new IllegalArgumentException("terminologyId null"); + } + } + + this.terminologyId = terminologyId; + this.codeList = codeList; + } + + /** + * Creates a single required CCodePhrase with terminologyId and codeList + * + * @param path + * @param terminologyId + * @param codeList + * @return + */ + public static CCodePhrase singleRequired(String path, String terminologyId, + List codeList) { + Interval occurrences = new Interval(1,1); + TerminologyID tid = new TerminologyID(terminologyId); + return new CCodePhrase(path, occurrences, null, + null, tid, codeList, null, null); + } + + public CCodePhrase copy() { + return new CCodePhrase(path(), getOccurrences(), getNodeId(), + getParent(), terminologyId, codeList, getDefaultValue(), + getAssumedValue()); + } + + /** + * Convenience constructor to create CCodePhrase with only terminologyId + * and single code + * + * @param path + * @param terminologyId + * @param code + */ + public CCodePhrase(String path, String terminologyId, String code) { + + super(false, path, CODE_PHRASE, new Interval(0, 1), null, null, + null, null); + + ArrayList codeList = new ArrayList(); + codeList.add(code); + + this.codeList = codeList; + this.terminologyId = new TerminologyID(terminologyId); + } + + /** + * List of codes + * + * @return null if unspecified + */ + public List getCodeList() { + return codeList; + } + + /** + * Syntax string expressing constraint on allowed primary terms + * + * @return null if unspecified + */ + public TerminologyID getTerminologyId() { + return terminologyId; + } + + /** + * Two CCodePhrase equal if have same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof CCodePhrase )) return false; + + final CCodePhrase ccp = (CCodePhrase) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(terminologyId, ccp.terminologyId) + .append(codeList, ccp.codeList) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(7, 37) + .appendSuper(super.hashCode()) + .append(terminologyId) + .append(codeList) + .toHashCode(); + } + + @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; + } + + @Override + public boolean validValue(CodePhrase value) { + if(value == null) { + return false; + } + if(terminologyId != null + && !terminologyId.equals(value.getTerminologyId())) { + return false; + } + if(codeList != null && !codeList.contains(value.getCodeString())) { + return false; + } + + return true; + } + + @Override + public CComplexObject standardEquivalent() { + // TODO Auto-generated method stub + return null; + } + + private static final String CODE_PHRASE = "CODE_PHRASE"; + + private TerminologyID terminologyId; + private List codeList; +} + +/* + * ***** 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 CCodePhrase.java + * + * The Initial Developer of the Original Code is Rong Chen. Portions created by + * the Initial Developer are Copyright (C) 2003-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 ***** + */ \ No newline at end of file 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 new file mode 100644 index 00000000..3ff2ef81 --- /dev/null +++ b/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/basic/CDvStateTest.java @@ -0,0 +1,61 @@ +package org.openehr.am.openehrprofile.datatypes.basic; + +import java.util.*; + +import junit.framework.TestCase; + +/** + * Testcase for CDvState + * + * @author Rong Chen + */ +public class CDvStateTest extends TestCase { + + /** + * Test to create a medication order state machine, from p11 of AOP doc + */ + public void testCreateMedicationOrderStateMachine() { + TerminalState completed = new TerminalState("COMPLETED"); + Transition finish = new Transition("finish", null, null, completed); + Set transitions = new HashSet(); + transitions.add(finish); + NonTerminalState inExecution = + new NonTerminalState("IN_EXECUTION", transitions); + Transition restart = new Transition("restart", inExecution); + transitions.clear(); + transitions.add(restart); + NonTerminalState suspended = new NonTerminalState("SUSPENDED", transitions); + Transition suspend = new Transition("suspend", suspended); + inExecution.addTransition(suspend); + + Transition start = new Transition("start", inExecution); + transitions.clear(); + transitions.add(start); + NonTerminalState proposed = new NonTerminalState("PROPOSED", transitions); + NonTerminalState ordered = new NonTerminalState("ORDERED", transitions); + NonTerminalState overdue = new NonTerminalState("OVERDUE", transitions); + + Transition order = new Transition("order", ordered); + Transition startFail = new Transition("start fail", overdue); + proposed.addTransition(order); + ordered.addTransition(startFail); + + TerminalState cancelled = new TerminalState("CANCELLED"); + Transition cancel = new Transition("cancel", cancelled); + proposed.addTransition(cancel); + ordered.addTransition(cancel); + overdue.addTransition(cancel); + + // verify the statemachine + assertEquals("number of transitions of PROPOSED", 3, + proposed.getTransitions().size()); + assertEquals("number of transitions of ORDERED", 3, + ordered.getTransitions().size()); + assertEquals("number of transitions of OVERDUE", 2, + overdue.getTransitions().size()); + assertEquals("number of transitions of IN_EXECUTE", 2, + inExecution.getTransitions().size()); + assertEquals("number of transitions of SUSPEND", 1, + suspended.getTransitions().size()); + } +} 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 new file mode 100644 index 00000000..8e797e54 --- /dev/null +++ b/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvOrdinalTest.java @@ -0,0 +1,75 @@ +package org.openehr.am.openehrprofile.datatypes.quantity; + +import java.util.*; + +import org.openehr.am.archetype.constraintmodel.CAttribute; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.basic.Interval; + +import junit.framework.TestCase; + +public class CDvOrdinalTest extends TestCase { + + public void testCreateEmptyCDvOrdinal() { + String path = "/term_definitions[en]/items[at0001]/text/"; + Interval occurrences = new Interval(1,1); + String nodeId = "at0010"; + CAttribute parent = null; + Set list = null; + + CDvOrdinal c = new CDvOrdinal(path, occurrences, nodeId, parent, list, + null, null); + assertTrue("anyAllowed expected", c.isAnyAllowed()); + assertNull("null list expected", c.getList()); + } + + public void testCreateCDvOrdinalWithAssumedValue() { + String path = "/term_definitions[en]/items[at0001]/text/"; + Interval occurrences = new Interval(1,1); + String nodeId = "at0010"; + CAttribute parent = null; + Ordinal assumed = new Ordinal(1, new CodePhrase("local", "at0001")); + + CDvOrdinal c = new CDvOrdinal(path, occurrences, nodeId, parent, null, + null, assumed); + assertEquals("assumed wrong", assumed, c.getAssumedValue()); + } + + public void testEqualsWithDifferentOrdinal() { + Interval occurrences = new Interval(1,1); + Set set1 = new HashSet(); + Ordinal ord1 = new Ordinal(1, new CodePhrase("local", "at0001")); + set1.add(ord1); + + Set set2 = new HashSet(); + Ordinal ord2 = new Ordinal(1, new CodePhrase("local", "at0003")); + set2.add(ord2); + + CDvOrdinal cdo1 = new CDvOrdinal("/path", occurrences, set1); + CDvOrdinal cdo2 = new CDvOrdinal("/path", occurrences, set2); + + assertFalse("CDvOrdinal with different ordinal should not equal", + cdo1.equals(cdo2)); + assertFalse("CDvOrdinal with different ordinal should not equal", + cdo2.equals(cdo1)); + } + + public void testEqualsWithSameOrdinal() { + Interval occurrences = new Interval(1,1); + Set set1 = new HashSet(); + Ordinal ord1 = new Ordinal(1, new CodePhrase("local", "at0001")); + set1.add(ord1); + + Set set2 = new HashSet(); + Ordinal ord2 = new Ordinal(1, new CodePhrase("local", "at0001")); + set2.add(ord2); + + CDvOrdinal cdo1 = new CDvOrdinal("/path", occurrences, set1); + CDvOrdinal cdo2 = new CDvOrdinal("/path", occurrences, set2); + + assertTrue("CDvOrdinal with the same ordinal should equal", + cdo1.equals(cdo2)); + assertTrue("CDvOrdinal with different ordinal should equal", + cdo2.equals(cdo1)); + } +} 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 new file mode 100644 index 00000000..1e6d5c38 --- /dev/null +++ b/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvQuantityItemTest.java @@ -0,0 +1,26 @@ +package org.openehr.am.openehrprofile.datatypes.quantity; + + +import org.openehr.rm.support.basic.Interval; + +import junit.framework.TestCase; + +/** + * Testcase for CDvQuantityItem + * + * @author Rong Chen + * + */ +public class CDvQuantityItemTest extends TestCase { + + public void testCreateCDvQuantityItem() { + Interval value = new Interval(20.0, 160.0); + Interval precision = new Interval(0, null); + String units = "Kg"; + CDvQuantityItem item = new CDvQuantityItem(value, precision, units); + + assertEquals("magnitude wrong", value, item.getMagnitude()); + assertEquals("precision wrong", precision, item.getPrecision()); + assertEquals("units wrong", units, item.getUnits()); + } +} 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 new file mode 100644 index 00000000..60a8dceb --- /dev/null +++ b/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvQuantityTest.java @@ -0,0 +1,152 @@ +package org.openehr.am.openehrprofile.datatypes.quantity; + +import java.util.*; + +import org.openehr.am.archetype.constraintmodel.CAttribute; +import org.openehr.rm.support.basic.Interval; +import org.openehr.rm.datatypes.quantity.DvQuantity; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.measurement.*; + +import junit.framework.TestCase; + +public class CDvQuantityTest extends TestCase { + + public void testCreateEmptyCDvQuantity() { + String path = "/term_definitions[en]/items[at0001]/text/"; + Interval occurrences = new Interval(1,1); + String nodeId = "at0010"; + CAttribute parent = null; + List list = null; + CodePhrase property = null; + + CDvQuantity constraint = new CDvQuantity(path, occurrences, nodeId, + parent, list, property, null, null); + assertTrue("anyAllowed expected", constraint.isAnyAllowed()); + } + + public void testCreateAnyAllowed() { + CDvQuantity dq = CDvQuantity.anyAllowed("/at0001"); + assertNotNull("failed to create anyAllowed"); + } + + public void testCreateWithAssumedValue() { + String path = "/term_definitions[en]/items[at0001]/text/"; + Interval occurrences = new Interval(1,1); + String nodeId = "at0010"; + CAttribute parent = null; + List list = null; + CodePhrase property = null; + MeasurementService ms = SimpleMeasurementService.getInstance(); + DvQuantity assumed = new DvQuantity("kg", 90.0, ms); + + CDvQuantity constraint = new CDvQuantity(path, occurrences, nodeId, + parent, list, property, null, assumed); + assertEquals("assumed wrong", assumed, constraint.getAssumedValue()); + } + + public void testCreateWithDefaultValue() { + String path = "/term_definitions[en]/items[at0001]/text/"; + Interval occurrences = new Interval(1,1); + String nodeId = "at0010"; + CAttribute parent = null; + List list = null; + CodePhrase property = null; + MeasurementService ms = SimpleMeasurementService.getInstance(); + DvQuantity defaultValue = new DvQuantity("kg", 90.0, ms); + + CDvQuantity constraint = new CDvQuantity(path, occurrences, nodeId, + parent, list, property, defaultValue, null); + assertEquals("default wrong", defaultValue, constraint.getDefaultValue()); + } + + public void testEqualsWithDifferentQuantityItems() { + Interval required = new Interval(1,1); + CDvQuantityItem item1 = new CDvQuantityItem( + new Interval(0.0, 1.0), + new Interval(2, 2), "mg"); + List list1 = new ArrayList(); + list1.add(item1); + CDvQuantity cq1 = new CDvQuantity("/path", required, list1, null); + + CDvQuantityItem item2 = new CDvQuantityItem( + new Interval(0.0, 2.0), + new Interval(2, 2), "mg"); + List list2 = new ArrayList(); + list2.add(item2); + CDvQuantity cq2 = new CDvQuantity("/path", required, list2, null); + + assertFalse("CDvQuantity with different items should not equal", + cq1.equals(cq2)); + assertFalse("CDvQuantity with different items should not equal", + cq2.equals(cq1)); + } + + public void testEqualsWithSameQuantityItems() { + Interval required = new Interval(1,1); + CDvQuantityItem item1 = new CDvQuantityItem( + new Interval(0.0, 1.0), + new Interval(2, 2), "mg"); + List list1 = new ArrayList(); + list1.add(item1); + CDvQuantity cq1 = new CDvQuantity("/path", required, list1, null); + + CDvQuantityItem item2 = new CDvQuantityItem( + new Interval(0.0, 1.0), + new Interval(2, 2), "mg"); + List list2 = new ArrayList(); + list2.add(item2); + CDvQuantity cq2 = new CDvQuantity("/path", required, list2, null); + + assertTrue("CDvQuantity with the same quantity items should equal", + cq1.equals(cq2)); + assertTrue("CDvQuantity with the same quantity items should equal", + cq2.equals(cq1)); + } + + public void testValidValueExpected() throws Exception { + Interval required = new Interval(1,1); + CDvQuantityItem item1 = new CDvQuantityItem( + new Interval(0.0, 1.0), + new Interval(2, 2), "mg"); + List list1 = new ArrayList(); + list1.add(item1); + CDvQuantity cdq = new CDvQuantity("/path", required, list1, null); + + DvQuantity dq = new DvQuantity("mg", 0.9, measureService); + + assertTrue("expected valid value expected", cdq.validValue(dq)); + } + + public void testValidValueValueOutOfRange() throws Exception { + Interval required = new Interval(1,1); + CDvQuantityItem item1 = new CDvQuantityItem( + new Interval(0.0, 1.0), + new Interval(2, 2), "mg"); + List list1 = new ArrayList(); + list1.add(item1); + CDvQuantity cdq = new CDvQuantity("/path", required, list1, null); + + DvQuantity dq = new DvQuantity("mg", 1.5, measureService); + + assertFalse("expected value out of range", cdq.validValue(dq)); + + + } + + public void testValidValueValueWrongUnits() throws Exception { + Interval required = new Interval(1,1); + CDvQuantityItem item1 = new CDvQuantityItem( + new Interval(0.0, 1.0), + new Interval(2, 2), "mg"); + List list1 = new ArrayList(); + list1.add(item1); + CDvQuantity cdq = new CDvQuantity("/path", required, list1, null); + + DvQuantity dq = new DvQuantity("kg", 0.9, measureService); + + assertFalse("expected invalid units", cdq.validValue(dq)); + } + + private MeasurementService measureService = SimpleMeasurementService.getInstance(); +} 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 new file mode 100644 index 00000000..555d18b8 --- /dev/null +++ b/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/OrdinalTest.java @@ -0,0 +1,22 @@ +package org.openehr.am.openehrprofile.datatypes.quantity; + +import org.openehr.rm.datatypes.text.CodePhrase; + +import junit.framework.TestCase; + +public class OrdinalTest extends TestCase { + public void testEquals() { + Ordinal o1 = new Ordinal(1, new CodePhrase("local", "at0001")); + Ordinal o2 = new Ordinal(1, new CodePhrase("local", "at0001")); + assertTrue("equals expected", o1.equals(o2)); + assertTrue("equals expected", o2.equals(o1)); + } + + public void testCreateOrdinalWithNegativeValue() { + try { + new Ordinal(-1, new CodePhrase("local", "at0001")); + } catch(Exception e) { + fail("failed to create ordinal with negative value"); + } + } +} 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 new file mode 100644 index 00000000..a7324374 --- /dev/null +++ b/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/text/CCodePhraseTest.java @@ -0,0 +1,114 @@ +package org.openehr.am.openehrprofile.datatypes.text; + +import java.util.*; + +import org.openehr.am.archetype.constraintmodel.CAttribute; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.basic.Interval; +import org.openehr.rm.support.identification.TerminologyID; + +import junit.framework.TestCase; + +/** + * Simple testcase for CDvCodedText + * + * @author Rong.Chen + */ +public class CCodePhraseTest extends TestCase { + + public void testCreateEmptyCCodePhrase() { + String path = "/term_definitions[en]/items[at0001]/text/"; + Interval occurrences = new Interval(1,1); + String nodeId = "at0010"; + CAttribute parent = null; + TerminologyID terminologyId = null; + List codeList = null; + CCodePhrase constraint = new CCodePhrase(path, occurrences, nodeId, + parent, terminologyId, codeList, null, null); + assertTrue("anyAllowed expected", constraint.isAnyAllowed()); + } + + public void testCreateCCodePhraseWithCodeList() { + String path = "/term_definitions[en]/items[at0001]/text/"; + Interval occurrences = new Interval(0, 1); + String nodeId = "at0010"; + TerminologyID terminologyId = new TerminologyID("openehr"); + List codeList = new ArrayList(); + codeList.add("mean"); + codeList.add("total"); + + CCodePhrase constraint = new CCodePhrase(path, occurrences, + nodeId, null, terminologyId, codeList, null, null); + + assertNotNull(constraint); + assertFalse("anyAllowed unexpected", constraint.isAnyAllowed()); + assertEquals("codeList wrong", codeList, constraint.getCodeList()); + } + + public void testValidValue() { + String path = "/term_definitions[en]/items[at0001]/text/"; + Interval occurrences = new Interval(0, 1); + String nodeId = "at0010"; + TerminologyID terminologyId = new TerminologyID("test"); + List codeList = new ArrayList(); + codeList.add("100"); + codeList.add("101"); + + CCodePhrase constraint = new CCodePhrase(path, occurrences, + nodeId, null, terminologyId, codeList, null, null); + + assertFalse("expected invalid - both wrong", + constraint.validValue(new CodePhrase("test2", "102"))); + assertFalse("expected invalid - wrong code", + constraint.validValue(new CodePhrase("test", "102"))); + assertFalse("expected invalid - wrong terminology", + constraint.validValue(new CodePhrase("test2", "100"))); + assertFalse("expected invalid - null value", + constraint.validValue(null)); + + assertTrue("expected valid", + constraint.validValue(new CodePhrase("test", "100"))); + assertTrue("expected valid", + constraint.validValue(new CodePhrase("test", "101"))); + } + + + public void testEqualsWithDifferentCode() { + CCodePhrase planned = new CCodePhrase("/defining_code", "openehr", + "524"); + CCodePhrase postponed = new CCodePhrase("/defining_code", "openehr", + "527"); + + assertFalse("two CCodePhrase with different code should not be equal", + planned.equals(postponed)); + + assertFalse("two CCodePhrase with different code should not be equal", + postponed.equals(planned)); + } + + public void testEqualsWithDifferentTerminology() { + CCodePhrase planned = new CCodePhrase("/defining_code", "openehr", + "524"); + CCodePhrase postponed = new CCodePhrase("/defining_code", "another", + "524"); + + assertFalse("two CCodePhrase with different terminology should not be equal", + planned.equals(postponed)); + + assertFalse("two CCodePhrase with different terminology should not be equal", + postponed.equals(planned)); + } + + public void testEqualsWithSameCodeAndTerminology() { + CCodePhrase planned = new CCodePhrase("/defining_code", "openehr", + "527"); + CCodePhrase postponed = new CCodePhrase("/defining_code", "openehr", + "527"); + + assertTrue("two CCodePhrase with same terminology and code should be equal", + planned.equals(postponed)); + + assertTrue("two CCodePhrase with same terminology and code should be equal", + postponed.equals(planned)); + } +} diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml new file mode 100644 index 00000000..50bba5b4 --- /dev/null +++ b/openehr-rm-core/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5-SNAPSHOT + + openehr-rm-core + jar + openEHR Reference Model Core + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2004 + + Java implementation of the openEHR Reference Model Core + + + + commons-lang + commons-lang + 2.6 + + + joda-time + joda-time + 2.2 + + + junit + junit + 3.8.1 + test + + + openehr + 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 new file mode 100644 index 00000000..88c24853 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/Attribute.java @@ -0,0 +1,65 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Attribute" + * keywords: "reference model" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/Attribute.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Attribute annotations + * + * @author Rong Chen + * @version 1.0 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.PARAMETER) +public @interface Attribute { + String name(); + boolean required() default false; + boolean system() default false; +} + +/* + * ***** 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 Attribute.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 ***** + */ + 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 new file mode 100644 index 00000000..d5259d3c --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/FullConstructor.java @@ -0,0 +1,63 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class FullConstructor" + * keywords: "reference model" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/FullConstructor.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * FullConstructor indicates that a constructor can take all attribute both + * required and optional to initialise the objet + * + * @author Rong Chen + * @version 1.0 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.CONSTRUCTOR) +public @interface FullConstructor { +} + +/* + * ***** 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 FullConstructor.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 ***** + */ + 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 new file mode 100644 index 00000000..23700ebc --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/RMObject.java @@ -0,0 +1,55 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class RMObject" + * keywords: "reference model" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/RMObject.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm; + +/** + * Root class of all reference model classes + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class RMObject implements java.io.Serializable { + private static final long serialVersionUID = 1L; +} + +/* + * ***** 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 RMObject.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/archetyped/Archetyped.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Archetyped.java new file mode 100644 index 00000000..3dc50978 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Archetyped.java @@ -0,0 +1,200 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Archetyped" + * 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/archetyped/Archetyped.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.common.archetyped; + +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; +import org.openehr.rm.RMObject; +import org.openehr.rm.support.identification.ArchetypeID; +import org.openehr.rm.support.identification.TemplateID; + +/** + * Archetypes act as the configuration basis for the particular + * structures of instances defined by the reference model. To enable + * archetypes to be used to create valid data, key classes in the + * reference model act as "root" points for archetyping; accordingly, + * these classes have the archetype_details attribute set. + * An instance of the class Archetyped contains the + * relevant archetype identification information, allowing generating + * archetypes to be matched up with data instances. + *

+ * Instances of this class are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class Archetyped extends RMObject { + + /** + * Creates an Archetyped + * + * @param archetypeId not null + * @param templateId null if unspecified + * @param rmVersion not null or empty + * + * @throws IllegalArgumentException if archetypeId null + * or rmVersion empty + */ + @FullConstructor + public Archetyped( + @Attribute(name = "archetypeId", required = true) ArchetypeID archetypeId, + @Attribute(name = "templateId") TemplateID templateId, + @Attribute(name = "rmVersion", required = true) String rmVersion) { + if (archetypeId == null) { + throw new IllegalArgumentException("null archetypeId"); + } + if (StringUtils.isEmpty(rmVersion)) { + throw new IllegalArgumentException("empty rmVersion"); + } + this.archetypeId = archetypeId; + this.templateId = templateId; + this.rmVersion = rmVersion; + } + + /** + * Creates an Archetyped without a templateId + * + * @param archetypeId + * @param rmVersion + * @throws IllegalArgumentException if archetypeId null + * or rmVersion empty + */ + public Archetyped(ArchetypeID archetypeId, String rmVersion) { + this(archetypeId, null, rmVersion); + } + + /** + * Creates an Archetyped without a templateId + * + * @param archetypeId + * @param rmVersion + * @throws IllegalArgumentException if archetypeId null + * or rmVersion empty + */ + public Archetyped(String archetypeId, String rmVersion) { + this(new ArchetypeID(archetypeId), null, rmVersion); + } + + /** + * Globally unique archetype identifier + * + * @return archetypeId + */ + public ArchetypeID getArchetypeId() { + return archetypeId; + } + + /** + * Globally unique template identifier + * + * @return templateId or null if not specified + */ + public TemplateID getTemplateId() { + return templateId; + } + + /** + * Version of the openEHR reference model used to create this + * object + * + * @return rmVersion + */ + public String getRmVersion() { + return rmVersion; + } + + /** + * Equals if have same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof Archetyped )) return false; + + final Archetyped archetyped = (Archetyped) o; + + return new EqualsBuilder() + .append(archetypeId, archetyped.archetypeId) + .append(templateId, archetyped.templateId) + .append(rmVersion, archetyped.rmVersion) + .isEquals(); + } + + /** + * Hashcode of this object + * + * @return hashcode + */ + public int hashCode() { + return new HashCodeBuilder(7,19) + .append(archetypeId) + .append(templateId) + .append(rmVersion) + .toHashCode(); + } + + // POJO start + Archetyped() { + } + + void setArchetypeId(ArchetypeID archetypeID) { + this.archetypeId = archetypeID; + } + + void setRmVersion(String rmVersion) { + this.rmVersion = rmVersion; + } + // POJO end + + /* fields */ + private ArchetypeID archetypeId; + private TemplateID templateId; + private String rmVersion; +} + +/* + * ***** 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 Archetyped.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2007 + * 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/archetyped/FeederAudit.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/FeederAudit.java new file mode 100644 index 00000000..939ad9e0 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/FeederAudit.java @@ -0,0 +1,210 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class FeederAudit" + * 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/archetyped/FeederAudit.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2006-03-09 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.common.archetyped; + +import java.util.List; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.RMObject; +import org.openehr.rm.datatypes.basic.DvIdentifier; +import org.openehr.rm.datatypes.encapsulated.DvEncapsulated; + +/** + * Audit and other meta-data for systems in the feeder chain. Instances of this class are + * immutable + * + * @author Yin Su Lim + * @version 1.0 + */ +public final class FeederAudit extends RMObject { + + /** + * Constrcuts a FeederAuditDetails + * + * @param originatingSystemAudit not null + * @param originatingSystemItemIds null if not specified + * @param feederSystemAudit null if not specified + * @param feederSystemItemIds null if not specified + * @param originalContent null if not specified + * + * @throws IllegalArgumentException if originatingSystemAudit null, + * originatingSystemItemIds or feederSystemItemIds empty + */ + public FeederAudit(FeederAuditDetails originatingSystemAudit, + List originatingSystemItemIDs, + FeederAuditDetails feederSystemAudit, + List feederSystemItemIDs, + DvEncapsulated originalContent) { + if (originatingSystemAudit == null) { + throw new IllegalArgumentException("null originatingSystemAudit"); + } + if (originatingSystemItemIDs != null && originatingSystemItemIDs.size() == 0) { + throw new IllegalArgumentException("empty originatingSystemItemIds"); + } + if (feederSystemItemIDs != null && feederSystemItemIDs.size() == 0) { + throw new IllegalArgumentException("empty feederSystemItemIds"); + } + this.originatingSystemAudit = originatingSystemAudit; + this.originatingSystemItemIds = originatingSystemItemIDs; + this.feederSystemAudit = feederSystemAudit; + this.feederSystemItemIds = feederSystemItemIDs; + this.originalContent = originalContent; + } + + /** + * Audit information for the information item from the originating system + * + * @return originatingSystemAudit + */ + public FeederAuditDetails getOriginatingSystemAudit() { + return originatingSystemAudit; + } + + /** + * Identifiers used for the item in the originating system + * + * @return originatingSystemItemIds or null if not specified + */ + public List getOriginatingSystemItemIds() { + return originatingSystemItemIds; + } + + /** + * Audit information for the information item from the feeder system, + * if different from the originating system + * + * @return feederSystemAudit or null if not specified + */ + public FeederAuditDetails getFeederSystemAudit() { + return feederSystemAudit; + } + + /** + * Identifiers used for the item in the feeder system, where the feeder + * system is distinct from the originating system + * + * @return feederSystemItemIds or null if not specified + */ + public List getFeederSystemItemIds() { + return feederSystemItemIds; + } + + /** + * Optional inline inclusion of or reference to original content + * corresponding to the openEHR content at this node. Typically a URI + * reference to a document or message in a persistent store associated + * with the EHR. + * + * @return originalContent or null if not specified + */ + public DvEncapsulated getOriginalContent() { + return originalContent; + } + + /** + * Equals if have same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof FeederAudit )) return false; + + final FeederAudit fa = (FeederAudit) o; + + return new EqualsBuilder() + .append(originatingSystemAudit, fa.originatingSystemAudit) + .append(originatingSystemItemIds, fa.originatingSystemItemIds) + .append(feederSystemAudit, fa.feederSystemAudit) + .append(feederSystemItemIds, fa.feederSystemItemIds) + .append(originalContent, fa.originalContent) + .isEquals(); + } + + /** + * Hashcode of this object + * + * @return hashcode + */ + public int hashCode() { + return new HashCodeBuilder(7,19) + .append(originatingSystemAudit) + .append(originatingSystemItemIds) + .append(feederSystemAudit) + .append(feederSystemItemIds) + .append(originalContent) + .toHashCode(); + } + + // POJO start + FeederAudit() { + } + + void setOriginatingSystemAudit(FeederAuditDetails originatingSystemAudit) { + this.originatingSystemAudit = originatingSystemAudit; + } + + void setOriginatingSystemItemIds(List originatingSystemItemIDs) { + this.originatingSystemItemIds = originatingSystemItemIDs; + } + + void setFeederSystemAudit(FeederAuditDetails feederSystemAudit) { + this.feederSystemAudit = feederSystemAudit; + } + + void setFeederSystemItemIds(List feederSystemItemIDs) { + this.feederSystemItemIds = feederSystemItemIDs; + } + + // POJO end + + /* fields */ + private FeederAuditDetails originatingSystemAudit; + private List originatingSystemItemIds; + private FeederAuditDetails feederSystemAudit; + private List feederSystemItemIds; + private DvEncapsulated originalContent; +} +/* + * ***** 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 FeederAudit.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2007 + * 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/archetyped/FeederAuditDetails.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/FeederAuditDetails.java new file mode 100644 index 00000000..6d81b649 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/FeederAuditDetails.java @@ -0,0 +1,218 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class FeederAuditDetails" + * keywords: "common" + * + * 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/archetyped/FeederAuditDetails.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2006-03-08 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.common.archetyped; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.RMObject; +import org.openehr.rm.common.generic.PartyIdentified; +import org.openehr.rm.common.generic.PartyProxy; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; + +/** + * Audit details for a feeder system. Instances of this class are + * immutable + * + * @author Yin Su Lim + * @version 1.0 + */ +public final class FeederAuditDetails extends RMObject { + + /** + * Constrcuts a FeederAuditDetails + * + * @param systemId not null + * @param provider null if not present + * @param timeCommitted null if not present + * @param location null if not present + * @param time null if not present + * @param subject null if not present + * @param versionId null if not present + * @throws IllegalArgumentException if systemId is null or empty + */ + public FeederAuditDetails(String systemID, PartyIdentified provider, + PartyIdentified location, DvDateTime time, PartyProxy subject, + String versionID) { + if (StringUtils.isEmpty(systemID)) { + throw new IllegalArgumentException("null or empty systemId"); + } + this.systemId = systemID; + this.provider = provider; + this.location = location; + this.time = time; + this.subject = subject; + this.versionId = versionID; + } + + /** + * Identity of the system which handled the information item + * + * @return systemId + */ + public String getSystemId() { + return systemId; + } + + /** + * Identity of optional provider who created/committed/forwarded/handled the item + * + * @return provider + */ + public PartyIdentified getProvider() { + return provider; + } + + /** + * Identity of site/facility within an organisation which handled the item + * + * @return location + */ + public PartyIdentified getLocation() { + return location; + } + + /** + * Time of handling of the item + * + * @return time + */ + public DvDateTime getTime() { + return time; + } + + /** + * Identity for subject of the received information item + * + * @return subject + */ + public PartyProxy getSubject() { + return subject; + } + + /** + * Any identifier used in the system if available + * + * @return versionId + */ + public String getVersionId() { + return versionId; + } + + /** + * Equals if have same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof FeederAuditDetails )) return false; + + final FeederAuditDetails fad = (FeederAuditDetails) o; + + return new EqualsBuilder() + .append(systemId, fad.systemId) + .append(provider, fad.provider) + .append(location, fad.location) + .append(time, fad.time) + .append(subject, fad.subject) + .append(versionId, fad.versionId) + .isEquals(); + } + + /** + * Return a hashcode of this object + * + * @return hashcode + */ + public int hashCode() { + return new HashCodeBuilder(7, 23) + .append(systemId) + .append(provider) + .append(location) + .append(time) + .append(subject) + .append(versionId) + .toHashCode(); + } + + //POJO start + FeederAuditDetails() {} + + void setProvider(PartyIdentified provider) { + this.provider = provider; + } + + void setSubject(PartyProxy subject) { + this.subject = subject; + } + + void setSystemId(String systemID) { + this.systemId = systemID; + } + + void setTime(DvDateTime time) { + this.time = time; + } + + void setVersionId(String versionID) { + this.versionId = versionID; + } + + void setLocation(PartyIdentified location) { + this.location = location; + } + //POJO end + + /* fields */ + private String systemId; + private PartyIdentified provider; + private PartyIdentified location; + private DvDateTime time; + private PartyProxy subject; + private String versionId; + +} + +/* + * ***** 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 FeederAuditDetails.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/archetyped/Link.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Link.java new file mode 100644 index 00000000..4bfe8f15 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Link.java @@ -0,0 +1,183 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Link" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/common/archetyped/Link.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.common.archetyped; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.RMObject; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.datatypes.uri.DvEHRURI; + +/** + * The Link type defines a logical relationship between two items, + * such as two ENTRYs or an ENTRY and a COMPOSITION. Links can be + * used across compositions, and across EHRs. Links can potentially + * be used between interior (ie non archetype root) nodes, although + * this probably should be prevented in archetypes. Multiple LINKs + * can be attached to the root object of any archetyped structure to + * give the effect of a 1->N link. + * + * Instances of this class are immutable + * + * @author Rong Chen + * @version 1.0 + */ +public final class Link extends RMObject { + + /** + * Constructs a Link by meaning, type and target + * + * @param meaning not null + * @param type not null + * @param target not null + * @throws IllegalArgumentException if any null argument + */ + public Link(DvText meaning, DvText type, DvEHRURI target) { + if(meaning == null) { + throw new IllegalArgumentException("null meaning"); + } + if(type == null) { + throw new IllegalArgumentException("null type"); + } + if(target == null) { + throw new IllegalArgumentException("null target"); + } + this.meaning = meaning; + this.type = type; + this.target = target; + } + + /** + * Used to describe the relationship, usually in clinical terms, + * such as in response to (the relationship between test + * results and an order), follow-up to and so on. Such + * relationships can represent any clinically meaningful + * connection between pieces of information. + * + * @return meaning + */ + public DvText getMeaning() { + return meaning; + } + + /** + * The type attribute is used to indicate a clinical or + * domain-level meaning for the kind of link, for example + * "problem" or "issue". If type values are designed + * appropriately, they can be used by the requestor of + * EHR extracts to categorise links which must be followed and + * which can be broken when the extract is created. + * + * @return type + */ + public DvText getType() { + return type; + } + + /** + * the logical "to" object in the link relation, as per the + * linguistic sense of the meaning attribute. + * + * @return target + */ + public DvEHRURI getTarget() { + return target; + } + + /** + * Two links equal if both have same values for meaning, + * type and target + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof Link )) return false; + + final Link link = (Link) o; + + return new EqualsBuilder() + .append(meaning, link.meaning) + .append(type, link.type) + .append(target, link.target) + .isEquals(); + } + + /** + * Return a hash code of this link + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(7, 29) + .append(meaning) + .append(type) + .append(target) + .toHashCode(); + } + + // POJO start + Link() { + } + + void setMeaning(DvText meaning) { + this.meaning = meaning; + } + + void setType(DvText type) { + this.type = type; + } + + void setTarget(DvEHRURI target) { + this.target = target; + } + // POJO end + + /* fields */ + private DvText meaning; + private DvText type; + private DvEHRURI target; +} + +/* + * ***** 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 Link.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/archetyped/Locatable.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Locatable.java new file mode 100644 index 00000000..01d0ec13 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Locatable.java @@ -0,0 +1,702 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Locatable" + * keywords: "common" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004 Acode HB, Sweden" + * copyright: "Copyright (c) 2010 Cambio Healthcare Systems, 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/archetyped/Locatable.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.common.archetyped; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.datatypes.text.DvText; + +import java.lang.reflect.Method; +import java.util.*; + +/** + * Root structural class of all information models. Instances of + * this class are immutalbe. + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class Locatable extends Pathable implements Settable, Cloneable { + + /** + * Constructs a Locatable + * + * @param uid null if not specified + * @param archetypeNodeId not null + * @param name not null + * @param archetypeDetails null if not specified + * @param feederAudit null if not specified + * @param links null if not specified + * @param parent null if not specified + * @throws IllegalArgumentException if name null or archetypeNodeId null + * or links not null and empty + */ + protected Locatable(UIDBasedID uid, String archetypeNodeId, DvText name, + Archetyped archetypeDetails,FeederAudit feederAudit, + Set links, Pathable parent) { + super(parent); + + if (archetypeNodeId == null) { + throw new IllegalArgumentException("null archetypeNodeId"); + } + if (name == null) { + throw new IllegalArgumentException("null name"); + } + if (links != null && links.isEmpty()) { + throw new IllegalArgumentException("empty links"); + } + this.uid = uid; + this.archetypeNodeId = archetypeNodeId; + this.name = name; + this.archetypeDetails = archetypeDetails; + this.feederAudit = feederAudit; + this.links = links; + } + + /** + * Constructs a Locatable node by archetypeNodeId and name + * same as name + * + * @param archetypeNodeId + * @param name + * @throws IllegalArgumentException if archetypeNodeId or name null + */ + protected Locatable(String archetypeNodeId, DvText name) { + this(null, archetypeNodeId, name, null, null, null, null); + } + + /** + * Optional globally unique object identifier for root object of + * archetyped data structure. + * + * @return uid + */ + public UIDBasedID getUid() { + return uid; + } + + /** + * Design-time archetype id of this node taken from its generating + * archetype; used to build archetype paths. Always in the form of an + * "at" code, eg "at0005". This value enables a "standardised" name + * for this node to be generated, by referring to the generating archetype + * local ontology. + * + * @return archetypeNodeId + */ + public String getArchetypeNodeId() { + return archetypeNodeId; + } + + public String getOriginalArchetypeNodeId() { + return originalArchetypeNodeId; + } + + public String setOriginalArchetypeNodeId(String originalArchetypeNodeId) { + return this.originalArchetypeNodeId = originalArchetypeNodeId; + } + + /** + * Runtime name of this fragment, used to build runtime paths. + * This is the term provided via a clinical application or batch + * process to name this EHR construct: its retention in the EHR + * faithfully preserves the original label by which this entry + * was known to end users. + * + * @return name + */ + public DvText getName() { + return name; + } + + /** + * Details of archetyping used on this node. + * + * @return archetype details + */ + public Archetyped getArchetypeDetails() { + return archetypeDetails; + } + + /** + * Audit trail from non-openEHR system of original commit of + * information forming the content of this node, or from a + * conversion gateway which has synthesised this node. + * + * @return feederAuidt + */ + public FeederAudit getFeederAudit() { + return feederAudit; + } + + /** + * Links to other archetyped structures (data whose root object + * inherits from ARCHETYPED, such as ENTRY, SECTION and so on). + * Links may be to structures in other compositions. + * + * @return links or null if unspecified + */ + public Set getLinks() { + return links; + } + + /** + * True if this node is the root of an archetyped structure + * + * @return true if archetype root + */ + public boolean isArchetypeRoot() { + return archetypeDetails != null; + } + + /** + * String The path to an item relative to the root of this + * archetyped structure. + * + * @param item + * @return string path + */ + 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(); + if (next.matches(".+\\[.+[^\\]]$")) { + do { + next = next + "/" + tokens.nextToken(); + } 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; + } + List segments = dividePathIntoSegments(path); + return evaluatePathSegment(segments, object); + } + + /* + * Evaluate recursively the path segments + */ + 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("]")); + } else { + attributeName = pathSegment; + } + + value = getAttributeValue(object, attributeName); + if(expression != null && value != null ) { + value = processPredicate(expression, value); + } + if(value != null) { + return evaluatePathSegment(pathSegments, value); + } + return null; + } + + public String toCamelCase(String underscoreSeparated) { + if( ! underscoreSeparated.contains("_")) { + return 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 toFirstUpperCaseCamelCase(String name) { + name = toCamelCase(name); + 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) { + String name = null; + String archetypeNodeId = null; + expression = expression.trim(); + int index; + + // shortcut syntax, [at0001, 'standing'] + if(expression.contains(",") + // avoid [at0001 and/value='status, 2nd'] + && expression.indexOf(",") < expression.indexOf("'")) { + index = expression.indexOf(","); + 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'. + if(expression.contains(" AND ")) { + index = expression.indexOf(" AND "); + } else { + index = expression.indexOf(" and "); + } + archetypeNodeId = expression.substring(0, index).trim(); + name = expression.substring(expression.indexOf("'") + 1, + 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] + } else { + archetypeNodeId = expression; + } + + Iterable collection = null; + if(object instanceof Iterable) { + collection = (Iterable) object; + } else { + List list = new ArrayList(); + list.add(object); + collection = list; + } + + for(Object item : collection) { + if(item instanceof Locatable) { + Locatable locatable = (Locatable) item; + 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. + * + * @param path + * @return the item + * @throws IllegalArgumentException if path invalid + */ + public Object itemAtPath(String path) { + if (path == null) { + throw new IllegalArgumentException("invalid path: " + path); + } + if (Locatable.ROOT.equals(path) || path.equals(whole())) { + return this; + } + return genericPathEvaluator(path, this); + } + + /* + * Retrieves the value of named attribute of given object + */ + private Object getAttributeValue(Object obj, String attribute) { + Class rmClass = obj.getClass(); + Object value = null; + Method getter = null; + String getterName = "get" + toFirstUpperCaseCamelCase(attribute); + + try { + getter = rmClass.getMethod(getterName, null); + value = getter.invoke(obj, null); + + } catch(Exception e) { + // TODO log as kernel warning + // e.printStackTrace(); + } + return value; + } + + /* + * Sets the value of named attribute of given object + */ + private void setAttributeValue(Object obj, String attribute, Object value) { + Class rmClass = obj.getClass(); + String setterName = "set" + toFirstUpperCaseCamelCase(attribute); + + try { + Method setter = getMethodByName(rmClass, setterName); + if(setter == null) { + throw new IllegalArgumentException("unkown setter method: " + setterName + " for rmClass=" + rmClass); + } + setter.invoke(obj, value); + + } catch(Exception e) { + // TODO log as kernel warning + e.printStackTrace(); + } + } + + private Method getMethodByName(Class klass, String method) { + Method[] methods = klass.getMethods(); + for(Method m : methods) { + if(method.equals(m.getName())) { + return m; + } + } + return null; + } + + + public void set(String path, Object value) { + int i = path.lastIndexOf("/"); + if(i < 0 || i == path.length()) { + throw new IllegalArgumentException( + "invalid path for setting value: " + path); + } + String objPath = "/"; + if(i > 0) { + 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 + */ + public static String parentPath(String path) { + List list = dividePathIntoSegments(path); + int pathLevel = list.size(); + if(pathLevel == 0) { + throw new IllegalArgumentException("Unable to compute parent path: " + + path); + } else if(pathLevel == 1) { + return PATH_SEPARATOR; + } + StringBuffer buf = new StringBuffer(); + for(int j = 0; j < pathLevel - 1; j++) { + buf.append(PATH_SEPARATOR); + buf.append(list.get(j)); + } + return buf.toString(); + } + + 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++) { + buf.append(PATH_SEPARATOR); + 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); + if(attributeValue == null) { + attributeValue = new ArrayList(); + } + if(attributeValue instanceof List) { + List parent = (List) attributeValue; + 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()) { + throw new IllegalArgumentException( + "invalid path for setting value: " + path); + } + String objPath = PATH_SEPARATOR; + List list = dividePathIntoSegments(path); + int pathLevel = list.size(); + if(pathLevel > 1) { + StringBuffer buf = new StringBuffer(); + for(int j = 0; j < pathLevel - 1; j++) { + buf.append(PATH_SEPARATOR); + buf.append(list.get(j)); + } + 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); + 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); + } + } + + /** + * Clinical concept of the archetype as a whole, derived from the + * archetypeNodeId of the root node + * + * @return archetype concept + * @throws UnsupportedOperationException if this node is not root + */ + public DvText concept() { + if (!isArchetypeRoot()) { + throw new UnsupportedOperationException("not root node"); + } + return new DvText(archetypeDetails.getArchetypeId().conceptName()); + } + + /** + * Return sting presentation of this locatable + * + * @return string presentation + */ + public String toString() { + return archetypeNodeId.equals(name) ? + archetypeNodeId.toString() : archetypeNodeId + ", " + name; + } + + /** + * Equals if two actors has same values + * + * @param o + * @return equals if true + */ + 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)) + .append(uid, loc.uid) + .append(archetypeNodeId, loc.archetypeNodeId) + .append(name, loc.name) + .append(archetypeDetails, loc.archetypeDetails) + .append(feederAudit, loc.feederAudit) + .append(links, loc.links) + .isEquals(); + } + + /** + * Return a hash code of this actor + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(11, 29) + .appendSuper(super.hashCode()) + .append(uid) + .append(archetypeNodeId) + .append(name) + .append(archetypeDetails) + .append(feederAudit) + .append(links) + .toHashCode(); + } + + @Override public Locatable clone() { + try { + return (Locatable) super.clone(); + } catch(CloneNotSupportedException e) { + throw new AssertionError(); + } + } + + /** + * Return path of current whole node + */ + public String whole() { + return ROOT;// + "[" + getName().getValue() + "]"; + } + + public String nodeName() { + return "[" + getName().getValue() + "]"; + } + + public String atNode() { + return ROOT + "[" + getArchetypeNodeId() + "]"; + } + + // POJO start + protected Locatable() { + } + + protected void setUid(UIDBasedID uid) { + this.uid = uid; + } + + protected void setArchetypeNodeId(String archetypeNodeId) { + this.archetypeNodeId = archetypeNodeId; + } + + protected void setName(DvText name) { + this.name = name; + } + + protected void setArchetypeDetails(Archetyped archetypeDetails) { + this.archetypeDetails = archetypeDetails; + } + + protected void setFeederAudit(FeederAudit feederAudit) { + this.feederAudit = feederAudit; + } + + protected void setLinks(Set links) { + this.links = links; + } + // POJO end + + /** + * Separator used to delimit segments in the path + */ + public static final String PATH_SEPARATOR = "/"; + public static final String ROOT = PATH_SEPARATOR; + + /* fields */ + private UIDBasedID uid; + private String archetypeNodeId; + private String originalArchetypeNodeId; + private DvText name; + private Archetyped archetypeDetails; + private FeederAudit feederAudit; + private Set links; + +} + +/* + * ***** 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 Locatable.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-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 new file mode 100644 index 00000000..4d384408 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Pathable.java @@ -0,0 +1,163 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Pathable" + * keywords: "common" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007,2008 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.rm.common.archetyped; + +import java.util.*; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.RMObject; + +/** + * Abstract parent of all classes whose instances are reachable by paths, and + * which know how to locate child object by paths. + * + * @author Rong Chen + */ +public abstract class Pathable extends RMObject { + + /** + * Creates a Pathable + * + * @param parent null if not present + */ + public Pathable(Pathable parent) { + this.parent = parent; + } + + /** + * Sets the parent + * + * @param parent + */ + protected void setParent(Pathable parent) { + this.parent = parent; + } + + /** + * Creates a pathable without parent + */ + public Pathable() { + this(null); + } + + /** + * Parent of this node in compositional hierarchy + * + * @return parent or null if not specified + */ + public Pathable getParent() { + return this.parent; + } + + /** + * The item at a path (relative to this item); only valid for unique paths, + * i.e. paths that resolve to a single item. + * + * @param path not null and unique + * @return the item + * @throws IllegalArgumentException if path invalid + */ + public abstract Object itemAtPath(String path); + + /** + * List of items corresponding to a nonunique path. + * + * @param path not null and not unique + * @return the items + */ + public abstract List itemsAtPath(String path); + + /** + * The path to an item relative to the root of this archetyped structure. + * + * @param item not null + */ + public abstract String pathOfItem(Pathable item); + + /** + * True if the path exists in the data with respect to the current item + * + * @param path not null or empty + * @return true if exists + */ + public abstract boolean pathExists(String path); + + /** + * True if the path corresponds to a single item in the data. + * @param path not null and exists + * @return true if unique + */ + public abstract boolean pathUnique(String path); + + /** + * Equals if two actors has same values + * + * @param o + * @return equals if true + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof Pathable )) return false; + + final Pathable path = (Pathable) o; + return new EqualsBuilder() + .append(parent, path.parent) + .isEquals(); + + } + + /** + * Return a hash code of this actor + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(11, 29) + .appendSuper(super.hashCode()) + .append(parent) + .toHashCode(); + } + + private Pathable parent; +} +/* + * ***** 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 Pathable.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2007,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-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 new file mode 100644 index 00000000..0a3a3068 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Settable.java @@ -0,0 +1,76 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Settable" + * keywords: "common" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2010 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.rm.common.archetyped; + +/** + * Interface for setting values in reference model classes based on paths + * + * @author rong.chen + */ +public interface Settable { + + /** + * Sets value based on path + * + * @param path the path to reach the RM instance relatively from this object + * @param value the value to set + */ + public void set(String path, Object value); + + /** + * Removes a child identified by the path from a container attribute + * + * @param path + * @exception IllegalArgumentException if the parent attribute is not a container attribute + */ + public void removeChild(String path); + + /** + * Adds a child to a container attributed identified by the path + * + * @param path the path to locate the container + * @param child the child object to add to the container + * @exception IllegalArgumentException if the parent attribute is not a container attribute + */ + public void addChild(String path, Object child); +} +/* + * ***** 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 Pathable.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2010 + * 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/changecontrol/Contribution.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/Contribution.java new file mode 100644 index 00000000..7bc13cfa --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/Contribution.java @@ -0,0 +1,179 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Contribution" + * keywords: "common" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2008 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL: http://svn.openehr.org/ref_impl_java/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/common/changecontrol/Contribution.java $" + * revision: "$LastChangedRevision: 29 $" + * last_change: "$LastChangedDate: 2006-04-29 00:34:13 +0200 (Sat, 29 Apr 2006) $" + */ +package org.openehr.rm.common.changecontrol; + +import org.openehr.rm.common.generic.AuditDetails; +import org.openehr.rm.support.identification.ObjectID; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.RMObject; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import java.util.Set; + +/** + * Documents a contribution of one or more versions added to a + * change-controlled repository. + * + * @author Rong Chen + * @version 1.0 + */ +public class Contribution extends RMObject { + + /** + * Constructs a contribution + * + * @param uid not null + * @param versions not null or empty + * @param audit not null + */ + @FullConstructor + public Contribution( + @Attribute(name = "uid", required = true)ObjectID uid, + @Attribute(name = "versions", required = true)Set versions, + @Attribute(name = "audit", required = true)AuditDetails audit) { + if (uid == null) { + throw new IllegalArgumentException("null uid"); + } + if (audit == null) { + throw new IllegalArgumentException("null audit"); + } + if (audit.getDescription() == null) { + throw new IllegalArgumentException("null audit description"); + } + if (versions == null || versions.isEmpty()) { + throw new IllegalArgumentException("invalid versions"); + } + this.uid = uid; + this.versions = versions; + this.audit = audit; + } + + /** + * Unique identifier for this contribution. + * + * @return uid + */ + public ObjectID getUid() { + return uid; + } + + /** + * Audit trail of this Contribution as a whole + * + * @return audit details + */ + public AuditDetails getAudit() { + return audit; + } + + /** + * Set of references to versions causing changes to this EHR. + * Each contribution contains a list of versions, which may + * include paths pointing to any number of VERSION items, + * ie items of type COMPOSITION and FOLDER. + * + * @return Set of ObjectRef + */ + public Set getVersions() { + return versions; + } + + /** + * Equals if have same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof Contribution )) return false; + + final Contribution contribution = (Contribution) o; + + return new EqualsBuilder() + .append(uid, contribution.uid) + .append(versions, contribution.versions) + .append(audit, contribution.audit) + .isEquals(); + } + + /** + * Return a hashcode of this object + * + * @return hashcode + */ + public int hashCode() { + return new HashCodeBuilder(17, 37) + .append(uid) + .append(versions) + .append(audit) + .toHashCode(); + } + + // POJO start + Contribution() { + } + + void setUid(ObjectID uid) { + this.uid = uid; + } + + void setAudit(AuditDetails audit) { + this.audit = audit; + } + + void setVersions(Set versions) { + this.versions = versions; + } + // POJO end + + /* fields */ + private ObjectID uid; + private Set versions; + private AuditDetails audit; +} + +/* + * ***** 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 Contribution.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-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 new file mode 100644 index 00000000..c17df19a --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/ImportedVersion.java @@ -0,0 +1,109 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ImportedVersion" + * keywords: "common" + * + * 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/changecontrol/ImportedVersion.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.common.changecontrol; + +import org.openehr.rm.common.generic.AuditDetails; +import org.openehr.rm.support.identification.ObjectRef; + +/** + * Versionable object that has been copied from another location and imported + * into a local version container + * + * @author Yin Su Lim + * @version 1.0 + */ +public final class ImportedVersion extends Version { + + /** + * Constructs an ImportedVersion + * + * @param commitAudit + * @param contribution + * @param originalVersion + */ + public ImportedVersion(OriginalVersion original, AuditDetails commitAudit, + ObjectRef contribution, String signature) { + if (original == null) { + throw new IllegalArgumentException("null item version"); + } + if (commitAudit == null) { + throw new IllegalArgumentException("null audit"); + } + if (contribution == null) { + throw new IllegalArgumentException("null contribution"); + } + this.item = original; + setAttributes(original.getUid(), original.getPrecedingVersionUid(), + original.getData(), original.getLifecycleState(), commitAudit, + contribution, signature); + } + + /** + * The item Version object that was imported. + * + * @return item + */ + public OriginalVersion getItem() { + return item; + } + + //POJO start + ImportedVersion() { + } + + void setItem(OriginalVersion original) { + if(original != null) { + this.item = original; + } else { + throw new IllegalArgumentException("null item version"); + } + } + + //POJO end + + /* fields */ + private OriginalVersion item; + +} + +/* + * ***** 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 ImportedVersion.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/changecontrol/OriginalVersion.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/OriginalVersion.java new file mode 100644 index 00000000..36314902 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/OriginalVersion.java @@ -0,0 +1,157 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class OriginalVersion" + * keywords: "common" + * + * 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/changecontrol/OriginalVersion.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.common.changecontrol; + +import java.util.List; +import java.util.Set; + +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.common.generic.Attestation; +import org.openehr.rm.common.generic.AuditDetails; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.support.identification.ObjectVersionID; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * @author yinsulim + * @author Modified by Erik Sundvall 2010-03-19 + */ +public class OriginalVersion extends Version { + + /** + * @param uid + * @param precedingVersionID + * @param data + * @param attestations + * @param commitAudit + * @param contribution + * @param lifecycleState + * @param terminologyService + */ + @FullConstructor + public OriginalVersion( + @Attribute(name = "uid", required = true)ObjectVersionID uid, + @Attribute(name = "precedingVersionUid")ObjectVersionID precedingVersionUid, + @Attribute(name = "data")T data, + @Attribute(name = "lifecycleState", required = true)DvCodedText lifecycleState, + @Attribute(name = "commitAudit", required = true)AuditDetails commitAudit, + @Attribute(name = "contribution", required = true)ObjectRef contribution, + @Attribute(name = "signature")String signature, + @Attribute(name = "otherInputVersionUids")Set otherInputVersionUids, + @Attribute(name = "attestations")List attestations, + // @Attribute(name = "isMerged") boolean isMerged, // This should not be an attribute, just internally calculated from existence of otherInputVersionUids + @Attribute(name = "terminologyService", system = true)TerminologyService terminologyService) { + + super(uid, precedingVersionUid, data, lifecycleState, commitAudit, + contribution, signature, terminologyService); + if (attestations != null && attestations.isEmpty()) { + throw new IllegalArgumentException("empty attestations"); + } + this.attestations = attestations; + + if (otherInputVersionUids != null && otherInputVersionUids.isEmpty()) { // == isMerged ) { + throw new IllegalArgumentException("empty otherInputVersionUids"); //("breach of isMerged validity"); + } + this.otherInputVersionUids = otherInputVersionUids; + } + + /** + * List of attestations relating this version. + * + * @return attestations or null if unspecified + */ + public List getAttestations() { + return attestations; + } + +// /** +// * True if this Version was created from more than +// * just the preceding (checked out) version. +// */ +// public boolean getIsMerged() { // This should not be an attribute, just internally calculated from existence of otherInputVersionUids +// return isMerged; +// } + + /** + * True if this Version was created from more than + * just the preceding (checked out) version. + */ + public boolean isMerged() { // This should not be an attribute, just internally calculated from existence of otherInputVersionUids + return otherInputVersionUids != null && otherInputVersionUids.size() > 0; + } + + /** + * Identifiers of other versions whose content was merged + * into this version, if any. + */ + public Set getOtherInputVersionUids() { + return otherInputVersionUids; + } + + // POJO start + OriginalVersion() { + } + + void setAttestations(List attestations) { + this.attestations = attestations; + } + +// void setIsMerged(boolean isMerged) { // This should not be an attribute, just internally calculated from existence of otherInputVersionUids +// this.isMerged = isMerged; +// } + + void setOtherInputVersionUids(Set otherInputVersionUids) { + this.otherInputVersionUids = otherInputVersionUids; + } + // POJO end + + /* fields */ + private Set otherInputVersionUids; + private List attestations; + private boolean isMerged; + +} + +/* + * ***** 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 OriginalVersion.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/changecontrol/Version.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/Version.java new file mode 100644 index 00000000..05ec74db --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/Version.java @@ -0,0 +1,252 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Version" + * keywords: "common" + * + * author: "Rong Chen , Yin Su Lim " + * 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/changecontrol/Version.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2006-03-21 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.common.changecontrol; + +import org.apache.commons.lang.NotImplementedException; +import org.openehr.rm.RMObject; +import org.openehr.rm.common.generic.AuditDetails; +import org.openehr.rm.support.identification.HierObjectID; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.support.identification.ObjectVersionID; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * Versionable object, with an audit trail containing details of + * change and list of attestations + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class Version extends RMObject { + + /** + * Constructs a Version + * + * @param versionID not null or empty + * @param precedingVersionUid not null or empty + * @throws IllegalArgumentException + */ + public Version(ObjectVersionID uid, ObjectVersionID precedingVersionID, + T data, DvCodedText lifeCycleState, AuditDetails commitAudit, + ObjectRef contribution, String signature, + TerminologyService terminologyService) { + + if (uid == null) { + throw new IllegalArgumentException("null uid"); + } + if(lifeCycleState == null) { + throw new IllegalArgumentException("null lifecycleState"); + } + if (commitAudit == null) { + throw new IllegalArgumentException("null audit"); + } + if (contribution == null) { + throw new IllegalArgumentException("null contribution"); + } + if (uid.versionTreeID().isFirst() == (precedingVersionID != null)) { + throw new IllegalArgumentException("breach of precedingVersionUid validity"); + } + if(!terminologyService.terminology(TerminologyService.OPENEHR) + .codesForGroupName("version lifecycle state", "en") + .contains(lifeCycleState.getDefiningCode())) { + throw new IllegalArgumentException("unknown lifecycleState"); + } + setAttributes(uid, precedingVersionID, data, lifeCycleState, commitAudit, + contribution, signature); + } + + + /** + * Unique identifier of the owning version container. + * + * @return uid of owning version container + */ + public HierObjectID ownerID() { + //TODO check if correct, the extension bit at the back? + return new HierObjectID(uid.objectID(), null); + } + + /** + * True if this Version represents a branch + */ + public boolean isBranch() { + return uid.versionTreeID().isBranch(); + } + + + /** + * Canonical form of Version object, created by + * serialising all attributes except signature + */ + public String canonicalForm() { + //return uid.toString() + "," + precedingVersionUid.toString() + + // "," + data.toString() + "," + lifecycleState.toString() + + // "," + commitAudit.toString() + "," + contribution.toString(); + //TODO:implement + throw new NotImplementedException(); + //return ""; + } + + /** + * Audit trail of this version + * + * @return version audit + */ + public AuditDetails getCommitAudit() { + return commitAudit; + } + + /** + * Unique identifier of this version + * + * @return versionID + */ + public ObjectVersionID getUid() { + return uid; + } + + /** + * Unique identifier of the version on which this version was + * based. May be the pseudo-version "first" + * + * @return preceding versionID + */ + public ObjectVersionID getPrecedingVersionUid() { + return precedingVersionUid; + } + + /** + * Lifecycle state of this version; coded by openEHR + * vocabulary "version lifecycle state" + */ + public DvCodedText getLifecycleState() { + return lifecycleState; + } + + + /** + * Contribution in which this version was added + * + * @return contribution + */ + public ObjectRef getContribution() { + return contribution; + } + + /** + * Original content of this Version + * + *@return data + */ + public T getData() { + return data; + } + + /** + * OpenPGP digital signature or digest of content + * committed in this Version + */ + public String getSignature() { + return signature; + } + + // POJO start + Version() { + } + + void setSignature(String signature) { + this.signature = signature; + } + + void setLifecycleState(DvCodedText lifeCycleState) { + this.lifecycleState = lifeCycleState; + } + + void setCommitAudit(AuditDetails audit) { + this.commitAudit = audit; + } + + void setUid(ObjectVersionID uid) { + this.uid = uid; + } + + void setPrecedingVersionUid(ObjectVersionID precedingVersionID) { + this.precedingVersionUid = precedingVersionID; + } + + void setContribution(ObjectRef contribution) { + this.contribution = contribution; + } + + void setData(T data) { + this.data = data; + } + + protected void setAttributes(ObjectVersionID uid, + ObjectVersionID precedingVersionID, T data, DvCodedText lifeCycleState, + AuditDetails commitAudit, ObjectRef contribution, + String signature) { + this.uid = uid; + this.precedingVersionUid = precedingVersionID; + this.data = data; + this.lifecycleState = lifeCycleState; + this.commitAudit = commitAudit; + this.contribution = contribution; + this.signature = signature; + } + + // POJO end + + /* fields */ + private AuditDetails commitAudit; + private ObjectVersionID uid; + private ObjectVersionID precedingVersionUid; + private ObjectRef contribution; + private T data; + private DvCodedText lifecycleState; + private String signature; + +} + +/* + * ***** 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 Version.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/changecontrol/VersionedObject.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/VersionedObject.java new file mode 100644 index 00000000..0a2c178c --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/VersionedObject.java @@ -0,0 +1,460 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class VersionedObject" + * keywords: "common" + * + * 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/changecontrol/VersionedObject.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.common.changecontrol; + +import java.util.*; + +import org.openehr.rm.RMObject; +import org.openehr.rm.common.generic.Attestation; +import org.openehr.rm.common.generic.AuditDetails; +import org.openehr.rm.common.generic.RevisionHistory; +import org.openehr.rm.common.generic.RevisionHistoryItem; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.support.identification.HierObjectID; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.support.identification.ObjectVersionID; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * @author yinsulim + * + */ +/** + * @author yinsulim + * + * @param + */ +public class VersionedObject extends RMObject { + + /** + * Constructs a VersionObject with first originalVersion + */ + public VersionedObject(HierObjectID uid, ObjectRef ownerID, + DvDateTime timeCreated, ObjectVersionID versionID, T data, + DvCodedText lifecycleState, AuditDetails commitAudit, + ObjectRef contribution, String signature, + TerminologyService terminologyService) { + + this(uid, ownerID, timeCreated); + commitOriginalVersion(versionID, null, data, commitAudit, contribution, + lifecycleState, signature, terminologyService); + } + + /** + * Constructs a VersionObject with first importedVersion + */ + public VersionedObject(HierObjectID uid, ObjectRef ownerID, + DvDateTime timeCreated, OriginalVersion item, AuditDetails commitAudit, + ObjectRef contribution, String signature) { + this(uid, ownerID, timeCreated); + commitImportedVersion(item, commitAudit, contribution, signature); + } + + /** + * Constructs a VersionObject with first merged Version + */ + public VersionedObject(HierObjectID uid, ObjectRef ownerID, + DvDateTime timeCreated, ObjectVersionID versionID, + ObjectVersionID precedingVersionID, T data, DvCodedText lifecycleState, + AuditDetails commitAudit, ObjectRef contribution, + Set otherInputVersionUids, String signature, + TerminologyService terminologyService) { + this(uid, ownerID, timeCreated); + commitOriginalMergedVersion(versionID, precedingVersionID, data, lifecycleState, + commitAudit, contribution, otherInputVersionUids, signature, + terminologyService); + } + + private VersionedObject(HierObjectID uid, ObjectRef ownerID, + DvDateTime timeCreated) { + if (uid == null) { + throw new IllegalArgumentException("null uid"); + } + if (ownerID == null) { + throw new IllegalArgumentException("null ownerID"); + } + if (timeCreated == null) { + throw new IllegalArgumentException("null timeCreated"); + } + this.uid = uid; + this.ownerID = ownerID; + this.timeCreated = timeCreated; + timeVersionMap = new TreeMap>(); + idVersionMap = new HashMap>(); + } + + /** + * Add a new ImportedVersion + * + * @param commitAudit + * @param contribution + * @param item + */ + public synchronized void commitImportedVersion(OriginalVersion item, AuditDetails commitAudit, + ObjectRef contribution, String signature) { + + commitVersionCheck(item.getUid(), item.getPrecedingVersionUid()); + Version version = new ImportedVersion(item, commitAudit, contribution, signature); + addVersion(version); + } + + private synchronized void commitVersionCheck(ObjectVersionID vUid, ObjectVersionID precedingVUid) { + if (versionCount() > 0 && !hasVersionID(precedingVUid)) { + throw new IllegalArgumentException("precedingVersionID not found"); + } + if(!vUid.objectID().equals(this.uid.root())) { + throw new IllegalArgumentException("ownerID different from versionedObject"); + } + } + + private synchronized void addVersion(Version version) { + if (!version.getUid().versionTreeID().isBranch()) { + int trunkNo = Integer.parseInt(version.getUid().versionTreeID().trunkVersion()); + if (trunkNo != trunkCounter + 1) { + throw new IllegalArgumentException("invlalid trunk no in uid"); + } else { + trunkCounter++; + latestTrunkUid = version.getUid(); + } + } + timeVersionMap.put(version.getCommitAudit().getTimeCommitted(), version); + idVersionMap.put(version.getUid(), version); + } + + /** + * Add a new original Version + * @param versionID + * @param precedingVersionID + * @param data + * @param commitAudit + * @param contribution + * @param lifecycleState + * @param terminologyService + */ + public synchronized void commitOriginalVersion(ObjectVersionID versionID, + ObjectVersionID precedingVersionID, T data, AuditDetails commitAudit, + ObjectRef contribution, DvCodedText lifecycleState, String signature, + TerminologyService terminologyService) { + + commitVersionCheck(versionID, precedingVersionID); + Version version = new OriginalVersion(versionID, precedingVersionID, + data, lifecycleState, commitAudit, contribution, signature, null, null, + //false, + terminologyService); + addVersion(version); + } + + /** + * Add a new original MergedVersion + * @param versionID + * @param precedingVersionID + * @param data + * @param commitAudit + * @param contribution + * @param lifecycleState + * @param terminologyService + */ + public synchronized void commitOriginalMergedVersion(ObjectVersionID versionID, + ObjectVersionID precedingVersionID, T data, DvCodedText lifecycleState, + AuditDetails commitAudit, ObjectRef contribution, + Set otherInputVersionUids, String signature, + TerminologyService terminologyService) { + + commitVersionCheck(versionID, precedingVersionID); + Version version = new OriginalVersion(versionID, precedingVersionID, + data, lifecycleState, commitAudit, contribution, signature, otherInputVersionUids, + null, + // true, + terminologyService); + addVersion(version); + } + + /** + * Unique identifier of this version repository. + * + * @return UID + */ + public HierObjectID getUid() { + return uid; + } + + /** + * Reference to object to which this versioned repository belongs, + * eg the id of the containing EHR. + * + * @return OwnerID + */ + public ObjectRef getOwnerID() { + return ownerID; + } + + /** + * Time of initial creation of this versioned object. + * + * @return time of creation + */ + public DvDateTime getTimeCreated() { + return timeCreated; + } + + /** + * Return a list of all versions in this object. + * + * @return all versions + */ + public synchronized List> allVersions() { + // todo: fix the order of this list + return new ArrayList>(idVersionMap.values()); + } + + /** + * Return a list of ids of all versions in this object. + * + * @return List + */ + public synchronized List allVersionIDs() { + // todo: fix the order of list + return new ArrayList(idVersionMap.keySet()); + } + + /** + * Return the total number of versions in this object + * + * @return version count + */ + public synchronized int versionCount() { + return idVersionMap.size(); + } + + /** + * True if a version with given id exists. + * + * @param id + * @return true if has + * @throws IllegalArgumentException + */ + public synchronized boolean hasVersionID(ObjectVersionID id) { + if (id == null) { + throw new IllegalArgumentException("null id"); + } + return idVersionMap.containsKey(id); + + } + + /** + * True if a version for given time exists. + * + * @param time + * @return true if has version + * @throws IllegalArgumentException if time null + */ + public synchronized boolean hasVersionAtTime(DvDateTime time) { + if (time == null) { + throw new IllegalArgumentException("null time"); + } + return timeVersionMap.containsKey(time); + } + + /** + * True if version with an id is an OriginalVersion + * + * @param uid + */ + public boolean isOriginalVersion(ObjectVersionID uid) { + if (!idVersionMap.containsKey(uid)) { + throw new IllegalArgumentException("versionID not found"); + } + Version version = idVersionMap.get(uid); + return version instanceof OriginalVersion; + } + + /** + * Return the version with given id + * + * @param id + * @return null if not found + * @throws IllegalArgumentException if id null + */ + public synchronized Version versionWithID(ObjectVersionID id) { + if (id == null) { + throw new IllegalArgumentException("null id"); + } + return idVersionMap.get(id); + } + + /** + * Return the version for given time + * + * @param time + * @return null if not found + * @throws IllegalArgumentException if time null + */ + public synchronized Version versionAtTime(DvDateTime time) { + if (time == null) { + throw new IllegalArgumentException("null time"); + } + return timeVersionMap.get(time); + } + + /** + * Return the latest version. + * + * @return lastest version + */ + public synchronized Version latestVersion() { + return (Version) timeVersionMap.get(timeVersionMap.lastKey()); + + } + + /** + * Return the most recetly added trunk version + * + */ + public synchronized Version latestTrunkVersion() { + return (Version) idVersionMap.get(latestTrunkUid); + + } + + /** + * Return the lifecycle state from the latest trunk version. + * + */ + public DvCodedText latestTrunkLifeCycleSate() { + Version trunk = latestTrunkVersion(); + return latestTrunkVersion().getLifecycleState(); + } + + /** + * History of all audits and attestations in this versioned repository + * + * @return revisionHistory + */ + public RevisionHistory revisionHistory() { + ArrayList> versions = new ArrayList> (timeVersionMap.values()); + ArrayList revHistoryItems = new ArrayList(); + for(Version version : versions) { + ArrayList audits = new ArrayList(); + audits.add(version.getCommitAudit()); + if (version instanceof OriginalVersion) { + OriginalVersion orgVersion = (OriginalVersion) version; + audits.addAll(orgVersion.getAttestations()); + } + revHistoryItems.add(new RevisionHistoryItem(audits, version.getUid())); + } + return new RevisionHistory(revHistoryItems); + } + + + /** + * Add a new attestation to the specified version. Attestations can only + * be added to OriginalVersion + * + * @param attestation + * @param versionID + */ + public synchronized void commitAttestation(Attestation attestation, + ObjectVersionID versionID) { + if (attestation == null) { + throw new IllegalArgumentException("null attestation"); + } + if (isOriginalVersion(versionID)) { + OriginalVersion oVersion = (OriginalVersion) idVersionMap.get(versionID); + oVersion.getAttestations().add(attestation); + } else { + throw new IllegalArgumentException("attestatios cannot be added to importedVersion"); + } + } + + //POJO start + protected VersionedObject() { + } + + private Long id; + + protected Long getId() { + return id; + } + + protected void setId(Long id) { + this.id = id; + } + + void setUid(HierObjectID uid) { + this.uid = uid; + } + + void setOwnerID(ObjectRef ownerID) { + this.ownerID = ownerID; + } + + void setTimeCreated(DvDateTime timeCreated) { + this.timeCreated = timeCreated; + } + + // in order to skip map timeVersionMap to table + void setVersions(Set> versions) { + idVersionMap = new HashMap>(); + timeVersionMap = new TreeMap>(); + for(Version version : versions) { + addVersion(version); + } + } + + // required to map bidirectional one-to-many relationship + Set> getVersions() { + return new HashSet>(timeVersionMap.values()); + } + + /* fields */ + private HierObjectID uid; + private ObjectRef ownerID; + private DvDateTime timeCreated; + + private SortedMap> timeVersionMap; + private HashMap> idVersionMap; + private int trunkCounter; + private ObjectVersionID latestTrunkUid; +} + +/* + * ***** 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 VersionedObject.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/directory/Folder.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/directory/Folder.java new file mode 100644 index 00000000..d54fe63d --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/directory/Folder.java @@ -0,0 +1,175 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Folder" + * keywords: "ehr" + * + * 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/directory/Folder.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.common.directory; + +import java.util.List; +import java.util.Set; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +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.datatypes.text.DvText; +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.support.identification.ObjectRef; + +public class Folder extends Locatable { + + /** + * Construts a Folder + * + * @param uid null if not specified + * @param archetypeNodeId not null + * @param name not null + * @param archetypeDetails null if not specified + * @param feederAudit null if not specified + * @param links null if not specified + * @param folders null if not specified + * @param items null if not specified + * @throws IllegalArgumentException if name null or archetypeNodeId null + * or links not null and empty + */ + public Folder(UIDBasedID uid, String archetypeNodeId, DvText name, + Archetyped archetypeDetails, FeederAudit feederAudit, Set links, + Pathable parent, List folders, List items) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, parent); + if(folders != null && folders.size() == 0) { + throw new IllegalArgumentException("empty sub-folders"); + } + this.folders = folders; + this.items = items; + } + + /** + * Sub-folders of this FOLDER + * @return folder A list of folders which are the sub-folders of this FOLDER + */ + public List getFolders() { + return folders; + } + + /** + * The list of references to other versioned objects logically in this FOLDER + * @return items List of versioned items in this FOLDER + */ + public List getItems() { + return items; + } + + /** + * Equals if two folders have the same values + * + * @param o + * @return equals if true + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof Folder )) return false; + if (!super.equals(o)) return false; + + final Folder folder = (Folder) o; + return new EqualsBuilder() +// .appendSuper(super.equals(o)) + .append(folders, folder.folders) + .append(items, folder.items) + .isEquals(); + } + + /** + * Return a hash code of this folder + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(41, 97) + .appendSuper(super.hashCode()) + .append(folders) + .append(items) + .toHashCode(); + } + @Override + public String pathOfItem(Pathable item) { + // TODO Auto-generated method stub + return null; + } + + //POJO starts + Folder() { + } + + void setFolders(List folders) { + this.folders = folders; + } + + void setItems(List items) { + this.items = items; + } + //POJO ends + + @Override + public List itemsAtPath(String path) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean pathExists(String path) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean pathUnique(String path) { + // TODO Auto-generated method stub + return false; + } + + /* fields */ + private List folders; + private List items; +} + +/* + * ***** 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 Folder.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/directory/VersionedFolder.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/directory/VersionedFolder.java new file mode 100644 index 00000000..19647344 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/directory/VersionedFolder.java @@ -0,0 +1,104 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class VersionedFolder" + * keywords: "common" + * + * 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/directory/VersionedFolder.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2006-03-08 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.common.directory; + +import java.util.Set; + +import org.openehr.rm.common.changecontrol.OriginalVersion; +import org.openehr.rm.common.changecontrol.VersionedObject; +import org.openehr.rm.common.generic.AuditDetails; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.support.identification.HierObjectID; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.support.identification.ObjectVersionID; +import org.openehr.rm.support.terminology.TerminologyService; + +public class VersionedFolder extends VersionedObject { + + /** + * Constructs a VersionFolder with first Folder created locally + */ + public VersionedFolder(HierObjectID uid, ObjectRef ownerID, + DvDateTime timeCreated, ObjectVersionID versionID, Folder folder, + DvCodedText lifecycleState, AuditDetails commitAudit, + ObjectRef contribution, String signature, + TerminologyService terminologyService) { + + super(uid, ownerID, timeCreated, versionID, folder, lifecycleState, commitAudit, + contribution, signature, terminologyService); + } + + /** + * Constructs a VersionFolder with first imported Folder + */ + public VersionedFolder(HierObjectID uid, ObjectRef ownerID, + DvDateTime timeCreated, OriginalVersion item, + AuditDetails commitAudit, ObjectRef contribution, + String signature) { + + super(uid, ownerID, timeCreated, item, commitAudit, contribution, signature); + + } + + /** + * Constructs a VersionFolder with first merged Folder + */ + public VersionedFolder(HierObjectID uid, ObjectRef ownerID, + DvDateTime timeCreated, ObjectVersionID versionID, + ObjectVersionID precedingVersionID, Folder folder, DvCodedText lifecycleState, + AuditDetails commitAudit, ObjectRef contribution, + Set otherInputVersionUids, String signature, + TerminologyService terminologyService) { + + super(uid, ownerID, timeCreated, versionID, precedingVersionID, folder, lifecycleState, + commitAudit, contribution, otherInputVersionUids, signature, terminologyService); + } + + //POJO start + VersionedFolder() { + } + +} + +/* + * ***** 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 VersionedFolder.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/generic/Attestation.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/Attestation.java new file mode 100644 index 00000000..f575c858 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/Attestation.java @@ -0,0 +1,193 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Attestation" + * 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/Attestation.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.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.datatypes.encapsulated.DvMultimedia; +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.datatypes.uri.DvEHRURI; +import org.openehr.rm.support.terminology.TerminologyService; + +import java.util.*; + +/** + * Record of one or more Parties attesting something. + * Instances of this class are immutable + * + * @author Rong Chen + * @version 1.0 + */ +public class Attestation extends AuditDetails { + + /** + * Constructs an Attestation + * + * @param participations not null or empty + * @param time not null + * @param proof + * @param items not null or empty + * @param status not null and exits + * @param terminologyService not null + * @throws IllegalArgumentException + */ + @FullConstructor + public Attestation( + @Attribute(name = "systemId", required = true)String systemId, + @Attribute(name = "committer", required = true)PartyProxy committer, + @Attribute(name = "timeCommitted", required = true)DvDateTime timeCommitted, + @Attribute(name = "changeType", required = true)DvCodedText changeType, + @Attribute(name = "description")DvText description, + @Attribute(name = "terminologyService", system = true)TerminologyService terminologyService, + @Attribute(name = "attestedView")DvMultimedia attestedView, + @Attribute(name = "proof")String proof, + @Attribute(name = "items")Set items, + @Attribute(name = "reason", required = true)DvText reason, + @Attribute(name = "isPending", required = true)boolean isPending) { + super(systemId, committer, timeCommitted, changeType, description, terminologyService); + if (items != null && items.isEmpty()) { + throw new IllegalArgumentException("empty items"); + } + if (reason == null) { + throw new IllegalArgumentException("null reason"); + } + if (reason instanceof DvCodedText) { + DvCodedText reasonCText = (DvCodedText) reason; + if (!terminologyService.terminology(TerminologyService.OPENEHR) + .codesForGroupName("attestation reason", "en") + .contains(reasonCText.getDefiningCode())) { + throw new IllegalArgumentException("unkown reason: " + reason); + } + } + this.attestedView = attestedView; + this.proof = proof; + this.items = new HashSet(items); + this.reason = reason; + this.isPending = isPending; + } + + /** + * Optional visual representation of content attested + * e.g. screen image + */ + public DvMultimedia getAttestedView() { + return attestedView; + } + + /** + * Proof of attestation + * + * @return proof + */ + public String getProof() { + return proof; + } + + /** + * Items attested. Although not recommended, these may include + * fine-grained items which have been attested in some other + * system. Otherwise it is assumed to be for the entire VERSION + * with which it is associated. + * + * @return unmodifiable set of EHR_URI + */ + public Set getItems() { + return Collections.unmodifiableSet(items); + } + + /** + * Reason of this attestation. Optionally coded by the openEHR Terminology + * group "attestation reason". + * + * @return reason + */ + public DvText getReason() { + return reason; + } + + /** + * True if this attestation is outstanding; False meants it has been + * completed + * + * @return isPending + */ + public boolean isPending() { + return isPending; + } + + // POJO start + Attestation() { + } + + void setAttestedView(DvMultimedia attestedView) { + this.attestedView = attestedView; + } + + void setProof(String proof) { + this.proof = proof; + } + + void setItems(Set items) { + this.items = items; + } + + void setReason(DvText status) { + this.reason = status; + } + + void setIsPending(boolean isPending) { + this.isPending = isPending; + } + // POJO end + + /* fields */ + private DvMultimedia attestedView; + private String proof; + private Set items; + private DvText reason; + private boolean isPending; +} + +/* + * ***** 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 Attestation.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/AuditDetails.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/AuditDetails.java new file mode 100644 index 00000000..f4f27149 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/AuditDetails.java @@ -0,0 +1,228 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class AuditDetails" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/common/generic/AuditDetails.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +package org.openehr.rm.common.generic; + +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; +import org.openehr.rm.RMObject; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.datatypes.text.DvText; + +/** + * The set of attributes required to document a new version of + * something. This class can be inherited or used in a client/supplier + * relationship to provide audit trail details to another class. + * + * @author Rong Chen + * @version 1.0 + */ +public class AuditDetails extends RMObject { + + /** + * Constructs a AudiDetails + * + * @param systemId not null or empty + * @param committer not null + * @param timeCommitted not null + * @param changeType + * @param description + * @param terminologyService + * @throws IllegalArgumentException + */ + @FullConstructor + public AuditDetails( + @Attribute(name = "systemId", required = true)String systemId, + @Attribute(name = "committer", required = true)PartyProxy committer, + @Attribute(name = "timeCommitted", required = true)DvDateTime timeCommitted, + @Attribute(name = "changeType", required = true)DvCodedText changeType, + @Attribute(name = "description")DvText description, + @Attribute(name = "terminologyService", system = true)TerminologyService terminologyService) { + if (StringUtils.isEmpty(systemId)) { + throw new IllegalArgumentException("empty systemId"); + } + if (committer == null) { + throw new IllegalArgumentException("null comitter"); + } + if (timeCommitted == null) { + throw new IllegalArgumentException("null timeCommitted"); + } + if (changeType == null) { + throw new IllegalArgumentException("null changeType"); + } + if (terminologyService == null) { + throw new IllegalArgumentException("null terminologyService"); + } + if (!terminologyService.terminology(TerminologyService.OPENEHR) + .codesForGroupName("audit change type", "en") + .contains(changeType.getDefiningCode())) { + throw new IllegalArgumentException("unknown change type: " + + changeType.getDefiningCode()); + } + this.systemId = systemId; + this.committer = committer; + this.timeCommitted = timeCommitted; + this.changeType = changeType; + this.description = description; + } + + /** + * Identity of the system where the change was committed + * + * @return systemId + */ + public String getSystemId() { + return systemId; + } + + /** + * Identity of party who committed the item + * + * @return committer + */ + public PartyProxy getCommitter() { + return committer; + } + + /** + * Time of committal of the item + * + * @return time of committal + */ + public DvDateTime getTimeCommitted() { + return timeCommitted; + } + + /** + * Type of change. Coded using the openEHR Terminology + * audit change type group. + * + * @return change type + */ + public DvCodedText getChangeType() { + return changeType; + } + + /** + * Reason for committal + * + * @return description or null if unspecified + */ + public DvText getDescription() { + return description; + } + + // POJO start + protected AuditDetails() { + } + + void setSystemId(String systemId) { + this.systemId = systemId; + } + + void setChangeType(DvCodedText changeType) { + this.changeType = changeType; + } + + void setDescription(DvText description) { + this.description = description; + } + + void setCommitter(PartyProxy committer) { + this.committer = committer; + } + + void setTimeCommitted(DvDateTime timeCommitted) { + this.timeCommitted = timeCommitted; + } + // POJO end + + /** + * Equals if have same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof AuditDetails )) return false; + + final AuditDetails ad = (AuditDetails) o; + + return new EqualsBuilder() + .append(systemId, ad.systemId) + .append(committer, ad.committer) + .append(timeCommitted, ad.timeCommitted) + .append(changeType, ad.changeType) + .append(description, ad.description) + .isEquals(); + } + + /** + * Return a hashcode of this object + * + * @return hashcode + */ + public int hashCode() { + return new HashCodeBuilder(5, 23) + .append(systemId) + .append(committer) + .append(timeCommitted) + .append(changeType) + .append(description) + .toHashCode(); + } + + /* fields */ + private String systemId; + private PartyProxy committer; + private DvDateTime timeCommitted; + private DvCodedText changeType; + private DvText 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 AuditDetails.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/Participation.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/Participation.java new file mode 100644 index 00000000..602fe14a --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/Participation.java @@ -0,0 +1,218 @@ +/* + * 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 ***** + */ \ 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 new file mode 100644 index 00000000..acb80a31 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/PartyIdentified.java @@ -0,0 +1,167 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class PartyIdentified" + * keywords: "common" + * + * 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/generic/PartyIdentified.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.common.generic; + +import java.util.List; + +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; +import org.openehr.rm.datatypes.basic.DvIdentifier; +import org.openehr.rm.support.identification.PartyRef; + +/** +* Represent proxy data for an identified party. +* +* @author Yin Su Lim +* @version 1.0 +*/ +public class PartyIdentified extends PartyProxy { + + /** + * Constructs a PartyIdentified + * + *@param externalRef + *@param name + *@param identifiers + *@throws IllegalArgumentException if identifiers is empty + */ + @FullConstructor + public PartyIdentified( + @Attribute(name = "externalRef")PartyRef externalRef, + @Attribute(name = "name")String name, + @Attribute(name = "identifiers")List identifiers) { + super(externalRef); + if(externalRef == null && name == null && identifiers == null) { + throw new IllegalArgumentException("externalRef, name, identifiers all empty"); + } + if(name != null && StringUtils.isEmpty(name)) { + throw new IllegalArgumentException("empty name"); + } + if(identifiers != null && identifiers.size() == 0) { + throw new IllegalArgumentException("empty identifiers"); + } + this.name = name; + this.identifiers = identifiers; + } + + /** + * Created a PartyIdentified by given name + * + * @param name + * @return + */ + public static PartyIdentified named(String name) { + return new PartyIdentified(null, name, null); + } + + /** + * Human-readable name + * + * @return name null if not present + */ + public String getName() { + return name; + } + + /** + * One or more formal identifiers + * + * @return identifiers null if not present + */ + public List getIdentifiers() { + return identifiers; + } + + /** + * Equals if two actors has same values + * + * @param o + * @return equals if true + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof PartyIdentified )) return false; + if (!super.equals(o)) return false; + + final PartyIdentified pi = (PartyIdentified) o; + return new EqualsBuilder() + .append(name, pi.name) + .append(identifiers, pi.identifiers) + .isEquals(); + } + + /** + * Return a hash code of this actor + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(17, 83) + .appendSuper(super.hashCode()) + .append(name) + .append(identifiers) + .toHashCode(); + } + + //POJO start + PartyIdentified() {} + + void setIdentifiers(List identifiers) { + this.identifiers = identifiers; + } + + void setName(String name) { + this.name = name; + } + //POJO end + + /* fields */ + private String name; + private List identifiers; + +} + +/* + * ***** 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 PartyIdentified.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/generic/PartyProxy.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/PartyProxy.java new file mode 100644 index 00000000..b8efb7cd --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/PartyProxy.java @@ -0,0 +1,127 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class PartyProxy" + * keywords: "common" + * + * 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/generic/PartyProxy.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +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.support.identification.PartyRef; + +/** +* Abstract concept of a proxy description of a party +* +* @author Yin Su Lim +* @version 1.0 +*/ +public abstract class PartyProxy extends RMObject { + + /** + * Constructs a PartyProxy + * + * @param externalRef null if not specified + * @throws IllegalArgumentException if name null or archetypeNodeId null + * or links not null and empty + */ + @FullConstructor + public PartyProxy(@Attribute(name = "externalRef") PartyRef externalRef) { // need this constructor public for reflection to work properly within the archetype validator + this.externalRef = externalRef; + } + + /** + * Reference to more detailed demographic or identification info for this party + * + * @return externalRef + */ + public PartyRef getExternalRef() { + return externalRef; + } + + /** + * Equals if two actors has same values + * + * @param o + * @return equals if true + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof PartyProxy)) { + return false; + } + + final PartyProxy pp = (PartyProxy) o; + return new EqualsBuilder() + .append(externalRef, pp.externalRef) + .isEquals(); + } + + /** + * Return a hash code of this actor + * + * @return hash code + */ + @Override + public int hashCode() { + return new HashCodeBuilder(3, 23) + .append(externalRef) + .toHashCode(); + } + + //POJO + protected PartyProxy() {} + + void setExternalRef(PartyRef externalRef) { + this.externalRef = externalRef; + } + //POJO end + + /* fields */ + private PartyRef externalRef; + +} + +/* + * ***** 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 PartyProxy.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/generic/PartyRelated.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/PartyRelated.java new file mode 100644 index 00000000..8b9500bc --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/PartyRelated.java @@ -0,0 +1,145 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class PartyRelated" + * 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/PartyRelated.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.common.generic; + +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.support.identification.PartyRef; +import org.openehr.rm.datatypes.basic.DvIdentifier; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * Party and relationship of the party. Immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class PartyRelated extends PartyIdentified { + + /** + * Construts a RelatedParty by party and relationsihp + * + * @param party + * @param relationship + * @param terminologyService not null + * @throws IllegalArgumentException if relationship invalid + */ + @FullConstructor + public PartyRelated( + @Attribute(name = "externalRef")PartyRef externalRef, + @Attribute(name = "name")String name, + @Attribute(name = "identifiers")List identifiers, + @Attribute(name = "relationship", required = true)DvCodedText relationship, + @Attribute(name = "terminologyService")TerminologyService terminologyService) { + super(externalRef, name, identifiers); + if (relationship == null) { + throw new IllegalArgumentException("null relationship"); + } + if (!terminologyService.terminology(TerminologyService.OPENEHR) + .codesForGroupName("related party relationship", "en") + .contains(relationship.getDefiningCode())) { + throw new IllegalArgumentException( + "unkown relationship: " + relationship); + } + this.relationship = relationship; + } + + /** + * Relationship of subject of this ENTRY to the subject of the + * record. May be coded. If it is the patient, coded as "self". + * + * @return relationship + */ + public DvCodedText getRelationship() { + return relationship; + } + + /** + * Equals if two has same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof PartyRelated )) return false; + if (!super.equals(o)) return false; + + final PartyRelated r = (PartyRelated) o; + + return new EqualsBuilder() + .append(relationship, r.relationship) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(13, 59) + .appendSuper(super.hashCode()) + .append(relationship) + .toHashCode(); + } + + // POJO start + PartyRelated() { + } + + void setRelationship(DvCodedText relationship) { + this.relationship = relationship; + } + // POJO end + + /* fields */ + private DvCodedText relationship; +} + +/* + * ***** 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 PartyRelated.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 ***** + */ 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 new file mode 100644 index 00000000..6c195e34 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/PartySelf.java @@ -0,0 +1,70 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class PartySelf" + * keywords: "common" + * + * 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/generic/PartySelf.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.common.generic; + +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.support.identification.PartyRef; + +public final class PartySelf extends PartyProxy { + + /** + * Constructs a PartySelf + * + *@param externalRef null if unspecified + */ + @FullConstructor + public PartySelf( + @Attribute(name = "externalRef") PartyRef externalRef) { + super(externalRef); + } + + /** + * Creates a partySelf without an externalRef + */ + public PartySelf() { + this(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 PartySelf.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-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 new file mode 100644 index 00000000..f5dfad0c --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/RevisionHistory.java @@ -0,0 +1,147 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class RevisionHistory" + * keywords: "common" + * + * 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/generic/RevisionHistory.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.common.generic; + +import java.util.List; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.RMObject; + +/** + * The notion of a revision history of audit items, each associated with the version + * for which which that audit was committed. Instances of this class are + * immutable + * + * @author Yin Su Lim + * @version 1.0 + */ +public final class RevisionHistory extends RMObject { + + /** + * Constructs a RevisionHistory + * + * @param items not null + * @throws IllegalArgumentException if items null or empty + */ + @FullConstructor + public RevisionHistory(List items) { + if (items == null || items.size() == 0) { + throw new IllegalArgumentException("empty items"); + } + this.items = items; + } + + /** + * All the history items in this history. The list + * is in most-recent-first order + * + * @param items + */ + public List getItems() { + return items; + } + + /** + * The version id of the most recent item, as a String + * + * @return versionID + */ + public String mostRecentVersionId() { + return items.get(items.size()-1).getVersionId().getValue(); + } + + /** + * The commit date/time of the most recent item, as a String + * + * @return version time + */ + public String mostRecentVersionTime() { + RevisionHistoryItem lastItem = items.get(items.size()-1); + int auditSize = lastItem.getAudits().size(); + return lastItem.getAudits().get(auditSize - 1).getTimeCommitted().toString(); + } + + /** + * Equals if have same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof RevisionHistory )) return false; + + final RevisionHistory rh = (RevisionHistory) o; + + return new EqualsBuilder() + .append(items, rh.items) + .isEquals(); + } + + /** + * Hashcode of this object + * + * @return hashcode + */ + public int hashCode() { + return new HashCodeBuilder(13, 41) + .append(items) + .toHashCode(); + } + + //POJO start + RevisionHistory() { + } + + void setItems(List items) { + this.items = items; + } + //POJO end + + /* fields */ + private List items; +} + +/* + * ***** 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 RevisionHistory.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/generic/RevisionHistoryItem.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/RevisionHistoryItem.java new file mode 100644 index 00000000..5ab6dfef --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/generic/RevisionHistoryItem.java @@ -0,0 +1,145 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class RevisionHistoryItem" + * keywords: "common" + * + * 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/generic/RevisionHistoryItem.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.common.generic; + +import java.util.List; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.RMObject; +import org.openehr.rm.support.identification.ObjectVersionID; + +/** + * Represent an entry in revision history + * + * @author Yin Su Lim + * @version 1.0 + */ +public final class RevisionHistoryItem extends RMObject { + + /** + * Constructs a RevisionHistoryItem + * + * @param audits not null + * @param versionId not null + * @throws IllegalArgumentException if audits null or empty, versionId null + */ + @FullConstructor + public RevisionHistoryItem(List audits, ObjectVersionID versionID) { + if (audits == null || audits.size() == 0) { + throw new IllegalArgumentException("empty audits"); + } + if (versionID == null) { + throw new IllegalArgumentException("null versionId"); + } + this.audits = audits; + this.versionId = versionID; + } + + /** + * The audits for this revision. There will always be at least one commit audit + * + * @return audits + */ + public List getAudits() { + return audits; + } + + /** + * Version identifier for this revision + * + * @return versionId + */ + public ObjectVersionID getVersionId() { + return versionId; + } + + /** + * Equals if two has same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof RevisionHistoryItem )) return false; + + final RevisionHistoryItem rhi = (RevisionHistoryItem) o; + + return new EqualsBuilder() + .append(audits, rhi.audits) + .append(versionId, rhi.versionId) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(3, 97) + .append(audits) + .append(versionId) + .toHashCode(); + } + //POJO start + RevisionHistoryItem() { + } + + void setAudits(List audits) { + this.audits = audits; + } + + void setVersionId(ObjectVersionID versionID) { + this.versionId = versionID; + } + //POJO end + + /* fields */ + private List audits; + private ObjectVersionID versionId; +} + +/* + * ***** 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 RevisionHistoryItem.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/AuthoredResource.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/resource/AuthoredResource.java new file mode 100644 index 00000000..3c462733 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/resource/AuthoredResource.java @@ -0,0 +1,277 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class AuthoredResource" + * 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/AuthoredResource.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.util.*; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.RMObject; +import org.openehr.rm.common.generic.RevisionHistory; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.terminology.OpenEHRCodeSetIdentifiers; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * Abstract idea of an online resource created by a human author + * + * @author Yin Su Lim + * @version 1.0 + */ +public abstract class AuthoredResource extends RMObject { + + /** + * Construct an AuthoredResource + * + * @param originalLanguage + * @param translations + * @param description + * @param revisionHistory + * @param isControlled + */ + public AuthoredResource(CodePhrase originalLanguage, + Map translations, + ResourceDescription description, RevisionHistory revisionHistory, + boolean isControlled, TerminologyService terminologyService) { + if (originalLanguage == null) { + throw new IllegalArgumentException("null originalLanguage"); + } + if (translations != null) { + if (translations.isEmpty()) { + throw new IllegalArgumentException("empty translations"); + } + if (translations.containsKey(originalLanguage.getCodeString())) { + throw new IllegalArgumentException( + "original language in translations"); + } + } + + // TODO + // if (terminologyService == null) { + // throw new IllegalArgumentException("null terminology service"); + // } + if (terminologyService != null + && !terminologyService.codeSetForId( + OpenEHRCodeSetIdentifiers.LANGUAGES).hasCode(originalLanguage)) { + throw new IllegalArgumentException("unknown original language " + + originalLanguage); + } + if (isControlled == (revisionHistory == null)) { + throw new IllegalArgumentException( + "breach of revision history validity"); + } + this.originalLanguage = originalLanguage; + this.translations = translations; + setDescription(description); + this.revisionHistory = revisionHistory; + this.isControlled = isControlled; + } + + /** + * Description and lifecycle information of the resource + * + * @return description + */ + public ResourceDescription getDescription() { + return description; + } + + /** + * True if this resource is under any kind of change control, + * in which case revision history is created + * + * @return true if under change control + */ + public boolean isControlled() { + return isControlled; + } + + /** + * Language in which this resource was initially authored. + * + * @return originalLanguage + */ + public CodePhrase getOriginalLanguage() { + return originalLanguage; + } + + /** + * The revision history of the resource. Only required + * if isControlled is true. + * + * @return revisionHistory + */ + public RevisionHistory getRevisionHistory() { + return revisionHistory; + } + + /** + * List of details for each natural translation made of this + * resource, keyed by language. + * + * @return translations + */ + public Map getTranslations() { + return translations; + } + + /** + * Current revision.... + *TODO check the spec... + * @return + */ + public String currentRevision() { + + if (isControlled) { + return revisionHistory.mostRecentVersionId(); + } else { + return "uncontrolled"; + } + } + + /** + * Total list of languages available in this resource, + * derived from originalLanguage and translations + * + *@return set of languages available + */ + public Set languagesAvailable() { + Set languages = null; + if (translations != null) { //TODO: && translations.size != 0? + languages = new HashSet(translations.keySet()); + } else { + languages = new HashSet(); + } + languages.add(originalLanguage.getCodeString()); + return languages; + } + + /** + * Equals if two authored resource have same values + * + * @param o + * @return equals if true + */ + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof AuthoredResource)) + return false; + + final AuthoredResource ar = (AuthoredResource) o; + return new EqualsBuilder().append(description, ar.description).append( + originalLanguage, ar.originalLanguage).append(translations, + ar.translations).append(revisionHistory, ar.revisionHistory) + .append(isControlled, ar.isControlled).isEquals(); + } + + /** + * Return a hash code of this authored resource + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(19, 43).append(description).append( + originalLanguage).append(translations).append(revisionHistory) + .append(isControlled).toHashCode(); + } + + //POJO start + AuthoredResource() { + } + + void setDescription(ResourceDescription description) + throws IllegalArgumentException { + if (description != null && translations != null) { + //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())) { + throw new IllegalArgumentException( + "the language of description details not in translations"); + } + } + } + } + this.description = description; + if (description != null && description.getParentResource() != this) { + description.setParentResource(this); + } + } + + void setControlled(boolean isControlled) { + this.isControlled = isControlled; + } + + void setOriginalLanguage(CodePhrase originalLanguage) { + this.originalLanguage = originalLanguage; + } + + void setRevisionHistory(RevisionHistory revisionHistory) { + this.revisionHistory = revisionHistory; + } + + void setTranslations(Map translations) { + this.translations = translations; + } + + //POJO end + + /* fields */ + private CodePhrase originalLanguage; + + private Map translations; + + private ResourceDescription description; + + private RevisionHistory revisionHistory; + + private boolean isControlled; + +} + +/* + * ***** 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 AuthoredResource.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/ResourceDescription.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/resource/ResourceDescription.java new file mode 100644 index 00000000..0a58f669 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/resource/ResourceDescription.java @@ -0,0 +1,301 @@ +/* + * 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 ***** + */ \ 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 new file mode 100644 index 00000000..ec335d56 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/resource/ResourceDescriptionItem.java @@ -0,0 +1,312 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ResourceDescriptionItem" + * 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/common/resource/ResourceDescriptionItem.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.util.Map; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.openehr.rm.RMObject; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.terminology.OpenEHRCodeSetIdentifiers; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * Language specific detail of resource description. When a resource is + * translated for use in another language environment, each + * ResourceDescriptionItem needs to be copied and trnaslated into the new + * language + * + * @author Yin Su Lim + * @version 1.0 + */ +public class ResourceDescriptionItem extends RMObject { + + /** + * Construct ResourceDescriptionItem + */ + public ResourceDescriptionItem( CodePhrase language, String purpose, + List keywords, String use, String misuse, String copyright, + Map originalResourceUri, Map otherDetails, + TerminologyService terminologyService) { + if (language == null) { + //throw new IllegalArgumentException("null language"); + System.out.println("WARNING: Archetype parsed that has wrong language handling...language set to ISO_639-1::en"); + language = new CodePhrase("ISO_639-1","en"); + } + if (StringUtils.isEmpty(purpose)) { + // throw new IllegalArgumentException("null or empty purpose"); + System.out.println("WARNING: Archetype parsed that has null or empty purpose..."); + } + if (use != null && StringUtils.isEmpty(use)) { + throw new IllegalArgumentException("empty use"); + } + if (misuse != null && StringUtils.isEmpty(misuse)) { + throw new IllegalArgumentException("empty misuse"); + } + if (copyright != null && StringUtils.isEmpty(copyright)) { + throw new IllegalArgumentException("empty copyright"); + } + if (terminologyService == null) { + throw new IllegalArgumentException("null terminologyService"); + } + if (!terminologyService.codeSetForId( + OpenEHRCodeSetIdentifiers.LANGUAGES).hasCode(language)) { + throw new IllegalArgumentException("unknown language:" + language); + } + this.language = language; + this.purpose = purpose; + this.keywords = keywords; + this.use = use; + this.misuse = misuse; + this.copyright = copyright; + this.originalResourceUri = originalResourceUri; + this.otherDetails = otherDetails; + } + + public ResourceDescriptionItem(CodePhrase language, String purpose, + TerminologyService terminologyService) { + this(language, purpose, null, null, null, null, null, null, terminologyService); + } + + /** + * Optional copyright statement for the resource as a knowledge resource. + * + * @return copyright + */ + public String getCopyright() { + return copyright; + } + + /** + * Keywords which characterise this resource, used e.g. for indexing + * and searching. + * + * @return keywords + */ + public List getKeywords() { + return keywords; + } + + /** + * The localised language in which the items in this description item + * are written. Coded frolm openEhr CodeSet "languages" + * + * @return language + */ + public CodePhrase getLanguage() { + return language; + } + + /** + * Description of any misuses of the resource, i.e. contexts in + * which it should not be used. + * + * @return misuse + */ + public String getMisuse() { + return misuse; + } + + /** + * URIs of original clinical document(s) or description of which + * resource is a fomalisation, in the language of this description + * item; keyed by meaning. + * + * @return originalResourceUri + */ + public Map getOriginalResourceUri() { + return originalResourceUri; + } + + /** + * Additional language-sensitive resource meta-data, + * as a list of name/value pairs + * + * @return otherDetails + */ + public Map getOtherDetails() { + return otherDetails; + } + + /** + * Purpose of the resource + * + * @return purpose + */ + public String getPurpose() { + return purpose; + } + + /** + * Description of the uses of the resource, i.e. contexts + * in which it could be used. + * + * @return use + */ + public String getUse() { + return use; + } + + //POJO start + ResourceDescriptionItem() { + } + + void setCopyright(String copyright) { + this.copyright = copyright; + } + void setKeywords(List keywords) { + this.keywords = keywords; + } + void setLanguage(CodePhrase language) { + this.language = language; + } + void setMisuse(String misuse) { + this.misuse = misuse; + } + void setOriginalResourceUri(Map originalResourceUri) { + this.originalResourceUri = originalResourceUri; + } + void setOtherDetails(Map otherDetails) { + this.otherDetails = otherDetails; + } + void setPurpose(String purpose) { + this.purpose = purpose; + } + void setUse(String use) { + this.use = use; + } + //POJO end + + /* fields */ + private CodePhrase language; + private String purpose; + private List keywords; + private String use; + private String misuse; + private String copyright; + private Map originalResourceUri; + private Map otherDetails; + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((copyright == null) ? 0 : copyright.hashCode()); + result = prime * result + + ((keywords == null) ? 0 : keywords.hashCode()); + result = prime * result + + ((language == null) ? 0 : language.hashCode()); + result = prime * result + ((misuse == null) ? 0 : misuse.hashCode()); + result = prime + * result + + ((originalResourceUri == null) ? 0 : originalResourceUri + .hashCode()); + result = prime * result + + ((otherDetails == null) ? 0 : otherDetails.hashCode()); + result = prime * result + ((purpose == null) ? 0 : purpose.hashCode()); + result = prime * result + ((use == null) ? 0 : use.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; + ResourceDescriptionItem other = (ResourceDescriptionItem) obj; + if (copyright == null) { + if (other.copyright != null) + return false; + } else if (!copyright.equals(other.copyright)) + return false; + if (keywords == null) { + if (other.keywords != null) + return false; + } else if (!keywords.equals(other.keywords)) + return false; + if (language == null) { + if (other.language != null) + return false; + } else if (!language.equals(other.language)) + return false; + if (misuse == null) { + if (other.misuse != null) + return false; + } else if (!misuse.equals(other.misuse)) + return false; + if (originalResourceUri == null) { + if (other.originalResourceUri != null) + return false; + } else if (!originalResourceUri.equals(other.originalResourceUri)) + return false; + if (otherDetails == null) { + if (other.otherDetails != null) + return false; + } else if (!otherDetails.equals(other.otherDetails)) + return false; + if (purpose == null) { + if (other.purpose != null) + return false; + } else if (!purpose.equals(other.purpose)) + return false; + if (use == null) { + if (other.use != null) + return false; + } else if (!use.equals(other.use)) + 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 ResourceDescriptionItem.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/TranslationDetails.java b/openehr-rm-core/src/main/java/org/openehr/rm/common/resource/TranslationDetails.java new file mode 100644 index 00000000..70e653e6 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/common/resource/TranslationDetails.java @@ -0,0 +1,189 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TranslationDetails" + * 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/TranslationDetails.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.util.Map; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.RMObject; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.terminology.OpenEHRCodeSetIdentifiers; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * Class providing details of a natural language translation + * + * @author Yin Su Lim + * @version 1.0 + */ +public class TranslationDetails extends RMObject { + + /** + * Construct a TranslationDetails + * + * @param language + * @param author + * @param accreditation + * @param otherDetails + */ + public TranslationDetails(CodePhrase language, Map author, + String accreditation, Map otherDetails, + TerminologyService terminologyService) { + if (language == null) { + throw new IllegalArgumentException("null language"); + } + if (author == null) { + throw new IllegalArgumentException("null author"); + } + if (!terminologyService.codeSetForId( + OpenEHRCodeSetIdentifiers.LANGUAGES).hasCode(language)) { + throw new IllegalArgumentException("unknown original language " + + language); + } + + this.language = language; + this.author = author; + this.accreditation = accreditation; + this.otherDetails = otherDetails; + } + + /** + * Accreditation of translator, usuallly a national translator's + * association id. + * + * @return accreditation + */ + public String getAccreditation() { + return accreditation; + } + + /** + * Translator name and other demographic details + * + * @return author + */ + public Map getAuthor() { + return author; + } + + /** + * Language of translation + * + * @return language + */ + public CodePhrase getLanguage() { + return language; + } + + /** + * Any other meta-data + * + * @return otherDetails + */ + public Map getOtherDetails() { + return otherDetails; + } + + /** + * Equals if two translation details has same values + * + * @param o + * @return equals if true + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof TranslationDetails )) return false; + + final TranslationDetails td = (TranslationDetails) o; + return new EqualsBuilder() + .append(language, td.language) + .append(author, td.author) + .append(accreditation, td.accreditation) + .append(otherDetails, td.otherDetails) + .isEquals(); + } + + /** + * Return a hash code of this translationDetails + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(19, 37) + .append(language) + .append(author) + .append(accreditation) + .append(otherDetails) + .toHashCode(); + } + + //POJO start + TranslationDetails() { + } + + void setAccreditation(String accreditation) { + this.accreditation = accreditation; + } + + void setAuthor(Map author) { + this.author = author; + } + + void setLanguage(CodePhrase language) { + this.language = language; + } + + void setOtherDetails(Map otherDetails) { + this.otherDetails = otherDetails; + } + //POJO end + + /* fields */ + private CodePhrase language; + private Map author; + private String accreditation; + private Map otherDetails; +} + +/* + * ***** 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 TranslationDetails.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/datastructure/DataStructure.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/DataStructure.java new file mode 100644 index 00000000..adfda42e --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/DataStructure.java @@ -0,0 +1,115 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DataStructure" + * keywords: "datastructure" + * + * 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/datastructure/DataStructure.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datastructure; + +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.support.identification.UIDBasedID; +import org.openehr.rm.datastructure.itemstructure.representation.Item; +import org.openehr.rm.datatypes.text.DvText; + +import java.util.Set; + +/** + * Abstract parent class of all data structure types + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class DataStructure extends Locatable { + + /** + * Construct a DataStructure + * + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + */ + protected DataStructure(UIDBasedID uid, String archetypeNodeId, DvText name, + Archetyped archetypeDetails, FeederAudit feederAudit, + Set links, Pathable parent) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, + links, parent); + } + + /** + * Constructs a Locatable node by archetypeNodeId and name + * + * @param archetypeNodeId + * @param name + * @throws IllegalArgumentException if archetypeNodeId or name null + */ + protected DataStructure(String archetypeNodeId, DvText name) { + super(archetypeNodeId, name); + } + + /** + * Returns a hierarchical equivalent of the physical representation + * of each subtype, compatible with CEN EN 13606 structures. + * + * @return item + */ + public abstract Item asHierarchy(); + + /** + * Path that represents whole node + * + * @return path for whole node + */ + public String whole() { + return PATH_SEPARATOR + getName().getValue(); + } + + // POJO start + protected DataStructure() { + } + // POJO end +} + +/* + * ***** 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 DataStructure.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/datastructure/history/Event.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/history/Event.java new file mode 100644 index 00000000..f24dc1cc --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/history/Event.java @@ -0,0 +1,252 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Event" + * keywords: "datastructure" + * + * 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/datastructure/history/Event.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datastructure.history; + +import java.util.Set; + +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.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.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.quantity.datetime.DvDuration; + +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.identification.UIDBasedID; + +/** + * Defines the abstract notion of a single event in a series. This class is + * generic, allowing types to be generated which are locked to a particular + * spatial types, such as EVENT Subtypes express point or interval + * data. + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class Event extends Locatable { + + /** + * Constructs an Event + * + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @param parent null if unspecified + * @param time not null + * @param data not null + * @param state + * @throws IllegalArgumentException if time, data or parent null + */ + @FullConstructor public Event( + @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") History parent, + @Attribute(name = "time", required = true) DvDateTime time, + @Attribute(name = "data", required = true) T data, + @Attribute(name = "state") ItemStructure state) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, parent); + if (time == null) { + throw new IllegalArgumentException("null time"); + } + if (data == null) { + throw new IllegalArgumentException("null data"); + } + //this.parent = parent; + this.time = time; + this.data = data; + this.state = state; + } + + /** + * The data of this event + * + * @return data + */ + public T getData() { + return data; + } + + /** + * Optional state data for this event + * + * @return state + */ + public ItemStructure getState() { + return state; + } + + /** + * Time of this event. If the width is non-zero, + * it is the time point of the trailing edge of + * the event. + * + * @return time + */ + public DvDateTime getTime() { + return time; + } + + /** + * Redefinition of LOCATABLE.parent to be of type + * History + * + * @return parent null if not known + */ + public History getParent() { + return (History) super.getParent(); + } + + /** + * Offset of this event from origin + * + * @return offset = time - parent.origin + */ + public DvDuration offset() { + return DvDuration.getDifference(getParent().getOrigin(), time); + } + + /** + * To assign parent object. This function can only be called + * once for the lifetime of an Event. Once set, the parent + * cannot be modified. + * This method does not include this object into the events + * list of the parent. To make sure the bi-directional relationships + * between History and Event work properly, try create a list of Event + * with null parent, then when the list of Event is assigned to History, + * this method will be called to complete the links. + * + * @param history + * @throws IllegalArgumentException if the given history object does not contain + * a copy of this Event object, or if this.parent is not null + */ + void assignParent(History parent) { + if (getParent() == null) { + super.setParent(parent); + + } else { + //TODO: throw or not throw? + throw new IllegalArgumentException("parent object existing"); + } + } + + /** + * String The path to an item relative to the root of this + * archetyped structure. + * + * @param item + * @return string path + */ + public String pathOfItem(Pathable item) { + return null; // todo: implement this method + } + + /** + * Two events are equal if both have the same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof Event )) return false; + + final Event event = (Event) o; + + return new EqualsBuilder() + .append(time, event.time) + .append(data, event.data) + .append(state, event.state) + .isEquals(); + } + + /** + * Return a hash code of this event + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(13, 41) + .append(time) + .append(data) + .append(state) + .toHashCode(); + } + + // POJO start + Event() { + } + + void setData(T data) { + this.data = data; + } + + void setState(ItemStructure state) { + this.state = state; + } + + void setTime(DvDateTime time) { + this.time = time; + } + + // POJO end + + /* fields */ + private DvDateTime time; + private T data; + private ItemStructure state; +} + +/* + * ***** 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 Event.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-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 new file mode 100644 index 00000000..e3cf039d --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/history/History.java @@ -0,0 +1,318 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class History" + * keywords: "datastructure" + * + * 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/datastructure/history/History.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datastructure.history; + +import java.util.List; +import java.util.Set; + +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.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.datastructure.DataStructure; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datastructure.itemstructure.representation.Item; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.quantity.datetime.DvDuration; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.identification.UIDBasedID; + +/** + * Root object of a linear history, i.e. time series structure. For a periodic + * series of events, period will be set, and the time of each Event in the + * History must correspond; i.e. the EVENT.offset must be a multiple of period + * for each Event. Missing events in a period History are however allowed. + * + * @author Rong Chen + * @version 1.0 + */ +public class History extends DataStructure { + + /** + * Construct a DataStructure + * + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @throws IllegalArgumentException if origin null + */ + @FullConstructor + public History(@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 = "origin", required=true) DvDateTime origin, + @Attribute(name = "events") List> events, + @Attribute(name = "period") DvDuration period, + @Attribute(name = "duration") DvDuration duration, + @Attribute(name = "summary") ItemStructure summary){ + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, + links, parent); + if (origin == null) { + throw new IllegalArgumentException("null origin"); + } + if (events != null && events.size() == 0) { + throw new IllegalArgumentException("empty events"); + } + if (events == null && summary == null) { + throw new IllegalArgumentException("null events and summary"); + } + this.origin = origin; + setEvents(events); + this.period = period; + this.duration = duration; + this.summary = summary; + } + + /** + * Convenient constructor + * + * @param archetypeNodeId + * @param name + * @param origin + * @param events + */ + public History(String archetypeNodeId, DvText name, DvDateTime origin, + List> events) { + this(null, archetypeNodeId, name, null, null, null, null, origin, + events, null, null, null); + } + + /** + * Convenient constructor + * + * @param archetypeNodeId + * @param name + * @param origin + * @param events + */ + public History(String archetypeNodeId, String name, DvDateTime origin, + List> events) { + this(archetypeNodeId, new DvText(name), origin, events); + } + + /** + * Time origin of this event history. The first event is not + * necessarily at the origin point. + * + * @return origin of this event history + */ + public DvDateTime getOrigin() { + return origin; + } + + /** + * The events in the series + * + * @return events + */ + public List> getEvents() { + return events; + } + + /** + * Period between samples in this segment if periodic + * + * @return period + */ + public DvDuration getPeriod() { + return period; + } + + /** + * Duration of the entire History; either corresponds + * to the duration of all the events, and/or the + * duration represented by the summary, if exists + * + * @return duration of History + */ + public DvDuration getDuration() { + return duration; + } + + /** + * Optional summary data expressing text/image which + * summarises entire History + * + * @return summary of entire History + */ + public ItemStructure getSummary() { + return summary; + } + + /** + * Indicates whether history is periodic + * + * @return true if period not null + */ + public boolean isPeriodic() { + return period != null; + } + + @Override + public String pathOfItem(Pathable item) { + throw new org.apache.commons.lang.NotImplementedException(); //TODO: implement + } + + /** + * Two History objects equal if both has same values + * + * @param o + * @return true if equals + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof History )) { + return false; + } + if (!super.equals(o)) { + return false; + } + + final History history = (History) o; + + return new EqualsBuilder() + .append(origin, history.origin) + .append(events, history.events) + .append(period, history.period) + .append(duration, history.duration) + .append(summary, history.summary) + .isEquals(); + } + + /** + * Return a hash code of this History + * + * @return hash code + */ + @Override + public int hashCode() { + return new HashCodeBuilder(43, 53) + .appendSuper(super.hashCode()) + .append(origin) + .append(events) + .append(period) + .append(duration) + .append(summary) + .toHashCode(); + } + + /* token used in query path */ + public static final String ORIGIN_IS = "origin="; + + /* fields */ + private DvDateTime origin; + private List > events; + private DvDuration period; + private DvDuration duration; + private ItemStructure summary; + + // POJO start + protected History() { + } + + void setEvents(List> events) { + if (events!= null) { + for(Event event : events) { + event.assignParent(this); + } + this.events = events; + } + } + + void setPeriod(DvDuration period) { + this.period = period; + } + + void setOrigin(DvDateTime origin) { + this.origin = origin; + } + + void setDuration(DvDuration duration) { + this.duration = duration; + } + + void setSummary(ItemStructure summary) { + this.summary = summary; + } + // POJO end + + @Override + public List itemsAtPath(String path) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean pathExists(String path) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean pathUnique(String path) { + // TODO Auto-generated method stub + return false; + } + + @Override + public Item asHierarchy() { + // 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 History.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-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 new file mode 100644 index 00000000..3ce02d23 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/history/IntervalEvent.java @@ -0,0 +1,198 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class IntervalEvent" + * keywords: "datastructure" + * + * 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/datastructure/history/IntervalEvent.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.datastructure.history; + +import java.util.List; +import java.util.Set; + +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.common.archetyped.*; +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.DvCodedText; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * Defines a single interval event in a series + * + * @author Yin Su Lim + * @version 1.0 + */ +public final class IntervalEvent extends Event { + + /** + * Construct an IntervalEvent + * + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @param time + * @param data + * @param state + */ + @FullConstructor + public IntervalEvent( + @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") History parent, + @Attribute(name = "time", required = true) DvDateTime time, + @Attribute(name = "data", required = true) T data, + @Attribute(name = "state") ItemStructure state, + @Attribute(name = "width", required = true) DvDuration width, + @Attribute(name = "mathFunction", required = true) DvCodedText mathFunction, + @Attribute(name = "sampleCount") int sampleCount, + @Attribute(name = "terminologyService", system=true) TerminologyService terminologyService) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, parent, + time, data, state); + if (width == null) { + throw new IllegalArgumentException("null width"); + } + if (mathFunction == null) { + throw new IllegalArgumentException("null mathFunction"); + } + if (terminologyService == null) { + throw new IllegalArgumentException("null terminologyService"); + } + if (!terminologyService.terminology(TerminologyService.OPENEHR) + .codesForGroupName("event math function", "en") + .contains(mathFunction.getDefiningCode())) { + throw new IllegalArgumentException( + "unknown mathFunction: " + mathFunction); + } + this.width = width; + this.mathFunction = mathFunction; + this.sampleCount = sampleCount; + } + + /** + * Mathematical function of the data of this event, e.g. + * "maximum", "mean" etc. Coded using openEHR Terminology group + * "event math function" + * + * @return mathFunction. + */ + public DvCodedText getMathFunction() { + return mathFunction; + } + + /** + * Optional count of original samples to which this event corresponds + * + * @return sampleCount. + */ + public int getSampleCount() { + return sampleCount; + } + + /** + * Length of the interval during which the state was true. + * Void if an instantaneous event. + * + * @return width. + */ + public DvDuration getWidth() { + return width; + } + + /** + * Start time of the interval of this event + * + *@return start time + */ + public DvDateTime intervalStartTime() { + return (DvDateTime) getTime().subtract(width); + } + + // POJO start + IntervalEvent() { + } + + void setMathFunction(DvCodedText mathFunction) { + this.mathFunction = mathFunction; + } + + void setSampleCount(int sampleCount) { + this.sampleCount = sampleCount; + } + + void setWidth(DvDuration width) { + this.width = width; + } + // POJO end + + @Override + public List itemsAtPath(String path) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean pathExists(String path) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean pathUnique(String path) { + // TODO Auto-generated method stub + return false; + } + + /* fields */ + private DvDuration width; + private DvCodedText mathFunction; + private int sampleCount; +} + +/* + * ***** 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 IntervalEvent.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/datastructure/history/PointEvent.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/history/PointEvent.java new file mode 100644 index 00000000..6a86bee8 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/history/PointEvent.java @@ -0,0 +1,136 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class PointEvent" + * keywords: "datastructure" + * + * 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/datastructure/history/PointEvent.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.datastructure.history; + +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.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.identification.UIDBasedID; + +/** + * Defines a single point event in a series + * + * @author Yin Su Lim + * @version 1.0 + */ +public final class PointEvent extends Event { + + /** + * Construct a PointEvent + * + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @param time + * @param data + * @param state + */ + @FullConstructor + public PointEvent( + @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") History parent, + @Attribute(name = "time", required = true) DvDateTime time, + @Attribute(name = "data", required = true) T data, + @Attribute(name = "state") ItemStructure state) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, + parent, time, data, state); + } + + /** + * Convenient constructor that only takes required values + */ + public PointEvent(String archetypeNodeId, DvText name, DvDateTime time, + T data) { + this(null, archetypeNodeId, name, null, null, null, null, time, data, + null); + } + + /** + * Convenient constructor that only takes required values + */ + public PointEvent(String archetypeNodeId, String name, DvDateTime time, + T data) { + this(archetypeNodeId, new DvText(name), time, data); + } + + //POJO + PointEvent() { + } + + @Override + public List itemsAtPath(String path) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean pathExists(String path) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean pathUnique(String path) { + // TODO Auto-generated method stub + return false; + } + +} + +/* + * ***** 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 PointEvent.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/datastructure/itemstructure/ItemList.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemList.java new file mode 100644 index 00000000..a774f0b0 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemList.java @@ -0,0 +1,241 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ItemList" + * keywords: "datastructure" + * + * 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/datastructure/itemstructure/ItemList.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datastructure.itemstructure; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +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.*; + +/** + * Logical list data structure, where each item has a value and can + * be referred to by a name and a positional index in the list. + * + * @author Rong Chen + * @version 1.0 + */ +public final class ItemList extends ItemStructure { + + /** + * Constructs an ItemList with a list of items + * + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @param items null if unspecified + */ + @FullConstructor + public ItemList(@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 = "items") List items) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, + links, parent); + this.items = items; + } + + /** + * Construct a ItemList with list of elements + * + * @param archetypeNodeId + * @param name + * @param items + */ + public ItemList(String archetypeNodeId, DvText name, List items) { + this(null, archetypeNodeId, name, null, null, null, null, items); + } + + /** + * Construct a ItemList with list of elements + * + * @param archetypeNodeId + * @param name as string + * @param items + */ + public ItemList(String archetypeNodeId, String name, List items) { + this(archetypeNodeId, new DvText(name), items); + } + + /** + * Returns the count of all items + * + * @return item count + */ + public int itemCount() { + return items.size(); + } + + /** + * Retrieves all items + * + * @return List of Element + */ + public List getItems() { + return items; + } + + /** + * Retrieves the names of all items as a list + * + * @return list of names + */ + public List names() { + List names = new ArrayList(); + for (Element element : items) { + names.add(element.getName()); + } + return names; + } + + /** + * Retrieves the item with given name + * + * @param name + * @return null if item of given name not found + * @throws IllegalArgumentException if name is null or empty + */ + public Element namedItem(String name) { + if (StringUtils.isEmpty(name)) { + throw new IllegalArgumentException("empty name"); + } + for (Element element : items) { + if (name.equals(element.getName().getValue())) { + return element; + } + } + return null; + } + + /** + * Retrieve item at specified position + * + * @param index starts with 0 + * @return element at given position + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index >= size()). + */ + public Element ithItem(int index) { + return getItems().get(index); + } + + /** + * Return the path to an item relative to the root of this + * archetyped structure. + * + * @param item + * @return path of given item + */ + 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 List itemsAtPath(String path) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean pathExists(String path) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean pathUnique(String path) { + // TODO Auto-generated method stub + return false; + } + + @Override + public Item asHierarchy() { + // TODO Auto-generated method stub + return null; + } + + /* calculated field */ + private List items; + + // POJO start + ItemList() { + } + // POJO end +} + +/* + * ***** 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 ItemList.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-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 new file mode 100644 index 00000000..44eb76ab --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemSingle.java @@ -0,0 +1,171 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ItemSingle" + * keywords: "datastructure" + * + * 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/datastructure/itemstructure/ItemSingle.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datastructure.itemstructure; + +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.*; + +/** + * Logical single value data structure. Instances of this class are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class ItemSingle extends ItemStructure { + + /** + * Construct a ItemSingle + * + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @param item not null + * @throws IllegalArgumentException if item null + */ + @FullConstructor + public ItemSingle(@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 = "item", required=true) Element item) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, + links, parent); + if(item == null) { + throw new IllegalArgumentException("item null"); + } + this.item = item; + } + + /** + * Construct a ItemSingle + * + * @param archetypeNodeId + * @param name + * @param representation + * @throws IllegalArgumentException if representation null + */ + public ItemSingle(String archetypeNodeId, DvText name, Element item) { + this(null, archetypeNodeId, name, null, null, null, null, item); + } + + /** + * Construct a ItemSingle + * + * @param archetypeNodeId + * @param name + * @param representation + * @throws IllegalArgumentException if representation null + */ + public ItemSingle(String archetypeNodeId, String name, Element item) { + this(archetypeNodeId, new DvText(name), item); + } + + /** + * Retrieves the item. + * + * @return item + */ + public Element getItem() { + return item; + } + + /** + * Return the path to an item relative to the root of this + * archetyped structure. + * + * @param item + * @return path + */ + public String pathOfItem(Pathable item) { + return null; // todo: implement this method + } + + @Override + public List itemsAtPath(String path) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean pathExists(String path) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean pathUnique(String path) { + // TODO Auto-generated method stub + return false; + } + + // POJO start + ItemSingle() { + } + // POJO end + + @Override + public Item asHierarchy() { + // TODO Auto-generated method stub + return null; + } + + private Element item; +} + +/* + * ***** 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 ItemSingle.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-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 new file mode 100644 index 00000000..b00cb9e9 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemStructure.java @@ -0,0 +1,87 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ItemStructure" + * keywords: "datastructure" + * + * 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/datastructure/itemstructure/ItemStructure.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datastructure.itemstructure; + +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.DataStructure; +import org.openehr.rm.datatypes.text.DvText; + +import java.util.Set; + +/** + * Abstract parent class of all spatial data types. + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class ItemStructure extends DataStructure { + + /** + * Constructs a ItemStructure + * + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @param parent + */ + protected ItemStructure(UIDBasedID uid, String archetypeNodeId, DvText name, + Archetyped archetypeDetails, FeederAudit feederAudit, + Set links, Pathable parent) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, + links, parent); + } + + // POJO start + protected ItemStructure() { + } + // POJO end +} + +/* + * ***** 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 ItemStructure.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-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 new file mode 100644 index 00000000..3afa4a68 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemTable.java @@ -0,0 +1,399 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ItemTable" + * keywords: "datastructure" + * + * 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/datastructure/itemstructure/ItemTable.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datastructure.itemstructure; + +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.Pathable; +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.datastructure.itemstructure.representation.Cluster; +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.*; + +/** + * Purpose Logical table data structure, in which columns are named + * and ordered. Some columns may be designated "key" columns, + * containing key data for each row, in the manner of relational + * tables. This allows row-naming, where each row represents a body + * site, a blood antigen etc. All values in a column have the same + * data type. + *

+ * + * @author Rong Chen + * @version 1.0 + */ +public final class ItemTable extends ItemStructure { + + /** + * Construct an ItemTable + * + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @param representation Cluster of Cluster + */ + @FullConstructor + public ItemTable(@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 = "rows") List rows) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, + links, parent); + this.rows = rows; + } + + /** + * Constructs a ItemTable + * + * @param archetypeNodeId + * @param name + * @param rows null if unspecified + */ + public ItemTable(String archetypeNodeId, DvText name, List rows) { + this(null, archetypeNodeId, name, null, null, null, null, rows); + } + + /** + * Constructs a ItemTable + * + * @param archetypeNodeId + * @param name + * @param rows null if unspecified + */ + public ItemTable(String archetypeNodeId, String name, List rows) { + this(archetypeNodeId, new DvText(name), rows); + } + + /** + * Gets rows of this table + * + * @return null if unspecified + */ + public List getRows() { + return rows; + } + + /** + * Return the number of rows + * + * @return row count + */ + public int rowCount() { + return rows == null ? 0: rows.size(); + } + + /** + * Return the number of columns + * + * @return column count + */ + public int columnCount() { + if(rows == null) { + return 0; + } + Cluster firstCol = getRows().get(0); + return firstCol.getItems().size(); + } + + /** + * Returns the row names + * + * @return list of names + */ + public List rowNames() { + if(rows == null) { + return Collections.EMPTY_LIST; + } + return fetchNames(rows); + } + + /** + * Return the column names + * + * @return List of Text + */ + public List columnNames() { + if(rows == null) { + return Collections.EMPTY_LIST; + } + Cluster firstCol = (Cluster) getRows().get(0); + return fetchNames(( firstCol.getItems() )); + } + + List names = new ArrayList(); + private List fetchNames(List items) { + for (Item item : items) { + names.add(item.getName()); + } + return names; + } + + /** + * Returns the row at specified position + * + * @param index starts with 1 + * @return List of element + * @throws IndexOutOfBoundsException + */ + public Cluster ithRow(int index) { + if (index <= 0 || index > rowCount()) { + throw new IndexOutOfBoundsException("invalid index"); + } + return getRows().get(index - 1); + } + + /** + * Returns true if there is a row with given name + * + * @param name + * @return ture if has row with name + */ + public boolean hasRowWithName(String name) { + checkName(name); + if(rows == null) { + return false; + } + return hasItemWithName(getRows(), name); + } + + /** + * Boolean True if there is a column with given name + * + * @param name + * @return true if has column with name + * @throws IllegalArgumentException if name null or empty + */ + public boolean hasColumnWithName(String name) { + checkName(name); + Cluster firstRow = (Cluster) getRows().get(0); + if(rows == null) { + return false; + } + return hasItemWithName(firstRow.getItems(), name); + } + + private void checkName(String name) { + if (StringUtils.isEmpty(name)) { + throw new IllegalArgumentException("null or empty name"); + } + } + + // return index of element with given name + private int indexOf(List items, String name) { + for (int i = 0, j = items.size(); i < j; i++) { + Item item = (Item) items.get(i); + if (item.getName().getValue().equals(name)) { + return i; + } + } + return -1; + } + + private boolean hasItemWithName(List items, String name) { + return indexOf(items, name) >= 0; + } + + /** + * Retrieves a row by given name + * + * @param name + * @return List of element + * @throws IllegalArgumentException if name null or empty + * or no row found for given name + */ + public Cluster namedRow(String name) { + checkName(name); + if(rows == null) { + return null; + } + int index = indexOf(getRows(), name); + if (index < 0) { + throw new IllegalArgumentException("unknow row name: " + name); + } + return (Cluster)getRows().get(index); + + } + + /** + * True if there is a row whose first n columns have the names + * in given keys + * + * @param keys set of string + * @return true if has row with key + * @throws IllegalArgumentException if keys null + */ + public boolean hasRowWithKey(Set keys) { + // todo: implement it (problem to understand the spec) + return false; + } + + /** + * Return the row whose first n columns have names equal to the + * values in keys + * + * @param key + * @return List of row + */ + public List rowWithKey(Set key) { + List rows = new ArrayList(); + // todo: fix it (problem to understand the spec) + return rows; + } + + /** + * Return the element at specified column and row + * + * @param column + * @param row + * @return Element found at (col, row) + * @throws IllegalArgumentException if col <= 0 or col > columnCount + * or row <= 0 or row > rowCount + */ + public Element elementAtCell(int column, int row) { + if (row <= 0 || row > rowCount()) { + throw new IllegalArgumentException("invalid row index: " + row); + } + Cluster targetRow = (Cluster) getRows().get(row - 1); + if (column <= 0 || column > targetRow.getItems().size()) { + throw new IllegalArgumentException("invalid column index: " + column); + } + return (Element) targetRow.getItems().get(column - 1); + } + + /** + * Retrieve the element at the row whose first column has the name + * colKey and row has the name rowKey + * + * @param colKey + * @param rowKey + * @return Element found by keys + * @throws IllegalArgumentException if either key null or empty + * or no row found for given keys + */ + public Element elementAtNamedCell(String rowKey, String colKey) { + if (StringUtils.isEmpty(colKey) || + StringUtils.isEmpty(rowKey)) { + throw new IllegalArgumentException("invalid keys: " + + colKey + ", " + rowKey); + } + Cluster firstRow = namedRow(rowKey); + int col = indexOf(firstRow.getItems(), colKey); + if (col < 0 ) { + throw new IllegalArgumentException( + "unknown keys: " + colKey + ", " + rowKey); + } + return (Element)firstRow.getItems().get(col); + } + + /** + * Return the path to an item relative to the root of this + * archetyped structure. + * + * @param item + * @return path of given item + */ + public String pathOfItem(Pathable item) { + return null; // todo: implement this method + } + + protected static List structureCheck(List rows) { + if(rows == null) { + return null; + } + for(Cluster row : rows) { + for(Item col : ((Cluster)row).getItems()) { + if(!(col instanceof Element)) { + throw new IllegalArgumentException("invalid col type for itemTable, Element expected"); + } + } + } + return rows; + } + + @Override + public List itemsAtPath(String path) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean pathExists(String path) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean pathUnique(String path) { + // TODO Auto-generated method stub + return false; + } + + // POJO start + ItemTable() { + } + // POJO end + + private List rows; + + @Override + public Item asHierarchy() { + // 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 ItemTable.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-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 new file mode 100644 index 00000000..0cd5d16e --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemTree.java @@ -0,0 +1,225 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ItemTree" + * keywords: "datastructure" + * + * 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/datastructure/itemstructure/ItemTree.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datastructure.itemstructure; + +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.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.*; + +/** + * Logical tree data structure. + * + * @author Rong Chen + * @version 1.0 + */ +public final class ItemTree extends ItemStructure { + + /** + * Constructs an ItemTree + * + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @param items null if unspecified + */ + @FullConstructor + public ItemTree(@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 = "items") List items) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, + links, parent); + this.items = items; + } + + /** + * Constructs a ItemStructure + * + * @param archetypeNodeId + * @param name + * @param items null if unspecified + */ + public ItemTree(String archetypeNodeId, DvText name, List items) { + this(null, archetypeNodeId, name, null, null, null, null, items); + } + + /** + * Constructs a ItemStructure + * + * @param archetypeNodeId + * @param name + * @param items null if unspecified + */ + public ItemTree(String archetypeNodeId, String name, List items) { + this(archetypeNodeId, new DvText(name), items); + } + + /** + * True if given path is a valid leaf path + * + * @param path + * @return ture if path is valid + * @throws IllegalArgumentException if path null or empty + */ + public boolean hasElementPath(String path) { + Object value = itemAtPath(path); + return value != null; + + } + + /** + * Return the leaf element at the path + * + * @param path + * @return element found + * @throws IllegalArgumentException if path is not valid + * or element doesn't exist at given path + */ + public Element elementAtPath(String path) { + Object node = itemAtPath(path); + if(node instanceof Element) { + return (Element) node; + } + throw new IllegalArgumentException("Invalid path: " + path); + } + + /** + * Gets the items + * + * @return null if unspecified + */ + 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(); + } + + /** + * Return a hash code of this actor + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(17, 23) + .appendSuper(super.hashCode()) + .append(items) + .toHashCode(); + } + + /** + * Return the path to an item relative to the root of this + * archetyped structure. + * + * @param item + * @return path of given item + */ + public String pathOfItem(Pathable item) { + return null; // todo: implement this method + } + + @Override + public Item asHierarchy() { + // TODO Auto-generated method stub + return null; + } + + @Override + public List itemsAtPath(String path) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean pathExists(String path) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean pathUnique(String path) { + // TODO Auto-generated method stub + return false; + } + + // POJO start + ItemTree() { + } + // POJO end + + private List items; +} + +/* + * ***** 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 ItemTree.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-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 new file mode 100644 index 00000000..2413587b --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/representation/Cluster.java @@ -0,0 +1,177 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Cluster" + * keywords: "datastructure" + * + * 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/datastructure/itemstructure/representation/Cluster.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datastructure.itemstructure.representation; + +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.datatypes.text.DvText; + +import java.util.*; + +/** + * The grouping variant of Item, which may contain further instances + * of ITEM, in an ordered list. + * + * @author Rong Chen + * @version 1.0 + */ +public final class Cluster extends Item { + + /** + * Construct a Cluster + * + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @param items + * @throws IllegalArgumentException if archetypeNodeId or name null, + * or items null or empty + */ + @FullConstructor + public Cluster(@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 = "items") List items) { + + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, + links, parent); + + if (items != null && items.isEmpty()) { //Skip items==null check to facilitate item skeleton generation + throw new IllegalArgumentException("null or empty items"); + } + if (items!=null){ + this.items = new ArrayList(items); + } + } + + /** + * Constructs a cluster list of items + * + * @param archetypeNodeId + * @param name + * @param items + * @throws IllegalArgumentException if archetypeNodeId or name null, + * or items null or empty + */ + public Cluster(String archetypeNodeId, DvText name, List items) { + this(null, archetypeNodeId, name, null, null, null, null, items); + } + + /** + * Constructs a cluster list of items + * + * @param archetypeNodeId + * @param name + * @param items + * @throws IllegalArgumentException if archetypeNodeId or name null, + * or items null or empty + */ + public Cluster(String archetypeNodeId, String name, List items) { + this(archetypeNodeId, new DvText(name), items); + } + + /** + * Ordered list of items - CLUSTER or ELEMENT objects + * - under this CLUSTER. + * + * @return items of this cluster + */ + public List getItems() { + return items; + } + + /** + * String The path to an item relative to the root of this + * archetyped structure. + * + * @param item + * @return path of given item + */ + public String pathOfItem(Pathable item) { + return null; // todo: implement this method + } + + // POJO start + protected Cluster() { + } + + void setItems(List items) { + this.items = items; + } + // POJO end + + @Override + public List itemsAtPath(String path) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean pathExists(String path) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean pathUnique(String path) { + // TODO Auto-generated method stub + return false; + } + + /* fields */ + private List items; +} + +/* + * ***** 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 Cluster.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/datastructure/itemstructure/representation/Element.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/representation/Element.java new file mode 100644 index 00000000..8f8cea6d --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/representation/Element.java @@ -0,0 +1,268 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Element" + * keywords: "datastructure" + * + * 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/datastructure/itemstructure/representation/Element.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datastructure.itemstructure.representation; + +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.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.datatypes.basic.DataValue; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.terminology.TerminologyService; + +import java.util.List; +import java.util.Set; + +/** + * The leaf variant of ITEM, to which a DATA_VALUE instance is + * attached. + * + * @author Rong Chen + * @version 1.0 + */ +public final class Element extends Item { + + /** + * Construct an Element + * + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @param value + * @param nullFlavour required if value is null + * @throws IllegalArgumentException if both value and nullFlavour + * are null + */ + @FullConstructor + public Element(@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 = "value") DataValue value, + @Attribute(name = "nullFlavour") DvCodedText nullFlavour, + @Attribute(name = "terminologyService", system=true) TerminologyService terminologyService) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, + links, parent); + if (( value == null && nullFlavour == null ) + || ( value != null && nullFlavour != null )) { + throw new IllegalArgumentException( + "null or unnecessary nullFlavour"); + } + if (value == null) { + if (terminologyService == null) { + throw new IllegalArgumentException("null terminologyService"); + } + if (!terminologyService.terminology(TerminologyService.OPENEHR) + .codesForGroupName(TerminologyService.NULL_FLAVOURS, "en") + .contains(nullFlavour.getDefiningCode())) { + throw new IllegalArgumentException( + "unknown nullFlavour: " + nullFlavour); + } + } + this.value = value; + this.nullFlavour = nullFlavour; + } + + /** + * Constructs an Element node by archetypeNodeId, name and non-null value + * + * @param archetypeNodeId + * @param name + * @param value + * @throws IllegalArgumentException if name or value null + */ + public Element(String archetypeNodeId, DvText name, DataValue value) { + this(null, archetypeNodeId, name, null, null, null, null, value, null, + null); + } + + /** + * Constructs an Element node by archetypeNodeId, name and non-null value + * + * @param archetypeNodeId + * @param name + * @param value + * @throws IllegalArgumentException if name or value null + */ + public Element(String archetypeNodeId, String name, DataValue value) { + this(archetypeNodeId, new DvText(name), value); + } + + /** + * Gets data value of this leaf + * + * @return value of this leaf + */ + public DataValue getValue() { + return value; + } + + /** + * Gets flavor of null value, like indeterminate, not asked etc + * + * @return null flavor + * @deprecated use getNullFlavour instead + */ + public DvCodedText getNullFlavor() { + return nullFlavour; + } + + /** + * Gets flavour of null value, like indeterminate, not asked etc + * + * @return null flavour + */ + public DvCodedText getNullFlavour() { + return nullFlavour; + } + + /** + * True if value logically not known, if indeterminate, + * not asked etc. + * + * @return true if value null + */ + public boolean isNull() { + return value == null; + } + + /** + * String The path to an item relative to the root of this + * archetyped structure. + * + * @param item + * @return path of given item + */ + 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; + } + Element element = (Element) obj; + return new EqualsBuilder() + .appendSuper(super.equals(obj)) + .append(value, element.value) + .append(nullFlavour, element.nullFlavour) + .isEquals(); + } + + /** + * Return a hash code of this actor + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(17, 71) + .appendSuper(super.hashCode()) + .append(value) + .append(nullFlavour) + .toHashCode(); + } + + // POJO start + Element() { + } + + public void setValue(DataValue value) { + this.value = value; + } + + /** + * @deprecated Use setNullFlavour instead + */ + public void setNullFlavor(DvCodedText nullFlavor) { + this.nullFlavour = nullFlavor; + } + + public void setNullFlavour(DvCodedText nullFlavour) { + this.nullFlavour = nullFlavour; + } + // POJO end + + @Override + public List itemsAtPath(String path) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean pathExists(String path) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean pathUnique(String path) { + // TODO Auto-generated method stub + return false; + } + + /* fields */ + private DataValue value; + private DvCodedText nullFlavour; +} + +/* + * ***** 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 Element.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2010 + * 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/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 new file mode 100644 index 00000000..4a2f4c9d --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/representation/Item.java @@ -0,0 +1,98 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Item" + * keywords: "datastructure" + * + * 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/datastructure/itemstructure/representation/Item.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datastructure.itemstructure.representation; + +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.support.identification.UIDBasedID; +import org.openehr.rm.datatypes.text.DvText; + +import java.util.Set; + +/** + * The abstract parent of CLUSTER and ELEMENT representation classes. + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class Item extends Locatable { + + /** + * Constructs an Item + * + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @throws IllegalArgumentException if archetypeNodeId, name null + */ + protected Item(UIDBasedID uid, String archetypeNodeId, DvText name, + Archetyped archetypeDetails, FeederAudit feederAudit, + Set links, Pathable parent) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, + links, parent); + } + + /** + * Constructs a Item node by archetypeNodeId and name + * + * @param archetypeNodeId + * @param name + * @throws IllegalArgumentException if archetypeNodeId or name null + */ + protected Item(String archetypeNodeId, DvText name) { + super(archetypeNodeId, name); + } + + // POJO start + protected Item() { + } + // POJO end +} + +/* + * ***** 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 Item.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/DataValue.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DataValue.java new file mode 100644 index 00000000..3d5504dd --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DataValue.java @@ -0,0 +1,155 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DataValue" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/datatypes/basic/DataValue.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datatypes.basic; + +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.*; +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 + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class DataValue extends RMObject { + + // POJO start + protected DataValue() { + } + // POJO end + + /** + * String form displayable for humans + * + * @return string presentation of this DataValue + */ + public String toString() { + return ToStringBuilder.reflectionToString(this, + ToStringStyle.MULTI_LINE_STYLE); + } + + public abstract String getReferenceModelName(); + + /** + * Serialise the value in string format. + * + * @return + */ + public abstract String serialise(); + + /** + * Parse a serialised dataValue and returns a concrete DataValue class + * + * The format is the following: + * [REFERENCE_MODEL_CLASS_NAME],[SERIALIZED FORMAT] + * + * @param value + * @return instance of DataValue + */ + public static DataValue parseValue(String value) { + if(value == null) { + throw new IllegalArgumentException("null value"); + } + + int i = value.indexOf(","); + if(i < 0 || i == value.length()) { + throw new IllegalArgumentException("wrong string format"); + } + + String rmName = value.substring(0, i); + DataValue dv = dataValueMap.get(rmName); + + if(dv == null) { + throw new IllegalArgumentException("unsupported RM class[" + rmName + "]"); + } + + String v = value.substring(i + 1).trim(); + return dv.parse(v); + } + + /** + * Parse a serialised dataValue. Implemented by subclasses. + * + * @param value + * @return instance of DataValue + */ + public DataValue parse(String value) { + throw new RuntimeException("no implementation"); + } + + private final static Map dataValueMap; + + /* + * Initiate the mapping between ReferenceModelName and concrete dataValue + */ + static { + dataValueMap = new HashMap(); + dataValueMap.put(ReferenceModelName.DV_COUNT.getName(), new DvCount(0)); + dataValueMap.put(ReferenceModelName.DV_BOOLEAN.getName(), new DvBoolean(false)); + dataValueMap.put(ReferenceModelName.DV_QUANTITY.getName(), new DvQuantity(1)); + dataValueMap.put(ReferenceModelName.DV_PROPORTION.getName(), new DvProportion(1,1,ProportionKind.FRACTION, 0)); + dataValueMap.put(ReferenceModelName.DV_TEXT.getName(), new DvText("text")); + dataValueMap.put(ReferenceModelName.DV_CODED_TEXT.getName(), new DvCodedText("text", new CodePhrase("tm", "cd"))); + 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_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")); + } + +} + +/* + * ***** 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 DataValue.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/DvBoolean.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvBoolean.java new file mode 100644 index 00000000..dabaae20 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvBoolean.java @@ -0,0 +1,190 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvBoolean" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/datatypes/basic/DvBoolean.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datatypes.basic; + +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; + +/** + * Items which are truly boolean data, such as true/false or yes/no + * answers. It's simply a wrapper around java.lang.Boolean. + * + * @author Rong Chen + * @version 1.0 + */ +public final class DvBoolean extends DataValue { + + /** + * + */ + private static final long serialVersionUID = -5827013068177253709L; + + /** + * Constructs a DvBoolean from a boolean value + * + * @param value + */ + public DvBoolean(boolean value) { + this.value = value; + } + + /** + * Constructs a DvBoolean from a string value + * + * @param value + */ + @FullConstructor public DvBoolean(@Attribute (name = "value", + required = true) String value) { + this(Boolean.TRUE.toString().equals(value)); + } + + /** + * Returns the value of this Boolean object as a boolean primitive + * + * @return boolean value + */ + public boolean getValue() { + return value; + } + + public DvBoolean parse(String value) throws IllegalArgumentException { + return valueOf(value); + } + + /** + * Returns an Boolean object holding the value of + * the specified String. String not equals to "true" will get + * false returned. + * + * @param value case insensitive + * @return instance of Boolean + */ + public static DvBoolean valueOf(String value) { + return Boolean.TRUE.toString().equals(value) ? + TRUE : FALSE; + } + + /** + * Return an instance of Boolean holding the value of + * primitive boolean value + * + * @param value + * @return instance of Boolean + */ + public static DvBoolean valueOf(boolean value) { + return value ? TRUE : FALSE; + } + + /** + * Two Boolean objects equal if both has same primitive boolean + * value + * + * @param o + * @return true if equals + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof DvBoolean )) { + return false; + } + + final DvBoolean aBoolean = (DvBoolean) o; + + if (value != aBoolean.value) { + return false; + } + + return true; + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + @Override + public int hashCode() { + return ( value ? 1 : 0 ); + } + + public String toString() { + return value ? Boolean.TRUE.toString() : Boolean.FALSE.toString(); + } + + // POJO start + private DvBoolean() { + } + + private void setValue(boolean value) { + this.value = value; + } + // POJO end + + /* fields */ + private boolean value; + + /** + * True value + */ + public static final DvBoolean TRUE = new DvBoolean(true); + + /** + * False value + */ + public static final DvBoolean FALSE = new DvBoolean(false); + + @Override + public String getReferenceModelName() { + return ReferenceModelName.DV_BOOLEAN.getName(); + } + + @Override + public String serialise() { + return getReferenceModelName() + "," + 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 DvBoolean.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/DvIdentifier.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvIdentifier.java new file mode 100644 index 00000000..6554aa60 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvIdentifier.java @@ -0,0 +1,202 @@ +/* + * 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 ***** + */ \ 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 new file mode 100644 index 00000000..df546f23 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvState.java @@ -0,0 +1,170 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvState" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/datatypes/basic/DvState.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datatypes.basic; + +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.text.DvCodedText; + +/** + * For representing state values which obey a defined state machine, + * such as a variable representing the states of an instruction or + * care process. Instances of this class are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class DvState extends DataValue { + + /** + * Constructs a state + * + * @param value + * @param terminal + * @throws IllegalArgumentException if value null + */ + @FullConstructor + public DvState(@Attribute(name = "value", required = true) DvCodedText value, + @Attribute(name = "terminal") String terminal) { + this(value, Boolean.parseBoolean(terminal)); + } + + /** + * Constructs a state + * + * @param value + * @param terminal + * @throws IllegalArgumentException if value null + */ + public DvState(DvCodedText value, boolean terminal) { + if (value == null) { + throw new IllegalArgumentException("null value"); + } + this.value = value; + this.terminal = terminal; + } + + /** + * The state name. State names are determined by a state/event + * table defined in archetypes, and coded using openEHR + * Terminology or local archetype terms, as specified by the + * archetype. + * + * @return state name + */ + public DvCodedText getValue() { + return value; + } + + /** + * Indicates whether this state is a terminal state, such as + * "aborted", "completed" etc from which no further transitions + * are possible. + * + * @return true if a terminal state + */ + public boolean isTerminal() { + return terminal; + } + + /** + * Two state equal if both has same value and terminal + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof DvState )) return false; + + final DvState state = (DvState) o; + + return new EqualsBuilder() + .append(value, state.value) + .append(terminal, state.terminal) + .isEquals(); + } + + /** + * Return a hash code of this state object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(7, 29) + .append(value) + .append(terminal) + .toHashCode(); + } + + // POJO start + DvState() { + } + + void setValue(DvCodedText value) { + this.value = value; + } + + void setTerminal(boolean terminal) { + this.terminal = terminal; + } + // POJO end + + /* fields */ + private DvCodedText value; + private boolean terminal; + @Override + public String getReferenceModelName() { + return "DV_STATE"; + } + + @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 DvState.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/ReferenceModelName.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/ReferenceModelName.java new file mode 100644 index 00000000..ac0dc98b --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/ReferenceModelName.java @@ -0,0 +1,32 @@ +package org.openehr.rm.datatypes.basic; + +public enum ReferenceModelName { + + DV_BOOLEAN("DV_BOOLEAN"), + DV_COUNT("DV_COUNT"), + DV_QUANTITY("DV_QUANTITY"), + DV_PROPORTION("DV_PROPORTION"), + DV_TEXT("DV_TEXT"), + DV_CODED_TEXT("DV_CODED_TEXT"), + DV_ORDINAL("DV_ORDINAL"), + CODE_PHRASE("CODE_PHRASE"), + DV_DATE_TIME("DV_DATE_TIME"), + DV_DATE("DV_DATE"), + DV__TIME("DV_TIME"), + DV_DURATION("DV_DURATION"); + + + private final String name; + + public String getName() { + return name; + } + + public String toString() { + return name; + } + + ReferenceModelName(String name) { + this.name = 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 new file mode 100644 index 00000000..0c48b184 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/encapsulated/DvEncapsulated.java @@ -0,0 +1,132 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvEncapsulated" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/datatypes/encapsulated/DvEncapsulated.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +package org.openehr.rm.datatypes.encapsulated; + +import org.openehr.rm.datatypes.basic.DataValue; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.terminology.OpenEHRCodeSetIdentifiers; +import org.openehr.rm.support.terminology.TerminologyAccess; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * Abstract class defining the common meta-data of all types of + * encapsulated data. + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class DvEncapsulated extends DataValue { + + /** + * Construct a Encapsulated by charset, language and size + * + * @param charset not null and valid + * @param language not null and valid + * @param terminologyService + * @throws IllegalArgumentException if any argument is invalid + */ + protected DvEncapsulated(CodePhrase charset, CodePhrase language, + TerminologyService terminologyService) { + + if ((charset != null || language != null) && terminologyService == null) { + throw new IllegalArgumentException("null terminologyService"); + } + if (language != null && ( ! terminologyService.codeSetForId( + OpenEHRCodeSetIdentifiers.LANGUAGES).hasCode(language))) { + throw new IllegalArgumentException("unknown language: " + language); + + } + if (charset != null && ( ! terminologyService.codeSetForId( + OpenEHRCodeSetIdentifiers.CHARACTER_SETS).hasCode(charset))) { + throw new IllegalArgumentException( + "unknown character set: " + charset); + } + this.charset = charset; + this.language = language; + } + + /** + * Returns IANA character set name if data is formatted text + * + * @return charset + */ + public CodePhrase getCharset() { + return charset; + } + + /** + * Returns name of language used if data is formatted text + * + * @return language + */ + public CodePhrase getLanguage() { + return language; + } + + /** + * Returns size in bytes of data of this Encapsulated + * + * @return size + */ + public abstract int getSize(); + + // POJO start + protected DvEncapsulated() { + } + + void setCharset(CodePhrase charset) { + this.charset = charset; + } + + void setLanguage(CodePhrase language) { + this.language = language; + } + + // POJO end + + /* fields */ + private CodePhrase charset; + 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 DvEncapsulated.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/encapsulated/DvMultimedia.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/encapsulated/DvMultimedia.java new file mode 100644 index 00000000..f9857b12 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/encapsulated/DvMultimedia.java @@ -0,0 +1,327 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvMultimedia" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/datatypes/encapsulated/DvMultimedia.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +package org.openehr.rm.datatypes.encapsulated; + +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.uri.DvURI; +import org.openehr.rm.support.terminology.OpenEHRCodeSetIdentifiers; +import org.openehr.rm.support.terminology.TerminologyAccess; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; + +/** + * A specialisation of Encapsulated for audiovisual and biosignal types. + * Includes further metadata relating to multimedia types which are not + * applicable to other subtypes of Encapsulated. + * Instances of this class are immutable + * + * @author Rong Chen + * @version 1.0 + */ +public final class DvMultimedia extends DvEncapsulated { + + /** + * Constructs a Multimedia by specifying all components + * + * @param charset + * @param language + * @param size >=0 + * @param alternateText + * @param mediaType not null and a valid code + * @param compressionAlgorithm null or a valid code + * @param integrityCheck not null if integrityCheckAlgorithm not null + * @param integrityCheckAlgorithm null or a valid code + * @param thumbnail + * @param uri not null if data is null + * @param data not null if uri is null + * @param terminologyService + * @throws IllegalArgumentException if any invalid argument + */ + @FullConstructor + public DvMultimedia(@Attribute (name = "charset") CodePhrase charset, + @Attribute (name = "language") CodePhrase language, + @Attribute (name = "alternateText") String alternateText, + @Attribute (name = "mediaType", required = true) CodePhrase mediaType, + @Attribute (name = "compressionAlgorithm", required = true) CodePhrase compressionAlgorithm, + @Attribute (name = "integrityCheck") byte[] integrityCheck, + @Attribute (name = "integrityCheckAlgorithm", required = true) CodePhrase integrityCheckAlgorithm, + @Attribute (name = "thumbnail") DvMultimedia thumbnail, + @Attribute (name = "uri") DvURI uri, + @Attribute (name = "data") byte[] data, + @Attribute (name = "terminologyService", system = true) TerminologyService terminologyService) { + + super(charset, language, terminologyService); + + if (mediaType == null) { + throw new IllegalArgumentException("null mediaType"); + } + if (compressionAlgorithm == null) { + throw new IllegalArgumentException("null compressionAlgorithm"); + } + if (integrityCheck != null && + integrityCheckAlgorithm == null) { + throw new IllegalArgumentException( + "null integrity check algorithm"); + } + + if (!terminologyService.codeSetForId( + OpenEHRCodeSetIdentifiers.MEDIA_TYPES).hasCode(mediaType)) { + throw new IllegalArgumentException( + "unknown media types: " + mediaType); + } + if (!terminologyService.codeSetForId( + OpenEHRCodeSetIdentifiers.COMPRESSION_ALGORITHMS).hasCode( + compressionAlgorithm)) { + throw new IllegalArgumentException("unknown compression algorithm: " + + compressionAlgorithm); + } + if (!terminologyService.codeSetForId( + OpenEHRCodeSetIdentifiers.INTEGRITY_CHECK_ALGORITHMS).hasCode( + integrityCheckAlgorithm)) { + throw new IllegalArgumentException( + "unknown integrity check algorithm: " + + integrityCheckAlgorithm); + } + if (uri == null && data == null) { + throw new IllegalArgumentException("both uri and ata are null"); + } + this.alternateText = alternateText; + this.mediaType = mediaType; + this.compressionAlgorithm = compressionAlgorithm; + this.integrityCheck = integrityCheck; + this.integrityCheckAlgorithm = integrityCheckAlgorithm; + this.thumbnail = thumbnail; + this.uri = uri; + this.data = data; + } + + @Override + public int getSize() { + return data == null ? 0 : data.length; + } + + /** + * Text to display in lieu of multimedia display/replay + * + * @return alternate text, null if unspecified + */ + public String getAlternateText() { + return alternateText; + } + + /** + * Data media type coded from the IANA MIME types, + * openEHR "media types" code set, see + *
+ * + * http://www.iana.org/assignments/mediatypes + *
+ * + * @return media type + */ + public CodePhrase getMediaType() { + return mediaType; + } + + /** + * Compression type, a coded value from the openEHR + * "compression algorithm" code set + * + * @return null if no compression + */ + public CodePhrase getCompressionAlgorithm() { + return compressionAlgorithm; + } + + /** + * binary cryptographic integrity checksum + * + * @return null if no checksum + */ + public byte[] getIntegrityCheck() { + return integrityCheck; + } + + /** + * Type of integrity check, a coded value from the openEHR + * "integrity check algorithm" code set. + * + * @return null if has no integrity check + */ + public CodePhrase getIntegrityCheckAlgorithm() { + return integrityCheckAlgorithm; + } + + /** + * The thumbnail for this item, if one exists; mainly for graphics formats. + * + * @return thumbnail null if unspecified + */ + public DvMultimedia getThumbnail() { + return thumbnail; + } + + /** + * URI reference to electronic information stored outside the record + * + * @return possibly null if data inline + */ + public DvURI getUri() { + return uri; + } + + /** + * The actual data found at 'uri', if supplied inline + * + * @return possibly null if data external + */ + public byte[] getData() { + return data; + } + + /** + * True if the data is stored externally to the record, + * as indicated by uri + * + * @return true if external + */ + public boolean isExternal() { + return uri != null; + } + + /** + * True if the data is stored in expanded form + * + * @return true if data inline + */ + public boolean isInline() { + return data != null; + } + + /** + * True if the data is stored in compressed form + * + * @return true if compressed + */ + public boolean isCompressed() { + return compressionAlgorithm != null; + } + + /** + * True if an integrity check has been computed + * + * @return true if has integrity check + */ + public boolean hasIntegrityCheck() { + return integrityCheckAlgorithm != null; + } + + /** + * string form displayable for humans + * + * @return string presentation + */ + public String toString() { + return mediaType.toString(); + } + + // POJO start + private DvMultimedia() { + } + + private void setAlternateText(String alternateText) { + this.alternateText = alternateText; + } + + private void setMediaType(CodePhrase mediaType) { + this.mediaType = mediaType; + } + + private void setCompressionAlgorithm(CodePhrase compressionAlgorithm) { + this.compressionAlgorithm = compressionAlgorithm; + } + + private void setIntegrityCheck(byte[] integrityCheck) { + this.integrityCheck = integrityCheck; + } + + private void setIntegrityCheckAlgorithm(CodePhrase integrityCheckAlgorithm) { + this.integrityCheckAlgorithm = integrityCheckAlgorithm; + } + + private void setThumbnail(DvMultimedia thumbnail) { + this.thumbnail = thumbnail; + } + + private void setUri(DvURI uri) { + this.uri = uri; + } + + private void setData(byte[] data) { + this.data = data; + } + // POJO end + + /* fields */ + private String alternateText; + private CodePhrase mediaType; + private CodePhrase compressionAlgorithm; + private byte[] integrityCheck; + private CodePhrase integrityCheckAlgorithm; + private DvMultimedia thumbnail; + private DvURI uri; + private byte[] data; + @Override + public String getReferenceModelName() { + return "DV_MULTIMEDIA"; + } + + @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 DvMultimedia.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/encapsulated/DvParsable.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/encapsulated/DvParsable.java new file mode 100644 index 00000000..0333e9b9 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/encapsulated/DvParsable.java @@ -0,0 +1,191 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvParsable" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/datatypes/encapsulated/DvParsable.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datatypes.encapsulated; + +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; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * Encapsulated data expressed as a parsable string. + * The internal model of the data item is not described in the + * openEHR model in common with other encapsulated types, but in + * this case, the form of the data is assumed to be plaintext, + * rather than compressed or other types of large binary data. + *

+ * Instances of Parsable are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class DvParsable extends DvEncapsulated { + + /** + * Constructs a Parsable by given components + * + * @param charset + * @param language + * @param size + * @param value not null + * @param formalism not null or empty + * @param terminologyService + * @throws IllegalArgumentException if any invalid arguement + */ + @FullConstructor + public DvParsable(@Attribute(name = "charset", system = true) CodePhrase charset, + @Attribute(name = "language", system = true) CodePhrase language, + @Attribute(name = "value", required = true) String value, + @Attribute(name = "formalism", required = true) String formalism, + @Attribute(name = "terminologyService", system = true) + TerminologyService terminologyService) { + + super(charset, language, terminologyService); + + if (value == null) { + throw new IllegalArgumentException("null value"); + } + if (StringUtils.isEmpty(formalism)) { + throw new IllegalArgumentException("null or empty formalism"); + } + this.value = value; + this.formalism = formalism; + } + + /** + * Create a parsable by value and formalism + * + * @param value + * @param formalism + */ + public DvParsable(String value, String formalism) { + this(null, null, value, formalism, null); + } + + /** + * The string value, which may validly be empty in some syntaxes + * + * @return value + */ + public String getValue() { + return value; + } + + /** + * Name of the formalism + * + * @return formalism + */ + public String getFormalism() { + return formalism; + } + + @Override + public int getSize() { + return value.length(); + } + + /** + * Two Parsable equal if both has same value and + * formalism + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof DvParsable )) return false; + + final DvParsable parsable = (DvParsable) o; + + return new EqualsBuilder() + .append(value, parsable.value) + .append(formalism, parsable.formalism) + .isEquals(); + } + + /** + * Return a hash code of this parsable + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(17, 47) + .append(value) + .append(formalism) + .toHashCode(); + } + + // POJO start + private DvParsable() { + } + + private void setValue(String value) { + this.value = value; + } + + private void setFormalism(String formalism) { + this.formalism = formalism; + } + + // POJO end + + /* fields */ + private String value; + private String formalism; + @Override + public String getReferenceModelName() { + return "DV_PARSABLE"; + } + + @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 DvParsable.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/quantity/DvAbsoluteQuantity.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvAbsoluteQuantity.java new file mode 100644 index 00000000..e2a11874 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvAbsoluteQuantity.java @@ -0,0 +1,115 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvAbsoluteQuantity" + * keywords: "datatypes" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.rm.datatypes.quantity; + +import java.util.List; + +import org.openehr.rm.datatypes.text.CodePhrase; + +/** + * Abstract class defining the concept of quantified entities whose values + * are absolute with respect to an origin. Dates and Times are the main example. + * + * @author Rong Chen + */ +public abstract class DvAbsoluteQuantity extends DvQuantified { + + /** + * Creates a DvAbsoluteQuantity + * + * @param otherReferenceRanges + * @param normalRange + * @param normalStatus + * @param magnitudeStatus + * @param accuracy + */ + protected DvAbsoluteQuantity(List> otherReferenceRanges, + DvInterval normalRange, CodePhrase normalStatus, + S accuracy, String magnitudeStatus) { + + super(otherReferenceRanges, normalRange, normalStatus, magnitudeStatus); + + this.accuracy = accuracy; + } + + /** + * Sum of this quantity and another whose formal type must be the + * difference type of this quantity. + * + * @param s + * @return product of addition + */ + public abstract T add(S s); + + /** + * Difference of this quantity and another whose formal type must + * be the difference type of this quantity type. + * + * @param s + * @return product of substration + */ + public abstract T subtract(S s); + + /** + * Difference of two quantities. + * + * @return diff type + */ + public abstract DvAmount diff(T other); + + /** + * Accuracy of measurement, expressed as a half-range value + * of the diff type for this quantity (i.e. an accuracy of + * x means +/−x). + * + * @return accuracy + */ + public S getAccuracy() { + return accuracy; + } + + + /* fields */ + private final S accuracy; +} +/* + * ***** 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 DvAbsoluteQuantity.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2007 + * 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/quantity/DvAmount.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvAmount.java new file mode 100644 index 00000000..2e39dbce --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvAmount.java @@ -0,0 +1,155 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvAmout" + * keywords: "datatypes" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.rm.datatypes.quantity; + +import java.util.List; + +import org.openehr.rm.Attribute; +import org.openehr.rm.datatypes.text.CodePhrase; + +/** + * Abstract class defining the concept of relative quantified 'amounts'. + * For relative quantities, the '+' and '-' operators are defined + * (unlike descendants of DV_ABSOLUTE_QUANTITY, such as the date/time types). + * + * @author Rong Chen + */ +public abstract class DvAmount extends DvQuantified { + + /** + * Constructs a DvAmount with referenceRanges and accuracy + * + * @param otherReferenceRanges null if not specified + * @param normalRange null if not specified + * @param normalStatus null if not specified + * @param accuracy 0 means not recorded + * @param accuracyPercent + * @param magnitudeStatus null if not specified + */ + protected DvAmount( + @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) { + + super(otherReferenceRanges, normalRange, normalStatus , magnitudeStatus); + + this.accuracy = accuracy; + this.accuracyPercent = accuracyPercent; + } + + /** + * Constructs a Quantified without referenceRanges + * + * @param accuracy 0 if not recorded + * @param accuracyIsPercent true if accuracy is percent + */ + protected DvAmount(double accuracy, boolean accuracyIsPercent) { + this(null, null, null, accuracy, accuracyIsPercent, null); + } + + /** + * Default constructor + */ + protected DvAmount() { + this(0.0, false); + } + + /** + * Accuracy of measurement instrument or method which applies + * to this specific instance of Quantified, expressed either + * as a half-range percent value (accuracy_is_percent = True) + * or a half-range quantity. + *

+ * A value of 0 means that accuracy was not recorded. + * + * @return accuracy + */ + public double getAccuracy() { + return accuracy; + } + + /** + * If True, indicates that when this object was created, + * accuracy was recorded as a percent value; if False, as an + * absolute quantity value. + * + * @return true if accuracy percent value + */ + public boolean isAccuracyPercent() { + return accuracyPercent; + } + + /** + * Sum of this quantity and another whose formal type must be the + * difference type of this quantity. + * + * @param q + * @return product of addition + */ + public abstract DvQuantified add(DvQuantified q); + + /** + * Difference of this quantity and another whose formal type must + * be the difference type of this quantity type. + * + * @param q + * @return product of substration + */ + public abstract DvQuantified subtract(DvQuantified q); + + /** + * Type of quantity which can be added or subtracted to this + * quantity. Usually the same type, but may be different as in + * the case of dates and times. + * + * @return diff type + */ + public abstract Class getDiffType(); + + /* fields */ + private final double accuracy; + private final boolean accuracyPercent; +} +/* + * ***** 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 DvAmount.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2007 + * 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/quantity/DvCount.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvCount.java new file mode 100644 index 00000000..e0d6b536 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvCount.java @@ -0,0 +1,246 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvCount" + * 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/DvCount.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 org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.datatypes.basic.ReferenceModelName; +import org.openehr.rm.datatypes.text.CodePhrase; + +import java.util.List; + +/** + * This class defines countable quantities. + * + * @author Rong Chen + * @version 1.0 + */ +public final class DvCount extends DvAmount { + + /** + * + */ + private static final long serialVersionUID = 1800575426332796870L; + + /** + * Constructs a Countable by all components + * + * @param otherReferenceRanges + * @param normalRange + * @param normalStatus + * @param accuracy + * @param accuracyPercent + * @param magnitudeStatus + * @param magnitude + + */ + @FullConstructor + public DvCount( + @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 = "magnitude", required = true) int magnitude) { + super(otherReferenceRanges, normalRange, normalStatus, accuracy, + accuracyPercent, magnitudeStatus); + this.magnitude = magnitude; + } + + /** + * Constructs a Countable by magnitude + * + * @param magnitude + */ + public DvCount(int magnitude) { + this.magnitude = magnitude; + } + + /** + * Numeric value of the quantity in canonical (single value) form + * + * @return getMagnitude + */ + public Integer getMagnitude() { + return new Integer(this.magnitude); + } + + /** + * Sum of this quantity and another whose formal type must be the + * difference type of this quantity. + * + * @param q + * @return product of addition + * @throws ClassCastException if q not type of Countable + */ + public DvQuantified add(DvQuantified q) { + final DvCount c = (DvCount) q; + return new DvCount(getOtherReferenceRanges(), getNormalRange(), + getNormalStatus(), getAccuracy(), isAccuracyPercent(), + getMagnitudeStatus(), magnitude + c.magnitude); + } + + /** + * Difference of this quantity and another whose formal type must + * be the difference type of this quantity type. + * + * @param q + * @return product of subtraction + */ + public DvQuantified subtract(DvQuantified q) { + final DvCount c = (DvCount) q; + return new DvCount(getOtherReferenceRanges(), getNormalRange(), + getNormalStatus(), getAccuracy(), isAccuracyPercent(), + getMagnitudeStatus(), magnitude - c.magnitude); + } + + /** + * Type of quantity which can be added or subtracted to this + * quantity. Usually the same type, but may be different as in + * the case of dates and times. + * + * @return diff type + */ + public Class getDiffType() { + return DvCount.class; + } + + /** + * Compares this object with the specified object for order. Returns a + * negative integer, zero, or a positive integer as this object is less + * than, equal to, or greater than the specified object. + * + * @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 DvCount c = (DvCount) o; + if (magnitude < c.magnitude) + return -1; + if (magnitude > c.magnitude) + return 1; + return 0; + } + + /** + * Tests if two instances are strictly comparable. + * + * @param ordered + * @return true if two instances are strictly comparable + */ + public boolean isStrictlyComparableTo(DvOrdered ordered) { + return ordered instanceof DvCount; + } + + /** + * Two Counts equal if has same magnitude + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof DvCount)) + return false; + + final DvCount dvCount = (DvCount) o; + + if (magnitude != dvCount.magnitude) + return false; + + return true; + } + + /** + * Return hash code of this Count + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(13, 37).append(magnitude).toHashCode(); + } + + public String toString() { + return Integer.toString(magnitude); + } + + public DvCount parse(String value) throws IllegalArgumentException { + try { + int i = Integer.parseInt(value); + return new DvCount(i); + } catch(NumberFormatException nfe) { + throw new IllegalArgumentException("Wrong format", nfe); + } + } + + // POJO start + DvCount() { + } + + public void setMagnitude(int magnitude) { + this.magnitude = magnitude; + } + + // POJO end + + /* fields */ + private int magnitude; + + @Override + public String getReferenceModelName() { + return ReferenceModelName.DV_COUNT.getName(); + } + + @Override + public String serialise() { + return getReferenceModelName() + "," + 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 DvCount.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2007 + * 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/quantity/DvInterval.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvInterval.java new file mode 100644 index 00000000..2a5a143a --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvInterval.java @@ -0,0 +1,204 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvInterval" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/datatypes/quantity/DvInterval.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datatypes.quantity; + +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.datatypes.basic.DataValue; +import org.openehr.rm.support.basic.Interval; + +/** + * Generic class defining an interval (ie range) of a comparable type. + * An interval is a contiguous subrange of a comparable base type. + * Instancese of this class are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class DvInterval extends DataValue { + + /** + * Constructs an Interval + * + * @param lower null if unbounded + * @param upper null if unbounded + * @throws IllegalArgumentException if lower > upper + */ + @FullConstructor + public DvInterval(@Attribute (name = "lower") T lower, + @Attribute (name = "upper") T upper) { + if (lower != null && upper != null + && upper.compareTo(lower) < 0) { + throw new IllegalArgumentException("lower > upper"); + } + interval = new Interval(lower, upper); + } + + /** + * Returns lower boundary + * + * @return null if not specified + */ + public T getLower() { + return interval.getLower(); + } + + /** + * Returns upper boundary + * + * @return null if not specified + */ + public T getUpper() { + return interval.getUpper(); + } + + /** + * Returns true if lower boundary open + * + * @return true is unbounded + */ + public boolean isLowerUnbounded() { + return interval.getLower() == null; + } + + /** + * Returns true if upper boundary open + * + * @return true is unbounded + */ + public boolean isUpperUnbounded() { + return interval.getUpper() == null; + } + + /** + * Checks if lower boundary valude included in range + * + * @return true if included + */ + public boolean isLowerIncluded() { + return interval.isLowerIncluded(); + } + + /** + * Checks if upper boundary valude included in range + * + * @return true if included + */ + public boolean isUpperIncluded() { + return interval.isUpperIncluded(); + } + + /** + * Returns true if lower >= value and value <= upper + * + * @param value not null + * @return true if given value is within this interval + * @throws IllegalArgumentException if value is null + */ + public boolean has(DvOrdered value) { + if (value == null) { + throw new IllegalArgumentException("null value"); + } + + return ( interval.isLowerUnbounded() || + value.compareTo(interval.getLower()) >= 0 ) + && ( interval.isUpperUnbounded() || + value.compareTo(interval.getUpper()) <= 0 ); + } + + /** + * Equals if both has same value for lower and upper boundaries + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof DvInterval )) return false; + + final DvInterval interval1 = (DvInterval) o; + + if (!interval.equals(interval1.interval)) return false; + + return true; + } + + /** + * Return a hash code of this interval + * + * @return hash code + */ + public int hashCode() { + return interval.hashCode(); + } + + + // POJO start + public void setInterval(Interval interval) { + this.interval = interval; + } + + private DvInterval() { + } + + public Interval getInterval() { + return interval; + } + // POJO end + + /* fields */ + private Interval interval; + + @Override + public String getReferenceModelName() { + return "DV_INTERVAL"; + } + + @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 DvInterval.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/quantity/DvOrdered.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvOrdered.java new file mode 100644 index 00000000..00451b23 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvOrdered.java @@ -0,0 +1,254 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvOrdered" + * keywords: "datatypes" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004,2007 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/DvOrdered.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 org.openehr.rm.Attribute; +import org.openehr.rm.datatypes.basic.DataValue; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.terminology.OpenEHRCodeSetIdentifiers; +import org.openehr.rm.support.terminology.TerminologyService; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Abstract class defining the concept of ordered values, which + * includes ordinals as well as true quantities. + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class DvOrdered extends DataValue + implements Comparable { + + /** + * Constructs an Ordered without reference ranges + */ + protected DvOrdered() { + this(null, null); + } + + /** + * Constructs a Ordered by otherReferenceRanges, normalRange and + * normalStatus + * + * @param otherReferenceRanges null if not specified + * @param normalRange null if not specified + * @param normalStatus null if not specified + * @throws IllegalArgumentException if otherReferenceRanges not null + * and empty + */ + protected DvOrdered ( + @Attribute (name = "otherReferenceRanges") + List> otherReferenceRanges, + @Attribute (name = "normalRange") DvInterval normalRange, + @Attribute (name= "normalStatus") CodePhrase normalStatus, + @Attribute(name = "terminologyService", system = true) + TerminologyService terminologyService) { + + if (otherReferenceRanges != null) { + if (otherReferenceRanges.isEmpty()) { + throw new IllegalArgumentException("empty otherReferenceRanges"); + } + this.otherReferenceRanges = + new ArrayList>(otherReferenceRanges); + } else { + this.otherReferenceRanges = null; + } + + if(normalStatus != null) { + if(terminologyService == null) { + throw new IllegalArgumentException("null terminologyService"); + } + if (!terminologyService.codeSetForId( + OpenEHRCodeSetIdentifiers.NORMAL_STATUSES).hasCode( + normalStatus)) { + throw new IllegalArgumentException( + "unknown normal status: " + normalStatus); + } + } + if(normalStatus != null && normalRange != null) { + + } + + this.normalRange = normalRange; + this.normalStatus = normalStatus; + } + + /** + * Constructs a Ordered by otherReferenceRanges, normalRange and + * normalStatus + * + * @param otherReferenceRanges null if not specified + * @param normalRange null if not specified + * @param normalStatus null if not specified + * @throws IllegalArgumentException if otherReferenceRanges not null + * and empty + */ + protected DvOrdered ( + List> otherReferenceRanges, + DvInterval normalRange, CodePhrase normalStatus) { + + if (otherReferenceRanges != null) { + if (otherReferenceRanges.isEmpty()) { + throw new IllegalArgumentException("empty otherReferenceRanges"); + } + this.otherReferenceRanges = + new ArrayList>(otherReferenceRanges); + } else { + this.otherReferenceRanges = null; + } + this.normalRange = normalRange; + this.normalStatus = normalStatus; + } + + /** + * Constructs a Ordered by otherReferenceRanges and normalRange + * + * @param otherReferenceRanges null if not specified + * @param normalRange null if not specified + * @throws IllegalArgumentException if otherReferenceRanges not null + * and empty + */ + protected DvOrdered (List> otherReferenceRanges, + DvInterval normalRange) { + + this(otherReferenceRanges, normalRange, null); + } + + /** + * Optional ranges for this value in its particular measurement + * context + * + * @return unmodifiable list of ReferenceRange + * null if not specified + */ + public List> getOtherReferenceRanges() { + return otherReferenceRanges == null ? + null : Collections.unmodifiableList(otherReferenceRanges); + } + + /** + * Optional normal range + * + * @return null if not specified + */ + public DvInterval getNormalRange() { + return normalRange; + } + + /** + * Optional normal status + * + * @return null if not specified + */ + public CodePhrase getNormalStatus() { + return normalStatus; + } + + /** + * Value is in the normal range if there is one, otherwise True + * + * @return true if normal + * @throws IllegalStateException if both normalRange and normalStatus null + */ + public boolean isNormal() throws IllegalStateException { + if(normalRange == null && normalStatus == null) { + throw new IllegalStateException( + "both normalRange and normalStatus null"); + } + if(normalRange != null) { + return getNormalRange().has(this); + } else { + return normalStatus.getCodeString().equals("N"); + } + } + + /** + * True if this quantity has no reference ranges + * + * @return true if has no reference range + */ + public boolean isSimple() { + return otherReferenceRanges == null; + } + + /** + * Tests if two instances are strictly comparable. + * + * @param ordered + * @return true if two instances are strictly comparable + */ + public abstract boolean isStrictlyComparableTo(DvOrdered ordered); + + // POJO start + /** + * @param normalRange The normalRange to set. + */ + public void setNormalRange(DvInterval normalRange) { + this.normalRange = normalRange; + } + + /** + * @param otherReferenceRanges The otherReferenceRanges to set. + */ + public void setOtherReferenceRanges(List> referenceRanges) { + this.otherReferenceRanges = referenceRanges; + } + + /** + * @param normalStatus The normalStatus to set. + */ + public void setNormalStatus(CodePhrase normalStatus) { + this.normalStatus = normalStatus; + } + // POJO end + + /* fields */ + private List> otherReferenceRanges; + private DvInterval normalRange; + private CodePhrase normalStatus; +} + +/* + * ***** 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 DvOrdered.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Bert Verhees, Sergio Miranda Freire + * + * 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/quantity/DvOrdinal.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvOrdinal.java new file mode 100644 index 00000000..f670b5e8 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvOrdinal.java @@ -0,0 +1,297 @@ +/* + * 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 pain, Apgar values, 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. + * + * @author Rong Chen + * @version 1.0 + */ +public final class DvOrdinal 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 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"); + } + int index = -1; + if (otherReferenceRanges != null) { + for (int i = 0, j = otherReferenceRanges.size(); i < j; i++) { + ReferenceRange range = (ReferenceRange) + 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 DvOrdinal(int value, DvCodedText symbol) { + this(null, null, value, symbol); + } + + /** + * Constructs an Ordinal by value and symbol + * + * @param value + * @param symbol + * @throws IllegalArgumentException + */ + public DvOrdinal(int value, String dvCodedTextvalue, String dvCodedTextTerminology, String dvCodedTextCode) { + this(null, null, value, new DvCodedText(dvCodedTextvalue, dvCodedTextTerminology, dvCodedTextCode)); + } + + /** + * string form displayable for humans + * + * @return string presentation + */ + 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 DvOrdinal dvOrdinal = (DvOrdinal) o; + if (value > dvOrdinal.value) return 1; + if (value < dvOrdinal.value) return -1; + return 0; + } + + /** + * Ordinal position in enumeration of values + * + * @return value + */ + public int 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 + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof DvOrdinal )) return false; + + final DvOrdinal ord = (DvOrdinal) o; + + return new EqualsBuilder() + .append(value, ord.value) + .append(symbol, ord.symbol) + .isEquals(); + } + + /** + * Return hash code of this DvOrdinal + * + * @return hash code + */ + 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 + */ + public boolean isStrictlyComparableTo(DvOrdered ordered) { + if (!( ordered instanceof DvOrdinal )) { + return false; + } + final DvOrdinal dvOrdinal = (DvOrdinal) 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 DvOrdinal() { + } + + 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 int value; + private DvCodedText symbol; + private int limitsIndex; + @Override + public String getReferenceModelName() { + return "DV_ORDINAL"; + } + + + + @Override + public String serialise() { + 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)); + } +} + +/* + * ***** 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 DvOrdinal.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 ***** + */ 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 new file mode 100644 index 00000000..f051dd9f --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvProportion.java @@ -0,0 +1,315 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvProportion" + * keywords: "datatypes" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.rm.datatypes.quantity; + +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.List; + +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.datatypes.text.CodePhrase; + +/** + * Models a ratio of values, i.e. where the numerator and denominator + * are both pure numbers + * + * @author Rong Chen + */ +public class DvProportion extends DvAmount { + + /** + * + */ + private static final long serialVersionUID = -6974879608546465410L; + /** + * Constructs a DvAmount with referenceRanges and accuracy + * + * @param otherReferenceRanges null if not specified + * @param normalRange null if not specified + * @param normalStatus null if not specified + * @param accuracy 0 means not recorded + * @param accuracyPercent + * @param magnitudeStatus null if not specified + * @param numerator not null + * @param denominator not null + * @param type not null + * @param precision null if not specified + */ + @FullConstructor + public DvProportion( + @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 = "numerator", required = true) double numerator, + @Attribute (name = "denominator", required = true) double denominator, + @Attribute (name = "type", required = true) ProportionKind type, + @Attribute (name = "precision") Integer precision) { + + super(otherReferenceRanges, normalRange, normalStatus , accuracy, + accuracyPercent, magnitudeStatus); + + if(type == null) { + throw new IllegalArgumentException("null type"); + } else if(type == ProportionKind.UNITARY) { + if(denominator != 1) { + throw new IllegalArgumentException( + "denominator for unitary proportion must be 1"); + } + } else if(type == ProportionKind.PERCENT) { + if(denominator != 100) { + throw new IllegalArgumentException( + "denominator for unitary proportion must be 100"); + } + } else if(type == ProportionKind.FRACTION || + type == ProportionKind.INTEGER_FRACTION) { + + if(! bothIntegral(numerator, denominator)) { + throw new IllegalArgumentException( + "both numberator and denominator must be integral for " + + "fraction or integer fraction proportion"); + } + } + + if(bothIntegral(numerator, denominator) + && (precision != null && precision != 0)) { + throw new IllegalArgumentException("precision must be 0 if both " + + "numerator and denominator are integral"); + } + if( !bothIntegral(numerator, denominator) + && (precision != null && precision == 0)) { + throw new IllegalArgumentException("zero precision for " + + "non-integral numerator or denominator"); + } + + this.numerator = numerator; + this.denominator = denominator; + this.type = type; + this.precision = precision; + } + + /** + * Creates a simple DvProportion + */ + public DvProportion(double numerator, double denominator, + ProportionKind type, Integer precision) { + this(null, null, null, 0.0, false, null, numerator, denominator, type, + precision); + } + + /** + * Create a unitary proportion + * + * @param numerator + * @param precision + * @return + */ + public static DvProportion createUnitaryProportion(double numerator, + Integer precision) { + return new DvProportion(numerator, 1.0, ProportionKind.UNITARY, precision); + } + + /** + * @return Returns the denominator. + */ + public double getDenominator() { + return denominator; + } + + /** + * @return Returns the numerator. + */ + public double getNumerator() { + return numerator; + } + + /** + * @return Returns the precision, null if unspecified + */ + public Integer getPrecision() { + return precision; + } + + /** + * @return Returns the type. + */ + public ProportionKind getType() { + return type; + } + + /** + * True if the numerator and denominator values are integers + * + * @return true if integral + */ + public boolean isIntegral() { + return bothIntegral(numerator, denominator); + } + + private boolean bothIntegral(double num1, double num2) { + return (Math.floor(num1) == num1) && (Math.floor(num2) == num2); + } + + @Override + public DvQuantified add(DvQuantified q) { + // TODO Auto-generated method stub + return null; + } + @Override + public DvQuantified subtract(DvQuantified q) { + // TODO Auto-generated method stub + return null; + } + @Override + public Class getDiffType() { + // TODO Auto-generated method stub + return null; + } + @Override + public Number getMagnitude() { + return new Double(numerator / denominator); + } + @Override + public boolean isStrictlyComparableTo(DvOrdered ordered) { + // TODO Auto-generated method stub + return false; + } + public int compareTo(DvOrdered arg0) { + DvProportion p = (DvProportion) arg0; + if (getDenominator()==0 || p.getDenominator()==0){ + throw new IllegalArgumentException("Cannot compare proportions with denominator==0"); + } + Double result = (getNumerator()/getDenominator()); + Double resultB = (p.getNumerator()/p.getDenominator()); + return result.compareTo(resultB); + } + + + + public void setNumerator(double numerator) { + this.numerator = numerator; + } + + public void setDenominator(double denominator) { + this.denominator = denominator; + } + + public void setType(ProportionKind type) { + this.type = type; + } + + public void setPrecision(Integer precision) { + this.precision = precision; + } + + @Override + public String serialise() { + return getReferenceModelName() + "," + toString(); + } + + public DvProportion parse(String value) { + int iNumerator = value.indexOf(","); + if(iNumerator < 0 || iNumerator == value.length()) { + throw new IllegalArgumentException("failed to parse proportion, wrong format [" + value + "]"); + } + String numeratorStr = value.substring(0, iNumerator); + int iDenominator = value.indexOf(",", iNumerator+1); + if(iDenominator < 0 || iDenominator == value.length()) { + throw new IllegalArgumentException("failed to parse proportion, wrong format [" + value + "]"); + } + String denominatorStr = value.substring(iNumerator+1, iDenominator); + + String propTypeStr = value.substring(iDenominator+1); + Integer propTypeInt = null; + try { + propTypeInt = Integer.parseInt(propTypeStr); + } catch(NumberFormatException nfe) { + throw new IllegalArgumentException("failed to parse proportion type ["+propTypeStr+"]", nfe); + } + ProportionKind propType = ProportionKind.valueOf(propTypeInt); + + //Precision is calculated from numerator + int precision = 0; + int i = numeratorStr.indexOf(DvQuantity.DECIMAL_SEPARATOR); + if(i >= 0) { + precision = numeratorStr.length() - i - 1; + } + try { + double numerator = Double.parseDouble(numeratorStr); + double denominator = Double.parseDouble(denominatorStr); + return new DvProportion(numerator, denominator, propType, precision); + } catch(NumberFormatException nfe) { + throw new IllegalArgumentException("failed to parse quantity[" + + numeratorStr + "/" + denominatorStr+ "]", nfe); + } + } + + /** + * string form displayable for humans + * + * @return string presentation + */ + public String toString() { + DecimalFormat format = new DecimalFormat(); + format.setMinimumFractionDigits(precision); + format.setMaximumFractionDigits(precision); + DecimalFormatSymbols dfs = format.getDecimalFormatSymbols(); + dfs.setDecimalSeparator(DvQuantity.DECIMAL_SEPARATOR); + format.setDecimalFormatSymbols(dfs); + format.setGroupingUsed(false); + return format.format(numerator) + "," + format.format(denominator) + "," + type; + } + + /* fields */ + private double numerator; + private double denominator; + private ProportionKind type; + private Integer precision; + @Override + public String getReferenceModelName() { + return "DV_PROPORTION"; + } +} +/* + * ***** 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 DvProportion.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2007 + * 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/quantity/DvQuantified.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvQuantified.java new file mode 100644 index 00000000..8a96651a --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvQuantified.java @@ -0,0 +1,144 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvQuantified" + * 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/DvQuantified.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.openehr.rm.Attribute; +import org.openehr.rm.datatypes.text.CodePhrase; + +/** + * Abstract class defining the concept of true quantified values, + * like values which are not only ordered, but which have + * a getMagnitude, and for which the addition and difference + * operations can be defined. + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class DvQuantified extends DvOrdered { + + /** + * Constructs a Quantified with referenceRanges and accuracy + * + * @param otherReferenceRanges null if not specified + * @param normalRange null if no specified + * @param normalStatus null if not specified + * @param magnitudeStatus null if not specified + */ + protected DvQuantified( + @Attribute (name = "otherReferenceRanges") List> otherReferenceRanges, + @Attribute (name = "normalRange") DvInterval normalRange, + @Attribute (name= "normalStatus") CodePhrase normalStatus, + @Attribute (name= "magnitudeStatus") String magnitudeStatus) { + super(otherReferenceRanges, normalRange, normalStatus); + this.magnitudeStatus = magnitudeStatus; + } + + /** + * Test whether a number is a valid percentage + * + * @param num + * @return true if given number is valid percentage + */ + public boolean is_valid_percentage(Number num) { + // todo: fix it + return false; + } + + /** + * Numeric value of the quantity in canonical (single value) form + * + * @return getMagnitude + */ + public abstract Number getMagnitude(); + + /** + * Optional status of magnitude with values: + *

    + *
  • "=" : magnitude is a point value
  • + *
  • "<" : value is < magnitude
  • + *
  • ">" : value is > magnitude
  • + *
  • "<=" : value is <= magnitude
  • + *
  • ">=" : value is >= magnitude
  • + *
  • "~" : value is approximately magnitude
  • + *
  • If not present, meaning is "="
  • + *
+ * @return null if unspecified + */ + public String getMagnitudeStatus() { + return magnitudeStatus; + } + + /** + * Equals if getMagnitude equals + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof DvQuantified )) return false; + + final DvQuantified dvQuantified = (DvQuantified) o; + + return getMagnitude().equals(dvQuantified.getMagnitude()); + } + + /** + * Return hash code of this Quantified + * + * @return hash code + */ + public int hashCode() { + return getMagnitude().hashCode(); + } + + /* fields */ + private final String magnitudeStatus; + + + +} + +/* + * ***** 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 DvQuantified.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/quantity/DvQuantity.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvQuantity.java new file mode 100644 index 00000000..9720285c --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvQuantity.java @@ -0,0 +1,400 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvQuantity" + * 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/DvQuantity.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 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; +import org.openehr.rm.datatypes.basic.ReferenceModelName; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.measurement.MeasurementService; +import org.openehr.rm.support.measurement.SimpleMeasurementService; + +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.text.NumberFormat; +import java.text.ParseException; +import java.util.List; + +/** + * Quantitified type representing scientific quantities, + * expressed as a single value and optional units. Instances of this class + * are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public class DvQuantity extends DvAmount { + + /** + * Constructs a Quantity by all components + * + * @param otherReferenceRanges + * @param normalRange + * @param normalStatus + * @param accuracy + * @param accuracyPercent + * @param units + * @param magnitude + * @param precision >= -1 + * @magnitudeStatus + * @param measurementService null if not specified only if units + * not specified as well + * @throws IllegalArgumentException + */ + @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); + + 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) + && measurementService == null) { + throw new IllegalArgumentException("null measurementService"); + } + */ + this.magnitude = magnitude; + this.precision = precision; + this.measurementService = measurementService; + this.units = units; + } + + /** + * Constructs a Quantity by units, getMagnitude and precision + * + * @param units + * @param magnitude + * @param precision >= 0 + * @throws IllegalArgumentException + */ + public DvQuantity(String units, double magnitude, int precision, + MeasurementService measurementService) { + this(null, null, null, 0, false, null, units, magnitude, precision, + measurementService); + } + + /** + * Constructs a integer Quantity by double value + * + * @param magnitude + * @throws IllegalArgumentException + */ + public DvQuantity(double magnitude) { + this("", magnitude, 0, null); + } + + /** + * Constructs a Measurable only by units + * + * @param units not null + * @throws IllegalArgumentException if units is null + */ + public DvQuantity(String units, double magnitude, + MeasurementService measurementService) { + this(units, magnitude, 0, measurementService); + } + + /** + * Constructs a Measurable only by units + * + * @param magnitude + * @param precision + * @throws IllegalArgumentException if units is null + */ + public DvQuantity(double magnitude, int precision, + MeasurementService measurementService) { + this("", magnitude, precision, measurementService); + } + + /** + * 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); + } + + /** + * True if precision = 0; quantity represents an integral number + * + * @return ture if integral + */ + public boolean isIntegral() { + return precision == 0; + } + + /** + * Magnitude of this Quantity instance + * + * @return getMagnitude + */ + public Double getMagnitude() { + return new Double(magnitude); + } + + /** + * Units of this quantity + * + * @return units + */ + public String getUnits() { + 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); + } + } + + /** + * Sum of this quantity and another whose formal type must be the + * difference type of this quantity. + * + * @param q + * @return result of addition + * @throws ClassCastException if the specified object's type + * prevents it from being added to this Object. + */ + public DvQuantified add(DvQuantified q) { + DvQuantity qt = (DvQuantity) q; + return new DvQuantity(getOtherReferenceRanges(), getNormalRange(), + getNormalStatus(), getAccuracy(), isAccuracyPercent(), + getMagnitudeStatus(), getUnits(), magnitude + qt.magnitude, + precision, measurementService); + } + + /** + * Difference of this quantity and another whose formal type must + * be the difference type of this quantity type. + * + * @param q + * @return result of subtraction + * @throws ClassCastException if the specified object's type + * prevents it from being subtracted to this Object. + */ + public DvQuantified subtract(DvQuantified q) { + DvQuantity qt = (DvQuantity) q; + return new DvQuantity(getOtherReferenceRanges(), getNormalRange(), + getNormalStatus(), getAccuracy(), isAccuracyPercent(), + getMagnitudeStatus(), getUnits(), magnitude - qt.magnitude, + precision, measurementService); + } + + /** + * Type of quantity which can be added or subtracted to this + * quantity. Usually the same type, but may be different as in + * the case of dates and times. + * + * @return diff type + */ + public Class getDiffType() { + return DvQuantity.class; + } + + /** + * Negated version of current object, such as used for + * representing a difference, like a weight loss. + * + * @return negated version + */ + public DvQuantity negate() { + return new DvQuantity(getOtherReferenceRanges(), getNormalRange(), + getNormalStatus(), getAccuracy(), isAccuracyPercent(), + getMagnitudeStatus(), getUnits(), -magnitude, + precision, measurementService); + } + + /** + * Precision of this Quantity instance + * + * @return precision + */ + public int getPrecision() { + return precision; + } + + /** + * string form displayable for humans + * + * @return string presentation + */ + public String toString() { + DecimalFormat format = new DecimalFormat(); + format.setMinimumFractionDigits(precision); + format.setMaximumFractionDigits(precision); + DecimalFormatSymbols dfs = format.getDecimalFormatSymbols(); + dfs.setDecimalSeparator(DECIMAL_SEPARATOR); + format.setDecimalFormatSymbols(dfs); + format.setGroupingUsed(false); + String tmp = format.format(magnitude) + ( StringUtils.isEmpty(getUnits()) ? "" : "," + + getUnits() ); + return tmp; + } + + /** + * 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 + * @throws ClassCastException if the specified object's type + * prevents it from being compared to this Object. + */ + public int compareTo(DvOrdered o) { + DvQuantity q = (DvQuantity) o; + return SimpleMeasurementService.getInstance().compare(getUnits(), getMagnitude(), q.getUnits(), q.getMagnitude()); + } + + /** + * Tests if two instances are strictly comparable. + * + * @param other + * @return true if two instances are strictly comparable + * @throws IllegalArgumentException if other null or wrong type + */ + public boolean isStrictlyComparableTo(DvOrdered other) { + if (!( other instanceof DvQuantity )) { + throw new IllegalArgumentException("other not Quantity"); + } + final DvQuantity dvQuantity = (DvQuantity) other; + return measurementService.unitsEquivalent(getUnits(), dvQuantity.getUnits()); + } + + /** + * Equals if getMagnitude, units and precision equals + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof DvQuantity )) return false; + + final DvQuantity dvQuantity = (DvQuantity) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(precision, dvQuantity.precision) + .append(units, dvQuantity.units) + .isEquals(); + } + + /** + * Return hash code of this Quantity + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder() + .appendSuper(super.hashCode()) + .append(precision) + .toHashCode(); + } + + // POJO start + public void setMagnitude(double magnitude) { + this.magnitude = magnitude; + } + + 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 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(); + } +} + +/* + * ***** 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 DvQuantity.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/quantity/ProportionKind.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/ProportionKind.java new file mode 100644 index 00000000..00435fd0 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/ProportionKind.java @@ -0,0 +1,140 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ProportionKind" + * keywords: "datatypes" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.rm.datatypes.quantity; + +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; + +/** + * Class of enumeration constants defining types of proportion for the + * DV_PROPORTION class. + * + * @author Rong Chen + */ +public enum ProportionKind { + /** + * Ratio type. Numerator and denominator may be any value + */ + RATIO(0), + + /** + * Denominator must be 1 + */ + UNITARY(1), + + /** + * Denominator is 100, numerator is understood as a percentage value + */ + PERCENT(2), + + /** + * Numerator and denominator are integral, and the presentation + * method uses a slash, e.g. "1/2". + */ + FRACTION(3), + + /** + * Numerator and denominator are integral, and the presentation + * method uses a slash, e.g. "1/2"; if the numerator is greater than the + * denominator, e.g. n=3, d=2, the presentation is "1 1/2" + */ + INTEGER_FRACTION(4); + + /* + * Constructor + * + * @param value + */ + @FullConstructor + private ProportionKind( + @Attribute(name = "value", required=true) int value) { + this.value = value; + } + + /** + * Gets the integer value of this proportion kind + * + * @return int value + */ + public int getValue() { + return value; + } + + /** + * Gets string presentation of this proportion kind + */ + public String toString() { + return Integer.toString(value); + } + + /** + * Gets proportion kind from integer value + * + * @param value + * @return proportionKind of given value + * @throws IllegalArgument if value is unknown + */ + public static ProportionKind fromValue(int value) { + switch (value) { + case 0: + return RATIO; + case 1: + return UNITARY; + case 2: + return PERCENT; + case 3: + return FRACTION; + case 4: + return INTEGER_FRACTION; + default: + throw new IllegalArgumentException("unknown value"); + } + } + + public static ProportionKind valueOf(int value) { + return fromValue(value); + } + + /* field */ + private int value; +} +/* + * ***** 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 ProportionKind.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2007 + * 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/quantity/ReferenceRange.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/ReferenceRange.java new file mode 100644 index 00000000..fc25208a --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/ReferenceRange.java @@ -0,0 +1,184 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ReferenceRange" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/datatypes/quantity/ReferenceRange.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datatypes.quantity; + +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.text.DvText; + +/** + * This class defines a named range to be associated with any Ordered + * datum. Each such range is particular to the patient and context, + * like sex, age, and any other factor which affects ranges. + * + * @author Rong Chen + * @version 1.0 + */ +public final class ReferenceRange extends DataValue { + + /** + * Constructs a ReferenceRange by meaning and range + * + * @param meaning + * @param range + * @throws IllegalArgumentException if meaning or range null, + * or range not simple + */ + @FullConstructor + public ReferenceRange(@Attribute (name = "meaning", required = true) + DvText meaning, + @Attribute (name = "range", required = true) + DvInterval range) { + if (meaning == null) { + throw new IllegalArgumentException("null meaning"); + } + if (range == null) { + throw new IllegalArgumentException("null range"); + } + if (!isSimple(range)) { + throw new IllegalArgumentException("range not simple"); + } + this.meaning = meaning; + this.range = range; + } + + private static boolean isSimple(DvInterval range) { + return ( range.isLowerUnbounded() || + range.getLower().isSimple() ) + && + ( range.isUpperUnbounded() || + range.getUpper().isSimple() ); + } + + /** + * Term whose value indicates the meaning of this range, + * like "normal", "critical", "therapeutic" + * + * @return meaning + */ + public DvText getMeaning() { + return meaning; + } + + /** + * The data range + * + * @return range + */ + public DvInterval getRange() { + return range; + } + + /** + * Indicates if the value is inside the range + * + * @param value + * @return true if has the value + */ + public boolean isInRange(DvOrdered value) { + return range.has(value); + } + + /** + * Two ReferenceRanges equal if both has same value for meaning + * and range + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof ReferenceRange )) return false; + + final ReferenceRange rg = (ReferenceRange) o; + + return new EqualsBuilder() + .append(meaning, rg.meaning) + .append(range, rg.range) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(13, 29) + .append(meaning) + .append(range) + .toHashCode(); + } + + /** + * String presentation of this range + * + * @return string presentation + */ + public String toString() { + return meaning + ", " + range; + } + + /* static field */ + public static final String NORMAL = "normal"; + + /* fields */ + private final DvText meaning; + private final DvInterval range; + @Override + public String getReferenceModelName() { + // TODO Auto-generated method stub + return null; + } + + @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 ReferenceRange.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/quantity/datetime/DvDate.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDate.java new file mode 100644 index 00000000..a498086a --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDate.java @@ -0,0 +1,359 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvDate" + * keywords: "datatypes" + * + * 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/datatypes/quantity/datetime/DvDate.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.datatypes.quantity.datetime; + +import java.util.List; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.joda.time.DateTime; +import org.joda.time.MutableDateTime; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.datatypes.quantity.DvInterval; +import org.openehr.rm.datatypes.quantity.DvOrdered; +import org.openehr.rm.datatypes.quantity.ReferenceRange; +import org.openehr.rm.datatypes.text.CodePhrase; + + +/** + * Represents a point in time, as measured on the Gregorian calendar, + * and specified only to the day. + * + * @author Rong Chen + * @version 1.0 + */ +public class DvDate extends DvTemporal { + + /** + * + */ + private static final long serialVersionUID = 4412140604570981489L; + /** + * Construct a DvDate + * + * @param otherReferenceRanges null if not specified + * @param normalRange null if not specified + * @param normalStatus null if not specified + * @param mangnitudeStatus null if not specified + * @param accuracy 0 if not specified + * @param magnitudeStatus null if not specified + * @param value + * @throws IllegalArgumentException + */ + @FullConstructor + public DvDate(@Attribute(name = "otherReferenceRanges") + List> otherReferenceRanges, + @Attribute(name = "normalRange") + DvInterval normalRange, @Attribute(name = "normalStatus") + CodePhrase normalStatus, @Attribute(name = "accuracy") + DvDuration accuracy, @Attribute(name = "magnitudeStatus") + String magnitudeStatus, @Attribute(name = "value", required = true) + String value) { + super(otherReferenceRanges, normalRange, normalStatus, accuracy, + magnitudeStatus, value); + } + + protected DvDate(List> referenceRanges, + DvInterval normalRange, CodePhrase normalStatus, + DvDuration accuracy, String magnitudeStatus, DateTime datetime, + String pattern) { + super(referenceRanges, normalRange, normalStatus, accuracy, + magnitudeStatus, datetime); + setValue(DvDateTimeParser.toDateString(getDateTime(), pattern)); + setBooleans(pattern); + } + + /** + * Construct a DvDate of current date + * + */ + public DvDate() { + super(DvDateTimeParser.defaultDate()); + setValue(DvDateTimeParser.toDateString(getDateTime(), "yyyy-MM-dd")); + setBooleans(false, true, true); + } + + /** + * Constructs a DvDate with timezone + * + * @param year + * @param month starts with 0 + * @param day + * @param timezone null if use default timezone + */ + public DvDate(int year, int month, int day) { + super(DvDateTimeParser.convertDate(year, month, day)); + setValueByPattern("yyyy-MM-dd"); + setBooleans(false, true, true); + } + + /** + * Contructs a partial DvDate + * + * @param year + * @param month + * @param monthKnown + * @param day + * @param dayKnown + * @param timezone + */ + public DvDate(int year, int month) { + super(DvDateTimeParser.convertDate(year, month, 1)); + setValueByPattern("yyyy-MM"); + setBooleans(true, true, false); + } + + public DvDate(int year) { + super(DvDateTimeParser.convertDate(year, 1, 1)); + setValueByPattern("yyyy"); + setBooleans(true, false, false); + } + + public DvDate(String value) { + this(null, null, null, null, null, value); + } + + /** + * Year + * + * @return year + */ + public int getYear() { + return getDateTime().getYear(); + } + + /** + * Month in year + * + * @return month, 0 if month is unknown + */ + public int getMonth() { + return monthKnown ? getDateTime().getMonthOfYear() : -1; + } + + /** + * Day in month + * + * @return day + */ + public int getDay() { + return dayKnown ? getDateTime().getDayOfMonth() : -1; + } + + /** + * Indicate if this DvDate is partial + * + * @return true if is partial + * + */ + public boolean isPartial() { + return isPartial; + } + + /** + * Indicate if month is unknown + * + * @return true if month is unknown + */ + public boolean monthKnown() { + return monthKnown; + } + + /** + * Indicate if day is unknown + * + * @return true if day is unknown + */ + public boolean dayKnown() { + return dayKnown; + } + + /** + * If date is valid ISO8601 format + * + *@param value + * + */ + public static boolean isValidISO8601Date(String value) { + DateTime dt = null; + try { + dt = DvDateTimeParser.parseDate(value); + } catch (Exception e) { + return false; + } + return dt != null; + } + + @Override + 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 + return null; + } + + @Override + public boolean isStrictlyComparableTo(DvOrdered ordered) { + // TODO Auto-generated method stub + return false; + } + + public boolean equals(Object o) { + if (!super.equals(o)) + return false; + + final DvDate dDate = (DvDate) o; + + return new EqualsBuilder() + .append(isPartial, dDate.isPartial) + .append(monthKnown, dDate.monthKnown) + .append(dayKnown, dDate.dayKnown) + .isEquals(); + } + + /** + * 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 = ""; + } else { + if (isExtended) { + date = DvDateTimeParser.basicToExtendedDate(date); + } else { + date = date.replace("-", ""); + } + } + return date; + } + + void setBooleans(boolean isPartial, boolean monthKnown, boolean dayKnown) { + this.isPartial = isPartial; + this.monthKnown = monthKnown; + this.dayKnown = dayKnown; + } + + void setBooleans(String value) { + int ele = DvDateTimeParser.analyseDateString(value); + //isPartial, monthKnown, dayKnown + if (ele == 3) { + setDayKnown(true); + setMonthKnown(true); + } else if (ele == 2) { + setMonthKnown(true); + setIsPartial(true); + } else if (ele == 1) { + setIsPartial(true); + } + } + + void setDayKnown(boolean dayKnown) { + this.dayKnown = dayKnown; + } + + void setMonthKnown(boolean monthKnown) { + this.monthKnown = monthKnown; + } + + void setIsPartial(boolean isPartial) { + this.isPartial = isPartial; + } + + @Override + public DvDate add(DvDuration q) { + if (!getDiffType().isInstance(q)) { + throw new IllegalArgumentException("invalid difference type"); + } + DvDuration d = (DvDuration) q; + MutableDateTime mdate = getDateTime().toMutableDateTimeISO(); + mdate.add(d.getPeriod()); + return new DvDate(getOtherReferenceRanges(), getNormalRange(), + getNormalStatus(), getAccuracy(), getMagnitudeStatus(), + mdate.toDateTimeISO(), toString()); + } + + @Override + public DvDate subtract(DvDuration q) { + if (!getDiffType().isInstance(q)) { + throw new IllegalArgumentException("invalid difference type"); + } + return add(q.negate()); + } + + /* set the string value by given pattern using datetime value */ + private void setValueByPattern(String pattern) { + DateTimeFormatter fmt = DateTimeFormat.forPattern(pattern); + String value = fmt.print(getDateTime()); + setValue(value); + } + + /* private fields */ + private boolean dayKnown; + private boolean monthKnown; + private boolean isPartial; + @Override + public String getReferenceModelName() { + return "DV_DATE"; + } + + @Override + public String serialise() { + return getReferenceModelName() + "," +toString(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 DvDate.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): Yin Su Lim + * + * 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/datetime/DvDateTime.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTime.java new file mode 100644 index 00000000..efdee72c --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTime.java @@ -0,0 +1,447 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvDateTime" + * keywords: "datatypes" + * + * 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/datatypes/quantity/datetime/DvDateTime.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ + +package org.openehr.rm.datatypes.quantity.datetime; + +import java.util.List; +import java.util.TimeZone; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.joda.time.DateTime; +import org.joda.time.MutableDateTime; +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.datatypes.basic.ReferenceModelName; +import org.openehr.rm.datatypes.quantity.DvInterval; +import org.openehr.rm.datatypes.quantity.DvOrdered; + +import org.openehr.rm.datatypes.quantity.ReferenceRange; +import org.openehr.rm.datatypes.text.CodePhrase; + +/** + * Represents a point in time, specified to the second. + * + * @author Yin Su Lim + * @version 1.0 + */ +public class DvDateTime extends DvTemporal { + + /** + * + */ + private static final long serialVersionUID = -84308270373625815L; + + /* static fields */ + static final DateTimeFormatter eDTimeFormatter = ISODateTimeFormat + .dateTime(); //extended formatter + + static final DateTimeFormatter dTimeFormatter = ISODateTimeFormat + .basicDateTime(); + + /** + * Construct a DvDateTime + * + * @param otherReferenceRanges null if not specified + * @param normalRange null if not specified + * @param normalStatus null if not specified + * @param accuracy 0 if not specified + * @param magnitudeStatus null if not specified + * @param value + * @throws IllegalArgumentException + */ + @FullConstructor + public DvDateTime(@Attribute(name = "otherReferenceRanges") + List> otherReferenceRanges, + @Attribute(name = "normalRange") DvInterval normalRange, + @Attribute(name = "normalStatus") CodePhrase normalStatus, + @Attribute(name = "accuracy") DvDuration accuracy, + @Attribute(name = "magnitudeStatus") String magnitudeStatus, + @Attribute(name = "value", required = true) String value) { + super(otherReferenceRanges, normalRange, normalStatus, accuracy, + magnitudeStatus, value); + } + + protected DvDateTime(List> referenceRanges, + DvInterval normalRange, CodePhrase normalStatus, + DvDuration accuracy, String magnitudeStatus, DateTime datetime, + String pattern) { + super(referenceRanges, normalRange, normalStatus, accuracy, + magnitudeStatus, datetime); + setValue(DvDateTimeParser.toDateTimeString(getDateTime(), pattern)); + setBooleans(pattern); + } + + /* + * Convenience constructor + */ + private DvDateTime(DateTime datetime) { + this(null, null, null, null, null, datetime, "yyyy-MM-dd'T'HH:mm:ss.SSSZZ"); + } + + /** + * Construct a DvDateTime by current date and time + * + */ + public DvDateTime() { + super(DvDateTimeParser.defaultDateTime()); + setValue(DvDateTimeParser.toDateTimeString(getDateTime(), + "yyyy-MM-dd'T'HH:mm:ss.SSSZZ")); + setBooleans(false, true, true, true); + } + + /** + * Construct a DvDateTime by value + * + * @param value + */ + public DvDateTime(String value) { + this(null, null, null, null, null, value); + } + + /** + * Constructs a complete DvDateTime + * + * @param year + * @param month starts with 0 + * @param day day of month + * @param hour hour of day + * @param minute + * @param second + * @param timezone null if use default timezone + */ + public DvDateTime(int year, int month, int day, int hour, int minute, + int second, double fractionalSec, TimeZone timezone) { + super(DvDateTimeParser.convertDateTime(year, month, day, hour, minute, + second, fractionalSec, timezone)); + String format = timezone == null ? "yyyy-MM-dd'T'HH:mm:ss.SSS" + : "yyyy-MM-dd'T'HH:mm:ss.SSSZZ"; + setValue(DvDateTimeParser.toDateTimeString(getDateTime(), format)); + setBooleans(false, true, true, true); + } + + public DvDateTime(int year, int month, int day, int hour, int minute, + int second, TimeZone timezone) { + super(DvDateTimeParser.convertDateTime( + year, month, day, hour, minute, second, 0.0, timezone)); + String format = timezone == null ? "yyyy-MM-dd'T'HH:mm:ss" + : "yyyy-MM-dd'T'HH:mm:ssZZ"; + setValue(DvDateTimeParser.toDateTimeString(getDateTime(), format)); + setBooleans(false, true, true, false); + } + + public DvDateTime(int year, int month, int day, int hour, int minute, + TimeZone timezone) { + super(DvDateTimeParser.convertDateTime( + year, month, day, hour, minute, 0, 0.0, timezone)); + String format = timezone == null ? "yyyy-MM-dd'T'HH:mm" + : "yyyy-MM-dd'T'HH:mmZZ"; + setValue(DvDateTimeParser.toDateTimeString(getDateTime(), format)); + setBooleans(true, true, false, false); + } + + public DvDateTime(int year, int month, int day, int hour, TimeZone timezone) { + super(DvDateTimeParser.convertDateTime( + year, month, day, hour, 0, 0, 0.0, timezone)); + String format = timezone == null ? "yyyy-MM-dd'T'HH" : "yyyy-MM-dd'T'HHZZ"; + setValue(DvDateTimeParser.toDateTimeString(getDateTime(), format)); + setBooleans(true, false, false, false); + } + + /* (non-Javadoc) + * @see org.openehr.rm.datatypes.quantity.datetime.NDvWorldTime#parseValue(java.lang.String) + */ + @Override + DateTime parseStringValue(String value) { + return DvDateTimeParser.parseDateTime(value); + } + + /** + * Parses a string value and return a DvDateTime + */ + public DvDateTime parse(String value) { + DateTime datetime = DvDateTimeParser.parseDateTime(value); + return new DvDateTime(datetime); + } + + public static boolean isValidISO8601DateTime(String value) { + DateTime dt = null; + try { + dt = DvDateTimeParser.parseDateTime(value); + } catch (Exception e) { + return false; + } + return dt != null; + } + + @Override + public String getReferenceModelName() { + return ReferenceModelName.DV_DATE_TIME.getName(); + } + + /** + * Year + * + * @return year + */ + public int getYear() { + return getDateTime().getYear(); + } + + /** + * Month in year + * + * @return month in year + */ + public int getMonth() { + return getDateTime().getMonthOfYear(); + } + + /** + * Day in month + * + * @return day in month + */ + public int getDay() { + return getDateTime().getDayOfMonth(); + } + + /** + * Hour in day + * + * @return hour + */ + public int getHour() { + return getDateTime().getHourOfDay(); + } + + /** + * Minute in hour + * + * @return minute in hour + */ + public int getMinute() { + return minuteKnown() ? getDateTime().getMinuteOfHour() : -1; + } + + /** + * Second in minute + * + * @return second in minute + */ + public int getSecond() { + return secondKnown ? getDateTime().getSecondOfMinute() : -1; + } + + /** + * fractional seconds + * + * @return fractional seconds + */ + public double getFractionalSecond() { + return fractionalSecKnown ? getDateTime().getMillisOfSecond() / 10E2 + : -0.1; + } + + public boolean minuteKnown() { + return minuteKnown; + } + + public boolean secondKnown() { + return secondKnown; + } + + public boolean fractionalSecKnown() { + return fractionalSecKnown; + } + + public boolean isPartial() { + return isPartial; + } + + @Override + public Number getMagnitude() { + //TODO + return null; + } + + public DvDuration differenceOf(DvDateTime dt) { + return DvDuration.getDifference(this, dt); + } + + @Override + public boolean isStrictlyComparableTo(DvOrdered ordered) { + // TODO Auto-generated method stub + return false; + } + + /** + * If date is valid ISO8601 format + * + * @param year + * @param month + * @param day + * @return true if valid + */ + public static boolean isValidISO8601Time(String value) { + DateTime dt = null; + try { + dt = DvDateTimeParser.parseDateTime(value); + } catch (Exception e) { + return false; + } + return dt != null; + } + + /** + * Two DvDateTime equal if both have same year, month, day and timezone + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (!super.equals(o)) + return false; + + final DvDateTime dt = (DvDateTime) o; + + return new EqualsBuilder().append( + this.getDateTime().getZone().hashCode(), + this.getDateTime().getZone().hashCode()).append(isPartial, + dt.isPartial).append(minuteKnown, dt.minuteKnown).append( + secondKnown, dt.secondKnown).append(fractionalSecKnown, + dt.fractionalSecKnown).isEquals(); + } + + public String toString(boolean isExtended) { + String dt = super.toString(); + if (dt == null) { + dt = ""; + } else { + if (isExtended) { + dt = DvDateTimeParser.basicToExtendedDateTime(dt); + } else { + dt = dt.replace(":", "").replace("-", ""); + } + } + return dt; + } + + void setBooleans(boolean isPartial, boolean minuteKnown, + boolean secondKnown, boolean fractionalSecKnown) { + this.isPartial = isPartial; + this.minuteKnown = minuteKnown; + this.secondKnown = secondKnown; + this.fractionalSecKnown = fractionalSecKnown; + } + + void setBooleans(String value) { + int ele = DvDateTimeParser.analyseTimeString(value.substring(value + .indexOf("T") + 1)); + //isPartial, monthKnown, dayKnown + if (ele > 3) { + setMinuteKnown(true); + setSecondKnown(true); + setFractionalSecKnown(true); + } else if (ele == 3) { + setSecondKnown(true); + setMinuteKnown(true); + } else if (ele == 2) { + setMinuteKnown(true); + setIsPartial(true); + } else if (ele == 1) { + setIsPartial(true); + } + } + + void setMinuteKnown(boolean minuteKnown) { + this.minuteKnown = minuteKnown; + } + + void setSecondKnown(boolean secondKnown) { + this.secondKnown = secondKnown; + } + + void setFractionalSecKnown(boolean fractionalSecKnown) { + this.fractionalSecKnown = fractionalSecKnown; + } + + void setIsPartial(boolean isPartial) { + this.isPartial = isPartial; + } + + @Override + public DvDateTime add(DvDuration q) { + if (!getDiffType().isInstance(q)) { + throw new IllegalArgumentException("invalid difference type"); + } + DvDuration d = (DvDuration) q; + MutableDateTime mdate = getDateTime().toMutableDateTimeISO(); + mdate.add(d.getPeriod()); + + return new DvDateTime(getOtherReferenceRanges(), getNormalRange(), + getNormalStatus(), getAccuracy(), getMagnitudeStatus(), mdate + .toDateTimeISO(), this.toString()); + } + + @Override + public DvDateTime subtract(DvDuration q) { + if (!getDiffType().isInstance(q)) { + throw new IllegalArgumentException("invalid difference type"); + } + return add(q.negate()); + } + + /* fields */ + private boolean isPartial; + private boolean minuteKnown; + private boolean secondKnown; + private boolean fractionalSecKnown; + + @Override + public String serialise() { + return getReferenceModelName() + "," + toString(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 DvDateTime.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): Yin Su Lim + * + * 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/datetime/DvDateTimeParser.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeParser.java new file mode 100644 index 00000000..15d24129 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeParser.java @@ -0,0 +1,506 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvDateTimeParser" + * keywords: "datatypes" + * + * 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/datatypes/quantity/datetime/DvDateTimeParser.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.datatypes.quantity.datetime; + +import java.lang.IllegalArgumentException; +import java.util.TimeZone; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.DateTimeFormatterBuilder; +import org.joda.time.format.FormatUtils; +import org.joda.time.format.ISODateTimeFormat; +/** + * + * Parser class to parse parameters given to the constructors of DvDate, DvTime and DvDateTime + * + * @author Yin Su Lim + * @version 1.0 + */ +public class DvDateTimeParser { + + /* static field */ + //For parsing time element + static final DateTimeFormatter timeFormatter = ISODateTimeFormat.basicTime().withOffsetParsed(); + static final DateTimeFormatter eTimeParser = ISODateTimeFormat.timeParser().withOffsetParsed(); //extended + //static final DateTimeFormatter eTimePrinter = ISODateTimeFormat.time(); //extended printer + private static final String EXT_TIME = + "(\\d){2}(:(\\d){2}(:(\\d){2}((,|\\.)(\\d){1,})?)?)?(Z|(\\+|-)(\\d){2}((:)?(\\d){2})?)?"; + private static final String BTIME_COMPLETE = "(\\d){6}((,|\\.)(\\d){1,})?(Z|(\\+|-)(\\d){2,4})?"; + private static final String TIME_PARTIAL = "((\\d){2}|(\\d){4})(Z|(\\+|-)(\\d){2,4})?"; + private static final String EXT_DATE = "(\\d){4}(-(\\d){2}(-(\\d){2})?)?"; + private static final String BDATE = "(\\d){4}((\\d){2}((\\d){2})?)?"; + private static final String BDATETIME = "(\\d){8}T((\\d){2}|(\\d){4}|(\\d){6}((,|\\.)(\\d){1,})?)(Z|(\\+|-)(\\d){2,4})?"; + private static final String EXT_DATETIME = + "(\\d){4}-(\\d){2}-(\\d){2}T(\\d){2}(:(\\d){2}(:(\\d){2}((,|\\.)(\\d){1,})?)?)?(Z|(\\+|-)(\\d){2}((:)?(\\d){2})?)?"; + //For pasing date element + + + /** Creates a new instance of DvDateTimeParser */ + public DvDateTimeParser() { + } + + public static DateTime parseTime(String value) { + if(value == null) { + throw new IllegalArgumentException("null value"); + } + DateTime dt = null; + if (value.matches(EXT_TIME)) { + try { + //dealing with extended format(complete and partial) + dt = eTimeParser.parseDateTime(value); + } catch (Exception e) { + throw new IllegalArgumentException("invalid value for time in extended format: " + value); + } + } else if(value.matches(BTIME_COMPLETE)) { + value = value.replace(",", "."); + try { + dt = timeFormatter.parseDateTime(padTimeValue(value)); + } catch (Exception e) { + throw new IllegalArgumentException("invalid value for time in basic format: " + value); + } + } else if(value.matches(TIME_PARTIAL)) { + DateTimeFormatter partial = null; + int zonePosition = tZonePresent(value); + if(zonePosition > 0) { + String timeElem = value.substring(0, zonePosition); + if(timeElem.length() > 2) { + partial = new DateTimeFormatterBuilder().appendHourOfDay(2) + .appendMinuteOfHour(2).appendTimeZoneOffset("Z", false, 1, 2) + .toFormatter().withOffsetParsed(); + } else { + partial = new DateTimeFormatterBuilder().appendHourOfDay(2) + .appendTimeZoneOffset("Z", false, 1, 2).toFormatter().withOffsetParsed(); + } + } else { + if(value.length() > 2) { + partial = new DateTimeFormatterBuilder().appendHourOfDay(2) + .appendMinuteOfHour(2).toFormatter().withOffsetParsed(); + } else { + partial = new DateTimeFormatterBuilder().appendHourOfDay(2) + .toFormatter().withOffsetParsed(); + } + } + try { + dt = partial.parseDateTime(value); + } catch (Exception e) { + throw new IllegalArgumentException("invalid partial time value in basic format: " + value); + } + } else { + throw new IllegalArgumentException("invalid format for time: " + value); + } + + return dt; + } + + public static DateTime parseDate(String value) { + if(value == null) { + throw new IllegalArgumentException("null value for date"); + } + if (!value.matches(EXT_DATE) && !value.matches(BDATE)) { + throw new IllegalArgumentException("invalid pattern for date: " + value); + } + DateTime dt = null; + if (value.indexOf("-") > 0 || value.length() == 4) { + try { + dt = ISODateTimeFormat.dateElementParser().withOffsetParsed().parseDateTime(value); + } catch (Exception e) { + throw new IllegalArgumentException("invalid value for extended date: " + value); + } + } else { + int size = analyseDateString(value); + DateTimeFormatter formatter = null; + switch (size) { + case 1: formatter = ISODateTimeFormat.year().withOffsetParsed(); break; + case 2: formatter = DateTimeFormat.forPattern("yyyyMM").withOffsetParsed(); break; + case 3: formatter = ISODateTimeFormat.basicDate().withOffsetParsed();break; + } + try { + dt = formatter.parseDateTime(value); + } catch (Exception e) { + throw new IllegalArgumentException("invalid value for basic date: " + value); + } + } + return dt; + } + + public static DateTime parseDateTime(String value) { + if(value == null) { + throw new IllegalArgumentException("null value for datetime"); + } + if (!value.matches(EXT_DATETIME) && !value.matches(BDATETIME)) { + throw new IllegalArgumentException("invalid pattern for datetime: " + value); + } + DateTime dt = null; + if(value.indexOf("-") > 0) { + try { + dt = ISODateTimeFormat.dateTimeParser().withOffsetParsed().parseDateTime(value); + } catch (Exception e) { + throw new IllegalArgumentException("invalid value for datetime: " + value); + } + } else { + value = value.replace(".", ","); + int tEleSize = analyseTimeString(value.substring(9)); + String pattern = ""; + switch(tEleSize) { + case 1: pattern = "yyyyMMdd'T'HH"; break; + case 2: pattern = "yyyyMMdd'T'HHmm"; break; + case 3: pattern = "yyyyMMdd'T'HHmmss"; break; + case 4: pattern = "yyyyMMdd'T'HHmmss,SSSSSSSSS"; break; + } + if(tZonePresent(value) > 0) { + pattern = pattern + "Z"; + } + dt = DateTimeFormat.forPattern(pattern).withOffsetParsed().parseDateTime(value); + } + return dt; + } + + private static int tZonePresent(String value) { + if(value == null) { + return -1; + } else { + if(value.indexOf("Z") > 0 || value.indexOf("+") > 0 || + value.indexOf("-") > 0 ) { + String zonePatt = "(Z|\\+|-)"; + String[] splitStr = value.split(zonePatt); + return splitStr[0].length(); + } + return -1; + } + } + + /** + * Pad value time string with 000 (fractional seconds) and/or timezone, + * before passing the value to the Joda time format parser. + * The Joda basicTime formatter can only parse string in HHmmss.SSS(Z|+/-HHmm) + * format. All element must be present. + * + * @param value + * @return + */ + static String padTimeValue(String value) { + + //value = value.replace(",", "."); +// check if there's timezone element?... + int zonePst = tZonePresent(value); + + if ( zonePst > 0 ) { + //check if fractional sec is present + if (zonePst <= 6) { + value = value.substring(0, zonePst) + ".000" + value.substring(zonePst); + } + } else { + String zone = convertDefaultTimeZone(false); + if (value.length() <= 6) { + value = value + ".000" + zone; + } else { + value = value + zone; + } + } + return value; + } + + static String convertDefaultTimeZone(boolean isExtended) { + DateTime dt = new DateTime(); + return convertTimeZone(dt.getZone().getOffset(dt), isExtended); + } + + static String convertTimeZone(int tzMillis, boolean isExtended) { + if(tzMillis == 0) return "Z"; + int offset = Math.abs(tzMillis)/60000; //timezone in minutes + int hour = offset/60; + int minute = Math.abs(offset % 60); + StringBuffer sb = new StringBuffer(); + FormatUtils.appendPaddedInteger(sb, hour, 2); + if(isExtended) { + sb.append(":"); + } + FormatUtils.appendPaddedInteger(sb, minute, 2); + String result = sb.toString(); + return tzMillis < 0 ? "-" + result : "+" + result; + } + + public static DateTime convertTime(int hour, int minute, int second, double fractSec, + TimeZone timezone) { + if(fractSec > 1 || fractSec < 0) { + throw new IllegalArgumentException("invalid fractional second"); + } + return new DateTime(1970, 1, 1, hour, minute, second, (int)(fractSec*1000), + DateTimeZone.forTimeZone(timezone)); + } + + public static DateTime convertDate(int year, int month, int day) { + return new DateTime(year, month, day, 0, 0, 0, 0); + + } + + public static DateTime convertDateTime(int year, int month, int day, int hour, int minute, + int second, double fractSec, TimeZone timezone) { + if(fractSec > 1) { + throw new IllegalArgumentException("invalid fractional second"); + } + return new DateTime(year, month, day, hour, minute, second, (int)(fractSec*1000), + DateTimeZone.forTimeZone(timezone)); + } + + public static DateTime defaultTime() { + DateTime time = new DateTime(); + return new DateTime(1970, 1, 1, time.getHourOfDay(), time.getMinuteOfHour(), + time.getSecondOfMinute(), time.getMillisOfSecond()); + } + + public static DateTime defaultDate() { + DateTime date = new DateTime(); + return new DateTime(date.getYear(), date.getMonthOfYear(), date.getDayOfMonth(), + 0, 0, 0, 0); + } + + public static DateTime defaultDateTime() { + return new DateTime(); + } + + /** + * Return dateTime a valid time format + */ + public static String toTimeString(DateTime time, String pattern) { + if(pattern == null) { + throw new IllegalArgumentException("null pattern for time"); + } + if(pattern.equals("")) return ""; + String patt = null; + if(pattern.startsWith("HH")) { + patt = pattern; + } else { + boolean isExtended = pattern.indexOf(":") > 0; + boolean zoneExist = tZonePresent(pattern) > 0; + int formatInt = analyseTimeString(pattern); + switch (formatInt) { + case 1: if(zoneExist) { + patt = isExtended ? "HHZZ" : "HHZ"; + } else patt = "HH"; + break; + + case 2: if(zoneExist) { + patt = isExtended ? "HH:mmZZ" : "HHmmZ"; + } else patt = isExtended ? "HH:mm" : "HHmm"; + break; + + case 3: if(zoneExist) { + patt = isExtended ? "HH:mm:ssZZ" : "HHmmssZ"; + } else patt = isExtended ? "HH:mm:ss" : "HHmmss"; + break; + + case 4: if(zoneExist) { + patt = isExtended ? "HH:mm:ss,SSSZZ" : "HHmmss,SSSZ"; + } else patt = isExtended ? "HH:mm:ss,SSS" : "HHmmss,SSS"; + break; + + } + } + String result = time.toString(patt); + if(result.matches("((.*\\+00:00)||(.*-00:00))")) { + result = result.substring(0, result.length()- 6) + "Z"; + } else if (result.matches("((.*\\+0000)||(.*-0000))")) { + result = result.substring(0, result.length()- 5) + "Z"; + } + return result; + } + + /** + * Return dateTime in a valid date format + */ + public static String toDateString(DateTime date, String pattern) { + if(pattern == null) { + throw new IllegalArgumentException("null pattern for date"); + } + String patt = null; + if(pattern.startsWith("yyyy")) { + patt = pattern; + } else { + boolean isExtended = pattern.indexOf("-") > 0; + int formatInt = analyseDateString(pattern); + switch (formatInt) { + case 1: patt = "yyyy"; break; + case 2: patt = isExtended ? "yyyy-MM" : "yyyyMM"; break; + case 3: patt = isExtended ? "yyyy-MM-dd" : "yyyyMMdd"; break; + } + } + return date.toString(patt); + } + + /** + * Return dateTime in the pattern required + */ + public static String toDateTimeString(DateTime time, String pattern) { + if(pattern == null) { + throw new IllegalArgumentException("null pattern for datetime"); + } + if(pattern.startsWith("yyyy")) { + String result = time.toString(pattern); + if(result.matches("((.*\\+00:00)||(.*-00:00))")) { + result = result.substring(0, result.length()- 6) + "Z"; + } else if (result.matches("((.*\\+0000)||(.*-0000))")) { + result = result.substring(0, result.length()- 5) + "Z"; + } + return result; + } else { + int t = pattern.indexOf("T"); + if( t > 0) { + String dateEle = toDateString(time, pattern.substring(0, t)); + String timeEle = toTimeString(time, pattern.substring(t+1)); + return dateEle + "T" + timeEle; + } else { + return toDateString(time, pattern); + } + } + } + + + public static String addExtension(String pattern) { + + return pattern.replace("yM", "y-M").replace("Md", "M-d") + .replace("Hm", "H:m").replace("ms", "m:s"); + } + + /** + * Return an integer value to indicate the level of completeness of + * a String value that represents a valid point of time. + * -1 means invalid string value; + * 1 means only HH component is present; 2 means HHmm; + * 3 for HHmmss, 4 for HHmmss.SSS + * These result is regardless of the format of the time string + * (whether or not it is in extended format) + */ + public static int analyseTimeString(String value) { + + if(value == null || value.equals("")) { + return -1; + } + String timeComp = value; + int zonePst = tZonePresent(value); + if(zonePst > 0) { + timeComp = value.substring(0, zonePst); + } + timeComp = timeComp.replace(":", ""); + return timeComp.length()/2 > 4? 4 : timeComp.length()/2; + } + + /** + * Return an integer value to indicate the level of completeness of + * a String value that represents a valid date. + * -1 means invalid string value; + * 1 means only yyyy component is present; 2 means yyyyMM; + * 3 for yyyyMMdd + * These result is regardless of the format of the date string + * (whether or not it is in extended format) + */ + public static int analyseDateString(String value) { + + if(value == null || value.equals("")) { + //System.out.println("in exception"); + return -1; + } + String dateComp = value; + //int zonePst = tZonePresent(value);//TODO have a look + //if(zonePst > 0) { + // dateComp = value.substring(0, zonePst); + //} + dateComp = dateComp.replace("-", ""); + //System.out.println("string is " + dateComp); + return dateComp.length()/2 - 1; + } + + public static String basicToExtendedTime(String time) { + if(time.indexOf(":") > 0 || time.length() <= 2) { + return time; + } + int zonePst = tZonePresent(time); + StringBuffer timeAsBuffer = null; + StringBuffer zoneAsBuffer = null; + if(zonePst > 0) { + timeAsBuffer = new StringBuffer(time.substring(0, zonePst)); + zoneAsBuffer = new StringBuffer(time.substring(zonePst)); + } else { + timeAsBuffer = new StringBuffer(time); + zoneAsBuffer = new StringBuffer(""); + } + + int timeElemSize = analyseTimeString(time) > 3 ? 3 : analyseTimeString(time); + //insert ':' for time elements + for(int i = 0; i < timeElemSize -1; i++) { + timeAsBuffer.insert(2*(i+1) + i, ":"); + } + //now dealing with zone + if(zoneAsBuffer.length() > 3) { + zoneAsBuffer.insert(3, ":"); + } + return timeAsBuffer.append(zoneAsBuffer).toString(); + } + + public static String basicToExtendedDate(String date) { + if(date.indexOf("-") > 0 || date.length() <= 4) { + return date; + } + if(date.length() > 6) { + return date.substring(0,4) + "-" + date.substring(4,6) + "-" + date.substring(6); + } else { //(date.length() <= 6) + return date.substring(0,4) + "-" + date.substring(4); + } + } + + public static String basicToExtendedDateTime(String dtime) { + String date = dtime.substring(0, dtime.indexOf("T")); + String time = dtime.substring(dtime.indexOf("T")+1); + if(time.indexOf(":") < 0 && time.length() > 2) { + time = DvDateTimeParser.basicToExtendedTime(time); + } + if(date.indexOf("-") < 0) { + date = DvDateTimeParser.basicToExtendedDate(date); + } + return date + "T" + 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 DvDateTimeParser.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/datatypes/quantity/datetime/DvDuration.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDuration.java new file mode 100644 index 00000000..ff24c5f6 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDuration.java @@ -0,0 +1,622 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvDuration" + * 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/datetime/DvDuration.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datatypes.quantity.datetime; + +import java.util.List; + +import org.joda.time.DateTime; +import org.joda.time.Duration; +import org.joda.time.Instant; +import org.joda.time.MutablePeriod; +import org.joda.time.Period; +import org.joda.time.format.ISOPeriodFormat; +import org.joda.time.format.PeriodFormatter; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.datatypes.basic.ReferenceModelName; +import org.openehr.rm.datatypes.quantity.DvAmount; +import org.openehr.rm.datatypes.quantity.DvInterval; +import org.openehr.rm.datatypes.quantity.DvOrdered; +import org.openehr.rm.datatypes.quantity.DvQuantified; +import org.openehr.rm.datatypes.quantity.DvQuantity; +import org.openehr.rm.datatypes.quantity.ReferenceRange; +import org.openehr.rm.datatypes.text.CodePhrase; + +/** + * 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 + * @param accuracy + * @param accuracyPercent + * @param magnitudeStatus + * @param value + * @throws IllegalArgumentException + * if value has wrong format + */ + @FullConstructor + public DvDuration(@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 = "value") + String value) { + + super(otherReferenceRanges, normalRange, normalStatus, accuracy, + accuracyPercent, magnitudeStatus); + + DvDuration d = DvDuration.getInstance(value); + this.period = d.period; + setValue(value); + } + + /** + * Creates a simple DvDuration with string value + * + * @param value + */ + public DvDuration(String value) { + this(null, null, null, 0.0, false, null, value); + } + + /** + * Constructs a Duration with referenceRange and accuracy + * + * @param referenceRanges + * @param accuracy + * @param accuracyPercent + * @param days + * @param hours + * @param minutes + * @param seconds + * @param fractionalSeconds + */ + public DvDuration(List> referenceRanges, + DvInterval normalRange, double accuracy, + boolean accuracyPercent, int years, int months, int weeks, + int days, int hours, int minutes, int seconds, + double fractionalSeconds) { + + super(referenceRanges, normalRange, null, accuracy, accuracyPercent, + null); + + if (Math.abs(fractionalSeconds) >= 1.0) { + throw new IllegalArgumentException("invalid fraction seconds: " + + fractionalSeconds); + } + + if (!isValidCombination(years, months, weeks, days, hours, minutes, + seconds, fractionalSeconds)) { + throw new IllegalArgumentException("invalid combination for period"); + } + + period = new Period(years, months, weeks, days, hours, minutes, + seconds, (int) (fractionalSeconds * 1000)); + setValue(ISOPeriodFormat.standard().print(period).replace(".", ",")); + } + + /** + * Constructs a Duration without referenceRange and accuracy + * + * @param days + * @param hours + * @param minutes + * @param seconds + * @param fractionalSeconds + */ + public DvDuration(int years, int months, int weeks, int days, int hours, + int minutes, int seconds, double fractionalSeconds) { + this(null, null, 0.0, false, years, months, weeks, days, hours, + minutes, seconds, fractionalSeconds); + } + + protected DvDuration(List> referenceRanges, + DvInterval normalRange, CodePhrase normalStatus, + double accuracy, boolean accuracyPercent, String magnitudeStatus, + Period period) { + super(referenceRanges, normalRange, normalStatus, accuracy, + accuracyPercent, magnitudeStatus); + this.period = period; + setValue(ISOPeriodFormat.standard().print(period).replace(".", ",")); + } + + /** + * 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())); + } + + @Override + public String getReferenceModelName() { + return ReferenceModelName.DV_DURATION.getName(); + } + + /** + * Create a Duration from a ISO8601 string presentation + * + * @param value + * @throws IllegalArgumentException + * if value null or wrong format + */ + public static DvDuration getInstance(String value) { + if (value == null) { + throw new IllegalArgumentException("null value"); + } + + if (!value.matches(PATTERN)) { + throw new IllegalArgumentException("Wrong duration format: " + + value); + } + Period period = null; + if (value.startsWith("-")) { + value = value.substring(1, value.length()); // skip '-' + period = ISOPeriodFormat.standard().parsePeriod(value); + period = negatePeriod(period); + } else { + period = ISOPeriodFormat.standard().parsePeriod(value); + } + + return new DvDuration(null, null, null, 0.0, false, null, period); + } + + @Override + public DvDuration parse(String value) { + return getInstance(value); + } + + /** + * Helper method to negate a copy of period + * + * @param mPeriod + * @return a negated copy of period + */ + static Period negatePeriod(Period period) { + MutablePeriod mPeriod = period.toMutablePeriod(); + mPeriod.setYears(-mPeriod.getYears()); + mPeriod.setMonths(-mPeriod.getMonths()); + mPeriod.setWeeks(-mPeriod.getWeeks()); + mPeriod.setDays(-mPeriod.getDays()); + mPeriod.setHours(-mPeriod.getHours()); + mPeriod.setMinutes(-mPeriod.getMinutes()); + mPeriod.setSeconds(-mPeriod.getSeconds()); + mPeriod.setMillis(-mPeriod.getMillis()); + return mPeriod.toPeriod(); + } + + /** + * Converts a customary quantity to a scientific one for comparison or other + * purposes. + * + * @return quantity + */ + public DvQuantity toQuantity() { + return new DvQuantity("s", toDouble(), null); + } + + /** + * numeric value of the duration as seconds + * + * @return getMagnitude + */ + @Override + public Number getMagnitude() { + return new Double(toDouble()); + } + + // convert dvduration to seconds + private double toDouble() { + return Math + .abs(period.toDurationFrom(new Instant()).getMillis() / 10E2); + } + + /** + * Sum of this quantity and another whose formal type must be the difference + * type of this quantity. + * + * @param q + * @return production of addition + * @throws ClassCastException + */ + @Override + public DvQuantified add(DvQuantified q) { + final DvDuration d = (DvDuration) q; + + DateTime dt = new DateTime(0); + Duration duration = period.toDurationFrom(dt); + Duration result = duration.plus(d.period.toDurationFrom(dt)); + Period p = result.toPeriodFrom(dt); + + return new DvDuration(d.getOtherReferenceRanges(), d.getNormalRange(), + d.getNormalStatus(), d.getAccuracy(), d.isAccuracyPercent(), + d.getMagnitudeStatus(), p); + } + + /** + * Negated version of current object + * + * @return negated version + */ + public DvDuration negate() { + return new DvDuration(getOtherReferenceRanges(), getNormalRange(), + getNormalStatus(), getAccuracy(), isAccuracyPercent(), + getMagnitudeStatus(), negatePeriod(period)); + } + + /** + * Difference of this quantity and another whose formal type must be the + * difference type of this quantity type. + * + * @param q + * @return product of substraction + * @throws ClassCastException + */ + @Override + public DvQuantified subtract(DvQuantified q) { + final DvDuration d = (DvDuration) q; + + DateTime dt = new DateTime(0); + Duration duration = period.toDurationFrom(dt); + Duration result = duration.minus(d.period.toDurationFrom(dt)); + Period p = result.toPeriodFrom(dt); + + return new DvDuration(d.getOtherReferenceRanges(), d.getNormalRange(), + d.getNormalStatus(), d.getAccuracy(), d.isAccuracyPercent(), + d.getMagnitudeStatus(), p); + } + + /** + * Type of quantity which can be added or subtracted to this quantity. + * Usually the same type, but may be different as in the case of dates and + * times. + * + * @return diff type + */ + @Override + public Class getDiffType() { + return DvDuration.class; + } + + /** + * Following ISO 8601, starts with "P", and is followed by a list of + * periods, each appended by a single letter designator: "D" for days, "H" + * for hours, "M" for minutes, and "S" for seconds. + * + * @return string presentation + */ + @Override + public String toString() { + String str = value == null ? ISOPeriodFormat.standard().print(period) : value; + // No DvDuration will be constructed in P-1y3M24W format, it's either + // all negative or all positive values for each element. The only time + // this format will exist is after addition or subtraction. However, + // turning the Period to Duration then back to Period again will make + // the elements all positive or negative again, because Duration is + // based + // on milli second + + return toPrefixFormat(str); + } + + /** + * Gets the String value of this duration + */ + public String getValue() { + return toString(); + } + + /** + * Compares this object with the specified object for order. Returns a + * negative integer, zero, or a positive integer as this object is less + * than, equal to, or greater than the specified object. + * + * @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 DvDuration d = (DvDuration) o; + + /* + * if (period.getYears() > d.period.getYears()) { return 1; } else if + * (period.getYears() < d.period.getYears()) { return -1; } if + * (period.getMonths() > d.period.getMonths()) { return 1; } else if + * (period.getMonths() < d.period.getMonths()) { return -1; } if + * (period.getWeeks() > d.period.getWeeks()) { return 1; } else if + * (period.getWeeks() < d.period.getWeeks()) { return -1; } if + * (period.getDays() > d.period.getDays()) { return 1; } else if + * (period.getDays() < d.period.getDays()) { return -1; } + * + * if (period.getHours() > d.period.getHours()) { return 1; } else if + * (period.getHours() < d.period.getHours()) { return -1; } + * + * if (period.getMinutes() > d.period.getMinutes()) { return 1; } else + * if (period.getMinutes() < d.period.getMinutes()) { return -1; } + * + * if (period.getSeconds() > d.period.getSeconds()) { return 1; } else + * if (period.getSeconds() < d.period.getSeconds()) { return -1; } + * + * if (period.getMillis() > d.period.getMillis()) { return 1; } else if + * (period.getMillis() < d.period.getMillis()) { return -1; } + */ + DateTime dt = new DateTime(0); + Duration duration = period.toDurationFrom(dt); + Duration otherD = d.period.toDurationFrom(dt); + return duration.compareTo(otherD); + // return 0; + } + + /** + * number of years of nominal 365-day length + * + * @return years + */ + public int getYears() { + return period.getYears(); + } + + /** + * number of months of nominal 30 day length + * + * @return months + */ + public int getMonths() { + return period.getMonths(); + } + + public int getWeeks() { + return period.getWeeks(); + } + + /** + * number of 24 hour days + * + * @return days + */ + public int getDays() { + return period.getDays(); + } + + /** + * number of 60 minute hours + * + * @return hours + */ + public int getHours() { + return period.getHours(); + } + + /** + * number of 60 second minutes + * + * @return minutes + */ + public int getMinutes() { + return period.getMinutes(); + } + + /** + * number of seconds + * + * @return seconds + */ + public int getSeconds() { + return period.getSeconds(); + } + + /** + * fractional seconds + * + * @return fractional seconds + */ + public double getFractionalSeconds() { + return period.getMillis() / 10E2; + } + + /** + * If time is valid duration within 24h/60min/60sec system of time + * + * @param days + * @param hours + * @param minutes + * @param seconds + * @return true if value + */ + static boolean isValidCombination(int years, int months, int weeks, + int days, int hours, int minutes, int seconds, + double fractionalSeconds) { + int total = Math.abs(years) + Math.abs(months) + Math.abs(weeks) + + Math.abs(days) + Math.abs(hours) + Math.abs(minutes) + + Math.abs(seconds); + boolean zero = total == 0 && fractionalSeconds == 0.0; + if (!zero) { + int[] arr = { years, months, weeks, days, hours, minutes, seconds }; + int max = 0; + int min = 0; + for (int i = 0; i < arr.length; i++) { + max = Math.max(arr[i], max); + min = Math.min(arr[i], min); + } + if (max > 0) { + if (min < 0 || fractionalSeconds < 0.0) { + return false; + } + } + } + return true; + } + + /** + * If time is valid duration within 24h/60min/60sec system of time + * + * @param value + * @return true if value is valid + */ + /* + * public static boolean isValidDuration(String value) { DvDuration dd = + * null; try { dd = DvDuration.getInstance(value); } catch + * (IllegalArgumentException iae) { } return dd != null; } + */ + + /** + * Tests if two instances are strictly comparable. + * + * @param ordered + * @return true if two instances are strictly comparable + */ + @Override + public boolean isStrictlyComparableTo(DvOrdered ordered) { + return (ordered instanceof DvDuration); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof DvDuration)) { + return false; + } + if (!super.equals(o)) { + return false; + } + + final DvDuration dvDuration = (DvDuration) o; + + /* + * if (years != dvDuration.years) return false; if (months != + * dvDuration.months) return false; if (days != dvDuration.days) return + * false; if (fractionalSeconds != dvDuration.fractionalSeconds) return + * false; if (hours != dvDuration.hours) return false; if (minutes != + * dvDuration.minutes) return false; if (seconds != dvDuration.seconds) + * return false; + */ + + return period.equals(dvDuration.period); + } + + @Override + public int hashCode() { + int result = super.hashCode(); + long temp; + result = 29 * result + period.getYears(); + result = 29 * result + period.getMonths(); + result = 29 * result + period.getDays(); + result = 29 * result + period.getHours(); + result = 29 * result + period.getMinutes(); + result = 29 * result + period.getSeconds(); + temp = (period.getMillis() / 10E2) != +0.0d ? Double + .doubleToLongBits(fractionalSeconds) : 0l; + result = 29 * result + (int) (temp ^ (temp >>> 32)); + + return result; + } + + Period getPeriod() { + return period; + } + + void setValue(String value) { + this.value = toPrefixFormat(value); + } + + private String toPrefixFormat(String value) { + String str = value; + if (str.indexOf("-") > 0) { + str = "-" + str.replace("-", ""); + } + return str; + } + + // POJO end + + /* fields */ + // keep this temporarily for persistence purpose + // private int years, months, weeks, days, hours, minutes, seconds; + private double fractionalSeconds; + + private String value; + + private Period period; + + /* static value */ + private static final String PATTERN = "(-)?P((\\d)+(y|Y))?((\\d)+(m|M))?((\\d)+(w|W))?((\\d)+(d|D))?" + + "(T((\\d)+(h|H))?((\\d)+(m|M))?((\\d)+((,|\\.)(\\d){1,3})?(s|S))?)?"; + + // private static String PATTERN_DATE = + // "(-)?P((\\d)*(y|Y))?((\\d)*(m|M))?((\\d)*(d|D))"; + //private static PeriodFormatter formatter = ISOPeriodFormat.standard(); + + @Override + public String serialise() { + return getReferenceModelName() + "," + 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 DvDuration.java + * + * The Initial Developer of the Original Code is Rong Chen. Portions created by + * the Initial Developer are Copyright (C) 2003-2007 the Initial Developer. All + * Rights Reserved. + * + * Contributor(s): Yin Su Lim + * + * 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/quantity/datetime/DvTemporal.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvTemporal.java new file mode 100644 index 00000000..a9cf87fd --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvTemporal.java @@ -0,0 +1,234 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvTemporal" + * keywords: "datatypes" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.rm.datatypes.quantity.datetime; + +import java.util.List; + +import org.joda.time.DateTime; +import org.openehr.rm.datatypes.quantity.DvAbsoluteQuantity; +import org.openehr.rm.datatypes.quantity.DvInterval; +import org.openehr.rm.datatypes.quantity.DvOrdered; +import org.openehr.rm.datatypes.quantity.ReferenceRange; +import org.openehr.rm.datatypes.text.CodePhrase; + +/** + * Specialised temporal variant of DV_ABSOLUTE_QUANTITY whose diff type is + * DV_DURATION. + * + * @author Rong Chen + */ +public abstract class DvTemporal extends + DvAbsoluteQuantity { + + /** + * Construct a WorldTime string value + * + * @param otherReferenceRanges + * null if not specified + * @param normalReference + * @param accuracy + * 0 if not specified + * @param accuracyPercent + * @param value + * @param pattern + * @throws IllegalArgumentException + */ + public DvTemporal(List> otherReferenceRanges, + DvInterval normalRange, CodePhrase normalStatus, + DvDuration accuracy, String magnitudeStatus, String value) { + + super(otherReferenceRanges, normalRange, normalStatus, accuracy, + magnitudeStatus); + + this.dateTime = parseStringValue(value); + this.value = value; + setBooleans(value); + } + + protected DvTemporal(List> referenceRanges, + DvInterval normalRange, CodePhrase normalStatus, + DvDuration accuracy, String magnitudeStatus, DateTime datetime) { + + super(referenceRanges, normalRange, normalStatus, accuracy, + magnitudeStatus); + this.dateTime = datetime; + } + + /** + * Creates a DvTemporal only with datetime + * + * @param datetime not null + */ + protected DvTemporal(DateTime datetime) { + this(null, null, null, null, null, datetime); + } + + @Override + public DvDuration diff(T other) { + return DvDuration.getDifference(this, other); + } + + abstract DateTime parseStringValue(String value); + + abstract void setBooleans(String value); + + public DateTime getDateTime() { + return dateTime; + } + + /** + * Compares this object with the specified object for order. Returns a + * negative integer, zero, or a positive integer as this object is less + * than, equal to, or greater than the specified object. + * + * @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) { + DvTemporal d = (DvTemporal) o; + return getDateTime().compareTo(d.getDateTime()); + } + + /** + * Type of quantity which can be added or subtracted to this quantity. + * Usually the same type, but may be different as in the case of dates and + * times. + * + * @return diff type + */ + public Class getDiffType() { + return DvDuration.class; + } + + /** + * Return a hashcode of this DvDate + * + * @return hashcode + */ + public int hashCode() { + return dateTime.hashCode(); + } + + /** + * Two DvTemporal are equivalent if both indicate the same point of + * datetime + * + * + * @param o + * @return true if equals + */ + public boolean isEquivalent(Object o) { + if (this == o) + return true; + if (!(o instanceof DvTemporal)) + return false; + + final DvTemporal wt = (DvTemporal) o; + return this.dateTime.isEqual(wt.dateTime); + } + + /** + * Two DvTemporal are equal if both indicate the same point of + * datetime. This function should be overwritten in subclass. + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + return isEquivalent(o); + } + + /** + * Gets string presentation of this object + * + * @return string + */ + public String toString() { + return value; + } + + /** + * Gets the string value + * + * @return value + */ + public String getValue() { + return value; + } + + protected String timeZoneString() { + int offset = dateTime.getZone().getOffset(dateTime.getMillis()) / 60000; // timezone + // in + // minutes + int minute = offset % 60 >= 0 ? offset % 60 : -(offset % 60); + int hour = offset / 60; + if (minute == 0 && hour == 0) { + return "Z"; + } else { + String mStr = Integer.toString(minute); + mStr = mStr.length() > 1 ? mStr : "0" + mStr; + String hStr = hour > 0 ? "+" + Integer.toString(hour) : Integer + .toString(hour); + if (hStr.length() < 3) { + hStr = hStr.substring(0, 1) + "0" + hStr.substring(1); + } + return hStr + mStr; + } + } + + // POJO start + void setDateTime(DateTime dateTime) { + this.dateTime = dateTime; + } + + void setValue(String value) { + this.value = value; + } + + // POJO end + + /* fields */ + private DateTime dateTime; + private String value; +} +/* + * ***** 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 DvTemporal.java + * + * The Initial Developer of the Original Code is Rong Chen. Portions created by + * the Initial Developer are Copyright (C) 2007 the Initial Developer. All + * Rights Reserved. + * + * Contributor(s): Yin Su Lim + * + * 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/quantity/datetime/DvTime.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvTime.java new file mode 100644 index 00000000..3545ed07 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvTime.java @@ -0,0 +1,418 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvTime" + * keywords: "datatypes" + * + * 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/datatypes/quantity/datetime/DvTime.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.datatypes.quantity.datetime; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.joda.time.DateTime; +import org.joda.time.MutableDateTime; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.datatypes.quantity.DvInterval; +import org.openehr.rm.datatypes.quantity.DvOrdered; +import org.openehr.rm.datatypes.quantity.ReferenceRange; +import org.openehr.rm.datatypes.text.CodePhrase; + +import java.util.List; +import java.util.TimeZone; + +/** + * Represents an absolute point in time from an origin usually + * interpreted as meaning the start of the current day, specified to + * the second. + * + * @author Rong Chen + * @version 1.0 + * + * Warning: Current DvTime implementation only takes 3 decimal digits for fractional second, and + * does not take 24 for hour! + * + */ +public class DvTime extends DvTemporal { + + /** + * + */ + private static final long serialVersionUID = -6203478492778373210L; + /** + * Construct a DvTime + * + * @param otherReferenceRanges null if not specified + * @param normalRange null if not specified + * @param normalStatus null if not specified + * @param accuracy 0 if not specified + * @param accuracyPercent + * @param value + * @throws IllegalArgumentException + */ + @FullConstructor + public DvTime( + @Attribute(name = "otherReferenceRanges") List> otherReferenceRanges, + @Attribute(name = "normalRange") DvInterval normalRange, + @Attribute(name = "normalStatus") CodePhrase normalStatus, + @Attribute(name = "accuracy") DvDuration accuracy, + @Attribute(name = "magnitudeStatus") String magnitudeStatus, + @Attribute(name = "value", required = true) String value) { + super(otherReferenceRanges, normalRange, normalStatus, accuracy, + magnitudeStatus, value); + } + + /** + * Creates a DvTime with string value + * + * @param value + */ + public DvTime(String value) { + this(null, null, null, null, null, value); + } + + /** + * Constructs a DvTime + * + * @param hour + * @param minute + * @param second + * @param fs + * @param timezone null if use default timezone + */ + public DvTime(int hour, int minute, int second, double fs, TimeZone timezone) { + super(DvDateTimeParser.convertTime(hour, minute, second, fs, timezone)); + String format = timezone == null ? "HH:mm:ss,SSS" : "HH:mm:ss,SSSZZ"; + setValue(DvDateTimeParser.toTimeString(getDateTime(), format)); + setBooleans(false, true, true, true); + } + + /** + * Constructs a DvTime + * + * @param hour + * @param minute + * @param second + * @param timezone null if use default timezone + */ + public DvTime(int hour, int minute, int second, TimeZone timezone) { + super(DvDateTimeParser.convertTime(hour, minute, second, 0, timezone)); + String format = timezone == null ? "HH:mm:ss" : "HH:mm:ssZZ"; + setValue(DvDateTimeParser.toTimeString(getDateTime(), format)); + setBooleans(false, true, true, false); + } + + /** + * Constructs a partial DvTime + * + * @param hour + * @param minute + * @param timezone null if use default timezone + */ + public DvTime(int hour, int minute, TimeZone timezone) { + super(DvDateTimeParser.convertTime(hour, minute, 0, 0, timezone)); + String format = timezone == null ? "HH:mm" : "HH:mmZZ"; + setValue(DvDateTimeParser.toTimeString(getDateTime(), format)); + setBooleans(true, true, false, false); + } + + /** + * Constructs a partial DvTime + * + * @param hour + * @param timezone null if use default timezone + */ + public DvTime(int hour, TimeZone timezone) { + super(DvDateTimeParser.convertTime(hour, 0, 0, 0, timezone)); + String format = timezone == null ? "HH" : "HHZZ"; + setValue(DvDateTimeParser.toTimeString(getDateTime(), format)); + setBooleans(true, false, false, false); + } + + /** + * Constructs a DvTime with current point of time + * The format of time value as the result of this constructor + * is HH:mm:ss.SSSZZ + * + */ + public DvTime() { + super(DvDateTimeParser.defaultTime()); + setValue(DvDateTimeParser.toTimeString(getDateTime(), "HH:mm:ss,SSSZZ")); + setBooleans(false, true, true, true); + } + + /** + * Constructs a DvTime, mainly for use in addition and subtraction + */ + protected DvTime(List> referenceRanges, + DvInterval normalRange, CodePhrase normalStatus, + DvDuration accuracy, String magnitudeStatus, DateTime datetime, + String pattern) { + super(referenceRanges, normalRange, normalStatus, accuracy, + magnitudeStatus, datetime); + setValue(DvDateTimeParser.toTimeString(getDateTime(), pattern)); + setBooleans(pattern); + } + + @Override + public String getReferenceModelName() { + return "DV_TIME"; + } + + /** + * Hour in day + * + * @return hour in day + */ + public int getHour() { + return getDateTime().getHourOfDay(); + } + + /** + * Minute in hour + * + * @return minute in hour, -1 if minute unknown + */ + public int getMinute() { + return minuteKnown() ? getDateTime().getMinuteOfHour() : -1; + } + + /** + * Second in minute + * + * @return second, -1 if second unknown + */ + public int getSecond() { + return secondKnown ? getDateTime().getSecondOfMinute() : -1; + } + + /** + * Fractional seconds + * + * @return fractional seconds, -0.1 if fractional second unknown + */ + public double getFractionalSecond() { + return fractionalSecKnown ? getDateTime().getMillisOfSecond() / 10E2 + : -0.1; + } + + public boolean isPartial() { + return isPartial; + } + + public boolean minuteKnown() { + return minuteKnown; + } + + public boolean secondKnown() { + return secondKnown; + } + + public boolean hasFractionalSecond() { + return fractionalSecKnown; + } + + /** + * If date is valid ISO8601 format + * + * @param year + * @param month + * @param day + * @return true if valid + */ + public static boolean isValidISO8601Time(String value) { + DateTime dt = null; + try { + dt = DvDateTimeParser.parseTime(value); + } catch (Exception e) { + return false; + } + return dt != null; + } + + @Override + public Number getMagnitude() { + // TODO Auto-generated method stub + return null; + } + + @Override + public DvTime add(DvDuration q) { + if (!getDiffType().isInstance(q)) { + throw new IllegalArgumentException("invalid difference type"); + } + DvDuration d = (DvDuration) q; + MutableDateTime mdate = getDateTime().toMutableDateTimeISO(); + mdate.add(d.getPeriod()); + return new DvTime(getOtherReferenceRanges(), getNormalRange(), + getNormalStatus(), getAccuracy(), getMagnitudeStatus(), mdate + .toDateTimeISO(), this.toString()); + } + + @Override + public DvTime subtract(DvDuration q) { + if (!getDiffType().isInstance(q)) { + throw new IllegalArgumentException("invalid difference type"); + } + return add(q.negate()); + } + + @Override + public boolean isStrictlyComparableTo(DvOrdered ordered) { + // TODO Auto-generated method stub + return false; + } + + /** + * Two DvTime equal if both have same value for hour, minute, second + * and timezone + * + * @param o + * @return true if equals + */ + 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, + dtime.isPartial).append(minuteKnown, dtime.minuteKnown).append( + secondKnown, dtime.secondKnown).append(fractionalSecKnown, + dtime.fractionalSecKnown).isEquals(); + } + + public String toString(boolean isExtended) { + String time = super.toString(); + if (time == null) { + time = ""; + } else { + if (isExtended) { + time = DvDateTimeParser.basicToExtendedTime(time); + } else { + time = time.replace(":", ""); + } + } + return time; + } + + /** + * IsEquivalent for DvTime is valid only for point of time within one single day. + * For example, 00:00:01Z(for 1970-01-01) is supposed to be equivalent to the + * point of datetime 23:00:01-01(on 1969-12-31). However, because no date is involved + * in DvTime, 23:00:01-01 can only be treated as 23:00:01-01(of the same day as the other + * DvTime in comparison). So 23:00:01-01 is simply interpreted as a point of time on + * 1970-01-01 in a zone an hour behind UTC. + * + */ + public boolean isEquivalent(Object o) { + return super.isEquivalent(o); + } + + @Override + 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 + if (ele > 3) { + setSecondKnown(true); + setMinuteKnown(true); + setFractionalSecKnown(true); + } else if (ele == 3) { + setSecondKnown(true); + setMinuteKnown(true); + } else if (ele == 2) { + setMinuteKnown(true); + setIsPartial(true); + } else if (ele == 1) { + setIsPartial(true); + } + } + + private void setBooleans(boolean isPartial, boolean minuteKnown, + boolean secondKnown, boolean fractionalSecKnown) { + this.isPartial = isPartial; + this.minuteKnown = minuteKnown; + this.secondKnown = secondKnown; + this.fractionalSecKnown = fractionalSecKnown; + } + + void setIsPartial(boolean isPartial) { + this.isPartial = isPartial; + } + + void setMinuteKnown(boolean minuteKnown) { + this.minuteKnown = minuteKnown; + } + + void setSecondKnown(boolean secondKnown) { + this.secondKnown = secondKnown; + } + + void setFractionalSecKnown(boolean fractionalSecKnown) { + this.fractionalSecKnown = fractionalSecKnown; + } + + /* fields */ + private boolean isPartial; + private boolean minuteKnown; + private boolean secondKnown; + private boolean fractionalSecKnown; + @Override + public String serialise() { + return getReferenceModelName() + "," + toString(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 DvTime.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Yin Su Lim + * + * 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/text/CodePhrase.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/CodePhrase.java new file mode 100644 index 00000000..752bd1c2 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/CodePhrase.java @@ -0,0 +1,209 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CodePhrase" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/datatypes/text/CodePhrase.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datatypes.text; + +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; +import org.openehr.rm.support.identification.TerminologyID; +import org.openehr.rm.datatypes.basic.DataValue; +import org.openehr.rm.datatypes.basic.ReferenceModelName; + +/** + * A fully coordinated (all coordination has been performed) + * term from a terminologyId service (as distinct from a particular + * terminologyId). Instances of this class are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class CodePhrase extends DataValue { + + /** + * Constructs a CodePhrase by terminologyId and codeString + * + * @param terminologyId + * @param codeString + * @throws IllegalArgumentException if terminolgy null + * or codeString null or empty + */ + @FullConstructor + public CodePhrase( + @Attribute(name = "terminologyId", required = true) TerminologyID terminologyId, + @Attribute(name = "codeString", required = true) String codeString) { + + if(terminologyId == null) { + throw new IllegalArgumentException("null terminologyId"); + } + if(StringUtils.isEmpty(codeString)) { + throw new IllegalArgumentException("empty codeString"); + } + this.terminologyId = terminologyId; + this.codeString = codeString; + } + + /** + * Constructs a CodePhrase by terminologyId and codeString + * + * @param terminologyId + * @param codeString + * @throws IllegalArgumentException if terminolgy null + * or codeString null or empty + */ + public CodePhrase(String terminologyID, String codeString) { + if(terminologyID == null) { + throw new IllegalArgumentException("null terminologyId"); + } + if(StringUtils.isEmpty(codeString)) { + throw new IllegalArgumentException("empty codeString"); + } + this.terminologyId = new TerminologyID(terminologyID); + this.codeString = codeString; + } + + /** + * string form displayable for humans + * + * @return String + */ + public String toString() { + return terminologyId + "::" + codeString; + } + + public CodePhrase parse(String value) { + if(value == null) { + throw new IllegalArgumentException("null value"); + } + int i = value.indexOf("::"); + if(i <= 0 || i >= value.length() -1) { + throw new IllegalArgumentException("wrong format of code phrase"); + } + + String t = value.substring(0, i); + String c = value.substring(i + 2); + return new CodePhrase(t, c); + } + + /** + * Identifier of the distinct terminologyId from which the + * code_string (or its elements) was extracted. + * + * @return TerminologyID + */ + public TerminologyID getTerminologyId() { + return terminologyId; + } + + /** + * The key used by the terminologyId service to identify a concept + * or coordination of concepts. This string is most likely + * parsable inside the terminologyId service, but nothing can be + * assumed about its syntax outside that context. + * + * @return String + */ + public String getCodeString() { + return codeString; + } + + /** + * Two CodePhrases equal if both has same value for + * terminologyId and codeString + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof CodePhrase )) return false; + + final CodePhrase codePhrase = (CodePhrase) o; + + return new EqualsBuilder() + .append(terminologyId, codePhrase.terminologyId) + .append(codeString, codePhrase.codeString) + .isEquals(); + } + + /** + * Return a hash code of this CodePhrase + * + * @return a hash code + */ + public int hashCode() { + return new HashCodeBuilder(13, 47) + .append(terminologyId) + .append(codeString) + .toHashCode(); + } + + // POJO start + CodePhrase() { + } + + public void setTerminologyId(TerminologyID terminologyID) { + this.terminologyId = terminologyID; + } + + public void setCodeString(String codeString) { + this.codeString = codeString; + } + // POJO end + + /* fields */ + private TerminologyID terminologyId; + private String codeString; + @Override + public String getReferenceModelName() { + return ReferenceModelName.CODE_PHRASE.getName(); + } + + @Override + public String serialise() { + return getReferenceModelName() + "," + 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 CodePhrase.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/text/DvCodedText.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvCodedText.java new file mode 100644 index 00000000..a83bc762 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvCodedText.java @@ -0,0 +1,225 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvCodedText" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/datatypes/text/DvCodedText.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datatypes.text; + +import java.util.List; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.datatypes.basic.ReferenceModelName; +import org.openehr.rm.datatypes.uri.DvURI; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * A text item whose value must be the rubric from a controlled + * terminology, the key (the code ) of which is the + * defining code attribute. + * Instances of this class are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class DvCodedText extends DvText { + + /** + * + */ + private static final long serialVersionUID = 5514325220408145036L; + + /** + * + */ + /** + * Constructs a CodedText of given components + * + * @param value + * @param mapping + * @param formatting + * @param hyperlink + * @param language + * @param charset + * @param definingCode not null + * @param terminologyService not null + * @throws IllegalArgumentException if + */ + @FullConstructor + public DvCodedText( + @Attribute(name = "value", required = true) String value, + @Attribute(name = "mappings") List mapping, + @Attribute(name = "formatting") String formatting, + @Attribute(name = "hyperlink") DvURI hyperlink, + @Attribute(name = "language") CodePhrase language, + @Attribute(name = "charset") CodePhrase charset, + @Attribute(name = "definingCode", required = true) CodePhrase definingCode, + @Attribute(name = "terminologyService", system = true) + TerminologyService terminologyService) { + super(value, mapping, formatting, hyperlink, language, + charset, terminologyService); + if (definingCode == null) { + throw new IllegalArgumentException("null defining code"); + } + this.definingCode = definingCode; + } + + /** + * Constructs a Text by string value, language, charset and define code + * + * @param value + * @param language + * @param charset + * @param terminologyService not null + * @throws IllegalArgumentException if value, language or charset + * are empty or invalid + */ + public DvCodedText(String value, CodePhrase language, + CodePhrase charset, CodePhrase definingCode, + TerminologyService terminologyService) { + this(value, null, null, null, language, charset, + definingCode, terminologyService); + } + + /** + * Constructs a DvText by string value and defining code + * + * @param value + */ + public DvCodedText(String value, CodePhrase definingCode) { + this(value, null, null, definingCode, null); + } + + public DvCodedText(String value, String terminology, String code) { + this(value, new CodePhrase(terminology, code)); + } + + /** + * Return defining code + * + * @return defining code + */ + public CodePhrase getDefiningCode() { + return definingCode; + } + + @Override + public String getReferenceModelName() { + return ReferenceModelName.DV_CODED_TEXT.getName(); + } + + /** + * Two CodedText euqual if super class equals and has same value + * for defining code + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof DvCodedText )) return false; + if (!super.equals(o)) return false; + + final DvCodedText codedText = (DvCodedText) o; + + return new EqualsBuilder() + .append(definingCode, codedText.definingCode) + .isEquals(); + } + + /** + * Return a hash code of this CodedText + * + * @return hash code + */ + public int hashCode() { + int result = super.hashCode(); + result = 29 * result + definingCode.hashCode(); + return result; + } + + /** + * Return string presentation of this CodedText + * + * @return string presentation + */ + public String toString() { + return definingCode.toString() + "|" + getValue() + "|"; + } + + public String serialise() { + return getReferenceModelName() + "," + toString(); + } + + 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]); + } + + public String getTerminologyId(){ + return getDefiningCode().getTerminologyId().getValue(); + } + + public String getCode(){ + return getDefiningCode().getCodeString(); + } + + // POJO start + DvCodedText() { + } + + public void setDefiningCode(CodePhrase definingCode) { + this.definingCode = definingCode; + } + // POJO end + + /* fields */ + private CodePhrase definingCode; +} + +/* + * ***** 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 DvCodedText.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/text/DvParagraph.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvParagraph.java new file mode 100644 index 00000000..d300280e --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvParagraph.java @@ -0,0 +1,120 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvParagraph" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/datatypes/text/DvParagraph.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datatypes.text; + +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.datatypes.basic.DataValue; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * A logical composite text value consisting of a series of text. + * Instances of this class are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class DvParagraph extends DataValue { + + /** + * Create paragrah by items + * + * @param items not null or empty + * @throws IllegalArgumentException if items null or empty + */ + @FullConstructor + public DvParagraph( + @Attribute(name = "items", required = true) List items) { + if (items == null || items.size() == 0) { + throw new IllegalArgumentException("null or empty items"); + } + this.items = new ArrayList(items); + } + + /** + * Return string form displayable for humans + * + * @return string presentation + */ + public String toString() { + return items.toString(); + } + + /** + * Return items of this paragraph + * + * @return unmodifiable list of Text + */ + public List getItems() { + return Collections.unmodifiableList(items); + } + + // POJO start + DvParagraph() { + } + + public void setItems(List items) { + this.items = items; + } + // POJO end + + /* fields */ + private List items; + + @Override + public String getReferenceModelName() { + // TODO Auto-generated method stub + return null; + } + + @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 DvParagraph.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/text/DvText.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvText.java new file mode 100644 index 00000000..370cd952 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvText.java @@ -0,0 +1,310 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvText" + * 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/text/DvText.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datatypes.text; + +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; +import org.openehr.rm.datatypes.basic.DataValue; +import org.openehr.rm.datatypes.basic.ReferenceModelName; +import org.openehr.rm.datatypes.uri.DvURI; +import org.openehr.rm.support.terminology.OpenEHRCodeSetIdentifiers; +import org.openehr.rm.support.terminology.TerminologyService; + +import java.util.ArrayList; +import java.util.List; + +/** + * The Text class represents any kind of atomic text item, coded or + * uncoded. + * Instances of this class are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public class DvText extends DataValue { + + /** + * + */ + private static final long serialVersionUID = -5474907649298777278L; + /** + * Constructs a Text from the given components. + * + * @param value not null or empty or contains + * @param mappings null if unspecified + * @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 terminologyService not null + * @throws IllegalArgumentException if any of the components + * is invalid + */ + @FullConstructor public DvText( + @Attribute(name = "value", required = true) String value, + @Attribute(name = "mappings") List mappings, + @Attribute(name = "formatting") String formatting, + @Attribute(name = "hyperlink") DvURI hyperlink, + @Attribute(name = "language") CodePhrase language, + @Attribute(name = "encoding") CodePhrase charset, + @Attribute(name = "terminologyService", system = true) TerminologyService terminologyService) { + if (!validValue(value)) { + throw new IllegalArgumentException("invalid value: " + value); + } + if (mappings != null && mappings.isEmpty()) { + throw new IllegalArgumentException("empty mapping"); + } + if (formatting != null && StringUtils.isEmpty(formatting)) { + throw new IllegalArgumentException("empty formatting"); + } + if (language != null || charset != null) { + if (terminologyService == null) { + throw new IllegalArgumentException("null terminologyService"); + } + if (language != null && !terminologyService.codeSetForId( + OpenEHRCodeSetIdentifiers.LANGUAGES).hasCode(language)) { + throw new IllegalArgumentException( + "unknown language: " + language); + } + if (charset != null && !terminologyService.codeSetForId( + OpenEHRCodeSetIdentifiers.CHARACTER_SETS).hasCode(charset)) { + throw new IllegalArgumentException( + "unknown character set: " + charset); + } + } + this.value = value; + this.mappings = ( mappings == null ? + null : new ArrayList(mappings) ); + this.formatting = formatting; + this.hyperlink = hyperlink; + this.language = language; + this.encoding = charset; + } + + /** + * Constructs a DvText by string value, language and encoding + * + * @param value + * @param language + * @param encoding + * @param terminologyService + * @throws IllegalArgumentException if value, language or encoding + * are empty or invalid + */ + public DvText(String value, CodePhrase language, + CodePhrase charset, TerminologyService terminologyService) { + this(value, null, null, null, language, charset, + terminologyService); + } + + /** + * Constructs a DvText by required value + * + * @param value + */ + public DvText(String value) { + this(value, null, null, null, null, null, null); + } + + static boolean validValue(String value) { + return StringUtils.isNotEmpty(value) + && StringUtils.containsNone(value, "\n\r"); + } + + public DvText parse(String value) { + return new DvText(value); + } + + /** + * string form displayable for humans + * + * @return String + */ + public String toString() { + return value; + } + + /** + * Returns value of this Text + * + * @return string value + */ + public String getValue() { + return value; + } + + /** + * Return mappings of this Text + * + * @return null if unspecified + */ + public List getMappings() { + return mappings; + } + + /** + * Returns formatting of this Text + * + * @return null if unspecified + */ + public String getFormatting() { + return formatting; + } + + /** + * Returns hyperlink of this Text + * + * @return null if unspecified + */ + public DvURI getHyperlink() { + return hyperlink; + } + + /** + * Optional indicator of the localised language in which the value is + * written. Coded from openEHR Code Set languages. Only used when either + * the text object is in a different language from the enclosing ENTRY, + * or else the text object is being used outside of an ENTRY or other + * enclosing structure which indicates the language. + * + * @return language or null if not specified + */ + public CodePhrase getLanguage() { + return language; + } + + /** + * Name of character set in which this value is encoded. Coded from + * openEHR Code Set character sets. + * + * @return character set or null if not specified + */ + public CodePhrase getEncoding() { + return encoding; + } + + /** + * Returns true if both has the same values for string + * value, language and encoding, all optional attributes are not + * included in comparision + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof DvText )) return false; + + final DvText dvText = (DvText) o; + + return new EqualsBuilder() + .append(value, dvText.value) + .append(language, dvText.language) + .append(encoding, dvText.encoding) + .isEquals(); + } + + /** + * Returns a hash code of this Text + * + * @return hashcode + */ + public int hashCode() { + return new HashCodeBuilder(17, 47) + .append(value) + .append(language) + .append(encoding) + .toHashCode(); + } + + // POJO start + protected DvText() { + } + + public void setValue(String value) { + this.value = value; + } + + public void setMappings(List mappings) { + this.mappings = mappings; // todo: add unmodifiable + } + + protected void setFormatting(String formatting) { + this.formatting = formatting; + } + + protected void setHyperlink(DvURI hyperlink) { + this.hyperlink = hyperlink; + } + + public void setLanguage(CodePhrase language) { + this.language = language; + } + + public void setEncoding(CodePhrase charset) { + this.encoding = charset; + } + // POJO end + + /* fields */ + private String value; + private List mappings; + private String formatting; + private DvURI hyperlink; + private CodePhrase language; + private CodePhrase encoding; + @Override + public String getReferenceModelName() { + return ReferenceModelName.DV_TEXT.getName(); + } + + @Override + public String serialise() { + return getReferenceModelName() + "," + 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 DvText.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/text/Match.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/Match.java new file mode 100644 index 00000000..586e5f1d --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/Match.java @@ -0,0 +1,77 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Match" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/datatypes/text/Match.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datatypes.text; + + + +/** + * Enumeration of match between terms + * + * @author Rong Chen + * @version 1.0 + */ + +public enum Match { + NARROWER ("<"), + EQUIVALENT ("="), + BROADER (">"), + UNKNOWN ("?"); + + /* constructor */ + private Match(String value) { + this.value = value; + } + + /** + * Return value of this term match + * + * @return value + */ + public String getValue() { + return value; + } + + private String value; +} + +/* + * ***** 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 Match.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/text/TermMapping.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/TermMapping.java new file mode 100644 index 00000000..0d763efe --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/TermMapping.java @@ -0,0 +1,215 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TermMapping" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/datatypes/text/TermMapping.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +package org.openehr.rm.datatypes.text; + +import org.openehr.rm.datatypes.basic.DataValue; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * A mapping of a term to a text item. Instances of this class are + * immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class TermMapping extends DataValue { + + /** + * Constructs a TermMapping by target, match and purpose + * + * @param target not null + * @param match not null + * @param purpose null if unspecified + * @param terminologyService + * @throws IllegalArgumentException if any of arguments invalid + */ + public TermMapping(CodePhrase target, Match match, + DvCodedText purpose, + TerminologyService terminologyService) { + if (target == null) { + throw new IllegalArgumentException("null target"); + } + if (purpose != null) { + if (terminologyService == null) { + throw new IllegalArgumentException("null terminologyService"); + } + if (!terminologyService.terminology(TerminologyService.OPENEHR) + .codesForGroupName("term mapping purpose", "en") + .contains(purpose.getDefiningCode())) { + throw new IllegalArgumentException( + "unknown term mapping purpose: " + purpose); + } + } + if (match == null) { + throw new IllegalArgumentException("null match"); + } + this.target = target; + this.match = match; + this.purpose = purpose; + } + + /** + * Constructs a TermMapping by target and match + * + * @param target + * @param match + */ + public TermMapping(CodePhrase target, Match match) { + this(target, match, null, null); + } + + /** + * The target term of the mapping. + * + * @return target + */ + public CodePhrase getTarget() { + return target; + } + + /** + * The relative match of the target term with respect to the + * mapped text item. Result meanings: " > : the mapping is to a + * broader termm, eg, orginal text = arbovirus infection , + * target = viral infection " = : the mapping is to a + * (supposedly) equivalent to the original item " < : + * the mapping is to a narrower term. e.g. original text = + * diabetes , mapping = diabetes mellitus . " ? : the kind of + * mapping is unknown. + * + * @return match + */ + public Match getMatch() { + return match; + } + + /** + * Purpose of the mapping e.g. automated data mining , + * billing , interoperability + * + * @return purpose + */ + public DvCodedText getPurpose() { + return purpose; + } + + /** + * The mapping is to an equivalent term. + * + * @return is equivalent + */ + public boolean equivalent() { + return Match.EQUIVALENT.equals(match); + } + + /** + * The mapping is to a broader term. + * + * @return true if broader + */ + public boolean broader() { + return Match.BROADER.equals(match); + } + + /** + * The mapping is to a narrower term. + * + * @return true if narrower + */ + public boolean narrower() { + return Match.NARROWER.equals(match); + } + + /** + * The kind of mapping is unknown + * + * @return true if unknown + */ + public boolean unkonwn() { + return Match.UNKNOWN.equals(match); + } + + // POJO start + private TermMapping() { + } + + private void setTarget(CodePhrase target) { + this.target = target; + } + + private void setMatch(Match match) { + this.match = match; + } + + private void setPurpose(DvCodedText purpose) { + this.purpose = purpose; + } + + private String getMatchString() { + return match.toString(); + } + + private void setMatchString(String value) { + this.match = Match.valueOf(value); + } + + // POJO end + + /* fields */ + private CodePhrase target; + private Match match; + private DvCodedText purpose; + @Override + public String getReferenceModelName() { + // TODO Auto-generated method stub + return null; + } + + @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 TermMapping.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/timespec/DvGeneralTimeSpecification.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/timespec/DvGeneralTimeSpecification.java new file mode 100644 index 00000000..61ce5d8f --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/timespec/DvGeneralTimeSpecification.java @@ -0,0 +1,118 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvGeneralTimeSpecification" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/datatypes/timespec/DvGeneralTimeSpecification.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datatypes.timespec; + +import org.openehr.rm.datatypes.encapsulated.DvParsable; + +/** + * Specifies points in time in a general syntax. + * Based on the HL7v3 GTS data type. + * + * @author Rong Chen + * @version 1.0 + */ +public class DvGeneralTimeSpecification extends DvTimeSpecification { + + /** + * Constructs a GeneralTimeSpecification by given value + * + * @param value not null and value.formalism.is_equal( HL7:GTS ) + * @throws IllegalArgumentException if value is null or + * not valid HL7:GTS + */ + public DvGeneralTimeSpecification(DvParsable value) { + + super(value); + + if (!value.getFormalism().equals("HL7:GTS")) { + throw new IllegalArgumentException("unknown formalism: " + + value.getFormalism()); + } + } + + /** + * Indicates what prototypical point in the calendar the + * specification is aligned to, like 5th of the month. + * Extracted from the value attribute. + * + * @return calendar alignment + */ + public String calendarAlignment() { + return null; // todo: implement this method + } + + /** + * Indicates what real-world event the specification is aligned + * to if any. Extracted from the value attribute. + * + * @return event aligment + */ + public String eventAlignment() { + return null; // todo: implement this method + } + + /** + * Indicates if the specification is aligned with institution + * schedules, like a hospital nursing changeover or meal serving + * times. Extracted from the value attribute. + * + * @return true if institution specified + */ + public boolean institutionSpecified() { + return false; // todo: implement this method + } + + @Override + public String getReferenceModelName() { + // TODO Auto-generated method stub + return null; + } + + @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 DvGeneralTimeSpecification.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/timespec/DvPeriodicTimeSpecification.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/timespec/DvPeriodicTimeSpecification.java new file mode 100644 index 00000000..6120c645 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/timespec/DvPeriodicTimeSpecification.java @@ -0,0 +1,135 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvPeriodicTimeSpecification" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/datatypes/timespec/DvPeriodicTimeSpecification.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datatypes.timespec; + +import org.openehr.rm.datatypes.encapsulated.DvParsable; +import org.openehr.rm.datatypes.quantity.datetime.DvDuration; + +/** + * Specifies periodic points in time, linked to the calendar + * (phase-linked), or a real world repeating event, such as + * "breakfast" (event-linked). Based on the HL7v3 data types + * PIVL and EIVL. + * + * @author Rong Chen + * @version 1.0 + */ +public final class DvPeriodicTimeSpecification + extends DvTimeSpecification { + + /** + * Constructs a PeriodicTimeSpecification by given value + * + * @param value not null and value.formalism is either + * "HL7:PIVL" or "HL7:EIVL" + * @throws IllegalArgumentException if value is null or not valid + * HL7 PIVL or EIVL + */ + public DvPeriodicTimeSpecification(DvParsable value) { + + super(value); + + if (!"HL7:PIVL".equals(value.getFormalism()) + && !"HL7:EIVL".equals(value.getFormalism())) { + + throw new IllegalArgumentException("unknown formalism: " + + value.getFormalism()); + } + } + + /** + * The period of the repetition, computationally derived from the + * syntax representation. Extracted from the "value" attribute. + * + * @return period + */ + public DvDuration period() { + return null; // todo: fix it + } + + /** + * Indicates what prototypical point in the calendar the + * specification is aligned to, like 5th of the month. + * Extracted from the value attribute. + * + * @return calendar alignment + */ + public String calendarAlignment() { + return null; // todo: implement this + } + + /** + * Indicates what real-world event the specification is aligned + * to if any. Extracted from the value attribute. + * + * @return event alignment + */ + public String eventAlignment() { + return null; // todo: implement this + } + + /** + * Indicates if the specification is aligned with institution + * schedules, like a hospital nursing changeover or meal serving + * times. Extracted from the value attribute. + * + * @return true if specified by institution + */ + public boolean institutionSpecified() { + return false; // todo: implement this + } + + @Override + public String getReferenceModelName() { + // TODO Auto-generated method stub + return null; + } + + @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 DvPeriodicTimeSpecification.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/timespec/DvTimeSpecification.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/timespec/DvTimeSpecification.java new file mode 100644 index 00000000..40b4b6b5 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/timespec/DvTimeSpecification.java @@ -0,0 +1,111 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvTimeSpecification" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/datatypes/timespec/DvTimeSpecification.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datatypes.timespec; + +import org.openehr.rm.datatypes.basic.DataValue; +import org.openehr.rm.datatypes.encapsulated.DvParsable; + +/** + * This is an abstract class of which all timing + * specifications are specialisations. Specifies points in timespec, + * possibly linked to the calendar, or a real world repeating event, + * such as "breakfast". + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class DvTimeSpecification extends DataValue { + + /** + * Constructs a TimeSpecification by given components + * + * @param value not null + * @throws IllegalArgumentException if value null + */ + public DvTimeSpecification(DvParsable value) { + if(value == null) { + throw new IllegalArgumentException("null value"); + } + this.value = value; + } + + /** + * The specification, in the HL7v3 syntax for PIVL or EIVL types + * + * @return value + */ + public DvParsable getValue() { + return value; + } + + /** + * Indicates what prototypical point in the calendar the + * specification is aligned to, like 5th of the month. + * Extracted from the value attribute. + * + * @return calendar alignment + */ + public abstract String calendarAlignment(); + + /** + * Indicates what real-world event the specification is aligned + * to if any. Extracted from the value attribute. + * + * @return event alignment + */ + public abstract String eventAlignment(); + + /** + * Indicates if the specification is aligned with institution + * schedules, like a hospital nursing changeover or meal serving + * times. Extracted from the value attribute. + * + * @return true if specified by institution + */ + public abstract boolean institutionSpecified(); + + /* fields */ + private final DvParsable value; +} + +/* + * ***** 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 DvTimeSpecification.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/uri/DvEHRURI.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/uri/DvEHRURI.java new file mode 100644 index 00000000..e994dd53 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/uri/DvEHRURI.java @@ -0,0 +1,86 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvEHRURI" + * 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/uri/DvEHRURI.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datatypes.uri; + +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; + +/** + * A EHRURI is a URI which has the scheme name "ehr", and which can + * only reference elements in EHRs. + * + * @author Rong Chen + * @version 1.0 + */ +public final class DvEHRURI extends DvURI { + + /** + * Constructs a URI by parsing the given string. + * + * @param str The string to be parsed into a URI + * @throws IllegalArgumentException if str null or bad syntax + */ + @FullConstructor public DvEHRURI(@Attribute(name = "value", required = true) String value) { + super(value); + } + + public String scheme() { + return EHR_SCHEM; + } + + // POJO start + private DvEHRURI() { + super(); + } + // POJO end + + @Override + public String getReferenceModelName() { + return "DV_EHR_URI"; + } + + /* fields */ + private static final String EHR_SCHEM = "ehr"; +} + +/* + * ***** 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 DvEHRURI.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): Daniel Karlsson + * + * 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/uri/DvURI.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/uri/DvURI.java new file mode 100644 index 00000000..943f2c79 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/uri/DvURI.java @@ -0,0 +1,201 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvURI" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/datatypes/uri/DvURI.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datatypes.uri; + +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.datatypes.basic.DataValue; + +import java.net.URISyntaxException; + +/** + * Purpose A reference to an object which conforms to the Universal + * Resource Identifier (URI) standard, as defined by W3C RFC 2936. + *

+ * See "Universal Resource Identifiers in WWW" by Tim Berners-Lee at + * + * http://www.ietf.org/rfc/rfc2396.txt + * This is a World-Wide Web RFC for global identification of resources. + *

+ *

+ * See + * http://www.w3.org/Addressing for a starting point on URIs. + *

+ *

+ * See + * http://www.ietf.org/rfc/rfc2806.txt + * for new URI types like telephone, fax and modem numbers. + *

+ * + * Instances of this class are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public class DvURI extends DataValue { + + /** + * Constructs a URI by parsing the given string. + * + * @param str The string to be parsed into a URI + * @throws IllegalArgumentException if str null or bad syntax + */ + @FullConstructor public DvURI(@Attribute(name = "value", required = true) String value) { + loadValue(value); + } + + private void loadValue(String value) { + try { + this.value = new java.net.URI(value); + } catch(NullPointerException e) { + throw new IllegalArgumentException("null uri"); + } catch(URISyntaxException urise) { + throw new IllegalArgumentException("bad syntax: " + value); + } + } + + // POJO start + DvURI() { + } + + private void setValue(String value) { + loadValue(value); + } + // POJO end + + /** + * string form displayable for humans + * + * @return string presentation + */ + public String toString() { + return value.toString(); + } + + /** + * Returns the scheme component of this URI. + * + * @return scheme + */ + public String scheme() { + return value.getScheme(); + } + + /** + * Returns the decoded path component of this URI. + * + * @return path + */ + public String path() { + return value.getPath(); + } + + /** + * Returns the decoded fragment component of this URI. + * + * @return fragment + */ + public String fragmentID() { + return value.getFragment(); + } + + /** + * Returns the decoded query component of this URI. + * + * @return query + */ + public String query() { + return value.getQuery(); + } + + /** + * Return value of URI as a String. + * + * @return string value + */ + public String getValue() { + return value.toString(); + } + + /** + * Equals if values are the same + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof DvURI )) return false; + + final DvURI dvURI = (DvURI) o; + + if (!value.equals(dvURI.value)) return false; + + return true; + } + + /** + * Return a hashcode of this object + * + * @return hashcode + */ + public int hashCode() { + return value.hashCode(); + } + + /* fields */ + private java.net.URI value; + + @Override + public String getReferenceModelName() { + return "DV_URI"; + } + + @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 DvURI.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): Daniel Karlsson + * + * 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/security/AccessControlSettings.java b/openehr-rm-core/src/main/java/org/openehr/rm/security/AccessControlSettings.java new file mode 100644 index 00000000..bcf628cf --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/security/AccessControlSettings.java @@ -0,0 +1,58 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class AccessControlSettings" + * keywords: "security" + * + * 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/security/AccessControlSettings.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.security; + +/** + * + * @author Yin Su Lim + * @version 1.0 + */ +public abstract class AccessControlSettings { + + /** Creates a new instance of AccessControlSettings */ + public AccessControlSettings() { + } + +} + +/* + * ***** 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 AccessControlSettings.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/support/ExternalEnvironment.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/ExternalEnvironment.java new file mode 100644 index 00000000..e0e38f27 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/ExternalEnvironment.java @@ -0,0 +1,73 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ExternalEnvironment" + * keywords: "support" + * + * 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/support/ExternalEnvironment.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.support; + +import org.openehr.rm.support.measurement.MeasurementService; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * A mixin class providing access to services in the external environment + * + * @author Yin Su Lim + * @version 1.0 + */ +public interface ExternalEnvironment { + + /** + * Return an interface to the terminology servive + * + * @return terminology service not null + */ + public TerminologyService terminologyService(); + + + /** + * Return an interface to the measurement service + * + * @return measurement service not null + */ + public MeasurementService measurementService(); + +} + +/* + * ***** 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 ExternalEnvironment.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/support/basic/Interval.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/basic/Interval.java new file mode 100644 index 00000000..5b10a225 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/basic/Interval.java @@ -0,0 +1,243 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Interval" + * keywords: "support" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/support/basic/Interval.java $" + * revision: "$LastChangedRevision: 32 $" + * last_change: "$LastChangedDate: 2006-05-03 15:01:22 +0200 (Wed, 03 May 2006) $" + */ +package org.openehr.rm.support.basic; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.openehr.rm.RMObject; + +/** + * Interval of comparable items. Instances of this class + * are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class Interval extends RMObject { + + /** + * Constructs an Interval + * + * @param lower null if unbounded + * @param upper null if unbounded + * @param lowerIncluded if lower boundary inclusive + * @param upperIncluded if upper boundary inclusive + * @throws IllegalArgumentException if lower > upper + */ + public Interval(T lower, T upper, + boolean lowerInclusive, boolean upperInclusive) { + if (lower != null && upper != null + && upper.compareTo(lower) < 0) { + throw new IllegalArgumentException("lower > upper"); + } + this.lower = lower; + this.upper = upper; + this.lowerIncluded = (lower == null ? false : lowerInclusive); + this.upperIncluded = (upper == null ? false : upperInclusive); + } + + /** + * Constructs an inclusive Interval + * + * @param lower null if unbounded + * @param upper null if unbounded + * @throws IllegalArgumentException if lower > upper + */ + public Interval(T lower, T upper) { + this(lower, upper, true, true); + } + + /** + * Returns the lower boundary of this Interval + * + * @return null if unbounded + */ + public T getLower() { + return lower; + } + + /** + * Returns the upper boundary of this Interval + * + * @return null if unbounded + */ + public T getUpper() { + return upper; + } + + /** + * Returns true if lower boundary open + * + * @return true if has lower boundary + */ + public boolean isLowerUnbounded() { + return lower == null; + } + + /** + * Returns true if upper boundary open + * + * @return true if has upper boundary + */ + public boolean isUpperUnbounded() { + return upper == null; + } + + /** + * Return true if lower boundary inclusive + * + * @return true if inclusive + */ + public boolean isLowerIncluded() { + return lowerIncluded; + } + + /** + * Return true if upper boundary inclusive + * + * @return true if inclusive + */ + public boolean isUpperIncluded() { + return upperIncluded; + } + + /** + * Returns true if (lower >= value and value <= upper) + * + * @param value to compare to + * @return ture if given value is included in this Interval + * @throws IllegalArgumentException if value is null + */ + public boolean has(T value) { + if (value == null) { + throw new IllegalArgumentException("null value"); + } + return ( lower == null + || value.compareTo(lower) > 0 + || ( lowerIncluded && value.compareTo(lower) == 0 ) ) + && ( upper == null + || value.compareTo(upper) < 0 + || ( upperIncluded && value.compareTo(upper) == 0 ) ); + } + + /** + * Equals if two Intervals have same values for lower and + * upper boundaries + * + * @param o the object to compare with + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof Interval )) return false; + + final Interval interval = (Interval) o; + + return new EqualsBuilder() + .append(lower, interval.lower) + .append(upper, interval.upper) + .append(lowerIncluded, interval.lowerIncluded) + .append(upperIncluded, interval.upperIncluded) + .isEquals(); + } + + /** + * Return a hash code of this Interval + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder() + .append(lower) + .append(upper) + .append(lowerIncluded) + .append(upperIncluded) + .toHashCode(); + } + + /** + * Return string presentation of this Interval. The string + * consists of both lower and upper boundary, if any of them + * is not specified, "unbounded" is provided. + * + * @return string presentation + */ + public String toString() { + return new ToStringBuilder(this) + .append("lower", lower) + .append("lowerIncluded", lowerIncluded) + .append("upper", upper) + .append("upperIncluded", upperIncluded) + .toString(); + } + + // POJO start + private Interval() { + } + + public void setLower(T lower) { + this.lower = lower; + } + + public void setUpper(T upper) { + this.upper = upper; + } + + public void setLowerIncluded(boolean lowerInclusive) { + this.lowerIncluded = lowerInclusive; + } + + public void setUpperIncluded(boolean upperInclusive) { + this.upperIncluded = upperInclusive; + } + // POJO end + + /* fields */ + private T lower; + private T upper; + private boolean lowerIncluded; + private boolean upperIncluded; +} + +/* + * ***** 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 Interval.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/support/definition/OpenehrDefinitions.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/definition/OpenehrDefinitions.java new file mode 100644 index 00000000..e7f71650 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/definition/OpenehrDefinitions.java @@ -0,0 +1,61 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class OpenehrDefinitions" + * keywords: "support" + * + * 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/support/definition/OpenehrDefinitions.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.support.definition; + +/** + * Defines an object providing proxy access to a measurement information service. + * + * @author Yin Su Lim + * @version 1.0 + */ +public class OpenehrDefinitions { + + OpenehrDefinitions() { + } + + public final static char CR = '\015'; + public final static char LF = '\012'; + +} + +/* + * ***** 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 OpenehrDefinitions.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/support/identification/AccessGroupRef.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/AccessGroupRef.java new file mode 100644 index 00000000..369f846d --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/AccessGroupRef.java @@ -0,0 +1,65 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class AccessGroupRef" + * keywords: "support" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.rm.support.identification; + +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; + +/** + * Reference to access group in an access control service + * + * @author Rong Chen + */ +public class AccessGroupRef extends ObjectRef { + /** + * Construt an AccessGroupRef + * + * @param id + * @throws IllegalArgumentException if id or type null + */ + @FullConstructor + public AccessGroupRef( + @Attribute(name = "id", required = true)ObjectID id) { + super(id, "ACCESS_CONTROL", "ACCESS_GROUP"); + } +} +/* + * ***** 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 AccessGroupRef.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-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 new file mode 100644 index 00000000..9e017a3b --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ArchetypeID.java @@ -0,0 +1,419 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ArchetypeID" + * keywords: "common" + * + * 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.rm.support.identification; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.StringTokenizer; +import java.util.regex.Pattern; + +/** + * Identifier for archetypes, instances of this class are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class ArchetypeID extends ObjectID { + + /** + * Constructs an ArchetypeID by a string value + * + * @param value + * @throws IllegalArgumentException if value wrong format + */ + @FullConstructor + public ArchetypeID( + @Attribute(name = "value", required = true) String value) { + super(value); + loadValue(value); + } + + private void loadValue(String value) { + StringTokenizer tokens = new StringTokenizer(value, + AXIS_SEPARATOR); + if (tokens.countTokens() != 3) { + throw new IllegalArgumentException("bad format, wrong number of \"" + + AXIS_SEPARATOR + + "\", " + value); + } + qualifiedRmEntity = tokens.nextToken(); + domainConcept = tokens.nextToken(); + versionID = tokens.nextToken(); + + tokens = new StringTokenizer(qualifiedRmEntity, + SECTION_SEPARATOR); + if (tokens.countTokens() != 3) { + throw new IllegalArgumentException("bad format, wrong number of \"" + + SECTION_SEPARATOR + + "\" , " + value); + } + rmOriginator = tokens.nextToken(); + rmName = tokens.nextToken(); + rmEntity = tokens.nextToken(); + + tokens = new StringTokenizer(domainConcept, SECTION_SEPARATOR); + if (tokens.countTokens() < 1) { + throw new IllegalArgumentException( + "bad format, too few sections for domainConcept, " + value); + } + conceptName = tokens.nextToken(); + specialisation = new ArrayList(); + while(tokens.hasMoreTokens()) { + specialisation.add(tokens.nextToken()); + } + validateAll(); + } + + + // POJO start + ArchetypeID() { + } + + protected void setValue(String value) { + loadValue(value); + super.setValue(value); + } + // POJO end + + /** + * Create an ArchetypeID by axis and section values + * + * @param rmOriginator + * @param rmName + * @param rmEntity + * @param conceptName + * @param specialisation + * @param versionID + * @throws IllegalArgumentException if any axis or section value + * has wrong format + */ + public ArchetypeID(String rmOriginator, String rmName, + String rmEntity, String conceptName, + String specialisation, String versionID) { + super(toValue(rmOriginator, rmName, rmEntity, conceptName, + specialisation, versionID)); + this.qualifiedRmEntity = toQualifiedRmEntity(rmOriginator, + rmName, rmEntity); + this.domainConcept = toDomainConcept(conceptName, + specialisation); + this.rmOriginator = rmOriginator; + this.rmName = rmName; + this.rmEntity = rmEntity; + this.conceptName = conceptName; + this.specialisation = new ArrayList(); + if(specialisation != null) { + this.specialisation.add(specialisation); + } + this.versionID = versionID; + validateAll(); + } + + /** + * Create an ArchetypeID by axis and section values + * + * @param rmOriginator + * @param rmName + * @param rmEntity + * @param conceptName + * @param specialisation + * @param versionID + * @throws IllegalArgumentException if any axis or section value + * has wrong format + */ + public ArchetypeID(String rmOriginator, String rmName, + String rmEntity, String conceptName, + List specialisation, String versionID) { + super(toValue(rmOriginator, rmName, rmEntity, conceptName, + specialisation, versionID)); + this.qualifiedRmEntity = toQualifiedRmEntity(rmOriginator, + rmName, rmEntity); + this.domainConcept = toDomainConcept(conceptName, + specialisation); + this.rmOriginator = rmOriginator; + this.rmName = rmName; + this.rmEntity = rmEntity; + this.conceptName = conceptName; + this.specialisation = specialisation == null + ? Collections.EMPTY_LIST + : Collections.unmodifiableList(specialisation); + this.versionID = versionID; + validateAll(); + } + + // validate all axis and section values + private void validateAll() { + validateName(rmOriginator, "rm_originator"); + validateName(rmName, "rm_name"); + validateName(rmEntity, "rm_entity"); + validateName(conceptName, "concept_name"); + + if (specialisation != null) { + for(String name : specialisation) { + validateName(name, "specialisation"); + } + } + validateVersionID(versionID); + } + + // create value out of axis and section values + private static String toValue(String rmOriginator, + String rmName, + String rmEntity, + String conceptName, + String specialisation, + String versionID) { + return new StringBuffer(toQualifiedRmEntity(rmOriginator, + rmName, rmEntity)) + .append(AXIS_SEPARATOR) + .append(toDomainConcept(conceptName, specialisation)) + .append(AXIS_SEPARATOR) + .append(versionID) + .toString(); + } + + private static String toValue(String rmOriginator, String rmName, + String rmEntity, String conceptName, List specialisation, + String versionID) { + return new StringBuffer(toQualifiedRmEntity(rmOriginator, rmName, + rmEntity)).append(AXIS_SEPARATOR).append( + toDomainConcept(conceptName, specialisation)).append( + AXIS_SEPARATOR).append(versionID).toString(); + } + + private static String toQualifiedRmEntity(String rmOriginator, + String rmName, + String rmEntity) { + return new StringBuffer(rmOriginator) + .append(SECTION_SEPARATOR) + .append(rmName) + .append(SECTION_SEPARATOR) + .append(rmEntity) + .toString(); + } + + private static String toDomainConcept(String conceptName, + List specialisation) { + //return conceptName + ( specialisation == null + // ? "" : SECTION_SEPARATOR + specialisation ); + + StringBuffer buf = new StringBuffer(conceptName); + if(specialisation != null && !specialisation.isEmpty()) { + for(int i = 0, j = specialisation.size(); i < j; i++) { + buf.append(SECTION_SEPARATOR); + buf.append(specialisation.get(i)); + } + } + return buf.toString(); + } + + private static String toDomainConcept(String conceptName, + String specialisation) { + return conceptName + ( specialisation == null + ? "" : SECTION_SEPARATOR + specialisation ); + } + + + + private static void validateName(String value, String label) { + if (!NAME_PATTERN.matcher(value).matches()) { + throw new IllegalArgumentException("wrong format of " + + label + ": " + value); + } + } + + private static void validateVersionID(String version) { + if (!VERSION_PATTERN.matcher(version).matches()) { + throw new IllegalArgumentException( + "wrong format of versionID, " + version); + } + } + + /** + * Globally qualified reference model entity, + * eg "openehr-ehr_rm-entry" + * + * @return qualifiedRmEntity + */ + public String qualifiedRmEntity() { + return qualifiedRmEntity; + } + + /** + * Name of the concept represented by this archetype, including + * specialisation, eg "biochemistry result-cholesterol" + * + * @return domainConcept + */ + public String domainConcept() { + return domainConcept; + } + + /** + * Name of the concept represented by this archetype + * without specialisation + * + * @return conceptName + */ + public String conceptName() { + return conceptName; + } + + /** + * Organisation originating the reference model on which this + * archetype is based, eg "openehr", "cen", "hl7" + * + * @return rmOriginator + */ + public String rmOriginator() { + return rmOriginator; + } + + /** + * Name of the reference model, eg "rim", "ehr_rm", "en13606" + * + * @return rmName + */ + public String rmName() { + return rmName; + } + + /** + * Name of the ontological level within the reference model to + * which this archetype is targeted, eg for openEHR, "folder", + * "composition", "section", "entry" + * + * @return rmEntity + */ + public String rmEntity() { + return rmEntity; + } + + /** + * Name of specialisation of concept, if this archetype is a + * specialisation of another archetype, eg "cholesterol" + * + * @return specialisation list or empty if no specialisation + */ + public List specialisation() { + return specialisation; + } + + /** + * Return localID + * + * @return localID + */ + public String localID() { + return getValue(); + } + + /** + * Return versionID + * + * @return versionID + */ + public String versionID() { + return versionID; + } + + /** + * The contextID + * + * @return always null + */ + public UID contextID() { + return null; + } + + /** + * Return true if both archetypeId has the same value, and versionID is + * not included in comparison + * + * @return true if equals + */ + public boolean equalsIgnoreVersionID(ArchetypeID id) { + return new EqualsBuilder() + .append(qualifiedRmEntity, id.qualifiedRmEntity) + .append(domainConcept, id.domainConcept) + .isEquals(); + } + + /** + * A base of the archetypeId is the value of it without versionId + * + * @return base part of the archetypeId + */ + public String base() { + return new StringBuffer(toQualifiedRmEntity(rmOriginator, + rmName, rmEntity)) + .append(AXIS_SEPARATOR) + .append(toDomainConcept(conceptName, specialisation)) + .toString(); + } + + /* static fields */ + private static final String AXIS_SEPARATOR = "."; + private static final String SECTION_SEPARATOR = "-"; + + private static Pattern NAME_PATTERN = + Pattern.compile("[a-zA-Z][a-zA-Z0-9()_/%$#&]*"); + private static Pattern VERSION_PATTERN = + Pattern.compile("[a-zA-Z0-9]+"); + + /* fields */ + private String qualifiedRmEntity; // calculated + private String rmOriginator; + private String rmName; + private String rmEntity; + private String domainConcept; // calculated + private String conceptName; + private List specialisation; + private String versionID; +} + +/* + * ***** 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 ArchetypeID.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-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 new file mode 100644 index 00000000..f476d8a3 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/GenericID.java @@ -0,0 +1,118 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class GenericID" + * keywords: "support" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.rm.support.identification; + +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; + +/** + * Generic identifier type for identifiers whose format is otherwise unknown + * to openEHR. Includes an attribute for naming the identification scheme + * (which may well be local). + * + * @author Rong Chen + */ +public class GenericID extends ObjectID { + + @FullConstructor + public GenericID( + @Attribute(name = "value", required = true)String value, + @Attribute(name = "scheme", required = true)String scheme) { + super(value); + if(StringUtils.isEmpty(scheme)) { + throw new IllegalArgumentException("empty scheme"); + } + this.scheme = scheme; + } + + /** + * Gets scheme of this id + * + * @return scheme + */ + public String getScheme() { + return this.scheme; + } + + /** + * Equals if value and scheme equals + * + * @param o + * @return true if equals + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!( o instanceof GenericID )) { + return false; + } + + final GenericID gid = (GenericID) o; + + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(scheme, gid.scheme) + .isEquals(); + } + + /** + * Return hash code of this id + * + * @return hash code + */ + @Override + public int hashCode() { + return new HashCodeBuilder() + .appendSuper(super.hashCode()) + .append(scheme) + .toHashCode(); + } + + /* fields */ + private final String scheme; +} +/* + * ***** 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 GenericID.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2007 + * 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/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 new file mode 100644 index 00000000..d6aea84e --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/HierObjectID.java @@ -0,0 +1,176 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class HierObjectID" + * 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/support/identification/HierObjectID.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.support.identification; + +import org.apache.commons.lang.StringUtils; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; + +/** + * Hierarchical object identifiers. + *

+ * The syntax of the value attribute is as follows: + *

root::extension
+ * with the extension bit optional + *

+ *

Instances of this class are immutable.

+ * + * @author Yin Su Lim + * @version 1.0 + */ +public class HierObjectID extends UIDBasedID { + + /** + * Create HierObjectID by string value + * + * @param value + * @throws IllegalArgumentException if value is null + * + */ + @FullConstructor + public HierObjectID( + @Attribute(name = "value", required = true)String value) { + super(value); + loadValue(value); + } + + /** + * Constructs a HierObjectID by root and extension + * + * @param root + * @param extension + * @throws IllegalArgumentException if root is null + */ + public HierObjectID(String root, String extension) { + this(extension == null ? root : root + "::" + extension); + } + + /** + * Constructs a HierObjectID by root (UID) and extension + * + * @param root + * @param extension + * @throws IllegalArgumentException if root is null + */ + public HierObjectID(UID root, String extension) { + if(root == null) { + throw new IllegalArgumentException("null root"); + } + if(StringUtils.isEmpty(extension)) { + super.setValue(root.getValue()); + } else { + super.setValue(root.getValue() + "::" + extension); + } + this.root = root; + this.extension = extension; + } + + /** + * Load value into root and extension + * @param value + */ + private void loadValue(String value) { + int doubleColons = value.indexOf("::"); + // Check for root segment + if (doubleColons == 0) { + throw new IllegalArgumentException("bad format, missing root"); + } + //the patterns below are for sorting only, the correct syntax + //checking is handled by the UID sublcasses. + String rootStr = null; + if(doubleColons > 0) { + rootStr = value.substring(0, doubleColons); + } else { + rootStr = value; + } + if (rootStr.matches(UUID.SIMPLE_UUID_PATTERN)) { + root = new UUID(rootStr); + } else if (rootStr.matches("(\\d)+(\\.(\\d)+)*")) { //for ISO_OID + //System.out.println("in ISO"); + root = new ISO_OID(rootStr); + } else if (rootStr.matches("(\\w)+(\\.(\\w)+)*")){ //for InternetID, + root = new InternetID(rootStr); + } else { + throw new IllegalArgumentException("wrong format"); + } + + if( 0 < doubleColons && doubleColons < (value.length() - 2)) { + extension = value.substring(doubleColons + 2); + } + } + + /** + * The identifier of the conceptual namespace in which the object exists, + * within the identification scheme + * + * @return root + */ + @Override + public UID root() { + return root; + } + + /** + * A local identifier of the object within the context of the + * root identifier + * + * @return extension + */ + @Override + public String extension() { + return extension; + } + + // POJO start + @Override + protected void setValue(String value) { + loadValue(value); + super.setValue(value); + } + // POJO end + + /* fields */ + private UID root; // mandatory + private String extension; +} +/* + * ***** 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 HierObjectID.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/support/identification/ISO_OID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ISO_OID.java new file mode 100644 index 00000000..8778ad5d --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ISO_OID.java @@ -0,0 +1,82 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ISO_OID" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/support/identification/ISO_OID.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.support.identification; + +import org.ietf.jgss.GSSException; +import org.ietf.jgss.Oid; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; + +/** + * Purpose Model of ISO s Object Identifier (oid) as defined by the + * standard ISO/IEC 8824 . Oids are formed from integers separated by + * dots. Each non-leaf node in an Oid starting from the left + * corresponds to an assigning authority, and identifies that + * authority s namespace, inside which the remaining part of the + * identifier is locally unique. + * + * @author Rong Chen + * @version 1.0 + */ +public class ISO_OID extends UID { + + /** + * Constructs an ISO_OID by string value + * + * @param value + * @throws IllegalArgumentException if value null + * or wrong format + */ + @FullConstructor + public ISO_OID(@Attribute(name = "value", required = true)String value) { + super(value); + try { + new Oid(value); + } catch(GSSException gsse) { + throw new IllegalArgumentException( + "The provided value is not a legal format for an OID as defined by the ISO/IEC 8824. " + gsse); // root can only be 0,1,2 and for 0 and 1 then only 0..39 arcs + } + } +} + +/* + * ***** 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 ISO_OID.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/support/identification/InternetID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/InternetID.java new file mode 100644 index 00000000..e4cf5c9a --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/InternetID.java @@ -0,0 +1,79 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class InternetID" + * keywords: "support" + * + * 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/support/identification/InternetID.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.support.identification; + +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; + +/** + * Model of a reverse internet domain, as used to uniquely identify an internet domain. + * + * @author Yin Su Lim + * @version 1.0 + * + */ +public class InternetID extends UID { + + /** + * @param value + */ + @FullConstructor + public InternetID(@Attribute(name = "value", required = true)String value) { + super(value); + if (!value.matches(PATTERN)) { + throw new IllegalArgumentException("wrong format"); + } + /* or checking using java.net.URL ? + try { + URL url = new URL("http", value, 0, ""); + } catch (MalformedURLException e) { + throw new IllegalArgumentException("wrong format"); + } + * but this won't check the format of host or domain. + */ + } + + private static String PATTERN = "[a-zA-Z]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\\.[a-zA-Z]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*"; +} + +/* + * ***** 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 InternetID.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/support/identification/LocatableRef.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/LocatableRef.java new file mode 100644 index 00000000..81d3564d --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/LocatableRef.java @@ -0,0 +1,143 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class LocatableRef" + * keywords: "support" + * + * 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/support/identification/LocatableRef.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.support.identification; + +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; + + +/** + * Reference to a LOCATABLE instance inside the top-level content structure + * inside a VERSION; the path attribute is applied to the object that + * VERSION.data points to. + * + * @author Yin Su Lim + * @version 1.0 + */ +public class LocatableRef extends ObjectRef { + + /** + * Construct a LocatableRef + * + * @param id + * @param namespace + * @param type + */ + @FullConstructor + public LocatableRef( + @Attribute(name = "id", required = true)ObjectVersionID id, + @Attribute(name = "namespace", required = true)String namespace, + @Attribute(name = "type", required = true)String type, + @Attribute(name = "path")String path) { + super(id, namespace, type); + + if (path != null && StringUtils.isEmpty(path)) { + throw new IllegalArgumentException("empty path"); + } + this.path = path; + } + + /** + * The path to an instance in question, as an absolute path with + * respect to the object found at VERSION.data. An empty path + * means that the object referred to by id being specified. + */ + public String getPath() { + return path; + } + + /** + * A URI form of the reference, created by concatenating the + * following: + * "ehr://" + id.value + "/" + path + */ + public String asURI() { + return "ehr://" + getId().getValue() + "/" + path; + } + + /** + * Two LocatableReferences equals if they have same values for id, + * namespace, type and path. + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof ObjectRef )) return false; + if (!super.equals(o)) return false; + + final LocatableRef locRef = (LocatableRef) o; + + return new EqualsBuilder() + .append(path, locRef.path) + .isEquals(); + } + + /** + * Return a hash code of this locatable reference + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder() + .appendSuper(super.hashCode()) + .append(path) + .toHashCode(); + } + // POJO start + LocatableRef() { + } + + void setPath(String path) { + this.path = path; + } + + /* fields */ + private String path; +} + +/* + * ***** 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 LocatableRef.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/support/identification/ObjectID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ObjectID.java new file mode 100644 index 00000000..43ace975 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ObjectID.java @@ -0,0 +1,129 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ObjectID" + * 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/support/identification/ObjectID.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.support.identification; + +import org.apache.commons.lang.StringUtils; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.RMObject; + +/** + * Ancestor class of identifiers of informational objects. Ids may be + * completely meaningless, in which case their only job is to refer + * to something, or may carry some information to do with the + * identified object. + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class ObjectID extends RMObject { + + /** + * Create objectID by string value + * + * @param value + * @throws IllegalArgumentException if value is empty + */ + @FullConstructor + public ObjectID(String value) { + if (StringUtils.isEmpty(value)) { + throw new IllegalArgumentException("empty value"); + } + this.value = value; + } + + /** + * The value of this objectID + * + * @return value + */ + public String getValue() { + return value; + } + + /** + * Return true if both have same value and + * + * @param o The object to which this object is to be compared + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof ObjectID )) return false; + + final ObjectID casted = (ObjectID) o; + + return value.equals(casted.value); + } + + /** + * Return a hash code value of this objectID + * + * @return hash code + */ + public int hashCode() { + return value.hashCode(); + } + + /** + * Return value as string presentation of this objectID + * + * @return string presentation + */ + public String toString() { + return value; + } + + // POJO start + protected ObjectID() { + } + + void setValue(String value) { + this.value = value; + } + // POJO end + + /* fields */ + private String value; +} + +/* + * ***** 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 ObjectID.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/support/identification/ObjectRef.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ObjectRef.java new file mode 100644 index 00000000..ebc8d59a --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ObjectRef.java @@ -0,0 +1,214 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ObjectRef" + * 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/support/identification/ObjectRef.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.support.identification; + +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; + +/** + * Class describing a reference to another object, which may exist + * locally or be maintained outside the current namespace, eg in + * another service. Services are usually external, eg available in + * a LAN (including on the same host) or the internet via Corba, SOAP, + * or some other distributed protocol. However, in small systems they + * may be part of the same executable as the data containing the Id. + * + * @author Rong Chen + * @version 1.0 + */ +public class ObjectRef extends RMObject { + + + + /** + * Constructs an ObjectRef by id, namespace and type + * + * @param id not null + * @param namespace not null or empty + * @param type not null or empty + * @throws IllegalArgumentException if any invalid parameter + */ + @FullConstructor + public ObjectRef( + @Attribute(name = "id", required = true)ObjectID id, + @Attribute(name = "namespace", required = true)String namespace, + @Attribute(name = "type", required = true)String type) { + if (id == null) { + throw new IllegalArgumentException("null id"); + } + if (namespace == null) { + throw new IllegalArgumentException("null namespace"); + } + if (type == null) { + throw new IllegalArgumentException("null type"); + } + this.id = id; + this.namespace = namespace; + this.type = type; + } + + /** + * Globally unique id of an object, regardless of where + * it is stored + * + * @return ID + */ + public ObjectID getId() { + return id; + } + + /** + * Namespace to which this identifier belongs in the local system + * context (and possibly in any other openEHR compliant + * environment) eg "terminology", "demographic". + * These names are not yet standardised. Legal values for the + * namespace are "local" | "unknown" | + * "[a-zAZ][ a-zA-Z0-9_-:/&+?]*" + * + * @return namespace + */ + public String getNamespace() { + return namespace; + } + + /** + * Name of the class of object to which this identifier type + * refers, eg "PARTY", "PERSON", "GUIDELINE" etc. These class + * names are from the relevant reference model. The type name + * "ANY" can be used to indicate that any type is accepted + * (eg if the type is unknown). + * + * @return type + */ + public String getType() { + return type; + } + + /** + * Two ObjectReferences equals if they have same values for id, + * namespace and type. + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof ObjectRef )) return false; + + final ObjectRef objRef = (ObjectRef) o; + + return new EqualsBuilder() + .append(id, objRef.id) + .append(namespace, objRef.namespace) + .append(type, objRef.type) + .isEquals(); + } + + /** + * Return a hash code of this object reference + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder() + .append(id) + .append(namespace) + .append(type) + .toHashCode(); + } + + /** + * Return string presentation of this ObjectRef + * + * @return string presentation + */ + public String toString() { + return new StringBuffer() + .append("id: ") + .append(id) + .append(", namespace: ") + .append(namespace) + .append(", type: ") + .append(type) + .toString(); + } + + // POJO start + ObjectRef() { + } + + private void setOid(ObjectID id) { + this.id = id; + } + + private ObjectID getOid() { + return id; + } + + String getNamespaceString() { + return namespace.toString(); + } + + String getTypeString() { + return type.toString(); + } + + void setNamespaceString(String namespace) { + this.namespace = namespace; + } + + void setTypeString(String type) { + this.type = type; + } + // POJO end + + /* fields */ + private ObjectID id; + private String namespace; + private String type; +} + +/* + * ***** 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 ObjectRef.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-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 new file mode 100644 index 00000000..33666ba4 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/ObjectVersionID.java @@ -0,0 +1,184 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ObjectID" + * keywords: "support" + * + * 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/support/identification/ObjectVersionID.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.support.identification; + +import org.apache.commons.lang.StringUtils; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; + +/** + * Globally unique identifier for one version of a versioned object. + *

+ * The syntax of the value attribute is as follows: + *

objectID::creatingSystemID::versionTreeID
+ *

+ *

Instances of this class are immutable.

+ * + * @author Yin Su Lim + * @version 1.0 + */ + +public class ObjectVersionID extends UIDBasedID { + + /** + * Create ObjectVersionID by string value + * + * @param value + * @throws IllegalArgumentException if value is empty + */ + @FullConstructor + public ObjectVersionID( + @Attribute(name = "value", required = true)String value) { + super(value); + loadValue(value); + } + + public ObjectVersionID(String objectId, String creatingSystemId, String versionTreeId) { + this(objectId + "::" + creatingSystemId + "::" + versionTreeId); + } + + public ObjectVersionID(UID objectID, HierObjectID creatingSystemID, + VersionTreeID versionTreeID) { + this(objectID.toString() + "::" + creatingSystemID.toString() + "::" + + versionTreeID.toString()); + this.objectID = objectID; + this.creatingSystemID = creatingSystemID; + this.versionTreeID = versionTreeID; + } + + private void loadValue(String value) { + // Steps for value checking: + // 1. Check if value contains any :: or starts with :: + int doubleColons = value.indexOf("::"); + if (doubleColons <= 0) { + throw new IllegalArgumentException("bad format, missing objectId"); + } + // 2. Check how many segments in the value + String[] splits = value.split("::"); + int segments = splits.length; + if(segments < 3) { + throw new IllegalArgumentException("bad format, missing creatingSystemId or versionTreeId"); + } + if(segments > 4) { + throw new IllegalArgumentException("bad format, too many segments or '::'"); + } + // 3. Construct objects for each segment + //the patterns below are for sorting only, the correct syntax + //checking is handled by the UID sublcasses. + if (splits[0].matches(UUID.SIMPLE_UUID_PATTERN)) { //pattern for UUID + objectID = new UUID(value.substring(0, doubleColons)); + } else if (splits[0].matches("(\\d)+(\\.(\\d)+)*")) { //for ISO_OID + objectID = new ISO_OID(value.substring(0, doubleColons)); + } else if (splits[0].matches("(\\w|-)+(\\.(\\w|-)+)*")){ //for InternetID, + objectID = new InternetID(value.substring(0, doubleColons)); + } else { + throw new IllegalArgumentException("wrong format: " + splits[0]); + } + if(segments == 4) { + creatingSystemID = new HierObjectID(splits[1] + "::" + splits[2]); + versionTreeID = new VersionTreeID(splits[3]); + } else { + creatingSystemID = new HierObjectID (splits[1]); + versionTreeID = new VersionTreeID(splits[2]); + } + } + + /** + * Unique identifier that identifies one version. It is + * normally the unique identifier of the version container + * containing the version referred to by this objectVersionID + * instance. + * + * @return objectID + */ + public UID objectID() { + return objectID; + } + + /** + * Tree identifier of this version with prespect to other versions + * in the same version tree, as either 1 or 3 part dot-separated numbers + * e.g. "1" , "2.1.4" + * + * @return versionTreeID + */ + public VersionTreeID versionTreeID() { + return versionTreeID; + } + + /** + * Identifier of the system that created the Version + * corresponding to this ObjectVersionID + * + * @return creatingSystemID + */ + public HierObjectID creatingSystemID() { + return creatingSystemID; + } + + @Override + public UID root() { + return objectID(); + } + + @Override + public String extension() { + return creatingSystemID.getValue() + "::" + versionTreeID.getValue(); + } + + //POJO start + ObjectVersionID() { + } + + protected void setValue(String value) { + loadValue(value); + super.setValue(value); + } + // POJO end + + /* fields */ + private UID objectID; + private VersionTreeID versionTreeID; + private HierObjectID creatingSystemID; +} +/* + * ***** 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 ObjectVersionID.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/support/identification/PartyRef.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/PartyRef.java new file mode 100644 index 00000000..7b0828b6 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/PartyRef.java @@ -0,0 +1,77 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class PartyRef" + * 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/support/identification/PartyRef.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.support.identification; + +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; + +/** + * Identifier for parties in a demographic service. There are + * typically a number of subtypes of the "PARTY" class, including + * "PERSON", "ORGANISATION", etc. + * + * @author Rong Chen + * @version 1.0 + */ +public class PartyRef extends ObjectRef { + + // POJO start + PartyRef() { + } + // POJO end + + /** + * Construt a PartyRef + * + * @param id + * @throws IllegalArgumentException if id or type null + */ + @FullConstructor + public PartyRef( + @Attribute(name = "id", required = true)ObjectID id, + @Attribute(name = "type", required = true)String type) { + super(id, "DEMOGRAPHIC", type); + } +} + +/* + * ***** 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 PartyRef.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-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 new file mode 100644 index 00000000..112c67f9 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/TemplateID.java @@ -0,0 +1,60 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TemplateID" + * keywords: "support" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.rm.support.identification; + +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; + +/** + * Identifier for templates. Lexical form to be determined. + * + * @author Rong Chen + */ +public class TemplateID extends ObjectID { + + @FullConstructor + public TemplateID( + @Attribute(name = "value", required = true)String value) { + super(value); + } +} +/* + * ***** 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 TemplateID.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2007 + * 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/support/identification/TerminologyID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/TerminologyID.java new file mode 100644 index 00000000..53dfb186 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/TerminologyID.java @@ -0,0 +1,139 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TerminologyID" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/support/identification/TerminologyID.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.support.identification; + +import org.apache.commons.lang.StringUtils; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; + +/** + * Terminology identifier. Instances of this class are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class TerminologyID extends ObjectID { + + /** + * Constructs a TerminologyID by name and version + * + * @param name + * @param version null if not present + * @throws IllegalArgumentException if name is empty + */ + public TerminologyID(String name, String version) { + + super(toValue(name, version)); + + this.name = name; + this.version = version; + } + + /** + * Constructs a TerminologyID by string value + * + * @param value + * @throws IllegalArgumentException if value empty or wrong format + */ + @FullConstructor + public TerminologyID( + @Attribute(name = "value", required = true)String value) { + super(value); + loadValue(value); + } + + private void loadValue(String value) { + int leftBrace = value.indexOf("("); + int rightBrace = value.lastIndexOf(")"); + if (leftBrace > 1 && rightBrace == value.length() - 1) { + name = value.substring(0, leftBrace); + version = value.substring(leftBrace + 1, rightBrace); + } else { + name = value; + version = null; + } + } + + private static String toValue(String name, String version) { + if (StringUtils.isEmpty(name)) { + throw new IllegalArgumentException("empty name"); + } + return name + ( version == null ? + "" : "(" + version + ")" ); + } + + /** + * Name of this terminology ID + * + * @return name + */ + public String name() { + return name; + } + + /** + * Return version of information pointed to by this ID, + * if versioning is supported. + * + * @return versionID null if not present + */ + public String versionID() { + return version; + } + + // POJO start + TerminologyID() { + } + + void setValue(String value) { + loadValue(value); + super.setValue(value); + } + // POJO end + + /* fields */ + private String name; + private String version; +} + +/* + * ***** 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 TerminologyID.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/support/identification/UID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/UID.java new file mode 100644 index 00000000..68d6d428 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/UID.java @@ -0,0 +1,118 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class UID" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/support/identification/UID.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.support.identification; + +import org.apache.commons.lang.StringUtils; + +/** + * Purpose Anstract 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 + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class UID { + + /** + * Create an UID by value + * + * @param value + * @throws IllegalArgumentException if value null + */ + protected UID(String value) { + if(StringUtils.isEmpty(value)) { + throw new IllegalArgumentException("empty value"); + } + this.value = value; + } + + /** + * The value of this id + * + * @return value + */ + public String getValue() { + return value; + } + + /** + * Return string presentation of this id + * + * @return string presentation + */ + public String toString() { + return value; + } + + /** + * Two UID equal if both have same value + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof UID )) return false; + + final UID uid = (UID) o; + + return value.equals(uid.value); + } + + /** + * Return a hash code of this UID + * + * @return hash code + */ + public int hashCode() { + return value.hashCode(); + } + + /* fields */ + private String value; +} + +/* + * ***** 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 UID.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/support/identification/UIDBasedID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/UIDBasedID.java new file mode 100644 index 00000000..c1050cdd --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/UIDBasedID.java @@ -0,0 +1,95 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class UIDBasedID" + * keywords: "support" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.rm.support.identification; + +import org.apache.commons.lang.StringUtils; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; + +/** + * Abstract model of UID-based identifiers consisting of a root part and + * an optional extension; lexical form: root "::" extension + * + * @author Rong Chen + */ +public abstract class UIDBasedID extends ObjectID { + + /** + * Creates a UIDBasedID + * + * @param value + */ + @FullConstructor + public UIDBasedID(@Attribute(name = "value", required = true)String value) { + super(value); + } + + protected UIDBasedID() {} + + /** + * The identifier of the conceptual namespace in which the object exists, + * within the identification scheme. + * + * @returns the part to the left of the first ‘::’ separator, if any, + * or else the whole string + */ + public abstract UID root(); + + /** + * Optional local identifier of the object within the context of the root + * identifier. + * + * @returns the part to the right of the first ‘::’ separator if any, + * or else any empty String + */ + public abstract String extension(); + + /** + * True if extension is not empty + * + * @return true if extension not empty + */ + public boolean hasExtension() { + return !StringUtils.isEmpty(extension()); + } +} +/* + * ***** 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 UIDBasedID.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2007 + * 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/support/identification/UUID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/UUID.java new file mode 100644 index 00000000..a3c12023 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/UUID.java @@ -0,0 +1,77 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class UUID" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/support/identification/UUID.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.support.identification; + +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; + +/** + * Purpose Model of the DCE Universal Unique Identifier or UUID which + * takes the form of hexadecimal integers separated by hyphens, + * following the pattern 8-4-4-4-12 as defined by the Open Group, + * CDE 1.1 Remote Procedure Call specification, + * + * @author Rong Chen + * @version 1.0 + */ +public class UUID extends UID { + + /** + * Simple UUID pattern + */ + public static final String SIMPLE_UUID_PATTERN = "([0-9a-fA-F])+(-([0-9a-fA-F])+)*"; + + /** + * Constructs an UUID + * + * @param value + */ + @FullConstructor + public UUID(@Attribute(name = "value", required = true)String value) { + super(value); + // kind of validation + java.util.UUID.fromString(value); + } +} + +/* + * ***** 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 UUID.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/support/identification/VersionTreeID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/VersionTreeID.java new file mode 100644 index 00000000..c1b7cd53 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/VersionTreeID.java @@ -0,0 +1,257 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class VersionTreeID" + * keywords: "support" + * + * 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/support/identification/VersionTreeID.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.support.identification; + +import org.apache.commons.lang.StringUtils; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.RMObject; + +/** + * Version tree identifier for one version + * The format of the identifier is: + * [..] + * + * @author Yin Su Lim + * @version 1.0 + */ +public class VersionTreeID extends RMObject { + + /** + * Contruct VersionTreeID by string value + * + * @param value + * @throws IllegalArgumentException if value is null or empty + */ + @FullConstructor + public VersionTreeID(@Attribute(name = "value", required = true)String value) { + if (StringUtils.isEmpty(value)) { + throw new IllegalArgumentException("empty value"); + } + loadValue(value); + //this.value = value; + } + + + /** + * Contruct VersionTreeID by value of trunkVersion, branchNumber + * and branchVersion. All valid integers must be >= 1. + * Special case branchNumber == 0 && branchVersion == 0 indicates no branch. + * + * @param trunkVersion + * @param branchVersion + * @param branchNumber + * @throws IllegalArgumentException + */ + public VersionTreeID(int trunkVersion, int branchNumber, + int branchVersion) { + validateValues(trunkVersion, branchNumber, branchVersion); + String trunk = Integer.toString(trunkVersion); + this.trunkVersion = trunk; + if(branchNumber > 0 ) { + this.value = trunk + "." + Integer.toString(branchNumber) + "." + + Integer.toString(branchVersion); + this.branchNumber = Integer.toString(branchNumber); + this.branchVersion = Integer.toString(branchVersion); + } else { + this.value = trunk; + } + } + + private void loadValue(String value) { + if (!value.matches(PATTERN)) { + throw new IllegalArgumentException("wrong format"); + } + int branch = value.indexOf("."); + if (branch < 0) { // no branch, just trunk + //validateValues(Integer.parseInt(value), 0, 0); + this.trunkVersion = value; + this.value = value; + } else { + String[] entries = value.split("\\."); + //System.out.println("in loadValues, size of entries:" + entries.length); + validateValues(Integer.parseInt(entries[0]), Integer.parseInt(entries[1]), + Integer.parseInt(entries[2])); + this.trunkVersion = entries[0]; + //never set branchNo or branchV to 0 + if(Integer.parseInt(entries[1]) > 0) { + this.branchNumber = entries[1]; + this.branchVersion = entries[2]; + this.value = value; + } else { + this.value = entries[0]; + } + } + } + + private void validateValues(int trunk, int branchNo, int branchV) { + if (trunk < 1 || branchNo < 0 || branchV < 0) { + throw new IllegalArgumentException("version number smaller than 0"); + } + //0 for branchNo or branchV is special case, + //where both must be 0 to indicate no branch + if (branchNo == 0 || branchV == 0) { + if (branchV != branchNo) { + throw new IllegalArgumentException("breach of branch_validity"); + } + } + } + + + public String getValue() { + return value; + } + + /** + * Trunk version number + * + *@return trunkVersion + */ + public String trunkVersion() { + return trunkVersion; + } + + /** + * Number of brnach from the trunk point + * + *@return + */ + public String branchNumber() { + return branchNumber; + } + + /** + * Version of the branch + * + *@return branchVersion + */ + public String branchVersion() { + return branchVersion; + } + + /** + * True if this version identifier represents a branch + * + */ + public boolean isBranch() { + return branchVersion != null; + } + + /** + * True if this version is the first copy in a version tree + * i.e. versionTreeId is 1. + */ + public boolean isFirst() { + return trunkVersion.equals("1") && !isBranch(); + } + + /** + * Return the next logical versionTreeId + * i.e. next logical versionTreeId for 1.2.1 is 1.2.2 + */ + public VersionTreeID next() { + if (isBranch()) { + String newBranchVersion = Integer.toString(Integer.valueOf(branchVersion) + 1); + return new VersionTreeID(trunkVersion + "." + branchNumber + + "." + newBranchVersion); + + } else { + + return new VersionTreeID(Integer.toString(Integer.valueOf(trunkVersion) + 1)); + } + } + + /** + * Return true if both have same value and + * + * @param o The object to which this object is to be compared + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof VersionTreeID )) return false; + + final VersionTreeID vtId = (VersionTreeID) o; + + return value.equals(vtId.value); + } + + /** + * Return a hash code value of this objectID + * + * @return hash code + */ + public int hashCode() { + return value.hashCode(); + } + + /** + * Return value as string presentation of this objectID + * + * @return string presentation + */ + public String toString() { + return value; + } + + //POJO start + VersionTreeID() { + } + + void setValue(String value) { + this.value = value; + loadValue(value); + } + + //POJO end + + private String PATTERN = "[1-9](\\d)*(\\.(\\d)+\\.(\\d)+)?"; + + /* field */ + private String value; + private String trunkVersion; + private String branchNumber; + private String branchVersion; +} + +/* + * ***** 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 VersionTreeID.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/support/terminology/CodeSetAccess.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/CodeSetAccess.java new file mode 100644 index 00000000..770a61a0 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/CodeSetAccess.java @@ -0,0 +1,87 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CodeSetAccess" + * keywords: "support" + * + * 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/support/terminology/CodeSetAccess.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.support.terminology; + +import org.openehr.rm.datatypes.text.CodePhrase; + +import java.util.Set; + +/** + * Defines interface to a code set. + * + * @author Rong Chen + * @version 1.0 + */ +public interface CodeSetAccess { + + /** + * Returns identification of this code set + * + * @return ID not null or empty + */ + public String id(); + + /** + * Returns all codes known in this code set + * + * @return Set of DvCodePhrase + */ + public Set allCodes(); + + /** + * Return true if this codeSet contains given codePhrase + * + * @param code + * @return true if has + */ + public boolean hasCode(CodePhrase code); + + /** + * Return true if this codeSet contains given 'lang' + * + * @param lang + * @return true if has + */ + public boolean hasLang(CodePhrase lang); +} +/* + * ***** 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 CodeSetAccess.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/support/terminology/OpenEHRCodeSetIdentifiers.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/OpenEHRCodeSetIdentifiers.java new file mode 100644 index 00000000..5b9aff3e --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/OpenEHRCodeSetIdentifiers.java @@ -0,0 +1,98 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class OpenEHRCodeSetIdentifiers" + * keywords: "support" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2006 ACODE HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ + +package org.openehr.rm.support.terminology; + +/** + * List of identifiers for code sets in the openEHR terminology. + * + * @author Rong Chen + */ +public enum OpenEHRCodeSetIdentifiers { + + CHARACTER_SETS ("character sets"), + COMPRESSION_ALGORITHMS ("compression algorithms"), + COUNTRIES ("countries"), + INTEGRITY_CHECK_ALGORITHMS ("integrity check algorithms"), + LANGUAGES ("languages"), + MEDIA_TYPES ("media types"), + NORMAL_STATUSES ("normal statuses"); + + /** + * Validity function to test if an identifier is in the set + * defined by this class + * + * @param id + * @return true if valid + */ + public static boolean validCodeSetId(String id) { + for(OpenEHRCodeSetIdentifiers codeSetId : values()) { + if(codeSetId.value.equals(id)) { + return true; + } + } + return false; + } + + /** + * Private constructor + * + * @param value + */ + private OpenEHRCodeSetIdentifiers(String value) { + this.value = value; + } + + /** + * Gets String representation of this identifier + * + * @return the string value + */ + public String toString() { + return value; + } + + /* String value of the identifier */ + private final String value; +} + +/* + * ***** 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 OpenEHRCodeSetIdentifiers.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-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 ***** + */ \ No newline at end of file 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 new file mode 100644 index 00000000..077bade2 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/OpenEHRTerminologyGroupIdentifiers.java @@ -0,0 +1,114 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TerminologyGroupIdentifiers" + * keywords: "support" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2006 ACODE HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ + +package org.openehr.rm.support.terminology; + +/** + * List of identifiers for groups in the openEHR terminology. + * + * @author Rong Chen + */ +public enum OpenEHRTerminologyGroupIdentifiers { + + AUDIT_CHANGE_TYPE("audit change type"), + ATTESTATION_REASON("attestation reason"), + COMPOSITION_CATEGORY("composition category"), + EVENT_MATH_FUNCTION("event math function"), + INSTRUCTION_STATES("instruction states"), + INSTRUCTION_TRANSITIONS("instruction transitions"), + NULL_FLAVOURS("null flavours"), + PROPERTY("property"), + PARTICIPATION_FUNCTION("participation function"), + PARTICIPATION_MODE("participation mode"), + SUBJECT_RELATIONSHIP("subject relationship"), + SETTING("setting"), + TERM_MAPPING_PURPOSE("term mapping purpose"), + VERSION_LIFECYCLE_STATE("version lifecycle state"); + + /** + * Private constructor + * + * @param value + */ + private OpenEHRTerminologyGroupIdentifiers(String value) { + this.value = value; + } + + /** + * Validity function to test if an identifier is in the set + * defined by this class. + * + * @param value + * @return true if id valid + */ + public static boolean validTerminologyGroupId(String value) { + for(OpenEHRTerminologyGroupIdentifiers id : values()) { + if(id.value.equals(value)) { + return true; + } + } + return false; + } + + /** + * Gets String representation of this identifier + * + * @return the string value + */ + public String toString() { + return value; + } + + /** + * Gets the string value + * + * @return value + */ + public String getValue() { + return value; + } + + /* String value of the identifier */ + private final String value; +} + +/* + * ***** 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 OpenEHRTerminologyGroupIdentifiers.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-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 ***** + */ \ No newline at end of file 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 new file mode 100644 index 00000000..1407e951 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/TerminologyAccess.java @@ -0,0 +1,113 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TerminologyAccess" + * keywords: "support" + * + * 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/BRANCHES/Release-1.0/libraries/src/java/org/openehr/rm/support/terminology/TerminologyAccess.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.support.terminology; + +import org.openehr.rm.datatypes.text.CodePhrase; + +import java.util.Set; + +/** + * Defines an interface to access a terminology + * + * @author Rong Chen + * @version 1.0 + */ +public interface TerminologyAccess { + + /** + * Returns identification of this terminology + * + * @return ID not null or empty + */ + public String id(); + + /** + * Returns all codes known in this terminology + * + * @return Set of DvCodePhrase + */ + public Set allCodes(); + + /** + * Returns all codes under grouper groupID of this terminology + * + * @param groupID + * @return Set of CodePhrase for given group ID, empty set + * returned if not found + * @throws IllegalArgumentException if groupID null or empty + */ + public Set codesForGroupId(String groupID); + + /** + * Returns true if the given code is known in the specified group + * + * @param groupId + * @param code + * @return true if code exists + */ + public boolean hasCodeForGroupId(String groupId, CodePhrase code); + + /** + * Return all codes under grouper whose name of given + * name and language from this terminology. + * + * @param name + * @param language + * @return Set of CodePhrase for given group name, + * empty set returned if not found + * @throws IllegalArgumentException if name,language null or empty + */ + public Set codesForGroupName(String name, String language); + + /** + * Returns all rubric of given code and language + * + * @param code + * @param language + * @return rubric of given code and language or null if not found + * @throws IllegalArgumentException if code,language null or empty + */ + public String rubricForCode(String code, String 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 TerminologyAccess.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/support/terminology/TerminologyService.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/TerminologyService.java new file mode 100644 index 00000000..4653e765 --- /dev/null +++ b/openehr-rm-core/src/main/java/org/openehr/rm/support/terminology/TerminologyService.java @@ -0,0 +1,131 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TerminologyService" + * keywords: "support" + * + * 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/support/terminology/TerminologyService.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.support.terminology; + +import java.util.*; + +/** + * Defines an object providing proxy access to a terminology service + * + * @author Rong Chen + * @version 1.0 + */ +public interface TerminologyService { + + /** + * Returns a TerminologyAccess of given name + * + * @param name not empty and known to this service + * @return terminology + * @throws IllegalArgumentException if name null, empty + * or unknown to this terminology service + */ + public TerminologyAccess terminology(String name); + + /** + * Return an interface to the code_set identified by the + * external identifier name + * + * @param name not empty and known to this service + * @return codeSet + * @throws IllegalArgumentException if name is null, empty + * or unknown to this terminology service + */ + public CodeSetAccess codeSet(String name); + + /** + * Return an interface to the code_set identified internally + * in openEHR by id. + * + * @param id not empty and known to this service + * @return codeSet + * @throws IllegalArgumentException if id is null, empty + * or unknown to this terminology service + */ + public CodeSetAccess codeSetForId(OpenEHRCodeSetIdentifiers id); + + /** + * Returns true if terminology of given name known by this service + * + * @param name not empty + * @return true if has given terminology + * @throws IllegalArgumentException if name is null or empty + */ + public boolean hasTerminology(String name); + + /** + * Returns true if code set of given name known by this service + * + * @param name not empty + * @return true if has given codeset + * @throws IllegalArgumentException if name is null or empty + */ + public boolean hasCodeSet(String name); + + /** + * Gets all terminology identifiers known in the terminology service. + * + * @return all terminology identifiers + */ + public List terminologyIdentifiers(); + + /** + * Gets all code set identifiers known in the terminology service + * + * @return all code identifiers + */ + public List codeSetIdentifiers(); + + /** + * Gets all code sets identifiers for which there is an internal + * openEHR name + * + * @return as a Hash of ids keyed by internal name + */ + public Map openehrCodeSets(); + + /* static fields */ + public static final String OPENEHR = "openehr"; + public static final String NULL_FLAVOURS = "null flavours"; +} +/* + * ***** 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 TerminologyService.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/archetyped/AddChildTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/AddChildTest.java new file mode 100644 index 00000000..999ff424 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/AddChildTest.java @@ -0,0 +1,40 @@ +package org.openehr.rm.common.archetyped; + +import java.util.ArrayList; +import java.util.List; + +import org.openehr.rm.datastructure.itemstructure.ItemList; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datatypes.text.DvText; + +import junit.framework.TestCase; + +public class AddChildTest extends TestCase { + + public void testAddItemToList() throws Exception { + ItemList list = itemList(); + int count = list.itemCount(); + String path = "/items"; + + DvText text = new DvText("new text"); + Element element = new Element("at0010", "New Element", text); + + list.addChild(path, element); + + assertTrue("child not added", list.itemCount() == count + 1); + + Element actual = (Element) list.itemAtPath("/items[at0010]"); + assertEquals(text, actual.getValue()); + } + + private ItemList itemList() { + List items = new ArrayList(); + for(int i = 1; i <= 3; i++) { + DvText text = new DvText("text " + i); + Element element = new Element("at000" + i, "element " + i, text); + items.add(element); + } + ItemList list = new ItemList("at0000", "list", items); + return list; + } +} \ No newline at end of file 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 new file mode 100644 index 00000000..4d8f0a9d --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/ArchetypedTest.java @@ -0,0 +1,126 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ArchetypedTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/common/archetyped/ArchetypedTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +/** + * ArchetypedTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.common.archetyped; + +import junit.framework.TestCase; +import org.openehr.rm.support.identification.ArchetypeID; + +public class ArchetypedTest extends TestCase { + + public ArchetypedTest(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 testConstructor() throws Exception { + new Archetyped(aid("openehr-ehr_rm-section.physical_examination.v2"), + "1.1"); + new Archetyped(aid("openehr-ehr_rm-section.physical_examination.v2"), + "1.1"); + + assertExceptionThrown(null, "1.1", "archetypeId"); + assertExceptionThrown(aid( + "openehr-ehr_rm-section.physical_examination.v2"), + null, "rmVersion"); + } + + public void testEquals() { + Archetyped a1 = new Archetyped(aid( + "openehr-ehr_rm-section.physical_examination.v2"), + "1.1"); + Archetyped a2 = new Archetyped(aid( + "openehr-ehr_rm-section.physical_examination.v2"), + "1.1"); + assertTrue(a1.equals(a2)); + assertTrue(a2.equals(a1)); + + Archetyped a3 = new Archetyped(aid( + "openehr-ehr_rm-section.physical_examination.v3"), + "1.1"); + assertFalse(a1.equals(a3)); + assertFalse(a3.equals(a1)); + + a3 = new Archetyped( + aid("openehr-ehr_rm-section.physical_examination.v2"), + "1.2"); + assertFalse(a1.equals(a3)); + assertFalse(a3.equals(a1)); + } + + private ArchetypeID aid(String value) { + return new ArchetypeID(value); + } + + private void assertExceptionThrown(ArchetypeID archetypeID, + String rmVersion, + String cause) { + try { + new Archetyped(archetypeID, rmVersion); + fail("exception should be thrown here"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + assertTrue(e.getMessage().contains(cause)); + } + } + + +} + +/* + * ***** 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 ArchetypedTest.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 ***** + */ 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 new file mode 100644 index 00000000..d83f32be --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/FeederAuditDetailsTest.java @@ -0,0 +1,129 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class FeederAuditDetailsTest" + * 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/archetyped/FeederAuditDetailsTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" + */ +/** + * FeederAuditDetailsTest + * + * @author Yin Su Lim + * @version 1.0 + */ +package org.openehr.rm.common.archetyped; + +import org.openehr.rm.common.generic.PartyIdentified; +import org.openehr.rm.common.generic.PartyProxy; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; + +import junit.framework.TestCase; + +public class FeederAuditDetailsTest extends TestCase { + + protected void setUp() throws Exception { + super.setUp(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + public void testConstructor() throws Exception { + + // test with null or empty systemID + assertExceptionThrown(null, null, null, + new DvDateTime("2004-10-12T09:00:00"), + null, "versionid12.1", "null or empty systemId"); + + assertExceptionThrown("", null, null, + new DvDateTime("2004-10-12T09:00:00"), + null, "versionid12.1", "null or empty systemId"); + } + + public void testEquals() throws Exception { + FeederAuditDetails fad1 = new FeederAuditDetails("systemId", null, null, + new DvDateTime("2004-10-12T09:00:00"), + null, "versionid12.1"); + + FeederAuditDetails fad2 = new FeederAuditDetails("systemId", null, null, + new DvDateTime("2004-10-12T09:00:00"), + null, "versionid12.1"); + + assertTrue(fad1.equals(fad2)); + assertTrue(fad2.equals(fad1)); + + FeederAuditDetails fad3 = new FeederAuditDetails("systemID", null, null, + new DvDateTime("2004-10-12T09:01:01"), + null, "versionid12.2"); + assertFalse(fad1.equals(fad3)); + assertFalse(fad3.equals(fad1)); + } + + public void testHashCode() throws Exception { + FeederAuditDetails fad1 = new FeederAuditDetails("systemID", null, null, + new DvDateTime("2004-10-12T09:00:00"), + null, "versionid12.1"); + + FeederAuditDetails fad2 = new FeederAuditDetails("systemID", null, null, + new DvDateTime("2004-10-12T09:00:00"), + null, "versionid12.1"); + assertEquals("hashcodes not equal", fad1.hashCode(), fad2.hashCode()); + + FeederAuditDetails fad3 = new FeederAuditDetails("systemID", null, null, + new DvDateTime("2004-10-12T09:01:01"), + null, "versionid12.2"); + assertFalse(fad3.equals(fad1)); + } + + private void assertExceptionThrown(String systemID, PartyIdentified provider, + PartyIdentified location, DvDateTime time, PartyProxy subject, + String versionID, String cause) throws Exception { + try { + new FeederAuditDetails(systemID, provider, location, time, + subject, versionID); + fail("exception should be thrown"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + assertTrue("expected cause: " + cause + ", got: " + e.getMessage(), + e.getMessage().contains(cause)); + } + } +} + +/* + * ***** 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 FeederAuditDetailsTest.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/archetyped/LocatableTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/LocatableTest.java new file mode 100644 index 00000000..e56a2154 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/LocatableTest.java @@ -0,0 +1,282 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class LocatableTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/common/archetyped/LocatableTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ + +/** + * LocatableTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.common.archetyped; + +import java.util.*; + +import junit.framework.TestCase; + +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.support.identification.HierObjectID; +import org.openehr.rm.support.identification.UIDBasedID; +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.common.directory.Folder; +import org.openehr.rm.support.terminology.*; + +public class LocatableTest extends TestCase { + + public LocatableTest(String test) { + super(test); + } + + /** + * The fixture set up called before every test method. + */ + protected void setUp() throws Exception { + DvText name = new DvText("test instance"); + DvDateTime origin = new DvDateTime("2005-12-03T09:22:00"); + ItemStructure summary = null; + instance = new TestLocatable("at0000", name, origin, summary, null); + + list = new ArrayList(); + for(int i = 1; i < 10; i++) { + String archetypeNodeId = "at000" + i; + String subname = "name" + i; + list.add(new TestLocatable(archetypeNodeId, subname)); + } + + // test iteam for testing archetyped root node + list.add(new TestLocatable( + "openEHR-EHR-OBSERVATION.laboratory-lipids.v1", + "archetyped root node")); + + assert(list.size() == 10); + } + + /** + * The fixture clean up called after every test method. + */ + protected void tearDown() throws Exception { + list = null; + } + + public void testGetLinks() throws Exception { + UIDBasedID uid = new HierObjectID("1-0-23-47-23"); + + Folder folder = new Folder(uid, "at0001", new DvText("folder name"), + null, null, null, null, null, null); + folder.getLinks(); + } + + public void testProcessArchetypePredicateWithMatch() throws Exception { + Object actual = instance.processPredicate("at0005", list); + assertNotNull("match on archetype predicate expected", actual); + assertTrue("locatable expected", actual instanceof Locatable); + Locatable l = (Locatable) actual; + assertEquals("wrong match on archetyep predicate", "at0005", + l.getArchetypeNodeId()); + } + + public void testProcessArchetypePredicateWithMatchedRootNode() throws Exception { + String aid = "openEHR-EHR-OBSERVATION.laboratory-lipids.v1"; + Object actual = instance.processPredicate(aid, list); + assertNotNull("match on archetype predicate expected", actual); + assertTrue("locatable expected", actual instanceof Locatable); + Locatable l = (Locatable) actual; + assertEquals("wrong match on archetyep predicate", aid, + l.getArchetypeNodeId()); + } + + public void testProcessArchetypePredicateWithoutMatch() throws Exception { + Object actual = instance.processPredicate("at0025", list); + assertNull("match on archetype predicate unexpected", actual); + } + + public void testProcessNamePredicateWithMatch() throws Exception { + Object actual = instance.processPredicate("'name8'", list); + assertNotNull("match on archetype predicate expected", actual); + assertTrue("locatable expected", actual instanceof Locatable); + Locatable l = (Locatable) actual; + assertEquals("wrong match on name predicate", "at0008", + l.getArchetypeNodeId()); + } + + public void testProcessNamePredicateWithoutMatch() throws Exception { + Object actual = instance.processPredicate("'name99'", list); + assertNull("match on name predicate unexpected", actual); + } + + public void testProcessArchetypeCommaNamePredicateWithMatch() throws Exception { + Object actual = instance.processPredicate("at0008, 'name8'", list); + assertNotNull("match on archetype predicate expected", actual); + assertTrue("locatable expected", actual instanceof Locatable); + Locatable l = (Locatable) actual; + assertEquals("wrong match on archetype and name predicate", "at0008", + l.getArchetypeNodeId()); + } + + public void testProcessArchetypeCommaNamePredicateWithoutMatch() throws Exception { + Object actual = instance.processPredicate("at0088, 'name99'", list); + assertNull("match on name predicate unexpected", actual); + } + + public void testProcessArchetypeAndNamePredicateWithMatchUppercaseAnd() throws Exception { + Object actual = instance.processPredicate("at0008 AND 'name8'", list); + assertNotNull("match on archetype predicate expected", actual); + assertTrue("locatable expected", actual instanceof Locatable); + Locatable l = (Locatable) actual; + assertEquals("wrong match on archetyep predicate", "at0008", + l.getArchetypeNodeId()); + } + + public void testProcessArchetypeAndNamePredicateWithMatchLowercaseAnd() throws Exception { + Object actual = instance.processPredicate("at0008 and 'name8'", list); + assertNotNull("match on archetype predicate expected", actual); + assertTrue("locatable expected", actual instanceof Locatable); + Locatable l = (Locatable) actual; + assertEquals("wrong match on archetyep predicate", "at0008", + l.getArchetypeNodeId()); + } + + public void testProcessArchetypeAndNamePredicateWithMatchUppercaseAndNameValue() throws Exception { + Object actual = instance.processPredicate("at0008 AND name/value='name8'", list); + assertNotNull("match on archetype predicate expected", actual); + assertTrue("locatable expected", actual instanceof Locatable); + Locatable l = (Locatable) actual; + assertEquals("wrong match on archetyep predicate", "at0008", + l.getArchetypeNodeId()); + } + + public void testProcessArchetypeAndNamePredicateWithMatchLowercaseAndNameValue() throws Exception { + Object actual = instance.processPredicate("at0008 and name/value='name8'", list); + assertNotNull("match on archetype predicate expected", actual); + assertTrue("locatable expected", actual instanceof Locatable); + Locatable l = (Locatable) actual; + assertEquals("wrong match on archetyep predicate", "at0008", + l.getArchetypeNodeId()); + } + + public void testProcessArchetypeAndNamePredicateWithoutMatchUppercaseAnd() throws Exception { + Object actual = instance.processPredicate("at0088 AND 'name99'", list); + assertNull("match on name predicate unexpected", actual); + } + + public void testProcessArchetypeAndNamePredicateWithoutMatchLowercaseAnd() throws Exception { + Object actual = instance.processPredicate("at0088 and 'name99'", list); + assertNull("match on name predicate unexpected", actual); + } + + public void testItemAtPathFirstLevelAttribute() { + path = "/name"; + value = instance.itemAtPath(path); + assertEquals(instance.getName(), value); + } + + public void testItemAtPathAttributesAttribute() { + path = "/name/value"; + value = instance.itemAtPath(path); + assertTrue(value instanceof String); + assertEquals(instance.getName().getValue(), value); + } + + public void testItemAtPathWithAttributeHavingUnderscore() { + path = "/archetype_node_id"; + value = instance.itemAtPath(path); + assertTrue(value instanceof String); + assertEquals(instance.getArchetypeNodeId(), value); + } + + + + private List list; + private Locatable instance; + private String path; + private Object value; + + /* Locatable subclass for testing use */ + private static class TestLocatable extends Locatable { + TestLocatable(String archetypeNodeId, String name) { + super(archetypeNodeId, new DvText(name)); + } + + // "borrowed" partly from history ;) + @FullConstructor + public TestLocatable( + @Attribute(name = "archetypeNodeId", required=true) String archetypeNodeId, + @Attribute(name = "name", required=true) DvText name, + @Attribute(name = "origin", required=true) DvDateTime origin, + @Attribute(name = "summary") ItemStructure summary, + @Attribute(name = "terminologyService", system=true) + TerminologyService terminologyService){ + super(archetypeNodeId, name); + this.origin = origin; + this.summary = summary; + } + + public DvDateTime getOrigin() { + return origin; + } + + public ItemStructure getSummary() { + return summary; + } + + public String pathOfItem(Pathable item) { + return null; + } + public List itemsAtPath(String path) { + return null; + } + public boolean pathExists(String path) { + return false; + } + public boolean pathUnique(String path) { + return false; + } + + private DvDateTime origin; + private ItemStructure summary; + } +} + +/* + * ***** 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 LocatableTest.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-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 new file mode 100644 index 00000000..c347163e --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/PathBasedQueryTest.java @@ -0,0 +1,115 @@ +package org.openehr.rm.common.archetyped; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.openehr.rm.datastructure.itemstructure.ItemList; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datatypes.text.*; + +public class PathBasedQueryTest extends TestCase { + + public void testPathWithCommaInNamePredicate() throws Exception { + DvText text = new DvText("yes"); + Element element = new Element("at0002", "Status, 2nd", text); + List items = new ArrayList(); + items.add(element); + ItemList list = new ItemList("at0001", "list", items); + + obj = list.itemAtPath("/items[at0002 and name/value='Status, 2nd']"); + assertNotNull("failed to get with comma in name predicate", obj); + } + + public void testPathWithCommaInNamePredicateSymplified() throws Exception { + DvText text = new DvText("yes"); + Element element = new Element("at0002", "Status, 2nd", text); + List items = new ArrayList(); + items.add(element); + ItemList list = new ItemList("at0001", "list", items); + + obj = list.itemAtPath("/items[at0002, 'Status, 2nd']"); + assertNotNull("failed to get with comma in name predicate", obj); + } + + public void testPathWithSpaceInNamePredicate() throws Exception { + DvText text = new DvText("yes"); + Element element = new Element("at0002", "Status 2nd", text); + List items = new ArrayList(); + items.add(element); + ItemList list = new ItemList("at0001", "list", items); + + obj = list.itemAtPath("/items[at0002 and name/value='Status 2nd']"); + assertNotNull("failed to get with space in name predicate", obj); + } + + public void testPathWithSpaceInNamePredicateSymplified() throws Exception { + DvText text = new DvText("yes"); + Element element = new Element("at0002", "Status 2nd", text); + List items = new ArrayList(); + items.add(element); + ItemList list = new ItemList("at0001", "list", items); + + obj = list.itemAtPath("/items[at0002, 'Status 2nd']"); + assertNotNull("failed to get with space in name predicate", obj); + } + + public void testPathWithPhraseANDInNamePredicate() throws Exception { + DvText text = new DvText("yes"); + Element element = new Element("at0002", "MEDICINSK BEHANDLING", text); + List items = new ArrayList(); + items.add(element); + ItemList list = new ItemList("at0001", "list", items); + + obj = list.itemAtPath("/items[at0002 and name/value='MEDICINSK BEHANDLING']"); + assertNotNull("failed to get with 'AND' in name predicate", obj); + } + + public void testPathWithPhraseANDInNamePredicateSimplified() throws Exception { + DvText text = new DvText("yes"); + Element element = new Element("at0002", "MEDICINSK BEHANDLING", text); + List items = new ArrayList(); + items.add(element); + ItemList list = new ItemList("at0001", "list", items); + + obj = list.itemAtPath("/items[at0002, 'MEDICINSK BEHANDLING']"); + assertNotNull("failed to get with 'AND' in name predicate", obj); + } + + public void testPathWithSimpleNamePredicate() throws Exception { + DvText text = new DvText("yes"); + Element element = new Element("at0002", "Status", text); + List items = new ArrayList(); + items.add(element); + ItemList list = new ItemList("at0001", "list", items); + + obj = list.itemAtPath("/items[at0002 and name/value='Status']"); + assertNotNull("failed to get with plain name predicate", obj); + } + + public void testPathWithSimpleNamePredicateSimplified() throws Exception { + DvText text = new DvText("yes"); + Element element = new Element("at0002", "Status", text); + List items = new ArrayList(); + items.add(element); + ItemList list = new ItemList("at0001", "list", items); + + obj = list.itemAtPath("/items[at0002, 'Status']"); + assertNotNull("failed to get with plain name predicate", obj); + } + + public void testPathPredicateWithAtCode() throws Exception { + DvText text = new DvText("yes"); + Element element = new Element("at0002", "Status, CABG", text); + List items = new ArrayList(); + items.add(element); + ItemList list = new ItemList("at0001", "list", items); + + // plain path without name predicate + obj = list.itemAtPath("/items[at0002]"); + assertNotNull("failed to get with at-code as predicate", obj); + } + + private Object obj; +} 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 new file mode 100644 index 00000000..cb79bbba --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/PathBasedValueSettingTest.java @@ -0,0 +1,161 @@ +package org.openehr.rm.common.archetyped; + +import java.util.*; + +import org.openehr.rm.datastructure.itemstructure.ItemList; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datatypes.quantity.DvOrdinal; +import org.openehr.rm.datatypes.quantity.DvQuantity; +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.measurement.MeasurementService; +import org.openehr.rm.support.measurement.TestMeasurementService; + +import junit.framework.TestCase; + +/** + * Test cases for path-based value setting implemented in Locatable class. + * + * @author rong.chen + * + */ + +public class PathBasedValueSettingTest extends TestCase { + + public void testSetDvTextOnElement() throws Exception { + String text = "test text"; + DvText dvText = new DvText(text); + Element element = new Element("at0001", "element", dvText); + element.setValue(dvText); + + // set the value with path + text = "new text"; + DvText newText = new DvText(text); + element.set("/value", newText); + + DvText actual = (DvText) element.getValue(); + assertEquals("failed to set dvText value with path", text, + actual.getValue()); + } + + public void testSetDvTexStringValuetOnElement() throws Exception { + String text = "test text"; + DvText dvText = new DvText(text); + Element element = new Element("at0001", "element", dvText); + element.setValue(dvText); + + // set the value with path + text = "new text"; + element.set("/value/value", text); + + DvText actual = (DvText) element.getValue(); + assertEquals("failed to set dvText string value with path", text, + actual.getValue()); + } + + public void testSetDvQuantityOnItemList() throws Exception { + DvQuantity dvq = new DvQuantity("mg", 2.3, 1, ms); + Element element = new Element("at0002", "element", dvq); + List items = new ArrayList(); + items.add(element); + ItemList list = new ItemList("at0001", "list", items); + + // set the value with path + dvq = new DvQuantity("mg", 6.2, 1, ms); + list.set("/items[at0002]/value", dvq); + + DvQuantity actual = (DvQuantity) list.getItems().get(0).getValue(); + assertEquals("failed to set dvQuantity on list", 6.2, actual.getMagnitude()); + } + + public void testSetDvQuantityMagnitudeOnItemList() throws Exception { + DvQuantity dvq = new DvQuantity("mg", 2.3, 1, ms); + Element element = new Element("at0002", "element", dvq); + List items = new ArrayList(); + items.add(element); + ItemList list = new ItemList("at0001", "list", items); + + // set the value with path + Double d = new Double(6.2); + list.set("/items[at0002]/value/magnitude", d); + + DvQuantity actual = (DvQuantity) list.getItems().get(0).getValue(); + assertEquals("failed to set dvQuantity on list", 6.2, actual.getMagnitude()); + } + + public void testSetDvCodedTextOnItemList() throws Exception { + CodePhrase cp = new CodePhrase("SNOMED-CT", "12345678"); + DvCodedText coded = new DvCodedText("yes", cp); + Element element = new Element("at0002", "element", coded); + List items = new ArrayList(); + items.add(element); + ItemList list = new ItemList("at0001", "list", items); + + // set the value with path + cp = new CodePhrase("SNOMED-CT", "12340000"); + coded = new DvCodedText("nope", cp); + list.set("/items[at0002]/value", coded); + + DvCodedText actual = (DvCodedText) list.getItems().get(0).getValue(); + assertEquals("failed to set codedText.value on list", "nope", actual.getValue()); + assertEquals("failed to set codedText.definingCode on list", "12340000", + actual.getDefiningCode().getCodeString()); + } + + public void testSetDvCodedTextDefiningCodeStringOnItemList() throws Exception { + CodePhrase cp = new CodePhrase("SNOMED-CT", "12345678"); + DvCodedText coded = new DvCodedText("yes", cp); + Element element = new Element("at0002", "element", coded); + List items = new ArrayList(); + items.add(element); + ItemList list = new ItemList("at0001", "list", items); + + // set the value with path + String newCode = "12340000"; + list.set("/items[at0002]/value/defining_code/code_string", newCode); + + DvCodedText actual = (DvCodedText) list.getItems().get(0).getValue(); + assertEquals("failed to set codedText.definingCode on list", "12340000", + actual.getDefiningCode().getCodeString()); + } + + public void testSetDvCodedTextStringValueOnItemList() throws Exception { + CodePhrase cp = new CodePhrase("SNOMED-CT", "12345678"); + DvCodedText coded = new DvCodedText("yes", cp); + Element element = new Element("at0002", "element", coded); + List items = new ArrayList(); + items.add(element); + ItemList list = new ItemList("at0001", "list", items); + + // set the value with path + String text = "nope"; + list.set("/items[at0002]/value/value", text); + + DvCodedText actual = (DvCodedText) list.getItems().get(0).getValue(); + assertEquals("failed to set codedText.value on list", "nope", actual.getValue()); + } + + public void testSetDvOrdinalOnItemList() throws Exception { + CodePhrase cp = new CodePhrase("SNOMED-CT", "12345678"); + DvCodedText coded = new DvCodedText("yes", cp); + DvOrdinal ordinal = new DvOrdinal(1, coded); + Element element = new Element("at0002", "element", ordinal); + List items = new ArrayList(); + items.add(element); + ItemList list = new ItemList("at0001", "list", items); + + // set the value with path + cp = new CodePhrase("SNOMED-CT", "12340000"); + coded = new DvCodedText("nope", cp); + ordinal = new DvOrdinal(2, coded); + list.set("/items[at0002]/value", ordinal); + + DvOrdinal actual = (DvOrdinal) list.getItems().get(0).getValue(); + assertEquals("failed to set ordinal.value on list", 2, actual.getValue()); + assertEquals("failed to set ordinal.symbol.value on list", "nope", + actual.getSymbol().getValue()); + } + + private MeasurementService ms = new TestMeasurementService(); +} 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 new file mode 100644 index 00000000..ed4db239 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/PathUtilTest.java @@ -0,0 +1,33 @@ +package org.openehr.rm.common.archetyped; + +import java.util.List; + +import junit.framework.TestCase; + +public class PathUtilTest extends TestCase { + + public void testDividePathIntoSegments() throws Exception { + String path = "/content[openEHR-EHR-SECTION.ad_hoc_heading.v1 and " + + "name/value='Biokemiska data']/items[openEHR-EHR-OBSERVATION." + + "lab_test.v1 and name/value='B-HB']"; + + List list = Locatable.dividePathIntoSegments(path); + + assertEquals(2, list.size()); + } + + public void testComputeParentPath() throws Exception { + String path = "/data[at0001]/events[at0002]/data[at0003]/items" + + "[at0004 and name/value='Buk']"; + + String expected = "/data[at0001]/events[at0002]/data[at0003]"; + + assertEquals(expected, Locatable.parentPath(path)); + } + + public void testComputeParentPathToRoot() throws Exception { + String path = "/items"; + String expected = "/"; + assertEquals(expected, Locatable.parentPath(path)); + } +} 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 new file mode 100644 index 00000000..2f09c562 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/archetyped/RemoveChildTest.java @@ -0,0 +1,77 @@ +package org.openehr.rm.common.archetyped; + +import java.util.*; + +import junit.framework.TestCase; + +import org.openehr.rm.datastructure.itemstructure.ItemList; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datatypes.text.DvText; + +public class RemoveChildTest extends TestCase { + + public void testRemove1stChildFromList() throws Exception { + ItemList list = itemList(); + int count = list.itemCount(); + String path = "/items[at0001]"; + + list.removeChild(path); + assertTrue("child not removed", list.itemCount() == count - 1); + assertNull("child not removed", list.itemAtPath(path)); + } + + public void testRemove1stChildFromListWithNamePredicate() throws Exception { + ItemList list = itemList(); + int count = list.itemCount(); + String path = "/items[at0001 and name/value='element 1']"; + + list.removeChild(path); + assertTrue("child not removed", list.itemCount() == count - 1); + assertNull("child not removed", list.itemAtPath(path)); + } + + public void testRemove2ndChildFromList() throws Exception { + ItemList list = itemList(); + int count = list.itemCount(); + String path = "/items[at0002]"; + + list.removeChild(path); + assertTrue("child not removed", list.itemCount() == count - 1); + assertNull("child not removed", list.itemAtPath(path)); + } + + public void testRemove3rdChildFromList() throws Exception { + ItemList list = itemList(); + int count = list.itemCount(); + String path = "/items[at0003]"; + + list.removeChild(path); + assertTrue("child not removed", list.itemCount() == count - 1); + assertNull("child not removed", list.itemAtPath(path)); + } + + public void testRemoveUnknownChildFromList() throws Exception { + ItemList list = itemList(); + int count = list.itemCount(); + String path = "/items[at0099]"; + try { + list.removeChild(path); + fail("exception should be thrown on unknonw child"); + } catch(Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + assertTrue("child should not be removed", + list.itemCount() == count); + } + + ItemList itemList() { + List items = new ArrayList(); + for(int i = 1; i <= 3; i++) { + DvText text = new DvText("text " + i); + Element element = new Element("at000" + i, "element " + i, text); + items.add(element); + } + ItemList list = new ItemList("at0000", "list", items); + return list; + } +} 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 new file mode 100644 index 00000000..9d811f07 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/changecontrol/ChangeControlTestBase.java @@ -0,0 +1,155 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ChangeControlTestBase" + * 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/changecontrol/ChangeControlTestBase.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" + */ + +/** + * ChangeControlTestBase + * + * @author Yin Su Lim + * @version 1.0 + */ + +package org.openehr.rm.common.changecontrol; + +import java.util.HashSet; +import java.util.Set; +import junit.framework.*; +import org.openehr.rm.common.generic.AuditDetails; +import org.openehr.rm.common.generic.PartyIdentified; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.datatypes.text.TestCodePhrase; +import org.openehr.rm.support.identification.HierObjectID; +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.TestTerminologyID; +import org.openehr.rm.support.terminology.TestTerminologyService; + +public class ChangeControlTestBase extends TestCase { + + public ChangeControlTestBase(String testName) { + super(testName); + } + + protected void setUp() throws Exception { + } + + protected void tearDown() throws Exception { + } + + protected DvCodedText lifeCycleState(String state) { + CodePhrase codePhrase = new CodePhrase(TestTerminologyID.SNOMEDCT, + "revisionCode"); + return new DvCodedText(state, TestCodePhrase.ENGLISH, + TestCodePhrase.LATIN_1, codePhrase, TestTerminologyService + .getInstance()); + } + + protected AuditDetails audit(String id, String name, String changeType, + String dt) { + PartyIdentified pi = new PartyIdentified(new PartyRef(new HierObjectID( + id), "PARTY"), name, null); + CodePhrase codePhrase = new CodePhrase(TestTerminologyID.SNOMEDCT, + "revisionCode"); + DvCodedText codedText = new DvCodedText(changeType, + TestCodePhrase.ENGLISH, TestCodePhrase.LATIN_1, codePhrase, + TestTerminologyService.getInstance()); + return new AuditDetails("12.3.4.5", pi, new DvDateTime(dt), codedText, + null, TestTerminologyService.getInstance()); + } + + protected LocatableRef contribution(String objectVersionID, String path) { + return new LocatableRef(new ObjectVersionID(objectVersionID), "LOCAL", + "CONTRIBUTION", path); + } + + protected OriginalVersion originalVersion(String data, + boolean isMerged, + String uidStr, String time) { + ObjectVersionID uid = new ObjectVersionID(uidStr); + CodePhrase codePhrase = new CodePhrase(TestTerminologyID.SNOMEDCT, + "revisionCode"); + DvCodedText codedText = new DvCodedText("complete", + TestCodePhrase.ENGLISH, TestCodePhrase.LATIN_1, codePhrase, + TestTerminologyService.getInstance()); + PartyIdentified pi = new PartyIdentified(new PartyRef(new HierObjectID( + "1-2-3-4-5"), "PARTY"), "committer name", null); + AuditDetails audit1 = new AuditDetails("12.3.4.5", pi, new DvDateTime( + time), codedText, null, TestTerminologyService.getInstance()); + ObjectRef lr = new LocatableRef(new ObjectVersionID( + "1.23.51.66::1.2.840.114.1.2.2::2"), "LOCAL", "CONTRIBUTION", + ""); + + if (isMerged) { + Set otherUids = new HashSet(); + otherUids.add(new ObjectVersionID( + "1.4.14.5::1.2.840.114.1.2.2::4.2.2")); + return new OriginalVersion(uid, null, data, codedText, + audit1, lr, null, otherUids, null, // isMerged, + TestTerminologyService.getInstance()); + + } else { + return new OriginalVersion(uid, null, data, codedText, + audit1, lr, null, null, null, // isMerged, + TestTerminologyService.getInstance()); + } + } + + protected ImportedVersion importedVersion(String data, + boolean isMerged, String uidStr, String orgTime, String importTime) { + ObjectRef lr = new LocatableRef(new ObjectVersionID( + "1.20.51.60::1.2.840.114.1.2.2::1"), "LOCAL", "CONTRIBUTION", + ""); + PartyIdentified pi = new PartyIdentified(new PartyRef(new HierObjectID( + "1-2-5-4-1"), "PARTY"), "committer name", null); + DvCodedText codedText = new DvCodedText("complete", + TestCodePhrase.ENGLISH, TestCodePhrase.LATIN_1, new CodePhrase( + TestTerminologyID.SNOMEDCT, "revisionCode"), + TestTerminologyService.getInstance()); + AuditDetails audit = new AuditDetails("1.32.4.15", pi, new DvDateTime( + importTime), codedText, null, TestTerminologyService + .getInstance()); + return new ImportedVersion(originalVersion(data, isMerged, + uidStr, orgTime), audit, lr, "committer's signature"); + } +} + +/* + * ***** 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 ChangeControlTestBase.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-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 new file mode 100644 index 00000000..28efe9e8 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/changecontrol/ImportedVersionTest.java @@ -0,0 +1,102 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ImportedVersionTest" + * 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/changecontrol/ImportedVersionTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" + */ + +/** + * ImportedVersionTest + * + * @author Yin Su Lim + * @version 1.0 + */ +package org.openehr.rm.common.changecontrol; + +import junit.framework.*; +import java.util.List; +import org.openehr.rm.common.generic.Attestation; +import org.openehr.rm.common.generic.AuditDetails; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.support.identification.ObjectVersionID; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.rm.support.terminology.TestTerminologyService; + +public class ImportedVersionTest extends ChangeControlTestBase { + + public ImportedVersionTest(String testName) { + super(testName); + } + + protected void setUp() throws Exception { + } + + protected void tearDown() throws Exception { + } + + public static Test suite() { + TestSuite suite = new TestSuite(ImportedVersionTest.class); + + return suite; + } + + public void test() { + OriginalVersion ov = new OriginalVersion( + new ObjectVersionID("1.4.4.5::1.2.840.114.1.2.2::1"), null, "a name", + lifeCycleState("complete"), audit("1-4-3-5-2", "comitter's name", "changeTypeCode", + "2006-07-01T13:22:55"), + contribution("1.4.4.5::1.2.840.114.1.2.2::2", "path/morePath"), null, + null, null, // false, + TestTerminologyService.getInstance()); + ImportedVersion iv = new ImportedVersion(ov, + audit("adminc.nhs.uk", "comitter's name", "changeTypeCode", "2006-07-01T15:00:09"), + contribution("1.4.4.15::1.2.840.114.1.2.2::1", "path/morePath"), + null); + assertEquals("1.4.4.5::1.2.840.114.1.2.2::1", iv.getUid().toString()); + assertEquals(null, iv.getPrecedingVersionUid()); + assertEquals(lifeCycleState("complete"), iv.getLifecycleState()); + assertEquals("a name", iv.getData()); + assertEquals(ov, iv.getItem()); + + } + +} + +/* + * ***** 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 ImportedVersionTest.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/changecontrol/OriginalVersionTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/changecontrol/OriginalVersionTest.java new file mode 100644 index 00000000..ac3460a8 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/changecontrol/OriginalVersionTest.java @@ -0,0 +1,106 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class OriginalVersionTest" + * 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/changecontrol/OriginalVersionTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" + */ + +/** + * OriginalVersionTest + * + * @author Yin Su Lim + * @version 1.0 + */ +package org.openehr.rm.common.changecontrol; + +import java.util.HashSet; +import junit.framework.*; +import java.util.Set; +import org.openehr.rm.common.generic.AuditDetails; +import org.openehr.rm.common.generic.PartyIdentified; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.datatypes.text.TestCodePhrase; +import org.openehr.rm.support.identification.HierObjectID; +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.TestTerminologyID; +import org.openehr.rm.support.terminology.TestTerminologyService; + +public class OriginalVersionTest extends TestCase { + + public OriginalVersionTest(String testName) { + super(testName); + } + + public static Test suite() { + TestSuite suite = new TestSuite(OriginalVersionTest.class); + return suite; + } + + public void testConstructors() { + + ObjectVersionID uid = new ObjectVersionID( + "1.4.4.5::1.2.840.114.1.2.2::1"); + CodePhrase codePhrase = new CodePhrase(TestTerminologyID.SNOMEDCT, + "revisionCode"); + DvCodedText codedText = new DvCodedText("complete", + TestCodePhrase.ENGLISH, TestCodePhrase.LATIN_1, codePhrase, + TestTerminologyService.getInstance()); + PartyIdentified pi = new PartyIdentified(new PartyRef(new HierObjectID( + "1-2-3-4-5"), "PARTY"), "committer name", null); + AuditDetails audit1 = new AuditDetails("12.3.4.5", pi, new DvDateTime( + "2006-05-01T10:10:00"), codedText, null, TestTerminologyService + .getInstance()); + ObjectRef lr = new LocatableRef(new ObjectVersionID( + "1.23.51.66::1.2.840.114.1.2.2::2"), "LOCAL", "CONTRIBUTION", + null); + OriginalVersion ov = new OriginalVersion(uid, null, + "A Party Info", codedText, audit1, lr, null, null, null, // false, + TestTerminologyService.getInstance()); + Set otherUids = new HashSet(); + otherUids + .add(new ObjectVersionID("1.4.14.5::1.2.840.114.1.2.2::4.2.2")); + OriginalVersion ov2 = new OriginalVersion(uid, null, + "A Party Info", codedText, audit1, lr, null, otherUids, null, //true, + TestTerminologyService.getInstance()); + + } +} + +/* + * ***** 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 OriginalVersionTest.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 ***** + */ 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 new file mode 100644 index 00000000..a049ecc6 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/changecontrol/VersionedObjectTest.java @@ -0,0 +1,333 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class VersionedObjectTest" + * 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/archetyped/VersionedObjectTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" + */ + +/** + * VersionedObjectTest + * + * @author Yin Su Lim + * @version 1.0 + */ +package org.openehr.rm.common.changecontrol; + +import java.util.HashSet; +import java.util.Set; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.support.identification.HierObjectID; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.support.identification.ObjectVersionID; +import org.openehr.rm.support.identification.VersionTreeID; +import org.openehr.rm.support.terminology.TestTerminologyAccess; +import org.openehr.rm.support.terminology.TestTerminologyService; + +public class VersionedObjectTest extends ChangeControlTestBase { + + public VersionedObjectTest(String testName) { + super(testName); + } + + public static Test suite() { + TestSuite suite = new TestSuite(VersionedObjectTest.class); + + return suite; + } + + public void testSuccess(){ + } + + public void _testVersionedObjectWOrgVersion() throws Exception { + String firstData = "the first one"; + String firstCSID = "1.2.40.14.1.2.2"; + String time = "2006-07-14T14:33:29"; + VersionedObject repository = repository(firstData, firstCSID, + time); + ObjectVersionID fVUid = new ObjectVersionID(repository.getUid().root() + .toString(), firstCSID, "1"); + // test count total number of versions + assertEquals("versionCount", 1, repository.versionCount()); + + // test has version id + + assertTrue(repository.hasVersionID(fVUid)); + + // test isOriginalVersion + assertTrue(repository.isOriginalVersion(fVUid)); + + // test get latest version + Version version = repository.latestVersion(); + assertEquals("latestVersion", firstData, version.getData()); + + // test get latest trunk version + version = repository.latestTrunkVersion(); + assertEquals("latestTrunkVersion", firstData, version.getData()); + + // test get latest trunk version lifecyclestate + assertEquals(new DvCodedText("creation", + TestTerminologyAccess.CREATION), repository + .latestTrunkLifeCycleSate()); + + // test has version at time + assertTrue(repository.hasVersionAtTime(version.getCommitAudit() + .getTimeCommitted())); + + // test all versions + assertEquals(1, repository.allVersions().size()); + assertTrue(repository.allVersions().contains(version)); + + // test all version ids + assertEquals(1, repository.allVersionIDs().size()); + assertTrue(repository.allVersionIDs().contains(fVUid)); + + // test versionWithID + version = repository.versionWithID(fVUid); + assertEquals("versionWithID", firstData, version.getData()); + + // test versionAtTime + version = repository.versionAtTime(new DvDateTime(time)); + assertEquals("versionWithID", firstData, version.getData()); + + repository.commitOriginalVersion(new ObjectVersionID(fVUid.toString() + + ".1.1"), version.getUid(), "the 1st one", audit("1-2-3-4-2", + "committer's name", "revisionCode", "2006-07-16T12:36:55"), + contribution("contrib::2-3-5-3-2::1", "path/o/path"), + lifeCycleState("complete"), null, TestTerminologyService + .getInstance()); + + version = repository.latestVersion(); + assertEquals("latestVersion", "the 1st one", version.getData()); + assertEquals("latestTrunkVersion", "the first one", repository + .latestTrunkVersion().getData()); + + } + + // test repository + VersionedObject repository(String firstData, String creatingSysID, + String time) throws Exception { + HierObjectID id = new HierObjectID("1-2-5-2-4"); + ObjectRef ehrRef = new ObjectRef(new HierObjectID("ehrdomain::1"), + "LOCAL", "EHR"); + ObjectVersionID vUid = new ObjectVersionID(id.root(), new HierObjectID( + creatingSysID), new VersionTreeID("1")); + DvCodedText changeType = new DvCodedText("creation", + TestTerminologyAccess.CREATION); + return new VersionedObject(id, ehrRef, new DvDateTime(time), + vUid, firstData, changeType, audit("1-5-7-7-1", "Yinsu", + "changeTypeCode", "2006-07-14T14:33:29"), contribution( + "1-6-2-2-4::1.2.40.14::1", "path"), + "comitter's signature", TestTerminologyService.getInstance()); + } + + OriginalVersion orgVersion(String dataStr, String dStrVersionID, + String pVersionID, String time) { + + ObjectVersionID pUid = null; + if (pVersionID != null && !pVersionID.equals("")) { + pUid = new ObjectVersionID(pVersionID); + } + DvCodedText changeType = new DvCodedText("creation", + TestTerminologyAccess.CREATION); + return new OriginalVersion(new ObjectVersionID(dStrVersionID), + pUid, dataStr, changeType, audit("1-6-7-7-2", "Yinsu", + "changeTypeCode", "2006-07-14T14:35:49"), contribution( + "1-6-2-2-4::1.2.42.14::1", "path"), null, null, null, //false, + TestTerminologyService.getInstance()); + + } + + public void _testVersionedObjectWImportVersion() throws Exception { + String firstData = "the first imported data"; + String firstVID = "1.7.5.2::1.2.40.14.1.2.2::1"; + String time = "2006-07-14T14:33:29"; + VersionedObject repository = repositoryImport(firstData, + firstVID, null, time); + + // test count total number of versions + assertEquals("versionCount", 1, repository.versionCount()); + + // test has version id + assertTrue(repository.hasVersionID(new ObjectVersionID(firstVID))); + + // test isOriginalVersion + assertFalse(repository.isOriginalVersion(new ObjectVersionID(firstVID))); + + // test get latest version + Version version = repository.latestVersion(); + assertEquals("latestVersion", firstData, version.getData()); + + // test get latest trunk version + version = repository.latestTrunkVersion(); + assertEquals("latestTrunkVersion", firstData, version.getData()); + + // test get latest trunk version lifecyclestate + assertEquals(new DvCodedText("creation", + TestTerminologyAccess.CREATION), repository + .latestTrunkLifeCycleSate()); + + // test has version at time + assertTrue(repository.hasVersionAtTime(version.getCommitAudit() + .getTimeCommitted())); + + // test all versions + assertEquals(1, repository.allVersions().size()); + assertTrue(repository.allVersions().contains(version)); + + // test all version ids + assertEquals(1, repository.allVersionIDs().size()); + assertTrue(repository.allVersionIDs().contains( + new ObjectVersionID(firstVID))); + + // test versionWithID + version = repository.versionWithID(new ObjectVersionID(firstVID)); + assertEquals("versionWithID", firstData, version.getData()); + + repository.commitOriginalVersion( + new ObjectVersionID(firstVID + ".1.1"), version.getUid(), + "the 1st original", audit("1-2-3-4-2", "committer's name", + "revisionCode", "2006-07-16T12:36:55"), contribution( + "contrib::2-3-5-3-2::1", "path/o/path"), + lifeCycleState("complete"), null, TestTerminologyService + .getInstance()); + + version = repository.latestVersion(); + assertEquals("latestVersion", "the 1st original", version.getData()); + assertEquals("latestTrunkVersion", "the first imported data", + repository.latestTrunkVersion().getData()); + repository.commitOriginalVersion( + new ObjectVersionID(firstVID + ".1.1"), version.getUid(), + "the 1st original", audit("1-2-3-4-2", "committer's name", + "revisionCode", "2006-07-16T12:36:55"), contribution( + "contrib::2-3-5-3-2::1", "path/o/path"), + lifeCycleState("complete"), null, TestTerminologyService + .getInstance()); + + } + + public void _testCommitMergedVersion() throws Exception { + String firstData = "the first imported data"; + String firstVID = "1.7.5.2::1.2.40.14.1.2.2::1"; + String time = "2006-07-14T14:33:29"; + VersionedObject repository = repositoryImport(firstData, + firstVID, null, time); + Version version = repository.latestVersion(); + ObjectVersionID orgUid = new ObjectVersionID(firstVID + ".1.1"); + repository.commitOriginalVersion(orgUid, version.getUid(), + "the 1st original", audit("1-2-3-4-2", "committer's name", + "revisionCode", "2006-07-16T12:36:55"), contribution( + "contrib::2-3-5-3-2::1", "path/o/path"), + lifeCycleState("complete"), null, TestTerminologyService + .getInstance()); + String mergeVUid = "1.7.5.2::1.2.40.14.1.2.2::2"; + Set otherUids = new HashSet(); + otherUids.add(orgUid); + ObjectVersionID mergeUid = new ObjectVersionID(mergeVUid); + repository.commitOriginalMergedVersion(mergeUid, version.getUid(), + "the merged data", lifeCycleState("complete"), audit( + "1-2-3-4-2", "committer's name", "revisionCode", + "2006-07-16T12:37:55"), contribution( + "contrib::2-3-5-3-3::1", "path/o/path"), otherUids, + null, TestTerminologyService.getInstance()); + + assertEquals("versionCount", 3, repository.versionCount()); + // test has version id + assertTrue(repository.hasVersionID(orgUid)); + assertTrue(repository.hasVersionID(mergeUid)); + // test isOriginalVersion + assertTrue(repository.isOriginalVersion(mergeUid)); + + // test get latest version + version = repository.latestVersion(); + assertEquals("latestVersion", "the merged data", version.getData()); + + // test get latest trunk version + version = repository.latestTrunkVersion(); + assertEquals("latestTrunkVersion", "the merged data", version.getData()); + + // test all version ids + assertEquals(3, repository.allVersionIDs().size()); + + // test versionWithID + version = repository.versionWithID(mergeUid); + assertEquals("versionWithID", "the merged data", version.getData()); + + } + + VersionedObject repositoryImport(String orgData, + String dStrVersionID, String pVersionID, String time) { + + OriginalVersion data = orgVersion(orgData, dStrVersionID, + pVersionID, time); + HierObjectID id = data.ownerID(); + ObjectRef ehrRef = new ObjectRef(new HierObjectID("ehrdomain::1"), + "LOCAL", "EHR"); + + return new VersionedObject(id, ehrRef, new DvDateTime(time), + data, audit("1-6-7-7-2", "Yinsu", "changeTypeCode", time), + contribution("1-6-2-2-4::1.2.42.14::1", "path"), "YLim"); + } + + OriginalVersion orgMergedVersion(String dataStr, + String dStrVersionID, String pVersionID, String time, + ObjectVersionID[] otherInputIDs) { + + Set ids = new HashSet(); + for (int i = 0; i < otherInputIDs.length; i++) { + ids.add(otherInputIDs[i]); + } + DvCodedText changeType = new DvCodedText("creation", TestTerminologyAccess.CREATION); + + return new OriginalVersion( + new ObjectVersionID(dStrVersionID), + new ObjectVersionID(pVersionID), + dataStr, + changeType, + audit( "1-6-7-7-2", "Yinsu", "changeTypeCode", "2006-07-14T14:35:49"), + contribution("1-6-2-2-4::1.2.42.14::1", "path"), + "signature", + ids, + null, //true, + TestTerminologyService.getInstance() + ); + } +} + +/* + * ***** 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 VersionedObjectTest.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 ***** + */ 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 new file mode 100644 index 00000000..1cfd53cd --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/directory/FolderTest.java @@ -0,0 +1,90 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class FolderTest" + * keywords: "unit test" + * + * 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/BRANCHES/Release-1.0/libraries/src/test/org/openehr/rm/ehr/FolderTest.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +/** + * FolderTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.common.directory; + +import junit.framework.TestCase; +import org.openehr.rm.support.identification.HierObjectID; +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.terminology.TestCodeSetAccess; +import org.openehr.rm.support.terminology.TestTerminologyService; + +public class FolderTest extends TestCase { + + public FolderTest(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 testConstructor() throws Exception { + UIDBasedID uid = new HierObjectID("1.4.7.23.4.7.23"); + + // verify a bug fix in constructor + new Folder(uid, "at0000", text("folder name"), null, + null, null, null, null, null); + } + + private DvText text(String value) { + return new DvText(value, TestCodeSetAccess.ENGLISH, TestCodeSetAccess.LATIN_1, + TestTerminologyService.getInstance()); + } +} + +/* + * ***** 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 FolderTest.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/generic/AuditDetailsCreateTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/generic/AuditDetailsCreateTest.java new file mode 100644 index 00000000..d9f8bbdd --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/generic/AuditDetailsCreateTest.java @@ -0,0 +1,34 @@ +package org.openehr.rm.common.generic; + +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.support.identification.HierObjectID; +import org.openehr.rm.support.identification.PartyRef; +import org.openehr.rm.support.terminology.*; +import junit.framework.TestCase; + +public class AuditDetailsCreateTest extends TestCase { + + public void setUp() throws Exception { + termServ = TestTerminologyService.getInstance(); + } + + public void testCreateAuditDetailsWithOpenehrCode() throws Exception { + CodePhrase lang = new CodePhrase("ISO_639-1", "en"); + CodePhrase encoding = new CodePhrase("IANA_character-sets", "UTF-8"); + CodePhrase creationCode = new CodePhrase("openehr", "249"); + DvCodedText codedText = new DvCodedText("creation", + lang, encoding, creationCode, termServ); + PartyIdentified pi = new PartyIdentified(new PartyRef(new HierObjectID( + "1-2-3-4-5"), "PARTY"), "committer name", null); + + audit = new AuditDetails("12.3.4.5", pi, new DvDateTime( + "2007-08-14T10:10:00"), codedText, null, termServ); + + assertNotNull("audit null", audit); + } + + private TerminologyService termServ; + private AuditDetails audit; +} 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 new file mode 100644 index 00000000..48341e80 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/generic/PartyIdentifiedTest.java @@ -0,0 +1,89 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class PartyIdentifiedTest" + * 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/generic/PartyIdentifiedTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" + */ + +/** + * PartyIdentifiedTest + * + * @author Yin Su Lim + * @version 1.0 + */ +package org.openehr.rm.common.generic; + +import junit.framework.*; +import java.util.List; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.datatypes.basic.DvIdentifier; +import org.openehr.rm.support.identification.HierObjectID; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.support.identification.PartyRef; + +public class PartyIdentifiedTest extends TestCase { + + public PartyIdentifiedTest(String testName) { + super(testName); + } + + protected void setUp() throws Exception { + } + + protected void tearDown() throws Exception { + } + + public static Test suite() { + TestSuite suite = new TestSuite(PartyIdentifiedTest.class); + + return suite; + } + + public void test() { + PartyRef pr = new PartyRef(new HierObjectID("1-2-3-4-5"),"PARTY"); + PartyIdentified pi = new PartyIdentified(pr, "party name", null); + PartyIdentified pi2 = new PartyIdentified(pr, "party name", null); + assertEquals(pi, pi2); + assertEquals(pi.hashCode(), pi2.hashCode()); + } +} + +/* + * ***** 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 PartyIdentifiedTest.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/generic/RevisionHistoryTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/generic/RevisionHistoryTest.java new file mode 100644 index 00000000..bb5d7eee --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/generic/RevisionHistoryTest.java @@ -0,0 +1,121 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class RevisionHistorytest" + * 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/generic/RevisionHistorytest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" + */ + +/** + * RevisionHistorytest + * + * @author Yin Su Lim + * @version 1.0 + */ +package org.openehr.rm.common.generic; + +import java.util.ArrayList; +import junit.framework.*; +import java.util.List; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.datatypes.text.TestCodePhrase; +import org.openehr.rm.support.identification.HierObjectID; +import org.openehr.rm.support.identification.ObjectVersionID; +import org.openehr.rm.support.identification.PartyRef; +import org.openehr.rm.support.identification.TestTerminologyID; +import org.openehr.rm.support.terminology.TestTerminologyService; + +public class RevisionHistoryTest extends TestCase { + + public RevisionHistoryTest(String testName) { + super(testName); + } + + protected void setUp() throws Exception { + PartyRef pr = new PartyRef(new HierObjectID("1-2-3-4-5"), "PARTY"); + PartyIdentified pi = new PartyIdentified(pr, "party name", null); + CodePhrase codePhrase = + new CodePhrase(TestTerminologyID.SNOMEDCT, "revisionCode"); + DvCodedText codedText = new DvCodedText("code value", TestCodePhrase.ENGLISH, + TestCodePhrase.LATIN_1, codePhrase, + TestTerminologyService.getInstance()); + AuditDetails audit1 = new AuditDetails("12.3.4.5", pi, + new DvDateTime("2006-05-01T10:10:00"), codedText, null, + TestTerminologyService.getInstance()); + AuditDetails audit2 = new AuditDetails("20.3.33.55", pi, + new DvDateTime("2006-06-01T10:10:00"), codedText, null, + TestTerminologyService.getInstance()); + List audits1 = new ArrayList(); + audits1.add(audit1); + List audits2 = new ArrayList(); + audits2.add(audit2); + RevisionHistoryItem rhi1 = new RevisionHistoryItem(audits1, + new ObjectVersionID("1.4.4.5::1.2.840.114.1.2.2::123::1")); + RevisionHistoryItem rhi2 = new RevisionHistoryItem(audits2, + new ObjectVersionID("1.4.4.5::1.2.840.114.1.2.2::123::2")); + List rhiList = new ArrayList(); + rhiList.add(rhi1); + rhiList.add(rhi2); + rh = new RevisionHistory(rhiList); + + } + + protected void tearDown() throws Exception { + } + + public static Test suite() { + TestSuite suite = new TestSuite(RevisionHistoryTest.class); + + return suite; + } + + + public void testMostRecentVersionId() { + assertEquals("1.4.4.5::1.2.840.114.1.2.2::123::2", rh.mostRecentVersionId()); + } + + public void testMostRecentVersionTime() { + assertEquals("2006-06-01T10:10:00", rh.mostRecentVersionTime()); + } + + private RevisionHistory rh; +} + +/* + * ***** 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 RevisionHistorytest.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-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 new file mode 100644 index 00000000..b1222f3c --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/resource/AuthoredResourceTest.java @@ -0,0 +1,136 @@ +/* + * 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 ***** + */ \ 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 new file mode 100644 index 00000000..b0f2792a --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/resource/ResourceDescriptionTest.java @@ -0,0 +1,134 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ResourceDescriptionTest" + * 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/ResourceDescriptionTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" + */ + +/** + * ResourceDescriptionTest + * + * @author Yin Su Lim + * @version 1.0 + */ +package org.openehr.rm.common.resource; + +import junit.framework.*; +import java.util.HashMap; +import java.util.List; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.identification.TestTerminologyID; +import org.openehr.rm.support.terminology.TestTerminologyService; + +public class ResourceDescriptionTest extends ResourceTestBase { + + public ResourceDescriptionTest(String testName) { + super(testName); + } + + protected void setUp() throws Exception { + } + + protected void tearDown() throws Exception { + } + + public static Test suite() { + TestSuite suite = new TestSuite(ResourceDescriptionTest.class); + + return suite; + } + + public void test() { + String[] fr = {"fr"}; + String[] en = {"en"}; + String[] purpose = {"purpose"}; + String[] languages = {"en", "fr"}; + String[] purposes = {"purpose", "but"}; + CodePhrase orgLang = new CodePhrase(TestTerminologyID.LANGUAGE, "en"); + AuthoredResource ar = new AuthoredResourceImpl(orgLang, translations(fr), null, null, false, + TestTerminologyService.getInstance()); + + ResourceDescription rd = new ResourceDescription(hashMap("Sam Heard", "Dr. Sam Heard"), + null, "initial", details(languages, purposes), null, null, ar); + assertEquals(ar, rd.getParentResource()); + assertEquals(rd, ar.getDescription()); + ar = new AuthoredResourceImpl(orgLang, null, null, null, false, + TestTerminologyService.getInstance()); + rd = new ResourceDescription(hashMap("Sam Heard", "Dr. Sam Heard"), + null, "initial", details(en, purpose), null, null, ar); + + } + + public void testFails() { + /* CodePhrase orgLang = new CodePhrase(TestTerminologyID.LANGUAGE, "en"); + String[] languages = {"en", "fr"}; + String[] purposes = {"purpose", "but"}; + String[] fr = {"fr"}; + + failConstructor(null, null, "initial", details(languages, purposes), + null, null, null, "original author missing"); + failConstructor(hashMap("Sam Heard", "Dr. Sam Heard"), null, null, details(languages, purposes), + null, null, null, "lifeCycleState missing"); + failConstructor(hashMap("Sam Heard", "Dr. Sam Heard"), null, "initial", null, + null, null, null, "details missing"); + + AuthoredResource ar = new AuthoredResourceImpl(orgLang, null, null, null, false, + TestTerminologyService.getInstance()); + ResourceDescription rd = new ResourceDescription(hashMap("Sam Heard", "Dr. Sam Heard"), + null, "initial", details(languages, purposes), null, null, null); + failConstructor(hashMap("Sam Heard", "Dr. Sam Heard"), null, "initial", details(languages, purposes), + null, null, ar, "details has more languages than that in parent"); + */ + } + + private void failConstructor(HashMap orgAuthor, List + otherContr, String lifeCycleState, List details, + String resourcePackageUri, HashMap otherDetails, + AuthoredResource parentResource, String reason) { + try { + ResourceDescription rd = new ResourceDescription(orgAuthor, otherContr, + lifeCycleState, details, resourcePackageUri, otherDetails, parentResource); + 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 ResourceDescriptionTest.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/ResourceTestBase.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/resource/ResourceTestBase.java new file mode 100644 index 00000000..2a7ee53d --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/common/resource/ResourceTestBase.java @@ -0,0 +1,113 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ResourceTestBase" + * 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/ResourceTestBase.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" + */ + +/** + * ResourceTestBase + * + * @author Yin Su Lim + * @version 1.0 + */ +package org.openehr.rm.common.resource; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import junit.framework.TestCase; +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 ResourceTestBase extends TestCase { + + /** Creates a new instance of ResourceTestBase */ + public ResourceTestBase(String name) { + super(name); + } + + protected List details(String[] languages, String[] purposes) { + List rdiList = new ArrayList(); + for(int i = 0; i < languages.length; i++) { + CodePhrase orgLang = new CodePhrase(TestTerminologyID.LANGUAGE, languages[i]); + ResourceDescriptionItem rdi = new ResourceDescriptionItem(orgLang, purposes[i], + TestTerminologyService.getInstance()); + rdiList.add(rdi); + } + return rdiList; + } + + protected HashMap translations(String[] languages) { + HashMap translations = new HashMap(); + for(int i = 0; i < languages.length; i++) { + CodePhrase langC = new CodePhrase(TestTerminologyID.LANGUAGE, languages[i]); + TranslationDetails td = new TranslationDetails(langC, hashMap("Tom Beale", "Thomas Beale"), + null, null, TestTerminologyService.getInstance()); + translations.put(languages[i], td); + } + return translations; + } + + protected HashMap hashMap(String key, String value) { + HashMap map = new HashMap(); + map.put(key, value); + return map; + } + + protected class AuthoredResourceImpl extends AuthoredResource { + + AuthoredResourceImpl(CodePhrase originalLanguage, HashMap translations, ResourceDescription description, + RevisionHistory revisionHistory, boolean isControlled, + TerminologyService terminologyService) { + super(originalLanguage, translations, description, revisionHistory, isControlled, + terminologyService); + } + + AuthoredResourceImpl() { + super(); + } + } +} + +/* + * ***** 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 ResourceTestBase.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/datastructure/DataStructureTestBase.java b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/DataStructureTestBase.java new file mode 100644 index 00000000..16854562 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/DataStructureTestBase.java @@ -0,0 +1,154 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DataStructureTestBase" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/datastructure/DataStructureTestBase.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +/** + * ItemStructureTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.datastructure; + +import junit.framework.TestCase; +import org.openehr.rm.support.identification.TestTerminologyID; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datastructure.itemstructure.representation.Cluster; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datastructure.itemstructure.representation.Item; +import org.openehr.rm.datatypes.basic.DataValue; +import org.openehr.rm.datatypes.quantity.DvQuantity; +import org.openehr.rm.datatypes.quantity.DvProportion; +import org.openehr.rm.datatypes.quantity.ProportionKind; +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.datatypes.text.TestCodePhrase; +import org.openehr.rm.support.terminology.TestTerminologyService; + +import java.util.List; + +public class DataStructureTestBase extends TestCase { + + public DataStructureTestBase(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 { + } + + // create a cluster + protected Cluster cluster(String archetypeNodeId, String name, List items) { + return new Cluster(archetypeNodeId, text(name), items); + } + + // create an element by same name, value and code + protected Element element(String name) { + return element(name, name, name , name); + } + + // create an element by name and code + protected Element element(String name, String code) { + return element(name, name, code, code); + } + + // create an element by name and value + protected Element element(String name, DataValue value) { + return new Element("at001", text(name), value); + } + + // create an element by name, and ratio + protected Element element(String name, double numerator, double denominator) { + return element(name, proportion(numerator, denominator)); + } + + // create an element with text value + protected Element element(String archetypeNodeId, String name, + String value) { + return new Element(archetypeNodeId, text(name), text(value)); + } + + // create an element with codedText value + protected Element element(String archetypeNodeId, String name, String value, + String code) { + return new Element(archetypeNodeId, text(name), codedText(value, code)); + } + + // create an element with quanity value + protected Element element(String archetypeNodeId, String name, + double value) { + return new Element(archetypeNodeId, text(name), + new DvQuantity(value)); + } + + // create a text + protected DvText text(String value) { + return new DvText(value, TestCodePhrase.ENGLISH, + TestCodePhrase.LATIN_1, + TestTerminologyService.getInstance()); + } + + // create a codeText + protected DvCodedText codedText(String value, String code) { + CodePhrase codePhrase = + new CodePhrase(TestTerminologyID.SNOMEDCT, code); + return new DvCodedText(value, TestCodePhrase.ENGLISH, + TestCodePhrase.LATIN_1, codePhrase, + TestTerminologyService.getInstance()); + } + + // create a quantityRatio + protected DvProportion proportion(double numerator, double denominator) { + return new DvProportion(numerator, denominator, ProportionKind.FRACTION, 0); + } + + protected static final String sep = ItemStructure.PATH_SEPARATOR; +} +/* + * ***** 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 DataStructureTestBase.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/datastructure/history/HistoryTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/history/HistoryTest.java new file mode 100644 index 00000000..650d8fde --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/history/HistoryTest.java @@ -0,0 +1,319 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class HistoryTest" + * 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/datastructure/history/HistoryTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" + */ +/** + * HistoryTest + * + * @author Yin Su Lim + * @version 1.0 + */ + +package org.openehr.rm.datastructure.history; + +import java.util.ArrayList; +import java.util.List; + +import org.openehr.rm.common.archetyped.Locatable; +import org.openehr.rm.datastructure.DataStructureTestBase; +import org.openehr.rm.datastructure.itemstructure.ItemList; +import org.openehr.rm.datastructure.itemstructure.ItemSingle; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.quantity.datetime.DvDuration; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.terminology.TestTerminologyService; + +public class HistoryTest extends DataStructureTestBase { + + public HistoryTest(String testName) { + super(testName); + } + + public void setUp() { + history = initWithItemList(); + } + + private History initWithItemSingle() { + element = element("element name", "value"); + + 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(TIME), item, null)); + } + return new History(null, "at0002", text(NAME), null, null, + null, null, new DvDateTime(TIME), items, DvDuration + .getInstance("PT1h"), DvDuration.getInstance("PT3h"), + null); + + } + + private History initWithSummary() { + ItemSingle summary = new ItemSingle(null, "at0001", text(ELEMENT_NAME), + null, null, null, null, element); + return new History(null, "at0002", text(NAME), null, null, + null, null, new DvDateTime(TIME), null, DvDuration + .getInstance("PT1h"), DvDuration.getInstance("PT3h"), + summary); + } + + public void testGetParent() { + History h1 = initWithItemSingle(); + for (Event event : h1.getEvents()) { + assertEquals(h1, event.getParent()); + } + History h2 = initWithItemList(); + for (Event event : h2.getEvents()) { + assertEquals(h2, event.getParent()); + } + } + + public void testHistoryContructorWithSharedParent() { + element = element("element name", "value"); + History h1 = initWithSummary(); + 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, h1, new DvDateTime( + TIME), item, null)); + } + try { + new History(null, "at0002", text(NAME), null, null, + null, null, new DvDateTime(TIME), items, DvDuration + .getInstance("PT1h"), DvDuration + .getInstance("PT3h"), null); + fail("this construction of History should fail, events already " + + "have parent assigned"); + } catch (IllegalArgumentException e) { + } + } + + public void testHistoryContructorWithNullValues() { + try { + new History(null, "at0002", text(NAME), null, null, + null, null, new DvDateTime(TIME), null, DvDuration + .getInstance("PT1h"), DvDuration + .getInstance("PT3h"), null); + fail("this construction of History should fail, both events " + + "and summary are null"); + } catch (IllegalArgumentException iae) { + } + } + + /* + * < + * archetype_node_id = <"at0005"> + * name = < + * value = <"history"> + * > + * origin = <2006-07-07T10:29:00> + * events = < + * [1] = < + * archetype_node_id = <"at0004"> + * name = < + * value = <"interval event"> + * > + * time = <2006-07-07T10:59:00> + * width = + * mathFunction = < + * value = <"mean"> + * defining_code = < + * terminology_id = + * value = <"openehr"> + * > + * code_string = <"123"> + * > + * > + * data = < + * archetype_node_id = <"at0001"> + * name = < + * value = <"element name"> + * > + * items = < + * 1] = < + name = < + value = <"element 1"> + > + archetype_node_id = <"at0014"> + value = < + value = <"text 1"> + > + > + [2] = < + name = < + value = <"element 2"> + > + archetype_node_id = <"at0015"> + value = < + value = <"text 1"> + > + > + [3] = < + name = < + value = <"element 3"> + > + archetype_node_id = <"at0016"> + value = < + value = <"text 1"> + > + > + * + * > + * > + * > + * > + * > + */ + private History initWithItemList() { + element = element("element name", "value"); + + List items = new ArrayList(); + items.add(new Element("at0014", new DvText("element 1"), new DvText("text 1"))); + items.add(new Element("at0015", new DvText("element 2"), new DvText("text 2"))); + items.add(new Element("at0016", new DvText("element 3"), new DvText("text 3"))); + + ItemList itemList = new ItemList(null, "at0001", text(ELEMENT_NAME), + null, null, null, null, items); + List> intEvent = new ArrayList>(); + intEvent.add(new IntervalEvent(null, "at0004", + text("interval event"), null, null, null, null, new DvDateTime( + "2006-07-07T10:59:00"), itemList, null, DvDuration + .getInstance("PT30m"), codedText("mean", "meanCode"), + 0, TestTerminologyService.getInstance())); + return new History(null, "at0005", text(NAME), null, null, + null, null, new DvDateTime(TIME), intEvent, DvDuration + .getInstance("PT1h"), DvDuration.getInstance("PT3h"), + null); + } + + public void testItemAtPathWithRoot() throws Exception { + assertEquals("/ return wrong", history, history.itemAtPath("/")); + } + + public void testItemAtPathWithArchetypePredicateWithMatch() throws Exception { + expression = "/events[at0004]"; + ret = history.itemAtPath(expression); + assertNotNull(expression + " should return event", ret); + assertTrue(expression + " should return event, but got: " + ret.getClass(), + ret instanceof IntervalEvent); + Locatable locatable = (Locatable) ret; + assertEquals(expression + " return wrong", "at0004", locatable.getArchetypeNodeId()); + } + + public void testItemAtPathWithNamePredicateWithMatch() throws Exception { + expression = "/events['interval event']"; + ret = history.itemAtPath(expression); + assertNotNull(expression + " should return event", ret); + assertTrue(expression + " should return event, but got: " + ret.getClass(), + ret instanceof IntervalEvent); + Locatable locatable = (Locatable) ret; + assertEquals(expression + " return wrong", "at0004", locatable.getArchetypeNodeId()); + } + + public void testItemAtPathWithArchetypeNamePredicateWithMatch() throws Exception { + expression = "/events[at0004, 'interval event']"; + ret = history.itemAtPath(expression); + assertNotNull(expression + " should return event", ret); + assertTrue(expression + " should return event, but got: " + ret.getClass(), + ret instanceof IntervalEvent); + Locatable locatable = (Locatable) ret; + assertEquals(expression + " return wrong", "at0004", locatable.getArchetypeNodeId()); + } + + public void testItemAtPathWithPredicatesAndTailingPart() throws Exception { + expression = "/events[at0004, 'interval event']/data/items[at0014, 'element 1']"; + ret = history.itemAtPath(expression); + + assertNotNull(expression + " expected Element, but got null", ret); + assertTrue(expression + " should return Element, but got: " + ret.getClass(), + ret instanceof Element); + Element e = (Element) ret; + assertEquals("element name wrong", "element 1", e.getName().getValue()); + } + + public void testItemAtPathWithPredicatesAndTailingPartValue() throws Exception { + expression = "/events[at0004, 'interval event']/data/items[at0014, 'element 1']/value"; + ret = history.itemAtPath(expression); + + assertNotNull(expression + " should return a DvText", ret); + assertTrue(expression + " should return DvText, but got: " + ret.getClass(), + ret instanceof DvText); + DvText dt = (DvText) ret; + assertEquals("dvText value wrong", "text 1", dt.getValue()); + } + + public void testItemAtPathWithPredicatesAndTailingPartValueValue() throws Exception { + expression = "/events[at0004, 'interval event']/data/items[at0014, 'element 1']/value/value"; + ret = history.itemAtPath(expression); + + assertNotNull(expression + " return a null", ret); + assertTrue("expected a string, but got: " + ret.getClass(), + ret instanceof String); + assertEquals("dvText value wrong", "text 1", ret); + } + + /* test fixtures */ + private History history; + private String expression; + private Object ret; + + /* static fields */ + private static final String NAME = "history"; + + private Element element; + + private static final String ELEMENT_NAME = "element name"; + + private static final String[] ITEMS = { "event one", "event two", + "event three" }; + + private static final String[] CODES = { "code one", "code two", + "code three" }; + + private static final String TIME = "2006-07-07T10:29:00"; + +} + +/* + * ***** 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 HistoryTest.java + * + * The Initial Developer of the Original Code is Rong Chen. Portions created by + * the Initial Developer are Copyright (C) 2003-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 ***** + */ \ No newline at end of file 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 new file mode 100644 index 00000000..5162f458 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/history/IntervalEventTest.java @@ -0,0 +1,116 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class IntervalEventTest" + * 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/datastructure/history/IntervalEventTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" + */ + +/** + * IntervalEventTest + * + * @author Yin Su Lim + * @version 1.0 + */ +package org.openehr.rm.datastructure.history; + +import java.util.ArrayList; +import java.util.List; +import junit.framework.*; +import java.util.Set; +import org.openehr.rm.Attribute; +import org.openehr.rm.common.archetyped.*; +import org.openehr.rm.datastructure.DataStructureTestBase; +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.DvDateTime; +import org.openehr.rm.datatypes.quantity.datetime.DvDuration; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.identification.ObjectID; +import org.openehr.rm.support.terminology.TestTerminologyService; + +public class IntervalEventTest extends DataStructureTestBase { + + public IntervalEventTest(String testName) { + super(testName); + } + + protected void setUp() throws Exception { + Element element = element("element name", "element value"); + item = new ItemSingle(null, "at0001", text("interval event item"), + null, null, null, null, element); + ie = new IntervalEvent(null, "at0002", text("point event"), + null, null, null, null, new DvDateTime("2004-12-07T10:29:00"), item, null, + DvDuration.getInstance("PT1h"), codedText("mean", "meanCode"), + 0, TestTerminologyService.getInstance()); + ItemSingle summary = new ItemSingle(null, "at0001", text("summary item"), + null, null, null, null, element("summary element", "summary content")); + h = new History(null, "at0002", text("history"), + null, null, null, null, new DvDateTime("2004-12-06T13:00:00"), null, DvDuration.getInstance("PT30m"), + DvDuration.getInstance("PT3h"), summary); + } + + protected void tearDown() throws Exception { + } + + public static Test suite() { + TestSuite suite = new TestSuite(IntervalEventTest.class); + + return suite; + } + + + public void testIntervalStartTime() { + assertEquals(null, ie.getParent()); + assertEquals(new DvDateTime("2004-12-07T09:29:00"), ie.intervalStartTime()); + ie = new IntervalEvent(null, "at0002", text("point event"), + null, null, null, h, new DvDateTime("2004-12-07T10:29:00"), item, null, + DvDuration.getInstance("PT1h"), codedText("mean", "meanCode"), + 0, TestTerminologyService.getInstance()); + assertEquals(h, ie.getParent()); + } + + ItemSingle item; + private History h; + private IntervalEvent ie; + private static final String NAME = "interval event"; +} + +/* + * ***** 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 IntervalEventTest.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 ***** + */ 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 new file mode 100644 index 00000000..45a39c7d --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/history/PointEventTest.java @@ -0,0 +1,122 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class PointEventTest" + * 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/datastructure/history/PointEventTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" + */ + +/** + * PointEventTest + * + * @author Yin Su Lim + * @version 1.0 + */ +package org.openehr.rm.datastructure.history; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.openehr.rm.datastructure.DataStructureTestBase; +import org.openehr.rm.datastructure.itemstructure.ItemSingle; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.quantity.datetime.DvDuration; +import org.openehr.rm.datatypes.text.DvText; + +public class PointEventTest extends DataStructureTestBase { + + public PointEventTest(String testName) { + super(testName); + } + + protected void tearDown() throws Exception { + element = null; + pointEvent = null; + } + + public static Test suite() { + TestSuite suite = new TestSuite(PointEventTest.class); + + return suite; + } + + /** + * The fixture set up called before every test method. + */ + protected void setUp() throws Exception { + element = element("element name", "value"); + item = new ItemSingle(null, "at0001", text("point event item"), null, + null, null, null, element); + pointEvent = new PointEvent(null, "at0002", + text("point event"), null, null, null, null, new DvDateTime( + TIME), item, null); + ItemSingle summary = new ItemSingle(null, "at0001", + text("summary item"), null, null, null, null, element( + "summary element", "summary content")); + h = new History(null, "at0002", text("history"), null, + null, null, null, new DvDateTime("2004-12-06T13:00:00"), null, + DvDuration.getInstance("PT30m"), + DvDuration.getInstance("PT3h"), summary); + } + + public void testPointEvent() { + pointEvent = new PointEvent(null, "at0002", + text("point event"), null, null, null, h, new DvDateTime(TIME), + item, null); + assertEquals(DvDuration.getInstance("PT10m"), pointEvent.offset()); + assertEquals(h, pointEvent.getParent()); + } + + public void testCreatePointEventWithConvenientConstructor() { + String nodeId = "at0002"; + DvText name = new DvText("point event"); + DvDateTime time = new DvDateTime(TIME); + ItemSingle data = item; + pointEvent = new PointEvent(nodeId, name, time, data); + + assertEquals(nodeId, pointEvent.getArchetypeNodeId()); + assertEquals(name, pointEvent.getName()); + assertEquals(time, pointEvent.getTime()); + assertEquals(data, pointEvent.getData()); + } + + private History h; + private static final String TIME = "2004-12-06T13:10:00"; + private PointEvent pointEvent; + private ItemSingle item; + private Element element; +} + +/* + * ***** 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 PointEventTest.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/datastructure/itemstructure/ItemListTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemListTest.java new file mode 100644 index 00000000..aaf3a35d --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemListTest.java @@ -0,0 +1,134 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ItemListTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/datastructure/itemstructure/ItemListTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +/** + * ItemListTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.datastructure.itemstructure; + +import org.openehr.rm.datastructure.DataStructureTestBase; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datatypes.text.DvText; + +import java.util.*; + +public class ItemListTest extends DataStructureTestBase { + + public ItemListTest(String test) { + super(test); + } + + /** + * The fixture set up called before every test method. + */ + protected void setUp() throws Exception { + itemList = init(); + } + + /** + * The fixture clean up called after every test method. + */ + protected void tearDown() throws Exception { + itemList = null; + } + + public void testItemCount() throws Exception { + assertEquals("itemCount", NAMES.length, itemList.itemCount()); + } + + public void testItems() throws Exception { + assertEquals("items", elements, itemList.getItems()); + } + + public void testNames() throws Exception { + List expected = new ArrayList(); + for (int i = 0; i < NAMES.length; i++) { + expected.add(text(NAMES[ i ])); + } + assertEquals("names", expected, itemList.names()); + } + + public void testNamedItem() throws Exception { + for (int i = 0; i < NAMES.length; i++) { + assertEquals(elements.get(i), itemList.namedItem(NAMES[ i ])); + } + assertTrue(itemList.namedItem("unknown name") == null); + } + + public void testIthItem() throws Exception { + for (int i = 0; i < NAMES.length; i++) { + assertEquals(elements.get(i), itemList.ithItem(i)); + } + assertTrue(itemList.namedItem("unknown name") == null); + } + + // create a itemList as the example in the spec doc + private ItemList init() { + + // save element in the array for comparison + elements = new ArrayList(); + + // elements + for (int i = 0; i < NAMES.length; i++) { + elements.add(element(NAMES[ i ], VALUES[ i ])); + } + return new ItemList(null, "at001", text(NAME), null, null, null, + null, elements); + } + + /* static fields */ + private static final String NAME = "BP protocol"; + private static final String[] NAMES = { + "device", "cuff", "position" + }; + private static final String[] VALUES = { + "sphygmomanometer", "wide", "seated" + }; + + /* field */ + private ItemList itemList; + private List elements; +} +/* + * ***** 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 ItemListTest.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/datastructure/itemstructure/ItemSingleTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemSingleTest.java new file mode 100644 index 00000000..0a584e25 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemSingleTest.java @@ -0,0 +1,165 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ItemSingleTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/datastructure/itemstructure/ItemSingleTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +/** + * ItemSingleTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.datastructure.itemstructure; + + +import org.openehr.rm.datastructure.DataStructureTestBase; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datatypes.text.DvText; + +public class ItemSingleTest extends DataStructureTestBase { + + public ItemSingleTest(String test) { + super(test); + } + + /** + * The fixture set up called before every test method. + */ + protected void setUp() throws Exception { + element = new Element("at0002", new DvText("test element"), + new DvText("text value")); + itemSingle = new ItemSingle(null, "at0001", text("single item"), + null, null, null, null, element); + } + + /** + * The fixture clean up called after every test method. + */ + protected void tearDown() throws Exception { + path = null; + value = null; + element = null; + itemSingle = null; + } + + public void testItemAtPathOnItem() throws Exception { + path = "/item"; + value = itemSingle.itemAtPath(path); + assertEquals("unexpected item", element, value); + } + + public void testItemAtPathOnItemWithName() throws Exception { + path = "/item['test element']"; + value = itemSingle.itemAtPath(path); + assertEquals("unexpected item", element, value); + } + + public void testItemAtPathOnItemWithATCode() throws Exception { + path = "/item[at0002]"; + value = itemSingle.itemAtPath(path); + assertEquals("unexpected item", element, value); + } + + public void testItemAtPathOnItemWithNameAndATCode() throws Exception { + path = "/item[at0002, 'test element']"; + value = itemSingle.itemAtPath(path); + assertEquals("unexpected item", element, value); + } + + public void testItemAtPathOnItemValue() throws Exception { + path = "/item/value"; + value = itemSingle.itemAtPath(path); + assertEquals("unexpected item.value", element.getValue(), value); + } + + public void testItemAtPathOnItemValueWithName() throws Exception { + path = "/item['test element']/value"; + value = itemSingle.itemAtPath(path); + assertEquals("unexpected item.value", element.getValue(), value); + } + + public void testItemAtPathOnItemValueWithATCode() throws Exception { + path = "/item[at0002]/value"; + value = itemSingle.itemAtPath(path); + assertEquals("unexpected item.value", element.getValue(), value); + } + + public void testItemAtPathOnItemValueWithNameAndATCode() throws Exception { + path = "/item[at0002, 'test element']/value"; + value = itemSingle.itemAtPath(path); + assertEquals("unexpected item.value", element.getValue(), value); + } + + public void testItemAtPathOnItemUnmatched() throws Exception { + path = "/item2"; + value = itemSingle.itemAtPath(path); + assertNull("expected null", value); + } + + public void testItemAtPathOnItemWithNameUnmatched() throws Exception { + path = "/item['test element 2']"; + value = itemSingle.itemAtPath(path); + assertNull("expected null", value); + } + + public void testItemAtPathOnItemWithATCodeUnmatched() throws Exception { + path = "/item[at0222]"; + value = itemSingle.itemAtPath(path); + assertNull("expected null", value); + } + + public void testItemAtPathOnItemWithNameAndATCodeUnmatched() throws Exception { + path = "/item[at3333, 'test element']"; + value = itemSingle.itemAtPath(path); + assertNull("expected null", value); + } + + public void testItemAtPathOnWhole() throws Exception { + path = "/"; + value = itemSingle.itemAtPath(path); + assertEquals("unexpected whole", itemSingle, value); + } + + private String path; + private Object value; + private Element element; + private ItemSingle itemSingle; +} +/* + * ***** 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 ItemSingleTest.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/datastructure/itemstructure/ItemTableTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemTableTest.java new file mode 100644 index 00000000..fa58991e --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemTableTest.java @@ -0,0 +1,337 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ItemTableTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/datastructure/itemstructure/ItemTableTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +/** + * ItemTableTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.datastructure.itemstructure; + +import org.openehr.rm.datastructure.DataStructureTestBase; +import org.openehr.rm.datastructure.itemstructure.representation.Cluster; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datastructure.itemstructure.representation.Item; +import org.openehr.rm.datatypes.quantity.*; +import org.openehr.rm.datatypes.text.DvText; + +import java.util.*; + +public class ItemTableTest extends DataStructureTestBase { + + public ItemTableTest(String test) { + super(test); + } + + /** + * The fixture set up called before every test method. + */ + protected void setUp() throws Exception { + createTable(); + } + + private void createTable() throws Exception { + 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 items = new ArrayList(); + items.add(eyes); + items.add(acuity); + rows.add(new Cluster("at0003", new DvText("1"), items)); + + // 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)); + items = new ArrayList(); + items.add(eyes); + items.add(acuity); + rows.add(new Cluster("at0006", new DvText("2"), items)); + + // 3rd row + eyes = new Element("at0007", new DvText("eye(s)"), + new DvText("both")); + acuity = new Element("at0008", new DvText("visual acuity"), + new DvProportion(6, 6, ProportionKind.RATIO, 0)); + items = new ArrayList(); + items.add(eyes); + items.add(acuity); + rows.add(new Cluster("at0009", new DvText("3"), items)); + + itemTable = new ItemTable("at0010", new DvText("vision"), rows); + } + + /** + * The fixture clean up called after every test method. + */ + protected void tearDown() throws Exception { + itemTable = null; + } + + public void testColumnCount() throws Exception { + assertEquals("column count wrong", 2, itemTable.columnCount()); + } + + public void testRowCount() throws Exception { + assertEquals("row count wrong", 3, itemTable.rowCount()); + } + + public void testRowNames() throws Exception { + List names = new ArrayList(); + names.add(new DvText("1")); + names.add(new DvText("2")); + names.add(new DvText("3")); + assertEquals("row names wrong", names, itemTable.rowNames()); + } + + public void testIthRow1() throws Exception { + assertEquals(rows.get(0), itemTable.ithRow(1)); + } + + public void testIthRow2() throws Exception { + assertEquals(rows.get(1), itemTable.ithRow(2)); + } + + public void testIthRow3() throws Exception { + assertEquals(rows.get(2), itemTable.ithRow(3)); + } + + public void testHasRowWithNameOne() throws Exception { + assertTrue(itemTable.hasRowWithName("1")); + } + + public void testHasRowWithNameTwo() throws Exception { + assertTrue(itemTable.hasRowWithName("2")); + } + + public void testHasRowWithNameThree() throws Exception { + assertTrue(itemTable.hasRowWithName("3")); + } + + public void testHasRowWithNameUnkown() throws Exception { + assertFalse(itemTable.hasRowWithName("unknown")); + } + + public void testHasColumnWithNameEyes() throws Exception { + assertTrue(itemTable.hasColumnWithName("eye(s)")); + } + + public void testHasColumnWithNameAcuity() throws Exception { + assertTrue(itemTable.hasColumnWithName("visual acuity")); + } + + public void testElementAtColumn1Row1() throws Exception { + Element element = itemTable.elementAtCell(1, 1); + assertEquals("at0001", element.getArchetypeNodeId()); + } + + public void testElementAtColumn2Row1() throws Exception { + Element element = itemTable.elementAtCell(2, 1); + assertEquals("at0002", element.getArchetypeNodeId()); + } + + public void testElementAtColumn1Row2() throws Exception { + Element element = itemTable.elementAtCell(1, 2); + assertEquals("at0004", element.getArchetypeNodeId()); + } + + public void testElementAtColumn2Row2() throws Exception { + Element element = itemTable.elementAtCell(2, 2); + assertEquals("at0005", element.getArchetypeNodeId()); + } + + public void testElementAtColumn1Row3() throws Exception { + Element element = itemTable.elementAtCell(1, 3); + assertEquals("at0007", element.getArchetypeNodeId()); + } + + public void testElementAtColumn2Row3() throws Exception { + Element element = itemTable.elementAtCell(2, 3); + assertEquals("at0008", element.getArchetypeNodeId()); + } + + public void testNamedRow1() throws Exception { + assertEquals(rows.get(0), itemTable.namedRow("1")); + } + + public void testNamedRow2() throws Exception { + assertEquals(rows.get(1), itemTable.namedRow("2")); + } + + public void testNamedRow3() throws Exception { + assertEquals(rows.get(2), itemTable.namedRow("3")); + } + + public void testElementAtNamedCellOneEyes() throws Exception { + element = itemTable.elementAtNamedCell("1", "eye(s)"); + assertEquals("at0001", element.getArchetypeNodeId()); + } + + public void testElementAtNamedCellOneAcuity() throws Exception { + element = itemTable.elementAtNamedCell("1", "visual acuity"); + assertEquals("at0002", element.getArchetypeNodeId()); + } + + public void testElementAtNamedCellTwoEyes() throws Exception { + element = itemTable.elementAtNamedCell("2", "eye(s)"); + assertEquals("at0004", element.getArchetypeNodeId()); + } + + public void testElementAtNamedCellTwoAcuity() throws Exception { + element = itemTable.elementAtNamedCell("2", "visual acuity"); + assertEquals("at0005", element.getArchetypeNodeId()); + } + + public void testElementAtNamedCellThreeEyes() throws Exception { + element = itemTable.elementAtNamedCell("3", "eye(s)"); + assertEquals("at0007", element.getArchetypeNodeId()); + } + + public void testElementAtNamedCellThreeAcuity() throws Exception { + element = itemTable.elementAtNamedCell("3", "visual acuity"); + assertEquals("at0008", element.getArchetypeNodeId()); + } + + public void testItemAtPathWhole() throws Exception { + assertEquals(itemTable, itemTable.itemAtPath("/")); + } + + public void testItemAtPathRow1() throws Exception { + assertEquals(rows.get(0), itemTable.itemAtPath("/rows[at0003]")); + } + + public void testItemAtPathRow1Column1() throws Exception { + assertEquals(rows.get(0).getItems().get(0), + itemTable.itemAtPath("/rows[at0003]/items[at0001]")); + } + + public void testItemAtPathRow1Column2() throws Exception { + assertEquals(rows.get(0).getItems().get(1), + itemTable.itemAtPath("/rows[at0003]/items[at0002]")); + } + + public void testItemAtPathRow2() throws Exception { + assertEquals(rows.get(1), + itemTable.itemAtPath("/rows[at0006]")); + } + + public void testItemAtPathRow2Column1() throws Exception { + assertEquals(rows.get(1).getItems().get(0), + itemTable.itemAtPath("/rows[at0006]/items[at0004]")); + } + + public void testItemAtPathRow2Column2() throws Exception { + assertEquals(rows.get(1).getItems().get(1), + itemTable.itemAtPath("/rows[at0006]/items[at0005]")); + } + + public void testItemAtPathRow3() throws Exception { + assertEquals(rows.get(2), + itemTable.itemAtPath("/rows[at0009]")); + } + + public void testItemAtPathRow3Column1() throws Exception { + assertEquals(rows.get(2).getItems().get(0), + itemTable.itemAtPath("/rows[at0009]/items[at0007]")); + } + + public void testItemAtPathRow3Column2() throws Exception { + assertEquals(rows.get(2).getItems().get(1), + itemTable.itemAtPath("/rows[at0009]/items[at0008]")); + } + + public void testItemAtPathRow1Name() throws Exception { + assertEquals(rows.get(0), itemTable.itemAtPath("/rows['1']")); + } + + public void testItemAtPathRow1Column1Name() throws Exception { + assertEquals(rows.get(0).getItems().get(0), + itemTable.itemAtPath("/rows['1']/items['eye(s)']")); + } + + public void testItemAtPathRow1Column2Name() throws Exception { + assertEquals(rows.get(0).getItems().get(1), + itemTable.itemAtPath("/rows['1']/items['visual acuity']")); + } + + public void testItemAtPathRow2Name() throws Exception { + assertEquals(rows.get(1), + itemTable.itemAtPath("/rows['2']")); + } + + public void testItemAtPathRow2Column1Name() throws Exception { + assertEquals(rows.get(1).getItems().get(0), + itemTable.itemAtPath("/rows['2']/items['eye(s)']")); + } + + public void testItemAtPathRow2Column2Name() throws Exception { + assertEquals(rows.get(1).getItems().get(1), + itemTable.itemAtPath("/rows['2']/items['visual acuity']")); + } + + public void testItemAtPathRow3Name() throws Exception { + assertEquals(rows.get(2), + itemTable.itemAtPath("/rows['3']")); + } + + public void testItemAtPathRow3Column1Name() throws Exception { + assertEquals(rows.get(2).getItems().get(0), + itemTable.itemAtPath("/rows['3']/items['eye(s)']")); + } + + public void testItemAtPathRow3Column2Name() throws Exception { + assertEquals(rows.get(2).getItems().get(1), + itemTable.itemAtPath("/rows['3']/items['visual acuity']")); + } + + /* field */ + private List rows; + private ItemTable itemTable; + private Element element; +} +/* + * ***** 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 ItemTableTest.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-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 new file mode 100644 index 00000000..49f1371a --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemTreeTest.java @@ -0,0 +1,227 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ItemTreeTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/datastructure/itemstructure/ItemTreeTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +/** + * ItemTreeTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.datastructure.itemstructure; + +import org.openehr.rm.datastructure.DataStructureTestBase; +import org.openehr.rm.datastructure.itemstructure.representation.Cluster; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datastructure.itemstructure.representation.Item; +import org.openehr.rm.datatypes.quantity.DvQuantity; +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.measurement.MeasurementService; +import org.openehr.rm.support.measurement.TestMeasurementService; + +import java.util.ArrayList; +import java.util.List; + +public class ItemTreeTest extends DataStructureTestBase { + + public ItemTreeTest(String test) { + super(test); + } + + /** + * The fixture set up called before every test method. + */ + protected void setUp() throws Exception { + init(); + } + + /** + * The fixture clean up called after every test method. + */ + protected void tearDown() throws Exception { + itemTree = null; + } + + private void init() { + + // sample + sample = new Element("at0001", new DvText("sample"), + new DvCodedText("serum", new CodePhrase("terminology", "111"))); + + // lipid studies + totalCholesterol = new Element("at0002", new DvText("total cholesterol"), + new DvQuantity("mmol/L", 6.1, measureServ)); + + ldlCholesterol = new Element("at0003", new DvText("LDL cholesterol"), + new DvQuantity("mmol/L", 0.9, measureServ)); + + hdlCholesterol = new Element("at0004", new DvText("HDL cholesterol"), + new DvQuantity("mmol/L", 5.2, measureServ)); + + List items = new ArrayList(); + items.add(totalCholesterol); + items.add(ldlCholesterol); + items.add(hdlCholesterol); + lipidStudies = new Cluster("at0005", new DvText("lipid studies"), items); + + // comment + comment = new Element("at0006", new DvText("comment"), + new DvText("high cardiac risk")); + + items = new ArrayList(); + items.add(sample); + items.add(lipidStudies); + items.add(comment); + itemTree = new ItemTree("at0007", new DvText("biochemstry result"), items); + } + + public void testItemAtPathWhole() { + assertEquals(itemTree, itemTree.itemAtPath("/")); + } + + public void testItemAtPathSample() { + assertEquals(sample, itemTree.itemAtPath("/items[at0001]")); + } + + public void testItemAtPathComment() { + assertEquals(comment, itemTree.itemAtPath("/items[at0006]")); + } + + public void testItemAtPathSampleName() { + assertEquals(sample, itemTree.itemAtPath("/items['sample']")); + } + + public void testItemAtPathCommentName() { + assertEquals(comment, itemTree.itemAtPath("/items['comment']")); + } + + public void testItemAtPathSampleBoth() { + assertEquals(sample, itemTree.itemAtPath("/items[at0001, 'sample']")); + } + + public void testItemAtPathCommentBoth() { + assertEquals(comment, itemTree.itemAtPath("/items[at0006, 'comment']")); + } + + public void testItemAtPathTotalCholesterol() { + assertEquals(totalCholesterol, + itemTree.itemAtPath("/items[at0005]/items[at0002]")); + } + + public void testItemAtPathLDLCholesterol() { + assertEquals(ldlCholesterol, + itemTree.itemAtPath("/items[at0005]/items[at0003]")); + } + + public void testItemAtPathHDLCholesterol() { + assertEquals(hdlCholesterol, + itemTree.itemAtPath("/items[at0005]/items[at0004]")); + } + + public void testItemAtPathTotalCholesterolName() { + assertEquals(totalCholesterol, + itemTree.itemAtPath( + "/items['lipid studies']/items['total cholesterol']")); + } + + public void testItemAtPathLDLCholesterolName() { + assertEquals(ldlCholesterol, + itemTree.itemAtPath( + "/items['lipid studies']/items['LDL cholesterol']")); + } + + public void testItemAtPathHDLCholesterolName() { + assertEquals(hdlCholesterol, + itemTree.itemAtPath( + "/items['lipid studies']/items['HDL cholesterol']")); + } + + public void testItemAtPathTotalCholesterolBoth() { + assertEquals(totalCholesterol, + itemTree.itemAtPath( + "/items[at0005, 'lipid studies']/items[at0002]")); + } + + public void testItemAtPathLDLCholesterolBoth() { + assertEquals(ldlCholesterol, + itemTree.itemAtPath( + "/items[at0005, 'lipid studies']/items[at0003]")); + } + + public void testItemAtPathHDLCholesterolBoth() { + assertEquals(hdlCholesterol, + itemTree.itemAtPath( + "/items[at0005, 'lipid studies']/items[at0004]")); + } + + public void testItemAtPathTotalCholesterolValue() { + assertEquals(totalCholesterol.getValue(), + itemTree.itemAtPath("/items[at0005]/items[at0002]/value")); + } + + public void testItemAtPathLDLCholesterolValue() { + assertEquals(ldlCholesterol.getValue(), + itemTree.itemAtPath("/items[at0005]/items[at0003]/value")); + } + + public void testItemAtPathHDLCholesterolValue() { + assertEquals(hdlCholesterol.getValue(), + itemTree.itemAtPath("/items[at0005]/items[at0004]/value")); + } + + public void testCreateEmptyTree() { + ItemTree empty = new ItemTree("at0001", new DvText("tree"), null); + assertNotNull(empty); + } + + /* fields */ + private ItemTree itemTree; + private Element sample; + private Element totalCholesterol; + private Element ldlCholesterol; + private Element hdlCholesterol; + private Element comment; + private Cluster lipidStudies; + private MeasurementService measureServ = TestMeasurementService.getInstance(); +} +/* + * ***** 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 ItemTreeTest.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-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 new file mode 100644 index 00000000..960258d7 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/representation/CreateEmptyElementTest.java @@ -0,0 +1,21 @@ +package org.openehr.rm.datastructure.itemstructure.representation; + +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 junit.framework.TestCase; + +public class CreateEmptyElementTest extends TestCase { + + public void testCreateElement() { + TerminologyService ts = TestTerminologyService.getInstance(); + DvCodedText nullFlavor = new DvCodedText("no information", + TestTerminologyAccess.NULL_FLAVOUR); + + new Element(null, "at0001", new DvText("name"), null, null, null, null, + null, nullFlavor, ts); + } +} 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 new file mode 100644 index 00000000..3fee5e34 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/basic/DvBooleanTest.java @@ -0,0 +1,85 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvBooleanTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/datatypes/basic/DvBooleanTest.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +/** + * BooleanTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.datatypes.basic; + +import junit.framework.TestCase; + +public class DvBooleanTest extends TestCase { + + public DvBooleanTest(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 testValueOf() throws Exception { + DvBoolean b = DvBoolean.valueOf("false"); + assertEquals("false expected", DvBoolean.FALSE, b); + + b = DvBoolean.valueOf("true"); + assertEquals("true expected", DvBoolean.TRUE, b); + } + + public void testValue() throws Exception { + assertEquals(true, DvBoolean.TRUE.getValue()); + assertEquals(false, DvBoolean.FALSE.getValue()); + } + +} +/* + * ***** 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 DvBooleanTest.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/datatypes/basic/DvStateTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/basic/DvStateTest.java new file mode 100644 index 00000000..b134722f --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/basic/DvStateTest.java @@ -0,0 +1,98 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvStateTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/datatypes/basic/DvStateTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +/** + * DvStateTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.datatypes.basic; + +import junit.framework.TestCase; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.support.terminology.TestCodeSetAccess; +import org.openehr.rm.support.terminology.TestTerminologyService; + +public class DvStateTest extends TestCase { + + public DvStateTest(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 testEquals() throws Exception { + DvCodedText codeOne = new DvCodedText("some text", + TestCodeSetAccess.ENGLISH, TestCodeSetAccess.LATIN_1, + new CodePhrase("test terms", "00001"), + TestTerminologyService.getInstance()); + DvState stateOne = new DvState(codeOne, false); + + DvCodedText codeTwo = new DvCodedText("some text", + TestCodeSetAccess.ENGLISH, TestCodeSetAccess.LATIN_1, + new CodePhrase("test terms", "00001"), + TestTerminologyService.getInstance()); + DvState stateTwo = new DvState(codeTwo, false); + + assertTrue(stateOne.equals(stateTwo)); + assertTrue(stateTwo.equals(stateOne)); + + DvState stateThree = new DvState(codeTwo, true); + assertFalse(stateOne.equals(stateThree)); + assertFalse(stateThree.equals(stateOne)); + assertFalse(stateTwo.equals(stateThree)); + assertFalse(stateThree.equals(stateTwo)); + } +} +/* + * ***** 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 DvStateTest.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/datatypes/basic/ParseDataValueTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/basic/ParseDataValueTest.java new file mode 100644 index 00000000..50cfa8ad --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/basic/ParseDataValueTest.java @@ -0,0 +1,93 @@ +package org.openehr.rm.datatypes.basic; + +import org.openehr.rm.datatypes.quantity.DvCount; +import org.openehr.rm.datatypes.quantity.DvQuantity; +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 junit.framework.TestCase; + +public class ParseDataValueTest extends TestCase { + + public void setUp() { + dv = null; + } + + public void testParseDvCount() { + dv = DataValue.parseValue("DV_COUNT,1"); + assertEquals(dv, new DvCount(1)); + } + + public void testDvCountRoundTrip() { + DvCount count = new DvCount(3); + String s = count.serialise(); + assertEquals("DvCount round trip failed", count, DataValue.parseValue(s)); + } + + public void testParseDvText() { + dv = DataValue.parseValue("DV_TEXT,some text"); + assertEquals(dv, new DvText("some text")); + } + + public void testDvTextRoundTrip() { + DvText text = new DvText("jag heter.."); + String s = text.serialise(); + assertEquals("DvText round trip failed", text, DataValue.parseValue(s)); + } + + public void testParseCodePhrase() { + dv = DataValue.parseValue("CODE_PHRASE,SNOMEDCT::12345678"); + assertEquals(dv, new CodePhrase("SNOMEDCT", "12345678")); + } + + public void testCodePhraseRoundTrip() { + CodePhrase cp = new CodePhrase("SNOMEDCT", "22334455"); + String s = cp.serialise(); + assertEquals("Code Phrase round trip failed", cp, DataValue.parseValue(s)); + } + + public void testParseDvQuantity() { + dv = DataValue.parseValue("DV_QUANTITY,1.5,mg"); + assertEquals(dv, new DvQuantity("mg", 1.5, 1)); + } + + public void testDvQuantityRoundTrip() { + DvQuantity dq = new DvQuantity("mg", 1.5, 3); + String s = dq.serialise(); + assertEquals("DvQuantity round trip failed", dq, DataValue.parseValue(s)); + } + + public void testParseDvDateTime() { + dv = DataValue.parseValue("DV_DATE_TIME,2004-10-31T20:10:55.000+01:00"); + assertEquals(dv, new DvDateTime("2004-10-31T20:10:55.000+01:00")); + } + + public void testDvDateTimeRoundTrip() { + DvDateTime datetime = new DvDateTime("2004-10-31T20:10:55.000+01:00"); + String s = datetime.serialise(); + assertEquals("DvDateTime round trip failed", datetime, DataValue.parseValue(s)); + } + + public void testParseDuration() { + dv = DataValue.parseValue("DV_DURATION,P10D"); + assertEquals(dv, new DvDuration("P10D")); + } + + public void testDurationRoundTrip() { + DvDuration duration = new DvDuration("P1Y"); + String s = duration.serialise(); + assertEquals("DvDuration round trip failed", duration, DataValue.parseValue(s)); + } + + public void testCodedTextRoundTrip() { + DvCodedText coded = new DvCodedText("coded text", "snomed", "123456"); + String s = coded.serialise(); + assertEquals("DvCodedText round trip failed", coded, 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 new file mode 100644 index 00000000..322096b5 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/encapsulated/DvMultimediaTest.java @@ -0,0 +1,30 @@ +package org.openehr.rm.datatypes.encapsulated; + +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.uri.DvURI; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.rm.support.terminology.TestTerminologyService; + +import junit.framework.TestCase; + +public class DvMultimediaTest extends TestCase { + + public void testCreateSimpleDvMultimedia() throws Exception { + CodePhrase charset = new CodePhrase("IANA_character-sets", "UTF-8"); + CodePhrase language = new CodePhrase("ISO_3166-1","eN"); + String alternateText = "alternative text"; + CodePhrase mediaType = new CodePhrase("IANA_media-types", "text/plain"); + CodePhrase compressionAlgorithm = new CodePhrase("openehr_compression_algorithms", "others"); + byte[] integrityCheck = new byte[0]; + CodePhrase integrityCheckAlgorithm = new CodePhrase("openehr_integrity_check_algorithms", "SHA-1"); + DvMultimedia thumbnail = null; + DvURI uri = new DvURI("www.iana.org"); + byte[] data = new byte[0]; + TerminologyService terminologyService = new TestTerminologyService(); + DvMultimedia dm = new DvMultimedia(charset, language, alternateText, + mediaType, compressionAlgorithm, integrityCheck, + integrityCheckAlgorithm, thumbnail, uri, data, terminologyService); + + assertNotNull(dm); + } +} 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 new file mode 100644 index 00000000..972ec277 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvCountTest.java @@ -0,0 +1,122 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvCountTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/datatypes/quantity/DvCountTest.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +/** + * CountTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.datatypes.quantity; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.openehr.rm.datatypes.text.DvText; + +import junit.framework.TestCase; + +public class DvCountTest extends TestCase { + + public DvCountTest(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 testAdd() throws Exception { + DvCount c1 = new DvCount(3); + DvCount c2 = new DvCount(5); + DvCount expected = new DvCount(8); + assertEquals(expected, c1.add(c2)); + assertEquals(expected, c2.add(c1)); + } + + public void testSubtract() throws Exception { + DvCount c1 = new DvCount(3); + DvCount c2 = new DvCount(5); + DvCount expected = new DvCount(2); + assertEquals(expected, c2.subtract(c1)); + } + + public void testCompareTo() throws Exception { + DvCount c1 = new DvCount(3); + DvCount c2 = new DvCount(5); + DvCount c3 = new DvCount(3); + + assertTrue("c1 < c2", c1.compareTo(c2) < 0); + assertTrue("c2 > c1", c2.compareTo(c1) > 0); + assertTrue("c3 == c1", c3.compareTo(c1) == 0); + assertTrue("c1 == c3", c1.compareTo(c3) == 0); + } + + public void testGetOtherReferenceRanges() throws Exception { + Map values = new HashMap(); + DvText normal = new DvText(ReferenceRange.NORMAL); + DvCount lower = new DvCount(1); + DvCount upper = new DvCount(10); + ReferenceRange normalRange = new ReferenceRange( + normal, new DvInterval(lower, upper)); + List> otherReferenceRanges = + new ArrayList>(); + otherReferenceRanges.add(normalRange); + + DvCount count = new DvCount(otherReferenceRanges, null, null, 0.0, + false, null, 5); + + assertEquals("otherReferenceRanges wrong", otherReferenceRanges, + count.getOtherReferenceRanges()); + } +} +/* + * ***** 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 DvCountTest.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/datatypes/quantity/DvOrderedTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvOrderedTest.java new file mode 100644 index 00000000..fca034ed --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvOrderedTest.java @@ -0,0 +1,146 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvQuantityTest" + * keywords: "unit test" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2007 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.rm.datatypes.quantity; + +import java.util.List; + +import junit.framework.TestCase; + +import org.openehr.rm.datatypes.text.CodePhrase; + +public class DvOrderedTest extends TestCase { + + public void testIsNormalWithoutNormalStatusAndNormalRange() { + List> referenceRanges = null; + DvInterval normalRange = null; + CodePhrase normalStatus = null; + double accuracy = 0; + boolean accuracyPercent = false; + String magnitudeStatus = null; + int magnitude = 1; + DvCount count = + new DvCount(referenceRanges, normalRange, normalStatus, accuracy, + accuracyPercent, magnitudeStatus, magnitude); + try { + count.isNormal(); + fail("exception should be thrown"); + } catch(Exception e) { + assertTrue(e instanceof IllegalStateException); + } + } + + public void testIsNormalWithNormalStatus() { + List> referenceRanges = null; + DvInterval normalRange = null; + CodePhrase normalStatus = new CodePhrase("normal statuses", "N"); + double accuracy = 0; + boolean accuracyPercent = false; + String magnitudeStatus = null; + int magnitude = 1; + DvCount count = + new DvCount(referenceRanges, normalRange, normalStatus, accuracy, + accuracyPercent, magnitudeStatus, magnitude); + assertTrue(count.isNormal()); + } + + public void testIsNormalWithAbnormalStatus() { + List> referenceRanges = null; + DvInterval normalRange = null; + CodePhrase normalStatus = new CodePhrase("normal statuses", "L"); + double accuracy = 0; + boolean accuracyPercent = false; + String magnitudeStatus = null; + int magnitude = 1; + DvCount count = + new DvCount(referenceRanges, normalRange, normalStatus, accuracy, + accuracyPercent, magnitudeStatus, magnitude); + assertFalse(count.isNormal()); + } + + public void testIsNormalWithNormalRange() { + List> referenceRanges = null; + DvInterval normalRange = new DvInterval( + new DvCount(0), new DvCount(2)); + CodePhrase normalStatus = null; + double accuracy = 0; + boolean accuracyPercent = false; + String magnitudeStatus = null; + int magnitude = 1; + DvCount count = + new DvCount(referenceRanges, normalRange, normalStatus, accuracy, + accuracyPercent, magnitudeStatus, magnitude); + assertTrue(count.isNormal()); + } + + public void testIsNormalWithNoneInclusiveNormalRange() { + List> referenceRanges = null; + DvInterval normalRange = new DvInterval( + new DvCount(2), new DvCount(4)); + CodePhrase normalStatus = null; + double accuracy = 0; + boolean accuracyPercent = false; + String magnitudeStatus = null; + int magnitude = 1; + DvCount count = + new DvCount(referenceRanges, normalRange, normalStatus, accuracy, + accuracyPercent, magnitudeStatus, magnitude); + assertFalse(count.isNormal()); + } + + public void testIsNormalWithNormalStatusAndNormalRange() { + List> referenceRanges = null; + DvInterval normalRange = new DvInterval( + new DvCount(0), new DvCount(2)); + CodePhrase normalStatus = new CodePhrase("normal statuses", "N"); + double accuracy = 0; + boolean accuracyPercent = false; + String magnitudeStatus = null; + int magnitude = 1; + DvCount count = + new DvCount(referenceRanges, normalRange, normalStatus, accuracy, + accuracyPercent, magnitudeStatus, magnitude); + assertTrue(count.isNormal()); + } + +} +/* + * ***** 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 DvQuantityTest.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Sergio Miranda Freire + * + * 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/datatypes/quantity/DvOrdinalTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvOrdinalTest.java new file mode 100644 index 00000000..ca711db6 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvOrdinalTest.java @@ -0,0 +1,44 @@ +package org.openehr.rm.datatypes.quantity; + +import org.openehr.rm.datatypes.basic.DataValue; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvCodedText; + +import junit.framework.TestCase; + +public class DvOrdinalTest extends TestCase { + + /** + * Tests creating a dvOrdinal with negative value + * + * @throws Exception + */ + public void testCreateDvOrdinalWithNegativeValue() { + CodePhrase definingCode = new CodePhrase("test", "123"); + DvCodedText coded = new DvCodedText("coded text", definingCode); + + try { + new DvOrdinal(-1, coded); + + } catch (IllegalArgumentException e) { + fail("failed to create dvOrdinal with negative value"); + } + } + + public void testParseDvOrdinal() throws Exception { + String value = "DV_ORDINAL,1|SNOMED-CT::313267000|Stroke|"; + DataValue dv = DataValue.parseValue(value); + assertTrue(dv instanceof DvOrdinal); + } + + public void testEquals() { + DvOrdinal ord1 = new DvOrdinal(1, new DvCodedText("text", + new CodePhrase("local", "at0002"))); + + DvOrdinal ord2 = new DvOrdinal(1, new DvCodedText("text", + new CodePhrase("local", "at0002"))); + + assertTrue(ord1.equals(ord2)); + assertTrue(ord2.equals(ord1)); + } +} 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 new file mode 100644 index 00000000..a9cadc05 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvProportionTest.java @@ -0,0 +1,146 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvProportionTest" + * keywords: "datatypes" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.rm.datatypes.quantity; + +import junit.framework.TestCase; + +public class DvProportionTest extends TestCase { + + public void testIsIntegeralWithFraction() { + DvProportion p = new DvProportion(1, 2, ProportionKind.FRACTION, 0); + assertTrue("fraction expected to be integral", p.isIntegral()); + } + + public void testIsIntegeralWithPercent() { + DvProportion p = new DvProportion(1.2, 100, ProportionKind.PERCENT, 1); + assertFalse("percent expected not to be integral", p.isIntegral()); + } + + public void testCreateFractionProportionWithNonZeroPrecision() { + try { + new DvProportion(1, 10, ProportionKind.FRACTION, 1); + fail("should fail to create integral fraction with non-zero precision"); + } catch(Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + } + + public void testCreateProportionWithZeroPrecisionAndNonIntegral() { + try { + new DvProportion(1.3, 10, ProportionKind.RATIO, 0); + fail("should fail to create non-integral with zero precision"); + } catch(Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + } + + public void testCreateIntegralProportionWithNonIntegralNumer() { + try { + new DvProportion(1.3, 10, ProportionKind.FRACTION, 0); + fail("should fail to create integral with non-integral num"); + } catch(Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + } + + public void testCreateUnitaryProportionWithBadDenominator() { + try { + new DvProportion(1.3, 2, ProportionKind.UNITARY, 1); + fail("should fail to create unitary with bad denominator"); + } catch(Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + } + + public void testCreateUnitaryProportionWithRightDenominator() { + new DvProportion(1.3, 1, ProportionKind.UNITARY, 1); + } + + public void testCreateIngegerProportionWithoutPricision() { + try { + new DvProportion(1.0, 1.0, ProportionKind.RATIO, null); + } catch(Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + } + + public void testCreateDoubleProportionWithoutPricision() { + try { + new DvProportion(0.5, 1.0, ProportionKind.RATIO, null); + } catch(Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + } + + public void testCreatePercentProportionWithBadDenominator() { + try { + new DvProportion(1.25, 10, ProportionKind.PERCENT, 2); + fail("should fail to create percent with bad denominator"); + } catch(Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + } + + public void testCreatePercentProportionWithRightDenominator() { + new DvProportion(1.25, 100, ProportionKind.PERCENT, 2); + } + + public void testCreateUnitaryProportionUsingFactoryMethod() { + DvProportion dp = DvProportion.createUnitaryProportion(1.2, 1); + assertEquals(1.2, dp.getNumerator(), 0); + } + + public void testParsingDvProportion() { + DvProportion dp = new DvProportion(25.3, 100, ProportionKind.PERCENT, 1); + assertEquals(DvProportion.parseValue("DV_PROPORTION,25.3,100,2"), dp); + } + + public void testParsingDvProportion2() { + DvProportion dp = new DvProportion(21, 24, ProportionKind.FRACTION, 0); + assertEquals(DvProportion.parseValue("DV_PROPORTION,21,24,3"), dp); + } + public void testParsingDvProportion3() { + DvProportion dp = new DvProportion(29, 24, ProportionKind.INTEGER_FRACTION, 0); + assertEquals(DvProportion.parseValue("DV_PROPORTION,29,24,3"), dp); + } +} +/* + * ***** 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 DvProportionTest.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2007 + * 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/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 new file mode 100644 index 00000000..e315fa13 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvQuantityTest.java @@ -0,0 +1,166 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvQuantityTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/datatypes/quantity/DvQuantityTest.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +/** + * QuantityTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.datatypes.quantity; + +import junit.framework.TestCase; + +import org.openehr.rm.datatypes.basic.DataValue; +import org.openehr.rm.support.measurement.MeasurementService; +import org.openehr.rm.support.measurement.TestMeasurementService; + +import java.text.DecimalFormatSymbols; + +public class DvQuantityTest extends TestCase { + + public DvQuantityTest(String test) { + super(test); + } + + // also test equals() from both Quantified and Measurable + public void testEquals() throws Exception { + DvQuantity q1 = new DvQuantity("mg", 10, 2, ms); + DvQuantity q2 = new DvQuantity("mg", 10, 2, ms); + assertTrue(q1 + " equals " + q2, q1.equals(q2)); + + q1 = new DvQuantity("mg", 10, ms); + q2 = new DvQuantity("mg", 10, ms); + assertTrue(q1 + " equals " + q2, q1.equals(q2)); + + q1 = new DvQuantity(10); + q2 = new DvQuantity(10); + assertTrue(q1 + " equals " + q2, q1.equals(q2)); + + q1 = new DvQuantity(10.5); + q2 = new DvQuantity(10.5); + assertTrue(q1 + " equals " + q2, q1.equals(q2)); + + // missing precision + q1 = new DvQuantity("mg", 10, 2, ms); + q2 = new DvQuantity("mg", 10, ms); + assertFalse(q1 + " not equals " + q2, q1.equals(q2)); + + // missing units + q1 = new DvQuantity(10); + q2 = new DvQuantity("mg", 10, ms); + assertFalse(q1 + " not equals " + q2, q1.equals(q2)); + + // diff precision + q1 = new DvQuantity("mg", 10, 2, ms); + q2 = new DvQuantity("mg", 10, 3, ms); + assertFalse(q1 + " not equals " + q2, q1.equals(q2)); + + // diff units + q1 = new DvQuantity("kg", 10, 2, ms); + q2 = new DvQuantity("mg", 10, 2, ms); + assertFalse(q1 + " not equals " + q2, q1.equals(q2)); + + // diff getMagnitude + q1 = new DvQuantity("mg", 12, 2, ms); + q2 = new DvQuantity("mg", 10, 2, ms); + assertFalse(q1 + " not equals " + q2, q1.equals(q2)); + } + + public void testToString() throws Exception { + DvQuantity q = new DvQuantity("kg", 78, 2, ms); + String expected = "78.00,kg"; + assertEquals(expected, q.toString()); + + q = new DvQuantity("kg", 78, ms); + expected = "78,kg"; + assertEquals(expected, q.toString()); + + q = new DvQuantity(78); + expected = "78"; + assertEquals(expected, q.toString()); + + q = new DvQuantity(78.9); + expected = "79"; + assertEquals(expected, q.toString()); + + q = new DvQuantity(78.5); + expected = "78"; + assertEquals(expected, q.toString()); + + q = new DvQuantity(78.5, 3, ms); + 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 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); + } + + 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); + } + + public void testCreateWithUnlimitedPrecision() { + try { + new DvQuantity("mg", 12, -1, ms); + } catch(Exception e) { + fail("failed to create DvQuantity with unlimited precision"); + } + } + + private MeasurementService ms = new TestMeasurementService(); +} +/* + * ***** 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 DvQuantityTest.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/datatypes/quantity/ProportionKindTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/ProportionKindTest.java new file mode 100644 index 00000000..7f3c117d --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/ProportionKindTest.java @@ -0,0 +1,78 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ProportionKindTest" + * keywords: "datatypes" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2007 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.rm.datatypes.quantity; + +import junit.framework.TestCase; + +/** + * Testcase for ProportionKind + * + * @author Rong Chen + */ +public class ProportionKindTest extends TestCase { + + public void testGetRatioFromValue() { + assertEquals("Ratio kind expected", ProportionKind.RATIO, + ProportionKind.fromValue(0)); + } + + public void testGetUnitaryFromValue() { + assertEquals("Unitar kind expected", ProportionKind.UNITARY, + ProportionKind.fromValue(1)); + } + + public void testGetPercentFromValue() { + assertEquals("Percent kind expected", ProportionKind.PERCENT, + ProportionKind.fromValue(2)); + } + + public void testGetFractionFromValue() { + assertEquals("Fraction kind expected", ProportionKind.FRACTION, + ProportionKind.fromValue(3)); + } + + public void testGetIntegerFractionFromValue() { + assertEquals("Integer fraction kind expected", + ProportionKind.INTEGER_FRACTION, ProportionKind.fromValue(4)); + } +} +/* + * ***** 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 ProportionKindTest.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2007 + * 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/datatypes/quantity/datetime/DvDateTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTest.java new file mode 100644 index 00000000..d7950bfb --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTest.java @@ -0,0 +1,205 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvDateTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/datatypes/quantity/datetime/DvDateTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ + +/** + * DvDateTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.datatypes.quantity.datetime; + +import junit.framework.TestCase; + +public class DvDateTest extends TestCase { + + public DvDateTest(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 testCompareTo() throws Exception { + assertTrue(dvDate("1999-12-31").compareTo(dvDate("2000-01-01")) < 0); + assertTrue(dvDate("2001-01-31").compareTo(dvDate("2001-02-01")) < 0); + assertTrue(dvDate("2001-02-11").compareTo(dvDate("2001-02-12")) < 0); + + assertTrue(dvDate("20030201").compareTo(dvDate("20021215")) > 0); + assertTrue(dvDate("20030202").compareTo(dvDate("20030124")) > 0); + assertTrue(dvDate("20030216").compareTo(dvDate("20030215")) > 0); + + assertTrue(dvDate("2002-02").compareTo(dvDate("2002-02-01")) == 0); + assertTrue(dvDate("2002-02").compareTo(dvDate("2002-02-02")) < 0); + assertTrue(dvDate("2002").compareTo(dvDate("2002-02-02")) < 0); + assertTrue(dvDate("2002-02").compareTo(dvDate("2002-01")) > 0); + assertTrue(dvDate("2002").compareTo(dvDate("2001-12")) > 0); + + } + + private DvDate dvDate(String value) throws Exception { + return new DvDate(value); + } + + public void testToString() throws Exception { + assertEquals(new DvDate("2001-01-15").toString(), "2001-01-15"); + assertEquals(new DvDate("20011015").toString(), "20011015"); + assertEquals(new DvDate("2001-10").toString(), "2001-10"); + assertEquals(new DvDate("2001").toString(), "2001"); + assertEquals(new DvDate(2001, 12, 15).toString(), "2001-12-15"); + assertEquals(new DvDate(2000, 10).toString(), "2000-10"); + assertEquals(new DvDate(2000).toString(), "2000"); + } + + public void testToStringTakesBoolean() { + assertEquals(new DvDate("2001-01-15").toString(false), "20010115"); + assertEquals(new DvDate("20011015").toString(true), "2001-10-15"); + assertEquals(new DvDate("2001-10").toString(false), "200110"); + assertEquals(new DvDate("2001").toString(true), "2001"); + assertEquals(new DvDate(2001, 12, 15).toString(false), "20011215"); + assertEquals(new DvDate(2000, 10).toString(true), "2000-10"); + assertEquals(new DvDate(2000).toString(false), "2000"); + } + + public void testEquals() throws Exception { + //Two DvDate are equal if both indicate the same date. + DvDate dateOne = new DvDate("2004-01-31"); + DvDate dateTwo = new DvDate(2004, 1, 31); + DvDate dateThree = new DvDate("20040131"); + assertTrue("dateOne.equals(dateTwo): ", dateOne.equals(dateTwo)); + assertTrue("dateTWo.equals(dateOne): ", dateTwo.equals(dateOne)); + assertTrue("dateOne.equals(dateThree): ", dateOne.equals(dateThree)); + assertTrue("dateThree.equals(dateOne): ", dateThree.equals(dateOne)); + assertTrue("dateTwo.equals(dateThree): ", dateTwo.equals(dateThree)); + assertTrue("dateThree.equals(dateTwo): ", dateThree.equals(dateTwo)); + dateOne = new DvDate("1999-09"); + dateTwo = new DvDate(1999, 9); + dateThree = new DvDate("199909"); + assertTrue("dateOne.equals(dateTwo): ", dateOne.equals(dateTwo)); + assertTrue("dateTWo.equals(dateOne): ", dateTwo.equals(dateOne)); + assertTrue("dateOne.equals(dateThree): ", dateOne.equals(dateThree)); + assertTrue("dateThree.equals(dateOne): ", dateThree.equals(dateOne)); + assertTrue("dateTwo.equals(dateThree): ", dateTwo.equals(dateThree)); + assertTrue("dateThree.equals(dateTwo): ", dateThree.equals(dateTwo)); + } + + public void testConstructorTakesString() throws Exception { + String[] values = { + "2004-12-31", "1999-01-01", "18990102", "1789-09", "166612", "2002" + }; + for (String value : values) { + assertEquals(new DvDate(value), dvDate(value)); + } + } + + public void testConstructorTakesIntegers() throws Exception { + assertNotNull(new DvDate(1000)); + assertNotNull(new DvDate(1980, 11)); + assertNotNull(new DvDate(2000, 11, 30)); + } + + public void testGetYearMonthDay() throws Exception { + DvDate date = new DvDate(1999, 10, 20); + assertEquals("year", 1999, date.getYear()); + assertEquals("month", 10, date.getMonth()); + assertEquals("day", 20, date.getDay()); + date = new DvDate("2002-09-20"); + assertEquals("year", 2002, date.getYear()); + assertEquals("month", 9, date.getMonth()); + assertEquals("day", 20, date.getDay()); + date = new DvDate("20060107"); + assertEquals("year", 2006, date.getYear()); + assertEquals("month", 1, date.getMonth()); + assertEquals("day", 7, date.getDay()); + date = new DvDate("204611"); + assertEquals("year", 2046, date.getYear()); + assertEquals("month", 11, date.getMonth()); + assertEquals("day", -1, date.getDay()); + date = new DvDate(1988, 3); + assertEquals("year", 1988, date.getYear()); + assertEquals("month", 3, date.getMonth()); + assertEquals("day", -1, date.getDay()); + date = new DvDate("2020"); + assertEquals("year", 2020, date.getYear()); + assertEquals("month", -1, date.getMonth()); + assertEquals("day", -1, date.getDay()); + } + + public void testMonthDayKnown() throws Exception { + DvDate date = new DvDate(1999, 10, 20); + assertEquals("isPartial", false, date.isPartial()); + assertEquals("month known", true, date.monthKnown()); + assertEquals("day known", true, date.dayKnown()); + date = new DvDate("204611"); + assertEquals("isPartial", true, date.isPartial()); + assertEquals("month known", true, date.monthKnown()); + assertEquals("day known", false, date.dayKnown()); + date = new DvDate(2020); + assertEquals("isPartial", true, date.isPartial()); + assertEquals("month known", false, date.monthKnown()); + assertEquals("day known", false, date.dayKnown()); + } + + public void testSetValueInConstructor() throws Exception { + assertEquals(new DvDate(2).getValue(), "0002"); + assertEquals(new DvDate(20).getValue(), "0020"); + assertEquals(new DvDate(200).getValue(), "0200"); + assertEquals(new DvDate(2000).getValue(), "2000"); + + assertEquals(new DvDate(2000, 9).getValue(), "2000-09"); + assertEquals(new DvDate(2000, 10).getValue(), "2000-10"); + + assertEquals(new DvDate(2000, 10, 1).getValue(), "2000-10-01"); + assertEquals(new DvDate(2000, 10, 10).getValue(), "2000-10-10"); + } +} +/* + * ***** 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 DvDateTest.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/datatypes/quantity/datetime/DvDateTimeParserTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeParserTest.java new file mode 100644 index 00000000..3b657dbb --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeParserTest.java @@ -0,0 +1,426 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvDateTimeParserTest" + * 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/datatypes/quantity/datetime/DvDateTimeParserTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" + */ + +/** + * DvDateTimeParserTest + * + * @author Yin Su Lim + * @version 1.0 + */ + +package org.openehr.rm.datatypes.quantity.datetime; + +import junit.framework.*; + +import java.util.Locale; +import java.util.TimeZone; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.joda.time.format.ISODateTimeFormat; + +public class DvDateTimeParserTest extends TestCase { + + public DvDateTimeParserTest(String testName) { + super(testName); + } + + protected void setUp() throws Exception { + defZoneStr = DvDateTimeParser.convertTimeZone( + DateTimeZone.getDefault().getOffset(new DateTime()), false); + } + + protected void tearDown() throws Exception { + } + + /** + * Test of parseTime method, of class org.openehr.rm.datatypes.quantity.datetime.DvDateTimeParser. + */ + public void testParseTime() { + String[] values = { + "23", "23:30", "23:30Z", "23+11", "2330", "1000Z", "11Z", "153722", + "225523.9", "102030.01", "191817.289", + "23:59:59", "12:35:45.666", "12:35:45-0700" + + };//strings that should pass + for(int i = 0; i < values.length; i++) { + DateTime result = DvDateTimeParser.parseTime(values[i]); + assertNotNull(result); + } + } + + public void testParseTimeWithPtBrLocale() { + Locale defaultLocale = Locale.getDefault(); + Locale.setDefault(new Locale("pt", "BR")); + + try { + DvDateTimeParser.parseTime("010000"); + } catch(Exception e) { + fail("failed to parse 010000 in 'pt-BR' locale"); + } + Locale.setDefault(defaultLocale); + } + + /** + * Test of parseDate method, of class org.openehr.rm.datatypes.quantity.datetime.DvDateTimeParser. + */ + public void testParseDate() { + //String value = "199912"; + String[] values = { + "1333", "1982-02-19", "1982-02", "29491213", "199002" + };//strings that pass + DateTime result = null; + for(int i = 0; i < values.length; i++) { + result = DvDateTimeParser.parseDate(values[i]); + assertNotNull(result); + } + } + + /** + * Test of parseDateTime method, of class org.openehr.rm.datatypes.quantity.datetime.DvDateTimeParser. + */ + public void testParseDateTime() { + + String[] values = { + "1999-09-10T23:59:59.010-02:00", "2009-12-12T00:12", "2009-12-12T00:12-01:00", "2000-12-01T10Z", + "1900-01-04T11+02:00", "19990910T235959,000+0100", "19441116T005900.000", "19001217T205933", + "19441116T00+0900", "13440916T00", "2000-01-01T00:00:59+1200" + };//strings that pass + for(int i = 0; i < values.length; i++) { + DateTime result = DvDateTimeParser.parseDateTime(values[i]); + assertNotNull(result); + } + } + + /** + * Test of padTimeValue method, of class org.openehr.rm.datatypes.quantity.datetime.DvDateTimeParser. + */ + public void testPadValue() { + assertEquals("232922.000" + defZoneStr, DvDateTimeParser.padTimeValue("232922")); + assertEquals("232922,099" + defZoneStr, DvDateTimeParser.padTimeValue("232922,099")); + assertEquals("131920.000Z", DvDateTimeParser.padTimeValue("131920Z")); + assertEquals("011300.000-09", DvDateTimeParser.padTimeValue("011300-09")); + assertEquals("021530.123-09", DvDateTimeParser.padTimeValue("021530.123-09")); + } + + /** + * Test of convertTimeZone method, of class org.openehr.rm.datatypes.quantity.datetime.DvDateTimeParser. + */ + public void testConvertTimeZone() { + + assertEquals("+0200", DvDateTimeParser.convertTimeZone(7200000, false)); + assertEquals("-00:30", DvDateTimeParser.convertTimeZone(-1800000, true)); + assertEquals("Z", DvDateTimeParser.convertTimeZone(0, false)); + } + + + /** + * Test of convertTime method, of class org.openehr.rm.datatypes.quantity.datetime.DvDateTimeParser. + */ + public void testConvertTime() { + TimeZone timezone = TimeZone.getTimeZone("GMT+04"); + + assertNotNull(DvDateTimeParser.convertTime(0, 0, 0, 0, null)); + assertNotNull(DvDateTimeParser.convertTime(2, 16, 35, 0, timezone)); + DateTime dt = null; + try { + dt = DvDateTimeParser.convertTime(2, 16, 35, 1.24, timezone); + } catch (Exception e) { + + } + assertNull(dt);//TODO: do try catch + } + + /** + * Test of convertDate method, of class org.openehr.rm.datatypes.quantity.datetime.DvDateTimeParser. + */ + public void testConvertDate() { + + int year = 1900; + int month = 1; + int day = 2; + TimeZone timezone = null; + + //DateTime expResult = null; + DateTime result = DvDateTimeParser.convertDate(year, month, day); + assertNotNull(result); + + } + + public static Test suite() { + TestSuite suite = new TestSuite(DvDateTimeParserTest.class); + + return suite; + } + + /** + * Test of convertDateTime method, of class org.openehr.rm.datatypes.quantity.datetime.DvDateTimeParser. + */ + public void testConvertDateTime() { + + int year = 1000; + int month = 1; + int day = 1; + int hour = 0; + int mintue = 0; + int second = 0; + double fractSec = 0.0; + TimeZone tzone = null; + + DateTime expResult = null; + DateTime result = DvDateTimeParser.convertDateTime(year, month, day, hour, mintue, second, fractSec, tzone); + assertNotNull(result); + + } + + /** + * Test of defaultTime method, of class org.openehr.rm.datatypes.quantity.datetime.DvDateTimeParser. + */ + public void testDefaultTime() { + + DateTime expResult = null; + DateTime result = DvDateTimeParser.defaultTime(); + assertNotNull(result); + } + + /** + * Test of defaultDate method, of class org.openehr.rm.datatypes.quantity.datetime.DvDateTimeParser. + */ + public void testDefaultDate() { + + DateTime expResult = null; + DateTime result = DvDateTimeParser.defaultDate(); + assertNotNull(result); + + } + + /** + * Test of defaultDateTime method, of class org.openehr.rm.datatypes.quantity.datetime.DvDateTimeParser. + */ + public void testDefaultDateTime() { + + DateTime expResult = null; + DateTime result = DvDateTimeParser.defaultDateTime(); + assertNotNull(result); + + } + + /** + * Test of toTimeString method, + * of class org.openehr.rm.datatypes.quantity.datetime.DvDateTimeParser. + */ + public void testToTimeString() { + + //int[] timeElems = {1, 23, 7, 12}; + TimeZone timezone = TimeZone.getTimeZone("GMT+04"); + DateTime time = new DateTime(1343, 3, 6 , 20, 22, 19, 0, DateTimeZone.forTimeZone(timezone)); + assertEquals("20:22:19.000+04:00", DvDateTimeParser.toTimeString(time, "HH:mm:ss.SSSZZ")); + assertEquals("20:22+04:00", DvDateTimeParser.toTimeString(time, "HH:mmZZ")); + assertEquals("20:22+04:00", DvDateTimeParser.toTimeString(time, "19:19Z")); + assertEquals("20:22:19,000", DvDateTimeParser.toTimeString(time, "19:19:00,010")); + // If the default timezone is London, say, then the following datetime will be + // 2006-06-30T20:59:00.000+01:00, because at that point of datetime, the timezone offset + // value will be +0100. In Joda, timezone and tzoffset value are different. tzOffset value + // always depends on a datetime and zone. + time = new DateTime(1970, 2 , 1 , 20, 22, 19, 0); //constructor without timezone + //no timeZone means default zone + assertEquals("202219.000", DvDateTimeParser.toTimeString(time, "HHmmss.SSS")); + assertEquals("2022", DvDateTimeParser.toTimeString(time, "HHmm")); + assertEquals("2022" + getZoneString(time), DvDateTimeParser.toTimeString(time, "1000Z")); + + timezone = TimeZone.getTimeZone("GMT-02"); + time = new DateTime(1970, 4 , 1 , 12, 25, 29, 235, DateTimeZone.forTimeZone(timezone)); + assertEquals("122529.235-0200", DvDateTimeParser.toTimeString(time, "HHmmss.SSSZ")); + assertEquals("12-0200", DvDateTimeParser.toTimeString(time, "HHZ")); + assertEquals("12-02:00", DvDateTimeParser.toTimeString(time, "01-01:00")); + timezone = TimeZone.getTimeZone("UTC"); + time = new DateTime(1970, 4 , 1 , 12, 25, 29, 235, DateTimeZone.forTimeZone(timezone)); + //assertEquals("122529.235Z", DvDateTimeParser.toTimeString(time, "HHmmss.SSSZ")); + assertEquals("12:25:29.235Z", DvDateTimeParser.toTimeString(time, "HH:mm:ss.SSSZZ")); + assertEquals("12Z", DvDateTimeParser.toTimeString(time, "HHZZ")); + assertEquals("12Z", DvDateTimeParser.toTimeString(time, "01+01:00")); + } + + /** + * Test of toDateString method, + * of class org.openehr.rm.datatypes.quantity.datetime.DvDateTimeParser. + */ + public void testToDateString() { + + //int[] timeElems = {1, 23, 7, 12}; + DateTime time = new DateTime(1343, 3, 6 , 0, 22, 19, 0); + assertEquals("1343-03-06", DvDateTimeParser.toDateString(time, "yyyy-MM-dd")); + assertEquals("13430306", DvDateTimeParser.toDateString(time, "yyyyMMdd")); + assertEquals("13430306", DvDateTimeParser.toDateString(time, "10000311")); + time = new DateTime(1970, 2 , 1 , 20, 22, 19, 0); + //no timeZone means default zone + assertEquals("1970-02", DvDateTimeParser.toDateString(time, "yyyy-MM")); + assertEquals("197002", DvDateTimeParser.toDateString(time, "yyyyMM")); + assertEquals("197002", DvDateTimeParser.toDateString(time, "196911")); + time = new DateTime(1960, 4 , 1 , 12, 25, 29, 235); + assertEquals("1960", DvDateTimeParser.toDateString(time, "yyyy")); + assertEquals("1960", DvDateTimeParser.toDateString(time, "2000")); + } + + /** + * Test of toDateTimeString method + * + */ + public void testToDateTimeString() { + TimeZone timezone = TimeZone.getTimeZone("UTC"); + DateTime time = new DateTime(1343, 3, 6 , 0, 22, 19, 0, DateTimeZone.forTimeZone(timezone)); + assertEquals("1343-03-06T00:22:19.000Z", DvDateTimeParser.toDateTimeString(time, "yyyy-MM-dd'T'HH:mm:ss.SSSZZ")); + assertEquals("13430306T002219.000", DvDateTimeParser.toDateTimeString(time, "yyyyMMdd'T'HHmmss.SSS")); + assertEquals("13430306T002219,000Z", DvDateTimeParser.toDateTimeString(time, "20000101T122010,000-0100")); + assertEquals("13430306T0022", DvDateTimeParser.toDateTimeString(time, "yyyyMMdd'T'HHmm")); + assertEquals("1343-03-06T00", DvDateTimeParser.toDateTimeString(time, "yyyy-MM-dd'T'HH")); + assertEquals("1343-03T00:22", DvDateTimeParser.toDateTimeString(time, "yyyy-MM'T'HH:mm")); + assertEquals("134303T00:22:19", DvDateTimeParser.toDateTimeString(time, "100003T11:00:23")); + time = ISODateTimeFormat.dateTimeParser().withOffsetParsed().parseDateTime("1997-09-01T19:09:29.789"); + //no timeZone means default zone + //String ret = DvDateTimeParser.toDateTimeString(time, "yyyyMMdd'T'HHmmss,SSSZ"); + //String exp = "19970901T190929,789" + getZoneString(time); + + assertEquals("19970901T190929,789" + getZoneString(time), DvDateTimeParser.toDateTimeString(time, "yyyyMMdd'T'HHmmss,SSSZ")); + assertEquals("19970901T1909", DvDateTimeParser.toDateTimeString(time, "20000101T1922")); + assertEquals("1997-09T19:09", DvDateTimeParser.toDateString(time, "yyyy-MM'T'HH:mm")); + + } + + + /** + * Test of concatenateTimeElems method, + * of class org.openehr.rm.datatypes.quantity.datetime.DvDateTimeParser. + */ + public void testAddExtension() { + + String pattern = "HHmmss.SSS"; + String result = DvDateTimeParser.addExtension(pattern); + assertEquals("HH:mm:ss.SSS", result); + assertEquals("HH", DvDateTimeParser.addExtension("HH")); + assertEquals("HH:mm", DvDateTimeParser.addExtension("HHmm")); + assertEquals("yyyy", DvDateTimeParser.addExtension("yyyy")); + assertEquals("yyyy-MM", DvDateTimeParser.addExtension("yyyyMM")); + assertEquals("yyyy-MM-dd", DvDateTimeParser.addExtension("yyyyMMdd")); + assertEquals("yyyyTHH", DvDateTimeParser.addExtension("yyyyTHH")); + assertEquals("yyyyTHH:mm", DvDateTimeParser.addExtension("yyyyTHHmm")); + assertEquals("yyyy-MMTHH:mm", DvDateTimeParser.addExtension("yyyyMMTHHmm")); + + } + + /** + * Test of concatenateTimeElems method, + * of class org.openehr.rm.datatypes.quantity.datetime.DvDateTimeParser. + */ + public void testAnalyseTimeString() { + + assertEquals(4, DvDateTimeParser.analyseTimeString("13:29:40.345Z")); + assertEquals(3, DvDateTimeParser.analyseTimeString("23:29:00")); + assertEquals(2, DvDateTimeParser.analyseTimeString("23:29+09:00")); + assertEquals(1, DvDateTimeParser.analyseTimeString("23")); + assertEquals(4, DvDateTimeParser.analyseTimeString("232900.809-0230")); + assertEquals(3, DvDateTimeParser.analyseTimeString("132940")); + assertEquals(2, DvDateTimeParser.analyseTimeString("2329-0230")); + assertEquals(1, DvDateTimeParser.analyseTimeString("23+0100")); + } + + /** + * Test of concatenateTimeElems method, + * of class org.openehr.rm.datatypes.quantity.datetime.DvDateTimeParser. + */ + public void testAnalyseDateString() { + + assertEquals(3, DvDateTimeParser.analyseDateString("1990-07-23")); + assertEquals(3, DvDateTimeParser.analyseDateString("1990-07-02")); + assertEquals(2, DvDateTimeParser.analyseDateString("1990-07")); + assertEquals(1, DvDateTimeParser.analyseDateString("1990")); + assertEquals(3, DvDateTimeParser.analyseDateString("20890912")); + assertEquals(2, DvDateTimeParser.analyseDateString("208909")); + assertEquals(1, DvDateTimeParser.analyseDateString("2089")); + } + + /** + * Test of basicToExtendedTime method, + * of class org.openehr.rm.datatypes.quantity.datetime.DvDateTimeParser. + */ + public void testBasicToExtendedTime() { + + assertEquals("23:29:00.809-02:30", DvDateTimeParser.basicToExtendedTime("232900.809-0230")); + assertEquals("22:22:10-10:30", DvDateTimeParser.basicToExtendedTime("222210-1030")); + assertEquals("12:11Z", DvDateTimeParser.basicToExtendedTime("1211Z")); + assertEquals("23+01:30", DvDateTimeParser.basicToExtendedTime("23+0130")); + assertEquals("10Z", DvDateTimeParser.basicToExtendedTime("10Z")); + assertEquals("10", DvDateTimeParser.basicToExtendedTime("10")); + assertEquals("10:30", DvDateTimeParser.basicToExtendedTime("1030")); + assertEquals("15:25:44", DvDateTimeParser.basicToExtendedTime("152544")); + assertEquals("15:25:44,678", DvDateTimeParser.basicToExtendedTime("152544,678")); + } + + /** + * Test of basicToExtendedDate method, + * of class org.openehr.rm.datatypes.quantity.datetime.DvDateTimeParser. + */ + public void testBasicToExtendedDate() { + + assertEquals("1999", DvDateTimeParser.basicToExtendedDate("1999")); + assertEquals("2222-10", DvDateTimeParser.basicToExtendedDate("222210")); + assertEquals("1700-09-01", DvDateTimeParser.basicToExtendedDate("17000901")); + + } + + public void testBasicToTextendedDateTime() { + + assertEquals("1999-09-09T21", DvDateTimeParser.basicToExtendedDateTime("19990909T21")); + assertEquals("2002-01-05T03:36", DvDateTimeParser.basicToExtendedDateTime("20020105T0336")); + assertEquals("2012-11-16T05:27Z", DvDateTimeParser.basicToExtendedDateTime("2012-11-16T05:27Z")); + assertEquals("1626-08-31T02-01:00", DvDateTimeParser.basicToExtendedDateTime("16260831T02-0100")); + assertEquals("1772-02-29T23", DvDateTimeParser.basicToExtendedDateTime("1772-02-29T23")); + } + + String getZoneString(DateTime dt) { + return DvDateTimeParser.convertTimeZone(DateTimeZone.getDefault().getOffset(dt), false); + } + + private String defZoneStr; +} + +/* + * ***** 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 DvDateTimeParserTest.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 ***** + */ 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 new file mode 100644 index 00000000..7e41783b --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeParserTimeZoneTest.java @@ -0,0 +1,30 @@ +package org.openehr.rm.datatypes.quantity.datetime; + +import java.util.TimeZone; + +import junit.framework.TestCase; + +public class DvDateTimeParserTimeZoneTest extends TestCase { + public DvDateTimeParserTimeZoneTest() { + defaultTimeZone = TimeZone.getDefault(); + } + + public void setUp() throws Exception { + System.setProperty("user.timezone", "GMT-3:00"); + TimeZone.setDefault(TimeZone.getTimeZone("GMT-3:00")); + } + + public void tearDown() throws Exception { + TimeZone.setDefault(defaultTimeZone); + } + + public void testParseTime() { + try { + DvDateTimeParser.parseTime("010000"); + } catch(Exception e) { + fail("failed to parse 010000 in GMT-3 timezone"); + } + } + + private TimeZone defaultTimeZone; +} 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 new file mode 100644 index 00000000..2948f908 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeTest.java @@ -0,0 +1,154 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvDateTimeTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ + +/** + * DvDateTimeTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.datatypes.quantity.datetime; + +import java.util.TimeZone; +import junit.framework.TestCase; + +public class DvDateTimeTest extends TestCase { + + public DvDateTimeTest(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 testCompareTo() throws Exception { + assertTrue(dvDate("1999-12-31T00:00:00").compareTo(dvDate("2000-01-01T00:00:00")) < 0); + assertTrue(dvDate("2001-01-31T00:00:00").compareTo(dvDate("2001-02-01T00:00:00")) < 0); + assertTrue(dvDate("20010211T000000").compareTo(dvDate("2001-02-12T00:00:00")) < 0); + assertTrue(dvDate("2001-02-11T00:00").compareTo(dvDate("2001-02-11T00:00:01")) < 0); + assertTrue(dvDate("2001-02-11T00").compareTo(dvDate("2001-02-11T00:01:00")) < 0); + assertTrue(dvDate("2001-02-11T00+01").compareTo(dvDate("2001-02-11T01:00:00Z")) < 0); + + assertTrue(dvDate("2003-02-01T00:00:00").compareTo(dvDate("2002-12-15T00:00:00")) > 0); + assertTrue(dvDate("2003-02-02T00:00").compareTo(dvDate("2003-01-24T00:00:00")) > 0); + assertTrue(dvDate("2003-02-16T00:00:00").compareTo(dvDate("2003-02-15T23:59:00")) > 0); + assertTrue(dvDate("2001-01-01T01:00:00").compareTo(dvDate("20010101T00")) > 0); + assertTrue(dvDate("2001-01-01T00:01:00").compareTo(dvDate("2001-01-01T00:00:00")) > 0); + assertTrue(dvDate("2001-01-01T00:00:01-03").compareTo(dvDate("2001-01-01T01:00:00Z")) > 0); + + assertTrue(dvDate("2002-02-01T00:00:00").compareTo(dvDate("2002-02-01T00:00:00")) == 0); + assertTrue(dvDate("2002-02-01T00:00:00Z").compareTo(dvDate("20020201T010000+01")) == 0); + + + } + + public void testToString() throws Exception { + String[] values = { + "2004-10-31T20:10:55", "2000-01-01T00:00:59" + }; + for(String value : values) { + assertEquals(dvDate(value).toString(), value); + } + } + + private DvDateTime dvDate(String value) throws Exception { + return new DvDateTime(value); + } + + public void testConstructorTakesString() throws Exception { + String[] values = { + "2004-10-31T20:10:55", "2000-01-01T00:00:59", + "2000-01-01T00:00:59+1200" + }; + for(String value : values) { + assertEquals(new DvDateTime(value), dvDate(value)); + } + } + + public void testGetters() throws Exception { + DvDateTime datetime = new DvDateTime("1999-10-20T18:15:45"); + assertEquals("year", 1999, datetime.getYear()); + assertEquals("month", 10, datetime.getMonth()); + assertEquals("day", 20, datetime.getDay()); + assertEquals("hour", 18, datetime.getHour()); + assertEquals("minute", 15, datetime.getMinute()); + assertEquals("second", 45, datetime.getSecond()); + assertEquals("fracSecond", -0.1, datetime.getFractionalSecond()); + } + + public void testEquals() throws Exception { + DvDateTime datetime1 = new DvDateTime("2003-12-15T09:30:00Z"); + DvDateTime datetime2 = new DvDateTime(2003, 12, 15, 9, 30, 0, TimeZone.getTimeZone("UTC")); + assertTrue(datetime1.equals(datetime2)); + assertTrue(datetime2.equals(datetime1)); + + datetime1 = new DvDateTime("2003-12-15T09:30:00"); + datetime2 = new DvDateTime("2003-12-15T10:30:00"); + assertFalse(datetime1.equals(datetime2)); + assertFalse(datetime2.equals(datetime1)); + + } + + public void testAdd() throws Exception { + DvDateTime datetime = new DvDateTime("2003-12-15T09:30:00Z"); + assertEquals(new DvDateTime("2004-12-15T09:30:00Z"), datetime.add(new DvDuration("P1Y"))); + assertEquals(new DvDateTime("2004-12-16T09:30:00Z"), datetime.add(new DvDuration("P1Y1D"))); + assertEquals(new DvDateTime("2004-12-17T00:00:00Z"), datetime.add(new DvDuration("P1Y1DT14H30m"))); + assertEquals(new DvDateTime("2002-12-13T18:45:00Z"), datetime.add(new DvDuration("-P1Y1DT14H45m"))); + } + + 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"))); + } +} +/* + * ***** 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 DvDateTimeTest.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/datatypes/quantity/datetime/DvDurationTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDurationTest.java new file mode 100644 index 00000000..8f8fc340 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDurationTest.java @@ -0,0 +1,287 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvDurationTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/datatypes/quantity/datetime/DvDurationTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +/** + * DurationTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.datatypes.quantity.datetime; + +import junit.framework.TestCase; + +public class DvDurationTest extends TestCase { + + public DvDurationTest(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 testConstructorTakesString() throws Exception { + + // test with wrong format + String[] value = { + null, "P10D9H8m7s", "10", "", "P10D11WT9h8M7s", "P10a8m7s", "T9H8m0,000s", + "P-1y-4W", "-P0Y0DT-7H", "PT", "P0DT" //once T is there, must be followed by at least one time ele + }; + for(int i = 0; i < value.length; i++) { + assertExceptionThrownByConstructor(value[i]); + } + + // test with expected values + value = new String[] { + "P0Y12M32W10DT9H8m7.898s", "P10DT9H8m7s", + "P10D", "PT9H", "PT8m", "PT7s", + "P10DT9H", "PT9H8m", "PT8m7s", "P10DT7s", + "P10DT9H7s", "PT9H0M8S", "P1Y2M3W4D", + "P9y6dT2.99s", "P35WT45H", "P20M33DT79m", + "PT0,19s", "-P1Y2m3W4dT5H6m7,8s", + "-PT0H0m56s", "P", "P0Y", "P0DT0s", "PT0H", + "PT0s" + }; + 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, 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, 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}, + {-1, -2, -3, -4, -5, -6, -7, -800}, {0, 0, 0, 0, 0, 0, -56, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0} + }; + for (int i = 0; i < value.length; i++) { + assertDuration(value[ i ], data[ i ]); + } + } + + private void assertExceptionThrownByConstructor(String value) { + try { + DvDuration.getInstance(value); + fail("Exception should be thrown by constructor"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + } + + private void assertDuration(String value, int[] data) { + DvDuration d = DvDuration.getInstance(value); + assertEquals(value + ", years", data[ 0 ], d.getYears()); + assertEquals(value + ", months", data[ 1 ], d.getMonths()); + assertEquals(value + ", weeks", data[ 2 ], d.getWeeks()); + assertEquals(value + ", days", data[ 3 ], d.getDays()); + assertEquals(value + ", hours", data[ 4 ], d.getHours()); + assertEquals(value + ", minutes", data[ 5 ], d.getMinutes()); + assertEquals(value + ", seconds", data[ 6 ], d.getSeconds()); + assertEquals(value + ", fseconds", data[ 7 ], (int)(d.getFractionalSeconds()*1000.0)); + } + + 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, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 10, 9, 0, 0, 0}, + }; + for(int i = 0; i < data.length; i++) { + DvDuration d = toDuration(data[i]); + assertEquals("years", data[i][ 0 ], d.getYears()); + assertEquals("months", data[i][ 1 ], d.getMonths()); + assertEquals("weeks", data[i][ 2 ], d.getWeeks()); + assertEquals("days", data[i][ 3 ], d.getDays()); + assertEquals("hours", data[i][ 4 ], d.getHours()); + assertEquals("minutes", data[i][ 5 ], d.getMinutes()); + assertEquals("seconds", data[i][ 6 ], d.getSeconds()); + 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}, + }; + for(int i = 0; i < fData.length; i++) { + try { + DvDuration d = toDuration(fData[i]); + fail("Exception should be thrown by constructor"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + } + + } + 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 + assertEquals("days", 4, d.getDays()); //18d = 2W4d + assertEquals("hours", 22, d.getHours()); + assertEquals("mintues", 33, d.getMinutes()); + 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()); + assertEquals("months", 1, d.getMonths()); //33d = 1M2d + assertEquals("weeks", 0, d.getWeeks()); + assertEquals("days", 2, d.getDays()); + assertEquals("hours", 0, d.getHours()); + assertEquals("mintues", 43, d.getMinutes()); + assertEquals("seconds", 46, d.getSeconds()); + assertEquals("fractionalSeconds", .15, + d.getFractionalSeconds()); + + } + + public void testSubtract() throws Exception { + DvDuration one = new DvDuration(0, 0, 0, 10, 20, 30, 40, .5); + DvDuration two = new DvDuration(0, 0, 1, 0, 2, 3, 4, .05); + DvDuration d = (DvDuration) one.subtract(two); + //System.out.println("after subtraction: " + d.toString()); + assertEquals("years", 0, d.getYears()); + assertEquals("months", 0, d.getMonths()); + assertEquals("weeks", 0, d.getWeeks()); + assertEquals("days", 3, d.getDays()); + assertEquals("hours", 18, d.getHours()); + assertEquals("mintues", 27, d.getMinutes()); + assertEquals("seconds", 36, d.getSeconds()); + assertEquals("fractionalSeconds", .45, + d.getFractionalSeconds()); + DvDuration three = new DvDuration("P5D"); + d = (DvDuration) d.subtract(three); + //System.out.println("after second subtraction: " + d.toString()); + assertEquals("years", 0, d.getYears()); + assertEquals("months", 0, d.getMonths()); + assertEquals("weeks", 0, d.getWeeks()); + assertEquals("days", -1, d.getDays()); + assertEquals("hours", -5, d.getHours()); + assertEquals("mintues", -32, d.getMinutes()); + assertEquals("seconds", -23, d.getSeconds()); + assertEquals("fractionalSeconds", -0.55, + d.getFractionalSeconds()); + assertEquals("value", "-P1DT5H32M23,550S", d.toString()); + } + + public void testToString() throws Exception { + //constructor takes string, integers, after addition/subtraction + //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, 0, 0, 0, 0, 0, 0, 0}, {0, 11, 23, 10, 9, 5, 0, 123} + }; + String[] strings = { + "P10DT20H30M40S", "P1DT14M2S", "P13M56W33DT25H67M77S", + "-P1M2WT9H", "PT0S", "P11M23W10DT9H5M0,123S" + }; + for(int i = 0; i < data.length; i++) { + DvDuration d = toDuration(data[i]); + assertEquals(strings[i], d.toString()); + } + + String[] strValues = { + "P10DT20H30M40.66S", "P16M45DT60M2S", "P13M56W33DT2H6M5.0S", + "-P1M2WT9H", "PT0S", "P11M23W10DT9H5M0,123S", "P" + }; + for(int i = 0; i < strValues.length; i++) { + DvDuration d = new DvDuration(strValues[i]); + assertEquals(strValues[i], d.toString()); + } + } + + public void testCompareTo() throws Exception { + int[] value = {1, 13, 45, 10, 20, 30, 40, 500};//D=(2*365)+31+(45*7)+10 + DvDuration d1 = toDuration(value); + DvDuration d2 = toDuration(value); + assertTrue(d1.compareTo(d2) == 0); + assertTrue(d2.compareTo(d1) == 0); + + int[][] array = { + {1, 13, 45, 10, 20, 30, 40, 499}, //the next 3 sets are all equivalent to the first + {2, 0, 0, 356, 20, 30, 40, 499}, {2, 11, 0, 21, 20, 0, 220, 499}, + {2, 11, 3, 0, 20, 30, 40, 499}, + {-2, -13, -45, -10, -20, -20, 0, -5}, {0, 0, 0, 10, 10, 50, 40, 5}, + }; + for (int i = 0; i < array.length; i++) { + DvDuration d = toDuration(array[ i ]); + assertTrue(d1.compareTo(d) > 0); + assertTrue(d.compareTo(d1) < 0); + } + + } + + public void testEquals() throws Exception { + + assertEquals(new DvDuration("P1Y2M3W"), new DvDuration(1, 2, 3, 0, 0, 0, 0, 0.0)); + assertEquals(new DvDuration("-P1Y2M3DT25H6S"), new DvDuration(-1, -2, 0, -3, -25, 0, -6, 0.0)); + assertEquals(new DvDuration("PT6H220m89.719S"), new DvDuration(0, 0, 0, 0, 6, 220, 89, .719)); + assertEquals(new DvDuration("P"), new DvDuration(0, 0, 0, 0, 0, 0, 0, 0.0)); + + } + + // int[] of { days, hours, mintues, seconds, fractionalSeconds } + private DvDuration toDuration(int[] values) throws Exception { + return new DvDuration(values[ 0 ], values[ 1 ], values[ 2 ], + values[ 3 ], values[ 4 ], values[ 5 ], values[ 6 ], + values[ 7 ]/10E2); + } + + +} +/* + * ***** 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 DvDurationTest.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/datatypes/quantity/datetime/DvTimeTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvTimeTest.java new file mode 100644 index 00000000..17d56f68 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvTimeTest.java @@ -0,0 +1,304 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvTimeTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/datatypes/quantity/datetime/DvTimeTest.java $" + * revision: "$LastChangedRevision: 52 $" + * last_change: "$LastChangedDate: 2006-08-10 17:53:34 +0200 (Thu, 10 Aug 2006) $" + */ + +/** + * DvTimeTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.datatypes.quantity.datetime; + +import junit.framework.TestCase; +import java.util.TimeZone; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; + +public class DvTimeTest extends TestCase { + + public DvTimeTest(String test) { + super(test); + } + + /** + * The fixture set up called before every test method. + */ + protected void setUp() throws Exception { + zoneStr = DvDateTimeParser.convertTimeZone( + DateTimeZone.getDefault().getOffset(new DateTime()), false); + } + + /** + * The fixture clean up called after every test method. + */ + protected void tearDown() throws Exception { + } + + public void testCompareTo() throws Exception { + + assertTrue(dvTime("00:00:00").compareTo(dvTime("01:00:00")) < 0); + assertTrue(dvTime("00:00:00").compareTo(dvTime("00:01:00")) < 0); + assertTrue(dvTime("00:00:00").compareTo(dvTime("00:00:01")) < 0); + assertTrue(dvTime("00:00:00.000").compareTo(dvTime("00:00:00.001")) < 0); + + assertTrue(dvTime("010000").compareTo(dvTime("000000")) > 0); + assertTrue(dvTime("000100").compareTo(dvTime("000000")) > 0); + assertTrue(dvTime("000001").compareTo(dvTime("000000")) > 0); + assertTrue(dvTime("000000,001").compareTo(dvTime("000000,000")) > 0); + + assertTrue(dvTime("00:00:01").compareTo(dvTime("00:00:01")) == 0); + + assertTrue(dvTime("00:00:00Z").compareTo(dvTime("00:00:00+01:00")) > 0); + assertTrue(dvTime("00:00:00Z").compareTo(dvTime("00:00:00-00:30")) < 0); + assertTrue(dvTime("00:00:00Z").compareTo(dvTime("01:00:00+01:00")) == 0); + assertTrue(dvTime("00:30:00Z").compareTo(dvTime("00:00:00-00:30")) == 0); + assertTrue(dvTime("01:30:00.001Z").compareTo(dvTime("00:30:00.001-01:00")) == 0); + + assertTrue(new DvTime(19, 55, 45, 0.899, TimeZone.getTimeZone("GMT-02")).compareTo(dvTime("195545-02")) > 0); + assertTrue(new DvTime(19, 55, 45, TimeZone.getTimeZone("GMT-02")).compareTo(dvTime("195545-02")) == 0); + assertTrue(new DvTime(19, 55, 45, TimeZone.getTimeZone("GMT-02")).compareTo(dvTime("195545-03")) < 0); + assertTrue(new DvTime(19, 55, TimeZone.getTimeZone("GMT-02")).compareTo(dvTime("195545-02")) < 0); + assertTrue(new DvTime(19, TimeZone.getTimeZone("GMT-02")).compareTo(dvTime("195545-02")) < 0); + + } + + public void testConstructorTakeString() throws Exception { + String[] values = { + "20:10:55", "00:00:59Z", "12:12:30-01:00", "21:23:34.234", + "01:02:03.009+02:30", "21:23:34,234", "08:10:33,001Z", "01:02:03,009+02:30", + "201055", "000059Z", "121230-0100", "212334.234", + "010203.009+0230", "212334,234", "081033,001Z", "010203,009+0230", + "12:35:45.666", "12:35:45-0700"}; + + for (String value : values) { + assertEquals(new DvTime(value), dvTime(value)); + assertNotNull(new DvTime(value)); + } + + } + + public void testConstructorTakesIntegers() throws Exception { + + assertNotNull(new DvTime(20, 10, 55, 0.133, null)); + assertNotNull(new DvTime(20, 10, 55, null)); + assertNotNull(new DvTime(0, 0, 59, TimeZone.getTimeZone("UTC"))); + assertNotNull(new DvTime(9, 4, 59, TimeZone.getTimeZone("GMT+10"))); + assertNotNull(new DvTime(5, 22, TimeZone.getTimeZone("GMT-3"))); + assertNotNull(new DvTime(0, null)); + assertNotNull(new DvTime(23, 59, 50, TimeZone.getTimeZone("GMT-11"))); + } + + public void testToString() throws Exception { + String[] values = { + "19:55:45-02", "01:15:25.245", "000000Z", "235959", "10:19:33,029-09:00" + }; + for (String value : values) { + assertEquals(dvTime(value).toString(), value); + } + assertEquals(dvTime("19:55:45-02:00").toString(), + new DvTime(19, 55, 45, TimeZone.getTimeZone("GMT-02")).toString()); + assertEquals(dvTime("01:15:25,000+01:00").toString(), + new DvTime(1, 15, 25, 0.0, TimeZone.getTimeZone("GMT+1")).toString()); + assertEquals(dvTime("00:00Z").toString(), + new DvTime(0, 0, TimeZone.getTimeZone("UTC")).toString()); + assertEquals(dvTime("01").toString(), new DvTime(1, null).toString()); + assertEquals(dvTime("01:02:03").toString(), new DvTime(1, 2, 3, null).toString()); + + } + + public void testToStringTakesBoolean() throws Exception { + String[] values = { + "19:55:45-02", "01:15:25.245", "00:00:00Z", "23:59:59", "10:19:33,029-09:00", + "12:22-04", "18Z" + }; + for (String value : values) { + assertEquals(dvTime(value).toString(false), value.replace(":", "")); + } + assertEquals(dvTime("195545-02").toString(true), "19:55:45-02"); + assertEquals(dvTime("101933,029-0900").toString(true), "10:19:33,029-09:00"); + assertEquals(dvTime("1223-0230").toString(true), "12:23-02:30"); + assertEquals(dvTime("02Z").toString(true), "02Z"); + + DvTime dTime = new DvTime(19, 55, 45, TimeZone.getTimeZone("GMT-02")); + assertEquals(dTime.toString(), dTime.toString(true)); + assertEquals("195545-0200", dTime.toString(false)); + dTime = new DvTime(1, 15, 25, 0.0, TimeZone.getTimeZone("GMT+1")); + assertEquals(dTime.toString(), dTime.toString(true)); + assertEquals("011525,000+0100", dTime.toString(false)); + } + + public void testEquals() throws Exception { + + assertEquals(new DvTime(0, 0, 59, 0.345, TimeZone.getTimeZone("UTC")), new DvTime("00:00:59.345Z")); + assertEquals(new DvTime(0, 0, 59, TimeZone.getTimeZone("GMT-1030")), new DvTime("000059-1030")); + assertEquals(new DvTime(2, 38, TimeZone.getTimeZone("GMT+0700")), new DvTime("02:38+07:00")); + assertEquals(new DvTime(23, TimeZone.getTimeZone("GMT-0230")), new DvTime("23-0230")); + + } + + private DvTime dvTime(String value) throws Exception { + return new DvTime(value); + } + + public void testIsValidTime() throws Exception { + assertFalse(DvTime.isValidISO8601Time("24:00:00"));//Joda specific, do anything? + assertFalse(DvTime.isValidISO8601Time("240000")); + assertFalse(DvTime.isValidISO8601Time("006000")); + assertFalse(DvTime.isValidISO8601Time("00:00:60")); + assertFalse(DvTime.isValidISO8601Time("256678")); + assertFalse(DvTime.isValidISO8601Time("005500U")); + assertFalse(DvTime.isValidISO8601Time("-000001")); + assertFalse(DvTime.isValidISO8601Time("003001+02:30")); + assertFalse(DvTime.isValidISO8601Time("00:03:09.999+25:30")); + + assertTrue(DvTime.isValidISO8601Time("23:59:59")); + assertTrue(DvTime.isValidISO8601Time("00:00:00+23:00")); + assertTrue(DvTime.isValidISO8601Time("164530+0000")); + assertTrue(DvTime.isValidISO8601Time("14:25:20-00:00")); + assertTrue(DvTime.isValidISO8601Time("22:46:08-01")); + assertTrue(DvTime.isValidISO8601Time("204724-11")); + assertTrue(DvTime.isValidISO8601Time("12:30:10-0230")); + } + + public void testIsEquivalent() throws Exception { + assertTrue(new DvTime("00:00:59Z").isEquivalent(new DvTime("010059+01"))); + assertTrue(new DvTime("013059Z").isEquivalent(new DvTime("00:30:59-01"))); + assertTrue(new DvTime("00:00:59Z").isEquivalent(new DvTime("01:00:59+01"))); + //assertTrue(new DvTime("00:00:59Z").isEquivalent(new DvTime("01:00:59+01"))); + assertFalse(new DvTime("003059Z").isEquivalent(new DvTime("23:30:59-01"))); + } + + public void testGetHourMinuteSecFSec() throws Exception { + + DvTime dTime = new DvTime(19, 55, 45, 0.829, TimeZone.getTimeZone("GMT-02")); + assertEquals(19, dTime.getHour()); + assertEquals(55, dTime.getMinute()); + assertEquals(45, dTime.getSecond()); + assertEquals(0.829, dTime.getFractionalSecond(), 0.000001); + dTime = dvTime("17:49:08,679-02"); + assertEquals(17, dTime.getHour()); + assertEquals(49, dTime.getMinute()); + assertEquals(8, dTime.getSecond()); + assertEquals(0.679, dTime.getFractionalSecond()); + dTime = dvTime("142908-02"); + assertEquals(14, dTime.getHour()); + assertEquals(29, dTime.getMinute()); + assertEquals(8, dTime.getSecond()); + assertEquals(-0.1, dTime.getFractionalSecond()); + dTime = dvTime("1225-0200"); + assertEquals(12, dTime.getHour()); + assertEquals(25, dTime.getMinute()); + assertEquals(-1, dTime.getSecond()); + assertEquals(-0.1, dTime.getFractionalSecond()); + dTime = dvTime("22-0100"); + assertEquals(22, dTime.getHour()); + assertEquals(-1, dTime.getMinute()); + assertEquals(-1, dTime.getSecond()); + assertEquals(-0.1, dTime.getFractionalSecond()); + dTime = new DvTime(8, 0, 16, null); + assertEquals(8, dTime.getHour()); + assertEquals(0, dTime.getMinute()); + assertEquals(16, dTime.getSecond()); + assertEquals(-0.1, dTime.getFractionalSecond()); + dTime = new DvTime(13, 39, TimeZone.getTimeZone("GMT-09")); + assertEquals(13, dTime.getHour()); + assertEquals(39, dTime.getMinute()); + assertEquals(-1, dTime.getSecond()); + assertEquals(-0.1, dTime.getFractionalSecond()); + dTime = new DvTime(1, TimeZone.getTimeZone("UTC")); + assertEquals(1, dTime.getHour()); + assertEquals(-1, dTime.getMinute()); + assertEquals(-1, dTime.getSecond()); + assertEquals(-0.1, dTime.getFractionalSecond()); + } + + public void testMinuteSecondFSecKnown() throws Exception { + DvTime dTime = new DvTime(19, 55, 45, 0.829, TimeZone.getTimeZone("GMT-02")); + assertEquals(false, dTime.isPartial()); + assertEquals(true, dTime.minuteKnown()); + assertEquals(true, dTime.secondKnown()); + assertEquals(true, dTime.hasFractionalSecond()); + dTime = dvTime("17:49:08,679-02"); + assertEquals(false, dTime.isPartial()); + assertEquals(true, dTime.minuteKnown()); + assertEquals(true, dTime.secondKnown()); + assertEquals(true, dTime.hasFractionalSecond()); + dTime = dvTime("142908-02"); + assertEquals(false, dTime.isPartial()); + assertEquals(true, dTime.minuteKnown()); + assertEquals(true, dTime.secondKnown()); + assertEquals(false, dTime.hasFractionalSecond()); + dTime = dvTime("1225-0200"); + assertEquals(true, dTime.isPartial()); + assertEquals(true, dTime.minuteKnown()); + assertEquals(false, dTime.secondKnown()); + assertEquals(false, dTime.hasFractionalSecond()); + dTime = dvTime("22-0100"); + assertEquals(true, dTime.isPartial()); + assertEquals(false, dTime.minuteKnown()); + assertEquals(false, dTime.secondKnown()); + assertEquals(false, dTime.hasFractionalSecond()); + dTime = new DvTime(8, 0, 16, null); + assertEquals(false, dTime.isPartial()); + assertEquals(true, dTime.minuteKnown()); + assertEquals(true, dTime.secondKnown()); + assertEquals(false, dTime.hasFractionalSecond()); + dTime = new DvTime(13, 39, TimeZone.getTimeZone("GMT-09")); + assertEquals(true, dTime.isPartial()); + assertEquals(true, dTime.minuteKnown()); + assertEquals(false, dTime.secondKnown()); + assertEquals(false, dTime.hasFractionalSecond()); + dTime = new DvTime(1, TimeZone.getTimeZone("UTC")); + assertEquals(true, dTime.isPartial()); + assertEquals(false, dTime.minuteKnown()); + assertEquals(false, dTime.secondKnown()); + assertEquals(false, dTime.hasFractionalSecond()); + } + + public void testAdd() throws Exception { + //TODO: testAdd + } + + private String zoneStr; +} +/* + * ***** 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 DvTimeTest.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/datatypes/text/DvCodedTextTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/text/DvCodedTextTest.java new file mode 100644 index 00000000..a03962b1 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/text/DvCodedTextTest.java @@ -0,0 +1,45 @@ +/** + * DvCodedTextTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.datatypes.text; + +import junit.framework.TestCase; + +public class DvCodedTextTest extends TestCase { + + public DvCodedTextTest(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 { + } + + /** + * Tests creating a dvCodedText with minimum set of parameters + * + * @throws Exception + */ + public void testCreateDvCodedTextWithMinimumParam() throws Exception { + CodePhrase definingCode = new CodePhrase("test terms", "12345"); + new DvCodedText("coded text", definingCode); + } + + public void testEquals() throws Exception { + DvCodedText t1 = new DvCodedText("some text", "icd10", "123"); + DvCodedText t2 = new DvCodedText("some text", "icd10", "123"); + assertEquals(t1, t2); + } + +} \ 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 new file mode 100644 index 00000000..8c57b2eb --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/text/DvTextTest.java @@ -0,0 +1,110 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DvTextTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/datatypes/text/DvTextTest.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +/** + * TextTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.datatypes.text; + +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.rm.support.terminology.TestTerminologyService; + +import junit.framework.TestCase; + +public class DvTextTest extends TestCase { + + public DvTextTest(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 testValidValue() throws Exception { + assertTrue("good value", DvText.validValue("good value")); + assertFalse("null value", DvText.validValue(null)); + assertFalse("value with \\r\\n ", DvText.validValue("bad value\r\n")); + assertFalse("value with \\n", DvText.validValue("bad value\n")); + assertFalse("value with \\r", DvText.validValue("bad value\r")); + assertFalse("empty value", DvText.validValue("")); + } + + public void testConstructor() throws Exception { + DvText text; + + // verify that both language and charset are optional now + text = new DvText("value", null, null, null, null, null, null); + + // try the new minimal constructor + text = new DvText("value"); + } + + public void testCreateWithNullEncoding() throws Exception { + TerminologyService ts = TestTerminologyService.getInstance(); + CodePhrase lang = new CodePhrase("ISO_639-1", "en"); + CodePhrase charset = null; + DvText dt = new DvText("test", lang, charset, ts); + assertNotNull("failed to create dvText", dt); + } + + public void testCreateWithNullLanguage() throws Exception { + TerminologyService ts = TestTerminologyService.getInstance(); + CodePhrase lang = null; + CodePhrase charset = new CodePhrase("IANA_character-sets", "UTF-8"); + DvText dt = new DvText("test", lang, charset, ts); + assertNotNull("failed to create dvText", dt); + } + +} +/* + * ***** 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 DvTextTest.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-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 new file mode 100644 index 00000000..9c4e5792 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/text/TestCodePhrase.java @@ -0,0 +1,65 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TestCodePhrase" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/datatypes/text/TestCodePhrase.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.datatypes.text; + +import org.openehr.rm.support.identification.TestTerminologyID; + +/** + * TestCodePhrase + * + * @author Rong Chen + * @version 1.0 + */ +public class TestCodePhrase { + + /* fields */ + public static final CodePhrase ENGLISH; + public static final CodePhrase LATIN_1; + + static { + ENGLISH = new CodePhrase(TestTerminologyID.LANGUAGE, "english"); + LATIN_1 = new CodePhrase(TestTerminologyID.CHARSET, "ISO-8859-1"); + } +} + +/* + * ***** 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 TestCodePhrase.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/support/basic/IntervalTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/basic/IntervalTest.java new file mode 100644 index 00000000..b5527481 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/support/basic/IntervalTest.java @@ -0,0 +1,160 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class IntervalTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/support/basic/IntervalTest.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +/** + * IntervalTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.support.basic; + +import junit.framework.TestCase; + +public class IntervalTest extends TestCase { + + public IntervalTest(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 testConstructor() throws Exception { + try { + new Interval(new Integer(10), new Integer(1)); + fail("should throw illegal argument exception"); + } catch (Exception ignored) { + } + } + + public void testHas() throws Exception { + // array of { lower(0:unbounded), upper(0:unbounded), + // lowerInclusive, upperInclusive (1:true, 0:false) + // testValue, expected (1:true, 0:false) } + int[][] data = { + // inclusive boundaries + {1, 8, 1, 1, 2, 1}, + {1, 8, 1, 1, 1, 1}, + {1, 8, 1, 1, 8, 1}, + {1, 8, 1, 1, 0, 0}, + {1, 8, 1, 1, 9, 0}, + {0, 8, 0, 1, 4, 1}, + {0, 8, 0, 1, -1, 1}, + {0, 8, 0, 1, 9, 0}, + {1, 0, 1, 0, 4, 1}, + {1, 0, 1, 0, 1, 1}, + {1, 0, 1, 0, -1, 0}, + // exclusive boundaries + {1, 8, 0, 0, 2, 1}, + {1, 8, 0, 0, 1, 0}, + {1, 8, 0, 0, 8, 0}, + {1, 8, 0, 0, 0, 0}, + {1, 8, 0, 0, 9, 0}, + {0, 8, 0, 0, 4, 1}, + {0, 8, 0, 0, -1, 1}, + {0, 8, 0, 0, 9, 0}, + {1, 0, 0, 0, 4, 1}, + {1, 0, 0, 0, 1, 0}, + {1, 0, 0, 0, -1, 0} + }; + for (int i = 0; i < data.length; i++) { + Interval iv = new Interval(popInt(data[ i ][ 0 ]), + popInt(data[ i ][ 1 ]), data[i][2] == 1, data[i][3] == 1); + boolean actual = iv.has(new Integer(data[ i ][ 4 ])); + boolean expected = data[ i ][ 5 ] == 1; + assertTrue("failed at " + testString(data[ i ]), + actual == expected); + } + } + + // return null if value 0 + private Integer popInt(int value) { + if (value == 0) { + return null; + } + return new Integer(value); + } + + private String testString(int[] row) { + return "(" + row[ 0 ] + ", " + row[ 1 ] + ") has " + + row[ 4 ] + ": " + ( row[ 5 ] == 1 ); + } + + public void testEquals() throws Exception { + Interval interval = new Interval(new Integer(-1), new Integer(10)); + Interval interval2 = new Interval(new Integer(-1), new Integer(10)); + assertEquals(interval, interval2); + + interval = new Interval(new Integer(-1), new Integer(10), true, false); + interval2 = new Interval(new Integer(-1), new Integer(10), true, false); + assertEquals(interval, interval2); + + interval = new Interval(new Integer(-1), new Integer(10), true, false); + interval2 = new Interval(new Integer(-1), new Integer(10), true, true); + assertFalse(interval.equals(interval2)); + + // not equals expected + int[][] data = { + {-1, 9}, {2, 10}, {0, 10}, {-1, 0}, {0, 0} + }; + + for(int i = 0; i < data.length; i++) { + interval2 = new Interval(popInt(data[i][0]), + popInt(data[i][1])); + assertFalse(interval2.toString(), interval.equals(interval2)); + assertFalse(interval2.toString(), interval2.equals(interval)); + } + } + + +} +/* + * ***** 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 IntervalTest.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/support/identification/ArchetypeIDTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/ArchetypeIDTest.java new file mode 100644 index 00000000..396fc969 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/ArchetypeIDTest.java @@ -0,0 +1,254 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ArchetypeIDTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/support/identification/ArchetypeIDTest.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +/** + * ArchetypeIDTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.support.identification; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +public class ArchetypeIDTest extends TestCase { + + public ArchetypeIDTest(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 testConstructorTakesStringValue() throws Exception { + for (int i = 0; i < STRING_VALUE.length; i++) { + assertArchetypeID(new ArchetypeID(STRING_VALUE[ i ]), i); + } + } + + public void testConstructorTakesSections() throws Exception { + for (int i = 0; i < SECTIONS.length; i++) { + + ArchetypeID aid = new ArchetypeID(SECTIONS[ i ][ 0 ], + SECTIONS[ i ][ 1 ], + SECTIONS[ i ][ 2 ], + SECTIONS[ i ][ 3 ], + SECTIONS[ i ][ 4 ], + SECTIONS[ i ][ 5 ]); + + assertArchetypeID(aid, i); + } + } + + public void testConstructorWithInvalidValue() { + String[] data = { + // rm entity part + "openehr-ehr_rm.physical_examination.v2", // too less sections + "openehr-ehr_rm-section-entry.physical_examination-prenatal.v1", // to many sections + "openehr.ehr_rm-entry.progress_note-naturopathy.v2", // too many axes + + // domain concept part + "openehr-ehr_rm-section.physical+examination.v2", // illegal char + + // version part + "hl7-rim-act.progress_note.", // missing version + "openehr-ehr_rm-entry.progress_note-naturopathy" // missing version + }; + + for (int i = 0; i < data.length; i++) { + try { + new ArchetypeID(data[ i ]); + fail("should fail on " + data[ i ]); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + } + } + + public void testEqualsIgnoreVersionID() throws Exception { + String base1 = "openehr-ehr_rm-section.physical_examination."; + String base2 = "openehr-ehr_rm-section.simple_medication."; + + // same base + assertEqualsIgnoreVersion(base1, "v1", base1, "v1", true); + assertEqualsIgnoreVersion(base1, "v1", base1, "v2", true); + assertEqualsIgnoreVersion(base1, "v2", base1, "v1", true); + + // different base + assertEqualsIgnoreVersion(base1, "v1", base2, "v1", false); + assertEqualsIgnoreVersion(base1, "v1", base2, "v2", false); + assertEqualsIgnoreVersion(base1, "v2", base2, "v1", false); + } + + private void assertEqualsIgnoreVersion(String baseOne, + String versionOne, + String baseTwo, + String versionTwo, + boolean expected) { + assertEquals(expected, + new ArchetypeID(baseOne + versionOne).equalsIgnoreVersionID( + new ArchetypeID(baseTwo + versionTwo))); + + } + + public void testBase() { + String base = "openehr-ehr_rm-section.physical_examination"; + assertEquals(base, new ArchetypeID(base + ".v1").base()); + } + + public void testMultipleSpecialisation() { + ArchetypeID aid = null; + try { + aid = new ArchetypeID("openEHR-EHR-CLUSTER.exam-generic-joint.v1"); + + List list = new ArrayList(); + list.add("generic"); + list.add("joint"); + + assertEquals("wrong specialisation", list, aid.specialisation()); + + } catch(Exception e) { + e.printStackTrace(); + fail("failed to create ArchetypeID with multiple specialisation"); + } + } + + public void testWithConceptInSwedish() { + ArchetypeID aid = null; + try { + // Omvrdnadsanteckning + aid = new ArchetypeID( + "openEHR-EHR-CLUSTER.Omv\u00E5rdnadsanteckning.v1"); + + fail("expect to fail on Swedish concept name"); + + } catch(Exception e) { + + } + } + + public void testArchetypeBase() { + ArchetypeID aid = null; + try { + aid = new ArchetypeID("openEHR-EHR-CLUSTER.exam.v1"); + assertEquals("wrong base", "openEHR-EHR-CLUSTER.exam", aid.base()); + + aid = new ArchetypeID("openEHR-EHR-CLUSTER.exam-generic.v1"); + assertEquals("wrong base", "openEHR-EHR-CLUSTER.exam-generic", aid.base()); + + aid = new ArchetypeID("openEHR-EHR-CLUSTER.exam-generic-joint.v1"); + assertEquals("wrong base", "openEHR-EHR-CLUSTER.exam-generic-joint", aid.base()); + + + } catch(Exception e) { + e.printStackTrace(); + fail("failed to create ArchetypeID for testing base"); + } + } + + + // assert content of archetype id + private void assertArchetypeID(ArchetypeID aid, int i) { + assertEquals("value", STRING_VALUE[ i ], aid.getValue()); + assertEquals("contextID", null, aid.contextID()); + assertEquals("localID", STRING_VALUE[ i ], aid.localID()); + + assertEquals("rmOriginator", SECTIONS[ i ][ 0 ], + aid.rmOriginator()); + assertEquals("rmName", SECTIONS[ i ][ 1 ], aid.rmName()); + assertEquals("rmEntity", SECTIONS[ i ][ 2 ], + aid.rmEntity()); + assertEquals("conceptName", SECTIONS[ i ][ 3 ], + aid.conceptName()); + + List list = new ArrayList(); + if(SECTIONS[ i ][ 4 ] != null) { + list.add(SECTIONS[ i ][ 4 ]); + } + assertEquals("specialisation", list, aid.specialisation()); + + assertEquals("qualifiedRmEntity", AXES[ i ][ 0 ], + aid.qualifiedRmEntity()); + assertEquals("domainConcept", AXES[ i ][ 1 ], + aid.domainConcept()); + assertEquals("versionID", AXES[ i ][ 2 ], + aid.versionID()); + } + + private static String[] STRING_VALUE = { + "openehr-ehr_rm-section.physical_examination.v2", + "openehr-ehr_rm-section.physical_examination-prenatal.v1", + "hl7-rim-act.progress_note.v1", + "openehr-ehr_rm-ENTRY.progress_note-naturopathy.draft" + }; + + private static String[][] SECTIONS = { + {"openehr", "ehr_rm", "section", "physical_examination", + null, "v2"}, + {"openehr", "ehr_rm", "section", "physical_examination", + "prenatal", "v1"}, + {"hl7", "rim", "act", "progress_note", null, "v1"}, + {"openehr", "ehr_rm", "ENTRY", "progress_note", "naturopathy", "draft"} + }; + + private static String[][] AXES = { + {"openehr-ehr_rm-section", "physical_examination", "v2"}, + {"openehr-ehr_rm-section", "physical_examination-prenatal", + "v1"}, + {"hl7-rim-act", "progress_note", "v1"}, + {"openehr-ehr_rm-ENTRY", "progress_note-naturopathy", "draft"} + }; + +} +/* + * ***** 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 ArchetypeIDTest.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/support/identification/HierObjectIDTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/HierObjectIDTest.java new file mode 100644 index 00000000..756dd545 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/HierObjectIDTest.java @@ -0,0 +1,115 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class HierarchicalObjectIDTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/support/identification/HierarchicalObjectIDTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +/** + * HierarhicalObjectIDTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.support.identification; + +import junit.framework.TestCase; + +public class HierObjectIDTest extends TestCase { + + public HierObjectIDTest(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 testConstructorTakesStringValue() throws Exception { + + for (int i = 0; i < STRING_VALUES.length; i++) { + assertHOID(new HierObjectID(STRING_VALUES[i]), i); + } + } + + public void testConstructorTakesSections() throws Exception { + + for (int i = 0; i < STRING_VALUES.length; i++) { + assertHOID(new HierObjectID(SECTIONS[i][0], + SECTIONS[i][1]), i); + } + } + + private void assertHOID(HierObjectID hoid, int i) throws Exception { + //System.out.println("matches? " + SECTIONS[i][0].matches("(\\d)+(\\.(\\d)+)*")); + assertEquals("value", STRING_VALUES[i], hoid.getValue()); + //System.out.println("root uid? " + hoid.root()); + //String str = hoid.root().getValue(); + + assertEquals("root", SECTIONS[i][0], hoid.root().getValue()); + assertEquals("extension", SECTIONS[i][1], hoid.extension()); + } + + private static final String[][] SECTIONS = { + {"1.2.840.113554.1.2.2", "345"}, + {"1-2-840-113554-1", "789"}, + {"w123.com", "123"}, + {"1.2.840.113554.1.2.2", null}, + {"1-2-840-113554-1", null}, + {"w123.com", null} + }; + + private static final String[] STRING_VALUES = { + "1.2.840.113554.1.2.2::345", + "1-2-840-113554-1::789", + "w123.com::123", + "1.2.840.113554.1.2.2", + "1-2-840-113554-1", + "w123.com", + }; + +} +/* + * ***** 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 HierarchicalObjectIDTest.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/support/identification/ISO_OIDTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/ISO_OIDTest.java new file mode 100644 index 00000000..4abdc957 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/ISO_OIDTest.java @@ -0,0 +1,83 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ISO_OIDTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/support/identification/ISO_OIDTest.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +/** + * ISO_OIDTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.support.identification; + +import junit.framework.TestCase; + +public class ISO_OIDTest extends TestCase { + + public ISO_OIDTest(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 testEquals() throws Exception { + String value = "1.2.840.113554.1.2.2"; + ISO_OID oid1 = new ISO_OID(value); + ISO_OID oid2 = new ISO_OID(value); + + assertTrue(oid1.equals(oid2)); + assertTrue(oid2.equals(oid1)); + + assertTrue(oid1.equals(oid1)); + assertTrue(oid2.equals(oid2)); + } +} +/* + * ***** 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 ISO_OIDTest.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/support/identification/InternetIDTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/InternetIDTest.java new file mode 100644 index 00000000..e967bc8e --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/InternetIDTest.java @@ -0,0 +1,101 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class InternetIDTest" + * 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/support/identification/InternetIDTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" + */ + +/** + * InternetIDTest + * + * @author Yin Su Lim + * @version 1.0 + */ +package org.openehr.rm.support.identification; + +import junit.framework.*; + +public class InternetIDTest extends TestCase { + + public InternetIDTest(String testName) { + super(testName); + } + + protected void setUp() throws Exception { + } + + protected void tearDown() throws Exception { + } + + public static Test suite() { + TestSuite suite = new TestSuite(InternetIDTest.class); + + return suite; + } + + public void testConstructorTakeString() throws Exception { + assertNotNull(new InternetID("www.google.com")); + assertNotNull(new InternetID("m-2.d2")); + assertNotNull(new InternetID("a123.com.nz")); + assertNotNull(new InternetID("openehr.org")); + assertNotNull(new InternetID("openehr1-1.org")); + assertNotNull(new InternetID("openehr1-1.com-2")); + assertNull(toInternetID("128.17.13.1")); + assertNull(toInternetID("123.com")); + assertNull(toInternetID("open_ehr.org")); + assertNull(toInternetID("openehr1-.org")); + assertNull(toInternetID("openehr1-1.0")); + assertNull(toInternetID("openehr1-1.com.")); + + } + + private InternetID toInternetID(String value) { + InternetID id = null; + try { + id = new InternetID(value); + fail("should have failed this test"); + } catch (IllegalArgumentException iae) { + + } + return id; + } + +} + +/* + * ***** 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 InternetIDTest.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/support/identification/ObjectRefTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/ObjectRefTest.java new file mode 100644 index 00000000..06ec1ed4 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/ObjectRefTest.java @@ -0,0 +1,115 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ObjectReferenceTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/support/identification/ObjectReferenceTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ + +/** + * ObjectReferenceTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.support.identification; + +import junit.framework.TestCase; + +public class ObjectRefTest extends TestCase { + + public ObjectRefTest(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 testConstructor() throws Exception { + assertExceptionThrown(null, "LOCAL", "EHR", "id"); + + assertExceptionThrown(hid("1.2.40.11.1.2.2::2"), null, "EHR", + "namespace"); + + assertExceptionThrown(hid("1.2.40.11.1.2.2::2"), "LOCAL", null, "type"); + + new ObjectRef(hid("openehr.org::23"), "LOCAL", "EHR"); + } + + private ObjectID hid(String value) { + return new HierObjectID(value); + } + + public void testEquals() throws Exception { + ObjectRef or1 = new ObjectRef(hid("1-2-80-11-1"), "LOCAL", "EHR"); + ObjectRef or2 = new ObjectRef(hid("1-2-80-11-1"), "LOCAL", "EHR"); + assertTrue(or1.equals(or2)); + assertTrue(or2.equals(or1)); + + ObjectRef or3 = new ObjectRef(hid("openehr.org::23"), "LOCAL", "EHR"); + assertFalse(or1.equals(or3)); + assertFalse(or3.equals(or1)); + + or3 = new ObjectRef(hid("1-2-80-11-1"), "DEMOGRAPHIC", "EHR"); + assertFalse(or1.equals(or3)); + assertFalse(or3.equals(or1)); + + or3 = new ObjectRef(hid("1-2-80-11-1"), "LOCAL", "PARTY"); + assertFalse(or1.equals(or3)); + assertFalse(or3.equals(or1)); + } + + private void assertExceptionThrown(ObjectID id, String namespace, + String type, String cause) { + try { + new ObjectRef(id, namespace, type); + fail("exception should be thrown"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + assertTrue(e.getMessage().contains(cause)); + } + + } +} + +/* + * ***** 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 ObjectReferenceTest.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/support/identification/ObjectVersionIDTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/ObjectVersionIDTest.java new file mode 100644 index 00000000..862e55f6 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/ObjectVersionIDTest.java @@ -0,0 +1,81 @@ +/* + * ObjectVersionIDTest.java + * JUnit based test + * + * Created on July 11, 2006, 3:05 PM + */ + +package org.openehr.rm.support.identification; + +import junit.framework.*; +import org.apache.commons.lang.StringUtils; + +/** + * + * @author yinsulim + */ +public class ObjectVersionIDTest extends TestCase { + + public ObjectVersionIDTest(String testName) { + super(testName); + } + + protected void setUp() throws Exception { + } + + protected void tearDown() throws Exception { + } + + public static Test suite() { + TestSuite suite = new TestSuite(ObjectVersionIDTest.class); + + return suite; + } + + public void testContructorTakeString() { + String[][] ids = { + {"1.4.4.5", "1.2.840.114.1.2.2::123", "1"}, + {"1.2.4.5", "7234-235-422-4-23::2", "2.0.0"}, + {"1.6.1.6", "openehr.org::0.99", "2.1.2"} + }; + for(int i = 0; i < ids.length; i++) { + ObjectVersionID ov = new ObjectVersionID(ids[i][0], ids[i][1], ids[i][2]); + assertEquals((UID)new ISO_OID(ids[i][0]), ov.objectID()); + assertEquals(new HierObjectID(ids[i][1]), ov.creatingSystemID()); + assertEquals(new VersionTreeID(ids[i][2]), ov.versionTreeID()); + } + String[][] ids2 = { + {"1-4-4-5-12", "1.2.840.114.1.2.2", "1"}, + {"12-14-1-1-9", "7234-235-422-4-23::23", "2.0.0"}, + {"1123-1-4-5457-7", "openehr.org", "2.1.2"} + }; + for(int i = 0; i < ids2.length; i++) { + ObjectVersionID ov = new ObjectVersionID(ids2[i][0], ids2[i][1], ids2[i][2]); + assertEquals((UID)new UUID(ids2[i][0]), ov.objectID()); + assertEquals(new HierObjectID(ids2[i][1]), ov.creatingSystemID()); + assertEquals(new VersionTreeID(ids2[i][2]), ov.versionTreeID()); + } + String[][] ids3 = { + {"openehr", "1.2.840.114.1.2.2", "1"}, + {"openehrR1-0.org", "7234-235-422-4-23::23", "2.0.0"}, + //{"openehr.org.uk", "w123.55.155::ext1", "2.1.2"} + }; + for(int i = 0; i < ids3.length; i++) { + ObjectVersionID ov = new ObjectVersionID(ids3[i][0], ids3[i][1], ids3[i][2]); + assertEquals((UID)new InternetID(ids3[i][0]), ov.objectID()); + assertEquals(new HierObjectID(ids3[i][1]), ov.creatingSystemID()); + assertEquals(new VersionTreeID(ids3[i][2]), ov.versionTreeID()); + } + } + + public void testCreateWithValidUIDInHexFormat() { + String value = "939cec48-d629-4a3f-89f1-28c573387680::" + + "10aec661-5458-4ff6-8e63-c2265537196d::1"; + try { + new ObjectVersionID(value); + } catch(Exception e) { + fail("exception raised by constructor: " + e.getMessage()); + } + } + +} 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 new file mode 100644 index 00000000..ab030cc4 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/TerminologyIDTest.java @@ -0,0 +1,106 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TerminologyIDTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/support/identification/TerminologyIDTest.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +/** + * TerminologyIDTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.support.identification; + +import junit.framework.TestCase; + +public class TerminologyIDTest extends TestCase { + + public TerminologyIDTest(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 testConstrcutorTakesStringValue() throws Exception { + for(int i = 0; i < STRING_VALUE.length; i++) { + assertTID(new TerminologyID(STRING_VALUE[i]), i); + } + } + + public void testConstrcutorTakesNameVersion() throws Exception { + for(int i = 0; i < STRING_VALUE.length; i++) { + assertTID(new TerminologyID(SECTIONS[i][0], SECTIONS[i][1]), i); + } + } + + public void testEquals() { + TerminologyID id1 = new TerminologyID("ICD9", "1999"); + TerminologyID id2 = new TerminologyID("ICD9", "1999"); + assertTrue("equals expected", id1.equals(id2)); + assertTrue("equals expected", id2.equals(id1)); + } + + private void assertTID(TerminologyID tid, int i) { + assertEquals("value", STRING_VALUE[i], tid.getValue()); + assertEquals("name", SECTIONS[i][0], tid.name()); + assertEquals("version", SECTIONS[i][1], tid.versionID()); + } + + private static final String[] STRING_VALUE = { + "snomed-ct", "ICD9(1999)" + }; + + private static final String[][] SECTIONS = { + {"snomed-ct", null}, + {"ICD9", "1999"} + }; + +} +/* + * ***** 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 TerminologyIDTest.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/support/identification/TestTerminologyID.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/TestTerminologyID.java new file mode 100644 index 00000000..5bc83f30 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/TestTerminologyID.java @@ -0,0 +1,68 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TestTerminologyID" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/support/identification/TestTerminologyID.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.support.identification; + +/** + * TestTerminologyID + * + * @author Rong Chen + * @version 1.0 + */ +public class TestTerminologyID { + + /* fields */ + public static final TerminologyID LANGUAGE; + public static final TerminologyID CHARSET; + public static final TerminologyID SNOMEDCT; + + + static { + LANGUAGE = new TerminologyID("language-test"); + + CHARSET = new TerminologyID("charset-test"); + + SNOMEDCT = new TerminologyID("snomedct-test"); + } +} + +/* + * ***** 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 TestTerminologyID.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/support/identification/UUIDTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/UUIDTest.java new file mode 100644 index 00000000..5a05ca1f --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/UUIDTest.java @@ -0,0 +1,37 @@ +/* + * UUIDTest.java + * JUnit based test + * + * Created on July 10, 2006, 4:27 PM + */ + +package org.openehr.rm.support.identification; + +import junit.framework.*; + +/** + * + * @author yinsulim + */ +public class UUIDTest extends TestCase { + + public UUIDTest(String testName) { + super(testName); + } + + protected void setUp() throws Exception { + } + + protected void tearDown() throws Exception { + } + + public static Test suite() { + TestSuite suite = new TestSuite(UUIDTest.class); + + return suite; + } + + public void testConstructorTakeString() { + assertNotNull(new UUID("128-1-1-12-15")); + } +} 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 new file mode 100644 index 00000000..f86981ac --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/support/identification/VersionTreeIDTest.java @@ -0,0 +1,185 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class VersionTreeID" + * 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/suppport/identification/VersionTreeID.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" + */ + +/** + * VersionTreeID + * + * @author Yin Su Lim + * @version 1.0 + */ +package org.openehr.rm.support.identification; + +import junit.framework.*; +import org.apache.commons.lang.StringUtils; +import org.openehr.rm.RMObject; + +public class VersionTreeIDTest extends TestCase { + + public VersionTreeIDTest(String testName) { + super(testName); + } + + protected void setUp() throws Exception { + } + + protected void tearDown() throws Exception { + } + + public static Test suite() { + TestSuite suite = new TestSuite(VersionTreeIDTest.class); + + return suite; + } + + + public void testConstructors() throws Exception { + String[] values = { + "1.1.2", "2", "1.3.24", "10", "3.0.0" + }; + int[][] intS = { + {1, 1, 2}, + {2, 0, 0}, + {1, 3, 24}, + {10, 0, 0}, + {3, 0, 0} + }; + boolean[] isB = { + true, false, true, false, false + }; + + for(int i = 0 ; i < values.length; i++) { + VersionTreeID v1 = toVersionTreeID(values[i]); + VersionTreeID v2 = toVersionTreeID(intS[i][0], intS[i][1], intS[i][2]); + assertEquals(v1, v2); + String bN = intS[i][1] == 0 ? null: Integer.toString(intS[i][1]); + String bV = intS[i][2] == 0 ? null: Integer.toString(intS[i][2]); + assertEquals("trunk", Integer.toString(intS[i][0]), v2.trunkVersion()); + assertEquals("branchNo", bN, v2.branchNumber()); + assertEquals("branchVersion", bV, v2.branchVersion()); + assertEquals("isBranch", isB[i], v2.isBranch()); + } + + } + + public void testConstructorsFail() throws Exception { + String[] values = { + "1.0.2", "0", "0.3.24", "1.1.0", "0.0.0", "1.1" + }; + int[][] intS = { + {0, 1, 2}, + {0, 0, 0}, + {1, 3, 0}, + {10, 0, 1}, + {-1, 3, 2}, + {1, -2, 2} + }; + for(int i = 0; i < values.length; i++) { + assertNull(toVersionTreeID(values[i])); + } + for(int i = 0; i < intS.length; i++) { + assertNull(toVersionTreeID(intS[i][0], intS[i][1], intS[i][2])); + } + } + + private VersionTreeID toVersionTreeID(String value) { + VersionTreeID v = null; + try { + v = new VersionTreeID(value); + } catch (IllegalArgumentException iae) { + } + return v; + } + + private VersionTreeID toVersionTreeID(int t, int bN, int bV) { + VersionTreeID v = null; + try { + v = new VersionTreeID(t, bN, bV); + } catch (IllegalArgumentException iae) { + } + return v; + } + + public void testIsFirst() { + + String[] values = {"1", "1.0.0", "1.1.1", "2"}; + boolean[] iF = {true, true, false, false}; + for(int i = 0; i < values.length; i++) { + assertEquals(iF[i], new VersionTreeID(values[i]).isFirst()); + } + + } + + public void testNext() { + String[] values = {"1", "1.0.0", "1.1.1", "2"}; + String[] nextV = {"2", "2", "1.1.2", "3"}; + for(int i = 0; i < values.length; i++) { + assertEquals(new VersionTreeID(nextV[i]), new VersionTreeID(values[i]).next()); + } + } + + public void testToString() { + int[][] intS = { + {1, 1, 2}, + {1, 0, 0}, + {1, 3, 1}, + }; + String[] values = { + "1.1.2", "1", "1.3.1" + }; + for(int i = 0; i < values.length; i++) { + assertEquals(values[i], toVersionTreeID(intS[i][0], intS[i][1], intS[i][2]).toString()); + } + String[] tValues = { + "1.1.2", "1", "1.0.0", "2.0.0" + }; + String[] eValues = { + "1.1.2", "1", "1", "2" + }; + for(int i = 0; i < values.length; i++) { + assertEquals(eValues[i], toVersionTreeID(tValues[i]).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 VersionTreeID.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/support/measurement/TestMeasurementService.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/measurement/TestMeasurementService.java new file mode 100644 index 00000000..2bc61f3a --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/support/measurement/TestMeasurementService.java @@ -0,0 +1,100 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TestMeasurementService" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/support/measurement/TestMeasurementService.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.support.measurement; + +/** + * Implementation of MeasurementService used for testing + * + * @author Rong Chen + * @version 1.0 + */ +public 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 if units null + */ + public boolean isValidUnitsString(String units) { + return true; + } + + /** + * Return True if two units strings correspond to the same + * measured property. + * + * @param units1 + * @param units2 + * @return true if two units equal + * @throws IllegalArgumentException if units1 or units2 null + */ + public boolean unitsEquivalent(String units1, String units2) { + return true; + } + + /** + * Return a new instance of test measurement service + * + * @return + */ + public static MeasurementService getInstance() { + return new TestMeasurementService(); + } + + @Override + public boolean unitsComparable(String units1, String units2) { + return true; + } + + @Override + public int compare(String units1, Double value1, String units2, + Double value2) { + return 0; + } +} + +/* + * ***** 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 TestMeasurementService.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/support/terminology/OpenEHRCodeSetIdentifiersTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/OpenEHRCodeSetIdentifiersTest.java new file mode 100644 index 00000000..6704e709 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/OpenEHRCodeSetIdentifiersTest.java @@ -0,0 +1,18 @@ +package org.openehr.rm.support.terminology; + +import junit.framework.TestCase; + +public class OpenEHRCodeSetIdentifiersTest extends TestCase { + + public void testValidateCodeSetIdWithValidId() throws Exception { + String id = OpenEHRCodeSetIdentifiers.CHARACTER_SETS.toString(); + assertTrue("id 'character sets' should be valid", + OpenEHRCodeSetIdentifiers.validCodeSetId(id)); + } + + public void testValidateCodeSetIdWithInvalidId() throws Exception { + String id = "some unknown id"; + assertFalse(id + " shouldn't be valid", + OpenEHRCodeSetIdentifiers.validCodeSetId(id)); + } +} 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 new file mode 100644 index 00000000..b7eebb51 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/OpenEHRTerminologyGroupIdentifiersTest.java @@ -0,0 +1,19 @@ +package org.openehr.rm.support.terminology; + +import junit.framework.TestCase; + +public class OpenEHRTerminologyGroupIdentifiersTest extends TestCase { + + public void testValidateTerminologyGroupIdWithValidId() { + String id = + OpenEHRTerminologyGroupIdentifiers.ATTESTATION_REASON.toString(); + assertTrue(id + " should be valid", + OpenEHRTerminologyGroupIdentifiers.validTerminologyGroupId(id)); + } + + public void testValidateTerminologyGroupIdWithInvalidId() { + String id = "unknow terminology group id"; + assertFalse(id + " should not be valid", + OpenEHRTerminologyGroupIdentifiers.validTerminologyGroupId(id)); + } +} 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 new file mode 100644 index 00000000..cdddd25e --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/TestCodeSetAccess.java @@ -0,0 +1,130 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TestCodeSetAccess" + * keywords: "unit test" + * + * 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/BRANCHES/Release-1.0/libraries/src/test/org/openehr/rm/support/terminology/TestCodeSetAccess.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.support.terminology; + +import java.util.HashSet; +import org.openehr.rm.datatypes.basic.DvState; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvCodedText; + +import java.util.Set; + +/** + * TestCodeSetAccess + * + * @author Rong Chen + * @version 1.0 + */ +public class TestCodeSetAccess implements CodeSetAccess { + + /* fields */ + /** + * Returns identification of this Terminology + * + * @return ID not null or empty + */ + public String id() { + return null; // todo: implement this method + } + + /** + * Returns all codes known in this terminology + * + * @return Set of DvCodePhrase + */ + public Set allCodes() { + return allCodes; // todo: implement this method + } + + public boolean hasCode(CodePhrase code) { + return true;//allCodes.contains(code); + } + + public boolean hasLang(CodePhrase lang) { + return true;//allCodes.contains(lang); + } + + public static final CodePhrase ENGLISH = new CodePhrase("test", "en"); + public static final CodePhrase LATIN_1 = new CodePhrase("test", + "iso-8859-1"); + public static final CodePhrase NULL_FLAVOUR = new CodePhrase("test", + "unanswered"); + + static final Set allCodes; + + static { + allCodes = new HashSet(); + allCodes.add(ENGLISH); + allCodes.add(LATIN_1); + allCodes.add(NULL_FLAVOUR); + } + + // change type + public static final DvCodedText AMENDMENT = new DvCodedText("creation", + ENGLISH, LATIN_1, new CodePhrase("test", "creation"), + TestTerminologyService.getInstance()); + + public static final DvCodedText SETTING = new DvCodedText("setting", + ENGLISH, LATIN_1, new CodePhrase("test", "setting_code"), + TestTerminologyService.getInstance()); + + public static final DvCodedText ISM_ACTIVE = new DvCodedText("ism states", + ENGLISH, LATIN_1, new CodePhrase("test", "active"), + TestTerminologyService.getInstance()); + + // composition category + public static final DvCodedText EVENT = new DvCodedText("event", + ENGLISH, LATIN_1, new CodePhrase("test", "event"), + TestTerminologyService.getInstance()); + + public static final DvCodedText PERSISTENT = new DvCodedText("persistent", + ENGLISH, LATIN_1, new CodePhrase("test", "persistent"), + TestTerminologyService.getInstance()); + + // lifecycle state + public static final DvState DRAFT = new DvState(new DvCodedText("draft", + new CodePhrase("test", "draft"), ENGLISH, LATIN_1, + TestTerminologyService.getInstance()), false); +} + +/* + * ***** 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 TestCodeSetAccess.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/support/terminology/TestTerminologyAccess.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/TestTerminologyAccess.java new file mode 100644 index 00000000..938a9f46 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/TestTerminologyAccess.java @@ -0,0 +1,184 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TestTerminologyAccess" + * keywords: "unit test" + * + * 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/BRANCHES/Release-1.0/libraries/src/test/org/openehr/rm/support/terminology/TestTerminologyAccess.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.support.terminology; + +import java.util.HashSet; +import org.openehr.rm.datatypes.text.CodePhrase; + +import java.util.Set; +import org.openehr.rm.support.identification.TestTerminologyID; + +/** + * TestTerminologyAccess + * + * @author Rong Chen + * @version 1.0 + */ +public class TestTerminologyAccess implements TerminologyAccess { + + /* fields */ + /** + * Returns all codes under grouper groupID of this terminology + * + * @param groupID + * @return Set of CodePhrase for given group ID, empty set + * returned if not found + * @throws IllegalArgumentException if groupID null or empty + */ + public Set codesForGroupId(String groupID) { + return null; // todo: implement this method + } + + /** + * Return all codes under grouper whose name of given + * name and language from this terminology. + * + * @param name + * @param language + * @return Set of CodePhrase for given group name, + * empty set returned if not found + * @throws IllegalArgumentException if name,language null or empty + */ + public Set codesForGroupName(String name, String language) { + + return CODES; // todo: implement this method + } + + /** + * Returns all rubric of given code and language + * + * @param code + * @param language + * @return rubric of given code and language or null if not found + * @throws IllegalArgumentException if code,language null or empty + */ + public String rubricForCode(String code, String language) { + return null; // todo: implement this method + } + + /** + * Return true if the code is under grouper of given name + * and language + * + * @param code + * @param name + * @param language + * @return true if the code exists + * @throws IllegalArgumentException if code or name or language + * null + */ + public boolean hasCodeForGroupName(CodePhrase code, String name, + String language) { + return true; + } + + /** + * Returns identification of this TerminologyAccess + * + * @return ID not null or empty + */ + public String id() { + return null; // todo: implement this method + } + + /** + * Returns all codes known in this terminology + * + * @return a Set of CodePhrase + */ + public Set allCodes() { + return null; // todo: implement this method + } + + /** + * Return true if this codeset contains given codePhrase + * + * @param code + * @return true if has + */ + public boolean has(CodePhrase code) { + return true; + } + + public boolean hasCodeForGroupId(String groupId, CodePhrase code) { + return true; + } + + public static final CodePhrase RELATIONS = new CodePhrase("test", "family_code"); + public static final CodePhrase SETTING = new CodePhrase("test", "setting_code"); + public static final CodePhrase FUNCTION = new CodePhrase(TestTerminologyID.SNOMEDCT, "meanCode"); + public static final CodePhrase REVISION = new CodePhrase(TestTerminologyID.SNOMEDCT, "revisionCode"); + public static final CodePhrase CHANGE = new CodePhrase(TestTerminologyID.SNOMEDCT, + "changeTypeCode"); + public static final CodePhrase ACTIVE = new CodePhrase("test", "active"); + public static final CodePhrase CREATION = new CodePhrase("openehr", "249"); + public static final CodePhrase PERSISTENT = new CodePhrase("test", "persistent"); + public static final CodePhrase EVENT = new CodePhrase("test", "event"); + public static final CodePhrase ENGLISH = new CodePhrase("test", "en"); + public static final CodePhrase LATIN_1 = new CodePhrase("test", + "iso-8859-1"); + public static final CodePhrase NULL_FLAVOUR = new CodePhrase("test", + "unanswered"); + public static final CodePhrase SOME_STATE = null; + public static final CodePhrase SOME_TRANSITION = null; + + + static Set CODES; + static { + CODES = new HashSet(); + CODES.add(FUNCTION); + CODES.add(REVISION); + CODES.add(EVENT); + CODES.add(PERSISTENT); + CODES.add(SETTING); + CODES.add(CHANGE); + CODES.add(RELATIONS); + CODES.add(CREATION); + CODES.add(ENGLISH); + CODES.add(ACTIVE); + CODES.add(NULL_FLAVOUR); + } + +} + +/* + * ***** 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 TestTerminologyAccess.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/support/terminology/TestTerminologyService.java b/openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/TestTerminologyService.java new file mode 100644 index 00000000..cef3b895 --- /dev/null +++ b/openehr-rm-core/src/test/java/org/openehr/rm/support/terminology/TestTerminologyService.java @@ -0,0 +1,136 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TestTerminologyService" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/support/terminology/TestTerminologyService.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +package org.openehr.rm.support.terminology; + +import java.util.List; +import java.util.Map; + +/** + * TestTerminologyService + * + * @author Rong Chen + * @version 1.0 + */ +public class TestTerminologyService implements TerminologyService { + + /** + * Create a new instance of test terminology service + * + * @return + */ + public static TestTerminologyService getInstance() { + return new TestTerminologyService(); + } + + + /** + * Returns a TerminologyAccess of given name + * + * @param name not empty and known to this service + * @return terminology + * @throws IllegalArgumentException if name null, empty + * or unknown to this terminology service + */ + public TerminologyAccess terminology(String name) { + return new TestTerminologyAccess(); + } + + /** + * Returns a CodeSetAccess of given name + * + * @param name not empty and known to this service + * @return codeSet + * @throws IllegalArgumentException if name is null, empty + * or unknown to this terminology service + */ + public CodeSetAccess codeSet(String name) { + return new TestCodeSetAccess(); + } + + /** + * Returns ture if terminology of given name known by this service + * + * @param name not empty + * @return true if has given terminology + * @throws IllegalArgumentException if name is null or empty + */ + public boolean hasTerminology(String name) { + return false; // todo: implement this method + } + + /** + * Returns true if code set of given name known by this service + * + * @param name not empty + * @return true if has given codeset + * @throws IllegalArgumentException if name is null or empty + */ + public boolean hasCodeSet(String name) { + return false; // todo: implement this method + } + + + public CodeSetAccess codeSetForId(OpenEHRCodeSetIdentifiers name) { + return new TestCodeSetAccess(); + } + + + public List terminologyIdentifiers() { + // TODO Auto-generated method stub + return null; + } + + + public List codeSetIdentifiers() { + // TODO Auto-generated method stub + return null; + } + + + public Map openehrCodeSets() { + // 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 TestTerminologyService.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/pom.xml b/openehr-rm-domain/pom.xml new file mode 100644 index 00000000..e0cb2e57 --- /dev/null +++ b/openehr-rm-domain/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5-SNAPSHOT + + openehr-rm-domain + jar + openEHR Reference Model Domain + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2004 + + Java implementation of the openEHR Reference Model Domain + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + mini-termserv + ${project.version} + test + + + commons-lang + commons-lang + 2.6 + + + junit + junit + 3.8.1 + 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 new file mode 100644 index 00000000..2854eda6 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/Composition.java @@ -0,0 +1,314 @@ +/* + * 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 ***** + */ \ 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 new file mode 100644 index 00000000..2172eb15 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/EventContext.java @@ -0,0 +1,297 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class EventContext" + * 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/EventContext.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.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; +import org.openehr.rm.RMObject; +import org.openehr.rm.common.generic.Participation; +import org.openehr.rm.common.generic.PartyIdentified; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.support.terminology.TerminologyService; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Documents the clinical context of the clinical session (or + * encounter). The context information recorded here are independent + * of the attributes recorded in the version audit, which document + * the system interaction context, ie the context of a user + * interacting with the health record system. Clinical sessions + * include patient contacts, and any other business activity, such + * as pathology investigations which take place on behalf of the + * patient. + *

+ * Instances of this class are immutable + * + * @author Rong Chen + * @version 1.0 + */ +public final class EventContext extends RMObject { + + /** + * Constructs an EventContext + * + * @param healthCareFacility null if not specified + * @param startTime required + * @param endTime null if not specified + * @param participations null if not specified + * @param location null if not specified + * @param setting required + * @param otherContext null if not specified + * @param terminologyService + * @throws IllegalArgumentException + */ + @FullConstructor + public EventContext( + @Attribute(name = "healthCareFacility") PartyIdentified healthCareFacility, + @Attribute(name = "startTime", required = true) DvDateTime startTime, + @Attribute(name = "endTime") DvDateTime endTime, + @Attribute(name = "participations") List participations, + @Attribute(name = "location") String location, + @Attribute(name = "setting", required = true) DvCodedText setting, + @Attribute(name = "otherContext") ItemStructure otherContext, + @Attribute(name = "terminologyService", system = true) TerminologyService terminologyService) { + + if (startTime == null) { + throw new IllegalArgumentException("null startTime"); + } + if (participations != null && participations.isEmpty()) { + throw new IllegalArgumentException("empty participations"); + } + if (location != null && StringUtils.isEmpty(location)) { + throw new IllegalArgumentException("empty location"); + } + if (terminologyService == null) { + throw new IllegalArgumentException("null terminologyService"); + } + if(setting == null) { + throw new IllegalArgumentException("null setting"); + } + if (!terminologyService.terminology(TerminologyService.OPENEHR) + .codesForGroupName("setting", "en") + .contains(setting.getDefiningCode())) { + throw new IllegalArgumentException("unknown setting: " + setting); + } + this.healthCareFacility = healthCareFacility; + this.startTime = startTime; + this.endTime = endTime; + this.participations = ( participations == null ? + null : new ArrayList(participations) ); + this.location = location; + this.setting = setting; + this.otherContext = otherContext; + } + + /** + * Create an eventText with required values + */ + public EventContext(DvDateTime startTime, DvCodedText setting, + TerminologyService termServ) { + this(null, startTime, null, null, null, setting, null, termServ); + } + + /** + * The health care facility under whose care the event took + * place. This is the most specific workgroup or delivery unit + * within a care delivery enterprise which has an official + * identifier in the health system, and can be used to ensure + * medicolegal accountability. + * + * @return healthcare facility + */ + public PartyIdentified getHealthCareFacility() { + return healthCareFacility; + } + + /** + * Start time of the clinical session + * + * @return startTime + */ + public DvDateTime getStartTime() { + return startTime; + } + + /** + * Optional end time of the clinical session + * + * @return endTime + */ + public DvDateTime getEndTime() { + return endTime; + } + + /** + * Parties involved in the clinical session. These would normally + * include the physician( s) and often the patient (but not the + * latter if the clinical session is a pathology test for + * example). + * + * @return unmodifiable list of participations + */ + public List getParticipations() { + return participations == null ? null : + Collections.unmodifiableList(participations); + } + + /** + * The actual location where the session occurred, + * eg "microbiol lab 2", "home", "ward A3" and so on. + * + * @return location + */ + public String getLocation() { + return location; + } + + /** + * The setting in which the clinical session took place. + * Coded using the openEHR Terminology, "setting" group. + * + * @return setting + */ + public DvCodedText getSetting() { + return setting; + } + + /** + * Other optional context which will be archetyped. + * + * @return other context + */ + public ItemStructure getOtherContext() { + return otherContext; + } + + /** + * Equals if values are the same + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof EventContext )) return false; + + final EventContext eventContext = (EventContext) o; + + return new EqualsBuilder() + .append(healthCareFacility, eventContext.healthCareFacility) + .append(startTime, eventContext.startTime) + .append(participations, eventContext.participations) + .append(location, eventContext.location) + .append(setting, eventContext.setting) + .append(otherContext, otherContext) + .isEquals(); + } + + + /** + * Return a hash code of this event context + * + * @return hashcode + */ + public int hashCode() { + return new HashCodeBuilder() + .append(healthCareFacility) + .append(startTime) + .append(endTime) + .append(participations) + .append(location) + .append(setting) + .append(otherContext) + .toHashCode(); + } + + // POJO start + EventContext() { + } + + void setHealthCareFacility(PartyIdentified healthCareFacility) { + this.healthCareFacility = healthCareFacility; + } + + void setStartTime(DvDateTime startTime) { + this.startTime = startTime; + } + + void setEndTime(DvDateTime endTime) { + this.endTime = endTime; + } + + void setParticipations(List participations) { + this.participations = participations; + } + + void setLocation(String location) { + this.location = location; + } + + void setSetting(DvCodedText setting) { + this.setting = setting; + } + + void setOtherContext(ItemStructure otherContext) { + this.otherContext = otherContext; + } + // POJO end + + /* fields */ + private PartyIdentified healthCareFacility; + private DvDateTime startTime; + private DvDateTime endTime; + private List participations; + private String location; + private DvCodedText setting; + private ItemStructure otherContext; +} + +/* + * ***** 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 EventContext.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/content/ContentItem.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/ContentItem.java new file mode 100644 index 00000000..5c0cb27f --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/ContentItem.java @@ -0,0 +1,85 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ContentItem" + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/composition/content/ContentItem.java $" + * revision: "$LastChangedRevision: 29 $" + * last_change: "$LastChangedDate: 2006-04-29 00:34:13 +0200 (Sat, 29 Apr 2006) $" + */ +package org.openehr.rm.composition.content; + +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.support.identification.UIDBasedID; +import org.openehr.rm.datatypes.text.DvText; + +import java.util.Set; + +/** + * ContentItem + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class ContentItem extends Locatable { + + /** + * Constructs a ContentItem + * + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + */ + protected ContentItem(UIDBasedID uid, String archetypeNodeId, DvText name, + Archetyped archetypeDetails, FeederAudit feederAudit, + Set links, Pathable parent) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, parent); + } + + // POJO start + protected ContentItem() { + } + // POJO end +} + +/* + * ***** 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 ContentItem.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/content/entry/Action.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Action.java new file mode 100644 index 00000000..dd881646 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Action.java @@ -0,0 +1,228 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Action" + * 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/Action.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.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.common.generic.Participation; +import org.openehr.rm.common.generic.PartyProxy; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvText; +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; + +/** + * Used to record a clinical action that has been performed, which may have been ad hoc, + * or due to the execution of an Acitivity in an Instruction workflow. Every Action + * corresponds to a careflow step of some kind or another. + * + * @author Yin Su Lim + * @version 1.0 + */ +public final class Action extends CareEntry { + + /** + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @param parent + * @param language + * @param encoding + * @param subject + * @param provider + * @param workflowId + * @param otherParticipations + * @param protocol + * @param guidelineId + * @param terminologyService + */ + @FullConstructor + public Action(@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 = "language", required = true) CodePhrase language, + @Attribute(name = "encoding", required = true) CodePhrase encoding, + @Attribute(name = "subject", required = true) PartyProxy subject, + @Attribute(name = "provider") PartyProxy provider, + @Attribute(name = "workflowId") ObjectRef workflowId, + @Attribute(name = "otherParticipations") List otherParticipations, + @Attribute(name = "protocol") ItemStructure protocol, + @Attribute(name = "guidelineId") ObjectRef guidelineId, + @Attribute(name = "time", required = true) DvDateTime time, + @Attribute(name = "description", required = true) ItemStructure description, + @Attribute(name = "ismTransition", required = true) ISMTransition ismTransition, + @Attribute(name = "instructionDetails") InstructionDetails instructionDetails, + @Attribute(name = "terminologyService", system = true) TerminologyService terminologyService + ){ + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, parent, + language, encoding, subject, provider, workflowId, otherParticipations, + protocol, guidelineId, terminologyService); + if (time == null) { + throw new IllegalArgumentException("null time"); + } + if (description == null) { + throw new IllegalArgumentException("null description"); + } + if (ismTransition == null) { + throw new IllegalArgumentException("null ismTransition"); + } + this.time = time; + this.description = description; + this.ismTransition = ismTransition; + this.instructionDetails = instructionDetails; + } + + /** + * Description of the activity to be performed, in the form of an + * archetyped structure. + * + * @return description + */ + public ItemStructure getDescription() { + return description; + } + + /** + * Details of the Instruction that caused this ACtion to be performed, + * if there was one. + * + * @return instructionDetails + */ + public InstructionDetails getInstructionDetails() { + return instructionDetails; + } + + /** + * Detials of transition in the Instruction state machine caused by + * this Action. + * + * @return ismTransition + */ + public ISMTransition getIsmTransition() { + return ismTransition; + } + + /** + * Point in time at which this action completed. + * + * @return time + */ + public DvDateTime getTime() { + return time; + } + + @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 + Action() { + } + + void setDescription(ItemStructure description) { + this.description = description; + } + + void setInstructionDetails(InstructionDetails instructionDetails) { + this.instructionDetails = instructionDetails; + } + + void setIsmTransition(ISMTransition ismTransition) { + this.ismTransition = ismTransition; + } + + void setTime(DvDateTime time) { + this.time = time; + } + //POJO end + + /* fields */ + private DvDateTime time; + private ItemStructure description; + private ISMTransition ismTransition; + private InstructionDetails instructionDetails; + + /* 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 Action.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/Activity.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Activity.java new file mode 100644 index 00000000..68225226 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Activity.java @@ -0,0 +1,191 @@ +/* + * 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 ***** + */ \ 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 new file mode 100644 index 00000000..a2d8c7ed --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/AdminEntry.java @@ -0,0 +1,161 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class AdminEntry" + * 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/AdminEntry.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.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.common.generic.Participation; +import org.openehr.rm.common.generic.PartyProxy; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * Entry subtype for administrative information, i.e. information about setting up + * the clinical process, but not itself clinically relevant. Archetypes will define + * contained information + * + * @author Yin Su Lim + * @version 1.0 + */ +public class AdminEntry extends Entry { + + /** + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @param parent + * @param language + * @param encoding + * @param subject + * @param provider + * @param workflowId + * @param otherParticipations + * @param terminologyService + */ + @FullConstructor + public AdminEntry(@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 = "language", required = true) CodePhrase language, + @Attribute(name = "encoding", required = true) CodePhrase encoding, + @Attribute(name = "subject", required = true) PartyProxy subject, + @Attribute(name = "provider") PartyProxy provider, + @Attribute(name = "workflowId") ObjectRef workflowId, + @Attribute(name = "otherParticipations") List otherParticipations, + @Attribute(name = "data", required = true) ItemStructure data, + @Attribute(name = "terminologyService", system = true) TerminologyService terminologyService) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, parent, + language, encoding, subject, provider, workflowId, otherParticipations, + terminologyService); + if (data == null) { + throw new IllegalArgumentException("null data"); + } + this.data = data; + } + + /** + * Gets data of this adminEntry + * + * @return data + */ + public ItemStructure getData() { + return data; + } + + @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 + AdminEntry() { + } + + void setData(ItemStructure data) { + this.data = data; + } + //POJO end + + /* field */ + private ItemStructure data; + +} + +/* + * ***** 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 AdminEntry.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/CareEntry.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/CareEntry.java new file mode 100644 index 00000000..85ebedba --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/CareEntry.java @@ -0,0 +1,139 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CareEntry" + * 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/CareEntry.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.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.common.generic.Participation; +import org.openehr.rm.common.generic.PartyProxy; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * The abstract parent of all clinical Entry subtypes. A CareEntry defines + * protocol and guideline attributes for all clinical Entry subtypes. + * + * @author Yin Su Lim + * @version 1.0 + */ +public abstract class CareEntry extends Entry { + + /** + * Construct an Entry + * + * @param archetypeNodeId + * @param name + * @param subject + * @param provider + * @param protocol null if unspecified + * @param actID null if unspecified + * @param guidelineId null if unspecified + * @param otherParticipations null if unspecified + * @throws IllegalArgumentException if archetypeNodeId or name null, + * or subject or provider null or invalid + */ + protected CareEntry(UIDBasedID uid, String archetypeNodeId, DvText name, + Archetyped archetypeDetails, FeederAudit feederAudit, + Set links, Pathable parent, CodePhrase language, + CodePhrase encoding, PartyProxy subject, + PartyProxy provider, ObjectRef workflowId, + List otherParticipations, + ItemStructure protocol, ObjectRef guidelineId, + TerminologyService terminologyService) { + + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, parent, + language, encoding, subject, provider, workflowId, otherParticipations, + terminologyService); + this.protocol = protocol; + this.guidelineId = guidelineId; + } + + /** + * Optional external identifier of guideline creating this action + * if relevant + * + * @return guidelineId + */ + public ObjectRef getGuidelineId() { + return guidelineId; + } + + /** + * Description of the method the information in this entry was arrived at. + * + * @return protocol + */ + public ItemStructure getProtocol() { + return protocol; + } + + //POJO start + CareEntry() { + } + + void setGuidelineId(ObjectRef guidelineId) { + this.guidelineId = guidelineId; + } + void setProtocol(ItemStructure protocol) { + this.protocol = protocol; + } + //POJO end + + /* fields */ + private ItemStructure protocol; + private ObjectRef guidelineId; + + /* static fields */ + public static final String PROTOCOL = "protocol"; +} + +/* + * ***** 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 CareEntry.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/Entry.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Entry.java new file mode 100644 index 00000000..8975a211 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Entry.java @@ -0,0 +1,255 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Entry" + * 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/content/entry/Entry.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.composition.content.entry; + +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.common.generic.Participation; +import org.openehr.rm.common.generic.PartyProxy; +import org.openehr.rm.common.generic.PartySelf; +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.support.terminology.OpenEHRCodeSetIdentifiers; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.rm.composition.content.ContentItem; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvText; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +/** + * The abstract parent of all Entry subtypes. An Entry is the root of + * a logical item of hard clinical information created in the + * "clinical statement" context, within a clinical session. + *

+ * Instances of this class are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class Entry extends ContentItem { + + /** + * Construct an Entry + * + * @param archetypeNodeId + * @param name + * @param subject + * @param provider + * @param protocol null if unspecified + * @param actID null if unspecified + * @param guidelineId null if unspecified + * @param otherParticipations null if unspecified + * @throws IllegalArgumentException if archetypeNodeId or name null, + * or subject or provider null or invalid + */ + protected Entry(UIDBasedID uid, String archetypeNodeId, DvText name, + Archetyped archetypeDetails, FeederAudit feederAudit, + Set links, Pathable parent, CodePhrase language, + CodePhrase encoding, PartyProxy subject, + PartyProxy provider, ObjectRef workflowId, + List otherParticipations, + TerminologyService terminologyService) { + + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, parent); + + if (language == null) { + throw new IllegalArgumentException("null language"); + } + if (encoding == null) { + throw new IllegalArgumentException("null encoding"); + } + if (subject == null) { + throw new IllegalArgumentException("null subject"); + } + if (!isArchetypeRoot()) { + throw new IllegalArgumentException("not archetype root"); + } + if (otherParticipations != null && otherParticipations.isEmpty()) { + throw new IllegalArgumentException("empty otherParticipations"); + } + if (terminologyService == null) { + throw new IllegalArgumentException("null terminologyService"); + } + + if(terminologyService.codeSetForId( + OpenEHRCodeSetIdentifiers.LANGUAGES) == null) { + throw new IllegalArgumentException( + "missing codeset " + OpenEHRCodeSetIdentifiers.LANGUAGES); + } + + if(terminologyService.codeSetForId( + OpenEHRCodeSetIdentifiers.CHARACTER_SETS) == null) { + throw new IllegalArgumentException( + "missing codeset " + OpenEHRCodeSetIdentifiers.CHARACTER_SETS); + } + + if (!terminologyService.codeSetForId( + OpenEHRCodeSetIdentifiers.LANGUAGES).hasCode(language)) { + throw new IllegalArgumentException( + "unknown language: " + language); + } + if (!terminologyService.codeSetForId( + OpenEHRCodeSetIdentifiers.CHARACTER_SETS).hasCode(encoding)) { + throw new IllegalArgumentException( + "unknown encoding: " + encoding); + } + + this.language = language; + this.encoding = encoding; + this.subject = subject; + this.provider = provider; + this.workflowId = workflowId; + this.otherParticipations = ( otherParticipations == null ? null : + new ArrayList(otherParticipations) ); + } + + /** + * Id of human subject of this ENTRY, usually the patient + * + * @return subject + */ + public PartyProxy getSubject() { + return subject; + } + + /** + * Id of provider of statement in this entry + * + * @return provider + */ + public PartyProxy getProvider() { + return provider; + } + + /** + * Name of character set in which text values in this Entry + * are encoded. Coded from openEHR code set "character sets". + * + * @return encoding + */ + public CodePhrase getEncoding() { + return encoding; + } + + /** + * Mandatory indicator of the localized language in which + * this Entry is written. Coded from openEHR code set "languages". + * @return + */ + public CodePhrase getLanguage() { + return language; + } + + /** + * Identifier of externally held workflow engine data for + * this workflow execution, for this subject of care. + * + * @return workflow ID or null if unspecified + */ + public ObjectRef getWorkflowId() { + return workflowId; + } + + /** + * Other participations at ENTRY level - archetypable. + * + * @return unmodifiable List of other participation or null if unspecified + */ + public List getOtherParticipations() { + return otherParticipations == null ? null : + Collections.unmodifiableList(otherParticipations); + } + + /** + * Returns True if this Entry is about the subject of the EHR, in which + * case the subject attribute is of type PartySelf + */ + public boolean subjectIsSelf() { + return (subject instanceof PartySelf); + } + + // POJO start + protected Entry() { + } + + void setSubject(PartyProxy subject) { + this.subject = subject; + } + + void setProvider(PartyProxy provider) { + this.provider = provider; + } + + void setEncoding(CodePhrase encoding) { + this.encoding = encoding; + } + + void setLanguage(CodePhrase language) { + this.language = language; + } + + void setWorkflowId(ObjectRef guidelineId) { + this.workflowId = guidelineId; + } + + void setOtherParticipations(List otherParticipations) { + this.otherParticipations = otherParticipations; + } + // POJO end + + /* fields */ + private CodePhrase language; + private CodePhrase encoding; + private PartyProxy subject; + private PartyProxy provider; + private ObjectRef workflowId; + private List otherParticipations; +} + +/* + * ***** 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 Entry.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 ***** + */ 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 new file mode 100644 index 00000000..768cfdf2 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Evaluation.java @@ -0,0 +1,176 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Evaluation" + * 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/content/entry/Evaluation.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.composition.content.entry; + +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.Participation; +import org.openehr.rm.common.generic.PartyProxy; +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.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvText; + +import java.util.List; +import java.util.Set; + +/** + * Entry type for evaluation statements. Instances of this class are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class Evaluation extends CareEntry { + + /** + * Create an Evaluation + * + * @param uid + * @param archetypeNodeId + * @param name + * @param subject + * @param provider + * @param protocol null if unspecified + * @param actID null if unspecified + * @param guidelineId null if unspecified + * @param otherParticipations null if unspecified + * @param data + * @throws IllegalArgumentException if data null + */ + @FullConstructor + public Evaluation(@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 = "language", required = true) CodePhrase language, + @Attribute(name = "encoding", required = true) CodePhrase encoding, + @Attribute(name = "subject", required = true) PartyProxy subject, + @Attribute(name = "provider") PartyProxy provider, + @Attribute(name = "workflowId") ObjectRef workflowId, + @Attribute(name = "otherParticipations") List otherParticipations, + @Attribute(name = "protocol") ItemStructure protocol, + @Attribute(name = "guidelineId") ObjectRef guidelineId, + @Attribute(name = "data", required = true) ItemStructure data, + @Attribute(name = "terminologyService", system = true) TerminologyService terminologyService) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, + parent, language, encoding, subject, provider, workflowId, + otherParticipations, protocol, guidelineId, terminologyService); + + if (data == null) { + throw new IllegalArgumentException("null data"); + } + this.data = data; + } + + /** + * The data of this evaluation, in the form of a spatial + * data structure. + * + * @return data of this evaluation + */ + public ItemStructure getData() { + return data; + } + + /** + * 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 + Evaluation() { + } + + void setData(ItemStructure data) { + this.data = data; + } + // POJO end + + /* fields */ + private ItemStructure data; + + /* static fields */ + public static final String DATA = "data"; +} + +/* + * ***** 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 Evaluation.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/content/entry/ISMTransition.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/ISMTransition.java new file mode 100644 index 00000000..5b112c2b --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/ISMTransition.java @@ -0,0 +1,153 @@ +/* + * 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 ***** + */ \ 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 new file mode 100644 index 00000000..1fa0c606 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Instruction.java @@ -0,0 +1,261 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Instruction" + * 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/content/entry/Instruction.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.composition.content.entry; + +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.common.archetyped.*; +import org.openehr.rm.common.generic.Participation; +import org.openehr.rm.common.generic.PartyProxy; +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.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datatypes.basic.DvState; +import org.openehr.rm.datatypes.encapsulated.DvParsable; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvText; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * The root of an action specification. Instances of this class are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class Instruction extends CareEntry { + + /** + * Constructs an Instruction + * + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @param subject + * @param provider + * @param protocol + * @param actID + * @param guidelineId + * @param otherParticipations + * @param state + * @param action + * @param profile + * @param data + * @throws IllegalArgumentException if state or action null + */ + @FullConstructor + public Instruction(@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 = "language", required = true) CodePhrase language, + @Attribute(name = "encoding", required = true) CodePhrase encoding, + @Attribute(name = "subject", required = true) PartyProxy subject, + @Attribute(name = "provider") PartyProxy provider, + @Attribute(name = "workflowId") ObjectRef workflowId, + @Attribute(name = "otherParticipations") List otherParticipations, + @Attribute(name = "protocol") ItemStructure protocol, + @Attribute(name = "guidelineId") ObjectRef guidelineId, + @Attribute(name = "narrative", required = true) DvText narrative, + @Attribute(name = "activities") List activities, + @Attribute(name = "expiryTime") DvDateTime expiryTime, + @Attribute(name = "wfDefinition") DvParsable wfDefinition, + @Attribute(name = "terminologyService", system = true) TerminologyService terminologyService) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, + parent, language, encoding, subject, provider, workflowId, + otherParticipations, protocol, guidelineId, terminologyService); + if (narrative == null) { + throw new IllegalArgumentException("null narrative"); + } + if (activities != null && activities.size() == 0) { + throw new IllegalArgumentException("empty activities"); + } + this.narrative = narrative; + this.activities = activities; + this.expiryTime = expiryTime; + this.wfDefinition = wfDefinition; + } + + /** + * List of all activities in Instruction + * + * @return activities + */ + public List getActivities() { + return activities; + } + + /** + * Optional expiry date/time to assist determination of when an Instruction + * can be assumed to hav expired. This helps prevent false listing of + * Instruction as Active when they clearly must have been terminated. + * + * @return expiryTime + */ + public DvDateTime getExpiryTime() { + return expiryTime; + } + + /** + * Mandatory human-readable version of what the Instruction is about. + * + * @return narrative + */ + public DvText getNarrative() { + return narrative; + } + + /** + * Optional workflow engine executable expression of the Instruction. + * + * @return wfDefinition + */ + public DvParsable getWfDefinition() { + return wfDefinition; + } + + /** + * Next actions in chain, derived from links attribute - any Link + * instance with name = "next actions". + * + * @return list of instructions, empty list if no next action + */ + public List nextActions() { + List list = new ArrayList(); + if (getLinks() == null) { + return list; + } + for (Link link : getLinks()) { + if ("next actions".equals(link.getMeaning().getValue())) { + // todo: how to find Instruction from link ? + //list.add(link) + } + } + return list; + } + + /** + * Overall status, derived from the state values of all linked + * Instructions in the chain. + * + * @return status + */ + public DvState status() { + // todo: fix it + return null; + } + + /** + * 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 + Instruction() { + } + + void setActivities(List activities) { + this.activities = activities; + } + + void setExpiryTime(DvDateTime expiryTime) { + this.expiryTime = expiryTime; + } + + void setNarrative(DvText narrative) { + this.narrative = narrative; + } + + void setWfDefinition(DvParsable wfDefinition) { + this.wfDefinition = wfDefinition; + } + // POJO end + + /* fields */ + private DvText narrative; + private List activities; + private DvDateTime expiryTime; + private DvParsable wfDefinition; +} + +/* + * ***** 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 Instruction.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/content/entry/InstructionDetails.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/InstructionDetails.java new file mode 100644 index 00000000..91c4b3d6 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/InstructionDetails.java @@ -0,0 +1,140 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class InstructionDetails" + * 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/InstructionDetails.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.apache.commons.lang.StringUtils; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.RMObject; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.support.identification.LocatableRef; + +/** + * Used to record details of the Instruction causing an Action. + * + * @author Yin Su Lim + * @version 1.0 + */ +public class InstructionDetails extends RMObject { + + /** + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @param parent + */ + @FullConstructor + public InstructionDetails( + @Attribute(name = "instructionId", required = true) LocatableRef instructionId, + @Attribute(name = "activityId", required = true) String activityId, + @Attribute(name = "wfDetails") ItemStructure wfDetails) { + if (instructionId == null) { + throw new IllegalArgumentException("null instructionId"); + } + if (StringUtils.isEmpty(activityId)) { + throw new IllegalArgumentException("null or empty activityId"); + } + this.instructionId =instructionId; + this.activityId = activityId; + this.wfDetails = wfDetails; + } + + /** + * Identifier of Activity within Instruction, in the form of its archetype + * path. + * + * @return activityId + */ + public String getActivityId() { + return activityId; + } + + /** + * Id of causing Instruction + * + * @return instructionId + */ + public LocatableRef getInstructionId() { + return instructionId; + } + + /** + * Various workflow engine state details, potentially including such things as: + * -condition that fired to cause this Action to be done + * -list of notifications which actually occured + * -other workflow engine state + * + * @return wfDetails + */ + public ItemStructure getWfDetails() { + return wfDetails; + } + + //POJO start + InstructionDetails() { + } + + void setActivityID(String activityId) { + this.activityId = activityId; + } + + void setInstructionId(LocatableRef instructionId) { + this.instructionId = instructionId; + } + + void setWfDetails(ItemStructure wfDetails) { + this.wfDetails = wfDetails; + } + //POJO end + + /* fields */ + private LocatableRef instructionId; + private String activityId; + private ItemStructure wfDetails; + +} + +/* + * ***** 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 InstructionDetails.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/Observation.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Observation.java new file mode 100644 index 00000000..e16c815d --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Observation.java @@ -0,0 +1,222 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Observation" + * 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/content/entry/Observation.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.composition.content.entry; + +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.Participation; +import org.openehr.rm.common.generic.PartyProxy; +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.datastructure.history.History; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvText; + +import java.util.List; +import java.util.Set; + +/** + * Purpose Entry subtype for all clinical data in the past or present, + * ie which (by the time it is recorded) has already occurred. + * OBSERVATION data is expressed using the class HISTORY, which + * guarantees that it is situated in time. + *

+ * Instances of this class are immutable. + * + * @author Rong Chen + * @version 1.0 + */ +public final class Observation extends CareEntry { + + /** + * Construct an Observation + * + * @param uid + * @param archetypeNodeId + * @param name + * @param subject + * @param provider + * @param protocol + * @param act + * @param guidelineId + * @param otherParticipations + * @param data + * @param state null if unspecified + * @throws IllegalArgumentException if date null + */ + @FullConstructor + public Observation(@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 = "language", required = true) CodePhrase language, + @Attribute(name = "encoding", required = true) CodePhrase encoding, + @Attribute(name = "subject", required = true) PartyProxy subject, + @Attribute(name = "provider") PartyProxy provider, + @Attribute(name = "workflowId") ObjectRef workflowId, + @Attribute(name = "otherParticipations") List otherParticipations, + @Attribute(name = "protocol") ItemStructure protocol, + @Attribute(name = "guidelineId") ObjectRef guidelineId, + @Attribute(name = "data", required = true) History data, + @Attribute(name = "state") History state, + @Attribute(name = "terminologyService", system = true) TerminologyService terminologyService + ) { + + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, parent, + language, encoding, subject, provider, workflowId, otherParticipations, + protocol, guidelineId, terminologyService); + + if (data == null) { + throw new IllegalArgumentException("null data"); + } + this.data = data; + this.state = state; + } + + /** + * Construct an Observation + * + * @param archetypeNodeId + * @param name + * @param subject + * @param provider + * @param data + * @throws IllegalArgumentException if date null + */ + public Observation(String archetypeNodeId, DvText name, Archetyped archetypeDetails, + CodePhrase language, CodePhrase encoding, + PartyProxy subject, PartyProxy provider, + History data, TerminologyService terminologyService) { + this(null, archetypeNodeId, name, archetypeDetails, null, null, null, language, encoding, + subject, provider, null, null, null, null, data, null, terminologyService); + } + + /** + * The data of this observation, in the form of a history of + * values which may be of any complexity. + * + * @return data + */ + public History getData() { + return data; + } + + /** + * The state of subject of this observation during the observation + * process, in the form of a history of values which may be of any + * complexity. Optional. + * + * @return state null if unspecified + */ + public History getState() { + return state; + } + + /** + * 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 + Observation() { + } + + void setData(History data) { + this.data = data; + } + + void setState(History state) { + this.state = state; + } + // POJO end + + /* fields */ + private History data; + private History state; + + /* static fields */ + public static final String DATA = "data"; + public static final String STATE = "state"; +} + +/* + * ***** 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 Observation.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/content/navigation/Section.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/navigation/Section.java new file mode 100644 index 00000000..7e0dbc98 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/navigation/Section.java @@ -0,0 +1,167 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Section" + * 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/content/navigation/Section.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.composition.content.navigation; + +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.support.identification.UIDBasedID; +import org.openehr.rm.composition.content.ContentItem; +import org.openehr.rm.datatypes.text.DvText; + +import java.util.*; + +/** + * Represents a heading in a heading structure, or "section tree". * + * + * @author Rong Chen + * @version 1.0 + */ +public final class Section extends ContentItem { + + /** + * Constructs a Section + * + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @param items null if not present + * @throws IllegalArgumentException if items not null and empty + */ + @FullConstructor + public Section(@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 = "items") List items) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, + links, parent); + if (items != null && items.isEmpty()) { + throw new IllegalArgumentException("empty items"); + } + this.items = ( items == null ? + null : new ArrayList(items) ); + } + + /** + * Constructs a Section + * + * @param archetypeNodeId + * @param name + * @param items + */ + public Section(String archetypeNodeId, DvText name, + List items) { + this(null, archetypeNodeId, name, null, null, null, null, items); + } + + /** + * String The path to an item relative to the root of this + * archetyped structure. + * + * @param item + * @return path of given item + */ + public String pathOfItem(Locatable item) { + return null; // todo: implement this method + } + + /** + * Ordered list of content items under this section, which may + * include more Sections or Entries + * + * @return list of ContentItem or null if not present + */ + public List getItems() { + return items; + } + + @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 + Section() { + } + + void setItems(List items) { + this.items = items; + } + // POJO end + + /* fields */ + private List items; + +} + +/* + * ***** 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 Section.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/demographic/Actor.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Actor.java new file mode 100644 index 00000000..1600c9a3 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Actor.java @@ -0,0 +1,228 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Attestation" + * keywords: "demographic" + * + * author: "Goran Pestana " + * support: "Acode HB " + * copyright: "Copyright (c) 2005 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/demographic/Actor.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.demographic; + +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.support.identification.LocatableRef; +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.datatypes.text.DvText; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.Attribute; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import java.util.Set; +import java.util.HashSet; + +/** + * Ancestor of all real-world types, including people and organisations. + * An actor is any real-world entity capable of taking on a role. + * + * @author Goran Pestana + * @author Rong Chen + * @version 1.0 + */ +public abstract class Actor extends Party { + + protected Actor() { + } + + /** + * Constructs a Actor + * + * @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 identities + * @param contacts + * @param relationships + * @param reverseRelationships + * @param details null if not specified + * @param roles + * @param languages + * @throws IllegalArgumentException if name null or archetypeNodeId null, + * or links not null and empty, + * or uid is null, or identities is null + * or empty, or contacts is empty, + * or no legal identity, or empty roles + * or empty languages + */ + @FullConstructor + protected Actor( + @Attribute(name = "uid", required = true) 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 = "identities", required = true) Set identities, + @Attribute(name = "contacts") Set contacts, + @Attribute(name = "relationships") Set relationships, + @Attribute(name = "reverseRelationships") Set reverseRelationships, + @Attribute(name = "details") ItemStructure details, + @Attribute(name = "roles") Set roles, + @Attribute(name = "languages") Set languages) { + + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, + identities, contacts, relationships, reverseRelationships, + details); + + boolean hasLegalIdentity = false; + for (PartyIdentity identity : identities) { + if (LEGAL_IDENTITY.equals(identity.purpose().getValue())) { + hasLegalIdentity = true; + break; + } + } + if (!hasLegalIdentity) { + throw new IllegalArgumentException("no legal identity"); + } + if (roles != null && roles.isEmpty()) { + throw new IllegalArgumentException("empty roles"); + } + if (languages != null && languages.isEmpty()) { + throw new IllegalArgumentException("empty languages"); + } + + this.roles = roles; + this.languages = languages; + } + + /** + * Roles played by this party + * + * @return null if not specified + */ + public Set getRoles() { + return roles; + } + + protected void setRoles(Set roles) { + this.roles = roles; + } + + /** + * Add a role to this actor if it is not already present + * + * @param role + * @return true if this agent did not already have this role + */ + public boolean addRole(Role role) { + if (roles == null) { + roles = new HashSet(); + } + return roles.add(role); + } + + /** + * Remove a role from this actor if it is present + * + * @param role + * @return true if the actor has this role + */ + public boolean removeRole(Role role) { + if (roles == null) { + return false; + } + return roles.remove(role); + } + + /** + * Languages which can be used to communicate with this actor. + * + * @return null if not specified + */ + public Set getLanguages() { + return languages; + } + + protected void setLanguages(Set languages) { + this.languages = languages; + } + + /** + * Equals if two actors has same values + * + * @param o + * @return equals if true + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof Actor )) return false; + if (!super.equals(o)) return false; + + final Actor actor = (Actor) o; + return new EqualsBuilder() + .append(roles, actor.roles) + .append(languages, actor.languages) + .isEquals(); + } + + /** + * Return a hash code of this actor + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(11, 29) + .appendSuper(super.hashCode()) + .append(roles) + .append(languages) + .toHashCode(); + } + + /* fields */ + private Set roles; + private Set languages; + + /* static fields */ + public static final String LEGAL_IDENTITY = "legal identity"; +} + +/* + * ***** 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 Actor.java + * + * The Initial Developer of the Original Code is Goran Pestana. + * Portions created by the Initial Developer are Copyright (C) 2003-2005 + * 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/demographic/Address.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Address.java new file mode 100644 index 00000000..cf2f9ace --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Address.java @@ -0,0 +1,201 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Attestation" + * keywords: "demographic" + * + * author: "Goran Pestana " + * support: "Acode HB " + * copyright: "Copyright (c) 2005 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/demographic/Address.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.demographic; + +import org.openehr.rm.common.archetyped.Locatable; +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.ItemStructure; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.Attribute; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.EqualsBuilder; + +import java.util.List; +import java.util.Set; + +/** + * Address of contact, which may be electronic or geographic. + * + * @author Goran Pestana + * @version 1.0 + */ + +public class Address extends Locatable { + + protected Address() { + } + + /** + * Constructs a Address + * + * @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 + * @throws IllegalArgumentException if name null, or archetypeNodeId null, + * or links not null and empty, + * or details null + */ + @FullConstructor + public Address(@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 = "details", required = true) ItemStructure details) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, parent); + if (details == null) { + throw new IllegalArgumentException("null details"); + } + this.details = details; + } + + public String pathOfItem(Locatable item) { + //todo: to be implemented + return null; + } + + /** + * Type of address, eg electronic, locality. + * Taken from value of inherited name attribute. + * + * @return type of relationship + */ + public DvText type() { + return this.getName(); + } + + /** + * Return the type of the relationship as string + * + * @return type of relationship + */ + public String toString() { + // todo: fix it + // return details.toString(); + return ""; + } + + /** + * The details of the address, in the form of a STRUCTURE. This may take + * the form of a SINGLE_S, whose data item is a parsable string or a list + * or tree of many parts. + * + * @return details + */ + public ItemStructure getDetails() { + return details; + } + + protected void setDetails(ItemStructure details) { + this.details = details; + } + + /** + * Equals if two address has same values + * + * @param o + * @return equals if true + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof Address )) return false; + if (!super.equals(o)) return false; + + final Address address = (Address) o; + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(details, address.details) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(13, 29) + .appendSuper(super.hashCode()) + .append(details) + .toHashCode(); + } + + @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; + } + + /* fields */ + private ItemStructure details; +} + +/* + * ***** 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 Address.java + * + * The Initial Developer of the Original Code is Goran Pestana. + * Portions created by the Initial Developer are Copyright (C) 2003-2005 + * 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/demographic/Agent.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Agent.java new file mode 100644 index 00000000..9e12529d --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Agent.java @@ -0,0 +1,114 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Attestation" + * keywords: "demographic" + * + * author: "Goran Pestana " + * support: "Acode HB " + * copyright: "Copyright (c) 2005 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/demographic/Agent.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.demographic; + +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.support.identification.LocatableRef; +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.datatypes.text.DvText; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; + +import java.util.Set; + +/** + * Generic concept of any kind of agent, including devices, software systems, + * but not humans or organisations. + * + * @author Goran Pestana + * @version 1.0 + */ +public class Agent extends Actor { + + protected Agent() { + } + + /** + * Constructs a Agent + * + * @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 identities + * @param contacts + * @param relationships + * @param reverseRelationships + * @param details null if not specified + * @param roles + * @param languages + * @throws IllegalArgumentException if name null or meaning null + * or links not null and empty, + * or uid is null, or identities is null + * or empty, or contacts is empty, + * or no legal identity, or empty roles + * or empty languages + */ + @FullConstructor + public Agent( + @Attribute(name = "uid", required = true) 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 = "identities", required = true) Set identities, + @Attribute(name = "contacts") Set contacts, + @Attribute(name = "relationships") Set relationships, + @Attribute(name = "reverseRelationships") Set reverseRelationships, + @Attribute(name = "details") ItemStructure details, + @Attribute(name = "roles") Set roles, + @Attribute(name = "languages") Set languages) { + + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, + identities, contacts, relationships, reverseRelationships, + details, roles, languages); + } +} + +/* + * ***** 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 Agent.java + * + * The Initial Developer of the Original Code is Goran Pestana. + * Portions created by the Initial Developer are Copyright (C) 2003-2005 + * 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/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 new file mode 100644 index 00000000..bb062720 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Capability.java @@ -0,0 +1,210 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Attestation" + * keywords: "demographic" + * + * author: "Goran Pestana " + * support: "Acode HB " + * copyright: "Copyright (c) 2005 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/demographic/Capability.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.demographic; + +import org.openehr.rm.common.archetyped.Locatable; +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.datatypes.quantity.datetime.DvDate; +import org.openehr.rm.datatypes.quantity.DvInterval; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.Attribute; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import java.util.List; +import java.util.Set; + +/** + * Capability of a role, such as ehr modifier, health care provider . + * Capability should be backed up by credentials. + * + * @author Goran Pestana + * @version 1.0 + */ +public class Capability extends Locatable { + + protected Capability() { + } + + /** + * Constructs a Capability + * + * @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 timeValidity null if not specified + * @param credentials not null + * @throws IllegalArgumentException if name null or meaning null + * or links not null and empty + * or credentials null + */ + @FullConstructor + public Capability( + @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 = "timeValidity") DvInterval timeValidity, + @Attribute(name = "credentials", required=true) ItemStructure credentials) { + + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, parent); + + if (credentials == null) { + throw new IllegalArgumentException("null credentials"); + } + this.timeValidity = timeValidity; + this.credentials = credentials; + } + + public String pathOfItem(Locatable item) { + //todo: to be implemented + return null; + } + + public boolean hasLegalIdentity() { + //todo: to be implemented + return false; + } + + /** + * Valid time interval for this capability + * + * @return time validity + */ + public DvInterval getTimeValidity() { + return timeValidity; + } + + protected void setTimeValidity(DvInterval timeValidity) { + this.timeValidity = timeValidity; + } + + /** + * The qualifications of the performer of the role for this capability. + * This might include professional qualifications and official + * identifications such as provider numbers etc. + * + * @return credentials + */ + public ItemStructure getCredentials() { + return credentials; + } + + protected void setCredentials(ItemStructure credentials) { + this.credentials = credentials; + } + + /** + * Equals if two capabilities has same values + * + * @param o + * @return equals if true + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof Capability )) return false; + if (!super.equals(o)) return false; + + final Capability capability = (Capability) o; + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(credentials, capability.credentials) + .append(timeValidity, capability.timeValidity) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(13, 29) + .appendSuper(super.hashCode()) + .append(timeValidity) + .append(credentials) + .toHashCode(); + } + + @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; + } + + /* fields */ + private DvInterval timeValidity; + private ItemStructure credentials; +} + +/* + * ***** 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 Capability.java + * + * The Initial Developer of the Original Code is Goran Pestana. + * Portions created by the Initial Developer are Copyright (C) 2003-2005 + * 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/demographic/Contact.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Contact.java new file mode 100644 index 00000000..fa201804 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Contact.java @@ -0,0 +1,211 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Attestation" + * keywords: "demographic" + * + * author: "Goran Pestana " + * support: "Acode HB " + * copyright: "Copyright (c) 2005 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/demographic/Contact.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.demographic; + +import org.openehr.rm.common.archetyped.Locatable; +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.datatypes.quantity.DvInterval; +import org.openehr.rm.datatypes.quantity.datetime.DvDate; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.Attribute; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import java.util.List; +import java.util.Set; + +/** + * Description of a means of contact of a party. Actual structure is archetyped. + * + * @author Goran Pestana + * @author Rong Chen + * + * @version 1.0 + */ +public class Contact extends Locatable { + + protected Contact() { + } + + /** + * Constructs a Contact + * + * @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 timeValidity null if not specified + * @param addresses not null + * @throws IllegalArgumentException if name null or archetypeNodeId null, + * or links not null and empty, + * or addresses null or empty + */ + @FullConstructor + public Contact(@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 = "timeValidity") DvInterval timeValidity, + @Attribute(name = "addresses", required = true) List
addresses) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, parent); + if (addresses == null || addresses.size() == 0) { + throw new IllegalArgumentException("null or empty addresses"); + } + this.timeValidity = timeValidity; + this.addresses = addresses; + } + + /** + * Purpose for which this contact is used, eg mail, daytime phone, etc. + * Taken from value of inherited name attribute. + * + * @return purpose + */ + public DvText purpose() { + return this.getName(); + } + + public String pathOfItem(Locatable item) { + //todo: to be implemented + return null; + } + + /** + * Valid time interval for this contact descriptor + * + * @return time validity or null if not specified + */ + public DvInterval getTimeValidity() { + return timeValidity; + } + + protected void setTimeValidity(DvInterval timeValidity) { + this.timeValidity = timeValidity; + } + + /** + * A set of address alternatives for this contact + * + * @return addresses + */ + public List
getAddresses() { + return addresses; + } + + protected void setAddresses(List
addresses) { + this.addresses = addresses; + } + + /** + * Equals if two contacts has same values + * + * @param o + * @return equals if true + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof Contact )) return false; + if (!super.equals(o)) return false; + + final Contact contact = (Contact) o; + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(timeValidity, contact.timeValidity) + .append(addresses, contact.addresses) + .isEquals(); + } + + /** + * Return a hash code of this contact + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(13, 29) + .appendSuper(super.hashCode()) + .append(timeValidity) + .append(addresses) + .toHashCode(); + } + + + @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; + } + + /* fields */ + private DvInterval timeValidity; + private List
addresses; +} + +/* + * ***** 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 Contact.java + * + * The Initial Developer of the Original Code is Goran Pestana. + * Portions created by the Initial Developer are Copyright (C) 2003-2005 + * 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/demographic/Group.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Group.java new file mode 100644 index 00000000..42919f83 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Group.java @@ -0,0 +1,109 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Attestation" + * keywords: "demographic" + * + * author: "Goran Pestana " + * support: "Acode HB " + * copyright: "Copyright (c) 2005 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/demographic/Group.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.demographic; + +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.support.identification.LocatableRef; +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.datatypes.text.DvText; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.Attribute; + +import java.util.Set; + +/** + * A group is a real world group of parties which is created by another + * party, usually an organisation, for some specific purpose. A typical + * clinical example is that of the specialist care team, eg cardiology team. + * The members of the group usually work together. + * + * @author Goran Pestana + * @version 1.0 + */ +public class Group extends Actor { + + protected Group() { + } + + /** + * Constructs a Group + * + * @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 + * @throws IllegalArgumentException if name null or archetypeNodeId null + * or links not null and empty, + * or uid is null, or identities is null + * or empty, or contacts is empty, + * or no legal identity, or empty roles + * or empty languages + */ + @FullConstructor + public Group( + @Attribute(name = "uid", required = true) 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 = "identities", required = true) Set identities, + @Attribute(name = "contacts") Set contacts, + @Attribute(name = "relationships") Set relationships, + @Attribute(name = "reverseRelationships") Set reverseRelationships, + @Attribute(name = "details") ItemStructure details, + @Attribute(name = "roles") Set roles, + @Attribute(name = "languages") Set languages) { + + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, + identities, contacts, relationships, reverseRelationships, + details, roles, languages); + } +} + +/* + * ***** 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 Group.java + * + * The Initial Developer of the Original Code is Goran Pestana. + * Portions created by the Initial Developer are Copyright (C) 2003-2005 + * 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/demographic/Organisation.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Organisation.java new file mode 100644 index 00000000..a8a4813c --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Organisation.java @@ -0,0 +1,114 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Attestation" + * keywords: "demographic" + * + * author: "Goran Pestana " + * support: "Acode HB " + * copyright: "Copyright (c) 2005 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/demographic/Organisation.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.demographic; + +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.support.identification.LocatableRef; +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.datatypes.text.DvText; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.Attribute; + +import java.util.Set; + +/** + * Generic description of organisations. An organisation is a legally + * constituted body whose existence (in general) outlives the existence of + * parties considered to be part of it. + * + * @author Goran Pestana + * @version 1.0 + */ +public class Organisation extends Actor { + + protected Organisation() { + } + + /** + * Constructs an Organisation + * + * @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 identities + * @param contacts + * @param relationships + * @param reverseRelationships + * @param details null if not specified + * @param roles + * @param languages + * @throws IllegalArgumentException if name null or meaning null + * or links not null and empty, + * or uid is null, or identities is null + * or empty, or contacts is empty, + * or no legal identity, or empty roles + * or empty languages + */ + @FullConstructor + public Organisation( + @Attribute(name = "uid", required = true) 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 = "identities", required = true) Set identities, + @Attribute(name = "contacts") Set contacts, + @Attribute(name = "relationships") Set relationships, + @Attribute(name = "reverseRelationships") Set reverseRelationships, + @Attribute(name = "details") ItemStructure details, + @Attribute(name = "roles") Set roles, + @Attribute(name = "languages") Set languages) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, + identities, contacts, relationships, reverseRelationships, + details, roles, languages); + } +} + +/* + * ***** 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 Organisation.java + * + * The Initial Developer of the Original Code is Goran Pestana. + * Portions created by the Initial Developer are Copyright (C) 2003-2005 + * 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/demographic/Party.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Party.java new file mode 100644 index 00000000..2dc92097 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Party.java @@ -0,0 +1,266 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Attestation" + * keywords: "demographic" + * + * author: "Goran Pestana " + * support: "Acode HB " + * copyright: "Copyright (c) 2005 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/demographic/Party.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.demographic; + +import org.openehr.rm.common.archetyped.Locatable; +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.datatypes.text.DvText; +import org.openehr.rm.support.identification.LocatableRef; +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import java.util.List; +import java.util.Set; + +/** + * Ancestor of all party types, including real world entities and their + * roles. A party is any entity which can participate in an activity. The + * meaning attribute inherited from LOCATABLE is used to indicate the actual + * type of party. + * + * @author Goran Pestana + * @author Rong Chen + * @version 1.0 + */ +public abstract class Party extends Locatable { + + protected Party() { + } + + /** + * Constructs a Party + * + * @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 identities + * @param contacts + * @param relationships + * @param reverseRelationships + * @param details null if not specified + * @throws IllegalArgumentException if name null or archetypeNodeId null + * or links not null and empty, + * or uid is null, or identities is null + * or empty, or contacts is empty + */ + protected Party(UIDBasedID uid, String archetypeNodeId, DvText name, + Archetyped archetypeDetails, FeederAudit feederAudit, + Set links, Set identities, + Set contacts, Set relationships, + Set reverseRelationships, + ItemStructure details) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, null); + + if (uid == null) { + throw new IllegalArgumentException("null uid"); + } + if (identities == null || identities.isEmpty()) { + throw new IllegalArgumentException("null or empty identities"); + } + if (contacts != null && contacts.isEmpty()) { + throw new IllegalArgumentException("empty contacts"); + } + if (relationships != null) { + if (relationships.isEmpty()) { + throw new IllegalArgumentException("empty relationships"); + } + boolean hasThis = false; + for (PartyRelationship relation : relationships) { + if (relation.getSource().getId().equals(getUid())) { + hasThis = true; + break; + } + } + if (!hasThis) { + throw new IllegalArgumentException("invalid relationships"); + } + } + + //todo: Reverse_releationships_validity + + if (!isArchetypeRoot()) { + throw new IllegalArgumentException("not archetype root"); + } + this.identities = identities; + this.contacts = contacts; + this.relationships = relationships; + this.reverseRelationships = reverseRelationships; + this.details = details; + } + + /** + * Type of party, such as PERSON, ORGANISATION, etc. + * Role name, eg general practitioner, nurse, private citizen. + * Taken from inherited name attribute. + * + * @return type + */ + public DvText type() { + return this.getName(); + } + + public String pathOfItem(Locatable item) { + //todo: to be implemented + return null; + } + + public Set getIdentities() { + return identities; + } + + protected void setIdentities(Set identities) { + this.identities = identities; + } + + public Set getContacts() { + return contacts; + } + + protected void setContacts(Set contacts) { + this.contacts = contacts; + } + + public Set getRelationships() { + return relationships; + } + + protected void setRelationships(Set relationships) { + this.relationships = relationships; + } + + public Set getReverseRelationships() { + return reverseRelationships; + } + + protected void setReverseRelationships( + Set reverseRelationships) { + this.reverseRelationships = reverseRelationships; + } + + public ItemStructure getDetails() { + return details; + } + + protected void setDetails(ItemStructure details) { + this.details = details; + } + + /** + * Equals if two parties have same values + * + * @param o + * @return true if equals + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof Party )) return false; + if (!super.equals(o)) return false; + + final Party party = (Party) o; + + return new EqualsBuilder() + .append(identities, party.identities) + .append(contacts, party.contacts) + .append(relationships, party.relationships) + .append(reverseRelationships, party.reverseRelationships) + .append(details, party.details) + .isEquals(); + } + + /** + * Return a hash code of this party + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(7, 19) + .appendSuper(super.hashCode()) + .append(identities) + .append(contacts) + .append(relationships) + .append(reverseRelationships) + .append(details) + .toHashCode(); + } + + @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; + } + + /* fields */ + private Set identities; + private Set contacts; + private Set relationships; + private Set reverseRelationships; + private ItemStructure details; +} + +/* + * ***** 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 Party.java + * + * The Initial Developer of the Original Code is Goran Pestana. + * Portions created by the Initial Developer are Copyright (C) 2003-2005 + * 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/demographic/PartyIdentity.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/PartyIdentity.java new file mode 100644 index 00000000..394a424a --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/PartyIdentity.java @@ -0,0 +1,200 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Attestation" + * keywords: "demographic" + * + * author: "Goran Pestana " + * support: "Acode HB " + * copyright: "Copyright (c) 2005 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/demographic/PartyIdentity.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.demographic; + +import org.openehr.rm.common.archetyped.Locatable; +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.ItemStructure; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.Attribute; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import java.util.List; +import java.util.Set; + +/** + * An identity owned by a PARTY, such as a person name or company name, + * and which is used by the party to identify itself. Actual structure is + * archetyped. + * + * @author Goran Pestana + * @version 1.0 + */ +public class PartyIdentity extends Locatable { + + protected PartyIdentity() { + } + + /** + * Constructs a PartyIdentity + * + * @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 + * @throws IllegalArgumentException if name null or archetypeNodeId null + * or links not null and empty, + * or details null + */ + @FullConstructor + public PartyIdentity(@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 = "details", required = true) ItemStructure details) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, parent); + if (details == null) { + throw new IllegalArgumentException("details null"); + } + this.details = details; + } + + public String pathOfItem(Locatable item) { + //todo: to be implemented + return null; + } + + /** + * Purpose of identity, eg legal, stagename, nickname, tribal name, + * trading name. Taken from value of inherited name attribute. + * + * @return identity purpose + */ + public DvText purpose() { + return this.getName(); + } + + /** + * Indentity in the form of a single string + * + * @return identity purpose + */ + public String toString() { + // todo: fix it + return ""; + } + + /** + * The value of the indentity. This will often taken the form of a + * parsable string or a small structure of strings. + * + * @return details + */ + public ItemStructure getDetails() { + return details; + } + + protected void setDetails(ItemStructure details) { + this.details = details; + } + + /** + * Equals if two party identities have same values + * + * @param o + * @return equals if true + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof PartyIdentity )) return false; + if (!super.equals(o)) return false; + + final PartyIdentity identity = (PartyIdentity) o; + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(details, identity.details) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(13, 29) + .appendSuper(super.hashCode()) + .append(details) + .toHashCode(); + } + + @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; + } + + /* fields */ + private ItemStructure details; +} + +/* + * ***** 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 PartyIdentity.java + * + * The Initial Developer of the Original Code is Goran Pestana. + * Portions created by the Initial Developer are Copyright (C) 2003-2005 + * 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/demographic/PartyRelationship.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/PartyRelationship.java new file mode 100644 index 00000000..5012f1bf --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/PartyRelationship.java @@ -0,0 +1,245 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Attestation" + * keywords: "demographic" + * + * author: "Goran Pestana " + * support: "Acode HB " + * copyright: "Copyright (c) 2005 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/demographic/PartyRelationship.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.demographic; + +import org.openehr.rm.common.archetyped.Locatable; +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.datatypes.text.DvText; +import org.openehr.rm.datatypes.quantity.datetime.DvDate; +import org.openehr.rm.datatypes.quantity.DvInterval; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.Attribute; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import java.util.List; +import java.util.Set; + +/** + * Generic description of a relationship between parties. + * + * @author Goran Pestana * + * @version 1.0 + */ + +public class PartyRelationship extends Locatable { + + protected PartyRelationship() { + } + + /** + * Constructs a PartyRelationship + * + * @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 + * @throws IllegalArgumentException if name null or archetypeNodeId null + * or links not null and empty, + * or uid null, or source null + * or target null + */ + @FullConstructor + public PartyRelationship( + @Attribute(name = "uid", required = true) 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 = "details") ItemStructure details, + @Attribute(name = "timeValidity") DvInterval timeValidity, + @Attribute(name = "source", required = true) ObjectRef source, + @Attribute(name = "target", required = true) ObjectRef target) { + + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, parent); + + if (uid == null) { + throw new IllegalArgumentException("null uid"); + } + + //todo: source.relationships.has(Current) + //todo: not target.reverserelationships.has(Current) + + if (source == null) { + throw new IllegalArgumentException("null source"); + } + if (target == null) { + throw new IllegalArgumentException("null target"); + } + + this.details = details; + this.timeValidity = timeValidity; + this.source = source; + this.target = target; + } + + public String pathOfItem(Locatable item) { + //todo: to be implemented + return null; + } + + public boolean hasLegalIdentity() { + //todo: to be implemented + return false; + } + + /** + * Type of relationship, such as "employment", "authority", + * "health provision" + * + * @return type of relationship + */ + public DvText type() { + return getName(); + } + + public ItemStructure getDetails() { + return details; + } + + protected void setDetails(ItemStructure details) { + this.details = details; + } + + public DvInterval getTimeValidity() { + return timeValidity; + } + + protected void setTimeValidity(DvInterval timeValidity) { + this.timeValidity = timeValidity; + } + + public ObjectRef getSource() { + return source; + } + + protected void setSource(ObjectRef source) { + this.source = source; + } + + public ObjectRef getTarget() { + return target; + } + + protected void setTarget(ObjectRef target) { + this.target = target; + } + + /** + * Equals if two party relationships have same values + * + * @param o + * @return equals if true + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof PartyRelationship )) return false; + if (!super.equals(o)) return false; + + final PartyRelationship relation = (PartyRelationship) o; + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(details, relation.details) + .append(timeValidity, relation.timeValidity) + .append(source, relation.source) + .append(target, relation.target) + .isEquals(); + } + + /** + * Return a hash code of this object + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(7, 13) + .appendSuper(super.hashCode()) + .append(details) + .append(timeValidity) + .append(source) + .append(target) + .toHashCode(); + } + + @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; + } + + /* fields */ + private ItemStructure details; + private DvInterval timeValidity; + private ObjectRef source; + private ObjectRef target; +} + +/* + * ***** 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 PartyRelationship.java + * + * The Initial Developer of the Original Code is Goran Pestana. + * Portions created by the Initial Developer are Copyright (C) 2003-2005 + * 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/demographic/Person.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Person.java new file mode 100644 index 00000000..0980161a --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Person.java @@ -0,0 +1,114 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Attestation" + * keywords: "demographic" + * + * author: "Goran Pestana " + * support: "Acode HB " + * copyright: "Copyright (c) 2005 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/demographic/Person.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.demographic; + +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.support.identification.LocatableRef; +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.datatypes.text.DvText; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.Attribute; + +import java.util.Set; + + +/** + * Generic description of persons. Provides a dedicated type to which Person + * archetypes can be targeted. + * + * @author Goran Pestana + * @version 1.0 + */ +public class Person extends Actor { + + protected Person() { + } + + /** + * Constructs a Person + * + * @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 identities + * @param contacts + * @param relationships + * @param reverseRelationships + * @param details null if not specified + * @param roles + * @param languages + * @throws IllegalArgumentException if name null or archetypeNodeId null + * or links not null and empty, + * or uid is null, or identities is null, + * or empty, or contacts is empty, + * or no legal identity, or empty roles + * or empty languages + */ + @FullConstructor + public Person( + @Attribute(name = "uid", required = true) 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 = "identities", required = true) Set identities, + @Attribute(name = "contacts") Set contacts, + @Attribute(name = "relationships") Set relationships, + @Attribute(name = "reverseRelationships") Set reverseRelationships, + @Attribute(name = "details") ItemStructure details, + @Attribute(name = "roles") Set roles, + @Attribute(name = "languages") Set languages) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, + identities, contacts, relationships, reverseRelationships, + details, roles, languages); + } +} + +/* + * ***** 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 Persion.java + * + * The Initial Developer of the Original Code is Goran Pestana. + * Portions created by the Initial Developer are Copyright (C) 2003-2005 + * 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/demographic/Role.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Role.java new file mode 100644 index 00000000..584ea7cf --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/Role.java @@ -0,0 +1,196 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Attestation" + * keywords: "demographic" + * + * author: "Goran Pestana " + * support: "Acode HB " + * copyright: "Copyright (c) 2005 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/demographic/Role.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.demographic; + +import java.util.List; +import java.util.Set; + +import org.openehr.rm.datatypes.quantity.datetime.DvDate; +import org.openehr.rm.datatypes.quantity.DvInterval; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.support.identification.LocatableRef; +import org.openehr.rm.support.identification.PartyRef; +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.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.Attribute; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +/** + * Generic description of a role performed by an actor. The role + * corresponds to a competency of the party. Roles are used to define the + * responsibilities undertaken by a party for a purpose. Roles should have + * credentials qualifying the performer to perform the role. + * + * @author Goran Pestana + * @version 1.0 + */ +public class Role extends Party { + + protected Role() { + } + + /** + * Constructs a Role + * + * @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 identities + * @param contacts + * @param relationships + * @param reverseRelationships + * @param details null if not specified + * @param capabilities null if not specified + * @param timeValidity null if not specified + * @param performer + * @throws IllegalArgumentException if name null or archetypeNodeId null, + * or links not null and empty, + * or uid is null, or identities is null + * or empty, or contacts is empty, + * or capabilities is empty, + * or performer is null + */ + @FullConstructor + public Role(@Attribute(name = "uid", required = true) 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 = "identities", required = true) Set identities, + @Attribute(name = "contacts") Set contacts, + @Attribute(name = "relationships") Set relationships, + @Attribute(name = "reverseRelationships") Set reverseRelationships, + @Attribute(name = "details") ItemStructure details, + @Attribute(name = "capabilities") List capabilities, + @Attribute(name = "timeValidity") DvInterval timeValidity, + @Attribute(name = "performer", required = true) PartyRef performer) { + + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, + identities, contacts, relationships, reverseRelationships, + details); + + if (capabilities != null && capabilities.size() == 0) { + throw new IllegalArgumentException("Empty capabilities"); + } + if (performer == null) { + throw new IllegalArgumentException("Null performer"); + } + this.capabilities = capabilities; + this.timeValidity = timeValidity; + this.performer = performer; + } + + public List getCapabilities() { + return capabilities; + } + + protected void setCapabilities(List capabilities) { + this.capabilities = capabilities; + } + + public DvInterval getTimeValidity() { + return timeValidity; + } + + protected void setTimeValidity(DvInterval timeValidity) { + this.timeValidity = timeValidity; + } + + public PartyRef getPerformer() { + return performer; + } + + protected void setPerformer(PartyRef performer) { + this.performer = performer; + } + + /** + * Equals if two roles has same values + * + * @param o + * @return equals if true + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof Role )) return false; + if (!super.equals(o)) return false; + + final Role role = (Role) o; + return new EqualsBuilder() + .appendSuper(super.equals(o)) + .append(capabilities, role.capabilities) + .append(timeValidity, role.timeValidity) + .append(performer, role.performer) + .isEquals(); + } + + /** + * Return a hash code of this role + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(17, 31) + .appendSuper(super.hashCode()) + .append(capabilities) + .append(timeValidity) + .append(performer) + .toHashCode(); + } + + + private List capabilities; + private DvInterval timeValidity; + private PartyRef performer; +} + +/* + * ***** 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 Role.java + * + * The Initial Developer of the Original Code is Goran Pestana. + * Portions created by the Initial Developer are Copyright (C) 2003-2005 + * 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/demographic/VersionedParty.java b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/VersionedParty.java new file mode 100644 index 00000000..835751ac --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/demographic/VersionedParty.java @@ -0,0 +1,111 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class VersionedParty" + * keywords: "demographic" + * + * 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/demographic/VersionedParty.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ + +package org.openehr.rm.demographic; + +import java.util.Set; + +import org.openehr.rm.common.changecontrol.OriginalVersion; +import org.openehr.rm.common.changecontrol.VersionedObject; +import org.openehr.rm.common.generic.AuditDetails; +import org.openehr.rm.support.identification.HierObjectID; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.support.identification.ObjectVersionID; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * Version controlled party + * + * @author Rong Chen + * @version 1.0 + */ +public class VersionedParty extends VersionedObject { + + /** + * Constructs a VersionParty with first Party created locally + */ + public VersionedParty(HierObjectID uid, ObjectRef ownerID, + DvDateTime timeCreated, ObjectVersionID versionID, Party party, + DvCodedText lifecycleState, AuditDetails commitAudit, + ObjectRef contribution, String signature, + TerminologyService terminologyService) { + + super(uid, ownerID, timeCreated, versionID, party, lifecycleState, commitAudit, contribution, + signature, terminologyService); + } + + /** + * Constructs a VersionParty with first imported Party + */ + public VersionedParty(HierObjectID uid, ObjectRef ownerID, + DvDateTime timeCreated, OriginalVersion item, + AuditDetails commitAudit, ObjectRef contribution, + String signature) { + + super(uid, ownerID, timeCreated, item, commitAudit, contribution, signature); + + } + + /** + * Constructs a VersionParty with first merged Party + */ + public VersionedParty(HierObjectID uid, ObjectRef ownerID, + DvDateTime timeCreated, ObjectVersionID versionID, + ObjectVersionID precedingVersionID, Party party, DvCodedText lifecycleState, + AuditDetails commitAudit, ObjectRef contribution, + Set otherInputVersionUids, String signature, + TerminologyService terminologyService) { + + super(uid, ownerID, timeCreated, versionID, precedingVersionID, party, lifecycleState, + commitAudit, contribution, otherInputVersionUids, signature, terminologyService); + } + + // POJO start + VersionedParty() { + } + // POJO end +} + +/* + * ***** 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 VersionedParty.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/ehr/EHR.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/EHR.java new file mode 100644 index 00000000..5c3afdaf --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/EHR.java @@ -0,0 +1,245 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class EHR" + * keywords: "ehr" + * + * 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/ehr/EHR.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.ehr; + +import org.openehr.rm.Attribute; +import org.openehr.rm.FullConstructor; +import org.openehr.rm.RMObject; +import org.openehr.rm.support.identification.HierObjectID; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; + +import java.util.List; + +/** + * The EHR class is the centre node of the EHR repository for a + * subject of care. + * + * @author Rong Chen + * @version 1.0 + */ +public class EHR extends RMObject { + + /** + * Constructs an EHR + * + * @param systemID required + * @param ehrID required + * @param timeCreated required + * @param contributions required + * @param ehrStatus required + * @param directory null if not specified + * @param compositions required + * @throws IllegalArgumentException + */ + @FullConstructor public EHR (@Attribute(name = "systemID", required = true) HierObjectID systemID, + @Attribute(name = "ehrID", required=true) HierObjectID ehrID, + @Attribute(name = "timeCreated", required=true) DvDateTime timeCreated, + @Attribute(name = "contributions", required=true) List contributions, + @Attribute(name = "ehrStatus", required = true) ObjectRef ehrStatus, + @Attribute(name = "directory") ObjectRef directory, + @Attribute(name = "compositions", required=true) List compositions) { + + if (systemID == null) { + throw new IllegalArgumentException("null systemID"); + } + if (ehrID == null) { + throw new IllegalArgumentException("null ehrID"); + } + if (timeCreated == null) { + throw new IllegalArgumentException("null timeCreated"); + } + if (contributions == null) { + throw new IllegalArgumentException("null contributions"); + } + for (ObjectRef ref : contributions) { + if (! "CONTRIBUTION".equals(ref.getType())) { + throw new IllegalArgumentException( + "non-contribution type object reference"); + } + } + if (compositions == null) { + throw new IllegalArgumentException("null compositions"); + } + for (ObjectRef ref : compositions) { + if (! "VERSIONED_COMPOSITION".equals( + ref.getType())) { + throw new IllegalArgumentException( + "non-versioned_composition type object reference"); + } + } + if (directory != null && !"VERSIONED_FOLDER".equals( + directory.getType())) { + throw new IllegalArgumentException( + "non-versioned_folder type object reference"); + } + + this.systemID = systemID; + this.ehrID = ehrID; + this.timeCreated = timeCreated; + this.contributions = contributions; + this.ehrStatus = ehrStatus; + this.directory = directory; + this.compositions = compositions; + } + + /** + * The id of this EHR + * + * @return ehrID + */ + public HierObjectID getEhrID() { + return ehrID; + } + + /** + * EHR_STATUS object for this EHR + * + * @return ehrStatus + */ + public ObjectRef getEhrStatus() { + return ehrStatus; + } + + /** + * The id of the EHR system on which this EHR was created + * + * @return systemID + */ + public HierObjectID getSystemID() { + return systemID; + } + + /** + * Time of creation of the repository + * + * @return time of creation + */ + public DvDateTime getTimeCreated() { + return timeCreated; + } + + /** + * List of contributions causing changes to this EHR. Each + * contribution contains a list of versions, which may include + * references to any number of VERSION instances, ie items of + * type VERSIONED_COMPOSITION and DIRECTORY. + * + * @return List of ObjectRef + */ + public List getContributions() { + return contributions; + } + + /** + * Optional directory structure for this EHR. + * + * @return directory + */ + public ObjectRef getDirectory() { + return directory; + } + + /** + * Master list of all composition references in this EHR + * + * @return list of objectReference + */ + public List getCompositions() { + return compositions; + } + + // POJO start + EHR() { + } + + private Long id; + + Long getId() { + return id; + } + + void setId(Long id) { + this.id = id; + } + + void setEhrID(HierObjectID ehrID) { + this.ehrID = ehrID; + } + + void setEhrStatus(ObjectRef ehrStatus) { + this.ehrStatus = ehrStatus; + } + + void setSystemID(HierObjectID systemID) { + this.systemID = systemID; + } + + void setTimeCreated(DvDateTime timeCreated) { + this.timeCreated = timeCreated; + } + + void setContributions(List contributions) { + this.contributions = contributions; + } + + void setDirectory(ObjectRef directory) { + this.directory = directory; + } + + void setCompositions(List compositions) { + this.compositions = compositions; + } + // POJO end + + /* fields */ + HierObjectID systemID; + HierObjectID ehrID; + DvDateTime timeCreated; + List contributions; + ObjectRef ehrStatus; + ObjectRef directory; + List compositions; +} + +/* + * ***** 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 EHR.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Erik Sundvall + * + * 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/ehr/EHRAccess.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/EHRAccess.java new file mode 100644 index 00000000..324536ee --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/EHRAccess.java @@ -0,0 +1,164 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class EHRAccess" + * keywords: "ehr" + * + * 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/ehr/EHRAccess.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.ehr; + +import java.util.List; +import java.util.Set; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.openehr.rm.Attribute; +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.datatypes.text.DvText; +import org.openehr.rm.security.AccessControlSettings; +import org.openehr.rm.support.identification.UIDBasedID; + +/** + * EHR-wide access control object. All access decisions to data in the EHR must be made + * in accordance with the policies and rules in this object. + * + * @author Yin Su Lim + * @version 1.0 + */ +public class EHRAccess extends Locatable { + + /** Creates a new instance of EHRAccess */ + public EHRAccess( + @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 = "settings") AccessControlSettings settings) { + + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, parent); + if(settings == null) { + throw new IllegalArgumentException("null settings"); + } + this.settings = settings; + } + + /** + * The name of the access control scheme in use; corresponds to the concrete instance + * of the settings attribute. + */ + public String scheme() { + return ""; //TODO: implement here or in AccessContolSettings + } + + /** + * Access control settings for the EHR. Instance is a subtype of the type + * AccessControlSettings, allowing for the use of different access control schemes. + */ + public AccessControlSettings getSettings() { + return settings; + } + + public String pathOfItem(Locatable item) { + return ""; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof EHRAccess)) return false; + if (!super.equals(o)) return false; + + final EHRAccess ehrA = (EHRAccess) o; + return new EqualsBuilder() + .append(settings, ehrA.settings) + .isEquals(); + } + + /** + * Return a hash code of this actor + * + * @return hash code + */ + public int hashCode() { + return new HashCodeBuilder(19, 83) + .appendSuper(super.hashCode()) + .append(settings) + .toHashCode(); + } + + @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 + EHRAccess() {} + + void setSettings(AccessControlSettings settings) { + this.settings = settings; + } + + /* private fields */ + private AccessControlSettings settings; +} + +/* + * ***** 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 EHRAccess.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/ehr/EHRStatus.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/EHRStatus.java new file mode 100644 index 00000000..6bff253b --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/EHRStatus.java @@ -0,0 +1,206 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class EHRStatus" + * keywords: "ehr" + * + * 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/ehr/EHRStatus.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.ehr; + +import java.util.List; +import java.util.Set; +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.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.PartySelf; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.identification.UIDBasedID; + +/** + * Single object per EHR giving various EHR-wide information. + * + * @author Yin Su Lim + * @version 1.0 + */ +public class EHRStatus extends Locatable { + + @FullConstructor public EHRStatus( + @Attribute(name = "uid", required = true) 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 = "subject", system = true) PartySelf subject, + @Attribute(name = "isQueryable", required = true) boolean isQueryable, + @Attribute(name = "isModifiable", required = true) boolean isModifiable, + @Attribute(name = "otherDetails") ItemStructure otherDetails ) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, parent); + if (subject == null) { + throw new IllegalArgumentException("null subject"); + } + if (parent != null) { + throw new IllegalArgumentException("parent must be null"); + } + if (!isArchetypeRoot()) { + throw new IllegalArgumentException("not archetype root"); + } + this.subject = subject; + this.isQueryable = isQueryable; + this.isModifiable = isModifiable; + this.otherDetails = otherDetails; + } + + /** + * The subject of this EHR. The externalRef attribute can be used to contain a direct + * reference to the subject in a demographic or identity service. Alternatively, the + * association between patients and their records may be done elsewhere for security + * reasons. + */ + public PartySelf getSubject() { + return subject; + } + + /** + * True if this EHR should be included in population queries, i.e. if this EHR + * is considered active in the population. + */ + public boolean getIsQueryable() { + return isQueryable; + } + + /** + * True if this EHR is allowed to be written to. + */ + public boolean getIsModifiable() { + return isModifiable; + } + + /** + * Any other details of the EHR summary object, in the form of an archetyped itemStructure. + */ + public ItemStructure getOtherDetails() { + return otherDetails; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!( o instanceof EHRStatus )) return false; + if (!super.equals(o)) return false; + + final EHRStatus ehrS = (EHRStatus) o; + + return new EqualsBuilder() + .append(subject, ehrS.subject) + .append(isQueryable, ehrS.isQueryable) + .append(isModifiable, ehrS.isModifiable) + .append(otherDetails, ehrS.otherDetails) + .isEquals(); + } + + public int hashCode() { + return new HashCodeBuilder(79, 19) + .appendSuper(super.hashCode()) + .append(subject) + .append(isQueryable) + .append(isModifiable) + .append(otherDetails) + .toHashCode(); + } + + @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 + void setSubject(PartySelf subject) { + this.subject = subject; + } + + void setIsQueryable(boolean isQueryable) { + this.isQueryable = isQueryable; + } + + void setIsModifiable(boolean isModifiable) { + this.isModifiable = isModifiable; + } + + void setOtherDetails(ItemStructure otherDetails) { + this.otherDetails = otherDetails; + } + + EHRStatus() {} + + /* fields */ + private PartySelf subject; + private boolean isQueryable; + private boolean isModifiable; + private ItemStructure otherDetails; + +} + +/* + * ***** 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 EHRStatus.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/ehr/VersionedComposition.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/VersionedComposition.java new file mode 100644 index 00000000..0f771181 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/VersionedComposition.java @@ -0,0 +1,172 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class VersionedComposition" + * keywords: "ehr" + * + * 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/ehr/VersionedComposition.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.ehr; + +import java.util.Set; + +import org.openehr.rm.common.changecontrol.OriginalVersion; +import org.openehr.rm.common.changecontrol.VersionedObject; +import org.openehr.rm.common.generic.AuditDetails; +import org.openehr.rm.support.identification.HierObjectID; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.support.identification.ObjectVersionID; +import org.openehr.rm.composition.Composition; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * Version-controlled composition abstraction, defined by inheriting + * VERSION_OBJECT. + * + * @author Rong Chen + * @version 1.0 + */ +public class VersionedComposition extends VersionedObject { + + /** + * Constructs a VersionComposition with first Composition created locally + */ + public VersionedComposition(HierObjectID uid, ObjectRef ownerID, + DvDateTime timeCreated, ObjectVersionID versionID, Composition composition, + DvCodedText lifecycleState, AuditDetails commitAudit, + ObjectRef contribution, String signature, + TerminologyService terminologyService) { + + super(uid, ownerIDCheck(ownerID), timeCreated, versionID, composition, lifecycleState, + commitAudit, contribution, signature, terminologyService); + } + + /** + * Constructs a VersionComposition with first imported Composition + */ + public VersionedComposition(HierObjectID uid, ObjectRef ownerID, + DvDateTime timeCreated, OriginalVersion item, + AuditDetails commitAudit, ObjectRef contribution, String signature) { + super(uid, ownerIDCheck(ownerID), timeCreated, item, commitAudit, contribution, signature); + + } + + /** + * Constructs a VersionComposition with first merged Composition + */ + public VersionedComposition(HierObjectID uid, ObjectRef ownerID, + DvDateTime timeCreated, ObjectVersionID versionID, + ObjectVersionID precedingVersionID, Composition composition, + DvCodedText lifecycleState, AuditDetails commitAudit, + ObjectRef contribution, Set otherInputVersionUids, + String signature, TerminologyService terminologyService) { + + super(uid, ownerIDCheck(ownerID), timeCreated, versionID, precedingVersionID, composition, + lifecycleState, commitAudit, contribution, otherInputVersionUids, signature, + terminologyService); + } + + public boolean isPersistent() { + Composition firstData = (Composition) allVersions().get(0).getData(); + return firstData.isPersistent(); + } + + public synchronized void commitImportedVersion(OriginalVersion item, + AuditDetails commitAudit, ObjectRef contribution, String signature) { + + checkAgainstFirstData(item.getData()); + super.commitImportedVersion(item, commitAudit, contribution, signature); + } + + public synchronized void commitOriginalMergedVersion(ObjectVersionID versionID, + ObjectVersionID precedingVersionID, Composition data, DvCodedText lifecycleState, + AuditDetails commitAudit, ObjectRef contribution, + Set otherInputVersionUids, String signature, + TerminologyService terminologyService) { + + checkAgainstFirstData(data); + super.commitOriginalMergedVersion(versionID, precedingVersionID, data, lifecycleState, + commitAudit, contribution, otherInputVersionUids, signature, terminologyService); + + } + + public synchronized void commitOriginalVersion(ObjectVersionID versionID, + ObjectVersionID precedingVersionID, Composition data, AuditDetails commitAudit, + ObjectRef contribution, DvCodedText lifecycleState, String signature, + TerminologyService terminologyService) { + + checkAgainstFirstData(data); + super.commitOriginalVersion(versionID, precedingVersionID, data, commitAudit, contribution, + lifecycleState, signature, terminologyService); + } + + protected void checkAgainstFirstData(Composition data) { + /*if(versionCount() == 0) { + firstArchetypeNodeID = data.getArchetypeNodeId(); + } else { + if(!data.getArchetypeNodeId().equals(firstArchetypeNodeID)) { + throw new IllegalArgumentException("different archetypedNodeID"); + } + }*/ + if(versionCount() > 0) { + Composition firstData = (Composition) allVersions().get(0).getData(); + if(! data.getArchetypeNodeId().equals(firstData.getArchetypeNodeId())) { + throw new IllegalArgumentException("different archetypedNodeID"); + } + if( data.isPersistent() != firstData.isPersistent()) { + throw new IllegalArgumentException("different persistent state"); + } + } + } + + protected static ObjectRef ownerIDCheck(ObjectRef ownerID) { + if(!ownerID.getType().equals("EHR")) { + throw new IllegalArgumentException("type of ownerID is not EHR"); + } + return ownerID; + } + + // POJO start + VersionedComposition() { + } + // POJO end + +} + +/* + * ***** 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 VersionedComposition.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/main/java/org/openehr/rm/ehr/VersionedEHRAccess.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/VersionedEHRAccess.java new file mode 100644 index 00000000..3d9c7a38 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/VersionedEHRAccess.java @@ -0,0 +1,108 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class VersionedEHRAccess" + * keywords: "ehr" + * + * 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/ehr/VersionedEHRAccess.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.ehr; + +import java.util.Set; +import org.openehr.rm.common.changecontrol.OriginalVersion; +import org.openehr.rm.common.changecontrol.VersionedObject; +import org.openehr.rm.common.generic.AuditDetails; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.support.identification.HierObjectID; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.support.identification.ObjectVersionID; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * Version container for EHRAcess instance. + * + * @author Yin Su Lim + * @version 1.0 + */ +public class VersionedEHRAccess extends VersionedObject { + + /** Creates a new instance of VersionedEHRAccess */ + VersionedEHRAccess() { + } + + + /** + * Constructs a VersionEHRAccess with first EHRAccess created locally + */ + public VersionedEHRAccess(HierObjectID uid, ObjectRef ownerID, + DvDateTime timeCreated, ObjectVersionID versionID, EHRAccess ehrAccess, + DvCodedText lifecycleState, AuditDetails commitAudit, + ObjectRef contribution, String signature, + TerminologyService terminologyService) { + + super(uid, ownerID, timeCreated, versionID, ehrAccess, lifecycleState, + commitAudit, contribution, signature, terminologyService); + } + + /** + * Constructs a VersionEHRAccess with first imported EHRAccess + */ + public VersionedEHRAccess(HierObjectID uid, ObjectRef ownerID, + DvDateTime timeCreated, OriginalVersion item, + AuditDetails commitAudit, ObjectRef contribution, String signature) { + super(uid, ownerID, timeCreated, item, commitAudit, contribution, signature); + + } + + /** + * Constructs a VersionEHRAccess with first merged EHRAccess + */ + public VersionedEHRAccess(HierObjectID uid, ObjectRef ownerID, + DvDateTime timeCreated, ObjectVersionID versionID, + ObjectVersionID precedingVersionID, EHRAccess ehrAccess, + DvCodedText lifecycleState, AuditDetails commitAudit, + ObjectRef contribution, Set otherInputVersionUids, + String signature, TerminologyService terminologyService) { + + super(uid, ownerID, timeCreated, versionID, precedingVersionID, ehrAccess, + lifecycleState, commitAudit, contribution, otherInputVersionUids, signature, + terminologyService); + } +} + +/* + * ***** 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 VersionedEHRAccess.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/ehr/VersionedEHRStatus.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/VersionedEHRStatus.java new file mode 100644 index 00000000..9c1491f7 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/ehr/VersionedEHRStatus.java @@ -0,0 +1,109 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class VersionedEHRStatus" + * keywords: "ehr" + * + * 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/ehr/VersionedEHRStatus.java $" + * revision: "$LastChangedRevision: 53 $" + * last_change: "$LastChangedDate: 2006-08-11 13:20:08 +0100 (Fri, 11 Aug 2006) $" + */ +package org.openehr.rm.ehr; + +import java.util.Set; + +import org.openehr.rm.common.changecontrol.OriginalVersion; +import org.openehr.rm.common.changecontrol.VersionedObject; +import org.openehr.rm.common.generic.AuditDetails; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.support.identification.HierObjectID; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.support.identification.ObjectVersionID; +import org.openehr.rm.support.terminology.TerminologyService; + +/** + * Versioning container for EHRStatus instance + * + * @author Yin Su Lim + * @version 1.0 + */ +public class VersionedEHRStatus extends VersionedObject { + + /** + * Constructs a VersionEHRStatus with first EHRStatus created locally + */ + public VersionedEHRStatus(HierObjectID uid, ObjectRef ownerID, + DvDateTime timeCreated, ObjectVersionID versionID, EHRStatus ehrStatus, + DvCodedText lifecycleState, AuditDetails commitAudit, + ObjectRef contribution, String signature, + TerminologyService terminologyService) { + + super(uid, ownerID, timeCreated, versionID, ehrStatus, lifecycleState, commitAudit, + contribution, signature, terminologyService); + } + + /** + * Constructs a VersionEHRStatus with first imported EHRStatus + */ + public VersionedEHRStatus(HierObjectID uid, ObjectRef ownerID, + DvDateTime timeCreated, OriginalVersion item, + AuditDetails commitAudit, ObjectRef contribution, + String signature) { + super(uid, ownerID, timeCreated, item, commitAudit, contribution, signature); + + } + + /** + * Constructs a VersionEHRStatus with first merged EHRStatus + */ + public VersionedEHRStatus(HierObjectID uid, ObjectRef ownerID, + DvDateTime timeCreated, ObjectVersionID versionID, + ObjectVersionID precedingVersionID, EHRStatus ehrStatus, DvCodedText lifecycleState, + AuditDetails commitAudit, ObjectRef contribution, + Set otherInputVersionUids, String signature, + TerminologyService terminologyService) { + + super(uid, ownerID, timeCreated, versionID, precedingVersionID, ehrStatus, lifecycleState, + commitAudit, contribution, otherInputVersionUids, signature, terminologyService); + } + + //POJO start + VersionedEHRStatus() { + } + +} + +/* + * ***** 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 VersionedEHRStatus.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 ***** + */ 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 new file mode 100644 index 00000000..f596a2e3 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/EHRExtract.java @@ -0,0 +1,153 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class EHRExtract" + * keywords: "ehr_extract" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004,2005 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL: http://svn.openehr.org/ref_impl_java/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/ehrextract/EHRExtract.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.ehrextract; + +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.support.identification.PartyRef; +import org.openehr.rm.common.generic.Participation; + +import java.util.Set; + +/** + * The outer package for information extracted from an EHR by another + * EHR system. + * + * @author Rong Chen + * @version 1.0 + */ +public class EHRExtract { + + /** + * Constructs an EHRExtract + * + * @param timeCreated + * @param ehrId + * @param subjectOfCare + * @param originator + * @param otherParticipations + * @param includeMultimedia + * @param followLinks + * @param directory + * @param terminology + * @param demographics + * @param accessControl + * @throws IllegalArgumentException + */ + public EHRExtract(DvDateTime timeCreated, String ehrId, + PartyRef subjectOfCare, PartyRef originator, + Set otherParticipations, + boolean includeMultimedia, int followLinks, + XFolder directory, XTerminology terminology, + XDemographics demographics, XAccessControl accessControl) { + this.timeCreated = timeCreated; + this.ehrId = ehrId; + this.subjectOfCare = subjectOfCare; + this.originator = originator; + this.otherParticipations = otherParticipations; + this.includeMultimedia = includeMultimedia; + this.followLinks = followLinks; + this.directory = directory; + this.terminology = terminology; + this.demographics = demographics; + this.accessControl = accessControl; + } + + public DvDateTime getTimeCreated() { + return timeCreated; + } + + public String getEhrId() { + return ehrId; + } + + public PartyRef getSubjectOfCare() { + return subjectOfCare; + } + + public PartyRef getOriginator() { + return originator; + } + + public Set getOtherParticipations() { + return otherParticipations; + } + + public boolean isIncludeMultimedia() { + return includeMultimedia; + } + + public int getFollowLinks() { + return followLinks; + } + + public XFolder getDirectory() { + return directory; + } + + public XTerminology getTerminology() { + return terminology; + } + + public XDemographics getDemographics() { + return demographics; + } + + public XAccessControl getAccessControl() { + return accessControl; + } + + /* fields */ + private DvDateTime timeCreated; + private String ehrId; + private PartyRef subjectOfCare; + private PartyRef originator; + private Set otherParticipations; + private boolean includeMultimedia; + private int followLinks; + private XFolder directory; + private XTerminology terminology; + private XDemographics demographics; + private XAccessControl accessControl; +} + +/* + * ***** 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 EHRExtract.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 ***** + */ 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 new file mode 100644 index 00000000..cf58c892 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XAccessControl.java @@ -0,0 +1,105 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class XAccessControl" + * keywords: "ehr_extract" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004,2005 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL: http://svn.openehr.org/ref_impl_java/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/ehrextract/XAccessControl.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.ehrextract; + +import org.openehr.rm.support.identification.ObjectID; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; + +import java.util.Map; + +/** + * Container class for all access control data required in an EHR Extract. + * The list of Access groups must be supplied except in the case when an EHR + * extract is sent within the one environment, and the receiver system has + * access to the same access control server as the sender. + * + * @author Rong Chen + * @version 1.0 + */ +public class XAccessControl { + + /** + * Constructs a XAccessControl + * + * @param groups null if unspecified, not empty + * @param details null if unspecified + * @throws IllegalArgumentException if groups empty + */ + public XAccessControl(Map groups, + ItemStructure details) { + if(groups != null && groups.isEmpty()) { + throw new IllegalArgumentException("empty groups"); + } + this.groups = groups; + this.details = details; + } + + /** + * Other access control details + * + * @return details or null if unspecified + */ + public ItemStructure getDetails() { + return details; + } + + /** + * Obtain the access group for the given key + * + * @param key + * @return null if groups unspecified or group not found for given key + */ + // todo: return type should be AccessGroup + public Object group(ObjectID key) { + if(groups == null) { + return null; + } + return groups.get(key); + } + + /* fields */ + private Map groups; // todo: value should be AccessGroup + private ItemStructure details; +} + +/* + * ***** 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 XAccessControl.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/ehrextract/XComposition.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XComposition.java new file mode 100644 index 00000000..b774c7f8 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XComposition.java @@ -0,0 +1,114 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class XComposition" + * keywords: "ehr_extract" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004,2005 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL: http://svn.openehr.org/ref_impl_java/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/ehrextract/XComposition.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.ehrextract; + +import org.openehr.rm.datatypes.uri.DvEHRURI; +import org.openehr.rm.ehr.VersionedComposition; + +/** + * Container for Composition in extract. Indicates whether it was part of the + * primary set and what it s original path was. + * + * @author Rong Chen + * @version 1.0 + */ +public class XComposition { + + /** + * Constructs a XComposition + * + * @param primary + * @param originalPath not null + * @param composition not null + * @throws IllegalArgumentException if originalPath null + * or composition null + */ + public XComposition(boolean primary, DvEHRURI originalPath, + VersionedComposition composition) { + if(originalPath == null) { + throw new IllegalArgumentException("null originalPath"); + } + if(composition == null) { + throw new IllegalArgumentException("null composition"); + } + this.primary = primary; + this.originalPath = originalPath; + this.composition = composition; + } + + /** + * True if the Composition in this container was part of the primary set + * for the Extract , ie not added due to link-following + * + * @return primary + */ + public boolean isPrimary() { + return primary; + } + + /** + * The original path of the Composition in the source EHR, used for + * matching compositions in the receiver's EHR. + * + * @return originalPath + */ + public DvEHRURI getOriginalPath() { + return originalPath; + } + + /** + * The composition content + * + * @return composition + */ + public VersionedComposition getComposition() { + return composition; + } + + /* fields */ + private boolean primary; + private DvEHRURI originalPath; + private VersionedComposition composition; +} + +/* + * ***** 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 XComposition.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/ehrextract/XDemographics.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XDemographics.java new file mode 100644 index 00000000..e853e7dc --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XDemographics.java @@ -0,0 +1,104 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class XDemographics" + * keywords: "ehr_extract" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004,2005 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL: http://svn.openehr.org/ref_impl_java/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/ehrextract/XDemographics.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.ehrextract; + +import org.openehr.rm.support.identification.ObjectID; +import org.openehr.rm.demographic.Party; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; + +import java.util.Map; + +/** + * Purpose Container class for all demograhic data required in an EHR Extract. + * The list of Parties must be supplied except in the case when an EHR extract + * is sent within the one environment, and the receiver system has access to + * the same demographic server as the sender. + * + * @author Rong Chen + * @version 1.0 + */ +public class XDemographics { + + /** + * Constructs a XDemographics + * + * @param parties null if unspecified + * @param details null if unspecified + * @throws IllegalArgumentException if parties empty + */ + public XDemographics(Map parties, ItemStructure details) { + if(parties != null && parties.isEmpty()) { + throw new IllegalArgumentException("empty paries"); + } + this.parties = parties; + this.details = details; + } + + /** + * Other demographic details + * + * @return details or null if unspecified + */ + public ItemStructure getDetails() { + return details; + } + + /** + * Obtain the party for the given key + * + * @param key + * @return null if parties unspecified or party not found for given key + */ + public Party party(ObjectID key) { + if(parties == null) { + return null; + } + return parties.get(key); + } + + /* fields */ + private Map parties; + private ItemStructure details; +} + +/* + * ***** 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 XDemographics.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/ehrextract/XFolder.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XFolder.java new file mode 100644 index 00000000..c0b89bd6 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XFolder.java @@ -0,0 +1,155 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class XFolder" + * keywords: "ehr_extract" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004,2005 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL: http://svn.openehr.org/ref_impl_java/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/ehrextract/XFolder.java $" + * revision: "$LastChangedRevision: 30 $" + * last_change: "$LastChangedDate: 2006-04-30 00:15:58 +0200 (Sun, 30 Apr 2006) $" + */ +package org.openehr.rm.ehrextract; + +import org.openehr.rm.common.archetyped.Locatable; +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.datatypes.text.DvText; + +import java.util.List; +import java.util.Set; + +/** + * XFolder + * + * @author Rong Chen + * @version 1.0 + */ +public class XFolder extends Locatable { + + /** + * Constructs a Locatable + * + * @param uid null if not specified + * @param archetypeNodeId not null + * @param name not null + * @param archetypeDetails null if not specified + * @param feederAudit null if not specified + * @param links null if not specified + * @param folders null if not specified, not empty + * @param compositions null if not specified, not empty + * @throws IllegalArgumentException if name null or archetypeNodeId null + * or links not null and empty + * or empty folders or empty compositions + */ + public XFolder(UIDBasedID uid, String archetypeNodeId, DvText name, + Archetyped archetypeDetails, FeederAudit feederAudit, + Set links, Pathable parent, List folders, + List compositions) { + + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, parent); + + if (folders != null && folders.isEmpty()) { + throw new IllegalArgumentException("empty folders"); + } + if (compositions != null && compositions.isEmpty()) { + throw new IllegalArgumentException("empty compositions"); + } + this.folders = folders; + this.compositions = compositions; + } + + /** + * 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 + } + + /** + * sub-folders of this folder, including distinct Folder trees, + * which may be separately archetyped. + * + * @return folders or null if unspecified + */ + public List getFolders() { + return folders; + } + + /** + * X_COMPOSITIONs in this folder + * + * @return compositions or null if unspecified + */ + public List getCompositions() { + return compositions; + } + + @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; + } + + /* fields */ + private List folders; + private List compositions; +} + +/* + * ***** 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 XFolder.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/ehrextract/XTerminology.java b/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XTerminology.java new file mode 100644 index 00000000..f66bdbeb --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/ehrextract/XTerminology.java @@ -0,0 +1,78 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class XTerminology" + * keywords: "ehr_extract" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004,2005 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL: http://svn.openehr.org/ref_impl_java/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/ehrextract/XTerminology.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.ehrextract; + +import org.openehr.rm.datastructure.itemstructure.ItemStructure; + +/** + * Container class for all terminology data required in an EHR Extract + * + * @author Rong Chen + * @version 1.0 + */ +public class XTerminology { + + /** + * Constructs a XTerminology + * + * @param details + */ + public XTerminology(ItemStructure details) { + this.details = details; + } + + /** + * Terminological details + * + * @return details + */ + public ItemStructure getDetails() { + return details; + } + + /* fields */ + private ItemStructure details; + +} + +/* + * ***** 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 XTerminology.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/integration/GenericEntry.java b/openehr-rm-domain/src/main/java/org/openehr/rm/integration/GenericEntry.java new file mode 100644 index 00000000..87b2c1a3 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/integration/GenericEntry.java @@ -0,0 +1,150 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ContentItem" + * keywords: "unit test" + * + * author: "Rong Chen " + * support: "openEHR Java project, http://www.openehr.org/projects/java.html" + * 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.rm.integration; + +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.composition.content.ContentItem; +import org.openehr.rm.datastructure.itemstructure.ItemTree; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.identification.UIDBasedID; + +/** + * This class is used to create intermediate representations of data from + * sources not otherwise conforming to openEHR classes, such as HL7 messages, + * relational databases and so on. + */ +public final class GenericEntry extends ContentItem { + + /** + * Constructs a GenericEntry + * + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @param data + */ + @FullConstructor + public GenericEntry( + @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 = "data", required = true) ItemTree data) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, + parent); + this.data = data; + } + + /** + * Constructs a GenericEntry with only required fields + * + * @param archetypeNodeId + * @param name + * @param data + */ + public GenericEntry(String archetypeNodeId, DvText name, ItemTree data) { + this(null, archetypeNodeId, name, null, null, null, null, data); + } + + /** + * Convenient constructor to create a GenericEntry with only required fields + * + * @param archetypeNodeId + * @param name in string + * @param data + */ + public GenericEntry(String archetypeNodeId, String name, ItemTree data) { + this(archetypeNodeId, new DvText(name), data); + } + + /** + * The data from the source message or record. + * + * @return data + */ + public ItemTree getData() { + return data; + } + + @Override + public String pathOfItem(Pathable item) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List itemsAtPath(String path) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean pathExists(String path) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean pathUnique(String path) { + // TODO Auto-generated method stub + return false; + } + + private final ItemTree data; +} +/* + * ***** 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 GenericEntry.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): + * + * 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/message/Message.java b/openehr-rm-domain/src/main/java/org/openehr/rm/message/Message.java new file mode 100644 index 00000000..db319f8f --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/message/Message.java @@ -0,0 +1,255 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class Message" + * keywords: "message" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004,2005 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL: http://svn.openehr.org/ref_impl_java/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/message/Message.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.message; + +import org.openehr.rm.RMObject; +import org.openehr.rm.demographic.Party; +import org.openehr.rm.common.generic.Attestation; +import org.openehr.rm.support.identification.PartyRef; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.quantity.DvOrdinal; +import org.apache.commons.lang.StringUtils; + +import java.util.Set; + +/** + * The message envelope for an extract, indicating the sender and receiver + * details, time and any other details required. + * + * @author Rong Chen + * @version 1.0 + */ +public class Message extends RMObject { + + /** + * Enumeration of Initiator of message + */ + public enum Initiator { + SENDER, RECEIVER + }; + + /** + * Constructs a Message + * + * @param timeSent + * @param sender + * @param receiver + * @param senderNode + * @param receiverNode + * @param sendersReference + * @param initiator + * @param urgency + * @param signature + * @param parties + * @param content + * @throws IllegalArgumentException + */ + public Message(DvDateTime timeSent, PartyRef sender, + PartyRef receiver, PartyRef senderNode, + PartyRef receiverNode, String sendersReference, + Initiator initiator, DvOrdinal urgency, + Attestation signature, Set parties, + MessageContent content) { + if (timeSent == null) { + throw new IllegalArgumentException("timeSent null"); + } + if (sender == null) { + throw new IllegalArgumentException("sender null"); + } + if (receiver == null) { + throw new IllegalArgumentException("receiver null"); + } + if (StringUtils.isEmpty(sendersReference)) { + throw new IllegalArgumentException( + "null or empty sendersReference"); + } + if (senderNode == null) { + throw new IllegalArgumentException("senderNode null"); + } + if (receiverNode == null) { + throw new IllegalArgumentException("receiverNode null"); + } + if (initiator == null) { + throw new IllegalArgumentException("initiator null"); + } + + if (urgency == null) { + throw new IllegalArgumentException("urgency null"); + } + if (parties != null && parties.isEmpty()) { + throw new IllegalArgumentException("empty parties"); + } + if (content == null) { + throw new IllegalArgumentException("content null"); + } + this.timeSent = timeSent; + this.sender = sender; + this.receiver = receiver; + this.senderNode = senderNode; + this.receiverNode = receiverNode; + this.sendersReference = sendersReference; + this.initiator = initiator; + this.urgency = urgency; + this.signature = signature; + this.parties = parties; + this.content = content; + } + + /** + * Date/time the message was sent. + * + * @return timeSent + */ + public DvDateTime getTimeSent() { + return timeSent; + } + + /** + * Party sending the extract. + * + * @return sender + */ + public PartyRef getSender() { + return sender; + } + + /** + * Party the extract is sent to. + * + * @return receiver + */ + public PartyRef getReceiver() { + return receiver; + } + + /** + * EHR node from which the message is sent. + * + * @return senderNode + */ + public PartyRef getSenderNode() { + return senderNode; + } + + /** + * EHR node receiving the message. + * + * @return receiverNode + */ + public PartyRef getReceiverNode() { + return receiverNode; + } + + /** + * Identification of message at sender s end. + * + * @return sendersReference + */ + public String getSendersReference() { + return sendersReference; + } + + /** + * Indicates which party - sender or receiver caused the message to be + * created and sent. If the receiver,there was an EHR_REQUEST. + * If the sender, there is no request, and the extract is being sent + * unsolicited. + * + * @return initiator of this message + */ + public Initiator getInitiator() { + return initiator; + } + + /** + * Urgency with which receiver should deal with message + * + * @return urgency + */ + public DvOrdinal getUrgency() { + return urgency; + } + + /** + * Signature of message content. + * + * @return signature + */ + public Attestation getSignature() { + return signature; + } + + /** + * Parties referred to by all PARTY_REF and ATTESTATION instances in this + * message instance. + * + * @return parties + */ + public Set getParties() { + return parties; + } + + /** + * The content of the message + * + * @return content + */ + public MessageContent getContent() { + return content; + } + + /* fields */ + private DvDateTime timeSent; + private PartyRef sender; + private PartyRef receiver; + private PartyRef senderNode; + private PartyRef receiverNode; + private String sendersReference; + private Initiator initiator; + private DvOrdinal urgency; + private Attestation signature; + private Set parties; + private MessageContent content; +} + +/* + * ***** 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 Message.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 ***** + */ 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 new file mode 100644 index 00000000..3046c1c5 --- /dev/null +++ b/openehr-rm-domain/src/main/java/org/openehr/rm/message/MessageContent.java @@ -0,0 +1,62 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class MessageContent" + * keywords: "message" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004,2005 Acode HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL: http://svn.openehr.org/ref_impl_java/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/message/MessageContent.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.message; + +import org.openehr.rm.common.archetyped.Locatable; + +/** + * Abstract supertype for any message content. + * + * @author Rong Chen + * @version 1.0 + */ +public abstract class MessageContent extends Locatable { + + /** + * Constructor + */ + protected MessageContent() { + } +} + +/* + * ***** 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 MessageContent.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/test/java/org/openehr/rm/composition/CompositionTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/CompositionTest.java new file mode 100644 index 00000000..8cec17e3 --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/CompositionTest.java @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2004 Rong Chen, Acode HB, Sweden + * All rights reserved. + * + * The contents of this software are subject to the FSF GNU Public License 2.0; + * you may not use this software except in compliance with the License. You may + * obtain a copy of the License at http://www.fsf.org/licenses/gpl.html + * + * 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. + */ +package org.openehr.rm.composition; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.openehr.rm.common.archetyped.Archetyped; +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.ArchetypeID; +import org.openehr.rm.support.identification.HierObjectID; +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.support.terminology.CodeSetAccess; +import org.openehr.rm.support.terminology.OpenEHRCodeSetIdentifiers; +import org.openehr.rm.support.terminology.TerminologyAccess; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.rm.support.terminology.TestCodeSetAccess; +import org.openehr.rm.support.terminology.TestTerminologyAccess; +import org.openehr.terminology.SimpleTerminologyService; + +/** + * CompositionTest + * + * @author Rong Chen + * @version 1.0 + */ +public class CompositionTest extends CompositionTestBase { + + public CompositionTest(String test) { + super(test); + } + + public void setUp() throws Exception { + DvText name = new DvText("composition"); + UIDBasedID id = new HierObjectID("1.11.2.3.4.5.0"); + List content = new ArrayList(); + content.add(section("section one")); + content.add(section("section two", "observation")); + DvCodedText category = TestCodeSetAccess.EVENT; + Archetyped archetypeDetails = new Archetyped(new ArchetypeID( + "openehr-ehr_rm-Composition.physical_examination.v2"), "1.0"); + + composition = new Composition(id, "at0001", name, archetypeDetails, null, + null, null, content, TestTerminologyAccess.ENGLISH, context(), provider(), + category, territory(), ts); + + } + + public void tearDown() throws Exception { + composition = null; + } + + /** + * Verifies that a bug related to territory checking is fixed + * + * @throws Exception + */ + public void testTerritoryCheckInConstructor() throws Exception { + + /** + * Mock terminology service designed to test checking of territory + */ + TerminologyService tsLocal = new TerminologyService () { + + /** + * Returns a Terminology of given name + * + * @param name not empty and known to this service + * @return terminology + * @throws IllegalArgumentException if name null, empty + * or unknown to this terminology service + */ + public TerminologyAccess terminology(String name) { + + if( ! TerminologyService.OPENEHR.equals(name)) { + return null; + } + + return new TerminologyAccess() { + + public Set codesForGroupID(String groupID) { + return null; + } + + public Set codesForGroupName(String name, String language) { + return null; + } + + public String rubricForCode(String code, String language) { + return null; + } + + public boolean hasCodeForGroupName(CodePhrase code, String name, + String language) { + if("composition category".equals(name) && "en".equals(language)) { + return true; + } + return false; + } + + public String id() { + return null; // todo: implement this method + } + + public Set allCodes() { + return null; // todo: implement this method + } + + public boolean has(CodePhrase code) { + return false; // todo: implement this method + } + + public Set codesForGroupId(String arg0) { + return null; + } + + public boolean hasCodeForGroupId(String arg0, + CodePhrase arg1) { + return true; + } + }; + } + + /** + * Returns a CodeSet of given name + * + * @param name not empty and known to this service + * @return codeSet + * @throws IllegalArgumentException if name is null, empty + * or unknown to this terminology service + */ + public CodeSetAccess codeSet(String name) { + + if( ! "countries".equals(name)) { + return null; + } + + return new CodeSetAccess() { + public String id() { + return null; + } + + public Set allCodes() { + return null; + } + + public boolean hasLang(CodePhrase code) { + return true; + } + + public boolean hasCode(CodePhrase code) { + return true; + } + }; + } + + /** + * Returns ture if terminology of given name known by this service + * + * @param name not empty + * @return true if has given terminology + * @throws IllegalArgumentException if name is null or empty + */ + public boolean hasTerminology(String name) { + return false; + } + + /** + * Returns true if code set of given name known by this service + * + * @param name not empty + * @return true if has given codeset + * @throws IllegalArgumentException if name is null or empty + */ + public boolean hasCodeSet(String name) { + return false; + } + + public List terminologyIdentifiers() { + // TODO Auto-generated method stub + return null; + } + + public List codeSetIdentifiers() { + // TODO Auto-generated method stub + return null; + } + + public Map openehrCodeSets() { + // TODO Auto-generated method stub + return null; + } + + public CodeSetAccess codeSetForId(OpenEHRCodeSetIdentifiers arg0) { + return new TestCodeSetAccess(); + } + }; + DvText name = new DvText("composition"); + UIDBasedID id = new HierObjectID("1.11.2.4.22.5.2"); + List content = new ArrayList(); + content.add(section("section one")); + content.add(section("section two", "observation")); + DvCodedText category = TestCodeSetAccess.EVENT; + Archetyped archetypeDetails = new Archetyped(new ArchetypeID( + "openehr-ehr_rm-Composition.physical_examination.v2"), "1.0"); + composition = new Composition(id, "at0001", name, archetypeDetails, + null, null, null, content, TestTerminologyAccess.ENGLISH, context(), + provider(), category, territory(), ts); + } + + public void testBuildCompositionWithOpenEHRTerminology() throws Exception { + DvText name = new DvText("composition2"); + UIDBasedID id = new HierObjectID("1.11.2.4.22.5.3"); + List content = new ArrayList(); + content.add(section("section one")); + + TerminologyService ts = SimpleTerminologyService.getInstance(); + CodePhrase lang = new CodePhrase("ISO_639-1", "en"); + CodePhrase charset = new CodePhrase("IANA_character-sets", "UTF-8"); + CodePhrase event = new CodePhrase("openehr", "433"); + DvCodedText category = new DvCodedText("event", lang, charset, event, + ts); + CodePhrase territory = new CodePhrase("ISO_3166-1", "SE"); + + Archetyped archetypeDetails = new Archetyped(new ArchetypeID( + "openehr-ehr_rm-Composition.physical_examination.v2"), "1.0"); + composition = new Composition(id, "at0001", name, archetypeDetails, + null, null, null, content, lang, context(), + provider(), category, territory, ts); + } + + public void testItemAtPathWhole() throws Exception { + path = "/"; + value = composition.itemAtPath(path); + assertEquals("unexpected value at path: " + path, composition, value); + } + + /* field */ + private Composition composition; + private String path; + private Object value; +} 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 new file mode 100644 index 00000000..3c134b70 --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/CompositionTestBase.java @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2004 Rong Chen, Acode HB, Sweden + * All rights reserved. + * + * The contents of this software are subject to the FSF GNU Public License 2.0; + * you may not use this software except in compliance with the License. You may + * obtain a copy of the License at http://www.fsf.org/licenses/gpl.html + * + * 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. + */ +package org.openehr.rm.composition; + +import java.util.ArrayList; +import java.util.List; + +import org.openehr.rm.common.archetyped.Archetyped; +import org.openehr.rm.common.archetyped.Locatable; +import org.openehr.rm.common.generic.PartyIdentified; +import org.openehr.rm.common.generic.PartySelf; +import org.openehr.rm.composition.content.ContentItem; +import org.openehr.rm.composition.content.entry.Observation; +import org.openehr.rm.composition.content.navigation.Section; +import org.openehr.rm.datastructure.DataStructureTestBase2; +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.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.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 org.openehr.rm.support.identification.ArchetypeID; +import org.openehr.rm.support.identification.HierObjectID; +import org.openehr.rm.support.identification.PartyRef; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.rm.support.terminology.TestCodeSetAccess; +import org.openehr.rm.support.terminology.TestTerminologyService; + +/** + * EntryTestBase + * + * @author Rong Chen + * @version 1.0 + */ +public class CompositionTestBase extends DataStructureTestBase2 { + + public CompositionTestBase(String test) { + super(test); + } + + // test context + protected EventContext context() throws Exception { + DvCodedText setting = new DvCodedText("setting", lang, encoding, + new CodePhrase("test", "setting_code"), ts); + return new EventContext(null, time("2006-02-01T12:00:09"), null, null, + null, setting, null, ts); + } + + protected Section section(String name) throws Exception { + List items = new ArrayList(); + items.add(observation()); + return new Section("at0000", new DvText(name), items); + } + + protected Section section(String name, String observation) throws Exception { + List items = new ArrayList(); + items.add(observation(observation)); + return new Section("at0000", new DvText(name), items); + } + + protected Observation observation() throws Exception { + return observation("test observation"); + } + + protected Observation observation(String name) throws Exception { + DvText meaning = new DvText(name); + Archetyped arch = new Archetyped(new ArchetypeID( + "openehr-ehr_rm-observation.physical_examination.v3"), "1.1"); + return new Observation("at0001", meaning, arch, language("en"), + language("en"), subject(), provider(), event("history"), ts); + } + + protected ItemList list(String name) { + String[] names = { "field 1", "field 2", "field 3" }; + String[] values = { "value 1", "value 2", "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); + } + + public void assertItemAtPath(String path, Locatable target, + Locatable expected) throws Exception { + Locatable actual = (Locatable) target.itemAtPath(path); + assertEquals("unexpected item: " + actual.getName().getValue() + + " for path: " + path, expected, actual); + } + + protected History event(String name) { + // element = element("element name", "value"); + String[] ITEMS = { "event one", "event two", "event three" }; + String[] CODES = { "code one", "code two", "code three" }; + 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); + } + + // test territory + protected CodePhrase territory() { + return new CodePhrase("test", "se"); + } + + // test subject + protected PartySelf subject() throws Exception { + PartyRef party = new PartyRef(new HierObjectID("1.2.4.5.6.12.1"), + "PARTY"); + return new PartySelf(party); + } + + // test provider + protected PartyIdentified provider() throws Exception { + PartyRef performer = new PartyRef(new HierObjectID("1.3.3.1.2.42.1"), + "ORGANISATION"); + return new PartyIdentified(performer, "provider's name", null); + } + + protected DvDateTime time(String time) throws Exception { + return new DvDateTime(time); + } + + protected CodePhrase language(String language) throws Exception { + return new CodePhrase("test", language); + } + + /* field */ + protected static CodePhrase lang = TestCodeSetAccess.ENGLISH; + protected static CodePhrase encoding = TestCodeSetAccess.LATIN_1; + protected static TerminologyService ts = TestTerminologyService + .getInstance(); + protected String path; + protected Object value; +} 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 new file mode 100644 index 00000000..46efd33a --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/EventContextTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2004 Rong Chen, Acode HB, Sweden + * All rights reserved. + * + * The contents of this software are subject to the FSF GNU Public License 2.0; + * you may not use this software except in compliance with the License. You may + * obtain a copy of the License at http://www.fsf.org/licenses/gpl.html + * + * 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. + */ +package org.openehr.rm.composition; + +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.DvCodedText; +import org.openehr.rm.support.terminology.TestCodeSetAccess; + +/** + * EventContextTest + * + * @author Rong Chen + * @version 1.0 + */ +public class EventContextTest extends CompositionTestBase { + + public EventContextTest(String test) { + super(test); + } + /** + * Tests null checking for setting within the constructor + * + * @throws Exception + */ + public void testCreateEventContextWithNullSetting() throws Exception { + try { + + new EventContext(null, time("2006-06-11T12:22:25"), null, null, null, + null, null, ts); + + fail("failed to thrown illeglArgumentException for null setting"); + + } catch (Exception e) { + assertTrue("caught unexpected exception: " + e, + e instanceof IllegalArgumentException); + assertTrue("wrong message: " + e.getMessage(), + e.getMessage().contains("setting")); + } + } + + public void testCreateSimpleEventContext() { + DvDateTime startTime = new DvDateTime("2006-11-22T18:57:01"); + DvCodedText setting = TestCodeSetAccess.SETTING; + EventContext context = new EventContext(startTime, setting, ts); + + assertEquals(startTime, context.getStartTime()); + assertEquals(setting, context.getSetting()); + } + + /** + * Tests null participations doesn't cause getParticipations throws + * exception + * + * @throws Exception + */ + public void testGetParticipations() throws Exception { + + EventContext eventContext = new EventContext(null, time("2006-06-11T12:22:25"), null, + null, null, TestCodeSetAccess.SETTING, null, ts); + + eventContext.getParticipations(); + } +} 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 new file mode 100644 index 00000000..d1d8016f --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ActionTest.java @@ -0,0 +1,131 @@ +/* + * 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 ***** + */ \ 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 new file mode 100644 index 00000000..fc10f602 --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ActivityTest.java @@ -0,0 +1,90 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ActivityTest" + * 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/ActivityTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" + */ + +/** + * ActivityTest + * + * @author Yin Su Lim + * @version 1.0 + */ + +package org.openehr.rm.composition.content.entry; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.openehr.rm.composition.CompositionTestBase; +import org.openehr.rm.datatypes.encapsulated.DvParsable; + +public class ActivityTest extends CompositionTestBase { + + public ActivityTest(String testName) { + super(testName); + } + + protected void setUp() throws Exception { + DvParsable timing = new DvParsable("timing value", "fomalism"); + activity = new Activity("at0004", text("activity 1"), + list("list activity"), timing, + "openEHR-EHR-ITEM_TREE.intravenous_fluids.v1"); + } + + protected void tearDown() throws Exception { + } + + public static Test suite() { + TestSuite suite = new TestSuite(ActivityTest.class); + + return suite; + } + + public void testItemAtPath() { + path = "/"; + value = activity.itemAtPath(path); + assertEquals(activity, value); + } + + private Activity activity; +} + +/* + * ***** 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 ActivityTest.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/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 new file mode 100644 index 00000000..8143e8bd --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/AdminEntryTest.java @@ -0,0 +1,172 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class AdminEntryTest" + * 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/AdminEntryTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" + */ + +package org.openehr.rm.composition.content.entry; + +import java.util.*; + +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.representation.Element; +import org.openehr.rm.datatypes.quantity.datetime.DvDate; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.identification.ArchetypeID; + +public class AdminEntryTest extends CompositionTestBase { + + public AdminEntryTest(String testName) { + super(testName); + } + + protected void setUp() throws Exception { + Archetyped archetypeDetails = new Archetyped( + new ArchetypeID("openehr-ehr_rm-adminEntry.date.v2"), + "1.0.2"); + List items = new ArrayList(); + items.add(new Element(("at0001"), "header", new DvText("date"))); + items.add(new Element(("at0002"), "value", new DvDate("2008-05-17"))); + itemList = new ItemList("at0003", "item list", items); + adminEntry = new AdminEntry(null, "at0004", new DvText("admin entry"), + archetypeDetails, null, null, null, lang, encoding, + subject(), provider(), null, null, itemList, ts); + } + + protected void tearDown() throws Exception { + itemList = null; + adminEntry = null; + } + + public void testItemAtPathWhole() throws Exception { + path = "/"; + value = adminEntry.itemAtPath(path); + assertEquals("unexpected result for path: " + path, adminEntry, value); + } + + public void testItemAtPathSubject() throws Exception { + path = "/subject"; + value = adminEntry.itemAtPath(path); + assertEquals("unexpected result for path: " + path, + adminEntry.getSubject(), value); + } + + public void testItemAtPathProvider() throws Exception { + path = "/provider"; + value = adminEntry.itemAtPath(path); + assertEquals("unexpected result for path: " + path, + adminEntry.getProvider(), value); + } + + public void testItemAtPathData() throws Exception { + path = "/data"; + value = adminEntry.itemAtPath(path); + assertEquals("unexpected result for path: " + path, itemList, value); + } + + public void testItemAtPathDataATCode() throws Exception { + path = "/data[at0003]"; + value = adminEntry.itemAtPath(path); + assertEquals("unexpected result for path: " + path, itemList, value); + } + + public void testItemAtPathDataItemOne() throws Exception { + path = "/data/items[at0001]"; + value = adminEntry.itemAtPath(path); + assertEquals("unexpected result for path: " + path, + itemList.getItems().get(0), value); + } + + public void testItemAtPathDataItemTwo() throws Exception { + path = "/data/items[at0002]"; + value = adminEntry.itemAtPath(path); + assertEquals("unexpected result for path: " + path, + itemList.getItems().get(1), value); + } + + public void testItemAtPathDataItemOneValue() throws Exception { + path = "/data/items[at0001]/value"; + value = adminEntry.itemAtPath(path); + assertEquals("unexpected result for path: " + path, + itemList.getItems().get(0).getValue(), value); + } + + public void testItemAtPathDataItemTwoValue() throws Exception { + path = "/data/items[at0002]/value"; + value = adminEntry.itemAtPath(path); + assertEquals("unexpected result for path: " + path, + itemList.getItems().get(1).getValue(), value); + } + + public void testItemAtPathDataItemHeader() throws Exception { + path = "/data/items['header']"; + value = adminEntry.itemAtPath(path); + assertEquals("unexpected result for path: " + path, + itemList.getItems().get(0), value); + } + + public void testItemAtPathDataItemValue() throws Exception { + path = "/data/items['value']"; + value = adminEntry.itemAtPath(path); + assertEquals("unexpected result for path: " + path, + itemList.getItems().get(1), value); + } + + public void testItemAtPathDataItemHeaderValue() throws Exception { + path = "/data/items['header']/value"; + value = adminEntry.itemAtPath(path); + assertEquals("unexpected result for path: " + path, + itemList.getItems().get(0).getValue(), value); + } + + public void testItemAtPathDataItemValueValue() throws Exception { + path = "/data/items['value']/value"; + value = adminEntry.itemAtPath(path); + assertEquals("unexpected result for path: " + path, + itemList.getItems().get(1).getValue(), value); + } + + private ItemList itemList; + private AdminEntry adminEntry; +} + +/* + * ***** 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 AdminEntryTest.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/EvaluationTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/EvaluationTest.java new file mode 100644 index 00000000..ee62520b --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/EvaluationTest.java @@ -0,0 +1,95 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class EvaluationTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/composition/content/entry/EvaluationTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +/** + * EvaluationTest + * + * @author Rong Chen + * @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.support.identification.ArchetypeID; + +public class EvaluationTest extends CompositionTestBase { + + public EvaluationTest(String test) { + super(test); + } + + /** + * The fixture clean up called after every test method. + */ + protected void tearDown() throws Exception { + evaluation = null; + } + + /** + * The fixture set up called before every test method. + */ + protected void setUp() throws Exception { + ItemStructure protocol = list("list protocol"); + ItemStructure data = list("list data"); + Archetyped arch = new Archetyped( + new ArchetypeID("openehr-ehr_rm-evaluation.physical_examination.v3"), + "1.1"); + evaluation = new Evaluation(null, "at000", text("evaluation"), arch, + null, null, null, language("en"), language("en"), subject(), provider(), + null, null, protocol, null, data, ts); + } + + public void testItemAtPath() { + path = "/"; + value = evaluation.itemAtPath(path); + assertEquals(evaluation, value); + } + + /* field */ + private Evaluation evaluation; + + +} + +/* + * ***** 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 EvaluationTest.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/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 new file mode 100644 index 00000000..62569b87 --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ISMTransitionTest.java @@ -0,0 +1,49 @@ +package org.openehr.rm.composition.content.entry; + +import junit.framework.TestCase; + +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvCodedText; +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; + +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); + + CodePhrase definingCode = new CodePhrase("test", "124"); + DvCodedText careflowStep = new DvCodedText("care flow Step", + definingCode); + + TerminologyService ts = TestTerminologyService.getInstance(); + + ISMTransition ismt = new ISMTransition(currentState, transition, + careflowStep, 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); + } +} 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 new file mode 100644 index 00000000..d3e77c48 --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/InstructionTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2004 Rong Chen, Acode HB, Sweden + * All rights reserved. + * + * The contents of this software are subject to the FSF GNU Public License 2.0; + * you may not use this software except in compliance with the License. You may + * obtain a copy of the License at http://www.fsf.org/licenses/gpl.html + * + * 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. + */ +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.ItemStructure; +import org.openehr.rm.datatypes.encapsulated.DvParsable; +import org.openehr.rm.support.identification.ArchetypeID; + +/** + * InstructionTest + * + * @author Rong Chen + * @version 1.0 + */ +public class InstructionTest extends CompositionTestBase { + + public InstructionTest(String test) { + super(test); + } + + public void tearDown() throws Exception { + instruction = null; + } + + public void setUp() 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 = 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); + } + + public void testItemAtPath() { + path = "/"; + value = instruction.itemAtPath(path); + assertEquals(instruction, value); + } + + /* fields */ + private static Instruction instruction; +} 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 new file mode 100644 index 00000000..e527d37f --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ObservationTest.java @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2004-2008 Rong Chen, Acode HB, Sweden + * All rights reserved. + * + * The contents of this software are subject to the FSF GNU Public License 2.0; + * you may not use this software except in compliance with the License. You may + * obtain a copy of the License at http://www.fsf.org/licenses/gpl.html + * + * 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. + */ +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.datastructure.history.Event; +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.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.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.composition.CompositionTestBase; +import org.openehr.rm.support.identification.ArchetypeID; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.rm.support.terminology.TestTerminologyService; +import org.openehr.terminology.SimpleTerminologyService; + +/** + * ObservationTest + * + * @author Rong Chen + * @version 1.0 + */ +public class ObservationTest extends CompositionTestBase { + + public ObservationTest(String test) { + super(test); + } + + /** + * The fixture clean up called after every test method. + */ + protected void tearDown() throws Exception { + observation = null; + } + + /** + * The fixture set up called before every test method. + */ + protected void setUp() throws Exception { + state = event("state"); + Archetyped archetypeDetails = new Archetyped( + new ArchetypeID("openehr-ehr_rm-observation.physical_examination.v3"), + "1.1"); + + List items = new ArrayList(); + items.add(new Element(("at0001"), "header", new DvText("date"))); + items.add(new Element(("at0002"), "value", new DvDate("2008-05-17"))); + itemList = new ItemList("at0003", "item list", items); + + event = new PointEvent("at0004", "point event", + new DvDateTime("2008-05-17T10:00:00"), itemList); + + List> events = new ArrayList>(); + events.add(event); + data = new History("at0005", "data", + new DvDateTime("2008-05-17T10:00:00"), events); + + items = new ArrayList(); + items.add(new Element(("at0004"), "protocol 1", new DvText("date"))); + items.add(new Element(("at0005"), "protocol 2", new DvDate("2008-05-17"))); + protocol = new ItemList("at0006", "item list", items); + + TerminologyService ts = TestTerminologyService.getInstance(); + observation = new Observation(null, "at0007", new DvText("observation"), + archetypeDetails, null, null, null, lang, encoding, subject(), + provider(), null, null, protocol, null, data, state, + TestTerminologyService.getInstance()); + } + + public void testCreateObservationWithSimpleTerminologyService() + 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 = new Observation(null, "at000", text("observation"), + arch, null, null, null, language, encoding, subject(), + provider(), null, null, protocol, null, data, state, termServ); + + } + + public void testItemAtPathWhole() throws Exception { + path = "/"; + value = observation.itemAtPath(path); + assertEquals("unexpected resutl for path: " + path, observation, value); + } + + public void testItemAtPathSubject() throws Exception { + path = "/subject"; + value = observation.itemAtPath(path); + assertEquals("unexpected resutl for path: " + path, + observation.getSubject(), value); + } + + public void testItemAtPathData() throws Exception { + path = "/data"; + value = observation.itemAtPath(path); + assertEquals("unexpected resutl for path: " + path, data, value); + } + + public void testItemAtPathDataEvent() throws Exception { + path = "/data/events[at0004]"; + value = observation.itemAtPath(path); + assertEquals("unexpected resutl for path: " + path, + data.getEvents().get(0), value); + } + + public void testItemAtPathDataEventName() throws Exception { + path = "/data/events['point event']"; + value = observation.itemAtPath(path); + assertEquals("unexpected resutl for path: " + path, + data.getEvents().get(0), value); + } + + public void testItemAtPathDataEventData() throws Exception { + path = "/data/events[at0004]/data"; + value = observation.itemAtPath(path); + assertEquals("unexpected resutl for path: " + path, itemList, value); + } + + public void testItemAtPathDataEventNameData() throws Exception { + path = "/data/events['point event']/data"; + value = observation.itemAtPath(path); + assertEquals("unexpected resutl for path: " + path, itemList, value); + } + + public void testItemAtPathDataEventDataItem1() throws Exception { + path = "/data/events[at0004]/data/items[at0001]"; + value = observation.itemAtPath(path); + assertEquals("unexpected resutl for path: " + path, + itemList.getItems().get(0), value); + } + + public void testItemAtPathDataEventDataItem2() throws Exception { + path = "/data/events[at0004]/data/items[at0002]"; + value = observation.itemAtPath(path); + assertEquals("unexpected resutl for path: " + path, + itemList.getItems().get(1), value); + } + + public void testItemAtPathDataEventDataItem1Value() throws Exception { + path = "/data/events[at0004]/data/items[at0001]/value"; + value = observation.itemAtPath(path); + assertEquals("unexpected resutl for path: " + path, + itemList.getItems().get(0).getValue(), value); + } + + public void testItemAtPathDataEventDataItem2Value() throws Exception { + path = "/data/events[at0004]/data/items[at0002]/value"; + value = observation.itemAtPath(path); + assertEquals("unexpected resutl for path: " + path, + itemList.getItems().get(1).getValue(), value); + } + + public void testItemAtPathDataEventDataItemHeader() throws Exception { + path = "/data/events['point event']/data/items['header']"; + value = observation.itemAtPath(path); + assertEquals("unexpected resutl for path: " + path, + itemList.getItems().get(0), value); + } + + public void testItemAtPathDataEventDataItemValue() throws Exception { + path = "/data/events['point event']/data/items['value']"; + value = observation.itemAtPath(path); + assertEquals("unexpected resutl for path: " + path, + itemList.getItems().get(1), value); + } + + public void testItemAtPathDataEventDataItemHeaderValue() throws Exception { + path = "/data/events['point event']/data/items['header']/value"; + value = observation.itemAtPath(path); + assertEquals("unexpected resutl for path: " + path, + itemList.getItems().get(0).getValue(), value); + } + + public void testItemAtPathDataEventDataItemValueValue() throws Exception { + path = "/data/events['point event']/data/items['value']/value"; + value = observation.itemAtPath(path); + assertEquals("unexpected resutl for path: " + path, + itemList.getItems().get(1).getValue(), value); + } + + public void testItemAtPathState() throws Exception { + path = "/state"; + value = observation.itemAtPath(path); + assertEquals("unexpected resutl for path: " + path, + observation.getState(), value); + } + + public void testItemAtPathProtocol() throws Exception { + path = "/protocol"; + value = observation.itemAtPath(path); + assertEquals("unexpected resutl for path: " + path, + observation.getProtocol(), value); + } + + /* field */ + private ItemList itemList; + private PointEvent event; + private History data; + private History state; + private ItemList protocol; + private Observation observation; +} \ No newline at end of file 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 new file mode 100644 index 00000000..0d5ccf45 --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/navigation/SectionTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2004 Rong Chen, Acode HB, Sweden + * All rights reserved. + * + * The contents of this software are subject to the FSF GNU Public License 2.0; + * you may not use this software except in compliance with the License. You may + * obtain a copy of the License at http://www.fsf.org/licenses/gpl.html + * + * 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. + */ +package org.openehr.rm.composition.content.navigation; + +import org.openehr.rm.composition.CompositionTestBase; +import org.openehr.rm.composition.content.ContentItem; +import org.openehr.rm.composition.content.entry.Observation; +import org.openehr.rm.datatypes.text.DvText; + +import java.util.List; +import java.util.ArrayList; + +/** + * SectionTest + * + * @author Rong Chen + * @version 1.0 + */ +public class SectionTest extends CompositionTestBase { + + public SectionTest(String test) { + super(test); + } + + public void setUp() throws Exception { + List items = new ArrayList(); + observationTwo = observation("observation 2"); + items.add(observationTwo); + + sectionThree = section("section 3"); + items.add(sectionThree); + + sectionTwo = new Section("at0000", new DvText("section 2"), items); + items = new ArrayList(); + items.add(sectionTwo); + + observationOne = observation("observation 1"); + items.add(observationOne); + section = new Section("at0000", new DvText("section"), items); + } + + public void tearDown() throws Exception { + section = null; + } + + public void testItemAtPathWhole() { + path = "/"; + value = section.itemAtPath(path); + assertEquals(section, value); + } + + public void testItemAtPathSectionTwo() { + path = "/items['section 2']"; + value = section.itemAtPath(path); + assertEquals(sectionTwo, value); + } + + public void testItemAtPathSectionThree() { + path = "/items['section 2']/items['section 3']"; + value = section.itemAtPath(path); + assertEquals(sectionThree, value); + } + + public void testItemAtPathObservationOne() { + path = "/items['observation 1']"; + value = section.itemAtPath(path); + assertEquals(observationOne, value); + } + + public void testItemAtPathObservationTwo() { + path = "/items['section 2']/items['observation 2']"; + value = section.itemAtPath(path); + assertEquals(observationTwo, value); + } + + /* fields */ + private Section section; + private Section sectionTwo; + private Section sectionThree; + private Observation observationOne; + private Observation observationTwo; +} 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 new file mode 100644 index 00000000..214048df --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/datastructure/DataStructureTestBase.java @@ -0,0 +1,147 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DataStructureTestBase" + * keywords: "unit test" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004,2006 Acode HB, Sweden" + * 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/datastructure/DataStructureTestBase.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +/** + * ItemStructureTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.datastructure; + +import java.util.List; + +import junit.framework.TestCase; + +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datastructure.itemstructure.representation.Cluster; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datastructure.itemstructure.representation.Item; +import org.openehr.rm.datatypes.basic.DataValue; +import org.openehr.rm.datatypes.quantity.DvQuantity; +import org.openehr.rm.datatypes.quantity.DvProportion; +import org.openehr.rm.datatypes.quantity.ProportionKind; +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.TerminologyID; + +public class DataStructureTestBase extends TestCase { + + public DataStructureTestBase(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 { + } + + // create a cluster + protected Cluster cluster(String archetypeNodeId, String name, + List items) { + return new Cluster(archetypeNodeId, text(name), items); + } + + // create an element by same name, value and code + protected Element element(String name) { + return element(name, name, name, name); + } + + // create an element by name and code + protected Element element(String name, String code) { + return element(name, name, code, code); + } + + // create an element by name and value + protected Element element(String name, DataValue value) { + return new Element("at001", text(name), value); + } + + // create an element by name, and ratio + protected Element element(String name, double numerator, double denominator) { + return element(name, proportion(numerator, denominator)); + } + + // create an element with text value + protected Element element(String archetypeNodeId, String name, String value) { + return new Element(archetypeNodeId, text(name), text(value)); + } + + // create an element with codedText value + protected Element element(String archetypeNodeId, String name, + String value, String code) { + return new Element(archetypeNodeId, text(name), codedText(value, code)); + } + + // create an element with quanity value + protected Element element(String archetypeNodeId, String name, double value) { + return new Element(archetypeNodeId, text(name), new DvQuantity(value)); + } + + // create a text + protected DvText text(String value) { + return new DvText(value); + } + + // create a codeText + protected DvCodedText codedText(String value, String code) { + CodePhrase codePhrase = new CodePhrase(new TerminologyID("SNOMED CT"), + code); + return new DvCodedText(value, codePhrase); + } + + // create a quantityRatio + protected DvProportion proportion(double numerator, double denominator) { + return new DvProportion(numerator, denominator, ProportionKind.FRACTION, 0); + } + + protected static final String sep = ItemStructure.PATH_SEPARATOR; +} +/* + * ***** 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 DataStructureTestBase.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-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 ***** + */ \ No newline at end of file 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 new file mode 100644 index 00000000..6708259d --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/datastructure/DataStructureTestBase2.java @@ -0,0 +1,147 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DataStructureTestBase" + * keywords: "unit test" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004,2006 Acode HB, Sweden" + * 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/datastructure/DataStructureTestBase.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +/** + * ItemStructureTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.datastructure; + +import java.util.List; + +import junit.framework.TestCase; + +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datastructure.itemstructure.representation.Cluster; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datastructure.itemstructure.representation.Item; +import org.openehr.rm.datatypes.basic.DataValue; +import org.openehr.rm.datatypes.quantity.DvQuantity; +import org.openehr.rm.datatypes.quantity.DvProportion; +import org.openehr.rm.datatypes.quantity.ProportionKind; +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.TerminologyID; + +public class DataStructureTestBase2 extends TestCase { + + public DataStructureTestBase2(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 { + } + + // create a cluster + protected Cluster cluster(String archetypeNodeId, String name, + List items) { + return new Cluster(archetypeNodeId, text(name), items); + } + + // create an element by same name, value and code + protected Element element(String name) { + return element(name, name, name, name); + } + + // create an element by name and code + protected Element element(String name, String code) { + return element(name, name, code, code); + } + + // create an element by name and value + protected Element element(String name, DataValue value) { + return new Element("at001", text(name), value); + } + + // create an element by name, and ratio + protected Element element(String name, double numerator, double denominator) { + return element(name, proportion(numerator, denominator)); + } + + // create an element with text value + protected Element element(String archetypeNodeId, String name, String value) { + return new Element(archetypeNodeId, text(name), text(value)); + } + + // create an element with codedText value + protected Element element(String archetypeNodeId, String name, + String value, String code) { + return new Element(archetypeNodeId, text(name), codedText(value, code)); + } + + // create an element with quanity value + protected Element element(String archetypeNodeId, String name, double value) { + return new Element(archetypeNodeId, text(name), new DvQuantity(value)); + } + + // create a text + protected DvText text(String value) { + return new DvText(value); + } + + // create a codeText + protected DvCodedText codedText(String value, String code) { + CodePhrase codePhrase = new CodePhrase(new TerminologyID("SNOMED CT"), + code); + return new DvCodedText(value, codePhrase); + } + + // create a quantityRatio + protected DvProportion proportion(double numerator, double denominator) { + return new DvProportion(numerator, denominator, ProportionKind.FRACTION, 0); + } + + protected static final String sep = ItemStructure.PATH_SEPARATOR; +} +/* + * ***** 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 DataStructureTestBase.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2003-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 ***** + */ \ No newline at end of file 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 new file mode 100644 index 00000000..a64a02a9 --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/AddressTest.java @@ -0,0 +1,82 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class AddressTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/demographic/AddressTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ + +package org.openehr.rm.demographic; + +public class AddressTest extends DemographicTestBase { + + public AddressTest(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 testConstructor() throws Exception { + + new Address(oid("address.trial"), "at0000", + text("address meaning"), null, null, null, null, + itemSingle("address details")); + + // null details + try { + new Address(oid("8702534253"), "at0000", + text("address meaning"), null, null, null, null, null); + + fail("exception should be thrown"); + + } catch(Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + } +} +/* + * ***** 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 AddressTest.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/test/java/org/openehr/rm/demographic/CapabilityTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/CapabilityTest.java new file mode 100644 index 00000000..e6e09a8a --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/CapabilityTest.java @@ -0,0 +1,87 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class CapabilityTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/demographic/CapabilityTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ + +package org.openehr.rm.demographic; + +import org.openehr.rm.datatypes.quantity.datetime.DvDate; +import org.openehr.rm.datatypes.quantity.DvInterval; + +/** + * CapabilityTest + * + * @author Rong Chen + * @version 1.0 + */ +public class CapabilityTest extends DemographicTestBase { + + public CapabilityTest(String name) { + super(name); + } + + public void testConstructor() throws Exception { + DvInterval timeValidity = new DvInterval( + date("2000-01-01"), date("2010-10-30")); + + new Capability(null, "at0000", + text("capability meaning"), null, null, null, null, + timeValidity, itemSingle("capability credentials")); + + // null timeValidity + new Capability(null, "at0000", + text("capability meaning"), null, null, null, null, + null, itemSingle("capability credentials")); + + // null credentials + try { + new Capability(null, "at0000", + text("capability meaning"), null, null, null, + null, timeValidity, null); + + fail("exception should be thrown"); + + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + } +} +/* + * ***** 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 CapabilityTest.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 ***** + */ 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 new file mode 100644 index 00000000..42321659 --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/ContactTest.java @@ -0,0 +1,91 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ContactTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/demographic/ContactTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ + +package org.openehr.rm.demographic; + +import org.openehr.rm.datatypes.quantity.datetime.DvDate; +import org.openehr.rm.datatypes.quantity.DvInterval; + +import java.util.List; +import java.util.ArrayList; + +/** + * ContactTest + * + * @author Rong Chen + * @version 1.0 + */ +public class ContactTest extends DemographicTestBase { + + public ContactTest(String name) { + super(name); + } + + public void testConstructor() throws Exception { + DvInterval timeValidity = new DvInterval( + date("2005-01-01"), date("2005-12-31")); + List
addresses = new ArrayList
(); + addresses.add(new Address(oid("address.trial"), "at0000", + text("post address"), null, null, null, null, + itemSingle("post address details"))); + addresses.add(new Address(oid("1.2.4.5.7.33.7"), "at0000", + text("email address"), null, null, null, null, + itemSingle("email address details"))); + + new Contact(null, "at0000", text("contact name"), + null, null, null, null, timeValidity, addresses); + + // null addresses + try { + new Contact(null, "at0000", text("contact meaning"), + null, null, null, null, timeValidity, null); + + fail("exception should be thrown"); + + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + } +} + +/* + * ***** 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 ContactTest.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/test/java/org/openehr/rm/demographic/DemographicTestBase.java b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/DemographicTestBase.java new file mode 100644 index 00000000..02ca7ca8 --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/DemographicTestBase.java @@ -0,0 +1,294 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DemographicTestBase" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/demographic/DemographicTestBase.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ + +package org.openehr.rm.demographic; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import junit.framework.TestCase; + +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.generic.Participation; +import org.openehr.rm.common.generic.PartyIdentified; +import org.openehr.rm.common.generic.PartySelf; +import org.openehr.rm.composition.EventContext; +import org.openehr.rm.composition.content.entry.Instruction; +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.ItemSingle; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datastructure.itemstructure.representation.Cluster; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datastructure.itemstructure.representation.Item; +import org.openehr.rm.datatypes.basic.DataValue; +import org.openehr.rm.datatypes.basic.DvState; +import org.openehr.rm.datatypes.quantity.DvCount; +import org.openehr.rm.datatypes.quantity.DvInterval; +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 org.openehr.rm.datatypes.uri.DvEHRURI; +import org.openehr.rm.support.identification.ArchetypeID; +import org.openehr.rm.support.identification.HierObjectID; +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.TerminologyID; +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.support.measurement.MeasurementService; +import org.openehr.rm.support.measurement.TestMeasurementService; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.rm.support.terminology.TestTerminologyService; + +/** + * DemographicTestBase + * + * @author Rong Chen + * @version 1.0 + */ +public class DemographicTestBase extends TestCase { + + /** + * Constructs a test case with the given name. + */ + public DemographicTestBase(String name) { + super(name); + } + + protected ItemSingle itemSingle(String value) { + Element element = element("test element", text(value)); + return new ItemSingle("at0000", text("item single"), element); + } + + protected Cluster testCluster() { + List items = new ArrayList(); + for (int i = 0; i < 5; i++) { + items.add(element("element no." + i, text("value " + i))); + } + return new Cluster("at0000", text("test cluster"), items); + } + + protected DvCodedText coded(String value, String code) { + return new DvCodedText(value, lang(), encoding(), new CodePhrase( + SNOMED_CT, code), ts); + } + + protected DvText text(String value) { + return new DvText(value, lang(), encoding(), ts); + } + + protected Element element(String meaning, DataValue value) { + return new Element("at0000", text(meaning), value); + } + + protected CodePhrase lang() { + return new CodePhrase(LANGUAGE, "english"); + } + + protected CodePhrase encoding() { + return new CodePhrase(CHARSET, "ISO-8859-1"); + } + + protected DvDate date(String value) { + return new DvDate(value); + } + + protected DvDateTime datetime(String value) { + return new DvDateTime(value); + } + + protected DvTime time(String value) { + return new DvTime(value); + } + + protected DvCount count(int value) { + return new DvCount(value); + } + + protected PartyRef partyRef(String id, String type) { + return new PartyRef(oid(id), type); + } + + protected ObjectRef contriRef(String id) { + return new ObjectRef(oid(id), "LOCAL", "CONTRIBUTION"); + } + + protected UIDBasedID oid(String value) { + return new HierObjectID(value); + } + + protected ObjectVersionID ovid(String value) { + return new ObjectVersionID(value); + } + + protected Set links(int num) { + Set links = new HashSet(); + for (int i = 0; i < num; i++) { + links.add(new Link(text("link meaning"), text("link type"), + new DvEHRURI("ehr://composition/section/entry" + i))); + } + return links; + } + + protected EventContext eventContext() throws Exception { + List participations = new ArrayList(); + PartyRef performer = new PartyRef(new HierObjectID("1.3.3.1.2.42.1"), + "ORGANISATION"); + Participation part1 = new Participation(provider("1.3.24.2.3.4.2", + "ORGANISATION"), coded("participation function", "23432423"), + coded("participation mode", "242344"), + new DvInterval(datetime("2000-10-10T10:00:00"), + datetime("2001-10-10T10:00:00")), ts); + participations.add(part1); + return new EventContext(provider("1.2.3.4.2.5", "ORGANISATION"), + datetime("2000-10-10T10:00:00"), null, participations, + "event context location", coded("event context setting", + "2342342"), itemSingle("other context"), ts); + } + + protected Instruction instruction() throws Exception { + UIDBasedID uid = oid("1.34.8.2.3.1.4"); + String meaning = "at0000"; + DvText name = text("instruction 2 name"); + Archetyped archetypeDetails = new Archetyped(new ArchetypeID( + "openehr-ehr_rm-instruction2.diabetes.v1"), "1.2"); + FeederAudit feederAudit = null; + Set links = null; + + ItemStructure protocol = itemSingle("instruction2 protocol"); + String actID = "instruction2 actId"; + ObjectRef guidelineId = guideline("543234"); + String[] types = { "PARTY" }; + List participations = participationList( + "1.2.3.4.5.6.11", 1, types); + DvState state = new DvState(coded("started", "141341234"), false); + ItemStructure action = itemSingle("instruction2 action"); + ItemStructure profile = itemSingle("instruction2 profile"); + ItemStructure data = itemSingle("instruction2 data"); + + return new Instruction(uid, meaning, name, archetypeDetails, + feederAudit, links, null, language("en"), language("en"), + subject("1.4.55.1.4.2.4"), provider("1.2.15.2.5.15.4", + "ORGANISATION"), null, participations, protocol, + guidelineId, text("narrative"), null, null, null, ts); + } + + protected History event(String name) { + String[] ITEMS = { "event one", "event two", "event three" }; + String[] CODES = { "code one", "code two", "code three" }; + List> items = new ArrayList>(); + for (int i = 0; i < ITEMS.length; i++) { + Element element = element("element " + i, text(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); + } + + protected PartySelf subject(String id) { + return new PartySelf(partyRef(id, "PERSON")); + } + + protected ObjectRef guideline(String id) { + return new ObjectRef(oid(id), "LOCAL", "GUIDELINE"); + } + + protected List participationList(String id, int num, + String[] types) throws Exception { + List list = new ArrayList(); + for (int i = 0; i < num; i++) { + list.add(participation(id + i, types[i])); + } + return list; + } + + protected Participation participation(String id, String type) + throws Exception { + return new Participation(provider(id, type), coded( + "participation function", id + 1), coded("participation mode ", + id + 1), new DvInterval( + datetime("2000-10-10 10:00:00"), + datetime("2001-10-10 10:00:00")), ts); + } + + protected PartyIdentified provider(String id, String type) throws Exception { + PartyRef performer = new PartyRef(new HierObjectID(id), type); + return new PartyIdentified(performer, "provider's name", null); + } + + protected CodePhrase language(String language) throws Exception { + return new CodePhrase("test", language); + } + + /* fields */ + protected TerminologyService ts = TestTerminologyService.getInstance(); + protected MeasurementService ms = TestMeasurementService.getInstance(); + + /* static fields */ + protected static final TerminologyID LANGUAGE; + protected static final TerminologyID CHARSET; + protected static final TerminologyID SNOMED_CT; + + static { + LANGUAGE = new TerminologyID("language-test"); + CHARSET = new TerminologyID("encoding-test"); + SNOMED_CT = new TerminologyID("snomedct-test"); + } + +} + +/* + * ***** 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 DemographicTestBase.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/test/java/org/openehr/rm/demographic/PartyIdentityTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/PartyIdentityTest.java new file mode 100644 index 00000000..76378fab --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/PartyIdentityTest.java @@ -0,0 +1,76 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class PartyIdentityTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/demographic/PartyIdentityTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ + +package org.openehr.rm.demographic; + +/** + * PartyIdentityTest + * + * @author Rong Chen + * @version 1.0 + */ +public class PartyIdentityTest extends DemographicTestBase { + + public PartyIdentityTest(String name) { + super(name); + } + + public void testConstructor() throws Exception { + + new PartyIdentity(null, "at0000", + text("person name"), null, null, null, null, + itemSingle("Neo")); + + // null details + try { + new PartyIdentity(null, "at0000", + text("person name"), null, null, null, null, null); + + fail("exception should be thrown"); + } catch(Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + } +} + +/* + * ***** 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 PartyIdentityTest.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/test/java/org/openehr/rm/demographic/PartyRelationshipTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/PartyRelationshipTest.java new file mode 100644 index 00000000..061cfa0b --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/PartyRelationshipTest.java @@ -0,0 +1,104 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class PartyRelationshipTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/demographic/PartyRelationshipTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ + +package org.openehr.rm.demographic; + +import org.openehr.rm.datatypes.quantity.datetime.DvDate; +import org.openehr.rm.datatypes.quantity.DvInterval; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; + +/** + * PartyRelationshipTest + * + * @author Rong Chen + * @version 1.0 + */ +public class PartyRelationshipTest extends DemographicTestBase { + + public PartyRelationshipTest(String name) { + super(name); + } + + public void testConstructor() throws Exception { + UIDBasedID oid = oid("1.5.2.34.0.4.3"); + String meaning = "at0000"; + DvText name = text("father"); + DvInterval time = new DvInterval(date("1980-05-13"), + null); + ItemStructure details = itemSingle("father to son"); + ObjectRef source = new ObjectRef(oid("1.9.0.8.57.34.25"), "LOCAL", + "PARTY"); + ObjectRef target = new ObjectRef(oid("1.9.8.0.70.78.0"), "LOCAL", + "PARTY"); + + new PartyRelationship(oid, meaning, name, null, null, null, null, + details, time, source, target); + + // null time + new PartyRelationship(oid, meaning, name, null, null, null, null, + details, null, source, target); + + // null details + new PartyRelationship(oid, meaning, name, null, null, null, null, null, + null, source, target); + + assertException(oid, meaning, name, details, time, null, target); + assertException(oid, meaning, name, details, time, source, null); + assertException(oid, meaning, name, details, time, null, null); + } + + private void assertException(UIDBasedID oid, String meaning, DvText name, + ItemStructure details, DvInterval timeValidity, + ObjectRef source, ObjectRef target) throws Exception { + + try { + new PartyRelationship(oid, meaning, name, null, null, null, null, + details, timeValidity, source, target); + + fail("exception should be thrown"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + } +} + +/* + * ***** 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 PartyRelationshipTest.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/test/java/org/openehr/rm/demographic/PartyTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/PartyTest.java new file mode 100644 index 00000000..24e59d15 --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/PartyTest.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2004 Rong Chen, Acode HB, Sweden + * All rights reserved. + * + * The contents of this software are subject to the FSF GNU Public License 2.0; + * you may not use this software except in compliance with the License. You may + * obtain a copy of the License at http://www.fsf.org/licenses/gpl.html + * + * 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. + */ +package org.openehr.rm.demographic; + +import org.openehr.rm.common.archetyped.Archetyped; +import org.openehr.rm.support.identification.ArchetypeID; +import org.openehr.rm.datastructure.itemstructure.ItemSingle; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.datatypes.quantity.DvInterval; +import org.openehr.rm.datatypes.quantity.datetime.DvDate; + +import java.util.Set; +import java.util.HashSet; +import java.util.ArrayList; +import java.util.List; + +/** + * PartyTest + * + * @author Rong Chen + * @version 1.0 + */ +public class PartyTest extends DemographicTestBase { + + public PartyTest(String name) { + super(name); + } + + public void setUp() { + init(); + } + + public void testItemAtPathWhole() { + path = "/"; + value = person.itemAtPath(path); + assertEquals("wrong result for path: " + path, person, value); + } + + public void testItemAtPathDetails() { + path = "/details"; + value = person.itemAtPath(path); + assertEquals("wrong result for path: " + path, person.getDetails(), + value); + } + + public void testItemAtPathLegalIdentity() { + path = "/identities['legal identity']"; + value = person.itemAtPath(path); + assertEquals("wrong result for path: " + path, identity, value); + } + + public void testItemAtPathContact() { + path = "/contacts['contact 1']"; + value = person.itemAtPath(path); + assertEquals("wrong result for path: " + path, contact, value); + } + + public void testItemAtPathAddressOne() { + path = "/contacts['contact 1']/addresses['address 1']"; + value = person.itemAtPath(path); + assertEquals("wrong result for path: " + path, addressOne, value); + } + + public void testItemAtPathAddressTwo() { + path = "/contacts['contact 1']/addresses['address 2']"; + value = person.itemAtPath(path); + assertEquals("wrong result for path: " + path, addressTwo, value); + } + + + private void init() { + Set identities = new HashSet(); + ItemSingle legalName = new ItemSingle("at0002", + text("legal name"), element("at0003", new DvText("value"))); + + identity = new PartyIdentity(null, "at0000", + text(Agent.LEGAL_IDENTITY), null, null, null, null, legalName); + identities.add(identity); + + Set contacts = new HashSet(); + List
addresses = new ArrayList
(); + addressOne = address("address 1", "element 1"); + addressTwo = address("address 2", "element 2"); + addresses.add(addressOne); + addresses.add(addressTwo); + + contact = new Contact(oid("1.3.4.5.4.6"), "at0010", + new DvText("contact 1"), null, null, null, null, + new DvInterval(new DvDate("2004-01-01"), + new DvDate("2005-01-01")), addresses); + contacts.add(contact); + + Archetyped archetypeDetails = new Archetyped( + new ArchetypeID("openehr-dm_rm-person.person.v1"), "v1.0"); + ItemSingle details = new ItemSingle("at0001", text("item single"), + element("at0003", new DvText("value"))); + + person = new Person(oid("1.2.33.2.3.6.4"), "at0000", + new DvText("person"), archetypeDetails, null, null, identities, + contacts, null, null, details, null, null); + } + + private Address address(String addressName, String itemName) { + ItemSingle item = new ItemSingle("at0004", itemName, + element("at0005", new DvText("value"))); + return new Address(oid("address.a1"), "at0011", new DvText(addressName), + null, null, null, null, item); + } + + private String path; + private Object value; + private Person person; + private PartyIdentity identity; + private Contact contact; + private Address addressOne; + private Address addressTwo; +} 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 new file mode 100644 index 00000000..36ba2035 --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/PersonTest.java @@ -0,0 +1,155 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class PersonTest" + * keywords: "unit test" + * + * author: "Rong Chen " + * support: "Acode HB " + * copyright: "Copyright (c) 2004,2005 Acode HB, Sweden" + * 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/demographic/PersonTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +package org.openehr.rm.demographic; + +import org.openehr.rm.support.identification.LocatableRef; +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.support.identification.ArchetypeID; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.common.archetyped.Archetyped; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.datatypes.quantity.datetime.DvDate; +import org.openehr.rm.datatypes.quantity.DvInterval; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; + +import java.util.*; + +/** + * PersonTest + * + * @author Rong Chen + * @version 1.0 + */ +public class PersonTest extends DemographicTestBase { + + public PersonTest(String name) { + super(name); + } + + public void testConstructor() throws Exception { + UIDBasedID uid = oid("1.7.8.4"); + DvText name = text("person name"); + String meaning = "at0001"; + ItemStructure details = itemSingle("person details"); + + Set identities = new HashSet(); + identities.add(new PartyIdentity(null, "at0000", + text(Agent.LEGAL_IDENTITY), null, null, null, null, + itemSingle(" identity value"))); + Archetyped archetypeDetails = new Archetyped(new ArchetypeID( + "openehr-dm_rm-person.person.v1"), "v1.0"); + + Set contacts = new HashSet(); + DvInterval timeValidity = new DvInterval( + date("2005-01-01"), date("2005-12-31")); + List
addresses = new ArrayList
(); + addresses.add(new Address(oid("address.ad2"), "at0000", + text("telecom address"), null, null, null, null, + itemSingle("telecom addresss details"))); + Contact contact = new Contact(null, "at0000", text("contact meaning"), + null, null, null, null, timeValidity, addresses); + contacts.add(contact); + + Set relationships = new HashSet(); + timeValidity = new DvInterval(date("1960-12-25"), null); + ObjectRef source = new ObjectRef(uid, "LOCAL", "PARTY"); + ObjectRef target = new ObjectRef(oid("1.7.34.8"), "LOCAL", "PARTY"); + PartyRelationship relation = new PartyRelationship(oid("1.3.6.7.3"), + "at0000", text("mother"), null, null, null, null, + itemSingle("mother to son"), timeValidity, source, target); + relationships.add(relation); + + Set reverseRelationships = new HashSet(); + reverseRelationships.add(new LocatableRef( + ovid("1.4.4.5::1.2.840.114.1.2.2::1"), "LOCAL", "PARTY", null)); + + List capabilities = new ArrayList(); + capabilities.add(new Capability(null, "at0000", + text("capability meaning"), null, null, null, null, + timeValidity, itemSingle("capability credentials"))); + Set languages = new HashSet(); + languages.add(text("swedish")); + + // null roles + new Person(uid, "at0000", name, archetypeDetails, null, null, + identities, contacts, relationships, reverseRelationships, + details, null, languages); + + // null contacts + new Person(uid, "at0000", name, archetypeDetails, null, null, + identities, null, relationships, reverseRelationships, details, + null, languages); + + // null relationships and reverseRelationships + new Person(uid, "at0000", name, archetypeDetails, null, null, + identities, contacts, null, null, details, null, languages); + + // null languages + new Person(uid, "at0000", name, archetypeDetails, null, null, + identities, contacts, relationships, reverseRelationships, + details, null, null); + + // null archetypeDetails + assertExceptionThrow(uid, meaning, name, null, identities, contacts, + relationships, reverseRelationships, details, null, languages); + + // null identities + assertExceptionThrow(uid, meaning, name, archetypeDetails, null, + contacts, relationships, reverseRelationships, details, null, + languages); + } + + private void assertExceptionThrow(UIDBasedID uid, String meaning, + DvText name, Archetyped archetypeDetails, + Set identities, Set contacts, + Set relationships, + Set revRelationships, ItemStructure details, + Set roles, Set languages) { + try { + new Person(uid, meaning, name, archetypeDetails, null, null, + identities, contacts, relationships, revRelationships, + details, roles, languages); + fail("exception should be thrown"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + } +} + +/* + * ***** 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 PersonTest.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/test/java/org/openehr/rm/demographic/VersionedPartyTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/VersionedPartyTest.java new file mode 100644 index 00000000..af306493 --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/demographic/VersionedPartyTest.java @@ -0,0 +1,167 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class VersionedPartyTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/demographic/VersionedPartyTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +package org.openehr.rm.demographic; + +import java.util.HashSet; +import java.util.Set; + +import org.openehr.rm.common.archetyped.Archetyped; +import org.openehr.rm.common.changecontrol.Version; +import org.openehr.rm.common.generic.AuditDetails; +import org.openehr.rm.common.generic.PartyIdentified; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +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.ArchetypeID; +import org.openehr.rm.support.identification.HierObjectID; +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.support.identification.PartyRef; +import org.openehr.rm.support.identification.TerminologyID; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.rm.support.terminology.TestCodeSetAccess; +import org.openehr.rm.support.terminology.TestTerminologyAccess; +import org.openehr.rm.support.terminology.TestTerminologyService; + +/** + * VersionedPartyTest + * + * @author Rong Chen + * @version 1.0 + */ +public class VersionedPartyTest extends DemographicTestBase { + + public VersionedPartyTest(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 testConstructor() throws Exception { + String details = "some data for the first version"; + VersionedParty vp = versionedParty(details); + + assertEquals("size wrong", 1, vp.allVersions().size()); + } + + public void testCommit() throws Exception { + VersionedParty vp = versionedParty("first version"); + + Person person = person("second version"); + + vp.commitOriginalVersion(ovid("1.23.24.23::system.id::1.1.1"), + ovid("1.23.24.23::system.id::1"), person, + audit(TestCodeSetAccess.AMENDMENT), contribution("1.3.5.7"), + TestCodeSetAccess.CREATION, null, ts); + Version last = vp.latestVersion(); + + assertEquals("size wrong", 2, vp.allVersions().size()); + assertEquals("data wrong", person, last.getData()); + } + + // test versioned party + private VersionedParty versionedParty(String details) throws Exception { + HierObjectID id = new HierObjectID("1.23.24.23"); + ObjectRef owner = new ObjectRef(new HierObjectID("1.20.0.1"), "LOCAL", + "FOLDER"); + Person person = person(details); + + return new VersionedParty(id, owner, new DvDateTime( + "2006-07-18T13:44:35"), ovid("1.23.24.23::system.id::1"), + person, TestCodeSetAccess.CREATION, + audit(TestCodeSetAccess.CREATION), contribution("1.4.6.7"), + null, ts); + } + + private Person person(String detailsText) throws Exception { + UIDBasedID uid = oid("1.9.3.42::creating.system::1"); + DvText name = text("name"); + String meaning = "at0000"; + ItemStructure details = itemSingle(detailsText); + + Set identities = new HashSet(); + identities.add(new PartyIdentity(null, "at0000", + text(Agent.LEGAL_IDENTITY), null, null, null, null, + itemSingle(" identity value"))); + Archetyped archetypeDetails = new Archetyped(new ArchetypeID( + "openehr-dm_rm-Person.person.v1"), "v1.0"); + + return new Person(uid, meaning, name, archetypeDetails, null, null, + identities, null, null, null, details, null, null); + } + + // test audit + private AuditDetails audit(DvCodedText changeType) throws Exception { + PartyRef pr = new PartyRef(new HierObjectID("1-2-3-4-5"), "PARTY"); + PartyIdentified pi = new PartyIdentified(pr, "party name", null); + CodePhrase codePhrase = new CodePhrase(TestTerminologyAccess.OPENEHR, + "revisionCode"); + DvCodedText codedText = new DvCodedText("code value", ENGLISH, LATIN_1, + codePhrase, TestTerminologyService.getInstance()); + return new AuditDetails("12.3.4.5", pi, new DvDateTime( + "2006-05-01T10:10:00"), codedText, null, TestTerminologyService + .getInstance()); + } + + // test contribution + private ObjectRef contribution(String id) throws Exception { + return new ObjectRef(new HierObjectID(id), "LOCAL", "CONTRIBUTION"); + } + + private TerminologyService ts = TestTerminologyService.getInstance(); + + private static final CodePhrase ENGLISH = new CodePhrase(new TerminologyID( + "iso-639-2"), "en"); + + private static final CodePhrase LATIN_1 = new CodePhrase(new TerminologyID( + "iana-character sets"), "ISO-8859-1"); +} +/* + * ***** 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 VersionedPartyTest.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/ehr/EHRStatusTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/ehr/EHRStatusTest.java new file mode 100644 index 00000000..64b2e103 --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/ehr/EHRStatusTest.java @@ -0,0 +1,92 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class EHRStatusTest" + * 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/ehr/EHRStatusTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 12:21:46 +0100 (Thu, 10 Aug 2006) $" + */ + +/** + * EHRStatusTest + * + * @author Yin Su Lim + * @version 1.0 + */ +package org.openehr.rm.ehr; + +import org.openehr.rm.common.archetyped.Archetyped; +import org.openehr.rm.common.generic.PartyProxy; +import org.openehr.rm.composition.CompositionTestBase; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.support.identification.ArchetypeID; + +public class EHRStatusTest extends CompositionTestBase { + + public EHRStatusTest(String testName) { + super(testName); + } + + protected void setUp() throws Exception { + otherDetails = list("list other details"); + Archetyped arch = new Archetyped( + new ArchetypeID("openehr-ehr_rm-ehrstatus.XYZ.v2"), + "1.1"); + ehrStatus = new EHRStatus(null, "at0001", text("EHR Status"), + arch, null, null, null, subject(), true, true, otherDetails); + } + + public void testItemAtPathWhole() throws Exception { + path = "/"; + value = ehrStatus.itemAtPath(path); + assertEquals(ehrStatus, value); + } + + public void testItemAtPathOtherDetails() throws Exception { + path = "/otherDetails"; + value = ehrStatus.itemAtPath(path); + assertEquals(otherDetails, value); + } + + private EHRStatus ehrStatus; + private ItemStructure otherDetails; + private PartyProxy subject; + private String path; + private Object value; +} + +/* + * ***** 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 EHRStatusTest.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/test/java/org/openehr/rm/ehr/VersionedCompositionTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/ehr/VersionedCompositionTest.java new file mode 100644 index 00000000..599333f0 --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/ehr/VersionedCompositionTest.java @@ -0,0 +1,191 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class VersionedCompositionTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/ehr/VersionedCompositionTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +/** + * VersionedCompositionTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.rm.ehr; + +import java.util.ArrayList; +import java.util.List; + +import org.openehr.rm.common.archetyped.Archetyped; +import org.openehr.rm.common.generic.AuditDetails; +import org.openehr.rm.composition.Composition; +import org.openehr.rm.composition.CompositionTestBase; +import org.openehr.rm.composition.content.ContentItem; +import org.openehr.rm.composition.content.navigation.Section; +import org.openehr.rm.datastructure.itemstructure.ItemSingle; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +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.ArchetypeID; +import org.openehr.rm.support.identification.HierObjectID; +import org.openehr.rm.support.identification.ObjectRef; +import org.openehr.rm.support.identification.ObjectVersionID; +import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.rm.support.terminology.TestCodeSetAccess; +import org.openehr.rm.support.terminology.TestTerminologyAccess; +import org.openehr.rm.support.terminology.TestTerminologyService; + +public class VersionedCompositionTest extends CompositionTestBase { + + public VersionedCompositionTest(String test) { + super(test); + } + + public void testCreateVersionedComposition() throws Exception { + VersionedComposition vc = versionedComposition("at0001", "first"); + assertEquals("size", 1, vc.allVersions().size()); + } + + public void testCommit() throws Exception { + VersionedComposition vc = versionedComposition("at0001", "first"); + + assertExceptionThrown(vc, composition("at0002", "second")); + assertExceptionThrown(vc, compositionPersistent("at0001", "second")); + + // todo: need to test different category + + vc.commitOriginalVersion(new ObjectVersionID( + "1.2.4.7::1.2.40.14.1.2.2::2"), new ObjectVersionID( + "1.2.4.7::1.2.40.14.1.2.2::1"), composition("at0001", + "subsequent"), audit(TestCodeSetAccess.AMENDMENT), + contribution("1.5.25.6.2.1.2"), TestCodeSetAccess.AMENDMENT, + null, ts); + } + + private void assertExceptionThrown(VersionedComposition vc, Composition data) + throws Exception { + try { + vc.commitOriginalVersion(new ObjectVersionID( + "1.7.5.2::1.2.40.14.1.2.2::2"), new ObjectVersionID( + "1.7.5.2::1.2.40.14.1.2.2::1"), data, + audit(TestCodeSetAccess.AMENDMENT), + contribution("1.5.25.6.2.1.2"), + TestCodeSetAccess.AMENDMENT, null, ts); + fail("exception should be thrown"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + } + + // test versioned composition + private VersionedComposition versionedComposition(String node, String text) + throws Exception { + HierObjectID id = new HierObjectID("1.2.4.7"); + Composition firstData = composition(node, text); + ObjectRef ehrRef = new ObjectRef(new HierObjectID("1.2.0.0.0.1.2"), + "LOCAL", "EHR"); + + return new VersionedComposition(id, ehrRef, new DvDateTime(), + new ObjectVersionID("1.2.4.7::1.2.40.14.1.2.2::1"), firstData, + TestCodeSetAccess.CREATION, audit(TestCodeSetAccess.CREATION), + contribution("1.2.3.1"), null, ts); + } + + // test audit + private AuditDetails audit(DvCodedText changeType) throws Exception { + + return new AuditDetails("/", provider(), new DvDateTime(), changeType, + new DvText("desc"), TestTerminologyService.getInstance()); + } + + // test contribution + private ObjectRef contribution(String id) throws Exception { + return new ObjectRef(new HierObjectID(id), "LOCAL", "CONTRIBUTION"); + } + + // test composition + private Composition composition(String node, String text) throws Exception { + DvText name = new DvText(text, lang, encoding, ts); + UIDBasedID id = new HierObjectID("1.11.2.5.1.66.3"); + List content = new ArrayList(); + content.add(section()); + DvCodedText category = TestCodeSetAccess.EVENT; + Archetyped archetypeDetails = new Archetyped(new ArchetypeID( + "openehr-ehr_rm-Composition.physical_examination.v2"), "1.0"); + return new Composition(id, node, name, archetypeDetails, null, null, + null, content, TestTerminologyAccess.ENGLISH, context(), + provider(), category, territory(), ts); + } + + private Composition compositionPersistent(String node, String text) + throws Exception { + DvText name = new DvText(text, lang, encoding, ts); + UIDBasedID id = new HierObjectID("1.11.2.5.1.66.3"); + List content = new ArrayList(); + content.add(section()); + DvCodedText category = TestCodeSetAccess.PERSISTENT; + Archetyped archetypeDetails = new Archetyped(new ArchetypeID( + "openehr-ehr_rm-Composition.physical_examination.v2"), "1.0"); + return new Composition(id, node, name, archetypeDetails, null, null, + null, content, TestTerminologyAccess.ENGLISH, null, provider(), + category, territory(), ts); + } + + private Section section() throws Exception { + DvText name = new DvText("test section", lang, encoding, ts); + List items = new ArrayList(); + items.add(observation()); + return new Section("at0000", name, items); + } + + // test element + private Element element() throws Exception { + DvText name = new DvText("test element", lang, encoding, ts); + DvText value = new DvText("test value", lang, encoding, ts); + return new Element("at0000", name, value); + } + + private ItemSingle itemSingle() throws Exception { + DvText name = new DvText("test item single", lang, encoding, ts); + return new ItemSingle("at0000", name, element()); + } + + private CodePhrase lang = TestCodeSetAccess.ENGLISH; + private CodePhrase encoding = TestCodeSetAccess.LATIN_1; + private TerminologyService ts = TestTerminologyService.getInstance(); +} +/* + * ***** 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 VersionedCompositionTest.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/test/java/org/openehr/rm/integration/GenericEntryCreationTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/integration/GenericEntryCreationTest.java new file mode 100644 index 00000000..1bb3f9a2 --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/integration/GenericEntryCreationTest.java @@ -0,0 +1,69 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class GenericEntryCreationTest" + * keywords: "unit test" + * + * author: "Rong Chen " + * support: "openEHR Java project, http://www.openehr.org/projects/java.html" + * copyright: "Copyright (c) 2008 Cambio Healthcare Systems, AB" + * license: "See notice at bottom of class" + * + * file: "$URL: $" + * revision: "$LastChangedRevision: $" + * last_change: "$LastChangedDate: $" + */ +package org.openehr.rm.integration; + +import java.util.*; + +import org.openehr.rm.datastructure.itemstructure.ItemTree; +import org.openehr.rm.datastructure.itemstructure.representation.*; +import org.openehr.rm.datatypes.quantity.DvQuantity; + +import junit.framework.TestCase; + +public class GenericEntryCreationTest extends TestCase { + + public void testCreateGenericEntry() { + String archetypeNodeId = "at0001"; + String name = "test generic entry"; + Element element = new Element("at0002", "te", new DvQuantity(12.0)); + List items = new ArrayList(); + items.add(element); + ItemTree itemTree = new ItemTree("at0003", "tree", items); + + GenericEntry entry = new GenericEntry(archetypeNodeId, name, itemTree); + assertNotNull("created genericEntry null", entry); + assertEquals("itemTree wrong", itemTree, entry.getData()); + } +} + +/* + * ***** 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 GenericEntryCreationTest.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/integration/GenericEntryPathTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/integration/GenericEntryPathTest.java new file mode 100644 index 00000000..5c0b4ab3 --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/integration/GenericEntryPathTest.java @@ -0,0 +1,152 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class GenericEntryPathTest" + * keywords: "unit test" + * + * author: "Rong Chen " + * support: "openEHR Java project, http://www.openehr.org/projects/java.html" + * copyright: "Copyright (c) 2008 Cambio Healthcare Systems, AB" + * license: "See notice at bottom of class" + * + * file: "$URL: $" + * revision: "$LastChangedRevision: $" + * last_change: "$LastChangedDate: $" + */ +package org.openehr.rm.integration; + +import java.util.ArrayList; +import java.util.List; + +import org.openehr.rm.datastructure.itemstructure.ItemTree; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datastructure.itemstructure.representation.Item; +import org.openehr.rm.datatypes.quantity.DvQuantity; + +import junit.framework.TestCase; + +public class GenericEntryPathTest extends TestCase { + + public void setUp() { + String archetypeNodeId = "at0001"; + String name = "test generic entry"; + element = new Element("at0002", "element", new DvQuantity(12.0)); + List items = new ArrayList(); + items.add(element); + itemTree = new ItemTree("at0003", "item tree", items); + entry = new GenericEntry(archetypeNodeId, name, itemTree); + } + + public void testItemAtPathWhole() { + path = "/"; + value = entry.itemAtPath(path); + assertEquals(entry, value); + } + + public void testItemAtPathData() { + path = "/data"; + value = entry.itemAtPath(path); + assertEquals(itemTree, value); + } + + public void testItemAtPathDataCode() { + path = "/data[at0003]"; + value = entry.itemAtPath(path); + assertEquals(itemTree, value); + } + + public void testItemAtPathDataName() { + path = "/data['item tree']"; + value = entry.itemAtPath(path); + assertEquals(itemTree, value); + } + + public void testItemAtPathElementAT() { + path = "/data/items[at0002]"; + value = entry.itemAtPath(path); + assertEquals(element, value); + } + + public void testItemAtPathElementName() { + path = "/data/items['element']"; + value = entry.itemAtPath(path); + assertEquals(element, value); + } + + public void testItemAtPathElementBoth() { + path = "/data/items[at0002, 'element']"; + value = entry.itemAtPath(path); + assertEquals(element, value); + } + + public void testItemAtPathElementValueAT() { + path = "/data/items[at0002]/value"; + value = entry.itemAtPath(path); + assertEquals(element.getValue(), value); + } + + public void testItemAtPathElementValueName() { + path = "/data/items['element']/value"; + value = entry.itemAtPath(path); + assertEquals(element.getValue(), value); + } + + public void testItemAtPathElementValueBoth() { + path = "/data/items[at0002, 'element']/value"; + value = entry.itemAtPath(path); + assertEquals(element.getValue(), value); + } + + public void testItemAtPathElementValueMagnitudeAT() { + path = "/data/items[at0002]/value/magnitude"; + value = entry.itemAtPath(path); + assertEquals(12.0, value); + } + + public void testItemAtPathElementValueMagnitudeName() { + path = "/data/items['element']/value/magnitude"; + value = entry.itemAtPath(path); + assertEquals(12.0, value); + } + + public void testItemAtPathElementValueMagnitudeBoth() { + path = "/data/items[at0002, 'element']/value/magnitude"; + value = entry.itemAtPath(path); + assertEquals(12.0, value); + } + + private Element element; + private ItemTree itemTree; + private GenericEntry entry; + private String path; + private Object value; +} + +/* + * ***** 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 GenericEntryPathTest.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/support/measurement/TestMeasurementService.java b/openehr-rm-domain/src/test/java/org/openehr/rm/support/measurement/TestMeasurementService.java new file mode 100644 index 00000000..2bc61f3a --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/support/measurement/TestMeasurementService.java @@ -0,0 +1,100 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TestMeasurementService" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/support/measurement/TestMeasurementService.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.support.measurement; + +/** + * Implementation of MeasurementService used for testing + * + * @author Rong Chen + * @version 1.0 + */ +public 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 if units null + */ + public boolean isValidUnitsString(String units) { + return true; + } + + /** + * Return True if two units strings correspond to the same + * measured property. + * + * @param units1 + * @param units2 + * @return true if two units equal + * @throws IllegalArgumentException if units1 or units2 null + */ + public boolean unitsEquivalent(String units1, String units2) { + return true; + } + + /** + * Return a new instance of test measurement service + * + * @return + */ + public static MeasurementService getInstance() { + return new TestMeasurementService(); + } + + @Override + public boolean unitsComparable(String units1, String units2) { + return true; + } + + @Override + public int compare(String units1, Double value1, String units2, + Double value2) { + return 0; + } +} + +/* + * ***** 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 TestMeasurementService.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/test/java/org/openehr/rm/support/terminology/TestCodeSetAccess.java b/openehr-rm-domain/src/test/java/org/openehr/rm/support/terminology/TestCodeSetAccess.java new file mode 100644 index 00000000..cb6fec4a --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/support/terminology/TestCodeSetAccess.java @@ -0,0 +1,134 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TestCodeSetAccess" + * keywords: "unit test" + * + * 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/BRANCHES/Release-1.0/libraries/src/test/org/openehr/rm/support/terminology/TestCodeSetAccess.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.support.terminology; + +import java.util.HashSet; +import org.openehr.rm.datatypes.basic.DvState; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvCodedText; + +import java.util.Set; + +/** + * TestCodeSetAccess + * + * @author Rong Chen + * @version 1.0 + */ +public class TestCodeSetAccess implements CodeSetAccess { + + /* fields */ + /** + * Returns identification of this Terminology + * + * @return ID not null or empty + */ + public String id() { + return null; // todo: implement this method + } + + /** + * Returns all codes known in this terminology + * + * @return Set of DvCodePhrase + */ + public Set allCodes() { + return allCodes; // todo: implement this method + } + + public boolean hasCode(CodePhrase code) { + return true;//allCodes.contains(code); + } + + public boolean hasLang(CodePhrase lang) { + return true;//allCodes.contains(lang); + } + + public static final CodePhrase ENGLISH = new CodePhrase("test", "en"); + public static final CodePhrase LATIN_1 = new CodePhrase("test", + "iso-8859-1"); + public static final CodePhrase NULL_FLAVOUR = new CodePhrase("test", + "unanswered"); + + static final Set allCodes; + + static { + allCodes = new HashSet(); + allCodes.add(ENGLISH); + allCodes.add(LATIN_1); + allCodes.add(NULL_FLAVOUR); + } + + // change type + public static final DvCodedText CREATION = new DvCodedText("creation", + ENGLISH, LATIN_1, new CodePhrase("test", "creation"), + TestTerminologyService.getInstance()); + + public static final DvCodedText AMENDMENT = new DvCodedText("creation", + ENGLISH, LATIN_1, new CodePhrase("test", "creation"), + TestTerminologyService.getInstance()); + + public static final DvCodedText SETTING = new DvCodedText("setting", + ENGLISH, LATIN_1, new CodePhrase("test", "setting_code"), + TestTerminologyService.getInstance()); + + public static final DvCodedText ISM_ACTIVE = new DvCodedText("ism states", + ENGLISH, LATIN_1, new CodePhrase("test", "active"), + TestTerminologyService.getInstance()); + + // composition category + public static final DvCodedText EVENT = new DvCodedText("event", + ENGLISH, LATIN_1, new CodePhrase("test", "event"), + TestTerminologyService.getInstance()); + + public static final DvCodedText PERSISTENT = new DvCodedText("persistent", + ENGLISH, LATIN_1, new CodePhrase("test", "persistent"), + TestTerminologyService.getInstance()); + + // lifecycle state + public static final DvState DRAFT = new DvState(new DvCodedText("draft", + new CodePhrase("test", "draft"), ENGLISH, LATIN_1, + TestTerminologyService.getInstance()), false); +} + +/* + * ***** 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 TestCodeSetAccess.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/test/java/org/openehr/rm/support/terminology/TestTerminologyAccess.java b/openehr-rm-domain/src/test/java/org/openehr/rm/support/terminology/TestTerminologyAccess.java new file mode 100644 index 00000000..e0b97d7d --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/support/terminology/TestTerminologyAccess.java @@ -0,0 +1,212 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TestTerminologyAccess" + * keywords: "unit test" + * + * 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/BRANCHES/Release-1.0/libraries/src/test/org/openehr/rm/support/terminology/TestTerminologyAccess.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 22:20:08 +0100 (Wed, 12 Oct 2005) $" + */ +package org.openehr.rm.support.terminology; + +import java.util.HashSet; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.identification.TerminologyID; + +import java.util.Set; + +/** + * Mock TerminologyAccess used by testcases + * + * @author Rong Chen + * @version 1.0 + */ +public class TestTerminologyAccess implements TerminologyAccess { + + /** + * Returns all codes under grouper groupID of this terminology + * + * @param groupID + * @return Set of CodePhrase for given group ID, empty set + * returned if not found + * @throws IllegalArgumentException if groupID null or empty + */ + public Set codesForGroupID(String groupID) { + return null; // todo: implement this method + } + + /** + * Return all codes under grouper whose name of given + * name and language from this terminology. + * + * @param name + * @param language + * @return Set of CodePhrase for given group name, + * empty set returned if not found + * @throws IllegalArgumentException if name,language null or empty + */ + public Set codesForGroupName(String name, String language) { + + return CODES; + } + + /** + * Returns all rubric of given code and language + * + * @param code + * @param language + * @return rubric of given code and language or null if not found + * @throws IllegalArgumentException if code,language null or empty + */ + public String rubricForCode(String code, String language) { + return null; + } + + /** + * Return true if the code is under grouper of given name + * and language + * + * @param code + * @param name + * @param language + * @return true if the code exists + * @throws IllegalArgumentException if code or name or language + * null + */ + public boolean hasCodeForGroupName(CodePhrase code, String name, + String language) { + return true; + } + + /** + * Returns identification of this TerminologyAccess + * + * @return ID not null or empty + */ + public String id() { + return null; // todo: implement this method + } + + /** + * Returns all codes known in this terminology + * + * @return a Set of CodePhrase + */ + public Set allCodes() { + return null; // todo: implement this method + } + + /** + * Return true if this codeset contains given codePhrase + * + * @param code + * @return true if has + */ + public boolean has(CodePhrase code) { + return true; + } + + /* static fields */ + public static final TerminologyID OPENEHR = new TerminologyID("openehr"); + + public static final CodePhrase RELATIONS = new CodePhrase("test", + "family_code"); + + public static final CodePhrase SETTING = new CodePhrase("test", + "setting_code"); + + public static final CodePhrase FUNCTION = new CodePhrase(OPENEHR, + "meanCode"); + + public static final CodePhrase REVISION = new CodePhrase(OPENEHR, + "revisionCode"); + + public static final CodePhrase CHANGE = new CodePhrase(OPENEHR, + "changeTypeCode"); + + public static final CodePhrase ACTIVE = new CodePhrase("test", "active"); + + public static final CodePhrase CREATION = new CodePhrase("test", "creation"); + + public static final CodePhrase PERSISTENT = new CodePhrase("test", + "persistent"); + + public static final CodePhrase EVENT = new CodePhrase("test", "event"); + + public static final CodePhrase ENGLISH = new CodePhrase("test", "en"); + + public static final CodePhrase LATIN_1 = new CodePhrase("test", + "iso-8859-1"); + + public static final CodePhrase NULL_FLAVOUR = new CodePhrase("test", + "unanswered"); + + public static final CodePhrase SOME_STATE = new CodePhrase("ISM states", + "some state"); + + public static final CodePhrase SOME_TRANSITION = new CodePhrase( + "ISM transitions", "some transition"); + + + static Set CODES; + static { + CODES = new HashSet(); + CODES.add(FUNCTION); + CODES.add(REVISION); + CODES.add(EVENT); + CODES.add(PERSISTENT); + CODES.add(SETTING); + CODES.add(CHANGE); + CODES.add(RELATIONS); + CODES.add(CREATION); + CODES.add(ENGLISH); + CODES.add(ACTIVE); + CODES.add(SOME_STATE); + CODES.add(SOME_TRANSITION); + } + public Set codesForGroupId(String arg0) { + // TODO Auto-generated method stub + return null; + } + + public boolean hasCodeForGroupId(String arg0, CodePhrase arg1) { + // TODO Auto-generated method stub + 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 TestTerminologyAccess.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/test/java/org/openehr/rm/support/terminology/TestTerminologyService.java b/openehr-rm-domain/src/test/java/org/openehr/rm/support/terminology/TestTerminologyService.java new file mode 100644 index 00000000..c2629077 --- /dev/null +++ b/openehr-rm-domain/src/test/java/org/openehr/rm/support/terminology/TestTerminologyService.java @@ -0,0 +1,135 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class TestTerminologyService" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/support/terminology/TestTerminologyService.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +package org.openehr.rm.support.terminology; + +import java.util.List; +import java.util.Map; + +/** + * TestTerminologyService + * + * @author Rong Chen + * @version 1.0 + */ +public class TestTerminologyService implements TerminologyService { + + /** + * Create a new instance of test terminology service + * + * @return + */ + public static TestTerminologyService getInstance() { + return new TestTerminologyService(); + } + + + /** + * Returns a TerminologyAccess of given name + * + * @param name not empty and known to this service + * @return terminology + * @throws IllegalArgumentException if name null, empty + * or unknown to this terminology service + */ + public TerminologyAccess terminology(String name) { + return new TestTerminologyAccess(); + } + + /** + * Returns a CodeSetAccess of given name + * + * @param name not empty and known to this service + * @return codeSet + * @throws IllegalArgumentException if name is null, empty + * or unknown to this terminology service + */ + public CodeSetAccess codeSet(String name) { + return new TestCodeSetAccess(); + } + + /** + * Returns ture if terminology of given name known by this service + * + * @param name not empty + * @return true if has given terminology + * @throws IllegalArgumentException if name is null or empty + */ + public boolean hasTerminology(String name) { + return false; // todo: implement this method + } + + /** + * Returns true if code set of given name known by this service + * + * @param name not empty + * @return true if has given codeset + * @throws IllegalArgumentException if name is null or empty + */ + public boolean hasCodeSet(String name) { + return false; // todo: implement this method + } + + public List terminologyIdentifiers() { + // TODO Auto-generated method stub + return null; + } + + + public List codeSetIdentifiers() { + // TODO Auto-generated method stub + return null; + } + + + public Map openehrCodeSets() { + // TODO Auto-generated method stub + return null; + } + + + public CodeSetAccess codeSetForId(OpenEHRCodeSetIdentifiers arg0) { + return new TestCodeSetAccess(); + } +} + +/* + * ***** 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 TestTerminologyService.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/pom.xml b/pom.xml new file mode 100644 index 00000000..d0f576e6 --- /dev/null +++ b/pom.xml @@ -0,0 +1,82 @@ + + 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 + + + + + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + + + + + 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 + archetype-validator + + \ No newline at end of file diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml new file mode 100644 index 00000000..9c61b917 --- /dev/null +++ b/rm-builder/pom.xml @@ -0,0 +1,60 @@ + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5-SNAPSHOT + + rm-builder + jar + openEHR Reference Model Object Builder + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2004 + + Reference Model objects creation named class and values + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + openehr + measure-serv + ${project.version} + + + commons-lang + commons-lang + 2.6 + + + log4j + log4j + 1.2.13 + + + junit + junit + 3.8.1 + test + + + diff --git a/rm-builder/src/main/java/org/openehr/build/AttributeFormatException.java b/rm-builder/src/main/java/org/openehr/build/AttributeFormatException.java new file mode 100644 index 00000000..f1c73f43 --- /dev/null +++ b/rm-builder/src/main/java/org/openehr/build/AttributeFormatException.java @@ -0,0 +1,60 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class AttributeFormatException" + * keywords: "util" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/util/AttributeFormatException.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.build; + +/** + * AttributeFormatException + * + * @author Rong Chen + * @version 1.0 + */ + +public class AttributeFormatException extends RMObjectBuildingException { + + public AttributeFormatException(String msg) { + super(msg, ErrorType.BAD_FORMAT); + } +} + + +/* + * ***** 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 AttributeFormatException.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/rm-builder/src/main/java/org/openehr/build/AttributeMissingException.java b/rm-builder/src/main/java/org/openehr/build/AttributeMissingException.java new file mode 100644 index 00000000..5040f1c7 --- /dev/null +++ b/rm-builder/src/main/java/org/openehr/build/AttributeMissingException.java @@ -0,0 +1,61 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class AttributeMissingException" + * keywords: "util" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/util/AttributeMissingException.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.build; + +/** + * RequiredAttributeMissingException + * + * @author Rong Chen + * @version 1.0 + */ + +public class AttributeMissingException extends RMObjectBuildingException { + + public AttributeMissingException(String msg) { + super(msg, ErrorType.MISSING); + } + +} + + +/* + * ***** 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 AttributeMissingException.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/rm-builder/src/main/java/org/openehr/build/ErrorType.java b/rm-builder/src/main/java/org/openehr/build/ErrorType.java new file mode 100644 index 00000000..33f8d46b --- /dev/null +++ b/rm-builder/src/main/java/org/openehr/build/ErrorType.java @@ -0,0 +1,56 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class ErrorType" + * keywords: "archetype" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/am/archetype/constraintmodel/ErrorType.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.build; + +/** + * ErrorType + * + * @author Rong Chen + * @version 1.0 + */ +public enum ErrorType { + MISSING, BAD_INDEX, BAD_FORMAT, BAD_VALUE, TERM_MISSING, UNKNOWN, + CARDINALITY_TOO_FEW, CARDINALITY_TOO_MUCH, +} + +/* + * ***** 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 ErrorType.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/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java b/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java new file mode 100644 index 00000000..d539ce10 --- /dev/null +++ b/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java @@ -0,0 +1,711 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Class RMObjectBuilder" + * keywords: "builder" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2003-2008 ACODE HB, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.build; + +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.common.changecontrol.Contribution; +import org.openehr.rm.common.changecontrol.OriginalVersion; +import org.openehr.rm.common.generic.*; +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.demographic.*; +import org.openehr.rm.support.identification.*; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.util.*; + +/** + * 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)); + } +} + +/* + * ***** 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 RMObjectBuilder.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): Daniel Karlsson + * + * 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/rm-builder/src/main/java/org/openehr/build/RMObjectBuildingException.java b/rm-builder/src/main/java/org/openehr/build/RMObjectBuildingException.java new file mode 100644 index 00000000..bf0cb5de --- /dev/null +++ b/rm-builder/src/main/java/org/openehr/build/RMObjectBuildingException.java @@ -0,0 +1,71 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class RMObjectBuildingException" + * keywords: "util" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/util/RMObjectBuildingException.java $" + * revision: "$LastChangedRevision: 2 $" + * last_change: "$LastChangedDate: 2005-10-12 23:20:08 +0200 (Wed, 12 Oct 2005) $" + */ +package org.openehr.build; + +/** + * Root exception thrown during RM object building + * + * @author Rong Chen + * @version 1.0 + */ + +public class RMObjectBuildingException extends Exception { + + public RMObjectBuildingException(String msg, ErrorType errorType) { + super(msg); + this.errorType = errorType; + } + + public RMObjectBuildingException(String msg) { + this(msg, ErrorType.UNKNOWN); + } + + public ErrorType getErrorType() { + return errorType; + } + + private final ErrorType errorType; +} + + +/* + * ***** 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 RMObjectBuildingException.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/rm-builder/src/main/java/org/openehr/build/SystemValue.java b/rm-builder/src/main/java/org/openehr/build/SystemValue.java new file mode 100644 index 00000000..b1897284 --- /dev/null +++ b/rm-builder/src/main/java/org/openehr/build/SystemValue.java @@ -0,0 +1,107 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class SystemValue" + * keywords: "util" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/java/org/openehr/rm/util/SystemValue.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +package org.openehr.build; + +import java.util.*; + +/** + * Enumeration of values that are supplied by the system + * + * @author Rong Chen + * @version 1.0 + */ +public enum SystemValue { + + LANGUAGE ("language"), + CHARSET ("charset"), + ENCODING ("encoding"), + TERMINOLOGY_SERVICE ("terminologyService"), + MEASUREMENT_SERVICE ("measurementService"), + SUBJECT ("subject"), + PROVIDER ("provider"), + COMPOSER ("composer"), + TERRITORY ("territory"), + CONTEXT ("context"), + CATEGORY ("category"), + UID("uid"); + + /* field */ + private final String id; + private static final Map idMap; + static { + SystemValue[] list = { LANGUAGE, CHARSET, TERMINOLOGY_SERVICE, + MEASUREMENT_SERVICE, SUBJECT, PROVIDER, COMPOSER, TERRITORY, CONTEXT, + CATEGORY, UID + }; + idMap = new HashMap(); + for(SystemValue value : list) { + idMap.put(value.id(), value); + } + } + + /* constructor */ + private SystemValue(String id) { + this.id = id; + } + + /** + * Id of this system value + * + * @return id + */ + public String id() { + return id; + } + + /** + * Return system value with matching id + * + * @param id + * @return null if not found + */ + public static SystemValue fromId(String id) { + return idMap.get(id); + } +} + +/* + * ***** 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 SystemValue.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/rm-builder/src/main/resources/log4j.properties b/rm-builder/src/main/resources/log4j.properties new file mode 100644 index 00000000..ebb694fb --- /dev/null +++ b/rm-builder/src/main/resources/log4j.properties @@ -0,0 +1,9 @@ +# Set root logger level to DEBUG and its only appender to stdout. +log4j.rootLogger=INFO, 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 diff --git a/rm-builder/src/test/java/org/openehr/build/BuildDvCountTest.java b/rm-builder/src/test/java/org/openehr/build/BuildDvCountTest.java new file mode 100644 index 00000000..50158b1a --- /dev/null +++ b/rm-builder/src/test/java/org/openehr/build/BuildDvCountTest.java @@ -0,0 +1,82 @@ +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.datatypes.quantity.DvCount; +import org.openehr.rm.datatypes.quantity.DvInterval; +import org.openehr.rm.datatypes.quantity.DvOrdered; +import org.openehr.rm.datatypes.quantity.ReferenceRange; +import org.openehr.rm.datatypes.text.DvText; + +public class BuildDvCountTest extends BuildTestBase { + + public void setUp() throws Exception { + super.setUp(); + type = "DvCount"; + values = new HashMap(); + } + + public void tearDown() throws Exception { + super.tearDown(); + obj = null; + } + + public void testBuildDvCountWithOtherReferenceRanges() throws Exception { + Map values = new HashMap(); + DvText normal = new DvText(ReferenceRange.NORMAL, lang, charset, ts); + DvCount lower = new DvCount(1); + DvCount upper = new DvCount(10); + ReferenceRange normalRange = new ReferenceRange( + normal, new DvInterval(lower, upper)); + List> otherReferenceRanges = + new ArrayList>(); + otherReferenceRanges.add(normalRange); + values.put("otherReferenceRanges", otherReferenceRanges); + values.put("magnitude", new Integer(5)); + + obj = builder.construct(type, values); + assertTrue(obj instanceof DvCount); + DvCount count = (DvCount) obj; + assertEquals("magnitude", 5, count.getMagnitude().intValue()); + assertEquals("otherReferenceRanges", otherReferenceRanges, + count.getOtherReferenceRanges()); + assertEquals("accuracy", 0.0, count.getAccuracy()); + assertEquals("accuracyPercent", false, count.isAccuracyPercent()); + } + + public void testBuildDvCountWithoutReferenceRanges() throws Exception { + values.put("magnitude", 3); + obj = builder.construct(type, values); + assertTrue(obj instanceof DvCount); + DvCount count = (DvCount) obj; + assertEquals("magnitude", 3, count.getMagnitude().intValue()); + assertEquals("referenceRanges", null, count.getOtherReferenceRanges()); + assertEquals("accuracy", 0.0, count.getAccuracy()); + assertEquals("accuracyPercent", false, count.isAccuracyPercent()); + } + + public void testBuildDvCountWithGoodStringValue() throws Exception { + values.put("magnitude", "10"); + obj = builder.construct(type, values); + assertTrue(obj instanceof DvCount); + } + + + public void testBuildDvCountWithBadStringValue() throws Exception { + values.put("magnitude", "wrong type"); + try { + obj = builder.construct(type, values); + fail("attribute format exception should be thrown here"); + } catch (Exception e) { + assertTrue(e instanceof AttributeFormatException); + } + } + + private String type = "DvCount"; + private Map values; + private RMObject obj; +} diff --git a/rm-builder/src/test/java/org/openehr/build/BuildTestBase.java b/rm-builder/src/test/java/org/openehr/build/BuildTestBase.java new file mode 100644 index 00000000..c27498b9 --- /dev/null +++ b/rm-builder/src/test/java/org/openehr/build/BuildTestBase.java @@ -0,0 +1,205 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class RMObjectBuilderTestBase" + * keywords: "unit test" + * + * 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.build; + +import junit.framework.TestCase; +import org.openehr.rm.common.generic.PartyIdentified; +import org.openehr.rm.datastructure.itemstructure.ItemList; +import org.openehr.rm.support.identification.*; +import org.openehr.rm.support.measurement.*; +import org.openehr.rm.datastructure.itemstructure.ItemSingle; +import org.openehr.rm.datastructure.itemstructure.representation.Cluster; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datastructure.itemstructure.representation.Item; +import org.openehr.rm.datatypes.quantity.DvInterval; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +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.common.generic.PartySelf; +import org.openehr.terminology.SimpleTerminologyService; + +import java.util.*; + +/** + * Base class for all RM object building test providing common test fixture + * + * @author Rong Chen + */ +public class BuildTestBase extends TestCase { + + /** + * The fixture set up called before every test method. + */ + protected void setUp() throws Exception { + Map values = new HashMap(); + values.put(SystemValue.LANGUAGE, lang); + values.put(SystemValue.CHARSET, charset); + values.put(SystemValue.ENCODING, charset); + values.put(SystemValue.TERMINOLOGY_SERVICE, ts); + values.put(SystemValue.MEASUREMENT_SERVICE, ms); + builder = new RMObjectBuilder(values); + } + + /** + * The fixture clean up called after every test method. + */ + protected void tearDown() throws Exception { + builder = null; + } + + // test cluster not exactly right for table or tree + protected Cluster cluster() throws Exception { + DvText name = new DvText("test element", lang, charset, ts); + List items = new ArrayList(); + for (int i = 0; i < 6; i++) { + DvText value = new DvText("test value" + i, lang, charset, ts); + items.add(new Element("at0001", name, value)); + } + name = new DvText("test cluster", lang, charset, ts); + return new Cluster("at0002", name, items); + } + + private List elements() { + DvText name = new DvText("test element", lang, charset, ts); + List items = new ArrayList(); + for (int i = 0; i < 6; i++) { + DvText value = new DvText("test value" + i, lang, charset, ts); + items.add(new Element("at0001", name, value)); + } + return items; + } + + List items() { + DvText name = new DvText("test element", lang, charset, ts); + List items = new ArrayList(); + for (int i = 0; i < 6; i++) { + DvText value = new DvText("test value" + i, lang, charset, ts); + items.add(new Element("at0001", name, value)); + } + return items; + } + + protected List tableRows() throws Exception { + List rows = new ArrayList(); + for (int i = 0; i < 3; i++) { + rows.add(cluster()); + } + return rows; + } + + // test element + protected Element element() throws Exception { + DvText name = new DvText("test element", lang, charset, ts); + DvText value = new DvText("test value", lang, charset, ts); + return new Element("at0001", name, value); + } + + protected ItemSingle itemSingle() throws Exception { + return itemSingle("test item single"); + } + + protected ItemSingle itemSingle(String value) throws Exception { + DvText name = new DvText(value, lang, charset, ts); + return new ItemSingle("at0001", name, element()); + } + + protected ItemList itemList() throws Exception { + return new ItemList("at001", "test itemList", elements()); + } + + // test subject + protected PartySelf subject() throws Exception { + PartyRef party = new PartyRef(new HierObjectID("1.2.4.5.6.12.1"), + "PARTY"); + return new PartySelf(party); + } + + // test provider + protected PartyIdentified provider() throws Exception { + PartyRef performer = new PartyRef(new HierObjectID("1.3.3.1"), + "ORGANISATION"); + return new PartyIdentified(performer, "provider's name", null); + } + + protected HierObjectID hid(String value) throws Exception { + return new HierObjectID(value); + } + + // test territory + public CodePhrase territory() { + return new CodePhrase("test", "se"); + } + + protected DvInterval time() throws Exception { + return new DvInterval( + new DvDateTime("2004-10-29 22:37:00"), new DvDateTime( + "2004-10-29 23:10:00")); + } + + protected DvText text(String value) throws Exception { + return new DvText(value, lang, charset, ts); + } + + protected DvCodedText codedText(String value, String code) throws Exception { + CodePhrase codePhrase = new CodePhrase(TerminologyService.OPENEHR, code); + + return new DvCodedText(value, lang, charset, codePhrase, ts); + } + + /* field */ + protected RMObjectBuilder builder; + protected static CodePhrase lang = new CodePhrase("ISO_639-1", "en"); + protected static CodePhrase charset = new CodePhrase("IANA_character-sets", + "UTF-8"); + protected static TerminologyService ts; + protected static MeasurementService ms; + + static { + try { + ts = SimpleTerminologyService.getInstance(); + ms = SimpleMeasurementService.getInstance(); + } catch (Exception e) { + throw new RuntimeException( + "failed to start terminology or measure service"); + } + } +} +/* + * ***** 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 BuildTestBase.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/rm-builder/src/test/java/org/openehr/build/CommonSupportBuildTest.java b/rm-builder/src/test/java/org/openehr/build/CommonSupportBuildTest.java new file mode 100644 index 00000000..8a97abb0 --- /dev/null +++ b/rm-builder/src/test/java/org/openehr/build/CommonSupportBuildTest.java @@ -0,0 +1,65 @@ +package org.openehr.build; + +import java.util.HashMap; +import java.util.Map; + +import org.openehr.rm.RMObject; +import org.openehr.rm.common.archetyped.Archetyped; +import org.openehr.rm.common.generic.PartySelf; +import org.openehr.rm.support.identification.ArchetypeID; +import org.openehr.rm.support.identification.TerminologyID; +import org.openehr.rm.support.measurement.MeasurementService; +import org.openehr.rm.support.measurement.SimpleMeasurementService; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.terminology.SimpleTerminologyService; + +public class CommonSupportBuildTest extends BuildTestBase { + + public CommonSupportBuildTest() throws Exception { + builder = new RMObjectBuilder(); + ms = SimpleMeasurementService.getInstance(); + ts = SimpleTerminologyService.getInstance(); + } + + public void setUp() { + valueMap = new HashMap(); + } + + public void testBuildPartySelf() throws Exception { + assertBuildRMClass(PartySelf.class); + } + + public void testBuildPartySelfWithUpperCaseUnderscoreClassName() throws Exception { + rmObj = builder.construct("PARTY_SELF", valueMap); + assertBuildRMClass(PartySelf.class); + } + + public void testBuildTerminologyID() throws Exception { + valueMap.put("value", "openehr(1.0)"); + assertBuildRMClass(TerminologyID.class); + } + + public void testBuildArchetypeID() throws Exception { + valueMap.put("value", "openEHR-EHR-OBSERVATION.blood_pressure.v1"); + assertBuildRMClass(ArchetypeID.class); + } + + public void testBuildArchetyped() throws Exception { + ArchetypeID archetypeId = new ArchetypeID( + "openEHR-EHR-OBSERVATION.blood_pressure.v1"); + valueMap.put("archetypeId", archetypeId); + valueMap.put("rmVersion", "1.0.1"); + assertBuildRMClass(Archetyped.class); + } + + private void assertBuildRMClass(Class rmClass) throws Exception { + rmObj = builder.construct(rmClass.getSimpleName(), valueMap); + assertTrue("failed to build " + rmClass, rmClass.isInstance(rmObj)); + } + + private Map valueMap; + private RMObject rmObj; + private RMObjectBuilder builder; + private MeasurementService ms; + private TerminologyService ts; +} diff --git a/rm-builder/src/test/java/org/openehr/build/CreateDvMultimediaTest.java b/rm-builder/src/test/java/org/openehr/build/CreateDvMultimediaTest.java new file mode 100644 index 00000000..a9e065f4 --- /dev/null +++ b/rm-builder/src/test/java/org/openehr/build/CreateDvMultimediaTest.java @@ -0,0 +1,48 @@ +package org.openehr.build; + +import java.util.HashMap; +import java.util.Map; + +import org.openehr.rm.RMObject; +import org.openehr.rm.datatypes.encapsulated.DvMultimedia; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.uri.DvURI; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.terminology.SimpleTerminologyService; + +public class CreateDvMultimediaTest extends BuildTestBase { + + public void testCreateSimpleDvMultiMedia() throws Exception { + + CodePhrase charset = new CodePhrase("IANA_character-sets", "UTF-8"); + CodePhrase language = new CodePhrase("ISO_639-1","en"); + String alternateText = "alternative text"; + CodePhrase mediaType = new CodePhrase("IANA_media-types", "text/plain"); + CodePhrase compressionAlgorithm = new CodePhrase("openehr_compression_algorithms", "other"); + byte[] integrityCheck = new byte[0]; + CodePhrase integrityCheckAlgorithm = new CodePhrase("openehr_integrity_check_algorithms", "SHA-1"); + DvMultimedia thumbnail = null; + DvURI uri = new DvURI("www.iana.org"); + byte[] data = new byte[0]; + TerminologyService terminologyService = SimpleTerminologyService.getInstance(); + DvMultimedia dm = new DvMultimedia(charset, language, alternateText, + mediaType, compressionAlgorithm, integrityCheck, + integrityCheckAlgorithm, thumbnail, uri, data, terminologyService); + + Map values = new HashMap(); + values.put("charset", charset); + values.put("language", language); + values.put("alternateText", alternateText); + values.put("mediaType", mediaType); + values.put("compressionAlgorithm", compressionAlgorithm); + values.put("integrityCheckAlgorithm", integrityCheckAlgorithm); + values.put("uri", uri); + //values.put("thumbnail", thumbnail); + //values.put("integrityCheck", integrityCheck); + //values.put("data", null); + + RMObject obj = builder.construct("DV_MULTIMEDIA", values); + assertTrue(obj instanceof DvMultimedia); + } + +} diff --git a/rm-builder/src/test/java/org/openehr/build/DataStructuresBuildTest.java b/rm-builder/src/test/java/org/openehr/build/DataStructuresBuildTest.java new file mode 100644 index 00000000..548c8052 --- /dev/null +++ b/rm-builder/src/test/java/org/openehr/build/DataStructuresBuildTest.java @@ -0,0 +1,276 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DataStructuresBuildTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/util/RMObjectBuilderDataStructuresTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +/** + * RMObjectBuilderDataStructuresTest + * + * @author Rong Chen + * @version 1.0 + */ +package org.openehr.build; + +import org.openehr.rm.RMObject; +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.*; +import org.openehr.rm.datastructure.itemstructure.representation.Cluster; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datastructure.itemstructure.representation.Item; +import org.openehr.rm.datatypes.quantity.DvQuantity; +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.*; + +public class DataStructuresBuildTest extends BuildTestBase { + + public void testBuildElement() throws Exception { + Map values = new HashMap(); + String node = "at0001"; + DvText name = new DvText("test element", lang, charset, ts); + DvText value = new DvText("test value", lang, charset, ts); + values.put("archetypeNodeId", node); + values.put("name", name); + values.put("value", value); + RMObject obj = builder.construct("Element", values); + + assertTrue(obj instanceof Element); + Element element = (Element) obj; + assertEquals("archetypeNodeId", node, element.getArchetypeNodeId()); + assertEquals("name", name, element.getName()); + assertEquals("value", value, element.getValue()); + } + + public void testBuildElementWithUnderscoreSeparatedAttrName() throws Exception { + Map values = new HashMap(); + String node = "at0001"; + DvText name = new DvText("test element"); + DvText value = new DvText("test value"); + values.put("archetype_node_id", node); + values.put("name", name); + values.put("value", value); + RMObject obj = builder.construct("Element", values); + assertTrue(obj instanceof Element); + } + + public void testBuildCluster() throws Exception { + Map values = new HashMap(); + String archetypeNodeId = "at0001"; + DvText name = new DvText("test element", lang, charset, ts); + List items = new ArrayList(); + for (int i = 0; i < 6; i++) { + DvText value = new DvText("test value" + i, lang, charset, ts); + items.add(new Element(archetypeNodeId, name, value)); + } + values.put("archetypeNodeId", archetypeNodeId); + values.put("name", name); + values.put("items", items); + RMObject obj = builder.construct("Cluster", values); + + assertTrue(obj instanceof Cluster); + Cluster cluster = (Cluster) obj; + assertEquals("archetypeNodeId", archetypeNodeId, + cluster.getArchetypeNodeId()); + assertEquals("name", name, cluster.getName()); + assertEquals("items", items, cluster.getItems()); + } + + public void testBuildItemList() throws Exception { + Map values = new HashMap(); + String archetypeNodeId = "at0001"; + DvText name = new DvText("test item list", lang, charset, ts); + List items = new ArrayList(); + Element element = new Element("at0002", new DvText("element"), + new DvQuantity("mmHg", 120.0, ms)); + items.add(element); + + values.put("archetypeNodeId", archetypeNodeId); + values.put("name", name); + values.put("items", items); + RMObject obj = builder.construct("ItemList", values); + + assertTrue(obj instanceof ItemList); + ItemList itemList = (ItemList) obj; + assertEquals("archetypeNodeId", archetypeNodeId, + itemList.getArchetypeNodeId()); + assertEquals("name", name, itemList.getName()); + assertEquals("items", items, itemList.getItems()); + } + + public void testBuildItemSingle() throws Exception { + Map values = new HashMap(); + + Element element = element(); + String archetypeNodeId = "at0001"; + DvText name = new DvText("test item single", lang, charset, ts); + values.put("archetypeNodeId", archetypeNodeId); + values.put("name", name); + values.put("item", element); + RMObject obj = builder.construct("ItemSingle", values); + + assertTrue(obj instanceof ItemSingle); + ItemSingle itemSingle = (ItemSingle) obj; + assertEquals("archetypeNodeId", archetypeNodeId, + itemSingle.getArchetypeNodeId()); + assertEquals("name", name, itemSingle.getName()); + assertEquals("item", element, itemSingle.getItem()); + + // test with clas + builder.construct("ITEM_SINGLE", values); + } + + public void testBuildItemTable() throws Exception { + Map values = new HashMap(); + String archetypeNodeId = "at0001"; + DvText name = new DvText("test item talbe", lang, charset, ts); + List rows = tableRows(); + + values.put("archetypeNodeId", archetypeNodeId); + values.put("name", name); + values.put("rows", rows); + RMObject obj = builder.construct("ItemTable", values); + + assertTrue(obj instanceof ItemTable); + ItemTable itemTable = (ItemTable) obj; + assertEquals("archetypeNodeId", archetypeNodeId, itemTable.getArchetypeNodeId()); + assertEquals("name", name, itemTable.getName()); + assertEquals("rows", rows, itemTable.getRows()); + } + + public void testBuildItemTree() throws Exception { + Map values = new HashMap(); + String archetypeNodeId = "at0001"; + DvText name = new DvText("test item tree", lang, charset, ts); + List items = items(); + + values.put("archetypeNodeId", archetypeNodeId); + values.put("name", name); + values.put("items", items); + RMObject obj = builder.construct("ItemTree", values); + + assertTrue(obj instanceof ItemTree); + ItemTree itemTree = (ItemTree) obj; + assertEquals("archetypeNodeId", archetypeNodeId, + itemTree.getArchetypeNodeId()); + assertEquals("name", name, itemTree.getName()); + assertEquals("items", items, itemTree.getItems()); + } + + public void testBuildPointEvent() throws Exception { + Map values = new HashMap(); + String archetypeNodeId = "at0001"; + DvText name = new DvText("test point event", lang, charset, ts); + ItemStructure data = itemSingle(); + DvDateTime time = new DvDateTime("2006-07-12T12:00:03"); + values.put("archetypeNodeId", archetypeNodeId); + values.put("name", name); + values.put("data", data); + values.put("time", time); + RMObject obj = builder.construct("PointEvent", values); + assertTrue(obj instanceof PointEvent); + PointEvent event = (PointEvent) obj; + assertEquals("archetypeNodeId", archetypeNodeId, event.getArchetypeNodeId()); + assertEquals("name", name, event.getName()); + assertEquals("data", data, event.getData()); + assertEquals("time", time, event.getTime()); + } + + public void testBuildIntervalEvent() throws Exception { + Map values = new HashMap(); + String archetypeNodeId = "at0001"; + DvText name = new DvText("test event series", lang, charset, ts); + ItemStructure data = itemList(); + DvDateTime time = new DvDateTime("2004-10-30T14:22:00"); + DvDuration width = DvDuration.getInstance("P1d"); + CodePhrase mathMean = new CodePhrase("openehr", "146"); + DvCodedText mathFunction = new DvCodedText("mean", lang, charset, + mathMean, ts); + values.put("archetypeNodeId", archetypeNodeId); + values.put("name", name); + values.put("time", time); + values.put("data", data); + values.put("width", width); + values.put("mathFunction", mathFunction); + RMObject obj = builder.construct("IntervalEvent", values); + + assertTrue(obj instanceof IntervalEvent); + IntervalEvent intEvent = (IntervalEvent) obj; + assertEquals("archetypeNodeId", archetypeNodeId, + intEvent.getArchetypeNodeId()); + assertEquals("name", name, intEvent.getName()); + assertEquals("data", data, intEvent.getData()); + assertEquals("time", time, intEvent.getTime()); + assertEquals("width", width, intEvent.getWidth()); + assertEquals("mathFunction", mathFunction, intEvent.getMathFunction()); + assertEquals("intervalStartTime", new DvDateTime("2004-10-29T14:22:00"), + intEvent.intervalStartTime()); + } + + public void testBuildHistoy() throws Exception { + Map values = new HashMap(); + String archetypeNodeId = "at0001"; + DvText name = new DvText("test history", lang, charset, ts); + DvDateTime origin = new DvDateTime("2004-10-30T14:22:00"); + List> events = new ArrayList>(); + events.add(new PointEvent(null, "at0003", text("point event"), null, + null, null, null, new DvDateTime("2004-10-31T08:00:00"), itemSingle(), null)); + values.put("archetypeNodeId", archetypeNodeId); + values.put("name", name); + values.put("origin", origin); + values.put("events", events); + RMObject obj = builder.construct("History", values); + + assertTrue(obj instanceof History); + History history = (History) obj; + assertEquals("archetypeNodeId", archetypeNodeId, + history.getArchetypeNodeId()); + assertEquals("name", name, history.getName()); + assertEquals("origin", origin, history.getOrigin()); + assertEquals("eventd", events, history.getEvents()); + } +} +/* + * ***** 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 DataStructuresBuildTest.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/rm-builder/src/test/java/org/openehr/build/DataTypesBuildTest.java b/rm-builder/src/test/java/org/openehr/build/DataTypesBuildTest.java new file mode 100644 index 00000000..ff14d505 --- /dev/null +++ b/rm-builder/src/test/java/org/openehr/build/DataTypesBuildTest.java @@ -0,0 +1,324 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DataTypesBuildTest" + * keywords: "unit test" + * + * 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.build; + +import java.util.*; + +import org.openehr.rm.RMObject; +import org.openehr.rm.datatypes.basic.DvBoolean; +import org.openehr.rm.datatypes.basic.DvState; +import org.openehr.rm.datatypes.encapsulated.DvParsable; +import org.openehr.rm.datatypes.quantity.DvOrdinal; +import org.openehr.rm.datatypes.quantity.DvQuantity; +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.support.identification.TerminologyID; + +public class DataTypesBuildTest extends BuildTestBase { + + // test classes from datatypes.basic package + public void testBuildDvBoolean() throws Exception { + String type = "DV_BOOLEAN"; + Map values = new HashMap(); + + // true value + values.put("value", "true"); + RMObject obj = builder.construct(type, values); + assertTrue(obj instanceof DvBoolean); + 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 { + String type = "DV_STATE"; + Map values = new HashMap(); + DvCodedText codedText = new DvCodedText("some text", lang, charset, + new CodePhrase("test terms", "00001"), ts); + values.put("value", codedText); + values.put("terminal", "true"); + RMObject obj = builder.construct(type, values); + assertTrue(obj instanceof DvState); + DvState state = (DvState) obj; + assertEquals("value", codedText, state.getValue()); + assertEquals("terminal", true, state.isTerminal()); + + // non-terminal + values = new HashMap(); + values.put("value", codedText); + obj = builder.construct(type, values); + assertTrue(obj instanceof DvState); + state = (DvState) obj; + assertEquals("value", codedText, state.getValue()); + assertEquals("terminal", false, state.isTerminal()); + } + + // test classes from datatypes.text package + public void testBuildDvText() throws Exception { + String type = "DV_TEXT"; + Map values = new HashMap(); + String value = "test text value"; + values.put("value", value); + RMObject obj = builder.construct(type, values); + + assertTrue(obj instanceof DvText); + DvText text = (DvText) obj; + assertEquals("value", value, text.getValue()); + } + + public void testBuildCodePhrase() throws Exception { + String type = "CODE_PHRASE"; + Map values = new HashMap(); + TerminologyID id = new TerminologyID("openehr"); + values.put("terminologyId", id); + values.put("codeString", "1234"); + RMObject obj = builder.construct(type, values); + + assertTrue(obj instanceof CodePhrase); + CodePhrase cp = (CodePhrase) obj; + assertEquals("terminologyId wrong", "openehr", + cp.getTerminologyId().getValue()); + assertEquals("codeString wrong", "1234", cp.getCodeString()); + } + + public void testBuildDvCodeText() throws Exception { + String type = "DV_CODED_TEXT"; + Map values = new HashMap(); + String value = "test text value"; + CodePhrase definingCode = new CodePhrase("local", "at0001"); + + values.put("value", value); + values.put("definingCode", definingCode); + RMObject obj = builder.construct(type, values); + + assertTrue(obj instanceof DvCodedText); + DvCodedText text = (DvCodedText) obj; + assertEquals("value", value, text.getValue()); + assertEquals("definingCode", definingCode, text.getDefiningCode()); + } + + public void testBuildDvParagraph() throws Exception { + String type = "DV_PARAGRAPH"; + Map values = new HashMap(); + List items = new ArrayList(); + CodePhrase definingCode = new CodePhrase("local", "at0001"); + DvText lineOne = new DvText("line one", lang, charset, ts); + DvText lineTwo = new DvText("line two", lang, charset, ts); + DvText lineCoded = new DvCodedText("line coded", lang, charset, + definingCode, ts); + items.add(lineOne); + items.add(lineTwo); + items.add(lineCoded); + values.put("items", items); + RMObject obj = builder.construct(type, values); + + assertTrue(obj instanceof DvParagraph); + DvParagraph paragraph = (DvParagraph) obj; + assertEquals("items.size", items.size(), paragraph.getItems().size()); + assertEquals("items", items, paragraph.getItems()); + } + + public void testBuildOrdinal() throws Exception { + String type = "DV_ORDINAL"; + Map values = new HashMap(); + DvCodedText symbol = new DvCodedText("test text", lang, + charset, new CodePhrase("test terms", "00001"), + ts); + values.put("symbol", symbol); + values.put("value", 1); + RMObject obj = builder.construct(type, values); + assertTrue(obj instanceof DvOrdinal); + DvOrdinal ordinal = (DvOrdinal) obj; + assertEquals("value", 1, ordinal.getValue()); + assertEquals("symbol", symbol, ordinal.getSymbol()); + } + + 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)); + RMObject obj = builder.construct(type, values); + assertTrue(obj instanceof DvQuantity); + DvQuantity quantity = (DvQuantity) obj; + assertEquals("units", "kg/L", quantity.getUnits()); + assertEquals("magnitude", 100.0, quantity.getMagnitude()); + + // test with good string value + values.clear(); + values.put("units", "mg"); + values.put("magnitude", "10.0"); + obj = builder.construct(type, values); + assertTrue(obj instanceof DvQuantity); + + // test with bad string value + values.put("units", "mg"); + values.put("magnitude", "wrong type"); + try { + obj = builder.construct(type, values); + fail("attribute format exception should be thrown here"); + } catch (Exception e) { + assertTrue(e instanceof AttributeFormatException); + } + + } + + // test datatypes.quantity.datetime classes + public void testBuildDvDate() throws Exception { + String type = "DV_DATE"; + + // with good string value and no referenceRanges + Map values = new HashMap(); + values.put("value", "1999-10-20"); + RMObject obj = builder.construct(type, values); + + assertTrue(obj instanceof DvDate); + DvDate date = (DvDate) obj; + assertEquals("year", 1999, date.getYear()); + assertEquals("month", 10, date.getMonth()); + assertEquals("day", 20, date.getDay()); + + // with bad string value + values.clear(); + values.put("value", "bad values"); + try { + obj = 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); + fail("attribute missing exception should be thrown here"); + } catch (Exception e) { + assertTrue(e instanceof AttributeMissingException); + } + } + + public void testBuildDvDateTime() throws Exception { + String type = "DV_DATE_TIME"; + + // without referenceRanges + Map values = new HashMap(); + values.put("value", "1999-10-20T18:15:45"); + RMObject obj = builder.construct(type, values); + + assertTrue(obj instanceof DvDateTime); + DvDateTime datetime = (DvDateTime) obj; + assertEquals("year", 1999, datetime.getYear()); + assertEquals("month", 10, datetime.getMonth()); + assertEquals("day", 20, datetime.getDay()); + assertEquals("hour", 18, datetime.getHour()); + assertEquals("minute", 15, datetime.getMinute()); + assertEquals("second", 45, datetime.getSecond()); + } + + public void testBuildDvTime() throws Exception { + String type = "DV_TIME"; + + // without referenceRanges + Map values = new HashMap(); + values.put("value", "18:15:45"); + RMObject obj = builder.construct(type, values); + + assertTrue(obj instanceof DvTime); + DvTime datetime = (DvTime) obj; + assertEquals("hour", 18, datetime.getHour()); + assertEquals("minute", 15, datetime.getMinute()); + assertEquals("second", 45, datetime.getSecond()); + } + + public void testBuildDvDuration() throws Exception { + String type = "DV_DURATION"; + + // without referenceRanges + Map values = new HashMap(); + values.put("value", "P10DT20H30M40S"); + RMObject obj = builder.construct(type, values); + + assertTrue(obj instanceof DvDuration); + DvDuration duration = (DvDuration) obj; + assertEquals("days", 10, duration.getDays()); + assertEquals("hours", 20, duration.getHours()); + assertEquals("minutes", 30, duration.getMinutes()); + assertEquals("seconds", 40, duration.getSeconds()); + assertEquals("fractionalSeconds", 0.0, duration.getFractionalSeconds()); + } + + // test datatypes.encapsulated classes + public void testBuildParsable() throws Exception { + String type = "DV_PARSABLE"; + Map values = new HashMap(); + values.put("formalism", "GLIF3"); + values.put("value", "guideline text"); + RMObject obj = builder.construct(type, values); + + assertTrue(obj instanceof DvParsable); + DvParsable parsable = (DvParsable) obj; + assertEquals("formalism", "GLIF3", parsable.getFormalism()); + assertEquals("value", "guideline text", parsable.getValue()); + } + + +} +/* + * ***** 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 DataTypesBuildTest.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/rm-builder/src/test/java/org/openehr/build/DemographicBuildTest.java b/rm-builder/src/test/java/org/openehr/build/DemographicBuildTest.java new file mode 100644 index 00000000..07af94bb --- /dev/null +++ b/rm-builder/src/test/java/org/openehr/build/DemographicBuildTest.java @@ -0,0 +1,264 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class DemographicBuildTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/util/RMObjectBuilderDemographicTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ + +package org.openehr.build; + +import org.openehr.rm.RMObject; +import org.openehr.rm.support.identification.*; +import org.openehr.rm.common.archetyped.Archetyped; +import org.openehr.rm.datastructure.DataStructure; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.datatypes.quantity.datetime.DvDate; +import org.openehr.rm.datatypes.quantity.DvInterval; +import org.openehr.rm.demographic.*; + +import java.util.*; + +/** + * Testcase for demographic object building + * + * @author Rong Chen + * @version 1.0 + */ +public class DemographicBuildTest extends BuildTestBase { + + public void testBuildAddress() throws Exception { + String type = "Address"; + Map values = new HashMap(); + + DvText text = text("addresss"); + String node = "at0001"; + DataStructure item = itemSingle("address details"); + values.put("name", text); + values.put("archetypeNodeId", node); + values.put("details", item); + + RMObject obj = builder.construct(type, values); + assertTrue(obj instanceof Address); + + Address addr = (Address) obj; + assertEquals("name wrong", text, addr.getName()); + assertEquals("archetypeNodeId wrong", node, addr.getArchetypeNodeId()); + assertEquals("details wrong", item, addr.getDetails()); + } + + public void testBuildPartyIdentity() throws Exception { + String type = "PartyIdentity"; + Map values = new HashMap(); + + DvText text = text("party identity"); + String node = "at0001"; + DataStructure item = itemSingle("party identity details"); + values.put("name", text); + values.put("archetypeNodeId", node); + values.put("details", item); + + RMObject obj = builder.construct(type, values); + assertTrue(obj instanceof PartyIdentity); + + PartyIdentity pid = (PartyIdentity) obj; + assertEquals("name wrong", text, pid.getName()); + assertEquals("archetypeNodeId wrong", node, pid.getArchetypeNodeId()); + assertEquals("details wrong", item, pid.getDetails()); + } + + public void testBuildContact() throws Exception { + String type = "Contact"; + Map values = new HashMap(); + + DvText text = text("contact"); + String node = "at0001"; + List

addresses = new ArrayList
(); + addresses.add(new Address(null, node, text("address"), null, null, + null, null, itemSingle("address detail"))); + values.put("name", text); + values.put("archetypeNodeId", node); + values.put("addresses", addresses); + + RMObject obj = builder.construct(type, values); + + Contact contact = (Contact) obj; + assertEquals("name wrong", text, contact.getName()); + assertEquals("archetypeNodeId wrong", node, contact + .getArchetypeNodeId()); + assertEquals("addresses wrong", addresses, contact.getAddresses()); + + // add timeValidity + DvInterval timeValidity = new DvInterval(new DvDate( + "2001-10-20"), null); + values.put("timeValidity", timeValidity); + obj = builder.construct(type, values); + contact = (Contact) obj; + assertEquals("timeValidity wrong", timeValidity, contact + .getTimeValidity()); + } + + public void testBuildPartyRelationship() throws Exception { + String type = "PartyRelationship"; + Map values = new HashMap(); + + ObjectID uid = hid("1.3.25.6"); + DvText text = text("PartyRelationship"); + String node = "at0001"; + DataStructure details = itemSingle("party relationship details"); + DvInterval timeValidity = new DvInterval(new DvDate( + "2001-10-30"), null); + ObjectRef source = new ObjectRef(hid("1.8.3.4.3.6.1"), "LOCAL", "PARTY"); + ObjectRef target = new ObjectRef(hid("1.2.13.3.7.31.1"), "LOCAL", + "PARTY"); + + values.put("uid", uid); + values.put("name", text); + values.put("archetypeNodeId", node); + values.put("timeValidity", timeValidity); + values.put("details", details); + values.put("source", source); + values.put("target", target); + + RMObject obj = builder.construct(type, values); + + PartyRelationship pi = (PartyRelationship) obj; + assertEquals("uid wrong", uid, pi.getUid()); + assertEquals("name wrong", text, pi.getName()); + assertEquals("archetypeNodeId wrong", node, pi.getArchetypeNodeId()); + assertEquals("details wrong", details, pi.getDetails()); + assertEquals("timeValidity wrong", timeValidity, pi.getTimeValidity()); + assertEquals("source wrong", source, pi.getSource()); + assertEquals("target wrong", target, pi.getTarget()); + } + + public void testBuildCapability() throws Exception { + String type = "Capability"; + Map values = new HashMap(); + + DvText text = text("Capability"); + String node = "at0001"; + DataStructure credentials = itemSingle("capbility credentials"); + DvInterval timeValidity = new DvInterval(new DvDate( + "2001-10-30"), null); + values.put("name", text); + values.put("archetypeNodeId", node); + values.put("timeValidity", timeValidity); + values.put("credentials", credentials); + + RMObject obj = builder.construct(type, values); + + Capability cap = (Capability) obj; + assertEquals("name wrong", text, cap.getName()); + assertEquals("archetypeNodeId wrong", node, cap.getArchetypeNodeId()); + assertEquals("details wrong", credentials, cap.getCredentials()); + assertEquals("timeValidity wrong", timeValidity, cap.getTimeValidity()); + } + + public void testBuildRole() throws Exception { + Map values = new HashMap(); + ObjectID uid = hid("1.13.23.9"); + DvText text = text("role"); + String node = "at0001"; + ItemStructure details = itemSingle("role details"); + Set identities = new HashSet(); + identities.add(new PartyIdentity(null, node, + text(Agent.LEGAL_IDENTITY), null, null, null, null, + itemSingle("legal name"))); + Archetyped archetypeDetails = new Archetyped(new ArchetypeID( + "openehr-dm_rm-Role.doctor.v2"), "v1.0"); + PartyRef performer = new PartyRef(new HierObjectID("1.2.4.5.6.12.1"), + "PERSON"); + + values.put("uid", uid); + values.put("name", text); + values.put("archetypeNodeId", node); + values.put("details", details); + values.put("identities", identities); + values.put("archetypeDetails", archetypeDetails); + values.put("performer", performer); + + RMObject obj = builder.construct("Role", values); + Role role = (Role) obj; + assertEquals("uid wrong", uid, role.getUid()); + assertEquals("name wrong", text, role.getName()); + assertEquals("archetypeNodeId wrong", node, role.getArchetypeNodeId()); + assertEquals("details wrong", details, role.getDetails()); + assertEquals("archetypeDetails wrong", archetypeDetails, role + .getArchetypeDetails()); + assertEquals("performer wrong", performer, role.getPerformer()); + } + + public void testBuildActorSubclasses() throws Exception { + verityBuildActor("Agent"); + verityBuildActor("Group"); + verityBuildActor("Organisation"); + verityBuildActor("Person"); + } + + private void verityBuildActor(String subclass) throws Exception { + Map values = new HashMap(); + ObjectID uid = hid("1.2.4.6.17.12.5"); + DvText text = text("actor"); + String node = "at0001"; + DataStructure item = itemSingle("actor details"); + Set identities = new HashSet(); + identities.add(new PartyIdentity(null, "at0003", + text(Agent.LEGAL_IDENTITY), null, null, null, null, + itemSingle("legal name"))); + Archetyped archetypeDetails = new Archetyped(new ArchetypeID( + "openehr-dm_rm-Actor.actor.v2"), "v1.0"); + values.put("uid", uid); + values.put("name", text); + values.put("archetypeNodeId", node); + values.put("details", item); + values.put("identities", identities); + values.put("archetypeDetails", archetypeDetails); + + RMObject obj = builder.construct(subclass, values); + Actor actor = (Actor) obj; + assertEquals("uid wrong", uid, actor.getUid()); + assertEquals("name wrong", text, actor.getName()); + assertEquals("archetypeNodeId wrong", node, actor.getArchetypeNodeId()); + assertEquals("details wrong", item, actor.getDetails()); + assertTrue("subclass wrong", actor.getClass().getName().endsWith( + subclass)); + } + + /* + * ***** 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 DemographicBuildTest.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 ***** + */ +} diff --git a/rm-builder/src/test/java/org/openehr/build/EHRBuildTest.java b/rm-builder/src/test/java/org/openehr/build/EHRBuildTest.java new file mode 100644 index 00000000..cadb7686 --- /dev/null +++ b/rm-builder/src/test/java/org/openehr/build/EHRBuildTest.java @@ -0,0 +1,347 @@ +/* + * component: "openEHR Reference Implementation" + * description: "Class EHRBuildTest" + * keywords: "unit test" + * + * 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/BRANCHES/RM-1.0-update/libraries/src/test/org/openehr/rm/util/RMObjectBuilderEHRTest.java $" + * revision: "$LastChangedRevision: 50 $" + * last_change: "$LastChangedDate: 2006-08-10 13:21:46 +0200 (Thu, 10 Aug 2006) $" + */ +package org.openehr.build; + +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.Evaluation; +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.History; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +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; + +/** + * Test case for EHR objects building + * + * @author Rong Chen + * @version 1.0 + */ + +public class EHRBuildTest extends BuildTestBase { + + private static CodePhrase EVENT = new CodePhrase("openehr", "433"); + + /** + * The fixture set up called before every test method. + */ + protected void setUp() throws Exception { + Map values = new HashMap(); + values.put(SystemValue.LANGUAGE, lang); + values.put(SystemValue.ENCODING, charset); + values.put(SystemValue.TERMINOLOGY_SERVICE, ts); + 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); + 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); + String node = "at0001"; + Archetyped archetypeDetails = new Archetyped( + new ArchetypeID("openehr-ehr_rm-observation.physical_examination.v3"), "v1.0"); + History data = event(); + values.put("archetypeNodeId", node); + values.put("archetypeDetails", archetypeDetails); + values.put("name", name); + values.put("language", lang); + values.put("encoding", charset); + values.put("subject", subject()); + values.put("provider", provider()); + values.put("data", data); + RMObject obj = builder.construct("Observation", values); + + assertTrue(obj instanceof Observation); + Observation observation = (Observation) obj; + assertEquals("archetypeNodeId", node, observation.getArchetypeNodeId()); + assertEquals("archetypeDetails", archetypeDetails, observation.getArchetypeDetails()); + assertEquals("name", name, observation.getName()); + assertEquals("language", lang, observation.getLanguage()); + assertEquals("encoding", charset, observation.getEncoding()); + assertEquals("subject", subject(), observation.getSubject()); + assertEquals("provider", provider(), observation.getProvider()); + assertEquals("data", event(), observation.getData()); + assertEquals("state", null, observation.getState()); + assertEquals("protocol", null, observation.getProtocol()); + assertEquals("guidelineId", null, observation.getGuidelineId()); + } + + public void testBuildEvaluation() throws Exception { + Map values = new HashMap(); + 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"); + ItemStructure data = itemSingle(); + values.put("archetypeNodeId", node); + values.put("archetypeDetails", archetypeDetails); + values.put("name", name); + values.put("language", lang); + values.put("encoding", charset); + values.put("subject", subject()); + values.put("provider", provider()); + values.put("data", data); + RMObject obj = builder.construct("Evaluation", values); + + assertTrue(obj instanceof Evaluation); + Evaluation evaluation = (Evaluation) obj; + assertEquals("archetypeNodeId", node, evaluation.getArchetypeNodeId()); + assertEquals("archetypeDetails", archetypeDetails, evaluation.getArchetypeDetails()); + assertEquals("name", name, evaluation.getName()); + assertEquals("language", lang, evaluation.getLanguage()); + assertEquals("encoding", charset, evaluation.getEncoding()); + assertEquals("subject", subject(), evaluation.getSubject()); + assertEquals("provider", provider(), evaluation.getProvider()); + assertEquals("data", data, evaluation.getData()); + assertEquals("protocol", null, evaluation.getProtocol()); + assertEquals("guidelineID", null, evaluation.getGuidelineId()); + } + + public void testBuildInstruction() throws Exception { + Map values = new HashMap(); + 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"); + DvText narrative = new DvText("medication instruction", lang, charset, ts); + + values.put("archetypeNodeId", node); + values.put("archetypeDetails", archetypeDetails); + values.put("name", name); + values.put("language", lang); + values.put("encoding", charset); + values.put("subject", subject()); + values.put("provider", provider()); + values.put("narrative", narrative); + RMObject obj = builder.construct("Instruction", values); + + assertTrue(obj instanceof Instruction); + Instruction instruction = (Instruction) obj; + assertEquals("archetypeNodeId", node, instruction.getArchetypeNodeId()); + assertEquals("archetypeDetails", archetypeDetails, instruction.getArchetypeDetails()); + assertEquals("name", name, instruction.getName()); + assertEquals("language", lang, instruction.getLanguage()); + assertEquals("encoding", charset, instruction.getEncoding()); + assertEquals("subject", subject(), instruction.getSubject()); + assertEquals("provider", provider(), instruction.getProvider()); + assertEquals("narrative", narrative, instruction.getNarrative()); + 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"; + DvText name = new DvText("test instruction", lang, charset, ts); + ItemStructure description = itemSingle(); + 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"); + + values.put("archetypeNodeId", node); + values.put("archetypeDetails", archetypeDetails); + values.put("name", name); + values.put("language", lang); + values.put("encoding", charset); + values.put("subject", subject()); + values.put("provider", provider()); + values.put("time", time); + values.put("description", description); + values.put("ismTransition", ismTransition); + RMObject obj = builder.construct("Action", values); + + assertTrue(obj instanceof Action); + Action action = (Action) obj; + assertEquals("archetypeNodeId", node, action.getArchetypeNodeId()); + assertEquals("archetypeDetails", archetypeDetails, action.getArchetypeDetails()); + assertEquals("name", name, action.getName()); + assertEquals("language", lang, action.getLanguage()); + assertEquals("encoding", charset, action.getEncoding()); + assertEquals("subject", subject(), action.getSubject()); + assertEquals("provider", provider(), action.getProvider()); + assertEquals("protocol", null, action.getProtocol()); + assertEquals("guidelineID", null, action.getGuidelineId()); + assertEquals("time", time, action.getTime()); + 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); + } + + public void testBuildSection() throws Exception { + Map values = new HashMap(); + String node = "at0001"; + DvText name = new DvText("test section", lang, charset, ts); + List items = new ArrayList(); + items.add(observation()); + values.put("archetypeNodeId", node); + values.put("name", name); + values.put("items", items); + RMObject obj = builder.construct("Section", values); + + assertTrue(obj instanceof Section); + Section section = (Section) obj; + assertEquals("archetypeNodeId", node, section.getArchetypeNodeId()); + assertEquals("name", name, section.getName()); + assertEquals("items", items, section.getItems()); + } + + public void testBuildComposition() throws Exception { + Map values = new HashMap(); + String node = "at0001"; + DvText name = new DvText("test composition", lang, charset, ts); + List
content = new ArrayList
(); + content.add(section()); + 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); + CodePhrase territory = new CodePhrase("ISO_3166-1", "SE"); + + values.put("archetypeNodeId", node); + values.put("archetypeDetails", archetypeDetails); + values.put("name", name); + values.put("content", content); + values.put("context", context()); + values.put("composer", composer); + values.put("category", category); + values.put("territory", territory); + values.put("language", lang); + RMObject obj = builder.construct("Composition", values); + assertTrue(obj instanceof Composition); + + Composition composition = (Composition) obj; + assertEquals("archetypeNodeId", node, composition.getArchetypeNodeId()); + assertEquals("archetypeDetails", archetypeDetails, composition.getArchetypeDetails()); + assertEquals("name", name, composition.getName()); + assertEquals("content", content, composition.getContent()); + assertEquals("context", context(), composition.getContext()); + assertEquals("composer", composer, composition.getComposer()); + assertEquals("category", category, composition.getCategory()); + assertEquals("territory", territory, composition.getTerritory()); + } + + private EventContext context() throws Exception { + 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, + null, homeSetting, null, ts); + } + + private Section section() throws Exception { + DvText name = new DvText("test section", lang, charset, ts); + List items = new ArrayList(); + items.add(observation()); + return new Section("at0001", name, items); + } + + 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"); + 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); + } + + 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"), + 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"), + itemSingle(), 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 EHRBuildTest.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/rm-builder/src/test/java/org/openehr/build/FindMatchingRMClassTest.java b/rm-builder/src/test/java/org/openehr/build/FindMatchingRMClassTest.java new file mode 100644 index 00000000..734ad102 --- /dev/null +++ b/rm-builder/src/test/java/org/openehr/build/FindMatchingRMClassTest.java @@ -0,0 +1,203 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Class FindMatchingRMClassTest" + * keywords: "builder" + * + * author: "Rong Chen " + * 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.build; + +import java.util.*; + +import org.openehr.rm.common.archetyped.Archetyped; +import org.openehr.rm.common.generic.PartySelf; +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.ItemList; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datatypes.quantity.DvQuantity; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.text.DvText; +import org.openehr.rm.support.identification.ArchetypeID; +import org.openehr.rm.support.identification.TerminologyID; +import org.openehr.rm.support.measurement.MeasurementService; +import org.openehr.rm.support.measurement.SimpleMeasurementService; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.terminology.SimpleTerminologyService; + +import junit.framework.TestCase; + +public class FindMatchingRMClassTest extends TestCase { + + public FindMatchingRMClassTest() throws Exception { + builder = new RMObjectBuilder(); + ms = SimpleMeasurementService.getInstance(); + ts = SimpleTerminologyService.getInstance(); + } + + public void setUp() { + valueMap = new HashMap(); + } + + public void testMatchDvQuantityValues() { + valueMap.put("units", "mmHg"); + valueMap.put("magnitude", 120.0); + assertMatchedRMClass("DvQuantity"); // This is the Java class, not the rm_type_name + } + + public void testMatchCodePhrase() { + valueMap.put("terminologyId", new TerminologyID("openehr")); + valueMap.put("codeString", "234"); + assertMatchedRMClass("CodePhrase"); // This is the Java class, not the rm_type_name + } + + public void testMatchElement() { + DvText name = new DvText("name"); + DvQuantity value = new DvQuantity("mmHg", 120.0, ms); + valueMap.put("archetypeNodeId", "at0001"); + valueMap.put("name", name); + valueMap.put("value", value); + assertMatchedRMClass("Element"); + } + + public void testWithUnderscoreSeparatedAttributeName() { + DvText name = new DvText("name"); + DvQuantity value = new DvQuantity("mmHg", 120.0, ms); + valueMap.put("archetype_node_id", "at0001"); + valueMap.put("name", name); + valueMap.put("value", value); + assertMatchedRMClass("Element"); + } + + public void testMatchItemList() { + DvText name = new DvText("BP measurement"); + DvQuantity systolicValue = new DvQuantity("mmHg", 120.0, ms); + DvQuantity diastolicValue = new DvQuantity("mmHg", 80.0, ms); + Element systolicElement = new Element("at0001", + new DvText("systolic"), systolicValue); + Element diastolicElement = new Element("at0002", + new DvText("diastolic"), diastolicValue); + List items = new ArrayList(); + items.add(systolicElement); + items.add(diastolicElement); + valueMap.put("name", name); + valueMap.put("archetypeNodeId", "at0003"); + valueMap.put("items", items); + assertMatchedRMClass("ItemList"); + } + + public void testMatchPointEvent() { + DvQuantity systolicValue = new DvQuantity("mmHg", 120.0, ms); + Element systolicElement = new Element("at0001", + new DvText("systolic"), systolicValue); + List items = new ArrayList(); + items.add(systolicElement); + ItemList itemList = new ItemList("at0003", new DvText("list"), items); + valueMap.put("name", new DvText("point event")); + valueMap.put("archetypeNodeId", "at0004"); + valueMap.put("data", itemList); + valueMap.put("time", new DvDateTime("2005-12-03T09:22:00")); + assertMatchedRMClass("PointEvent"); + } + + public void testMatchingHistory() { + DvQuantity systolicValue = new DvQuantity("mmHg", 120.0, ms); + Element systolicElement = new Element("at0001", + new DvText("systolic"), systolicValue); + List items = new ArrayList(); + items.add(systolicElement); + ItemList itemList = new ItemList("at0003", new DvText("list"), items); + PointEvent event = new PointEvent("at0004", new DvText("event"), + new DvDateTime("2005-12-03T09:22:00"), itemList); + List events = new ArrayList(); + events.add(event); + + valueMap.put("name", new DvText("history")); + valueMap.put("archetypeNodeId", "at0005"); + valueMap.put("origin", new DvDateTime("2005-12-03T10:22:00")); + valueMap.put("events", events); + assertMatchedRMClass("History"); + } + + public void testMatchObservation() { + DvQuantity systolicValue = new DvQuantity("mmHg", 120.0, ms); + Element systolicElement = new Element("at0001", + new DvText("systolic"), systolicValue); + List items = new ArrayList(); + items.add(systolicElement); + ItemList itemList = new ItemList("at0003", new DvText("list"), items); + PointEvent event = new PointEvent("at0004", new DvText("event"), + new DvDateTime("2005-12-03T09:22:00"), itemList); + List events = new ArrayList(); + events.add(event); + History history = new History("at0005", new DvText("history"), + new DvDateTime("2005-12-03T09:22:00"), events); + CodePhrase language = new CodePhrase("ISO_639-1", "en"); + CodePhrase encoding = new CodePhrase("IANA_character-sets", "UTF-8"); + valueMap.put("name", new DvText("observation")); + valueMap.put("archetypeNodeId", "at0006"); + valueMap.put("data", history); + valueMap.put("language", language); + valueMap.put("encoding", encoding); + valueMap.put("subject", new PartySelf()); + valueMap.put("archetypeDetails", new Archetyped(new ArchetypeID( + "openEHR-EHR-OBSERVATION.laboratory.v1"), "1.0")); + assertMatchedRMClass("Observation"); + } + + public void testMatchArchetyped() throws Exception { + ArchetypeID archetypeId = new ArchetypeID( + "openEHR-EHR-OBSERVATION.blood_pressure.v1"); + valueMap.put("archetypeId", archetypeId); + valueMap.put("rmVersion", "1.0.1"); + assertMatchedRMClass("Archetyped"); + } + + private void assertMatchedRMClass(String expectedRMClass) { + String actualRMClass = builder.findMatchingRMClass(valueMap); + assertEquals("failed to match " + expectedRMClass, expectedRMClass, + actualRMClass); + } + + private Map valueMap; + private RMObjectBuilder builder; + private MeasurementService ms; + private TerminologyService ts; +} +/* + * ***** 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 FindMatchingRMClassTest.java + * + * The Initial Developer of the Original Code is Rong Chen. + * Portions created by the Initial Developer are Copyright (C) 2006-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/rm-skeleton/hypersensitivity_drug.dadl b/rm-skeleton/hypersensitivity_drug.dadl new file mode 100644 index 00000000..d0a61a4a --- /dev/null +++ b/rm-skeleton/hypersensitivity_drug.dadl @@ -0,0 +1,136 @@ +(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 = + > + > + [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_drug_sulfa.dadl b/rm-skeleton/hypersensitivity_drug_sulfa.dadl new file mode 100644 index 00000000..0a15e58a --- /dev/null +++ b/rm-skeleton/hypersensitivity_drug_sulfa.dadl @@ -0,0 +1,157 @@ +(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 = <"Sulfa"> + > + > + [3] = (ELEMENT) < + archetype_node_id = <"at0009"> + name = (DV_TEXT) < + value = <"Agent"> + > + value = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"J01E A"> + terminology_id = (TERMINOLOGY_ID) < + value = <"ATC"> + > + > + value = <"Trimetoprim och derivat"> + > + > + [4] = (ELEMENT) < + archetype_node_id = <"at0009"> + name = (DV_TEXT) < + value = <"Agent"> + > + value = (DV_CODED_TEXT) < + defining_code = (CODE_PHRASE) < + code_string = <"J01E E"> + terminology_id = (TERMINOLOGY_ID) < + value = <"ATC"> + > + > + value = <"Sulfonamider och trimetoprim, kombinationer"> + > + > + [5] = (ELEMENT) < + archetype_node_id = <"at0010"> + name = (DV_TEXT) < + value = <"Comment"> + > + value = (DV_TEXT) < + value = <"Absolute contraindication"> + > + > + [6] = (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> + > + > + [7] = (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> + > + > + [8] = (ELEMENT) < + archetype_node_id = <"at0019"> + name = (DV_TEXT) < + value = <"Is reassessment required"> + > + value = (DV_BOOLEAN) < + value = + > + > + [9] = (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_food_milk.dadl b/rm-skeleton/hypersensitivity_food_milk.dadl new file mode 100644 index 00000000..2e908b29 --- /dev/null +++ b/rm-skeleton/hypersensitivity_food_milk.dadl @@ -0,0 +1,118 @@ +(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 = <"Food"> + > + > + [2] = (ELEMENT) < + archetype_node_id = <"at0003"> + name = (DV_TEXT) < + value = <"Heading"> + > + value = (DV_TEXT) < + value = <"Milk allergy"> + > + > + [3] = (ELEMENT) < + archetype_node_id = <"at0009"> + name = (DV_TEXT) < + value = <"Agent"> + > + value = (DV_TEXT) < + value = <"Milk protein"> + > + > + [4] = (ELEMENT) < + archetype_node_id = <"at0010"> + name = (DV_TEXT) < + value = <"Comment"> + > + value = (DV_TEXT) < + value = <"Skin rash"> + > + > + [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 = <"at0014"> + terminology_id = (TERMINOLOGY_ID) < + value = <"local"> + > + > + value = <"Troublesome"> + > + value = <3> + > + > + [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> + > + > + > + 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_max.dadl b/rm-skeleton/hypersensitivity_max.dadl new file mode 100644 index 00000000..0694390f --- /dev/null +++ b/rm-skeleton/hypersensitivity_max.dadl @@ -0,0 +1,136 @@ +(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 new file mode 100644 index 00000000..d0a61a4a --- /dev/null +++ b/rm-skeleton/hypersensitivity_maximum.dadl @@ -0,0 +1,136 @@ +(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 = + > + > + [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_min.dadl b/rm-skeleton/hypersensitivity_min.dadl new file mode 100644 index 00000000..0694390f --- /dev/null +++ b/rm-skeleton/hypersensitivity_min.dadl @@ -0,0 +1,136 @@ +(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 new file mode 100644 index 00000000..ab0b199f --- /dev/null +++ b/rm-skeleton/pom.xml @@ -0,0 +1,94 @@ + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5-SNAPSHOT + + rm-skeleton + jar + openEHR RM Skeleton Instance Generator + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + openehr-aom + ${project.version} + + + openehr + adl-parser + ${project.version} + + + openehr + dadl-parser + ${project.version} + + + openehr + oet-parser + ${project.version} + + + openehr + measure-serv + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + openehr + dadl-binding + ${project.version} + + + openehr + xml-binding + ${project.version} + + + junit + junit + 4.5 + test + + + com.thoughtworks.xstream + xstream + 1.3.1 + test + + + openehr + adl-serializer + ${project.version} + test + + + log4j + log4j + 1.2.13 + + + commons-io + commons-io + 1.4 + 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 new file mode 100644 index 00000000..a1e49619 --- /dev/null +++ b/rm-skeleton/src/main/java/org/openehr/rm/util/GenerationStrategy.java @@ -0,0 +1,58 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Class GenerationStrategy" + * keywords: "rm-skeleton" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2009,2010 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ + +package org.openehr.rm.util; + +public enum GenerationStrategy { + + /** + * Minimum structure with default or mock data values + */ + MINIMUM, + + /** + * Maximum structure with default or mock data values + */ + MAXIMUM, + + /** + * Maximum structure with empty data elements + */ + MAXIMUM_EMPTY +} +/* + * ***** 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 GenerationStrategy.java + * + * The Initial Developer of the Original Code is Rong Chen. Portions created by + * the Initial Developer are Copyright (C) 2009-2010 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/rm-skeleton/src/main/java/org/openehr/rm/util/RMUtil.java b/rm-skeleton/src/main/java/org/openehr/rm/util/RMUtil.java new file mode 100644 index 00000000..e849fe35 --- /dev/null +++ b/rm-skeleton/src/main/java/org/openehr/rm/util/RMUtil.java @@ -0,0 +1,236 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Class RMUtil" + * keywords: "rm-skeleton" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2009,2010 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.rm.util; + +import java.util.Iterator; +import java.util.List; + +import org.apache.log4j.Logger; +import org.openehr.rm.composition.Composition; +import org.openehr.rm.composition.content.ContentItem; +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.Entry; +import org.openehr.rm.composition.content.entry.Evaluation; +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.itemstructure.ItemList; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datastructure.itemstructure.ItemTree; +import org.openehr.schemas.v1.ACTIVITY; + +/** + * Support class that provide various utility functions + * + * TODO + * some of these functions could end up in RM classes themselves + * + * @author rong.chen + * + */ + +public class RMUtil { + + /** + * Clears away unnecessary RM structure in given composition + * + * The following structures are purged + * 1. section with empty list of items + * 2. entry with empty items as data or other key attributes + * + * TODO + * only entry type Observation is expected for now + * + * @param composition + */ + public static void purge(Composition composition) { + + log.debug("Composition.purge() started.."); + + List items = composition.getContent(); + + for(Iterator it = items.iterator(); it.hasNext();) { + ContentItem item = it.next(); + if(isEmpty(item)) { + + it.remove(); + + log.debug("item of class " + item.getClass() + ", removed.."); + + } else if(item instanceof Section) { + + Section section = (Section) item; + purge(section); + } + } + + log.debug("Composition.purge() finished.."); + } + + + /** + * Purges the given section. Recursive function. + * + * + * @param section + */ + public static void purge(Section section) { + + log.debug("Section.purge() started.. "); + + List items = section.getItems(); + + for(Iterator it = items.iterator(); it.hasNext();) { + ContentItem item = it.next(); + + if(isEmpty(item)) { + + it.remove(); + + log.debug("item of class " + item.getClass() + ", removed.."); + + } else if(item instanceof Section) { + + Section subsection = (Section) item; + purge(subsection); + } + } + + log.debug("Section.purge() finished.. "); + } + + private static boolean isEmpty(Section section) { + List items = section.getItems(); + if(items.isEmpty()) { + return true; + } + for(Iterator it = items.iterator(); it.hasNext();) { + ContentItem item = it.next(); + if( ! isEmpty(item)) { + return false; + } + } + return true; + } + + private static boolean isEmpty(ContentItem item) { + if(item instanceof Section) { + return isEmpty((Section) item); + } else { + return isEmpty((Entry) item); + } + } + + private static boolean isEmpty(Entry entry) { + + if(entry instanceof Observation) { + + Observation obs = (Observation) entry; + return isEmpty(obs.getData()); + + } else if(entry instanceof Evaluation) { + + Evaluation eval = (Evaluation) entry; + return isEmpty(eval.getData()); + + } else if(entry instanceof Instruction) { + + Instruction intr = (Instruction) entry; + List activities = intr.getActivities(); + if(activities.isEmpty()) { + return true; + } + for(Iterator it = activities.iterator(); it.hasNext();) { + Activity activity = it.next(); + if( ! isEmpty(activity.getDescription())) { + return false; + } + } + return true; + + } else if(entry instanceof Action) { + + Action action = (Action) entry; + return isEmpty(action.getDescription()); + + } else if(entry instanceof AdminEntry) { + + AdminEntry admin = (AdminEntry) entry; + return isEmpty(admin.getData()); + } else { + throw new UnsupportedOperationException("unsupported entry type"); + } + } + + private static boolean isEmpty(History history) { + if(history.getEvents().isEmpty()) { + return true; + } + for(Iterator it = history.getEvents().iterator(); it.hasNext();) { + Event event = (Event) it.next(); + if( ! isEmpty(event.getData())) { + return false; + } + } + return true; + } + + private static boolean isEmpty(ItemStructure structure) { + if(structure instanceof ItemList) { + + ItemList list = (ItemList) structure; + return list.getItems().isEmpty(); + + } else if(structure instanceof ItemTree) { + + ItemTree tree = (ItemTree) structure; + return tree.getItems().isEmpty(); + + } else { + // TODO more types + throw new UnsupportedOperationException(); + } + } + + private static final Logger log = Logger.getLogger(RMUtil.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 RMUtil.java + * + * The Initial Developer of the Original Code is Rong Chen. Portions created by + * the Initial Developer are Copyright (C) 2009-2010 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/rm-skeleton/src/main/java/org/openehr/rm/util/SkeletonGenerator.java b/rm-skeleton/src/main/java/org/openehr/rm/util/SkeletonGenerator.java new file mode 100644 index 00000000..999f1ee8 --- /dev/null +++ b/rm-skeleton/src/main/java/org/openehr/rm/util/SkeletonGenerator.java @@ -0,0 +1,939 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Class SkeletonGenerator" + * keywords: "rm-skeleton" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2009,2010 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.rm.util; + +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.*; + +import org.apache.log4j.Logger; +import org.openehr.am.archetype.Archetype; +import org.openehr.am.archetype.constraintmodel.*; +import org.openehr.am.archetype.constraintmodel.primitive.*; +import org.openehr.am.archetype.ontology.ArchetypeTerm; +import org.openehr.am.openehrprofile.datatypes.quantity.*; +import org.openehr.am.openehrprofile.datatypes.text.CCodePhrase; +import org.openehr.am.template.TermMap; +import org.openehr.build.RMObjectBuilder; +import org.openehr.build.SystemValue; +import org.openehr.rm.common.archetyped.Archetyped; +import org.openehr.rm.common.generic.PartyIdentified; +import org.openehr.rm.common.generic.PartySelf; +import org.openehr.rm.datastructure.itemstructure.ItemTree; +import org.openehr.rm.datatypes.encapsulated.DvMultimedia; +import org.openehr.rm.datatypes.encapsulated.DvParsable; +import org.openehr.rm.datatypes.quantity.DvOrdinal; +import org.openehr.rm.datatypes.quantity.DvQuantity; +import org.openehr.rm.datatypes.quantity.ProportionKind; +import org.openehr.rm.datatypes.quantity.datetime.*; +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.datatypes.uri.DvURI; +import org.openehr.rm.support.identification.*; +import org.openehr.rm.support.measurement.*; +import org.openehr.rm.support.terminology.TerminologyAccess; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.terminology.SimpleTerminologyService; + +public class SkeletonGenerator { + + /** + * Factory method to get instance of the RM skeleton generator + * + * @return + */ + public static SkeletonGenerator getInstance() throws Exception { + return new SkeletonGenerator(); + } + + /* private constructor */ + private SkeletonGenerator() throws Exception { + measurementService = SimpleMeasurementService.getInstance(); + terminologyService = SimpleTerminologyService.getInstance(); + openEHRTerminology = terminologyService.terminology( + TerminologyService.OPENEHR); + + builder = initializeBuilder(); + termMap = new TermMap(); + } + + // TODO lots of hard-coded settings for the RM builder + private RMObjectBuilder initializeBuilder() { + CodePhrase lang = new CodePhrase("ISO_639-1", "sv"); + CodePhrase charset = new CodePhrase("IANA_character-sets", "UTF-8"); + + + + Map values = new HashMap(); + values.put(SystemValue.LANGUAGE, lang); + values.put(SystemValue.ENCODING, charset); + + values.put(SystemValue.TERMINOLOGY_SERVICE, terminologyService); + values.put(SystemValue.MEASUREMENT_SERVICE, measurementService); + return RMObjectBuilder.getInstance(values); + } + + public void loadTermMapFromFile(String filename) throws Exception { + InputStream input = new FileInputStream(filename); + termMap.addAll(input); + } + + public void loadTermMapFromClasspath(String filename) throws Exception { + InputStream input = + SkeletonGenerator.class.getClassLoader().getResourceAsStream(filename); + if(input == null) throw new IllegalArgumentException("Can not open filename="+filename); + termMap.clear(); + termMap.addAll(input); + } + + /** + * Create RM object tree based on given archetype with a default minimum strategy + * + * @param archetype + * @return + * @throws Exception + */ + public Object create(Archetype archetype) throws Exception { + return create(archetype, null, null, null, GenerationStrategy.MINIMUM); + } + + public Object create(Archetype archetype, + GenerationStrategy strategy) throws Exception { + return create(archetype, null, null, null, strategy); + } + + //Only used for adding slots + public Object create(Archetype archetype, Map extraValues, + GenerationStrategy strategy) throws Exception { + return create(archetype, null, null, extraValues, strategy); + } + + + /** + * Create RM object tree based on given main the archetype and + * associated archetypes in the archetypeMap + * + * TODO + * This entry is used to create object tree for flattened templates + * + * @param archetype + * @return + * @throws Exception + */ + public Object create(Archetype archetype, + Map archetypeMap) throws Exception { + + return create(archetype, null, archetypeMap, null, GenerationStrategy.MINIMUM); + } + + /** + * Create RM object tree with specified template + * + * @param archetype + * @param templateId + * @param archetypeMap + * @param extraValues extra values indexed by path + * @param strategy + * @return + * @throws Exception + */ + public Object create(Archetype archetype, String templateId, + Map archetypeMap, + Map extraValues, + GenerationStrategy strategy) throws Exception { + + return createComplexObject(archetype.getDefinition(), archetype, + templateId, archetypeMap, extraValues, strategy); + } + + public Object create(Archetype archetype, String templateId, + Map archetypeMap, + GenerationStrategy strategy) throws Exception { + + return createComplexObject(archetype.getDefinition(), archetype, + templateId, archetypeMap, null, strategy); + } + + /* + * Entering point for complex object creation + */ + public Object createComplexObject(CComplexObject ccobj, + Archetype archetype, String templateId, + Map archetypeMap, + Map extraValues, + GenerationStrategy strategy) throws Exception { + + log.debug("create complex object " + ccobj.getRmTypeName()); + + Map valueMap = new HashMap(); + valueMap.put(TEMPLATE_ID, templateId); + + String nodeId = ccobj.getNodeId(); + if(nodeId != null) { + DvText name; + + // root node with archetype_id as node_id + // TODO check if name is already define? + if(nodeId.startsWith("openEHR")) { + archetype = archetypeMap.get(nodeId); + if(archetype == null) { + throw new Exception("unknown archetype for nodeId: " + nodeId); + } + name = retrieveName(archetype.getConcept(), archetype); + } else { + name = retrieveName(nodeId, archetype); + } + valueMap.put("name", name); + + // use archetypeId instead of nodeId for root + if(nodeId.equals(archetype.getConcept())) { + nodeId = archetype.getArchetypeId().toString(); + } + valueMap.put("archetype_node_id", nodeId); + } + + String rmTypeName = ccobj.getRmTypeName(); + + if(ccobj.getAttributes() != null && ccobj.getAttributes().size() > 0) { + for(CAttribute cattr : ccobj.getAttributes()) { + + // TODO create 'required' attribute + if(cattr.isAllowed() + && (GenerationStrategy.MAXIMUM.equals(strategy) + || GenerationStrategy.MAXIMUM_EMPTY.equals(strategy) + || (GenerationStrategy.MINIMUM.equals(strategy) + && cattr.isRequired()))) { + Object attrValue; + String path = cattr.path(); + + if(extraValues != null && extraValues.containsKey(path)) { + attrValue = extraValues.get(path); + } else { + attrValue = createAttribute(cattr, archetype, archetypeMap, extraValues, strategy); + } + valueMap.put(cattr.getRmAttributeName(), attrValue); + + } else if("CLUSTER".equals(rmTypeName)) { // TODO quickfix + + Object attrValue = createAttribute(cattr, archetype, + archetypeMap, extraValues, strategy); + valueMap.put(cattr.getRmAttributeName(), attrValue); + } + } + } + + // deal with missing required attributes in RM + if("DV_TEXT".equals(rmTypeName)) { + + if(! valueMap.containsKey(VALUE)) { + valueMap.put(VALUE, "text value"); + } + + } else if("DV_CODED_TEXT".equals(rmTypeName)) { + + // TODO type-check is temporary fix + Object definingCode = valueMap.get(DEFINING_CODE); + CodePhrase codePhrase = null; + + + if( ! (definingCode instanceof CodePhrase)) { + valueMap.put(DEFINING_CODE, new CodePhrase("local", "at9999")); + } else { + codePhrase = (CodePhrase) valueMap.get(DEFINING_CODE); + } + + + if(valueMap.get(VALUE) == null) { + String text = null; + + if(codePhrase != null) { + String code = codePhrase.getCodeString(); + + if(isLocallyDefined(codePhrase)) { + + // archetype terms + text = retrieveArchetypeTermText(code, archetype); + + } else if(isOpenEHRTerm(codePhrase)) { + + // openEHR terms + // TODO hard-coded language "en" + text = openEHRTerminology.rubricForCode(code, "en"); + + } else { + + // externally defined term + text = termMap.getText(codePhrase, ccobj.path()); + } + } + if(text == null) { + text = DEFAULT_CODED_TEXT; + } + valueMap.put(VALUE, text); + } + + + } else if("DV_URI".equals(rmTypeName) || "DV_EHR_URI".equals(rmTypeName)) { + + if(! valueMap.containsKey(VALUE)) { + valueMap.put(VALUE, DEFAULT_URI); + } + + }else if("DV_DATE_TIME".equals(rmTypeName)) { + + if( ! valueMap.containsKey(VALUE)) { + valueMap.put(VALUE, DEFAULT_DATE_TIME); + } + + } else if("DV_DATE".equals(rmTypeName)) { + + if( ! valueMap.containsKey(VALUE)) { + valueMap.put(VALUE, DEFAULT_DATE); + } + + } else if("DV_TIME".equals(rmTypeName)) { + + if( ! valueMap.containsKey(VALUE)) { + valueMap.put(VALUE, DEFAULT_TIME); + } + + } else if("DV_MULTIMEDIA".equals(rmTypeName)) { + + CodePhrase charset = new CodePhrase("IANA_character-sets", "UTF-8"); + CodePhrase language = new CodePhrase("ISO_639-1","en"); + String alternateText = "alternative text"; + CodePhrase mediaType = new CodePhrase("IANA_media-types", "text/plain"); + CodePhrase compressionAlgorithm = new CodePhrase("openehr_compression_algorithms", "other"); + //byte[] integrityCheck = new byte[0]; + CodePhrase integrityCheckAlgorithm = new CodePhrase("openehr_integrity_check_algorithms", "SHA-1"); + DvMultimedia thumbnail = null; + DvURI uri = new DvURI("www.iana.org"); + //byte[] data = new byte[0]; + TerminologyService terminologyService = SimpleTerminologyService.getInstance(); + DvMultimedia dm = new DvMultimedia(charset, language, alternateText, + mediaType, compressionAlgorithm, null, + integrityCheckAlgorithm, thumbnail, uri, null, terminologyService); + + return dm; + + } else if("DV_COUNT".equals(rmTypeName)) { + + if(valueMap.get(MAGNITUDE) == null) { + valueMap.put(MAGNITUDE, DEFAULT_COUNT); + } + }else if("DV_DURATION".equals(rmTypeName)) { + if(valueMap.get(VALUE) == null) { + valueMap.put(VALUE, DEFAULT_DURATION); + } + }else if("DV_IDENTIFIER".equals(rmTypeName)) { + if(valueMap.get(ID) == null) { + valueMap.put(ID, DEFAULT_ID); + } + if(valueMap.get(ASSIGNER) == null) { + valueMap.put(ASSIGNER, DEFAULT_ASSIGNER); + } + if(valueMap.get(ISSUER) == null) { + valueMap.put(ISSUER, DEFAULT_ISSUER); + } + if(valueMap.get(TYPE) == null) { + valueMap.put(TYPE, DEFAULT_TYPE); + } + } else if("DV_PROPORTION".equals(rmTypeName)) { + + // default dv_proportion + // DV_PROPORTION) < + // numerator = <0.5> + // denominator = <1.0> + // type = <0> + // precision = <2> + // > + + if( ! valueMap.containsKey("numerator") || ! valueMap.containsKey("denominator")) { + valueMap.put("numerator", "0.5"); + valueMap.put("denominator", "1.0"); + valueMap.put("precision", "1"); + valueMap.put("type", ProportionKind.RATIO); + } + + } else if("HISTORY".equals(rmTypeName)) { + + if(! valueMap.containsKey(ORIGIN)) { + valueMap.put(ORIGIN, new DvDateTime()); + } + + } else if("EVENT".equals(rmTypeName)) { + + if(! valueMap.containsKey(TIME)) { + valueMap.put(TIME, new DvDateTime()); } + + } else if("OBSERVATION".equals(rmTypeName)) { + + addEntryValues(valueMap, archetype); + + } else if("EVALUATION".equals(rmTypeName)) { + + addEntryValues(valueMap, archetype); + + } else if("ADMIN_ENTRY".equals(rmTypeName)) { + + addEntryValues(valueMap, archetype); + + } else if("ACTION".equals(rmTypeName)) { + + addEntryValues(valueMap, archetype); + if( ! valueMap.containsKey(TIME)) { + valueMap.put(TIME, new DvDateTime()); + } + if(valueMap.get(DESCRIPTION) == null) { + valueMap.put(DESCRIPTION, + new ItemTree("at0001", new DvText("tree"), null)); + } + + } else if("INSTRUCTION".equals(rmTypeName)) { + + if( ! valueMap.containsKey(NARRATIVE)) { + valueMap.put(NARRATIVE, new DvText("instruction narrative")); + } + addEntryValues(valueMap, archetype); + + } else if("ACTIVITY".equals(rmTypeName)) { + + if( ! valueMap.containsKey(TIMING)) { + valueMap.put(TIMING, new DvParsable("activity timing", "txt")); + } + if( ! valueMap.containsKey("action_archetype_id")) { + valueMap.put("action_archetype_id", "string value"); + } + } else if("COMPOSITION".equals(rmTypeName)) { + CodePhrase country = new CodePhrase("ISO_3166-1", "SE"); + DvCodedText category = new DvCodedText("event", + new CodePhrase("openehr", "433")); + + if( ! valueMap.containsKey("composer")) { + valueMap.put("composer", PartyIdentified.named("Doctor")); + } + + if( ! valueMap.containsKey("territory")) { + valueMap.put("territory", country); + } + + if( ! valueMap.containsKey("category")) { + valueMap.put("category", category); + } + + addEntryValues(valueMap, archetype); + + } else if("ELEMENT".equals(rmTypeName)) { + + if(GenerationStrategy.MAXIMUM_EMPTY.equals(strategy) + && (("INPUT".equals(ccobj.getAnnotation()) || + ccobj.isAnyAllowed()))) { + + // TODO input annotation needs to be standardized + valueMap.put(VALUE, null); + valueMap.put(NULL_FLAVOUR, NULL_FLAVOUR_VALUE); + + + } else { + + // special fix to create a wrapping dv_coded_text of code_phrase + // should not be necessary now when the AOM from flattener is fixed + Object value = valueMap.get(VALUE); + String text = null; + if(value instanceof CodePhrase) { + CodePhrase code = (CodePhrase) value; + text = termMap.getText(code, ccobj.path() + "/value"); + if(text == null) { + text = DEFAULT_CODED_TEXT; + } + value = new DvCodedText(text, code); + valueMap.put(VALUE, value); + } + } + + } else if("EVENT_CONTEXT".equals(rmTypeName)) { + + if( ! valueMap.containsKey(START_TIME)) { + valueMap.put(START_TIME, new DvDateTime()); + } + + if( ! valueMap.containsKey(SETTING)) { + valueMap.put(SETTING, new DvCodedText("emergency care", + new CodePhrase("openehr", "227"))); + } + + } else if("SECTION".equals(rmTypeName)) { + + List list = (List) valueMap.get("items"); + if(list != null && list.isEmpty()) { + valueMap.remove("items"); + } + } else if("INTERVAL_EVENT".equals(rmTypeName)) { + /*if( ! valueMap.containsKey("width")) { + valueMap.put("width", new DvDuration("P1d")); + } + if( ! valueMap.containsKey("time")) { + valueMap.put("time", new DvDateTime()); + } */ + return null; + + } else if("POINT_EVENT".equals(rmTypeName)) { + if( ! valueMap.containsKey("time")) { + valueMap.put("time", new DvDateTime()); + } + } + + // special fix for event + if("EVENT".equals(rmTypeName)) { + rmTypeName = "POINT_EVENT"; + } + + Object obj = builder.construct(rmTypeName, valueMap); + return obj; + } + + /* + * Checks if given code_prhase is locally defined within an archetype + */ + private boolean isLocallyDefined(CodePhrase code) { + return "local".equalsIgnoreCase(code.getTerminologyId().toString()) + && code.getCodeString().startsWith("at"); + } + + private boolean isOpenEHRTerm(CodePhrase code) { + return "openehr".equalsIgnoreCase(code.getTerminologyId().getValue()); + } + + private void addEntryValues(Map valueMap, + Archetype archetype) throws Exception { + + CodePhrase lang = new CodePhrase("ISO_639-1", "en"); + CodePhrase charset = new CodePhrase("IANA_character-sets", "UTF-8"); + String tid = (String) valueMap.get(TEMPLATE_ID); + TemplateID templateId = tid == null ? null : new TemplateID(tid); + Archetyped archetypeDetails = new Archetyped( + archetype.getArchetypeId(), templateId, "1.0.1"); + + valueMap.put("subject", subject()); + //valueMap.put("provider", provider()); + valueMap.put("encoding", charset); + valueMap.put("language", lang); + valueMap.put("archetype_details", archetypeDetails); + } + + // test subject + protected PartySelf subject() throws Exception { + PartyRef party = new PartyRef(new HierObjectID("1.2.4.5.6.12.1"), + "PARTY"); + return new PartySelf(party); + } + + // test provider + protected PartyIdentified provider() throws Exception { + PartyRef performer = new PartyRef(new HierObjectID("1.3.3.1"), + "ORGANISATION"); + return new PartyIdentified(performer, "provider's name", null); + } + + public Object createAttribute(CAttribute cattribute, Archetype archetype, + Map archetypeMap, Map extraValues, + GenerationStrategy strategy) + throws Exception { + + log.debug("create attribute " + cattribute.getRmAttributeName()); + + List children = cattribute.getChildren(); + if(cattribute instanceof CSingleAttribute) { + + log.debug("single attribute.."); + + if(children != null && children.size() > 0) { + // TODO first child is used for rm generation + CObject cobj = children.get(0); + return createObject(cobj, archetype, archetypeMap, extraValues, strategy); + } else { + throw new Exception ("no child object.."); + } + } else { // multiple c_attribute + + log.debug("multiple attribute.."); + + CMultipleAttribute cma = (CMultipleAttribute) cattribute; + Collection container; + if(cma.getCardinality().isList()) { + container = new ArrayList(); + + } else { + // default container type + container = new ArrayList(); + } + for(CObject cobj : children) { + + log.debug("looping children, required: " + cobj.isRequired()); + + // TODO only create 'required' child + if(cobj.isAllowed() && + (GenerationStrategy.MAXIMUM.equals(strategy) + || GenerationStrategy.MAXIMUM_EMPTY.equals(strategy) + || (GenerationStrategy.MINIMUM.equals(strategy) + && cobj.isRequired()))) { + + log.debug("required child"); + + Object obj = createObject(cobj, archetype, archetypeMap, + extraValues, strategy); + if(obj != null) { + container.add(obj); + } + } + + // special fix for mistaken optional event: + // events cardinality matches {1..*; unordered} matches { + // EVENT[at0003] occurrences matches {0..*} matches { + else if("events".equals(cma.getRmAttributeName()) + && "EVENT".equals(cobj.getRmTypeName())) { + + log.debug("mandatory events attribute fix"); + + container.add(createObject(cobj, archetype, archetypeMap, + extraValues, strategy)); + } + } + + // TODO special rule to include first child + if(container.isEmpty()) { + + log.debug("add first child for empty container attribute"); + + // disabled + // container.add(createObject(children.get(0), archetype)); + return null; + } + + return container; + } + } + + public Object createObject(CObject cobj, Archetype archetype, + Map archetypeMap, Map extraValues, + GenerationStrategy strategy) throws Exception { + + log.debug("create object with constraint " + cobj.getClass()); + + if(cobj instanceof CComplexObject) { + + // no need for templateId at this level + return createComplexObject((CComplexObject) cobj, + archetype, null, archetypeMap, extraValues, strategy); + + } else if(cobj instanceof CPrimitiveObject) { + + return createPrimitiveTypeObject((CPrimitiveObject) cobj, 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? + return null; + } + } + + //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 { + + CPrimitive cp = cpo.getItem(); + + if(cp.hasDefaultValue()) { + return cp.defaultValue(); + } + + if(cp instanceof CBoolean) { + if(((CBoolean) cp).isTrueValid()) { + return "true"; + } else { + return "false"; + } + + } else if(cp instanceof CString) { + + return createString((CString) cp); + + } else if(cp instanceof CDate) { + + return DEFAULT_DATE; + + } else if(cp instanceof CTime) { + + return DEFAULT_TIME; + + } else if(cp instanceof CDateTime) { + + return DEFAULT_DATE_TIME; + + } else if(cp instanceof CInteger) { + + return new Integer(0); + + } else if(cp instanceof CReal) { + + return new Double(0); + + } else if(cp instanceof CDuration) { + + CDuration cd = (CDuration) cp; + DvDuration duration = null; + + if(cd.hasAssignedValue()) { + duration = cd.assignedValue(); + + } else if(cd.hasDefaultValue()) { + duration = cd.defaultValue(); + + } else if(cd.hasAssumedValue()) { + duration = cd.assumedValue(); + + } else if(cd.getInterval() != null) { + + if(cd.getInterval().getLower() != null) { + duration = cd.getInterval().getLower(); + + } else if(cd.getInterval().getUpper() != null) { + duration = cd.getInterval().getUpper(); + } + } + if(duration == null) { + return DEFAULT_DURATION; + } else { + return duration.toString(); + } + + } + + // TODO implement other types + throw new Exception("unsupported primitive type: " + cp.getType()); + } + + private String createString(CString cs) { + if(cs.defaultValue() != null) { + + return cs.defaultValue(); + + } else if (cs.getList() != null && cs.getList().size() > 0) { + + return cs.getList().get(0); + + } else { + return "string value"; + } + } + + private Object createDomainTypeObject(CDomainType cpo, Archetype archetype) + throws Exception { + + if(cpo instanceof CDvQuantity) { + + return createDvQuantity((CDvQuantity) cpo); + + } else if(cpo instanceof CCodePhrase) { + + return createCodePhrase((CCodePhrase) cpo); + + } else if(cpo instanceof CDvOrdinal) { + + return createDvOrdinal((CDvOrdinal) cpo, archetype); + + } else { + throw new Exception("unsupported c_domain_type: " + cpo.getClass()); + } + } + + private DvOrdinal createDvOrdinal(CDvOrdinal cdo, Archetype archetype) + throws Exception { + + if(cdo.getDefaultValue() != null) { + Ordinal o = cdo.getDefaultValue(); + return new DvOrdinal(o.getValue(), + new DvCodedText(DEFAULT_CODED_TEXT, o.getSymbol())); + } + Set list = cdo.getList(); + if(list == null || list.size() == 0) { + throw new Exception("empty list of ordinal"); + } + Ordinal ordinal = list.iterator().next(); + String text = DEFAULT_CODED_TEXT; + CodePhrase symbol = ordinal.getSymbol(); + String code = symbol.getCodeString(); + + if(isLocallyDefined(symbol)) { + text = retrieveArchetypeTermText(code, archetype); + } else { + text = termMap.getText(symbol, cdo.path()); + } + + return new DvOrdinal(ordinal.getValue(), + new DvCodedText(text, ordinal.getSymbol())); + } + + CodePhrase createCodePhrase(CCodePhrase ccp) throws Exception { + if(ccp.getDefaultValue() != null) { + return ccp.getDefaultValue(); + } + TerminologyID tid = ccp.getTerminologyId(); + List codeList = ccp.getCodeList(); + + String code; + if(codeList == null || codeList.isEmpty()) { + code = "0123456789"; + } else { + code = codeList.get(0); + } + return new CodePhrase(tid, code); + } + + DvQuantity createDvQuantity(CDvQuantity cdq) throws Exception { + if(cdq.getList() == null || cdq.getList().isEmpty()) { + return new DvQuantity(0.0); + } + // TODO take the first item + CDvQuantityItem item = cdq.getList().get(0); + + // TODO take the lower limit as magnitude or zero + double magnitude; + if(item.getMagnitude() != null) { + magnitude = item.getMagnitude().getLower(); + } else { + magnitude = 0; + } + + return new DvQuantity(item.getUnits(), magnitude, measurementService); + } + + /* + * Retrieves a language-specific name of given nodeId + * + * TODO hard-coded to retrieve the first language for now + */ + DvText retrieveName(String nodeId, Archetype archetype) throws Exception { + DvText name = new DvText(retrieveArchetypeTermText(nodeId, archetype)); + return name; + } + + /* + * Retrieves just the text of given nodeId (at code) + * + * @param nodeId + * @param archetype + * @return + * @throws Exception + */ + String retrieveArchetypeTermText(String nodeId, Archetype archetype) throws Exception { + String language = archetype.getOriginalLanguage().getCodeString(); + ArchetypeTerm term = archetype.getOntology().termDefinition(language, nodeId); + if(term == null) { + throw new Exception("term of given code: " + nodeId + + ", language: " + language + " not found.."); + } + return term.getText(); + } + + void processCObject(CObject cobj) { + + } + + // rm attribute names + private static final String VALUE = "value"; + private static final String NULL_FLAVOUR = "null_flavour"; + private static final String NARRATIVE = "narrative"; + private static final String DEFINING_CODE = "defining_code"; + private static final String ORIGIN = "origin"; + private static final String TIME = "time"; + private static final String TIMING = "timing"; + private static final String START_TIME = "start_time"; + private static final String SETTING = "setting"; + private static final String DESCRIPTION = "description"; + private static final String MAGNITUDE = "magnitude"; + private static final String TEMPLATE_ID = "template_id"; + private static final String ID = "id"; + private static final String ASSIGNER = "assigner"; + private static final String ISSUER = "issuer"; + private static final String TYPE = "type"; + + // default values + private static final String DEFAULT_DATE = "2010-01-01"; + private static final String DEFAULT_TIME = "10:00:00"; + private static final String DEFAULT_DATE_TIME = "2010-01-01T10:00:00"; + private static final String DEFAULT_DURATION = "PT1H"; + private static final String DEFAULT_TEXT = "text value"; + private static final String DEFAULT_CODED_TEXT = "coded text value"; + private static final String DEFAULT_COUNT = "1"; + private static final String DEFAULT_URI = "http://www.google.com/"; + private static final String DEFAULT_ID = "1"; + private static final String DEFAULT_ISSUER = "1"; + private static final String DEFAULT_ASSIGNER = "1"; + private static final String DEFAULT_TYPE = "1"; + + private static final DvCodedText NULL_FLAVOUR_VALUE = new DvCodedText( + "no information", new CodePhrase(TerminologyService.OPENEHR, "271")); + + private static final Logger log = Logger.getLogger(SkeletonGenerator.class); + + private RMObjectBuilder builder; + private TermMap termMap; + private MeasurementService measurementService; + private TerminologyService terminologyService; + private TerminologyAccess openEHRTerminology; +} +/* + * ***** 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 SkeletonGenerator.java + * + * The Initial Developer of the Original Code is Rong Chen. Portions created by + * the Initial Developer are Copyright (C) 2009-2010 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/rm-skeleton/src/test/java/org/openehr/rm/util/CodedTextTest.java b/rm-skeleton/src/test/java/org/openehr/rm/util/CodedTextTest.java new file mode 100644 index 00000000..f907fb49 --- /dev/null +++ b/rm-skeleton/src/test/java/org/openehr/rm/util/CodedTextTest.java @@ -0,0 +1,63 @@ +package org.openehr.rm.util; + +import org.openehr.rm.datastructure.itemstructure.ItemTree; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datatypes.text.DvCodedText; + +public class CodedTextTest extends SkeletonGeneratorTestBase { + + public CodedTextTest() throws Exception { + } + + public void testSingleCodedTextElementTreeWithTermMap() throws Exception { + archetype = loadArchetype("openEHR-EHR-ITEM_TREE.medication_test_two.v1.adl"); + expected = loadData("item_tree_medicataion_8.dadl"); + + generator.loadTermMapFromClasspath("terms.txt"); + instance = generator.create(archetype); + + Element e1 = (Element) ((ItemTree) instance).getItems().get(0); + Element e2 = (Element) ((ItemTree) expected).getItems().get(0); + + DvCodedText t1 = (DvCodedText) e1.getValue(); + DvCodedText t2 = (DvCodedText) e2.getValue(); + assertEquals(t1, t2); + + assertEquals(e2, e1); + assertEquals(expected, instance); + } + + public void testCodedTextElementWithLocalTerm() throws Exception { + archetype = loadArchetype("openEHR-EHR-ITEM_TREE.medication_test_nine.v1.adl"); + expected = loadData("item_tree_medicataion_11.dadl"); + + generator.loadTermMapFromClasspath("terms.txt"); + instance = generator.create(archetype); + + Element e1 = (Element) ((ItemTree) instance).getItems().get(0); + Element e2 = (Element) ((ItemTree) expected).getItems().get(0); + + DvCodedText t1 = (DvCodedText) e1.getValue(); + DvCodedText t2 = (DvCodedText) e2.getValue(); + assertEquals(t2, t1); + + assertEquals(e1, e2); + assertEquals(expected, instance); + } + + public void testSingleCodedTextElementTree() throws Exception { + archetype = loadArchetype("openEHR-EHR-ITEM_TREE.medication_test_two.v1.adl"); + expected = loadData("item_tree_medicataion_2.dadl"); + instance = generator.create(archetype); + + Element e1 = (Element) ((ItemTree) instance).getItems().get(0); + Element e2 = (Element) ((ItemTree) expected).getItems().get(0); + + DvCodedText t1 = (DvCodedText) e1.getValue(); + DvCodedText t2 = (DvCodedText) e2.getValue(); + assertEquals(t1, t2); + + assertEquals(e1, e2); + assertEquals(expected, instance); + } +} 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 new file mode 100644 index 00000000..c6d3f0fc --- /dev/null +++ b/rm-skeleton/src/test/java/org/openehr/rm/util/GenerateHypersensitivityTest.java @@ -0,0 +1,33 @@ +package org.openehr.rm.util; + +import java.io.File; +import java.util.List; + +import org.apache.commons.io.FileUtils; +import org.openehr.am.archetype.Archetype; + +public class GenerateHypersensitivityTest extends SkeletonGeneratorTestBase { + + public GenerateHypersensitivityTest() throws Exception { + super(); + // TODO Auto-generated constructor stub + } + + public void testGenerateSimpleHypersensitivity() throws Exception { + Archetype archetype = loadArchetype("openEHR-EHR-EVALUATION.hypersensitivity.v1.adl"); + assertNotNull(archetype); + + Object obj = generator.create(archetype, null, archetypeMap, + GenerationStrategy.MAXIMUM); + + List lines = dadlBinding.toDADL(obj); + + FileUtils.writeLines(new File("hypersensitivity_max.dadl"), lines); + + generator.create(archetype, null, archetypeMap, + GenerationStrategy.MINIMUM); + + lines = dadlBinding.toDADL(obj); + FileUtils.writeLines(new File("hypersensitivity_min.dadl"), lines); + } +} 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 new file mode 100644 index 00000000..b09e797d --- /dev/null +++ b/rm-skeleton/src/test/java/org/openehr/rm/util/GenerateNestedSectionsTest.java @@ -0,0 +1,25 @@ +package org.openehr.rm.util; + +import org.openehr.am.archetype.Archetype; +import org.openehr.rm.composition.content.navigation.Section; + +public class GenerateNestedSectionsTest extends SkeletonGeneratorTestBase { + + public GenerateNestedSectionsTest() throws Exception { + } + + public void testWithOptionalChildren() throws Exception { + Archetype flattened = flattenTemplate( + "test_nested_sections_with_optional_children"); + + Object obj = generator.create(flattened, null, archetypeMap, + GenerationStrategy.MINIMUM); + + assertTrue(obj instanceof Section); + Section section = (Section) obj; + + // section.name from archetype + String path = "/items[openEHR-EHR-SECTION.ad_hoc_heading.v1]/name/value"; + assertNull("unexpected nested section", section.itemAtPath(path)); + } +} 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 new file mode 100644 index 00000000..d35fd94a --- /dev/null +++ b/rm-skeleton/src/test/java/org/openehr/rm/util/OrdinalTest.java @@ -0,0 +1,42 @@ +package org.openehr.rm.util; + +import org.openehr.rm.datastructure.itemstructure.ItemTree; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datatypes.quantity.DvOrdinal; + +public class OrdinalTest extends SkeletonGeneratorTestBase { + + public OrdinalTest() throws Exception { + } + + public void testDvOrdinalWithLocalCode() throws Exception { + archetype = loadArchetype("openEHR-EHR-ITEM_TREE.medication_test_seven.v1.adl"); + expected = loadData("item_tree_medicataion_9.dadl"); + instance = generator.create(archetype); + + Element e1 = (Element) ((ItemTree) instance).getItems().get(0); + Element e2 = (Element) ((ItemTree) expected).getItems().get(0); + + DvOrdinal t1 = (DvOrdinal) e1.getValue(); + DvOrdinal t2 = (DvOrdinal) e2.getValue(); + assertEquals(t2, t1); + assertEquals(expected, instance); + } + + public void testDvOrdinalWithExternalCode() throws Exception { + archetype = loadArchetype("openEHR-EHR-ITEM_TREE.medication_test_eight.v1.adl"); + expected = loadData("item_tree_medicataion_10.dadl"); + + generator.loadTermMapFromClasspath("terms.txt"); + instance = generator.create(archetype); + + Element e1 = (Element) ((ItemTree) instance).getItems().get(0); + Element e2 = (Element) ((ItemTree) expected).getItems().get(0); + + DvOrdinal t1 = (DvOrdinal) e1.getValue(); + DvOrdinal t2 = (DvOrdinal) e2.getValue(); + assertEquals(t2, t1); + + assertEquals(expected, instance); + } +} 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 new file mode 100644 index 00000000..feed00d7 --- /dev/null +++ b/rm-skeleton/src/test/java/org/openehr/rm/util/RMUtilTest.java @@ -0,0 +1,34 @@ +package org.openehr.rm.util; + +import java.util.List; + +import org.openehr.rm.composition.Composition; +import org.openehr.rm.composition.content.ContentItem; +import org.openehr.rm.composition.content.navigation.Section; + +public class RMUtilTest extends SkeletonGeneratorTestBase { + + public RMUtilTest() throws Exception { + super(); + } + + public void testPurgeWithOneEmptyOneFilledSections() throws Exception { + composition = loadXMLComposition("to_purge.xml"); + + List items = composition.getContent(); + assertEquals("unexpected total sections before purge", 2, items.size()); + + Section section = (Section) items.get(0); + assertEquals("unexpected total section.items before purge", 2, + section.getItems().size()); + + RMUtil.purge(composition); + + items = composition.getContent(); + assertEquals("unexpected total sections after purge", 1, items.size()); + assertEquals("unexpected total section.items before purge", 1, + section.getItems().size()); + } + + private Composition composition; +} 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 new file mode 100644 index 00000000..10d057cc --- /dev/null +++ b/rm-skeleton/src/test/java/org/openehr/rm/util/RootNodeNameTest.java @@ -0,0 +1,18 @@ +package org.openehr.rm.util; + +import org.openehr.rm.datastructure.itemstructure.ItemTree; + +public class RootNodeNameTest extends SkeletonGeneratorTestBase { + + public RootNodeNameTest() throws Exception { + } + + public void testDvOrdinalWithLocalCode() throws Exception { + archetype = loadArchetype("openEHR-EHR-ITEM_TREE.medication_test_seven.v1.adl"); + instance = generator.create(archetype); + + assertTrue(instance instanceof ItemTree); + ItemTree tree = (ItemTree) instance; + assertEquals("Medication description", tree.getName().getValue()); + } +} 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 new file mode 100644 index 00000000..291e0727 --- /dev/null +++ b/rm-skeleton/src/test/java/org/openehr/rm/util/SimpleDvMultimediaTest.java @@ -0,0 +1,31 @@ +package org.openehr.rm.util; + +import org.openehr.rm.datatypes.encapsulated.DvMultimedia; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.datatypes.uri.DvURI; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.terminology.SimpleTerminologyService; + +import junit.framework.TestCase; + +public class SimpleDvMultimediaTest extends TestCase { + + public void testCreateSimpleDvMultimedia() throws Exception { + CodePhrase charset = new CodePhrase("IANA_character-sets", "UTF-8"); + CodePhrase language = new CodePhrase("ISO_639-1","en"); + String alternateText = "alternative text"; + CodePhrase mediaType = new CodePhrase("IANA_media-types", "text/plain"); + CodePhrase compressionAlgorithm = new CodePhrase("openehr_compression_algorithms", "other"); + byte[] integrityCheck = new byte[0]; + CodePhrase integrityCheckAlgorithm = new CodePhrase("openehr_integrity_check_algorithms", "SHA-1"); + DvMultimedia thumbnail = null; + DvURI uri = new DvURI("www.iana.org"); + byte[] data = new byte[0]; + TerminologyService terminologyService = SimpleTerminologyService.getInstance(); + DvMultimedia dm = new DvMultimedia(charset, language, alternateText, + mediaType, compressionAlgorithm, integrityCheck, + integrityCheckAlgorithm, thumbnail, uri, data, terminologyService); + + assertNotNull(dm); + } +} 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 new file mode 100644 index 00000000..43c6e66a --- /dev/null +++ b/rm-skeleton/src/test/java/org/openehr/rm/util/SkeletonGeneratorTestBase.java @@ -0,0 +1,178 @@ +package org.openehr.rm.util; + +import java.io.File; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +import openEHR.v1.template.TEMPLATE; + +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.openehr.am.archetype.Archetype; +import org.openehr.am.parser.ContentObject; +import org.openehr.am.parser.DADLParser; +import org.openehr.am.serialize.ADLSerializer; +import org.openehr.am.template.Flattener; +import org.openehr.am.template.OETParser; +import org.openehr.binding.XMLBinding; +import org.openehr.rm.binding.DADLBinding; +import org.openehr.rm.composition.Composition; +import org.openehr.rm.support.measurement.MeasurementService; +import org.openehr.rm.support.measurement.SimpleMeasurementService; +import org.openehr.schemas.v1.COMPOSITION; +import org.openehr.schemas.v1.CompositionDocument; + +import com.thoughtworks.xstream.XStream; + +import se.acode.openehr.parser.ADLParser; +import junit.framework.TestCase; + +public class SkeletonGeneratorTestBase extends TestCase { + + public SkeletonGeneratorTestBase() throws Exception { + dadlBinding = new DADLBinding(); + xmlBinding = new XMLBinding(); + generator = SkeletonGenerator.getInstance(); + oetParser = new OETParser(); + flattener = new Flattener(); + adlSerializer = new ADLSerializer(); + measurementService = SimpleMeasurementService.getInstance(); + + setXmlOptions(); + loadArchetypeMap(); + } + + private void setXmlOptions() { + xmlOptions = new XmlOptions(); + xmlOptions.setSavePrettyPrint(); + xmlOptions.setSaveAggressiveNamespaces(); + xmlOptions.setSaveOuter(); + xmlOptions.setSaveInner(); + } + + public void tearDown() { + instance = null; + expected = null; + } + + protected Archetype loadArchetype(String id) throws Exception { + ADLParser adlParser = new ADLParser(fromClasspath(ARCHETYPE_PATH + id)); + archetype = adlParser.parse(); + return archetype; + } + + protected InputStream loadXML(String filename) throws Exception { + return fromClasspath(XML_PATH + filename); + } + + /* load a test composition in xml format */ + protected Composition loadXMLComposition(String filename) throws Exception { + COMPOSITION comp = CompositionDocument.Factory.parse( + loadXML(filename)).getComposition(); + + assertTrue("expected composition, but got: " + + (comp == null ? null : comp.getClass()), + comp instanceof COMPOSITION); + + Object rmObj = xmlBinding.bindToRM(comp); + + assertTrue("rmObj not a Composition, got " + + (rmObj == null ? null : rmObj.getClass()), + rmObj instanceof Composition); + + return (Composition) rmObj; + } + + protected InputStream fromClasspath(String filename) throws Exception { + return this.getClass().getClassLoader().getResourceAsStream(filename); + } + + protected Archetype flattenTemplate(String templateFilename) throws Exception { + TEMPLATE template = loadTemplate(templateFilename); + Archetype flattened = flattener.toFlattenedArchetype(template, + archetypeMap, null); + return flattened; + } + + protected TEMPLATE loadTemplate(String name) throws Exception { + String path = TEMPLATE_PATH + name + ".oet"; + TEMPLATE template = oetParser.parseTemplate( + fromClasspath(path)).getTemplate(); + return template; + } + + /* + * Loads dadl from file and binds data to RM object + */ + protected Object loadData(String filename) throws Exception { + DADLParser parser = new DADLParser(fromClasspath(DATA_PATH + filename)); + ContentObject contentObj = parser.parse(); + return dadlBinding.bind(contentObj); + } + + protected void loadArchetypeMap() throws Exception { + String[] ids = { + "openEHR-EHR-ITEM_TREE.medication_test_one.v1", + "openEHR-EHR-SECTION.medications.v1", + "openEHR-EHR-INSTRUCTION.medication.v1", + "openEHR-EHR-ITEM_TREE.medication.v1", + "openEHR-EHR-SECTION.ad_hoc_heading.v1" + }; + + archetypeMap = new HashMap(); + + for(String id : ids) { + Archetype archetype = loadArchetype(id + ".adl"); + archetypeMap.put(archetype.getArchetypeId().toString(), archetype); + } + } + + protected void printXML(Object obj) throws Exception { + Object value = xmlBinding.bindToXML(obj); + XmlObject xmlObj = (XmlObject) value; + xmlObj.save(System.out, xmlOptions); + } + + protected void saveXML(Object obj, String filename) throws Exception { + Object value = xmlBinding.bindToXML(obj); + XmlObject xmlObj = (XmlObject) value; + xmlObj.save(new File(filename), xmlOptions); + } + + protected void printStreamXML(Object toPrint) throws Exception { + XStream xstream = new XStream(); + String xml = xstream.toXML(toPrint); + System.out.println(xml); + } + + /** + * Print out given archetype in ADL for debugging purpose + * + * @param toPrint + * @throws Exception + */ + protected void printADL(Archetype toPrint) throws Exception { + adlSerializer.output(toPrint, System.out); + } + + protected DADLBinding dadlBinding; + private XMLBinding xmlBinding; + private OETParser oetParser; + private Flattener flattener; + private ADLSerializer adlSerializer; + private XmlOptions xmlOptions; + private MeasurementService measurementService; + + protected Map archetypeMap; + protected SkeletonGenerator generator; + protected Object instance; + protected Object expected; + protected Archetype archetype; + + /* path for test fixtures */ + private static final String ARCHETYPE_PATH = "adl/"; + private static final String DATA_PATH = "dadl/"; + private static final String TEMPLATE_PATH = "oet/"; + private static final String XML_PATH = "xml/"; +} 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 new file mode 100644 index 00000000..21acfda8 --- /dev/null +++ b/rm-skeleton/src/test/java/org/openehr/rm/util/TemplateIdTest.java @@ -0,0 +1,27 @@ +package org.openehr.rm.util; + +import org.openehr.rm.common.archetyped.Archetyped; +import org.openehr.rm.composition.content.entry.Observation; + + +public class TemplateIdTest extends SkeletonGeneratorTestBase { + + public TemplateIdTest() throws Exception { + super(); + } + + public void testWithBloodPressureArchetype() throws Exception { + archetype = loadArchetype("openEHR-EHR-OBSERVATION.blood_pressure.v2.adl"); + String templateId = "Blood_pressure"; + + instance = generator.create(archetype, templateId, null, + GenerationStrategy.MINIMUM); + + assertTrue(instance instanceof Observation); + + Observation obs = (Observation) instance; + Archetyped details = obs.getArchetypeDetails(); + assertNotNull(details); + assertEquals("wrong templateId", templateId, details.getTemplateId().toString()); + } +} \ No newline at end of file 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 new file mode 100644 index 00000000..4c9f845d --- /dev/null +++ b/rm-skeleton/src/test/java/org/openehr/rm/util/TestActions.java @@ -0,0 +1,15 @@ +package org.openehr.rm.util; + +import org.openehr.rm.composition.content.entry.Action; + +public class TestActions extends SkeletonGeneratorTestBase { + + public TestActions() throws Exception { + } + + public void testWithMedicationAction() throws Exception { + archetype = loadArchetype("openEHR-EHR-ACTION.medication.v1.adl"); + instance = generator.create(archetype); + assertTrue("failed to create Action instance", instance instanceof Action); + } +} 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 new file mode 100644 index 00000000..b50cb4a8 --- /dev/null +++ b/rm-skeleton/src/test/java/org/openehr/rm/util/TestFlattenedTemplate.java @@ -0,0 +1,36 @@ +package org.openehr.rm.util; + +import org.openehr.am.archetype.Archetype; +import org.openehr.rm.composition.content.navigation.Section; +import org.openehr.rm.datastructure.itemstructure.ItemTree; + +public class TestFlattenedTemplate extends SkeletonGeneratorTestBase { + + public TestFlattenedTemplate() throws Exception { + } + + public void testGenerateWithFlattenedTemplate() throws Exception { + Archetype flattened = flattenTemplate("test_text_name"); + Object obj = generator.create(flattened, archetypeMap); + assertTrue(obj instanceof ItemTree); + + ItemTree tree = (ItemTree) obj; + assertEquals(tree.itemAtPath("/items[at0001]/name/value"), "Typ"); + } + + public void testSectionWithInstructionAndItemTree() throws Exception { + Archetype flattened = flattenTemplate("test_section_instruction_tree"); + Object obj = generator.create(flattened, archetypeMap); + assertTrue(obj instanceof Section); + Section section = (Section) obj; + + // node.name from archetype + String path = "/items[openEHR-EHR-INSTRUCTION.medication.v1]/name/value"; + assertEquals("Medication order", section.itemAtPath(path)); + + // node.name from template + path = "/items[openEHR-EHR-INSTRUCTION.medication.v1]/activities" + + "[at0001]/description/name/value"; + assertEquals("medication details", section.itemAtPath(path)); + } +} 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 new file mode 100644 index 00000000..ff988aa2 --- /dev/null +++ b/rm-skeleton/src/test/java/org/openehr/rm/util/TestItemTreeGeneration.java @@ -0,0 +1,42 @@ +package org.openehr.rm.util; + +/** + * Testcases for leaf-node data types on item_tree level + * + * @author rong.chen + * + */ +public class TestItemTreeGeneration extends SkeletonGeneratorTestBase { + + public TestItemTreeGeneration() throws Exception { + } + + public void testSingleTextElementTree() throws Exception { + archetype = loadArchetype("openEHR-EHR-ITEM_TREE.medication_test_one.v1.adl"); + expected = loadData("item_tree_medicataion_1.dadl"); + instance = generator.create(archetype); + assertEquals(expected, instance); + } + + public void testDoubleQuantityElementTree() throws Exception { + archetype = loadArchetype("openEHR-EHR-ITEM_TREE.blood_pressure.v1.adl"); + expected = loadData("item_tree_blood_pressure_1.dadl"); + instance = generator.create(archetype); + assertEquals(expected, instance); + } + + public void testSingleDvCountElement() throws Exception { + archetype = loadArchetype("openEHR-EHR-ITEM_TREE.medication_test_five.v1.adl"); + expected = loadData("item_tree_medicataion_6.dadl"); + instance = generator.create(archetype); + assertEquals(expected, instance); + } + + public void testSingleDvProportionElement() throws Exception { + archetype = loadArchetype("openEHR-EHR-ITEM_TREE.medication_test_six.v1.adl"); + expected = loadData("item_tree_medicataion_7.dadl"); + instance = generator.create(archetype); + assertEquals(expected, instance); + } + +} 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 new file mode 100644 index 00000000..bdf7a616 --- /dev/null +++ b/rm-skeleton/src/test/java/org/openehr/rm/util/TestObservations.java @@ -0,0 +1,38 @@ +package org.openehr.rm.util; + +public class TestObservations extends SkeletonGeneratorTestBase { + + public TestObservations() throws Exception { + } + + public void testWithBloodPressureArchetype() throws Exception { + archetype = loadArchetype("openEHR-EHR-OBSERVATION.blood_pressure.v2.adl"); + instance = generator.create(archetype); + + } + + public void testWithHeightArchetype() throws Exception { + archetype = loadArchetype("openEHR-EHR-OBSERVATION.height.v2.adl"); + instance = generator.create(archetype); + } + + public void testWithWeightArchetype() throws Exception { + archetype = loadArchetype("openEHR-EHR-OBSERVATION.body_weight.v2.adl"); + instance = generator.create(archetype); + } + + public void testWithWaistArchetype() throws Exception { + archetype = loadArchetype("openEHR-EHR-OBSERVATION.waist_hip.v2.adl"); + instance = generator.create(archetype); + } + + public void testWithHeartRateArchetype() throws Exception { + archetype = loadArchetype("openEHR-EHR-OBSERVATION.heart_rate.v2.adl"); + instance = generator.create(archetype); + } + + public void testWithLabArchetype() throws Exception { + archetype = loadArchetype("openEHR-EHR-OBSERVATION.lab_test.v1.adl"); + instance = generator.create(archetype, GenerationStrategy.MAXIMUM_EMPTY); + } +} 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 new file mode 100644 index 00000000..9690ea5a --- /dev/null +++ b/rm-skeleton/src/test/java/org/openehr/rm/util/TestStrategy.java @@ -0,0 +1,47 @@ +package org.openehr.rm.util; + +import org.openehr.am.archetype.constraintmodel.CObject; + +public class TestStrategy extends SkeletonGeneratorTestBase { + + public TestStrategy() throws Exception { + archetype = loadArchetype("openEHR-EHR-ITEM_TREE.medication_test_four.v1.adl"); + } + + public void testWithDefaultStrategy() throws Exception { + expected = loadData("item_tree_medicataion_4.dadl"); + instance = generator.create(archetype); + assertEquals(expected, instance); + } + + public void testWithExplicitMinimumStrategy() throws Exception { + expected = loadData("item_tree_medicataion_4.dadl"); + instance = generator.create(archetype, GenerationStrategy.MINIMUM); + assertEquals(expected, instance); + } + + public void testWithMaximumStrategy() throws Exception { + expected = loadData("item_tree_medicataion_5.dadl"); + instance = generator.create(archetype, GenerationStrategy.MAXIMUM); + assertEquals(expected, instance); + } + + public void testWithMaximumEmptyStrategy() throws Exception { + expected = loadData("item_tree_medicataion_12.dadl"); + + // required for max_empty strategy to differentiate input node from + // the rest of nodes + setInputAnnotation("/items[at0001]"); + setInputAnnotation("/items[at0002]"); + setInputAnnotation("/items[at0003]"); + + instance = generator.create(archetype, GenerationStrategy.MAXIMUM_EMPTY); + assertEquals(expected, instance); + } + + private void setInputAnnotation(String path) { + CObject cobj = (CObject) archetype.node(path); + cobj.setAnnotation("INPUT"); + } + +} 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 new file mode 100644 index 00000000..3cead49f --- /dev/null +++ b/rm-skeleton/src/test/java/org/openehr/rm/util/UtilityTest.java @@ -0,0 +1,27 @@ +package org.openehr.rm.util; + +import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantity; +import org.openehr.rm.datatypes.quantity.DvQuantity; +import org.openehr.rm.datatypes.text.DvText; + +public class UtilityTest extends SkeletonGeneratorTestBase { + + public UtilityTest() throws Exception { + } + + public void testRetrieveName() throws Exception { + archetype = loadArchetype("openEHR-EHR-ITEM_TREE.medication_test_one.v1.adl"); + String expected = "Medication name"; + DvText retrievedName = generator.retrieveName("at0001", archetype); + + assertEquals("failed to retrieve name", expected, retrievedName.getValue()); + } + + public void testCreateFromEmptyCDvQuantity() throws Exception { + CDvQuantity any = CDvQuantity.anyAllowed("/at0001"); + DvQuantity dq = generator.createDvQuantity(any); + assertNotNull("failed to create dv_quantity out of any-allowed c_dv_quantity"); + } + + +} 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 new file mode 100644 index 00000000..e0b166ce --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ACTION.medication.v1.adl @@ -0,0 +1,319 @@ +archetype (adl_version=1.4) + openEHR-EHR-ACTION.medication.v1 + +concept + [at0000] -- Medication action +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"Sam Heard"> + ["organisation"] = <"Ocean Informatics"> + ["email"] = <"sam.heard@oceaninformatics.com"> + ["date"] = <"23/03/2006"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"This ACTION enables the recording of actions taken with regard to medication. This will usually be in response to a medication order or prescription, but may be self administered or supplied by a pharmacy. There is no timing information as use of this archetype indicates that some action has actually occurred."> + use = <""> + misuse = <""> + copyright = <"copyright (c) 2009 openEHR Foundation"> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <> + other_details = < + ["references"] = <""> + > + +definition + ACTION[at0000] matches { -- Medication 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]} -- Plan + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::527]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0013]} -- Plan suspended + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::528]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0012]} -- Cancelled + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::529]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0016]} -- Start time set + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches { + [openehr:: + 245, + 524] + } + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0002]} -- Prescribe + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches { + [openehr:: + 245, + 524] + } + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0003]} -- Dispense + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::245]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0004]} -- Commence administration + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::245]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0005]} -- Review + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::245]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0006]} -- Administer (point in time) + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::245]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0010]} -- Re-issue prescription + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::530]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0008]} -- Delayed supply + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::530]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0009]} -- Suspended administration + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::530]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0011]} -- Suspended re-order + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::531]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0015]} -- Cancelled administration + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::531]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0014]} -- Cancelled prescription + } + } + } + ISM_TRANSITION matches { + current_state matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::532]} + } + } + careflow_step matches { + DV_CODED_TEXT matches { + defining_code matches {[local::at0007]} -- Completed + } + } + } + } + description matches { + allow_archetype ITEM_TREE matches { + include + archetype_id/value matches {/openEHR-EHR-ITEM_TREE\.medication\.v1|openEHR-EHR-ITEM_TREE\.medication-vaccine\.v1/} + exclude + archetype_id/value matches {/.*/} + } + } + } + + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication action"> + description = <"An action arising from a medication order created by a clinician which specifies which medication to take, when, for how long etc."> + > + ["at0001"] = < + text = <"Plan"> + description = <"The medication is planned but no execution has taken place"> + > + ["at0002"] = < + text = <"Prescribe"> + description = <"The order has been transfered to the dispensary"> + > + ["at0003"] = < + text = <"Dispense"> + description = <"The medication has been dispensed"> + > + ["at0004"] = < + text = <"Commence administration"> + description = <"The medication has been taken by the patient"> + > + ["at0005"] = < + text = <"Review"> + description = <"The medication has been reviewed"> + > + ["at0006"] = < + text = <"Administer (point in time)"> + description = <"The medication has been administered"> + > + ["at0007"] = < + text = <"Completed"> + description = <"The medication has been completed as prescribed"> + > + ["at0008"] = < + text = <"Delayed supply"> + description = <"The medication will not been dispensed as supply is not available"> + > + ["at0009"] = < + text = <"Suspended administration"> + description = <"The administration of the medication has been suspended"> + > + ["at0010"] = < + text = <"Re-issue prescription"> + description = <"The medication has been re-ordered or prescribed"> + > + ["at0011"] = < + text = <"Suspended re-order"> + description = <"Reordering of this medication is not available"> + > + ["at0012"] = < + text = <"Cancelled"> + description = <"The planned administration has been cancelled"> + > + ["at0013"] = < + text = <"Plan suspended"> + description = <"The plan to order medication has been suspended"> + > + ["at0014"] = < + text = <"Cancelled prescription"> + description = <"The prescription has been cancelled"> + > + ["at0015"] = < + text = <"Cancelled administration"> + description = <"The administration has been cancelled"> + > + ["at0016"] = < + text = <"Start time set"> + description = <"The time to start this medication has been set"> + > + > + > + > 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 new file mode 100644 index 00000000..c5088d85 --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-EVALUATION.hypersensitivity.v1.adl @@ -0,0 +1,184 @@ +archetype (adl_version=1.4) + openEHR-EHR-EVALUATION.hypersensitivity.v1 + +concept + [at0000] -- Hypersensitivity +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["organisation"] = <"Cambio Healthcare Systems"> + ["name"] = <"Rong Chen"> + ["date"] = <"2012-07-05"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"Record hypersensitivity information related to drug or others"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"0"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"068A959015B94D2DDAED15583D8950E1"> + > + +definition + EVALUATION[at0000] matches { -- Hypersensitivity + data matches { + ITEM_TREE[at0001] matches { -- Träd + items cardinality matches {4..*; unordered} matches { + ELEMENT[at0002] matches { -- Type + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0004, -- Drug + at0005, -- Food + at0006, -- Animals/Pets + at0007, -- Plants + at0008] -- Chemical substance + } + } + } + } + ELEMENT[at0003] occurrences matches {0..1} matches { -- Heading + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0009] occurrences matches {1..*} matches { -- Agent + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0010] occurrences matches {0..1} matches { -- Comment + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0011] matches { -- Severity level + value matches { + 1|[local::at0012], -- Life threatening + 2|[local::at0013], -- Harmful + 3|[local::at0014] -- Troublesome + } + } + ELEMENT[at0015] matches { -- Assertion level + value matches { + 1|[local::at0016], -- Confirmed + 2|[local::at0017], -- Probable + 3|[local::at0018] -- Suspected + } + } + ELEMENT[at0019] occurrences matches {0..1} matches { -- Is reassessment required + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + ELEMENT[at0020] occurrences matches {0..1} matches { -- Reassessment date + value matches { + DV_DATE_TIME matches {*} + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Hypersensitivity"> + description = <"For recording hypersensitivity information related to drug or others"> + > + ["at0001"] = < + text = <"Träd"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Type"> + description = <"*"> + > + ["at0003"] = < + text = <"Heading"> + description = <"*"> + > + ["at0004"] = < + text = <"Drug"> + description = <"Drug related hypersensitivity"> + > + ["at0005"] = < + text = <"Food"> + description = <"Food related hypersenstivity"> + > + ["at0006"] = < + text = <"Animals/Pets"> + description = <"Animals/Pets related hypersenstivity"> + > + ["at0007"] = < + text = <"Plants"> + description = <"Plants related hypersenstivity"> + > + ["at0008"] = < + text = <"Chemical substance"> + description = <"Chemical substance related hypersenstivity"> + > + ["at0009"] = < + text = <"Agent"> + description = <"*"> + > + ["at0010"] = < + text = <"Comment"> + description = <"*"> + > + ["at0011"] = < + text = <"Severity level"> + description = <"*"> + > + ["at0012"] = < + text = <"Life threatening"> + description = <"Life threatening"> + > + ["at0013"] = < + text = <"Harmful"> + description = <"Harmful"> + > + ["at0014"] = < + text = <"Troublesome"> + description = <"Troublesome"> + > + ["at0015"] = < + text = <"Assertion level"> + description = <"*"> + > + ["at0016"] = < + text = <"Confirmed"> + description = <"Confirmed"> + > + ["at0017"] = < + text = <"Probable"> + description = <"Probable"> + > + ["at0018"] = < + text = <"Suspected"> + description = <"Suspected"> + > + ["at0019"] = < + text = <"Is reassessment required"> + description = <"*"> + > + ["at0020"] = < + text = <"Reassessment date"> + description = <"*"> + > + > + > + > 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 new file mode 100644 index 00000000..b667b035 --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-INSTRUCTION.medication.v1.adl @@ -0,0 +1,90 @@ +archetype (adl_version=1.4) + openEHR-EHR-INSTRUCTION.medication.v1 + +concept + [at0000] -- Medication order +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"] = <"21/04/2006"> + ["email"] = <"sam.heard@oceaninformatics.biz"> + > + details = < + ["de"] = < + language = <[ISO_639-1::de]> + purpose = <"Zur Dokumentation einer Medikationsverordnung, kann mehr als eine Aktivität enthalten, aber immer mit der selben Struktur"> + use = <"Zur Dokumentation von Anweisungen bezüglich eines Medikaments"> + keywords = <"Verschreibung", "Medikationsverordnung", "Verordnung"> + misuse = <"Nicht zur Dokumentation der Verabreichung, der Gabe usw. benutzen. Für diese Dokumentation openEHR-EHR-ACTION.medication benutzen."> + copyright = <"copyright (c) 2008 openEHR Foundation"> + > + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"For recording a medication order, which may involve more than one activity, but all have the same structure."> + use = <"For recording an instruction about medication."> + keywords = <"prescribe", "medication order", "order"> + misuse = <"Do not use for recording administration, dispensing etc. Use openEHR-EHR-ACTION.medication for these recordings."> + copyright = <"copyright (c) 2008 openEHR Foundation"> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <"NEHTA (Australia) data groups", ...> + +definition + INSTRUCTION[at0000] matches { -- Medication order + activities cardinality matches {1..*; unordered} matches { + ACTIVITY[at0001] occurrences matches {1..*} matches { -- Medication activity + action_archetype_id matches {/medication\.v1/} + description matches { + allow_archetype ITEM_TREE matches { + include + archetype_id/value matches {/medication\.v1/} + archetype_id/value matches {/medication-formulation\.v1/} + archetype_id/value matches {/medication-vaccine\.v1/} + exclude + archetype_id/value matches {/.*/} + } + } + } + } + } + +ontology + term_definitions = < + ["de"] = < + items = < + ["at0000"] = < + text = <"Medikationsverordnung"> + description = <"Eine von einem Klinikarzt verfasste Verordnung oder Anweisung, die beschreibt welches Medikament wann, für wie lange usw. eingenommen werden soll"> + > + ["at0001"] = < + text = <"Medikationshandlung"> + description = <"Informationen über die auszuführende Medikationshandlung"> + > + > + > + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication order"> + description = <"An order or instruction created by a clinician which specifies which medication to take, when, for how long etc."> + > + ["at0001"] = < + text = <"Medication activity"> + description = <"Information about the medication action(s) to be carried out"> + > + > + > + > 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 new file mode 100644 index 00000000..62212369 --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.blood_pressure.v1.adl @@ -0,0 +1,63 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.blood_pressure.v1 + +concept + [at0000] -- blood pressure + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] matches { + items cardinality matches {2..*; ordered} matches { + ELEMENT[at0001] occurrences matches {1..1} matches { -- Systolic + value matches { + C_DV_QUANTITY < + property = <[openehr::125]> + list = < + ["1"] = < + units = <"mm[Hg]"> + magnitude = <|0.0..<1000.0|> + precision = <|0|> + > + > + > + } + } + ELEMENT[at0002] occurrences matches {1..1} matches { -- Diastolic + value matches { + C_DV_QUANTITY < + property = <[openehr::125]> + list = < + ["1"] = < + units = <"mm[Hg]"> + magnitude = <|0.0..<1000.0|> + precision = <|0|> + > + > + > + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Blood pressure"> + description = <"blood pressure"> + > + ["at0001"] = < + text = <"Systolic"> + description = <"Systolic pressure"> + > + ["at0002"] = < + text = <"Diastolic"> + description = <"Diastolic pressure"> + > + > + + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..dc4ad7c7 --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication.v1.adl @@ -0,0 +1,921 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication.v1 + +concept + [at0000] -- Medication description +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <"Sam Heard"> + ["organisation"] = <"Ocean Informatics"> + ["date"] = <"12/03/2006"> + ["email"] = <"sam.heard@oceaninformatics.com"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"Specifies the description of the medication as part of an INSTRUCTION or ACTION recording taken with regard to medication. This will usually be in response to a medication order or prescription, but may be self administered or supplied by a pharmacy."> + use = <"For use with INSTRUCTION.medication and ACTION.medication to describe the medication"> + keywords = <"medication", "description"> + misuse = <""> + copyright = <"copyright (c) 2008 openEHR Foundation"> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <> + +definition + ITEM_TREE[at0000] occurrences matches {0..*} matches { -- Medication description + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0001] matches { -- Name of medication + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0012] occurrences matches {0..1} matches { -- Generic name + name matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0003]} -- =Generic name OR Brand name + } + } + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0003] occurrences matches {0..1} matches { -- Strength per dose unit + value matches { + C_DV_QUANTITY < + property = <[openehr::124]> + list = < + ["1"] = < + units = <"pg"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"µg"> + magnitude = <|>=0.0|> + > + ["3"] = < + units = <"mg"> + magnitude = <|>=0.0|> + > + ["4"] = < + units = <"gm"> + magnitude = <|>=0.0|> + > + > + > + C_DV_QUANTITY < + property = <[openehr::385]> + list = < + ["1"] = < + units = <"IU"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"mIU"> + magnitude = <|>=0.0|> + > + > + > + C_DV_QUANTITY < + property = <[openehr::445]> + list = < + ["1"] = < + units = <"mU"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"U"> + magnitude = <|>=0.0|> + > + > + > + } + } + ELEMENT[at0006] matches { -- Dose unit + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0001]} -- any term that 'is a' Dose unit for this form + } + } + } + ELEMENT[at0004] occurrences matches {0..1} matches { -- Form + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0000]} -- Any term that 'is_a' form of medication + } + } + } + CLUSTER[at0033] occurrences matches {0..1} matches { -- Dose + items cardinality matches {1; unordered} matches { + CLUSTER[at0035] occurrences matches {0..1} matches { -- By absolute quantity + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0036] occurrences matches {1..2} matches { -- Quantity by volume + value matches { + C_DV_QUANTITY < + property = <[openehr::129]> + list = < + ["1"] = < + units = <"ml"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"l"> + magnitude = <|>=0.0|> + > + > + > + DV_INTERVAL matches { + upper matches { + C_DV_QUANTITY < + property = <[openehr::129]> + list = < + ["1"] = < + units = <"ml"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"l"> + magnitude = <|>=0.0|> + > + > + > + } + lower matches { + C_DV_QUANTITY < + property = <[openehr::129]> + list = < + ["1"] = < + units = <"ml"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"l"> + magnitude = <|>=0.0|> + > + > + > + } + } + } + } + ELEMENT[at0037] occurrences matches {0..1} matches { -- Quantity by mass + value matches { + C_DV_QUANTITY < + property = <[openehr::124]> + list = < + ["1"] = < + units = <"µg"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"mg"> + > + ["3"] = < + units = <"gm"> + > + > + > + DV_INTERVAL matches { + upper matches { + C_DV_QUANTITY < + property = <[openehr::124]> + list = < + ["1"] = < + units = <"µg"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"mg"> + magnitude = <|>=0.0|> + > + ["3"] = < + units = <"gm"> + magnitude = <|>=0.0|> + > + > + > + } + lower matches { + C_DV_QUANTITY < + property = <[openehr::124]> + list = < + ["1"] = < + units = <"µg"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"mg"> + magnitude = <|>=0.0|> + > + ["3"] = < + units = <"gm"> + magnitude = <|>=0.0|> + > + > + > + } + } + } + } + } + } + CLUSTER[at0034] occurrences matches {0..1} matches { -- By dose units + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0005] matches { -- Number or fraction + value matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + DV_INTERVAL matches { + upper matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + } + lower matches { + DV_COUNT matches { + magnitude matches {|>=1|} + } + } + } + DV_PROPORTION matches { + numerator matches {|>=1.0|} + denominator matches {|1.0..4.0|} + type matches {1, 2, 4} + } + } + } + } + } + } + } + ELEMENT[at0007] occurrences matches {0..1} matches { -- Dose duration + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"d"> + > + ["2"] = < + units = <"h"> + > + ["3"] = < + units = <"min"> + > + ["4"] = < + units = <"s"> + magnitude = <|>=0.0|> + > + > + > + } + } + ELEMENT[at0008] occurrences matches {0..1} matches { -- Route + value matches { + DV_CODED_TEXT matches { + defining_code matches {[ac0002]} -- Any term that 'is_a' route of administration + } + } + } + CLUSTER[at0057] occurrences matches {0..1} matches { -- Timing + items cardinality matches {0..*; unordered} matches { + CLUSTER[at0061] occurrences matches {0..1} matches { -- Approximate + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0052] occurrences matches {0..1} matches { -- Frequency + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0053, -- Once + at0054, -- Twice + at0055, -- Three times + at0056, -- Four times + at0058] -- Five times + } + } + DV_CODED_TEXT matches { + defining_code matches {[ac0005]} -- Frequency + } + } + } + ELEMENT[at0059] occurrences matches {0..1} matches { -- Unit time + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"a"> + > + ["2"] = < + units = <"d"> + > + ["3"] = < + units = <"h"> + > + ["4"] = < + units = <"min"> + > + ["5"] = < + units = <"mo"> + > + ["6"] = < + units = <"wk"> + > + > + > + } + } + } + } + CLUSTER[at0062] occurrences matches {0..1} matches { -- Exact + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0063] occurrences matches {0..1} matches { -- Exact time of administration + value matches { + DV_DATE_TIME matches { + value matches {yyyy-??-??T??:??:??} + } + } + } + } + } + CLUSTER[at0064] occurrences matches {0..1} matches { -- Relative + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0065] occurrences matches {0..1} matches { -- Timing + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"a"> + > + ["2"] = < + units = <"d"> + > + ["3"] = < + units = <"h"> + > + ["4"] = < + units = <"mo"> + > + ["5"] = < + units = <"s"> + > + ["6"] = < + units = <"min"> + > + ["7"] = < + units = <"wk"> + > + > + > + } + } + ELEMENT[at0066] occurrences matches {0..1} matches { -- Qualifier + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0068, -- before + at0069, -- after + at0070, -- with + at0073] -- at + } + } + } + } + ELEMENT[at0067] occurrences matches {0..1} matches { -- Event + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + ELEMENT[at0060] occurrences matches {0..1} matches { -- Instruction qualifiers + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0050] occurrences matches {0..1} matches { -- Reason for commencement + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0051] occurrences matches {0..1} matches { -- Reason for ceasing + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0009] occurrences matches {0..1} matches { -- Is long term + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + CLUSTER[at0010] occurrences matches {0..1} matches { -- Indications + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0011] occurrences matches {0..*} matches { -- Indication + value matches { + DV_TEXT matches {*} + DV_URI matches {*} + } + } + } + } + CLUSTER[at0013] occurrences matches {0..1} matches { -- Safety limits + items cardinality matches {1..4; ordered} matches { + ELEMENT[at0014] occurrences matches {0..1} matches { -- Maximum dose unit frequency + value matches { + C_DV_QUANTITY < + property = <[openehr::382]> + list = < + ["1"] = < + units = <"{QUALIFIED REAL/TIME}"> + magnitude = <|>0.0|> + > + > + assumed_value = < + precision = <-1> + magnitude = <0.0> + units = <"{QUALIFIED REAL/TIME}"> + > + > + } + } + ELEMENT[at0015] 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[at0016] occurrences matches {0..1} matches { -- Minimum dose interval + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"min"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"h"> + magnitude = <|>=0.0|> + > + ["3"] = < + units = <"d"> + magnitude = <|>=0.0|> + > + ["4"] = < + units = <"wk"> + magnitude = <|>=0.0|> + > + ["5"] = < + units = <"mo"> + magnitude = <|>=0.0|> + > + > + > + } + } + ELEMENT[at0017] occurrences matches {0..1} matches { -- Maximum dose interval + value matches { + C_DV_QUANTITY < + property = <[openehr::128]> + list = < + ["1"] = < + units = <"d"> + magnitude = <|>=0.0|> + > + ["2"] = < + units = <"h"> + magnitude = <|>=0.0|> + > + ["3"] = < + units = <"min"> + magnitude = <|>=0.0|> + > + ["4"] = < + units = <"wk"> + magnitude = <|>=0.0|> + > + ["5"] = < + units = <"mo"> + magnitude = <|>=0.0|> + > + > + > + } + } + ELEMENT[at0002] occurrences matches {0..1} matches { -- Administration instructions + value matches { + DV_TEXT matches {*} + } + } + } + } + CLUSTER[at0018] occurrences matches {0..1} matches { -- Administration information + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0019] occurrences matches {0..1} matches { -- Date (time) of first administration + value matches { + DV_DATE_TIME matches { + value matches {yyyy-??-??T??:??:??} + } + } + } + ELEMENT[at0020] occurrences matches {0..1} matches { -- Batch number + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0021] occurrences matches {0..1} matches { -- Site of administration + value matches { + DV_CODED_TEXT matches { + defining_code matches {[local::]} + } + } + } + ELEMENT[at0022] occurrences matches {0..1} matches { -- Sequence number + value matches { + DV_COUNT matches {*} + } + } + ELEMENT[at0032] occurrences matches {0..1} matches { -- Date (time) of last administration + value matches { + DV_DATE_TIME matches { + value matches {yyyy-??-??T??:??:??} + } + } + } + } + } + CLUSTER[at0023] occurrences matches {0..1} matches { -- Dispensing information + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0024] occurrences matches {0..1} matches { -- Quantity to be dispensed + value matches { + C_DV_QUANTITY < + property = <[openehr::445]> + > + DV_COUNT matches { + magnitude matches {|>0|; 1} + } + DV_TEXT matches {*} + } + } + ELEMENT[at0025] occurrences matches {0..1} matches { -- Number of authorised repeat dispensing + value matches { + DV_COUNT matches { + magnitude matches {|>=0|} + } + } + } + ELEMENT[at0026] occurrences matches {0..1} matches { -- Dispensed product + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0027] occurrences matches {0..1} matches { -- Brand substitution allowed + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + ELEMENT[at0028] occurrences matches {0..1} matches { -- Authority approval number + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0029] occurrences matches {0..1} matches { -- Patient counselled on CMI + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + ELEMENT[at0030] occurrences matches {0..1} matches { -- Deferred supply + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + ELEMENT[at0031] occurrences matches {0..1} matches { -- Reason for deferred supply + value matches { + DV_TEXT matches {*} + } + } + } + } + CLUSTER[at0049] occurrences matches {0..1} matches { -- Admission information + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0048] occurrences matches {0..1} matches { -- Own Medication + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication for recording as part of an ACTION or INSTRUCTION"> + > + ["at0001"] = < + text = <"Name of medication"> + description = <"The name of the intervention - which may be coded"> + > + ["at0002"] = < + text = <"Administration instructions"> + description = <"Detailed instructions about how to administer this medication"> + > + ["at0003"] = < + text = <"Strength per dose unit"> + description = <"The strength of the medication"> + > + ["at0004"] = < + text = <"Form"> + description = <"The form of the medication"> + > + ["at0005"] = < + text = <"Number or fraction"> + description = <"The number of dose units to be taken at any time"> + > + ["at0006"] = < + text = <"Dose unit"> + description = <"The dose unit that is given for this type of medication"> + > + ["at0007"] = < + text = <"Dose duration"> + description = <"The time over which an individual dose is to be administered"> + > + ["at0008"] = < + text = <"Route"> + description = <"The route of administration"> + > + ["at0009"] = < + text = <"Is long term"> + description = <"Included and set to true if this medication is to be used continuously or repeatedly over a significant period of time."> + > + ["at0010"] = < + text = <"Indications"> + description = <"Indications including related problems and diagnoses, abnormal test results etc"> + > + ["at0011"] = < + text = <"Indication"> + description = <"The indication for the intervention"> + > + ["at0012"] = < + text = <"Generic name"> + description = <"The generic name of the drug which is an alternative name to the name of medication"> + > + ["at0013"] = < + text = <"Safety limits"> + description = <"*"> + > + ["at0014"] = < + text = <"Maximum dose unit frequency"> + description = <"The maximum number of dose units to be taken in a particular time"> + > + ["at0015"] = < + text = <"Dosage per kg body weight"> + description = <"The dose per kg of body weight"> + > + ["at0016"] = < + text = <"Minimum dose interval"> + description = <"The minimum safe interval between doses"> + > + ["at0017"] = < + text = <"Maximum dose interval"> + description = <"The maximum safe interval between doses"> + > + ["at0018"] = < + text = <"Administration information"> + description = <"Information relating to the administration of the medication order"> + > + ["at0019"] = < + text = <"Date (time) of first administration"> + description = <"The date and time (if required) the medication is/was first administered"> + > + ["at0020"] = < + text = <"Batch number"> + description = <"Manufacturer's identification number"> + > + ["at0021"] = < + text = <"Site of administration"> + description = <"The site of administration e.g. outer thigh if intramuscular, via PEG if patient is nil orally"> + > + ["at0022"] = < + text = <"Sequence number"> + description = <"The dose number or sequence"> + > + ["at0023"] = < + text = <"Dispensing information"> + description = <"Data relating to dispensing"> + > + ["at0024"] = < + text = <"Quantity to be dispensed"> + description = <"The total quantity to be dispensed"> + > + ["at0025"] = < + text = <"Number of authorised repeat dispensing"> + description = <"The number of times this quantity of medication may be dispensed before a further prescription is required"> + > + ["at0026"] = < + text = <"Dispensed product"> + description = <"The name of the product dispensed"> + > + ["at0027"] = < + text = <"Brand substitution allowed"> + description = <"True if an alternative brand may be substituted when dispensing"> + > + ["at0028"] = < + text = <"Authority approval number"> + description = <"*"> + > + ["at0029"] = < + text = <"Patient counselled on CMI"> + description = <"Dispenser counselled the patient with regard to the Consumer Medicines Information"> + > + ["at0030"] = < + text = <"Deferred supply"> + description = <"True if the supply of the medication has been deferred"> + > + ["at0031"] = < + text = <"Reason for deferred supply"> + description = <"Information relating to the reason for deferred supply"> + > + ["at0032"] = < + text = <"Date (time) of last administration"> + description = <"The date and time (if required) the medication is to be administered for the last time"> + > + ["at0033"] = < + text = <"Dose"> + description = <"The dose to be administered at one time"> + > + ["at0034"] = < + text = <"By dose units"> + description = <"Dose as number (or fraction) of the dose units"> + > + ["at0035"] = < + text = <"By absolute quantity"> + description = <"Dosage by absolute quantity"> + > + ["at0036"] = < + text = <"Quantity by volume"> + description = <"The quantity (or range) to be administered as a single dose"> + > + ["at0037"] = < + text = <"Quantity by mass"> + description = <"*"> + > + ["at0048"] = < + text = <"Own Medication"> + description = <"On admission to hospital, medication is from subject's own supply."> + > + ["at0049"] = < + text = <"Admission information"> + description = <"*"> + > + ["at0050"] = < + text = <"Reason for commencement"> + description = <"Reason for commencement of medication"> + > + ["at0051"] = < + text = <"Reason for ceasing"> + description = <"Reason for ceasing of medication"> + > + ["at0052"] = < + text = <"Frequency"> + description = <"The frequency of administration"> + > + ["at0053"] = < + text = <"Once"> + description = <"Administer once per unit time"> + > + ["at0054"] = < + text = <"Twice"> + description = <"Administer twice per unit time"> + > + ["at0055"] = < + text = <"Three times "> + description = <"Administer three times per unit time"> + > + ["at0056"] = < + text = <"Four times "> + description = <"Adminiter four times per unit time"> + > + ["at0057"] = < + text = <"Timing"> + description = <"*"> + > + ["at0058"] = < + text = <"Five times"> + description = <"Administer five times per unit time"> + > + ["at0059"] = < + text = <"Unit time"> + description = <"*"> + > + ["at0060"] = < + text = <"Instruction qualifiers"> + description = <"Instruction for administration"> + > + ["at0061"] = < + text = <"Approximate"> + description = <"*"> + > + ["at0062"] = < + text = <"Exact"> + description = <"*"> + > + ["at0063"] = < + text = <"Exact time of administration"> + description = <"*"> + > + ["at0064"] = < + text = <"Relative"> + description = <"*"> + > + ["at0065"] = < + text = <"Timing"> + description = <"*"> + > + ["at0066"] = < + text = <"Qualifier"> + description = <"Qualifier eg before or after meals (event); with food; at bedtime"> + > + ["at0067"] = < + text = <"Event"> + description = <"*"> + > + ["at0068"] = < + text = <"before"> + description = <"*"> + > + ["at0069"] = < + text = <"after"> + description = <"*"> + > + ["at0070"] = < + text = <"with"> + description = <"*"> + > + ["at0073"] = < + text = <"at"> + description = <"*"> + > + > + > + > + constraint_definitions = < + ["en"] = < + items = < + ["ac0000"] = < + text = <"Any term that 'is_a' form of medication"> + description = <"Terms such as tablet, inhaler, liquid...."> + > + ["ac0001"] = < + text = <"any term that 'is a' Dose unit for this form"> + description = <"A set of terms that describes the dose units for medication - e.g. tablet, puff, ampule etc - which allow the dose to be expressed as a number."> + > + ["ac0002"] = < + text = <"Any term that 'is_a' route of administration"> + description = <"The route by which the medication is administered"> + > + ["ac0003"] = < + text = <"=Generic name OR Brand name"> + description = <"*"> + > + ["ac0005"] = < + text = <"Frequency"> + description = <"Subset of frequencies of medication administration + +"> + > + > + > + > 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 new file mode 100644 index 00000000..05791a7f --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_eight.v1.adl @@ -0,0 +1,38 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_test_eight.v1 + +concept + [at0000] -- Medication description + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] matches { + items cardinality matches {1..*; ordered} matches { + ELEMENT[at0001] matches { -- Name of medication + value matches { + 1|[SNOMED-CT::1201000053901], -- yes + 2|[SNOMED-CT::1201000053902], -- no + 3|[SNOMED-CT::1201000053903] -- unknown + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication"> + > + ["at0001"] = < + text = <"Status"> + description = <"The status of a medication"> + > + > + + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..03f48ce6 --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_five.v1.adl @@ -0,0 +1,36 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_test_five.v1 + +concept + [at0000] -- Medication description + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] matches { + items cardinality matches {1..*; ordered} matches { + ELEMENT[at0001] matches { -- Name of medication + value matches { + DV_COUNT matches {*} + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication"> + > + ["at0001"] = < + text = <"Medication name"> + description = <"The name of a medication"> + > + > + + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..f4a156a1 --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_four.v1.adl @@ -0,0 +1,54 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_test_four.v1 + +concept + [at0000] -- Medication description + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] matches { + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0001] matches { -- Name of medication + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0002] occurrences matches {0..1} matches { -- status of medication + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0003] occurrences matches {0..0} matches { -- indication of medication + value matches { + DV_TEXT matches {*} + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication"> + > + ["at0001"] = < + text = <"Medication name"> + description = <"The name of a medication"> + > + ["at0002"] = < + text = <"Medication status"> + description = <"The status of a medication"> + > + ["at0003"] = < + text = <"Medication indication"> + description = <"The indication of a medication"> + > + > + + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..a1d18ba1 --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_nine.v1.adl @@ -0,0 +1,50 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_test_nine.v1 + +concept + [at0000] -- Medication description + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] matches { + items cardinality matches {1..*; ordered} matches { + ELEMENT[at0001] matches { -- Name of medication + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0002, + at0003] + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication"> + > + ["at0001"] = < + text = <"Status"> + description = <"The status of a medication"> + > + ["at0002"] = < + text = <"one"> + description = <"first choice"> + > + ["at0003"] = < + text = <"two"> + description = <"2nd choice"> + > + > + + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..379e0521 --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_one.v1.adl @@ -0,0 +1,36 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_test_one.v1 + +concept + [at0000] -- Medication description + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] matches { + items cardinality matches {1..*; ordered} matches { + ELEMENT[at0001] matches { -- Name of medication + value matches { + DV_TEXT matches {*} + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication"> + > + ["at0001"] = < + text = <"Medication name"> + description = <"The name of a medication"> + > + > + + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..5a7c1587 --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_seven.v1.adl @@ -0,0 +1,50 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_test_seven.v1 + +concept + [at0000] -- Medication description + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] matches { + items cardinality matches {1..*; ordered} matches { + ELEMENT[at0001] matches { -- Name of medication + value matches { + 1|[local::at0002], + 2|[local::at0003], + 3|[local::at0004] + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication"> + > + ["at0001"] = < + text = <"Status"> + description = <"The status of a medication"> + > + ["at0002"] = < + text = <"one"> + description = <"first choice"> + > + ["at0003"] = < + text = <"two"> + description = <"2nd choice"> + > + ["at0004"] = < + text = <"three"> + description = <"3rd choice"> + > + > + + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..c4f550e9 --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_six.v1.adl @@ -0,0 +1,36 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_test_five.v1 + +concept + [at0000] -- Medication description + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] matches { + items cardinality matches {1..*; ordered} matches { + ELEMENT[at0001] matches { -- Name of medication + value matches { + DV_PROPORTION matches {*} + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication"> + > + ["at0001"] = < + text = <"Medication name"> + description = <"The name of a medication"> + > + > + + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..7c0dc708 --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_three.v1.adl @@ -0,0 +1,40 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_test_three.v1 + +concept + [at0000] -- Medication description + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] matches { + items cardinality matches {1..*; ordered} matches { + ELEMENT[at0001] matches { -- Name of medication + value matches { + [SNOMED-CT:: + 1201000053901, -- yes + 1201000053902, -- no + 1201000053903; -- unknown + 1201000053901] -- assumed value + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication"> + > + ["at0001"] = < + text = <"Medication name"> + description = <"The name of a medication"> + > + > + + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..e83428bd --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-ITEM_TREE.medication_test_two.v1.adl @@ -0,0 +1,44 @@ +archetype (adl_version=1.4) + openEHR-EHR-ITEM_TREE.medication_test_two.v1 + +concept + [at0000] -- Medication description + +language + original_language = <[ISO_639-1::en]> + +definition + ITEM_TREE[at0000] matches { + items cardinality matches {1..*; ordered} matches { + ELEMENT[at0001] matches { -- Name of medication + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [SNOMED-CT:: + 1201000053901, -- yes + 1201000053902, -- no + 1201000053903; -- unknown + 1201000053901] -- assumed value + } + } + } + } + } + } + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Medication description"> + description = <"The description of a medication"> + > + ["at0001"] = < + text = <"Status"> + description = <"The status of a medication"> + > + > + + > + > \ No newline at end of file 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 new file mode 100644 index 00000000..388e720a --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.blood_pressure.v2.adl @@ -0,0 +1,1254 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.blood_pressure.v2 + +concept + [at0000] -- Blood Pressure +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"> + > + > + ["ja"] = < + language = <[ISO_639-1::ja]> + author = < + ["name"] = <"Shinji Kobayashi"> + > + > + ["zh-cn"] = < + language = <[ISO_639-1::zh-cn]> + author = < + ["organisation"] = <"Ocean Informatics"> + ["name"] = <"Chunlan Ma"> + > + > + > +description + original_author = < + ["name"] = <"Sam Heard"> + ["organisation"] = <"Ocean Informatics"> + ["email"] = <"sam.heard@oceaninformatics.com"> + ["date"] = <"22/03/2006"> + > + details = < + ["zh-cn"] = < + language = <[ISO_639-1::zh-cn]> + purpose = <"*To record the systemic blood pressure of a person. The measurement records the systolic and the diastolic pressure by some means suitable for the result to be seen as a surrogate for the general and systemic blood pressure.(en)"> + use = <"*All blood pressure measurements are recorded using this archetype. There is a rich state model for use with exercise ECGs and Tilt Table measurements.(en)"> + keywords = <"*observations(en)", "*blood pressure(en)", "*measurement(en)"> + misuse = <"*Not to be used for intravascular pressure.(en)"> + copyright = <"copyright (c) 2009 openEHR Foundation"> + > + ["ja"] = < + language = <[ISO_639-1::ja]> + purpose = <"*To record the systemic blood pressure of a person. The measurement records the systolic and the diastolic pressure by some means suitable for the result to be seen as a surrogate for the general and systemic blood pressure.(en)"> + use = <"*All blood pressure measurements are recorded using this archetype. There is a rich state model for use with exercise ECGs and Tilt Table measurements.(en)"> + keywords = <"*observations(en)", "*blood pressure(en)", "*measurement(en)"> + misuse = <"*Not to be used for intravascular pressure.(en)"> + copyright = <"copyright (c) 2009 openEHR Foundation"> + > + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"To record the systemic arterial blood pressure of an individual. "> + use = <"Use to record all representations of systemic arterial blood pressure measurement, no matter which method or body location is used to record it. The archetype is intended to capture blood pressure measurements in all clinical scenarios - for example, self-measurement with a home blood pressure machine; an emergency assessment of systolic using palpation and a sphygmomanometer; measurements taken in clinical consultations or during exercise stress testing; and a series of measurements made by a machine in Intensive Care. +There is a rich state model that supports interpretation of measurements through identifying patient position, exercise, confounding factors and angle of a tilt table in research. +Named events have been limited to average over a 24 hour period, however templates can further constrain the default 'any event' to cater for specific requirements for blood pressure measurements such as recording Blood Pressure against specific points in time, or over a range of intervals (+/- mathematical functions)."> + keywords = <"observations", "measurement", "bp", "vital signs", "mean arterial pressure", "pulse pressure", "systolic", "diastolic", "RR", "NIBP"> + misuse = <"Not to be used for intravenous pressure. +Not to be used for the measurement of arterial blood pressure which is NOT a surrogate for arterial pressure in the systemic circulation eg specific measurement of right Pulmonary artery pressure. +Use OBSERVATION.intravascular_pressure and related specialisations in both of these situations."> + copyright = <"copyright (c) 2009 openEHR Foundation"> + > + ["de"] = < + language = <[ISO_639-1::de]> + purpose = <"Dient der Dokumentation des systemischen Blutdrucks einer Person. Die Messung zeichnet den systolischen und diastolischen Blutdruck auf geeignete Art und Weise auf, sodass das Resultat der Messung als charakteristisch für den tatsächlichen systemischen Blutdruck angesehen werden kann."> + use = <"Alle Blutdruckmessungen werden unter Zuhilfenahme dieses Archetypen dokumentiert. Der Archetyp beinhaltet ein umfassendes Status-Modell z.B. bei Durchführung von Belastungs-EKGs und Kipptischuntersuchungen."> + misuse = <"Nicht zu Benutzen zur Dokumentation des intravaskulären Drucks."> + copyright = <"copyright (c) 2009 openEHR Foundation"> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <"Koray Atalag, University of Auckland, New Zealand", "Knut Bernstein, MEDIQ, Denmark", "Marja Buur, Medisch Centrum Alkmaar, Netherlands", "Rong Chen, Cambio Healthcare Systems, Sweden", "Beatriz de Faria Leão, Zilics, Brazil", "Paul Donaldson, Nursing Informatics Australia, Australia", "Jose Florez Arango, Universidad de Antioquia, Colombia", "Gerard Freriks, ERC, Netherlands", "Sebastian Garde, Ocean Informatics, Germany", "Anneke Goossen, Results 4 Care, Netherlands", "Sam Heard, Ocean Informatics, Australia", "Karsten Heusser, Hannover Medical School, Germany", "Omer Hotomaroglu, Turkey", "Evelyn Hovenga, EJSH Consulting, Australia", "Derek Hoy, United Kingdom", "Pieter Hummel, Medisch Centrum Alkmaar, Netherlands", "Eugene Igras, IRIS Systems, Inc., Canada", "Sundaresan Jagannathan, Scottish NHS, United Kingdom", "Andrew James, University of Toronto, Canada", "Heather Leslie, Ocean Informatics, Australia (Editor)", "Rikard Lovstrom, Swedish Medical Association, Sweden", "Rohan Martin, Ambulance Victoria, Australia", "Ian McNicoll, Ocean Informatics, United Kingdom", "Jeroen Meintjens, Medisch Centrum Alkmaar, Netherlands", "Udo Müller-Oest, CompuGROUP Software, Germany", "Melvin Reynolds, United Kingdom", "Tony Shannon, NHS, United Kingdom", "Hwei-Yee Tai, Tan Tock Seng Hospital, Singapore", "Stef Verlinden, Vivici, Netherlands", "Soon Ghee Yap, Singapore Health Services Pte Ltd, Singapore"> + other_details = < + ["references"] = <"O'Brien E, Asmar R, Beilin L, et al. European Society of Hypertension recommendations for conventional, ambulatory and home blood pressure measurement. Journal of Hypertension [Internet]. 2003 [cited 2009 Jul 30] ; 21(5):821-848. Available from http://www.bhsoc.org/bp_monitors/ESH_BP_rec.pdf + +Perloff D, Grim C, Flack J, Frohlich ED, Hill M, McDonald M, Morgenstern BZ. Human blood pressure determination by sphygmomanometry. Circulation [Internet]. 1993 [cited 2009 Jul 29] 88 (5): 2460. Available from: http://circ.ahajournals.org/cgi/reprint/88/5/2460 +"> + ["MD5-CAM-1.0.1"] = <"D612A7A8DAC9DC4145AA43BA92153CF5"> + > + +definition + OBSERVATION[at0000] matches { -- Blood Pressure + data matches { + HISTORY[at0001] matches { -- history + events cardinality matches {1..*; unordered} matches { + EVENT[at0006] occurrences matches {1..*} matches { -- any event + data matches { + ITEM_TREE[at0003] matches { -- blood pressure + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0004] occurrences matches {1..1} matches { -- Systolic + value matches { + C_DV_QUANTITY < + property = <[openehr::125]> + list = < + ["1"] = < + units = <"mm[Hg]"> + magnitude = <|0.0..<1000.0|> + precision = <|0|> + > + > + > + } + } + ELEMENT[at0005] occurrences matches {1..1} matches { -- Diastolic + value matches { + C_DV_QUANTITY < + property = <[openehr::125]> + list = < + ["1"] = < + units = <"mm[Hg]"> + magnitude = <|0.0..<1000.0|> + precision = <|0|> + > + > + > + } + } + ELEMENT[at1006] occurrences matches {0..1} matches { -- Mean Arterial Pressure + value matches { + C_DV_QUANTITY < + property = <[openehr::125]> + list = < + ["1"] = < + units = <"mm[Hg]"> + magnitude = <|0.0..<1000.0|> + precision = <|0|> + > + > + > + } + } + ELEMENT[at1007] occurrences matches {0..1} matches { -- Pulse Pressure + value matches { + C_DV_QUANTITY < + property = <[openehr::125]> + list = < + ["1"] = < + units = <"mm[Hg]"> + magnitude = <|0.0..<1000.0|> + precision = <|0|> + > + > + > + } + } + ELEMENT[at0033] occurrences matches {0..1} matches { -- Comment + value matches { + DV_TEXT matches {*} + } + } + } + } + } + state matches { + ITEM_TREE[at0007] matches { -- state structure + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0008] occurrences matches {0..1} matches { -- Position + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at1000, -- Standing + at1001, -- Sitting + at1002, -- Reclining + at1003, -- Lying + at1014; -- Lying with tilt to left + at1001] -- assumed value + } + } + } + } + ELEMENT[at1052] occurrences matches {0..1} matches { -- Confounding factors + value matches { + DV_TEXT matches {*} + } + } + allow_archetype CLUSTER[at1030] occurrences matches {0..1} matches { -- Exertion + include + archetype_id/value matches {/openEHR-EHR-CLUSTER\.level_of_exertion(-[a-zA-Z0-9_]+)*\.v1/} + } + ELEMENT[at1043] occurrences matches {0..1} matches { -- Sleep status + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at1044, -- Alert & awake + at1045; -- Sleeping + at1044] -- assumed value + } + } + } + } + ELEMENT[at1005] occurrences matches {0..1} matches { -- Tilt + value matches { + C_DV_QUANTITY < + property = <[openehr::497]> + list = < + ["1"] = < + units = <"°"> + magnitude = <|-90.0..90.0|> + precision = <|0|> + > + > + assumed_value = < + magnitude = <0.0> + units = <"°"> + precision = <0> + > + > + } + } + } + } + } + } + INTERVAL_EVENT[at1042] occurrences matches {0..1} matches { -- 24 hour average + math_function matches { + DV_CODED_TEXT matches { + defining_code matches {[openehr::146]} + } + } + width matches { + DV_DURATION matches { + value matches {|PT24H|} + } + } + data matches { + use_node ITEM_TREE /data[at0001]/events[at0006]/data[at0003] -- /data[history]/events[any event]/data[blood pressure] + } + state matches { + use_node ITEM_TREE /data[at0001]/events[at0006]/state[at0007] -- /data[history]/events[any event]/state[state structure] + } + } + } + } + } + protocol matches { + ITEM_TREE[at0011] matches { -- list structure + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0013] occurrences matches {0..1} matches { -- Cuff size + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0015, -- Adult Thigh + at0016, -- Large Adult + at0017, -- Adult + at1008, -- Small Adult + at1009, -- Paediatric/Child + at1018, -- Infant + at1019] -- Neonatal + } + } + } + } + CLUSTER[at1033] occurrences matches {0..1} matches { -- Location + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0014] occurrences matches {0..1} matches { -- Location of measurement + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0025, -- Right arm + at0026, -- Left arm + at0027, -- Right thigh + at0028, -- Left thigh + at1020, -- Right wrist + at1021, -- Left wrist + at1026, -- Right ankle + at1031, -- Left ankle + at1032, -- Finger + at1051, -- Toe + at1053] -- Intra-arterial + } + } + } + } + ELEMENT[at1034] occurrences matches {0..1} matches { -- Specific location + value matches { + DV_TEXT matches {*} + } + } + } + } + ELEMENT[at1035] occurrences matches {0..1} matches { -- Method + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at1036, -- Auscultation + at1037, -- Palpation + at1039, -- Machine + at1040] -- Invasive + } + } + } + } + ELEMENT[at1038] occurrences matches {0..1} matches { -- Mean Arterial Pressure Formula + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at1010] occurrences matches {0..1} matches { -- Diastolic endpoint + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at1011, -- Phase IV + at1012] -- Phase V + } + } + } + } + allow_archetype CLUSTER[at1025] occurrences matches {0..1} matches { -- Device + include + archetype_id/value matches {/openEHR-EHR-CLUSTER\.device(-[a-zA-Z0-9_]+)*\.v1/} + } + } + } + } + } + +ontology + terminologies_available = <"SNOMED-CT", ...> + term_definitions = < + ["zh-cn"] = < + items = < + ["at0000"] = < + text = <"*Blood Pressure(en)"> + description = <"*The local measurement of arterial blood pressure which is a surrogate for arterial pressure in the systemic circulation. Most commonly, use of the term 'blood pressure' refers to measurement of brachial artery pressure in the upper arm.(en)"> + > + ["at0001"] = < + text = <"*history(en)"> + description = <"*history Structural node(en)"> + > + ["at0003"] = < + text = <"血压"> + description = <"*@ internal @(en)"> + > + ["at0004"] = < + text = <"收缩压"> + description = <"一个血液循环周期中,系统性动脉血压高峰值。 收缩期血压"> + > + ["at0005"] = < + text = <"舒张压"> + description = <"一个血液循环周期中,系统性动脉血压最低值。 舒张期血压"> + > + ["at0006"] = < + text = <"*any event(en)"> + description = <"*Default event(en)"> + > + ["at0007"] = < + text = <"*state structure(en)"> + description = <"*@ internal @(en)"> + > + ["at0008"] = < + text = <"*Position(en)"> + description = <"*The position of the subject at the time of measurement(en)"> + > + ["at0011"] = < + text = <"*list structure(en)"> + description = <"*list structure(en)"> + > + ["at0013"] = < + comment = <"*Perloff D, Grim C, Flack J, Frohlich ED, Hill M, McDonald M, Morgenstern BZ. Human blood pressure determination by sphygmomanometry. Circulation 1993;88;2460-2470. (en)"> + text = <"*Cuff size(en)"> + description = <"*The size of the cuff used for blood pressure measurement(en)"> + > + ["at0014"] = < + text = <"*Location of measurement(en)"> + description = <"*Common body locations where blood pressure is recorded(en)"> + > + ["at0015"] = < + text = <"*Adult Thigh(en)"> + description = <"*A cuff used for an adult thigh - bladder approx 20cm x 42cm(en)"> + > + ["at0016"] = < + text = <"*Large Adult(en)"> + description = <"*A cuff for adults with larger arms - bladder approx 16cm x 38cm(en)"> + > + ["at0017"] = < + text = <"*Adult(en)"> + description = <"*A cuff that is standard for an adult - bladder approx 13cm x 30cm(en)"> + > + ["at0025"] = < + text = <"右臂"> + description = <"被测试者右臂"> + > + ["at0026"] = < + text = <"左臂"> + description = <"被测试者左臂"> + > + ["at0027"] = < + text = <"*Right leg(en)"> + description = <"*The right leg of the person(en)"> + > + ["at0028"] = < + text = <"左腿"> + description = <"被测试者左下肢"> + > + ["at0033"] = < + text = <"注释"> + description = <"有关血压值的注释"> + > + ["at1000"] = < + text = <"立位"> + description = <"测量血压时身体处于站立体位"> + > + ["at1001"] = < + text = <"坐位"> + description = <"测量血压时身体处于坐位"> + > + ["at1002"] = < + text = <"侧卧位"> + description = <"测量血压时身体处于45度角侧卧位"> + > + ["at1003"] = < + text = <"*Lying(en)"> + description = <"*Lying flat at the time of blood pressure measurement.(en)"> + > + ["at1005"] = < + text = <"*Tilt(en)"> + description = <"*The craniocaudal tilt of the surface on which the person is lying at the time of measurement(en)"> + > + ["at1006"] = < + text = <"*Mean Arterial Pressure(en)"> + description = <"*The average arterial pressure that occurs over the entire course of the heart contraction and relaxation cycle. (en)"> + > + ["at1007"] = < + text = <"脉压"> + description = <"*The variation in pressure over one contraction cycle(en)"> + > + ["at1008"] = < + text = <"*Small Adult(en)"> + description = <"*A cuff used for a small adult - bladder approx 10cm x 24cm(en)"> + > + ["at1009"] = < + text = <"*Paediatric/Child(en)"> + description = <"*A cuff that is appropriate for a child or adult with a thin arm - bladder approx 8cm x 21cm.(en)"> + > + ["at1010"] = < + text = <"*Diastolic endpoint(en)"> + description = <"*Record which Korotkoff sound is used for determining diastolic pressure using auscultative method(en)"> + > + ["at1011"] = < + text = <"*Phase IV(en)"> + description = <"*The fourth Korotkoff sound is identified as an abrupt muffling of sounds(en)"> + > + ["at1012"] = < + text = <"*Phase V(en)"> + description = <"*The fifth Korotkoff sound is identified by absence of sounds as the cuff pressure drops below the diastolic blood pressure(en)"> + > + ["at1014"] = < + text = <"*Lying with tilt to left(en)"> + description = <"*Lying flat with some lateral tilt, usually angled towards the left side. Commonly required in the last trimester of pregnancy to relieve aortocaval compression.(en)"> + > + ["at1018"] = < + text = <"*Infant(en)"> + description = <"*A cuff used for infants - bladder approx 5cm x 15cm(en)"> + > + ["at1019"] = < + text = <"*Neonatal(en)"> + description = <"*A cuff used for a neonate, assuming cuff is the appropriate size for maturity and birthweight of the neonate(en)"> + > + ["at1020"] = < + text = <"*Right wrist(en)"> + description = <"*The right wrist of the subject(en)"> + > + ["at1021"] = < + text = <"*Left wrist(en)"> + description = <"*The left wrist of the subject(en)"> + > + ["at1025"] = < + text = <"*Device(en)"> + description = <"*Details about sphygmomanometer or other device used to measure the blood pressure(en)"> + > + ["at1026"] = < + text = <"*Right ankle(en)"> + description = <"*The right ankle of the subject(en)"> + > + ["at1030"] = < + text = <"*Exertion (en)"> + description = <"*Details about physical activity undertaken at the time of blood pressure measurement(en)"> + > + ["at1031"] = < + text = <"*Left ankle(en)"> + description = <"*The left ankle of the subject(en)"> + > + ["at1032"] = < + text = <"*Finger(en)"> + description = <"*A finger of the subject. Identification of the finger can be recorded in 'Specific Location' data element, if required.(en)"> + > + ["at1033"] = < + text = <"*New cluster(en)"> + description = <"**(en)"> + > + ["at1034"] = < + text = <"*Specific location(en)"> + description = <"*Detailed description about the site of the measurement of the blood pressure(en)"> + > + ["at1035"] = < + text = <"*New element(en)"> + description = <"**(en)"> + > + ["at1036"] = < + text = <"*Auscultation(en)"> + description = <"*Method of measuring blood pressure externally, using a stethoscope and Korotkoff sounds(en)"> + > + ["at1037"] = < + text = <"*Palpation(en)"> + description = <"*Method of measuring blood pressure externally, using palpation (usually of the brachial or radial arteries)(en)"> + > + ["at1038"] = < + text = <"*Mean Arterial Pressure Formula(en)"> + description = <"*Formula used to calculate the MAP (if recorded in data)(en)"> + > + ["at1039"] = < + text = <"*Machine(en)"> + description = <"*Method of measuring blood pressure externally, using a blood pressure machine(en)"> + > + ["at1040"] = < + text = <"*Invasive(en)"> + description = <"*Method of measuring blood pressure internally ie involving penetration of the skin and measuring inside blood vessels(en)"> + > + ["at1042"] = < + text = <"*24 hour average (en)"> + description = <"*Estimate of the average blood pressure over a 24 hour period(en)"> + > + ["at1043"] = < + text = <"*Sleep status(en)"> + description = <"*Sleep status - supports interpretation of 24 hour ambulatory blood pressure records. (en)"> + > + ["at1044"] = < + text = <"*Alert & awake(en)"> + description = <"*Subject is fully conscious(en)"> + > + ["at1045"] = < + text = <"*Sleeping(en)"> + description = <"*Subject is in the natural state of bodily rest(en)"> + > + ["at1051"] = < + text = <"*Toe(en)"> + description = <"*A toe of the subject. Identification of the toe can be recorded in 'Specific Location' data element, if required.(en)"> + > + ["at1052"] = < + text = <"*Confounding factors(en)"> + description = <"*Comment on and record other incidental factors that may be contributing to the blood pressure measurement. For example, level of anxiety or 'white coat syndrome'; pain or fever; changes in atmospheric pressure etc.(en)"> + > + ["at1053"] = < + text = <"*Intra-arterial(en)"> + description = <"*Invasive measurement via transducer access line within an artery. Location of the transducer can be recorded in 'Specific Location' data element, if required.(en)"> + > + > + > + ["ja"] = < + items = < + ["at0000"] = < + text = <"*Blood Pressure(en)"> + description = <"*The local measurement of arterial blood pressure which is a surrogate for arterial pressure in the systemic circulation. Most commonly, use of the term 'blood pressure' refers to measurement of brachial artery pressure in the upper arm.(en)"> + > + ["at0001"] = < + text = <"*history(en)"> + description = <"*history Structural node(en)"> + > + ["at0003"] = < + text = <"血圧"> + description = <"*@ internal @(en)"> + > + ["at0004"] = < + text = <"収縮期"> + description = <"1つ以上の脈の間で最高値を示す全身の動脈圧 - 心機図の収縮期で測定される"> + > + ["at0005"] = < + text = <"拡張期"> + description = <"1つ以上の脈の間で最低値を示す全身の動脈圧 - 心機図の拡張期で測定される"> + > + ["at0006"] = < + text = <"*any event(en)"> + description = <"*Default event(en)"> + > + ["at0007"] = < + text = <"*state structure(en)"> + description = <"*@ internal @(en)"> + > + ["at0008"] = < + text = <"*Position(en)"> + description = <"*The position of the subject at the time of measurement(en)"> + > + ["at0011"] = < + text = <"*list structure(en)"> + description = <"*list structure(en)"> + > + ["at0013"] = < + comment = <"*Perloff D, Grim C, Flack J, Frohlich ED, Hill M, McDonald M, Morgenstern BZ. Human blood pressure determination by sphygmomanometry. Circulation 1993;88;2460-2470. (en)"> + text = <"*Cuff size(en)"> + description = <"*The size of the cuff used for blood pressure measurement(en)"> + > + ["at0014"] = < + text = <"*Location of measurement(en)"> + description = <"*Common body locations where blood pressure is recorded(en)"> + > + ["at0015"] = < + text = <"*Adult thigh(en)"> + description = <"*A cuff used for an adult thigh - bladder approx 20cm x 42cm(en)"> + > + ["at0016"] = < + text = <"*Large Adult(en)"> + description = <"*A cuff for adults with larger arms - bladder approx 16cm x 38cm(en)"> + > + ["at0017"] = < + text = <"*Adult(en)"> + description = <"*A cuff that is standard for an adult - bladder approx 13cm x 30cm(en)"> + > + ["at0025"] = < + text = <"右腕"> + description = <"*The right arm of the person(en)"> + > + ["at0026"] = < + text = <"左腕"> + description = <"*The left arm of the person(en)"> + > + ["at0027"] = < + text = <"*Right leg(en)"> + description = <"*The right leg of the person(en)"> + > + ["at0028"] = < + text = <"左脚"> + description = <"*The left leg of the person(en)"> + > + ["at0033"] = < + text = <"コメント"> + description = <"血圧測定のコメント"> + > + ["at1000"] = < + text = <"立位"> + description = <"*Standing at the time of blood pressure measurement(en)"> + > + ["at1001"] = < + text = <"座位"> + description = <"*Sitting on bed or chair at the time of blood pressure measurement(en)"> + > + ["at1002"] = < + text = <"斜位"> + description = <"*Person reclining at 45 degrees at the time of blood pressure measurement(en)"> + > + ["at1003"] = < + text = <"*Lying(en)"> + description = <"*Lying flat at the time of blood pressure measurement.(en)"> + > + ["at1005"] = < + text = <"*Tilt(en)"> + description = <"*The craniocaudal tilt of the surface on which the person is lying at the time of measurement(en)"> + > + ["at1006"] = < + text = <"*Mean Arterial Pressure(en)"> + description = <"*The average arterial pressure that occurs over the entire course of the heart contraction and relaxation cycle. (en)"> + > + ["at1007"] = < + text = <"脈圧"> + description = <"1回の収縮サイクルでの血圧の変動"> + > + ["at1008"] = < + text = <"*Small Adult(en)"> + description = <"*A cuff used for a small adult - bladder approx 10cm x 24cm(en)"> + > + ["at1009"] = < + text = <"*Paediatric/Child(en)"> + description = <"*A cuff that is appropriate for a child or adult with a thin arm - bladder approx 8cm x 21cm.(en)"> + > + ["at1010"] = < + text = <"*Diastolic endpoint(en)"> + description = <"*Record which Korotkoff sound is used for determining diastolic pressure using auscultative method(en)"> + > + ["at1011"] = < + text = <"*Phase IV(en)"> + description = <"*The fourth Korotkoff sound is identified as an abrupt muffling of sounds(en)"> + > + ["at1012"] = < + text = <"*Phase V(en)"> + description = <"*The fifth Korotkoff sound is identified by absence of sounds as the cuff pressure drops below the diastolic blood pressure(en)"> + > + ["at1014"] = < + text = <"*Lying with tilt to left(en)"> + description = <"*Lying flat with some lateral tilt, usually angled towards the left side. Commonly required in the last trimester of pregnancy to relieve aortocaval compression.(en)"> + > + ["at1018"] = < + text = <"*Infant(en)"> + description = <"*A cuff used for infants - bladder approx 5cm x 15cm(en)"> + > + ["at1019"] = < + text = <"*Neonatal(en)"> + description = <"*A cuff used for a neonate, assuming cuff is the appropriate size for maturity and birthweight of the neonate(en)"> + > + ["at1020"] = < + text = <"*Right wrist(en)"> + description = <"*The right wrist of the subject(en)"> + > + ["at1021"] = < + text = <"*Left wrist(en)"> + description = <"*The left wrist of the subject(en)"> + > + ["at1025"] = < + text = <"*Device(en)"> + description = <"*Details about sphygmomanometer or other device used to measure the blood pressure(en)"> + > + ["at1026"] = < + text = <"*Right ankle(en)"> + description = <"*The right ankle of the subject(en)"> + > + ["at1030"] = < + text = <"*Exertion (en)"> + description = <"*Details about physical activity undertaken at the time of blood pressure measurement(en)"> + > + ["at1031"] = < + text = <"*Left ankle(en)"> + description = <"*The left ankle of the subject(en)"> + > + ["at1032"] = < + text = <"*Finger(en)"> + description = <"*A finger of the subject. Identification of the finger can be recorded in 'Specific Location' data element, if required.(en)"> + > + ["at1033"] = < + text = <"*New cluster(en)"> + description = <"**(en)"> + > + ["at1034"] = < + text = <"*Specific location(en)"> + description = <"*Detailed description about the site of the measurement of the blood pressure(en)"> + > + ["at1035"] = < + text = <"*New element(en)"> + description = <"**(en)"> + > + ["at1036"] = < + text = <"*Auscultation(en)"> + description = <"*Method of measuring blood pressure externally, using a stethoscope and Korotkoff sounds(en)"> + > + ["at1037"] = < + text = <"*Palpation(en)"> + description = <"*Method of measuring blood pressure externally, using palpation (usually of the brachial or radial arteries)(en)"> + > + ["at1038"] = < + text = <"*Mean Arterial Pressure Formula(en)"> + description = <"*Formula used to calculate the MAP (if recorded in data)(en)"> + > + ["at1039"] = < + text = <"*Machine(en)"> + description = <"*Method of measuring blood pressure externally, using a blood pressure machine(en)"> + > + ["at1040"] = < + text = <"*Invasive(en)"> + description = <"*Method of measuring blood pressure internally ie involving penetration of the skin and measuring inside blood vessels(en)"> + > + ["at1042"] = < + text = <"*24 hour average (en)"> + description = <"*Estimate of the average blood pressure over a 24 hour period(en)"> + > + ["at1043"] = < + text = <"*Sleep status(en)"> + description = <"*Sleep status - supports interpretation of 24 hour ambulatory blood pressure records. (en)"> + > + ["at1044"] = < + text = <"*Alert & awake(en)"> + description = <"*Subject is fully conscious(en)"> + > + ["at1045"] = < + text = <"*Sleeping(en)"> + description = <"*Subject is in the natural state of bodily rest(en)"> + > + ["at1051"] = < + text = <"*Toe(en)"> + description = <"*A toe of the subject. Identification of the toe can be recorded in 'Specific Location' data element, if required.(en)"> + > + ["at1052"] = < + text = <"*Confounding factors(en)"> + description = <"*Comment on and record other incidental factors that may be contributing to the blood pressure measurement. For example, level of anxiety or 'white coat syndrome'; pain or fever; changes in atmospheric pressure etc.(en)"> + > + ["at1053"] = < + text = <"*Intra-arterial(en)"> + description = <"*Invasive measurement via transducer access line within an artery. Location of the transducer can be recorded in 'Specific Location' data element, if required.(en)"> + > + > + > + ["en"] = < + items = < + ["at0000"] = < + text = <"Blood Pressure"> + description = <"The local measurement of arterial blood pressure which is a surrogate for arterial. pressure in the systemic circulation. Most commonly, use of the term 'blood pressure' refers to measurement of brachial artery pressure in the upper arm."> + > + ["at0001"] = < + text = <"history"> + description = <"history Structural node"> + > + ["at0003"] = < + text = <"blood pressure"> + description = <"@ internal @"> + > + ["at0004"] = < + text = <"Systolic"> + description = <"Peak systemic arterial blood pressure - measured in systolic or contraction phase of the heart cycle."> + > + ["at0005"] = < + text = <"Diastolic"> + description = <"Minimum systemic arterial blood pressure - measured in the diastolic or relaxation phase of the heart cycle."> + > + ["at0006"] = < + text = <"any event"> + description = <"Default event"> + > + ["at0007"] = < + text = <"state structure"> + description = <"@ internal @"> + > + ["at0008"] = < + text = <"Position"> + description = <"The position of the subject at the time of measurement."> + > + ["at0011"] = < + text = <"list structure"> + description = <"list structure"> + > + ["at0013"] = < + comment = <"Perloff D, Grim C, Flack J, Frohlich ED, Hill M, McDonald M, Morgenstern BZ. Human blood pressure determination by sphygmomanometry. Circulation 1993;88;2460-2470. "> + text = <"Cuff size"> + description = <"The size of the cuff used for blood pressure measurement. "> + > + ["at0014"] = < + text = <"Location of measurement"> + description = <"Common body sites where blood pressure is recorded."> + > + ["at0015"] = < + text = <"Adult Thigh"> + description = <"A cuff used for an adult thigh - bladder approx 20cm x 42cm."> + > + ["at0016"] = < + text = <"Large Adult"> + description = <"A cuff for adults with larger arms - bladder approx 16cm x 38cm."> + > + ["at0017"] = < + text = <"Adult"> + description = <"A cuff that is standard for an adult - bladder approx 13cm x 30cm."> + > + ["at0025"] = < + text = <"Right arm"> + description = <"The right arm of the person."> + > + ["at0026"] = < + text = <"Left arm"> + description = <"The left arm of the person."> + > + ["at0027"] = < + text = <"Right thigh"> + description = <"The right thigh of the person."> + > + ["at0028"] = < + text = <"Left thigh"> + description = <"The left thigh of the person."> + > + ["at0033"] = < + text = <"Comment"> + description = <"Comment on blood pressure measurement."> + > + ["at1000"] = < + text = <"Standing"> + description = <"Standing at the time of blood pressure measurement."> + > + ["at1001"] = < + text = <"Sitting"> + description = <"Sitting (for example on bed or chair) at the time of blood pressure measurement."> + > + ["at1002"] = < + text = <"Reclining"> + description = <"Reclining at the time of blood pressure measurement."> + > + ["at1003"] = < + text = <"Lying"> + description = <"Lying flat at the time of blood pressure measurement."> + > + ["at1005"] = < + text = <"Tilt"> + description = <"The craniocaudal tilt of the surface on which the person is lying at the time of measurement."> + > + ["at1006"] = < + text = <"Mean Arterial Pressure"> + description = <"The average arterial pressure that occurs over the entire course of the heart contraction and relaxation cycle."> + > + ["at1007"] = < + text = <"Pulse Pressure"> + description = <"The difference between the systolic and diastolic pressure."> + > + ["at1008"] = < + text = <"Small Adult"> + description = <"A cuff used for a small adult - bladder approx 10cm x 24cm."> + > + ["at1009"] = < + text = <"Paediatric/Child"> + description = <"A cuff that is appropriate for a child or adult with a thin arm - bladder approx 8cm x 21cm."> + > + ["at1010"] = < + text = <"Diastolic endpoint"> + description = <"Record which Korotkoff sound is used for determining diastolic pressure using auscultative method."> + > + ["at1011"] = < + text = <"Phase IV"> + description = <"The fourth Korotkoff sound is identified as an abrupt muffling of sounds."> + > + ["at1012"] = < + text = <"Phase V"> + description = <"The fifth Korotkoff sound is identified by absence of sounds as the cuff pressure drops below the diastolic blood pressure."> + > + ["at1014"] = < + text = <"Lying with tilt to left"> + description = <"Lying flat with some lateral tilt, usually angled towards the left side. Commonly required in the last trimester of pregnancy to relieve aortocaval compression."> + > + ["at1018"] = < + text = <"Infant"> + description = <"A cuff used for infants - bladder approx 5cm x 15cm."> + > + ["at1019"] = < + text = <"Neonatal"> + description = <"A cuff used for a neonate, assuming cuff is the appropriate size for maturity and birthweight of the neonate."> + > + ["at1020"] = < + text = <"Right wrist"> + description = <"The right wrist of the subject."> + > + ["at1021"] = < + text = <"Left wrist"> + description = <"The left wrist of the subject."> + > + ["at1025"] = < + text = <"Device"> + description = <"Details about sphygmomanometer or other device used to measure the blood pressure."> + > + ["at1026"] = < + text = <"Right ankle"> + description = <"The right ankle of the subject."> + > + ["at1030"] = < + text = <"Exertion "> + description = <"Details about physical activity undertaken at the time of blood pressure.measurement."> + > + ["at1031"] = < + text = <"Left ankle"> + description = <"The left ankle of the subject."> + > + ["at1032"] = < + text = <"Finger"> + description = <"A finger of the subject. Identification of the finger can be recorded in 'Specific Location' data element, if required."> + > + ["at1033"] = < + text = <"Location"> + description = <"Body location where blood pressure is measured. Use 'Location of measurement' to select from common sites. Use 'Specific location' to record more specific details or a site that is not in the common set or to refer to an external terminology."> + > + ["at1034"] = < + text = <"Specific location"> + description = <"Specific details about the body site where blood pressure is recorded."> + > + ["at1035"] = < + text = <"Method"> + description = <"Method of measurement of blood pressure."> + > + ["at1036"] = < + text = <"Auscultation"> + description = <"Method of measuring blood pressure externally, using a stethoscope and Korotkoff sounds."> + > + ["at1037"] = < + text = <"Palpation"> + description = <"Method of measuring blood pressure externally, using palpation (usually of the brachial or radial arteries)."> + > + ["at1038"] = < + text = <"Mean Arterial Pressure Formula"> + description = <"Formula used to calculate the MAP (if recorded in data)."> + > + ["at1039"] = < + text = <"Machine"> + description = <"Method of measuring blood pressure externally, using a blood pressure machine."> + > + ["at1040"] = < + text = <"Invasive"> + description = <"Method of measuring blood pressure internally ie involving penetration of the skin and measuring inside blood vessels."> + > + ["at1042"] = < + text = <"24 hour average "> + description = <"Estimate of the average blood pressure over a 24 hour period."> + > + ["at1043"] = < + text = <"Sleep status"> + description = <"Sleep status - supports interpretation of 24 hour ambulatory blood pressure records. "> + > + ["at1044"] = < + text = <"Alert & awake"> + description = <"Subject is fully conscious."> + > + ["at1045"] = < + text = <"Sleeping"> + description = <"Subject is in the natural state of bodily rest."> + > + ["at1051"] = < + text = <"Toe"> + description = <"A toe of the subject. Identification of the toe can be recorded in 'Specific Location' data element, if required."> + > + ["at1052"] = < + text = <"Confounding factors"> + description = <"Comment on and record other incidental factors that may be contributing to the blood pressure measurement. For example, level of anxiety or 'white coat syndrome'; pain or fever; changes in atmospheric pressure etc."> + > + ["at1053"] = < + text = <"Intra-arterial"> + description = <"Invasive measurement via transducer access line within an artery. Location of the transducer can be recorded in 'Specific Location' data element, if required."> + > + > + > + ["de"] = < + items = < + ["at0000"] = < + text = <"*Blood Pressure(en)"> + description = <"*The local measurement of arterial blood pressure which is a surrogate for arterial pressure in the systemic circulation. Most commonly, use of the term 'blood pressure' refers to measurement of brachial artery pressure in the upper arm.(en)"> + > + ["at0001"] = < + text = <"Historie"> + description = <"Historie"> + > + ["at0003"] = < + text = <"Blutdruck"> + description = <"*@ internal @(en)"> + > + ["at0004"] = < + text = <"Systolisch"> + description = <"Der höchste arterielle Blutdruck eines Zyklus - gemessen in der systolischen oder Kontraktionsphase des Herzens."> + > + ["at0005"] = < + text = <"Diastolisch"> + description = <"Der minimale systemische arterielle Blutdruck eines Zyklus - gemessen in der diastolischen oder Entspannungsphase des Herzens."> + > + ["at0006"] = < + text = <"*any event(en)"> + description = <"*Default event(en)"> + > + ["at0007"] = < + text = <"*state structure(en)"> + description = <"*@ internal @(en)"> + > + ["at0008"] = < + text = <"*Position(en)"> + description = <"*The position of the subject at the time of measurement(en)"> + > + ["at0011"] = < + text = <"Listenstruktur"> + description = <"Listenstruktur"> + > + ["at0013"] = < + comment = <"*Perloff D, Grim C, Flack J, Frohlich ED, Hill M, McDonald M, Morgenstern BZ. Human blood pressure determination by sphygmomanometry. Circulation 1993;88;2460-2470. (en)"> + text = <"*Cuff size(en)"> + description = <"*The size of the cuff used for blood pressure measurement(en)"> + > + ["at0014"] = < + text = <"*Location of measurement(en)"> + description = <"*Common body locations where blood pressure is recorded(en)"> + > + ["at0015"] = < + text = <"*Adult Thigh(en)"> + description = <"*A cuff used for an adult thigh - bladder approx 20cm x 42cm(en)"> + > + ["at0016"] = < + text = <"*Large Adult(en)"> + description = <"*A cuff for adults with larger arms - bladder approx 16cm x 38cm(en)"> + > + ["at0017"] = < + text = <"*Adult(en)"> + description = <"*A cuff that is standard for an adult - bladder approx 13cm x 30cm(en)"> + > + ["at0025"] = < + text = <"Rechter Arm"> + description = <"Der rechte Arm der Person"> + > + ["at0026"] = < + text = <"Linker Arm"> + description = <"Der linke Arm der Person"> + > + ["at0027"] = < + text = <"*Right leg(en)"> + description = <"*The right leg of the person(en)"> + > + ["at0028"] = < + text = <"Linkes Bein"> + description = <"Linkes Bein des Patienten"> + > + ["at0033"] = < + text = <"Kommentar"> + description = <"Kommentar zur Blutdruckmessung"> + > + ["at1000"] = < + text = <"Stehend"> + description = <"Stehend zum Zeitpunkt der Blutdruckmessung"> + > + ["at1001"] = < + text = <"Sitzend"> + description = <"Sitzend zum Zeitpunkt der Blutdruckmessung"> + > + ["at1002"] = < + text = <"Zurückgelehnt"> + description = <"Patient 45 Grad zurückgelehnt zum Zeitpunkt der Blutdruckmessung"> + > + ["at1003"] = < + text = <"*Lying(en)"> + description = <"*Lying flat at the time of blood pressure measurement.(en)"> + > + ["at1005"] = < + text = <"*Tilt(en)"> + description = <"*The craniocaudal tilt of the surface on which the person is lying at the time of measurement(en)"> + > + ["at1006"] = < + text = <"*Mean Arterial Pressure(en)"> + description = <"*The average arterial pressure that occurs over the entire course of the heart contraction and relaxation cycle. (en)"> + > + ["at1007"] = < + text = <"Pulsdruck"> + description = <"Der Abstand zwischen dem systolischen und dem diastolischen Blutdruckwert. Beschreibt die Druckwelle, die mit jedem Herzschlag durch das Blutgefäßsystem läuft."> + > + ["at1008"] = < + text = <"*Small Adult(en)"> + description = <"*A cuff used for a small adult - bladder approx 10cm x 24cm(en)"> + > + ["at1009"] = < + text = <"*Paediatric/Child(en)"> + description = <"*A cuff that is appropriate for a child or adult with a thin arm - bladder approx 8cm x 21cm.(en)"> + > + ["at1010"] = < + text = <"*Diastolic endpoint(en)"> + description = <"*Record which Korotkoff sound is used for determining diastolic pressure using auscultative method(en)"> + > + ["at1011"] = < + text = <"*Phase IV(en)"> + description = <"*The fourth Korotkoff sound is identified as an abrupt muffling of sounds(en)"> + > + ["at1012"] = < + text = <"*Phase V(en)"> + description = <"*The fifth Korotkoff sound is identified by absence of sounds as the cuff pressure drops below the diastolic blood pressure(en)"> + > + ["at1014"] = < + text = <"*Lying with tilt to left(en)"> + description = <"*Lying flat with some lateral tilt, usually angled towards the left side. Commonly required in the last trimester of pregnancy to relieve aortocaval compression.(en)"> + > + ["at1018"] = < + text = <"*Infant(en)"> + description = <"*A cuff used for infants - bladder approx 5cm x 15cm(en)"> + > + ["at1019"] = < + text = <"*Neonatal(en)"> + description = <"*A cuff used for a neonate, assuming cuff is the appropriate size for maturity and birthweight of the neonate(en)"> + > + ["at1020"] = < + text = <"*Right wrist(en)"> + description = <"*The right wrist of the subject(en)"> + > + ["at1021"] = < + text = <"*Left wrist(en)"> + description = <"*The left wrist of the subject(en)"> + > + ["at1025"] = < + text = <"*Device(en)"> + description = <"*Details about sphygmomanometer or other device used to measure the blood pressure(en)"> + > + ["at1026"] = < + text = <"*Right ankle(en)"> + description = <"*The right ankle of the subject(en)"> + > + ["at1030"] = < + text = <"*Exertion (en)"> + description = <"*Details about physical activity undertaken at the time of blood pressure measurement(en)"> + > + ["at1031"] = < + text = <"*Left ankle(en)"> + description = <"*The left ankle of the subject(en)"> + > + ["at1032"] = < + text = <"*Finger(en)"> + description = <"*A finger of the subject. Identification of the finger can be recorded in 'Specific Location' data element, if required.(en)"> + > + ["at1033"] = < + text = <"*New cluster(en)"> + description = <"**(en)"> + > + ["at1034"] = < + text = <"*Specific location(en)"> + description = <"*Detailed description about the site of the measurement of the blood pressure(en)"> + > + ["at1035"] = < + text = <"*New element(en)"> + description = <"**(en)"> + > + ["at1036"] = < + text = <"*Auscultation(en)"> + description = <"*Method of measuring blood pressure externally, using a stethoscope and Korotkoff sounds(en)"> + > + ["at1037"] = < + text = <"*Palpation(en)"> + description = <"*Method of measuring blood pressure externally, using palpation (usually of the brachial or radial arteries)(en)"> + > + ["at1038"] = < + text = <"*Mean Arterial Pressure Formula(en)"> + description = <"*Formula used to calculate the MAP (if recorded in data)(en)"> + > + ["at1039"] = < + text = <"*Machine(en)"> + description = <"*Method of measuring blood pressure externally, using a blood pressure machine(en)"> + > + ["at1040"] = < + text = <"*Invasive(en)"> + description = <"*Method of measuring blood pressure internally ie involving penetration of the skin and measuring inside blood vessels(en)"> + > + ["at1042"] = < + text = <"*24 hour average (en)"> + description = <"*Estimate of the average blood pressure over a 24 hour period(en)"> + > + ["at1043"] = < + text = <"*Sleep status(en)"> + description = <"*Sleep status - supports interpretation of 24 hour ambulatory blood pressure records. (en)"> + > + ["at1044"] = < + text = <"*Alert & awake(en)"> + description = <"*Subject is fully conscious(en)"> + > + ["at1045"] = < + text = <"*Sleeping(en)"> + description = <"*Subject is in the natural state of bodily rest(en)"> + > + ["at1051"] = < + text = <"*Toe(en)"> + description = <"*A toe of the subject. Identification of the toe can be recorded in 'Specific Location' data element, if required.(en)"> + > + ["at1052"] = < + text = <"*Confounding factors(en)"> + description = <"*Comment on and record other incidental factors that may be contributing to the blood pressure measurement. For example, level of anxiety or 'white coat syndrome'; pain or fever; changes in atmospheric pressure etc.(en)"> + > + ["at1053"] = < + text = <"*Intra-arterial(en)"> + description = <"*Invasive measurement via transducer access line within an artery. Location of the transducer can be recorded in 'Specific Location' data element, if required.(en)"> + > + > + > + > + term_bindings = < + ["SNOMED-CT"] = < + items = < + ["at0000"] = <[SNOMED-CT(2003)::163020007]> + ["at0004"] = <[SNOMED-CT(2003)::163030003]> + ["at0005"] = <[SNOMED-CT(2003)::163031004]> + > + > + > 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 new file mode 100644 index 00000000..5c248ecc --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.body_weight.v2.adl @@ -0,0 +1,268 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.body_weight.v2 + +concept + [at0000] -- Body weight +language + original_language = <[ISO_639-1::en]> + translations = < + ["de"] = < + language = <[ISO_639-1::de]> + author = < + ["organisation"] = <"University of Heidelberg"> + ["name"] = <"Jasmin Buck"> + > + > + > +description + original_author = < + ["name"] = <"Sam Heard"> + ["organisation"] = <"Ocean Informatics"> + ["email"] = <"sam.heard@oceaninformatics.com"> + ["date"] = <"9/03/2006"> + > + details = < + ["de"] = < + language = <[ISO_639-1::de]> + purpose = <"Zur Dokumentation des Gewichtes einer Person, eines Neugeborenen oder eines Fötus."> + use = <"Zur Dokumentation des gesamten Körpergewichtes eines Menschen."> + keywords = <"Gewicht", "Verlust", "Zunahme"> + misuse = <"Nicht zur Dokumentation einer anderen Einheit oder eines Teils des Körpers. Siehe measurement-weight."> + copyright = <"copyright (c) 2009 openEHR Foundation"> + > + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"To record the body weight of an individual - both actual and approximate."> + use = <"To be used for recording the actual measurement of body weight, including when the individual is missing a body part due to a congenital cause or after surgical removal. A statement identifying the physical incompleteness of the body can be recorded in the 'Confounding factors' data element, if required. This is the usual archetype to be used for a typical measurement of weight, for example self-measured by the individual at home, a clinician measurement in a clinic/hospital, or a fitness instructor in a gymnasium. + +Can also be used for recording an approximation of body weight measurement in a clinical scenario where it is not possible to measure accurately body weight - for example, weighing an uncooperative child, or estimating the weight of an unborn fetus (where the 'subject of data' is the Fetus and recording occurs within the mother's health record). This is not modelled explicitly in the archetype as the openEHR Reference model allows the attribute of Approximation for any Quantity data type. At implementation, for example, an application user interface could allow clinicians to select an appropriately labelled check box adjacent to the Weight data field to indicate that the recorded weight is an approximation, rather than actual. + +To be used for recording weight change, that is, either weight loss or weight gain. This can currently be modelled by constraining the 'any event' to an interval with associated mathematical function of increase or decrease, as appropriate. "> + keywords = <"weight", "gain", "loss", "increase", "decrease", "mass", "estimate", "actual"> + misuse = <"Not to be used to record the first weight of an infant soon after birth which is designated as their 'birth weight' - use the specialisation of this archetype OBSERVATION.body_weight-birth. +Not to be used to record the adjusted body weight eg a calculation of the full body weight of a person with limb amputation, based on other body part measurements and an algorithm - use OBSERVATION.body_weight-adjusted. +Not to be used to record the weight of an object or body part. "> + copyright = <"copyright (c) 2009 openEHR Foundation"> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <"Jeroen Meintjens, Medisch Centrum Alkmaar, Netherlands", "Marja Buur-Krom, Medisch Centrum Alkmaar, Netherlands", "Sebastian Garde, Ocean Informatics, Germany", "Ian McNicoll, Ocean Informatics, Scotland", "Heather Leslie, Ocean Informatics, Australia", "Paul Donaldson, Queensland Health, Australia", "Heather Grain, Llewellyn Informatics, Australia", "Anne Harbison, Australia", "Andrew James, University of Toronto, Canada", "Rikard Lovstrom, Swedish Medical Association, Sweden", "Hans Demski, Helmholtz Zentrum München, Germany", "Soon Ghee Yap, Singapore Health Services Pte Ltd, Singapore"> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"27F7E169FB5ACFD6C13E4B061298DD7D"> + > + +definition + OBSERVATION[at0000] matches { -- Body weight + 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 { -- Simple + items cardinality matches {1; unordered} matches { + ELEMENT[at0004] matches { -- Weight + value matches { + C_DV_QUANTITY < + property = <[openehr::124]> + list = < + ["1"] = < + units = <"kg"> + magnitude = <|0.0..1000.0|> + > + ["2"] = < + units = <"lb"> + magnitude = <|0.0..2000.0|> + > + > + > + } + } + ELEMENT[at0024] occurrences matches {0..1} matches { -- Comment + value matches { + DV_TEXT matches {*} + } + } + } + } + } + state matches { + ITEM_TREE[at0008] matches { -- state structure + items cardinality matches {0..*; ordered} matches { + ELEMENT[at0009] occurrences matches {0..1} matches { -- State of Dress + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0011, -- Lightly clothed/underwear + at0013, -- Naked + at0010, -- Fully clothed, including shoes + at0017; -- Nappy/diaper + at0011] -- assumed value + } + } + } + } + ELEMENT[at0025] occurrences matches {0..1} matches { -- Confounding Factors + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + } + } + } + protocol matches { + ITEM_TREE[at0015] matches { -- protocol structure + items cardinality matches {0..*; ordered} matches { + allow_archetype CLUSTER[at0020] occurrences matches {0..1} matches { -- Device + include + archetype_id/value matches {/openEHR-EHR-CLUSTER\.device(-[a-zA-Z0-9_]+)*\.v1/} + } + } + } + } + } + +ontology + terminologies_available = <"SNOMED-CT", ...> + term_definitions = < + ["de"] = < + items = < + ["at0000"] = < + text = <"*Body weight(en)"> + description = <"*Measurement of the body weight of an individual.(en)"> + > + ["at0001"] = < + text = <"Simple"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"History"> + description = <"@ internal @"> + > + ["at0003"] = < + text = <"*Any event(en)"> + description = <"*Any event(en)"> + > + ["at0004"] = < + text = <"*Weight(en)"> + description = <"*The weight of the individual.(en)"> + > + ["at0008"] = < + text = <"State structure"> + description = <"@ internal @"> + > + ["at0009"] = < + text = <"*State of Dress(en)"> + description = <"*Description of the state of dress of the person at the time of weighing.(en)"> + > + ["at0010"] = < + text = <"*Fully clothed, including shoes(en)"> + description = <"*Clothing which may add significantly to weight, including shoes.(en)"> + > + ["at0011"] = < + text = <"*Lightly clothed/underwear(en)"> + description = <"*Clothing which will not add to weight significantly.(en)"> + > + ["at0013"] = < + text = <"unbekleidet"> + description = <"Ohne Kleidung"> + > + ["at0015"] = < + text = <"Protocol structure"> + description = <"@ internal @"> + > + ["at0017"] = < + text = <"*Nappy/diaper(en)"> + description = <"*Wearing only a nappy - can add significant weight.(en)"> + > + ["at0020"] = < + text = <"*Device(en)"> + description = <"*Details about the weighing device.(en)"> + > + ["at0024"] = < + text = <"*Comment(en)"> + description = <"*Comment about the measurement of weight.(en)"> + > + ["at0025"] = < + text = <"*Confounding Factors(en)"> + description = <"*Record any issues or factors that may impact on the measurement of body weight eg timing in menstrual cycle, timing of recent bowel motion or noting of amputation.(en)"> + > + > + > + ["en"] = < + items = < + ["at0000"] = < + text = <"Body weight"> + description = <"Measurement of the body weight of an individual."> + > + ["at0001"] = < + text = <"Simple"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"history"> + description = <"@ internal @"> + > + ["at0003"] = < + text = <"Any event"> + description = <"Any event"> + > + ["at0004"] = < + text = <"Weight"> + description = <"The weight of the individual."> + > + ["at0008"] = < + text = <"state structure"> + description = <"@ internal @"> + > + ["at0009"] = < + text = <"State of Dress"> + description = <"Description of the state of dress of the person at the time of weighing."> + > + ["at0010"] = < + text = <"Fully clothed, including shoes"> + description = <"Clothing which may add significantly to weight, including shoes."> + > + ["at0011"] = < + text = <"Lightly clothed/underwear"> + description = <"Clothing which will not add to weight significantly."> + > + ["at0013"] = < + text = <"Naked"> + description = <"Without any clothes"> + > + ["at0015"] = < + text = <"protocol structure"> + description = <"@ internal @"> + > + ["at0017"] = < + text = <"Nappy/diaper"> + description = <"Wearing only a nappy - can add significant weight."> + > + ["at0020"] = < + text = <"Device"> + description = <"Details about the weighing device."> + > + ["at0024"] = < + text = <"Comment"> + description = <"Comment about the measurement of weight."> + > + ["at0025"] = < + text = <"Confounding Factors"> + description = <"Record any issues or factors that may impact on the measurement of body weight eg timing in menstrual cycle, timing of recent bowel motion or noting of amputation."> + > + > + > + > + term_bindings = < + ["SNOMED-CT"] = < + items = < + ["at0004"] = <[SNOMED-CT::363808001]> + > + > + > 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 new file mode 100644 index 00000000..b0cddf67 --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.heart_rate.v2.adl @@ -0,0 +1,393 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.heart_rate.v2 + +concept + [at0000] -- Heart rate and rhythm +language + original_language = <[ISO_639-1::en]> + translations = < + ["de"] = < + language = <[ISO_639-1::de]> + author = < + ["organisation"] = <"University of Heidelberg, Central Queensland University"> + ["name"] = <"Jasmin Buck, Sebastian Garde"> + > + > + > +description + original_author = < + ["name"] = <"Sam Heard"> + ["organisation"] = <"Ocean Informatics"> + ["email"] = <"sam.heard@oceaninformatics.com"> + ["date"] = <"26/03/2006"> + > + details = < + ["de"] = < + language = <[ISO_639-1::de]> + purpose = <"Zur Dokumentation der Frequenz und des Rhythmus des Herzens."> + use = <"Zur allgemeinen Dokumentation der Herzfrequenz, besonders der elektrischen Frequenz."> + keywords = <"Frequenz", "Herzfrequenz", "Rhythmus"> + misuse = <"Zur Dokumentation der mechanischen Frequenz Puls benutzen (OSBSERVATION.heart_reate-pulse.v1)."> + copyright = <"copyright (c) 2009 openEHR Foundation"> + > + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"To record details about the rate and rhythm of the heart."> + use = <"Use to record the measured characteristics related to the rate and rhythm of the heart, including a simple statement of presence of heart rate. These are not recorded by direct observation of the heart itself but inferenced from alternative sources including the auscultation of the apex beat or an electrocardiograph reflecting the electrical activity of the heart. +Heart rate and rhythm (or it's specialisation, Pulse) are commonly recorded as one component of Vital signs - comprising Blood Pressure, Respirations, Temperature, and Oximetry. There are additional specific archetypes for each of these concepts. + +"> + keywords = <"rate", "heart rate", "rhythm"> + misuse = <"Not to be used to record conclusions about the measured heart rate and rhythm. Statements such as the patient is in Atrial Fibrillation, or is tachycardic, should be recorded in other specific and related EVALUATION archetypes. +Not to be used to record the mechanical heart rate, rhythm and related characteristics - this is recorded using the specialisation of this archetype OBSERVATION.heart_rate-pulse. +Not to be used to record other details of the broader cardiovascular examination or assessment. Other specific archetypes will be used to record characteristics such as apex beat, murmurs, auscultatory findings etc. +Concepts such as Maximal or Target Heart Rate should be recorded in separate archetypes specifically related to exercise assessment."> + copyright = <"copyright (c) 2009 openEHR Foundation"> + > + > + lifecycle_state = <"Initial"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"48DEE828B4C8AB55F79B1EFBA7E088A7"> + > + +definition + OBSERVATION[at0000] matches { -- Heart rate and rhythm + 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..*; unordered} matches { + ELEMENT[at1005] occurrences matches {0..1} matches { -- Heart rate present + value matches { + DV_BOOLEAN matches { + value matches {True, False} + } + } + } + ELEMENT[at0004] occurrences matches {0..1} matches { -- Rate + value matches { + C_DV_QUANTITY < + property = <[openehr::382]> + list = < + ["1"] = < + units = <"/min"> + magnitude = <|>=0.0|> + precision = <|0|> + > + > + > + } + } + ELEMENT[at0005] occurrences matches {0..1} matches { -- Rhythm + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0006, -- Regular + at0007, -- Irregular + at0008] -- Irregularly irregular + } + } + } + } + ELEMENT[at0009] occurrences matches {0..1} matches { -- Comment + value matches { + DV_TEXT matches {*} + } + } + } + } + } + state matches { + ITEM_TREE[at0012] matches { -- List + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0013] occurrences matches {0..1} matches { -- Position + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at1000, -- Lying + at1001, -- Sitting + at1002, -- Reclining + at1003; -- Standing + at1001] -- assumed value + } + } + } + } + ELEMENT[at1018] occurrences matches {0..1} matches { -- Confounding factors + value matches { + DV_TEXT matches {*} + } + } + allow_archetype CLUSTER[at1017] occurrences matches {0..*} matches { -- Exertion + include + archetype_id/value matches {/openEHR-EHR-CLUSTER\.exertion(-[a-zA-Z0-9_]+)*\.v1/} + } + } + } + } + } + } + } + } + protocol matches { + ITEM_TREE[at0010] matches { -- List + items cardinality matches {0..*; unordered} matches { + allow_archetype CLUSTER[at1013] occurrences matches {0..1} matches { -- Device + include + archetype_id/value matches {/openEHR-EHR-CLUSTER\.device(-[a-zA-Z0-9_]+)*\.v1/} + exclude + archetype_id/value matches {/.*/} + } + ELEMENT[at1014] occurrences matches {0..1} matches { -- Description + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at1019] occurrences matches {0..1} matches { -- Method + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at1020, -- Apex beat auscultation + at1021] -- Electrocardiograph + } + } + } + } + } + } + } + } + +ontology + terminologies_available = <"SNOMED-CT", ...> + term_definitions = < + ["de"] = < + items = < + ["at0000"] = < + text = <"*Heart rate and rhythm(en)"> + description = <"*The characteristics of the heart rate and rhythm. +(en)"> + > + ["at0001"] = < + text = <"Structure"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"History"> + description = <"@ internal @"> + > + ["at0003"] = < + text = <"*Any event(en)"> + description = <"*Default and unspecified event.(en)"> + > + ["at0004"] = < + text = <"*Rate(en)"> + description = <"*The rate of the heart in beats per minute.(en)"> + > + ["at0005"] = < + text = <"*Rhythm(en)"> + description = <"*The non-interpreted rhythm of the heartbeat.(en)"> + > + ["at0006"] = < + text = <"Regulär"> + description = <"Regulärer Herzschlag"> + > + ["at0007"] = < + text = <"Unregulär"> + description = <"Unregulärer Herzschlag"> + > + ["at0008"] = < + text = <"Unregulär unregulär"> + description = <"Unregulär in einer chaotischen Art und Weise"> + > + ["at0009"] = < + text = <"*Comment(en)"> + description = <"*Comment about the heart rate and rhythm.(en)"> + > + ["at0010"] = < + text = <"List"> + description = <"@ internal @"> + > + ["at0012"] = < + text = <"List"> + description = <"@ internal @"> + > + ["at0013"] = < + text = <"Position"> + description = <"Die Position des Patienten während der Messung der Herzfrequenz"> + > + ["at1000"] = < + text = <"Liegend"> + description = <"Gestrecktes Liegen"> + > + ["at1001"] = < + text = <"Sitzend"> + description = <"Auf dem Bett oder einem Stuhl sitzend"> + > + ["at1002"] = < + text = <"Liegesitz"> + description = <"Person sitzt im 45° Winkel mit erhöhten Beinen"> + > + ["at1003"] = < + text = <"Stehend"> + description = <"Aufrecht stehend"> + > + ["at1005"] = < + text = <"*Heart rate present(en)"> + description = <"*The pulse rate is present (implied true if rate >0).(en)"> + > + ["at1013"] = < + text = <"*Device(en)"> + description = <"*Details about the device used to measure heart rate and rhythm.(en)"> + > + ["at1014"] = < + text = <"*Description (en)"> + description = <"*Details about the method used to record the heart rate and rhythm.(en)"> + > + ["at1017"] = < + text = <"*Exertion(en)"> + description = <"*Details about physical exertion being undertaken at the time of recording heart rate and/or rhythm.(en)"> + > + ["at1018"] = < + text = <"*Confounding factors(en)"> + description = <"*Comment on and record other incidental factors that may be contributing to the heart rate and rhythm measurement. For example, level of anxiety or 'white coat syndrome'; pain or fever etc.(en)"> + > + ["at1019"] = < + text = <"*Method(en)"> + description = <"*Source of heart rate and rhythm record.(en)"> + > + ["at1020"] = < + text = <"*Apex beat auscultation(en)"> + description = <"*Direct auscultation of the apex beat of the heart.(en)"> + > + ["at1021"] = < + text = <"*Electrocardiograph(en)"> + description = <"*Derived from the electrical activity of the heart found in an electrocardiograph.(en)"> + > + > + > + ["en"] = < + items = < + ["at0000"] = < + text = <"Heart rate and rhythm"> + description = <"The characteristics of the heart rate and rhythm. +"> + > + ["at0001"] = < + text = <"structure"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"history"> + description = <"@ internal @"> + > + ["at0003"] = < + text = <"Any event"> + description = <"Default unspecified event."> + > + ["at0004"] = < + text = <"Rate"> + description = <"The rate of the heart in beats per minute."> + > + ["at0005"] = < + text = <"Rhythm"> + description = <"The non-interpreted rhythm of the heartbeat."> + > + ["at0006"] = < + text = <"Regular"> + description = <"Heart rhythm is regular."> + > + ["at0007"] = < + text = <"Irregular"> + description = <"Heart rhythm is irregular."> + > + ["at0008"] = < + text = <"Irregularly irregular"> + description = <"Heart rhythm is irregular in a chaotic manner."> + > + ["at0009"] = < + text = <"Comment"> + description = <"Comment about the heart rate and rhythm."> + > + ["at0010"] = < + text = <"List"> + description = <"@ internal @"> + > + ["at0012"] = < + text = <"List"> + description = <"@ internal @"> + > + ["at0013"] = < + text = <"Position"> + description = <"The position of the patient when the heartbeat was recorded."> + > + ["at1000"] = < + text = <"Lying"> + description = <"Lying prone."> + > + ["at1001"] = < + text = <"Sitting"> + description = <"Sitting on bed or chair."> + > + ["at1002"] = < + text = <"Reclining"> + description = <"Person reclining at 45 degrees with legs raised."> + > + ["at1003"] = < + text = <"Standing"> + description = <"Standing upright."> + > + ["at1005"] = < + text = <"Heart rate present"> + description = <"The pulse rate is present (implied true if rate >0)."> + > + ["at1013"] = < + text = <"Device"> + description = <"Details about the device used to measure heart rate and rhythm."> + > + ["at1014"] = < + text = <"Description "> + description = <"Details about the method used to record the heart rate and rhythm."> + > + ["at1017"] = < + text = <"Exertion"> + description = <"Details about physical exertion being undertaken at the time of recording heart rate and/or rhythm."> + > + ["at1018"] = < + text = <"Confounding factors"> + description = <"Comment on and record other incidental factors that may be contributing to the heart rate and rhythm measurement. For example, level of anxiety or 'white coat syndrome'; pain or fever etc."> + > + ["at1019"] = < + text = <"Method"> + description = <"Source of heart rate and rhythm record."> + > + ["at1020"] = < + text = <"Apex beat auscultation"> + description = <"Direct auscultation of the apex beat of the heart."> + > + ["at1021"] = < + text = <"Electrocardiograph"> + description = <"Derived from the electrical activity of the heart found in an electrocardiograph."> + > + > + > + > + term_bindings = < + ["SNOMED-CT"] = < + items = < + ["at0000"] = <[SNOMED-CT::106066004]> + ["at0004"] = <[SNOMED-CT::364075005]> + ["at0005"] = <[SNOMED-CT::364074009]> + ["at0006"] = <[SNOMED-CT::248649006]> + ["at0007"] = <[SNOMED-CT::248650006]> + ["at0008"] = <[SNOMED-CT::248651005]> + > + > + > 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 new file mode 100644 index 00000000..b710a000 --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.height.v2.adl @@ -0,0 +1,252 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.height.v2 + +concept + [at0000] -- Height/Length +language + original_language = <[ISO_639-1::en]> + translations = < + ["de"] = < + language = <[ISO_639-1::de]> + author = < + ["organisation"] = <"University of Heidelberg, Central Queensland University"> + ["name"] = <"Jasmin Buck, Sebastian Garde"> + > + > + > +description + original_author = < + ["name"] = <"Sam Heard"> + ["organisation"] = <"Ocean Informatics"> + ["email"] = <"sam.heard@oceaninformatics.com"> + ["date"] = <"9/03/2006"> + > + details = < + ["de"] = < + language = <[ISO_639-1::de]> + purpose = <"Zur Dokumentation der Körpergröße in einer gestreckten Position, von Scheitel bis Sohle"> + use = <""> + keywords = <"Größe", "Länge"> + misuse = <"Nicht zur Dokumentation anderer Größen und Längen (siehe OBSERVATION.dimensions.v1)"> + copyright = <"copyright (c) 2009 openEHR Foundation"> + > + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"To record the length of the body from crown of head to sole of foot of an individual - both actual and approximate, and either in a standing or recumbent position."> + use = <"To be used for recording the actual height or body length of an individual at any point in time. A statement identifying the physical incompleteness of the body can be recorded in the 'Confounding factors' protocol element, if required. This is the usual archetype to be used for a typical measurement of height or body length, independent of the clinical setting. +Can also be used for recording an approximation of height or body length measurement in a clinical scenario where it is not possible to measure an accurate height or length - for example, measuring an uncooperative child. This is not modelled explicitly in the archetype as the openEHR Reference model allows the attribute of Approximation for any Quantity data type. At implementation, for example, an application user interface could allow clinicians to select an appropriately labelled check box adjacent to the Height data field to indicate that the recorded height is an approximation, rather than actual. +In general, length measurements are recommended for children under 2 years of age and individuals who cannot stand; height measurements for all others. +Ideally, height is measured standing on both feet with weight distributed evenly, heels together and both buttocks and heels in contact with a vertical back board; body length is measured in a fully extended, supine position with the pelvis flat, legs extended and feet flexed. +Use to record growth and loss of height. This can currently be modelled by constraining the 'any event' to an interval in a template with associated mathematical function of increase or decrease, as appropriate. "> + keywords = <"shrinkage", "increase", "decrease", "height loss", "height", "length", "growth"> + misuse = <"Not to be used to record the first length of an infant soon after birth which is designated as their 'birth length' - use the specialisation of this archetype - see OBSERVATION.height-birth. +Not to be used to record the adjusted height or body length eg a calculation of the estimated full height of a person with limb contractures, based on other body part measurements and/or an algorithm - use OBSERVATION.height-adjusted. +Not to be used to record growth velocity. +Not to be used to record the length of an object or specific body part."> + copyright = <"copyright (c) 2009 openEHR Foundation"> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <"Jeroen Meintjen, Medisch Centrum Alkmaar, Netherlands", "Sebastian Garde, Ocean Informatics, Germany", "Heather Leslie, Ocean Informatics, Australia", "Omer Hotomaroglu, Turkey", "Andrew James, University of Toronto, Canada", "Anne Harbison, Australia", "Thilo Schuler, Germany", "Anneke Goossen, Results 4 Care, Netherlands", "Rikard Lovstrom, Swedish Medical Association, Sweden", "Heather Grain, Llewelyn Informatics, Australia", "Hans Demski, Helmholtz Zentrum München, Germany", "Soon Ghee Yap, Singapore Health Services Pte Ltd, Singapore", "Paul Donaldson, Nursing Informatics Australia, Australia", "Rong Chen, Cambio Healthcare Systems, Sweden", "Sundaresan Jagannathan, Scottish NHS, United Kingdom", "Ian McNicoll, Ocean Informatics, United Kingdom", "Marja Buur, Medisch Centrum Alkmaar, Netherlands"> + other_details = < + ["references"] = <"Wilks Z, Bryan S, Mead V and Davies EH. Clinical guideline: Height, measuring a child [Internet]. London, United Kingdom: UCL Institute of Child Health; 2008 Apr 01 [cited 2009 Jul 28 ]. Available from: http://www.ich.ucl.ac.uk/clinical_information/clinical_guidelines/cpg_guideline_00060"> + ["MD5-CAM-1.0.1"] = <"C8557596E1A6FDD4EE76D31D66251382"> + > + +definition + OBSERVATION[at0000] matches { -- Height/Length + data matches { + HISTORY[at0001] matches { -- history + events cardinality matches {1..*; unordered} matches { + EVENT[at0002] occurrences matches {1..*} matches { -- Any event + data matches { + ITEM_TREE[at0003] matches { -- Simple + items cardinality matches {1..*; unordered} matches { + ELEMENT[at0004] matches { -- Height/Length + value matches { + C_DV_QUANTITY < + property = <[openehr::122]> + list = < + ["1"] = < + units = <"cm"> + magnitude = <|0.0..1000.0|> + > + ["2"] = < + units = <"in"> + magnitude = <|0.0..250.0|> + > + > + > + } + } + ELEMENT[at0018] occurrences matches {0..1} matches { -- Comment + value matches { + DV_TEXT matches {*} + } + } + } + } + } + state matches { + ITEM_TREE[at0013] matches { -- Tree + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0014] occurrences matches {0..1} matches { -- Position + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0016, -- Standing + at0020; -- Lying + at0016] -- assumed value + } + } + } + } + ELEMENT[at0019] occurrences matches {0..1} matches { -- Confounding factors + value matches { + DV_TEXT matches {*} + } + } + } + } + } + } + } + } + } + protocol matches { + ITEM_TREE[at0007] matches { -- List + items cardinality matches {0..*; ordered} matches { + allow_archetype CLUSTER[at0011] occurrences matches {0..1} matches { -- Device + include + archetype_id/value matches {/openEHR-EHR-CLUSTER\.device(-[a-zA-Z0-9_]+)*\.v1/} + } + } + } + } + } + +ontology + terminologies_available = <"SNOMED-CT", ...> + term_definitions = < + ["de"] = < + items = < + ["at0000"] = < + text = <"*Height/Length(en)"> + description = <"*Height, or body length, is measured from crown of head to sole of foot. Height is measured with the individual in a standing position and body length in a recumbent position. (en)"> + > + ["at0001"] = < + text = <"History"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Any event"> + description = <"Jede zu einem Zeitpunkt gemessene Körpergröße"> + > + ["at0003"] = < + text = <"Simple"> + description = <"@ internal @"> + > + ["at0004"] = < + text = <"*Height/Length(en)"> + description = <"*The length of the body from crown of head to sole of foot.(en)"> + > + ["at0007"] = < + text = <"List"> + description = <"@ internal "> + > + ["at0011"] = < + text = <"*CLUSTER(en)"> + description = <"**(en)"> + > + ["at0013"] = < + text = <"*Tree(en)"> + description = <"*@ internal @(en)"> + > + ["at0014"] = < + text = <"*New element(en)"> + description = <"**(en)"> + > + ["at0016"] = < + text = <"*Standing(en)"> + description = <"*Height is measured standing erect, feet flat on the ground and against a backboard(en)"> + > + ["at0018"] = < + text = <"*Comment(en)"> + description = <"*Comment about the measurement of body height/length.(en)"> + > + ["at0019"] = < + text = <"*Confounding factors(en)"> + description = <"*Record any issues or factors that may impact on the measurement of body height/length eg noting of amputation.(en)"> + > + ["at0020"] = < + text = <"*Lying(en)"> + description = <"*Length is measured in a fully extended, recumbent position with the pelvis flat, legs extended and feet flexed. (en)"> + > + > + > + ["en"] = < + items = < + ["at0000"] = < + text = <"Height/Length"> + description = <"Height, or body length, is measured from crown of head to sole of foot. Height is measured with the individual in a standing position and body length in a recumbent position. "> + > + ["at0001"] = < + text = <"history"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Any event"> + description = <"Any timed measurement of height or body length."> + > + ["at0003"] = < + text = <"Simple"> + description = <"@ internal @"> + > + ["at0004"] = < + text = <"Height/Length"> + description = <"The length of the body from crown of head to sole of foot."> + > + ["at0007"] = < + text = <"List"> + description = <"@ internal @"> + > + ["at0011"] = < + text = <"Device"> + description = <"Description of the device used to measure height or body length."> + > + ["at0013"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0014"] = < + text = <"Position"> + description = <"Position of individual when measured. +"> + > + ["at0016"] = < + text = <"Standing"> + description = <"Height is measured standing on both feet with weight distributed evenly, heels together and both buttocks and heels in contact with a vertical back board."> + > + ["at0018"] = < + text = <"Comment"> + description = <"Comment about the measurement of body height/length."> + > + ["at0019"] = < + text = <"Confounding factors"> + description = <"Record any issues or factors that may impact on the measurement of body height/length eg noting of amputation."> + > + ["at0020"] = < + text = <"Lying"> + description = <"Length is measured in a fully extended, recumbent position with the pelvis flat, legs extended and feet flexed. "> + > + > + > + > + term_bindings = < + ["SNOMED-CT"] = < + items = < + ["at0004"] = <[SNOMED-CT::50373000]> + > + > + > 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 new file mode 100644 index 00000000..e000c783 --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.lab_test.v1.adl @@ -0,0 +1,376 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.lab_test.v1 + +concept + [at0000] -- Laboratory test +language + original_language = <[ISO_639-1::en]> + translations = < + ["ar-sy"] = < + language = <[ISO_639-1::ar-sy]> + author = < + ["name"] = <"Mona Saleh"> + > + > + > +description + original_author = < + ["name"] = <"Dr Ian McNicoll"> + ["organisation"] = <"Ocean Informatics, United Kingdom"> + ["email"] = <"ian.mcnicoll@oceaninformatics.com"> + ["date"] = <"07/11/2009"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"To record the result of a laboratory test which may be used to record a single valued test but will often be specialised or templated to represent multiple value or 'panel' tests. +This archetype also acts as the parent for specialisations appropriate for more specific laboratory tests microbiology, histopathology."> + use = <"May be used to represent 'standard' single-value laboratory test results but will often be specialised or templated to represent multi-value results, sometimes referred to as panels. May also be specialised to more highly structured laboratory tests such as microbiology or histopathology. + +Will normally be reported back to the requesting clinician within the context of an overall Composition-based laboratory report."> + keywords = <"lab", "pathology", "biochemistry", "haematology", "microbiology", "immunology", "laboratory"> + misuse = <"Specialisations may be more appropriate for specific structured reports such as for microbiology or histopathology."> + copyright = <"© openEHR Foundation"> + > + ["ar-sy"] = < + language = <[ISO_639-1::ar-sy]> + purpose = <"لتسجيل نتيجة اختبار المعمل, و التي قد يتم استخدامها لتسجيل اختبار ذي قيمة واحدة, و عادة ما يتم بعد ذلك المزيد من التخصيص أو الوضع في قالب لتمثيل اختبار متعدد القيم أو رتل من الاختبارات. +و يمثل هذا النموذج كوالد (أب) للتخصيصات الأخرى لاختبارات معملية أكثر تحديدا مثل الميكروبيولوجيا و الهيستوباثولوجيا."> + use = <"قد يستخدم لتسجيل نتيجة اختبار المعمل, و التي قد يتم استخدامها لتسجيل اختبار ذي قيمة واحدة, و عادة ما يتم بعد ذلك المزيد من التخصيص أو الوضع في قالب لتمثيل اختبار متعدد القيم أو رتل من الاختبارات. + +يتم بعد ذلك تقديم التقرير للطبيب السريري الذي قام بطلب الاختبار في سياق تقرير معملي متكامل."> + keywords = <"المعمل - المختبر", "الباثولوجيا - المرضية", "الكيمياء الحيوية", "الدمويات", "الميكروبيولوجيا", "المناعيات - علم المناعة"> + misuse = <"قد تكون التخصيصات أكثر مناسبة للتقارير المركبة مثل حالات الميكروبيولوجيا أو الهيستوباثولوجيا."> + copyright = <"© openEHR Foundation"> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <"Koray Atalag, University of Auckland, New Zealand", "Heath Frankel, Ocean Informatics, Australia", "Sam Heard, Ocean Informatics, Australia (Editor)", "Heather Leslie, Ocean Informatics, Australia", "Ian McNicoll, Ocean Informatics, United Kingdom (Editor)", "David Rowed, VAMC Clinic, Australia (Editor)", "Mona Saleh (Translator)"> + other_details = < + ["MD5-CAM-1.0.1"] = <"F6054E644F13ABC06CEA75C74E058F8A"> + ["references"] = <"NEHTA, Australia. Pathology Episode v1.0 - Data Group library [Internet]. 2009;[cited 2009 Dec 8 ] Available from: http://www.nehta.gov.au/data-group-library/data-specifications/dgl-pathology + +IHE. IHE, Laboratory Technical Framework, Volume 3 Content [Internet]. 2008;Available from: http://www.ihe.net/Technical_Framework/upload/ihe_lab_TF_rel2_1-Vol-3_FT_2008-08-08.pdf."> + > + +definition + OBSERVATION[at0000] matches { -- Laboratory test + data matches { + HISTORY[at0001] matches { -- Event Series + events cardinality matches {1..*; unordered} matches { + EVENT[at0002] occurrences matches {0..*} matches { -- Any event + data matches { + ITEM_TREE[at0003] matches { -- Tree + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0005] occurrences matches {0..1} matches { -- Test name + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0077] occurrences matches {0..1} matches { -- Diagnostic service + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0073] occurrences matches {0..1} matches { -- Test status + value matches { + DV_CODED_TEXT matches { + defining_code matches { + [local:: + at0037, -- Interim + at0038, -- Final + at0039, -- Supplementary + at0040, -- Corrected (amended) + at0074, -- Aborted + at0079] -- Never performed + } + } + } + } + allow_archetype CLUSTER[at0065] occurrences matches {0..*} matches { -- Specimen detail + include + archetype_id/value matches {/openEHR-EHR-CLUSTER\.specimen\.v1/} + exclude + archetype_id/value matches {/.*/} + } + ELEMENT[at0078] occurrences matches {0..*} matches {*} + allow_archetype CLUSTER[at0089] occurrences matches {0..*} matches { -- Per-result annotation + include + archetype_id/value matches {/openEHR-EHR-CLUSTER\.lab_result_annotation(-[a-zA-Z0-9_]+)*\.v1/} + exclude + archetype_id/value matches {/.*/} + } + ELEMENT[at0057] occurrences matches {0..1} matches { -- Overall interpretation + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0010] occurrences matches {0..*} matches { -- Multimedia representation + value matches { + DV_MULTIMEDIA matches { + media_type matches {[openEHR::]} + } + } + } + } + } + } + } + } + } + } + protocol matches { + ITEM_TREE[at0004] matches { -- Tree + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0062] occurrences matches {0..1} matches { -- Requestor order identifier + value matches { + DV_TEXT matches {*} + } + } + allow_archetype CLUSTER[at0090] occurrences matches {0..*} matches { -- Requestor + include + archetype_id/value matches {/.*/} + } + ELEMENT[at0063] occurrences matches {0..1} matches { -- Receiver order Identifier + value matches { + DV_TEXT matches {*} + } + } + allow_archetype CLUSTER[at0017] occurrences matches {0..*} matches { -- Receiving laboratory + include + archetype_id/value matches {/openEHR-EHR-CLUSTER\.organisation\.v1/} + exclude + archetype_id/value matches {/.*/} + } + ELEMENT[at0068] occurrences matches {0..1} matches { -- Laboratory test result identifier + value matches { + DV_TEXT matches {*} + } + } + ELEMENT[at0075] occurrences matches {0..1} matches { -- Datetime result issued + value matches { + DV_DATE_TIME matches {*} + } + } + } + } + } + } + + + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Laboratory test"> + description = <"To record the result of a laboratory test which may be used to record a single valued test but will often be specialised or templated to represent multiple value or 'panel' tests. +This archetype also acts as the parent for specialisations appropriate for more specific laboratory tests microbiology, histopathology."> + > + ["at0001"] = < + text = <"Event Series"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Any event"> + description = <"Any event."> + > + ["at0003"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0004"] = < + text = <"Tree"> + description = <"@ internal @"> + > + ["at0005"] = < + text = <"Test name"> + description = <"Specific identifier for this lab test. e.g. Full blood count , blood glucose, urine microbiology. May equate to the result name for a single value result. Commonly a coded term e.g from LOINC or SNOMED-CT."> + > + ["at0010"] = < + text = <"Multimedia representation"> + description = <"Representations of the whole test in mutlimedia e.g image, audio, video."> + > + ["at0017"] = < + text = <"Receiving laboratory"> + description = <"Demographic details of the laboratory with responsibility for the test. Details of secondary laboratories may also be included."> + > + ["at0037"] = < + text = <"Interim"> + description = <"This is an initial or interim result - further updates are anticipated."> + > + ["at0038"] = < + text = <"Final"> + description = <"This is the final result. No further alterations are anticipated."> + > + ["at0039"] = < + text = <"Supplementary"> + description = <"This is a supplementary result ehich should be appended to a previous result."> + > + ["at0040"] = < + text = <"Corrected (amended)"> + description = <"This is a correction which should completely replace any previous results."> + > + ["at0057"] = < + text = <"Overall interpretation"> + description = <"An overall interpretative comment on this test."> + > + ["at0062"] = < + text = <"Requestor order identifier"> + description = <"The local ID assigned to the order by the order requester. Equivalent to the Placer Order Identifier."> + > + ["at0063"] = < + text = <"Receiver order Identifier"> + description = <"The local ID assigned to the test order by the order filler, usually by the (LIS) Laboratory Information System. Equivalent to the DICOM Accession Number and the Filler Order Identifier."> + > + ["at0065"] = < + text = <"Specimen detail"> + description = <"Details of the specimen being reported where all individual results are derived from the same specimen."> + > + ["at0068"] = < + text = <"Laboratory test result identifier"> + description = <"The identifier given to the laboratory test result of a pathology investigation."> + > + ["at0073"] = < + text = <"Test status"> + description = <"The status of the lab test as a whole."> + > + ["at0074"] = < + text = <"Aborted"> + description = <"The test was aborted and never completed."> + > + ["at0075"] = < + text = <"Datetime result issued"> + description = <"The date and/or time that the result was issued for the recorded ‘test status’."> + comment = <"The date and time related to the results status is useful for version control and cumulative results for the report."> + > + ["at0077"] = < + text = <"Diagnostic service"> + description = <"The type of high-level diagnostic service e.g. biochemistry, haematology."> + > + ["at0078"] = < + text = <"Result"> + description = <"The result of the test."> + > + ["at0079"] = < + text = <"Never performed"> + description = <"The test was never performed."> + > + ["at0089"] = < + text = <"Per-result annotation"> + description = <"Slot to allow an annotation to be added to a particular test result at run-time."> + > + ["at0090"] = < + text = <"Requestor"> + description = <"Details of the clinician or organisation requesting the laboratory test."> + > + > + > + ["ar-sy"] = < + items = < + ["at0000"] = < + text = <"الاختبار المعملي"> + description = <"لتسجيل نتيجة الاختبار و التي قد تستخدم إما لتسجيل اختبار ذي قيمة واحدة كما أنه قد يتم تخصيصه أو وضعه في قالب لتمثيل الاختبارات متعددة القيمة أو رتل من الاختبارات. +يستخدم هذا النموذج كوالد (أب) للتخصيصات المناسبة لاختبارات أكثر تحديدا مثل حالات الميكروبيولوجيا و الهيستوباثولوجيا."> + > + ["at0001"] = < + text = <"*Event Series(en)"> + description = <"*@ internal @(en)"> + > + ["at0002"] = < + text = <"إحدى الوقائع"> + description = <"إحدى الوقائع"> + > + ["at0003"] = < + text = <"*Tree(en)"> + description = <"*@ internal @(en)"> + > + ["at0004"] = < + text = <"*Tree(en)"> + description = <"*@ internal @(en)"> + > + ["at0005"] = < + text = <"اسم الاختبار"> + description = <"تعريف معين لهوية هذا الاختبار. مثل العد الدموي الشامل, الغلوكوز (سكر العنب) في الدم. قد يكون هو نفسه اسم النتيجة في الاختبارات ذات النتيجة المتكونة من قيمة وحيدة. عادة ما يكون مُصطَلحاً مُرمَزًا مثل لوينك و سنوميد-سي تي."> + > + ["at0010"] = < + text = <"تمثيل الوسائط المتعددة"> + description = <"تمثيلات الاختبار الكلي عن طريق الوسائط المتعددة مثل: الصورة, الصوت, و الفيديو"> + > + ["at0017"] = < + text = <"المعمل المستقبل لطلب الاختبار"> + description = <"التفاصيل الديموغرافية عن المعمل المسئول عن الاختبار. قد يتضمن معلومات عن معامل أخرى ثانوية."> + > + ["at0037"] = < + text = <"مؤقت"> + description = <"هذه هي النتيجة المبدئية أو المؤقتة - المزيد من التحديثات للنتيجة متوقَّعة أو منتظَرة"> + > + ["at0038"] = < + text = <"نهائية"> + description = <"هذه هي النتيجة النهائية. لا يوجد المزيد من التعديلات المتوقَّعة"> + > + ["at0039"] = < + text = <"تكميلية"> + description = <"هذه هي نتيجة تكميلية بالإضافة إلى النتيجة الموَقتة"> + > + ["at0040"] = < + text = <"بعد التصحيح – معدَّلة"> + description = <"هذا هو تصحيح لابد و أن يحل محلّ أي نتائج سابقة"> + > + ["at0057"] = < + text = <"التفسير الإجمالي"> + description = <"تعليق تفسيري إجمالي حول هذا الاختبار"> + > + ["at0062"] = < + text = <"عنصر معرِّف فريد بواسطة طالب الاختبار"> + description = <"العنصر التعريفي الفريد الذي يتم إعطاؤه للأمر بالاختبار بواسطة من يقوم بإجراء الأمر. مكافئ للعنصر التعريفي للأمر بواسطة من يقوم بطلب إجرائه."> + > + ["at0063"] = < + text = <"عنصر معرِّف فريد بواسطة مستقبل الاختبار"> + description = <"العنصر التعريفي الذي يتم إعطاؤه للأمر بالاختبار بواسطة منفذ الاختبار, عادةً النظام المعلومات الخاص بالمعمل. يكافئ رقم الإضافة الخاص بـ دايكوم, و معرِّف أمر الاختبار "> + > + ["at0065"] = < + text = <"تفاصيل العيِّنة"> + description = <"تفاصيل العينة حيث جميع النتائج مشتقة من نفس العينة"> + > + ["at0068"] = < + text = <"العنصر التعريفي الخاص بنتيجة الاختبار"> + description = <"العنصر التعريفي الذي تم إعطاؤه لنتيجة اختبار معملي خاص بالباثولوجيا – المَرَضية"> + > + ["at0073"] = < + text = <"حالة الاختبار"> + description = <"حالة الاختبار المعملي ككل"> + > + ["at0074"] = < + text = <"مُلغاة"> + description = <"تم إلغاء الاختبار و لم يتم استكماله بعد ذلك."> + > + ["at0075"] = < + text = <"تاريخ و وقت إصدار النتيجة"> + description = <"التاريخ و / أو الوقت الذي تم فيه إصدار النتيجة لحالة الاختبار المسجَّلة."> + comment = <"التاريخ و الوقت المتعلق بحالة النتائج هو من النقاط المفيدة للتحكم في الروايات المتعددة و النتائج التراكمية الخاصة بالتقرير."> + > + ["at0077"] = < + text = <"الخدمة التشخيصية"> + description = <"نوع الخدمة التشخيصية - مستوى عالي من التشخيص - مثلا: الكيمياء الحيوية و الدمويات"> + > + ["at0078"] = < + text = <"النتيجة"> + description = <"نتيجة الاختبار"> + > + ["at0079"] = < + text = <"لم يتم عملها على الإطلاق"> + description = <"لم يتم عمل الاختبار على الإطلاق"> + > + ["at0089"] = < + text = <"ملاحظات ما قبل الاختبار"> + description = <"شرفة تسمح بإضافة ملاحظات حول نتيجة اختبار معين في أثناء إجرائه"> + > + ["at0090"] = < + text = <"الطالب"> + description = <"تفاصيل حول الطبيب السريري أو المؤسسة التي تطلب الاختبار المعملي."> + > + > + > + > 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 new file mode 100644 index 00000000..d2816d01 --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-OBSERVATION.waist_hip.v2.adl @@ -0,0 +1,129 @@ +archetype (adl_version=1.4) + openEHR-EHR-OBSERVATION.waist_hip.v2 + +concept + [at0000] -- Waist and hip circumference +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["organisation"] = <"Ocean Informatics"> + ["name"] = <"Heather Leslie"> + ["date"] = <"12/10/2007"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"To record the waist (or girth) and hip circumference and waist/hip ratio"> + use = <""> + keywords = <"waist", "hip"> + misuse = <""> + copyright = <"copyright (c) 2009 openEHR Foundation"> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"9DA698CBBBF5EDDDCF52C7D2E4E69BDD"> + > + +definition + OBSERVATION[at0000] matches { -- Waist and hip circumference + 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_LIST[at0003] matches { -- List + items cardinality matches {0..*; unordered} matches { + ELEMENT[at0004] occurrences matches {0..1} matches { -- Waist circumference + value matches { + C_DV_QUANTITY < + property = <[openehr::122]> + list = < + ["1"] = < + units = <"cm"> + > + ["2"] = < + units = <"in"> + > + > + > + } + } + ELEMENT[at0005] occurrences matches {0..1} matches { -- Hip circumference + value matches { + C_DV_QUANTITY < + property = <[openehr::122]> + list = < + ["1"] = < + units = <"cm"> + magnitude = <|>=0.0|> + precision = <|1|> + > + > + > + } + } + ELEMENT[at0006] occurrences matches {0..1} matches { -- Waist:hip ratio + value matches { + DV_PROPORTION matches { + type matches {1} + } + } + } + } + } + } + } + } + } + } + } + +ontology + terminologies_available = <"SNOMED-CT", ...> + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Waist and hip circumference"> + description = <"The waist (or girth) and hip circumference"> + > + ["at0001"] = < + text = <"Event Series"> + description = <"@ internal @"> + > + ["at0002"] = < + text = <"Any event"> + description = <"Timing event"> + > + ["at0003"] = < + text = <"List"> + description = <"@ internal @"> + > + ["at0004"] = < + text = <"Waist circumference"> + description = <"The waist circumference measured at or above the umbilicus"> + > + ["at0005"] = < + text = <"Hip circumference"> + description = <"Measurement of body circumference at the widest point of the buttocks"> + > + ["at0006"] = < + text = <"Waist:hip ratio"> + description = <"Ratio with unitary denominator"> + > + > + > + > + term_bindings = < + ["SNOMED-CT"] = < + items = < + ["at0004"] = <[SNOMED-CT::396552003]> + ["at0005"] = <[SNOMED-CT::284472007]> + ["at0006"] = <[SNOMED-CT::248367009]> + > + > + > 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 new file mode 100644 index 00000000..ec030d28 --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-SECTION.ad_hoc_heading.v1.adl @@ -0,0 +1,40 @@ +archetype (adl_version=1.4) + openEHR-EHR-SECTION.ad_hoc_heading.v1 + +concept + [at0000] -- Heading +language + original_language = <[ISO_639-1::en]> +description + original_author = < + ["name"] = <""> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"ad hoc heading"> + use = <""> + misuse = <""> + > + > + lifecycle_state = <"0"> + other_contributors = <> + other_details = < + ["references"] = <""> + ["MD5-CAM-1.0.1"] = <"6211E600D00A019604319C19B8303CF6"> + > + +definition + SECTION[at0000] matches {*} + +ontology + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + text = <"Heading"> + description = <"An ad-hoc heading"> + > + > + > + > 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 new file mode 100644 index 00000000..4f5d9206 --- /dev/null +++ b/rm-skeleton/src/test/resources/adl/openEHR-EHR-SECTION.medications.v1.adl @@ -0,0 +1,52 @@ +archetype (adl_version=1.4) + openEHR-EHR-SECTION.medications.v1 + +concept + [at0000] -- Medications + +language + original_language = <[ISO_639-1::en]> + +description + original_author = < + ["name"] = <"Sam Heard"> + ["organisation"] = <"Ocean Informatics"> + ["date"] = <"9/01/2007"> + ["email"] = <"sam.heard@oceaninformatics.biz"> + > + details = < + ["en"] = < + language = <[ISO_639-1::en]> + purpose = <"A heading for medications"> + use = <"Only contains medications by constraint"> + misuse = <""> + > + > + lifecycle_state = <"AuthorDraft"> + other_contributors = <> + +definition + SECTION[at0000] matches { -- Medications + items cardinality matches {1..*; unordered} matches { + allow_archetype INSTRUCTION matches { + include + domain_concept matches {/medication\.v1/} + exclude + domain_concept matches {/.*/} + } + } + } + +ontology + primary_language = <"en"> + languages_available = <"en", ...> + term_definitions = < + ["en"] = < + items = < + ["at0000"] = < + description = <"A section containing medication orders only"> + text = <"Medications"> + > + > + > + > 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 new file mode 100644 index 00000000..1a97882d --- /dev/null +++ b/rm-skeleton/src/test/resources/dadl/item_tree_blood_pressure_1.dadl @@ -0,0 +1,28 @@ +(ITEM_TREE) < + archetype_node_id = <"openEHR-EHR-ITEM_TREE.blood_pressure.v1"> + name = < + value = <"Blood pressure"> + > + items = < + [1] = < + name = < + value = <"Systolic"> + > + archetype_node_id = <"at0001"> + value = < + magnitude = <0.0> + units = <"mm[Hg]"> + > + > + [2] = < + name = < + value = <"Diastolic"> + > + archetype_node_id = <"at0002"> + value = < + magnitude = <0.0> + units = <"mm[Hg]"> + > + > + > +> \ No newline at end of file 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 new file mode 100644 index 00000000..d75f251d --- /dev/null +++ b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_1.dadl @@ -0,0 +1,17 @@ +(ITEM_TREE) < + archetype_node_id = <"openEHR-EHR-ITEM_TREE.medication_test_one.v1"> + name = < + value = <"Medication description"> + > + items = < + [1] = (ELEMENT) < + name = < + value = <"Medication name"> + > + archetype_node_id = <"at0001"> + value = < + value = <"text value"> + > + > + > +> \ No newline at end of file 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 new file mode 100644 index 00000000..76b2df71 --- /dev/null +++ b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_10.dadl @@ -0,0 +1,26 @@ +(ITEM_TREE) < + archetype_node_id = <"openEHR-EHR-ITEM_TREE.medication_test_eight.v1"> + name = < + value = <"Medication description"> + > + items = < + [1] = (ELEMENT) < + name = < + value = <"Status"> + > + archetype_node_id = <"at0001"> + value = (DV_ORDINAL) < + value = <1> + symbol = < + defining_code = < + terminology_id = (TERMINOLOGY_ID) < + value = <"SNOMED-CT"> + > + code_string = <"1201000053901"> + > + value = <"yes"> + > + > + > + > +> \ No newline at end of file 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 new file mode 100644 index 00000000..bf48320c --- /dev/null +++ b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_11.dadl @@ -0,0 +1,23 @@ +(ITEM_TREE) < + archetype_node_id = <"openEHR-EHR-ITEM_TREE.medication_test_nine.v1"> + name = < + value = <"Medication description"> + > + items = < + [1] = (ELEMENT) < + name = < + value = <"Status"> + > + archetype_node_id = <"at0001"> + value = < + defining_code = < + terminology_id = (TERMINOLOGY_ID) < + value = <"local"> + > + code_string = <"at0002"> + > + value = <"one"> + > + > + > +> \ No newline at end of file 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 new file mode 100644 index 00000000..9cfe0dff --- /dev/null +++ b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_12.dadl @@ -0,0 +1,38 @@ +(ITEM_TREE) < + archetype_node_id = <"openEHR-EHR-ITEM_TREE.medication_test_four.v1"> + name = < + value = <"Medication description"> + > + items = < + [1] = (ELEMENT) < + name = < + value = <"Medication name"> + > + archetype_node_id = <"at0001"> + null_flavour = < + value = <"no information"> + defining_code = < + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + code_string = <"271"> + > + > + > + [2] = (ELEMENT) < + name = < + value = <"Medication status"> + > + archetype_node_id = <"at0002"> + null_flavour = < + value = <"no information"> + defining_code = < + terminology_id = (TERMINOLOGY_ID) < + value = <"openehr"> + > + code_string = <"271"> + > + > + > + > +> \ No newline at end of file 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 new file mode 100644 index 00000000..d0389b9d --- /dev/null +++ b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_2.dadl @@ -0,0 +1,23 @@ +(ITEM_TREE) < + archetype_node_id = <"openEHR-EHR-ITEM_TREE.medication_test_two.v1"> + name = < + value = <"Medication description"> + > + items = < + [1] = (ELEMENT) < + name = < + value = <"Status"> + > + archetype_node_id = <"at0001"> + value = < + defining_code = < + terminology_id = (TERMINOLOGY_ID) < + value = <"SNOMED-CT"> + > + code_string = <"1201000053901"> + > + value = <"coded text value"> + > + > + > +> \ No newline at end of file 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 new file mode 100644 index 00000000..b8a37531 --- /dev/null +++ b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_3.dadl @@ -0,0 +1,23 @@ +(ITEM_TREE) < + archetype_node_id = <"openEHR-EHR-ITEM_TREE.medication_test_three.v1"> + name = < + value = <"Medication description"> + > + items = < + [1] = (ELEMENT) < + name = < + value = <"Status"> + > + archetype_node_id = <"at0001"> + value = < + defining_code = < + terminology_id = (TERMINOLOGY_ID) < + value = <"SNOMED-CT"> + > + code_string = <"1201000053901"> + > + value = <"coded text value"> + > + > + > +> \ No newline at end of file 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 new file mode 100644 index 00000000..49e65cc3 --- /dev/null +++ b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_4.dadl @@ -0,0 +1,17 @@ +(ITEM_TREE) < + archetype_node_id = <"openEHR-EHR-ITEM_TREE.medication_test_four.v1"> + name = < + value = <"Medication description"> + > + items = < + [1] = (ELEMENT) < + name = < + value = <"Medication name"> + > + archetype_node_id = <"at0001"> + value = < + value = <"text value"> + > + > + > +> \ No newline at end of file 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 new file mode 100644 index 00000000..26b920c4 --- /dev/null +++ b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_5.dadl @@ -0,0 +1,26 @@ +(ITEM_TREE) < + archetype_node_id = <"openEHR-EHR-ITEM_TREE.medication_test_four.v1"> + name = < + value = <"Medication description"> + > + items = < + [1] = (ELEMENT) < + name = < + value = <"Medication name"> + > + archetype_node_id = <"at0001"> + value = < + value = <"text value"> + > + > + [2] = (ELEMENT) < + name = < + value = <"Medication status"> + > + archetype_node_id = <"at0002"> + value = < + value = <"text value"> + > + > + > +> \ No newline at end of file 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 new file mode 100644 index 00000000..e6b6842f --- /dev/null +++ b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_6.dadl @@ -0,0 +1,17 @@ +(ITEM_TREE) < + archetype_node_id = <"openEHR-EHR-ITEM_TREE.medication_test_five.v1"> + name = < + value = <"Medication description"> + > + items = < + [1] = (ELEMENT) < + name = < + value = <"Medication name"> + > + archetype_node_id = <"at0001"> + value = (DV_COUNT) < + magnitude = <1> + > + > + > +> \ No newline at end of file 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 new file mode 100644 index 00000000..26976dc2 --- /dev/null +++ b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_7.dadl @@ -0,0 +1,20 @@ +(ITEM_TREE) < + archetype_node_id = <"openEHR-EHR-ITEM_TREE.medication_test_five.v1"> + name = < + value = <"Medication description"> + > + items = < + [1] = (ELEMENT) < + name = < + value = <"Medication name"> + > + archetype_node_id = <"at0001"> + value = (DV_PROPORTION) < + numerator = <0.5> + denominator = <1.0> + type = <0> + precision=<1> + > + > + > +> \ No newline at end of file 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 new file mode 100644 index 00000000..a5030eca --- /dev/null +++ b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_8.dadl @@ -0,0 +1,23 @@ +(ITEM_TREE) < + archetype_node_id = <"openEHR-EHR-ITEM_TREE.medication_test_two.v1"> + name = < + value = <"Medication description"> + > + items = < + [1] = (ELEMENT) < + name = < + value = <"Status"> + > + archetype_node_id = <"at0001"> + value = < + defining_code = < + terminology_id = (TERMINOLOGY_ID) < + value = <"SNOMED-CT"> + > + code_string = <"1201000053901"> + > + value = <"yes"> + > + > + > +> \ No newline at end of file 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 new file mode 100644 index 00000000..caa3d053 --- /dev/null +++ b/rm-skeleton/src/test/resources/dadl/item_tree_medicataion_9.dadl @@ -0,0 +1,26 @@ +(ITEM_TREE) < + archetype_node_id = <"openEHR-EHR-ITEM_TREE.medication_test_seven.v1"> + name = < + value = <"Medication description"> + > + items = < + [1] = (ELEMENT) < + name = < + value = <"Status"> + > + archetype_node_id = <"at0001"> + value = (DV_ORDINAL) < + value = <1> + symbol = < + defining_code = < + terminology_id = (TERMINOLOGY_ID) < + value = <"local"> + > + code_string = <"at0002"> + > + value = <"one"> + > + > + > + > +> \ No newline at end of file diff --git a/rm-skeleton/src/test/resources/log4j.properties b/rm-skeleton/src/test/resources/log4j.properties new file mode 100644 index 00000000..872dfa09 --- /dev/null +++ b/rm-skeleton/src/test/resources/log4j.properties @@ -0,0 +1,13 @@ +# Set root logger level to DEBUG 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 +log4j.logger.org.openehr.rm.util= +log4j.logger.org.openehr.rm.util.RMUtil= +log4j.logger.org.openehr.build= +log4j.logger.org.openehr.am.template.Flattener= +log4j.logger.org.openehr.am.template.TermMap= \ No newline at end of file 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 new file mode 100644 index 00000000..011a4757 --- /dev/null +++ b/rm-skeleton/src/test/resources/oet/test_nested_sections_with_optional_children.oet @@ -0,0 +1,12 @@ + + \ No newline at end of file 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 new file mode 100644 index 00000000..6f0af334 --- /dev/null +++ b/rm-skeleton/src/test/resources/oet/test_section_instruction_tree.oet @@ -0,0 +1,10 @@ + + \ No newline at end of file diff --git a/rm-skeleton/src/test/resources/oet/test_text_name.oet b/rm-skeleton/src/test/resources/oet/test_text_name.oet new file mode 100644 index 00000000..97790f82 --- /dev/null +++ b/rm-skeleton/src/test/resources/oet/test_text_name.oet @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/rm-skeleton/src/test/resources/terms.txt b/rm-skeleton/src/test/resources/terms.txt new file mode 100644 index 00000000..2805b172 --- /dev/null +++ b/rm-skeleton/src/test/resources/terms.txt @@ -0,0 +1,3 @@ +SNOMED-CT::1201000053901::yes +SNOMED-CT::1201000053902::no +SNOMED-CT::1201000053903::unknown \ No newline at end of file diff --git a/rm-skeleton/src/test/resources/xml/purged.xml b/rm-skeleton/src/test/resources/xml/purged.xml new file mode 100644 index 00000000..56978910 --- /dev/null +++ b/rm-skeleton/src/test/resources/xml/purged.xml @@ -0,0 +1,110 @@ + + + + quality-report + + + + openEHR-EHR-COMPOSITION.quality_report.v1 + + 1.0.1 + + + + ISO_639-1 + + en + + + + ISO_3166-1 + + SE + + + event + + + openehr + + 433 + + + + Doctor + + + + non-empty section + + + + hjärtsvikt-allvarlighetsgrad + + + + openEHR-EHR-OBSERVATION.heart_failure_stage.v2 + + 1.0.1 + + + + ISO_639-1 + + en + + + + IANA_character-sets + + UTF-8 + + + + + 1.2.4.5.6.12.1 + + PARTY + + + + + *Event Series(en) + + + 2010-09-02T20:15:53,829 + + + + *Any event(en) + + + 2010-09-02T20:15:53,829 + + + + *List(en) + + + + Trötthet + + + 1 + + Helt opåverkad + + + local + + at0005 + + + + + + + + + + \ No newline at end of file diff --git a/rm-skeleton/src/test/resources/xml/to_purge.xml b/rm-skeleton/src/test/resources/xml/to_purge.xml new file mode 100644 index 00000000..d9ac3dec --- /dev/null +++ b/rm-skeleton/src/test/resources/xml/to_purge.xml @@ -0,0 +1,271 @@ + + + + quality-report + + + + openEHR-EHR-COMPOSITION.quality_report.v1 + + 1.0.1 + + + + ISO_639-1 + + en + + + + ISO_3166-1 + + SE + + + event + + + openehr + + 433 + + + + Doctor + + + + non-empty section + + + + hjärtsvikt-allvarlighetsgrad + + + + openEHR-EHR-OBSERVATION.heart_failure_stage.v2 + + 1.0.1 + + + + ISO_639-1 + + en + + + + IANA_character-sets + + UTF-8 + + + + + 1.2.4.5.6.12.1 + + PARTY + + + + + *Event Series(en) + + + 2010-09-02T20:15:53,829 + + + + *Any event(en) + + + 2010-09-02T20:15:53,829 + + + + *List(en) + + + + Trötthet + + + 1 + + Helt opåverkad + + + local + + at0005 + + + + + + + + + + + Health Status + + + + openEHR-EHR-OBSERVATION.eq_5d.v2 + + 1.0.1 + + + + ISO_639-1 + + en + + + + IANA_character-sets + + UTF-8 + + + + + 1.2.4.5.6.12.1 + + PARTY + + + + + *Event Series(en) + + + 2010-09-02T20:15:53,829 + + + + *Any event(en) + + + 2010-09-02T20:15:53,829 + + + + *List(en) + + + + + + + + + empty section + + + + hjärtsvikt-allvarlighetsgrad + + + + openEHR-EHR-OBSERVATION.heart_failure_stage.v2 + + 1.0.1 + + + + ISO_639-1 + + en + + + + IANA_character-sets + + UTF-8 + + + + + 1.2.4.5.6.12.1 + + PARTY + + + + + *Event Series(en) + + + 2010-09-02T20:15:53,829 + + + + *Any event(en) + + + 2010-09-02T20:15:53,829 + + + + *List(en) + + + + + + + + Health Status + + + + openEHR-EHR-OBSERVATION.eq_5d.v2 + + 1.0.1 + + + + ISO_639-1 + + en + + + + IANA_character-sets + + UTF-8 + + + + + 1.2.4.5.6.12.1 + + PARTY + + + + + *Event Series(en) + + + 2010-09-02T20:15:53,829 + + + + *Any event(en) + + + 2010-09-02T20:15:53,829 + + + + *List(en) + + + + + + + \ No newline at end of file diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml new file mode 100644 index 00000000..e9d040f4 --- /dev/null +++ b/xml-binding/pom.xml @@ -0,0 +1,128 @@ + + + 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} + + + diff --git a/xml-binding/src/main/groovy/load-observation.groovy b/xml-binding/src/main/groovy/load-observation.groovy new file mode 100644 index 00000000..28ce030d --- /dev/null +++ b/xml-binding/src/main/groovy/load-observation.groovy @@ -0,0 +1,12 @@ +import org.openehr.schemas.v1.*; +import org.openehr.binding.*; + +input = new FileInputStream(new File("c:\\tmp\\original_version_002.xml")); + +xml = VersionDocument.Factory.parse(input).getVersion() +ver = new XMLBinding().bindToRM(xml) +comp = ver.getData() +section = comp.getContent().get(0) +obser = section.getItems().get(0) + +println 'name: ' + obser.getName() + ', nodeId: ' + obser.getArchetypeNodeId() \ No newline at end of file diff --git a/xml-binding/src/main/java/org/openehr/binding/RMInspector.java b/xml-binding/src/main/java/org/openehr/binding/RMInspector.java new file mode 100644 index 00000000..8bfdb086 --- /dev/null +++ b/xml-binding/src/main/java/org/openehr/binding/RMInspector.java @@ -0,0 +1,523 @@ +package org.openehr.binding; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.util.*; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +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.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.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.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.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, + + // 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, + UUID.class, + VersionTreeID.class, + + // datatypes classes + DvBoolean.class, + DvURI.class, + DvState.class, + DvIdentifier.class, + DvText.class, + DvCodedText.class, + DvParagraph.class, + CodePhrase.class, + DvCount.class, + DvOrdinal.class, + DvQuantity.class, + DvInterval.class, + DvProportion.class, + ProportionKind.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, 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 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) { + Class rmClass = typeMap.get(rmClassName); + if (rmClass == null) { + rmClass = upperCaseMap.get(rmClassName.replace("_", "")); + } + 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); + + 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; + } + + /* + * 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/xml-binding/src/main/java/org/openehr/binding/XMLBinding.java b/xml-binding/src/main/java/org/openehr/binding/XMLBinding.java new file mode 100644 index 00000000..d78105c2 --- /dev/null +++ b/xml-binding/src/main/java/org/openehr/binding/XMLBinding.java @@ -0,0 +1,509 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Class XMLBinding" + * keywords: "XML binding" + * + * author: "Rong Chen " + * copyright: "Copyright (c) 2008-2010 Cambio Healthcare Systems, Sweden" + * license: "See notice at bottom of class" + * + * file: "$URL$" + * revision: "$LastChangedRevision$" + * last_change: "$LastChangedDate$" + */ +package org.openehr.binding; + +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.math.BigInteger; +import java.util.*; + +import org.apache.log4j.Logger; +import org.apache.xmlbeans.XmlOptions; +import org.openehr.build.RMObjectBuilder; +import org.openehr.build.RMObjectBuildingException; +import org.openehr.build.SystemValue; +import org.openehr.rm.datatypes.quantity.ProportionKind; +import org.openehr.rm.datatypes.text.CodePhrase; +import org.openehr.rm.support.measurement.MeasurementService; +import org.openehr.rm.support.measurement.SimpleMeasurementService; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.terminology.SimpleTerminologyService; + +/** + * Bind data from XMLBeans class to openEHR RM classes + * + * @author Rong.Chen + * @author minor modifications by Erik Sundvall, Linköping University + */ +public class XMLBinding { + + /** + * Constructor allowing use of a custom SystemValue Map + */ + public XMLBinding(Map values) throws XMLBindingException { + try { + init(values); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("failed to start XMLBinding..."); + } + } + + /** + * Default constructor starting the XML-binding using the following system values + *
    + *
  • TERMINOLOGY_SERVICE = an instance of SimpleTerminologyService
  • + *
  • MEASUREMENT_SERVICE = an instance of SimpleMeasurementService
  • + *
  • TERMINOLOGY_SERVICE = an instance of CodePhrase("IANA_character-sets", "UTF-8");
  • + *
+ */ + public XMLBinding() throws XMLBindingException { + try { + TerminologyService termServ = SimpleTerminologyService + .getInstance(); + MeasurementService measureServ = SimpleMeasurementService + .getInstance(); + CodePhrase charset = new CodePhrase("IANA_character-sets", + "UTF-8"); + + Map values = new HashMap(); + values.put(SystemValue.TERMINOLOGY_SERVICE, termServ); + values.put(SystemValue.MEASUREMENT_SERVICE, measureServ); + values.put(SystemValue.CHARSET, charset); + init(values); + + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("failed to start XMLBinding.."); + } + } + + /** + * Binds data from reference model instance to XML binding classes + * + * @param obj + * @return + * @throws XMLBindingException + */ + public Object bindToXML(Object obj) throws XMLBindingException { + if(obj == null) { + return null; + } + String className = obj.getClass().getSimpleName(); + Method[] methods = obj.getClass().getMethods(); + + try { + Class xmlClass = Class.forName(XML_BINDING_PACKAGE + + className.toUpperCase()); + + // debug code only + if(xmlClass.getClasses().length != 1) { + log.debug("XMLBinding: bindToXML(): xmlClass.getClass()=" + xmlClass.getClass()); + log.debug("XMLBinding: bindToXML(): xmlClass.toString()=" + xmlClass.toString()); + for(Class clazz : xmlClass.getClasses()) { + log.debug("\t clazz.getClass()=" + clazz.getClass()); + log.debug("\t clazz.toString()=" + clazz.toString()); + } + } + + Class factoryClass = xmlClass.getClasses()[0]; + + // ES modification: Add xmlOptions containing openehr (default) and xsi namespaces + + // Method factoryMethod = factoryClass.getMethod(NEW_INSTANCE, null); + // Changed to pick the method with an XmlOptions parameter instead + Method factoryMethod = factoryClass.getMethod(NEW_INSTANCE, XmlOptions.class); + + // First prameter null because it's a static method, see: + // http://java.sun.com/docs/books/tutorial/reflect/member/methodInvocation.html + // Second parameter should be the parameter of XmlObject.Factory.newInstance(XmlOptions options) + // see: http://xmlbeans.apache.org/docs/2.2.0/reference/org/apache/xmlbeans/XmlObject.Factory.html + // + // Previous code was: Object xmlObj = factoryMethod.invoke(null, null); + Object xmlObj = factoryMethod.invoke(null, xopt); + + Map attributes = builder.retrieveAttribute(className); + Set attributeNames = attributes.keySet(); + Object attributeValue = null; + Method setterMethod = null; + + for (Method method : methods) { + String name = method.getName(); + + // cause dead-loop + if("getParent".equals(name)) { + continue; // + } + + if (isGetter(name, attributeNames)) { + + log.debug("getter: " + name); + + if(method.getParameterTypes().length > 0) { + continue; + } + + attributeValue = method.invoke(obj, null); + + if (attributeValue == null) { + continue; + } + + log.debug("value.class: " + attributeValue.getClass()); + + boolean isList = false; + + if (attributeValue.getClass().isArray()) { + Object[] array = (Object[]) attributeValue; + if(array.length == 0) { + continue; + } + Object[] done = new Object[array.length]; + for (int i = 0; i < array.length; i++) { + done[i] = bindToXML(array[i]); + } + attributeValue = done; + + } else if (ProportionKind.class.equals( + attributeValue.getClass())) { + + ProportionKind kind = (ProportionKind) attributeValue; + attributeValue = BigInteger.valueOf(kind.getValue()); + + } else if (isOpenEHRRMClass(attributeValue)) { + + attributeValue = bindToXML(attributeValue); + + } else if(List.class.isAssignableFrom( + attributeValue.getClass())) { + + isList = true; + List list = (List) attributeValue; + + log.debug("list.size: " + list.size()); + + String attributeName = getAttributeNameFromGetter(name); + setterMethod = findSetter(attributeName, xmlClass, isList); + + Method addNew = findAddNew(attributeName, xmlClass); + + log.debug("setter: " + setterMethod.getName() + ", xmlClass: " + xmlClass); + + for(int i = 0, j = list.size() - 1; i <= j; i++) { + Object value = list.get(i); + + Object[] array = new Object[2]; + + addNew.invoke(xmlObj, null); + + array[0] = new Integer(i); + array[1] = bindToXML(value); + setterMethod.invoke(xmlObj, array); + + log.debug("list.member value set!!!!"); + } + } + + if( ! isList) { + String attributeName = getAttributeNameFromGetter(name); + + log.debug("attribute: " + attributeName + ", value(" + attributeValue + "), " + + "type: " + attributeValue.getClass()); + + // TODO fix for mismatched attribute name in XSD and RM + if("nullFlavor".equals(attributeName)) { + attributeName = "nullFlavour"; + } + + // skip function according to specs + if("isMerged".equals(attributeName)) { + continue; + } + + setterMethod = findSetter(attributeName, xmlClass, isList); + + if(setterMethod == null) { + log.error("failed to find setterMethod for attribute: " + + attributeName + " with type: " + xmlClass); + continue; + } + + // special handling deals with 'real' typed + // attributes in specs but typed 'float' in xsd + String setter = setterMethod.getName(); + if("setAccuracy".equals(setter) + || "setDenominator".equals(setter) + || "setNumerator".equals(setter)) { + + Double d = (Double) attributeValue; + attributeValue = d.floatValue(); + } + + log.debug("setter: " + setterMethod.getName() + + ", xmlClass: " + xmlClass + + ", attributeValue: " + attributeValue + + ", attributeValue.class: " + attributeValue.getClass()); + + setterMethod.invoke(xmlObj, attributeValue); + } + } + } + + return xmlObj; + + } catch(Exception e) { + e.printStackTrace(); + throw new XMLBindingException("exception caught when bind obj to " + + className + ", " + e.getMessage()); + } + } + + Method findSetter(String attributeName, Class xmlClass, boolean isList) { + Method[] methods = xmlClass.getMethods(); + String name = "set" + attributeName.substring(0, 1).toUpperCase() + + attributeName.substring(1); + + if(isList) { + name += "Array"; + } + + log.debug("search method of name '" + name + "'"); + + for(Method method : methods) { + if(method.getName().equals(name)) { + Type[] paras = method.getParameterTypes(); + if(isList) { + if(paras.length == 2) { + return method; + } + } else if(paras.length == 1) { + return method; + } + } + } + return null; + } + + Method findAddNew(String attributeName, Class xmlClass) { + Method[] methods = xmlClass.getMethods(); + String name = "addNew" + attributeName.substring(0, 1).toUpperCase() + + attributeName.substring(1); + + log.debug("search method of name '" + name + "'"); + + for(Method method : methods) { + if(method.getName().equals(name)) { + return method; + } + } + return null; + } + + Class findXMLAbstractClass(Class xmlClass) throws ClassNotFoundException { + + if( ! xmlClass.getName().contains(XML_BINDING_PACKAGE)) { + return xmlClass; // primitive class + } + + String className = xmlClass.getSimpleName(); + if (className.endsWith("Impl")) { + className = className.substring(0, className.length() - 4); + } + Class abstractClass = Class.forName(XML_BINDING_PACKAGE + className); + return abstractClass; + } + + + /** + * Binds data from XML binding classes to RM classes using reflection + * + * @param value + * @return + * @throws Exception + */ + public Object bindToRM(Object object) throws Exception { + Method[] methods = object.getClass().getMethods(); + Object value = null; + Map valueMap = new HashMap(); + + String className = object.getClass().getSimpleName(); + if (className.endsWith("Impl")) { + className = className.substring(0, className.length() - 4); + } + + Map attributes = builder.retrieveAttribute(className); + Set attributeNames = attributes.keySet(); + + log.debug("attributeNames: " + attributeNames); + + for (Method method : methods) { + String name = method.getName(); + + if (isGetter(name, attributeNames)) { + + if(method.getParameterTypes().length > 0) { + continue; + } + + String attribute = getAttributeNameFromGetter(name); + + value = method.invoke(object, null); + + log.info("getter: " + name + ", attribute: " + attribute + + ", value: " + value); + + if (value == null) { + + continue; + } + + log.debug("value.class: " + value.getClass() + ", " + + isXMLBindingClass(value)); + + if (value.getClass().isArray()) { + Object[] array = (Object[]) value; + if(array.length == 0) { + + // special fix for item_structure.items + if("items".equals(attribute)) { + valueMap.put(attribute, new ArrayList()); + } + continue; + + } else { + + Object[] done = new Object[array.length]; + for (int i = 0; i < array.length; i++) { + done[i] = bindToRM(array[i]); + } + value = done; + } + + } else if (isXMLBindingClass(value)) { + + value = bindToRM(value); + + } + + log.debug("attribute: " + attribute + ", value(" + value + ")"); + + valueMap.put(attribute, value); + } + } + + log.info("building rm class: " + className + + ", with valueMap: " + valueMap); + + Object rmObj = null; + + try { + + rmObj = builder.construct(className, valueMap); + + } catch (RMObjectBuildingException e) { + + log.warn(">>> FAILED to build instance of " + className + + ", exception: " + e.getMessage()); + } + return rmObj; + } + + + + /* checks if the given method is a known getter of attributes */ + private boolean isGetter(String method, Set attributes) { + if (!method.startsWith("get")) { + return false; + } + String name = getAttributeNameFromGetter(method); + return attributes.contains(name); + } + + /* turns a getter's name into an attribute name */ + private String getAttributeNameFromGetter(String name) { + name = name.substring(3, name.length()); + name = name.substring(0, 1).toLowerCase() + name.substring(1); + if(name.endsWith("Array")) { + name = name.substring(0, name.length() - 5); + } + return name; + } + + private boolean isXMLBindingClass(Object obj) { + return obj.getClass().getName().contains(XML_BINDING_PACKAGE); + } + + private boolean isOpenEHRRMClass(Object obj) { + return obj.getClass().getName().contains(OPENEHR_RM_PACKAGE); + } + + + protected void init(Map values) throws XMLBindingException{ + + // Set up xml defaults + xopt = new XmlOptions(); + + HashMap uriToPrefixMap = new HashMap(); + uriToPrefixMap.put(SCHEMA_XSI, "xsi"); + uriToPrefixMap.put(SCHEMA_OPENEHR_ORG_V1, "v1"); + xopt.setSaveSuggestedPrefixes(uriToPrefixMap); + + xopt.setSaveAggressiveNamespaces(); + xopt.setSavePrettyPrint(); + xopt.setCharacterEncoding("UTF-8"); + + try { + builder = new RMObjectBuilder(values); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("failed to start XMLBinding..."); + } + } + + /* logger */ + private static Logger log = Logger.getLogger(XMLBinding.class); + + /* namespace for generated binding class */ + private static String XML_BINDING_PACKAGE = "org.openehr.schemas.v1."; + + /* namespace for rm class */ + private static String OPENEHR_RM_PACKAGE = "org.openehr.rm."; + + /* factory method name */ + private static String NEW_INSTANCE = "newInstance"; + + public static final String SCHEMA_XSI = "http://www.w3.org/2001/XMLSchema-instance"; + public static final String SCHEMA_OPENEHR_ORG_V1 = "http://schemas.openehr.org/v1"; + + /* the builder used to create rm objects */ + private RMObjectBuilder builder; + + /* ES: XMLOptions to make nicer XML */ + private XmlOptions xopt; +} +/* + * ***** 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 XMLBinding.java + * + * The Initial Developer of the Original Code is Rong Chen. Portions created by + * the Initial Developer are Copyright (C) 2003-2010 the Initial Developer. All + * Rights Reserved. + * + * Contributor(s): Erik Sundvall + * + * 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/xml-binding/src/main/java/org/openehr/binding/XMLBindingException.java b/xml-binding/src/main/java/org/openehr/binding/XMLBindingException.java new file mode 100644 index 00000000..49e718dd --- /dev/null +++ b/xml-binding/src/main/java/org/openehr/binding/XMLBindingException.java @@ -0,0 +1,48 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Class XMLBindingException" + * keywords: "XML binding" + * + * author: "Rong Chen " + * 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.binding; + +public class XMLBindingException extends Exception { + public XMLBindingException() { + } + + public XMLBindingException(String msg) { + super(msg); + } +} +/* + * ***** 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 XMLBindingException.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): + * + * 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/xml-binding/src/main/xsd/Archetype.xsd b/xml-binding/src/main/xsd/Archetype.xsd new file mode 100644 index 00000000..c0e75758 --- /dev/null +++ b/xml-binding/src/main/xsd/Archetype.xsd @@ -0,0 +1,394 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xml-binding/src/main/xsd/BaseTypes.xsd b/xml-binding/src/main/xsd/BaseTypes.xsd new file mode 100644 index 00000000..2a366498 --- /dev/null +++ b/xml-binding/src/main/xsd/BaseTypes.xsd @@ -0,0 +1,594 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xml-binding/src/main/xsd/Composition.xsd b/xml-binding/src/main/xsd/Composition.xsd new file mode 100644 index 00000000..1b4a3f44 --- /dev/null +++ b/xml-binding/src/main/xsd/Composition.xsd @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xml-binding/src/main/xsd/Content.xsd b/xml-binding/src/main/xsd/Content.xsd new file mode 100644 index 00000000..2823bd5a --- /dev/null +++ b/xml-binding/src/main/xsd/Content.xsd @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xml-binding/src/main/xsd/Extract.xsd b/xml-binding/src/main/xsd/Extract.xsd new file mode 100644 index 00000000..ffe2d573 --- /dev/null +++ b/xml-binding/src/main/xsd/Extract.xsd @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xml-binding/src/main/xsd/OpenehrProfile.xsd b/xml-binding/src/main/xsd/OpenehrProfile.xsd new file mode 100644 index 00000000..660491ab --- /dev/null +++ b/xml-binding/src/main/xsd/OpenehrProfile.xsd @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xml-binding/src/main/xsd/Resource.xsd b/xml-binding/src/main/xsd/Resource.xsd new file mode 100644 index 00000000..50fd3614 --- /dev/null +++ b/xml-binding/src/main/xsd/Resource.xsd @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xml-binding/src/main/xsd/Structure.xsd b/xml-binding/src/main/xsd/Structure.xsd new file mode 100644 index 00000000..71b008bd --- /dev/null +++ b/xml-binding/src/main/xsd/Structure.xsd @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xml-binding/src/main/xsd/Version.xsd b/xml-binding/src/main/xsd/Version.xsd new file mode 100644 index 00000000..5b613333 --- /dev/null +++ b/xml-binding/src/main/xsd/Version.xsd @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xml-binding/src/test/java/org/openehr/binding/BindDataTypesTest.java b/xml-binding/src/test/java/org/openehr/binding/BindDataTypesTest.java new file mode 100644 index 00000000..6e01cb23 --- /dev/null +++ b/xml-binding/src/test/java/org/openehr/binding/BindDataTypesTest.java @@ -0,0 +1,39 @@ +package org.openehr.binding; + +import java.math.BigInteger; + +import org.openehr.rm.datatypes.quantity.DvProportion; +import org.openehr.rm.datatypes.quantity.ProportionKind; +import org.openehr.schemas.v1.DVPROPORTION; + +public class BindDataTypesTest extends XMLBindingTestBase { + + public void testBindDvProportionToXML() throws Exception { + DvProportion bp = new DvProportion(0.5, 1.0, ProportionKind.RATIO, null); + Object obj = binding.bindToXML(bp); + + assertTrue("XML class wrong", obj instanceof DVPROPORTION); + } + + public void testBindXMLDvProportionToRM() throws Exception { + DVPROPORTION xobj = DVPROPORTION.Factory.parse( + fromClasspath("dv_proportion.xml")); + + assertTrue("expected dv_proportion, but got: " + + (xobj == null ? null : xobj.getClass()), + xobj instanceof DVPROPORTION); + + DVPROPORTION prop = (DVPROPORTION) xobj; + assertEquals("unexpected proportion.numerator", 0.5f, + prop.getNumerator()); + assertEquals("unexpected proportion.denominator", 1.0f, + prop.getDenominator()); + assertEquals("unexpected proportion.type", BigInteger.valueOf(0), + prop.getType()); + assertEquals("unexpected proportion.precision", 1, + prop.getPrecision()); + + Object rmObj = binding.bindToRM(prop); + assertTrue("expected dv_proportion", rmObj instanceof DvProportion); + } +} \ No newline at end of file diff --git a/xml-binding/src/test/java/org/openehr/binding/BindEmptyItemTreeTest.java b/xml-binding/src/test/java/org/openehr/binding/BindEmptyItemTreeTest.java new file mode 100644 index 00000000..30e9b4a5 --- /dev/null +++ b/xml-binding/src/test/java/org/openehr/binding/BindEmptyItemTreeTest.java @@ -0,0 +1,27 @@ +package org.openehr.binding; + +import org.openehr.rm.datastructure.itemstructure.ItemTree; +import org.openehr.schemas.v1.*; + +public class BindEmptyItemTreeTest extends XMLBindingTestBase { + + public void testBindXMLDvProportionToRM() throws Exception { + ITEMTREE tree = ITEMTREE.Factory.parse(fromClasspath( + "empty_item_tree.xml")); + + assertEquals(0, tree.getItemsArray().length); + assertEquals(0, tree.sizeOfItemsArray()); + + + // do the data binding + Object rmObj = binding.bindToRM(tree); + + assertTrue("unexpected type: " + + (rmObj == null ? "null" : rmObj.getClass()), + rmObj instanceof ItemTree); + + ItemTree itemTree = (ItemTree) rmObj; + assertNotNull("unexpected null items attribute", itemTree.getItems()); + assertTrue(itemTree.getItems().isEmpty()); + } +} diff --git a/xml-binding/src/test/java/org/openehr/binding/BindItemTreeWithDvProportionTest.java b/xml-binding/src/test/java/org/openehr/binding/BindItemTreeWithDvProportionTest.java new file mode 100644 index 00000000..0c768789 --- /dev/null +++ b/xml-binding/src/test/java/org/openehr/binding/BindItemTreeWithDvProportionTest.java @@ -0,0 +1,32 @@ +package org.openehr.binding; + +import org.openehr.schemas.v1.DVPROPORTION; +import org.openehr.schemas.v1.ELEMENT; +import org.openehr.schemas.v1.ITEMTREE; +import org.openehr.schemas.v1.ItemsDocument; + +import java.math.BigInteger; + +public class BindItemTreeWithDvProportionTest extends XMLBindingTestBase { + + public void testBindXMLDvProportionToRM() throws Exception { + ItemsDocument xobj = ItemsDocument.Factory.parse(fromClasspath( + "item_tree_003.xml")); + Object obj = xobj.getItems(); + ITEMTREE tree = (ITEMTREE) obj; + ELEMENT element = (ELEMENT) tree.getItemsArray(0); + Object value = element.getValue(); + + assertTrue("expected dv_proportion, but got: " + + (xobj == null ? null : value.getClass()), + value instanceof DVPROPORTION); + + DVPROPORTION prop = (DVPROPORTION) value; + assertEquals("unexpected proportion.numerator", 0.5f, + prop.getNumerator()); + assertEquals("unexpected proportion.denominator", 1.0f, + prop.getDenominator()); + assertEquals("unexpected proportion.type", BigInteger.valueOf(0), + prop.getType()); + } +} diff --git a/xml-binding/src/test/java/org/openehr/binding/BindStructureToXMLTest.java b/xml-binding/src/test/java/org/openehr/binding/BindStructureToXMLTest.java new file mode 100644 index 00000000..f06a3560 --- /dev/null +++ b/xml-binding/src/test/java/org/openehr/binding/BindStructureToXMLTest.java @@ -0,0 +1,196 @@ +package org.openehr.binding; + +import java.util.*; + +import javax.xml.namespace.QName; + +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.openehr.rm.common.archetyped.Archetyped; +import org.openehr.rm.common.changecontrol.OriginalVersion; +import org.openehr.rm.common.generic.PartyProxy; +import org.openehr.rm.common.generic.PartySelf; +import org.openehr.rm.composition.content.entry.Observation; +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.ItemList; +import org.openehr.rm.datastructure.itemstructure.ItemStructure; +import org.openehr.rm.datastructure.itemstructure.ItemTree; +import org.openehr.rm.datastructure.itemstructure.representation.Element; +import org.openehr.rm.datastructure.itemstructure.representation.Item; +import org.openehr.rm.datatypes.quantity.DvQuantity; +import org.openehr.rm.datatypes.quantity.datetime.DvDateTime; +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.ArchetypeID; +import org.openehr.rm.support.terminology.TerminologyService; +import org.openehr.schemas.v1.*; +import org.openehr.terminology.SimpleTerminologyService; + +public class BindStructureToXMLTest extends XMLBindingTestBase { + + public void testBindElementToXML() throws Exception { + DvText text = new DvText("new text"); + Element element = new Element("at0001", "text element", text); + + Object obj = binding.bindToXML(element); + + assertTrue("XML class wrong", obj instanceof ELEMENT); + + ELEMENT xmlElement = (ELEMENT) obj; + assertTrue("value type wrong", xmlElement.getValue() instanceof DVTEXT); + + DVTEXT xmlText = (DVTEXT) xmlElement.getValue(); + assertEquals("text value wrong", "new text", xmlText.getValue()); + } + + public void testBindEmptyElementToXML() throws Exception { + DvCodedText nullFlavor = new DvCodedText("no information", + new CodePhrase(TerminologyService.OPENEHR, "271")); + + TerminologyService ts = SimpleTerminologyService.getInstance(); + + Element element = new Element(null, "at0001", new DvText("name"), + null, null, null, null, null, nullFlavor, ts); + + Object obj = binding.bindToXML(element); + + assertTrue("XML class wrong", obj instanceof ELEMENT); + + ELEMENT xmlElement = (ELEMENT) obj; + assertNull("value type wrong", xmlElement.getValue()); + assertNotNull("nullFlavor null", xmlElement.getNullFlavour()); + } + + + public void testBindItemTreeToXML() throws Exception { + DvText text = new DvText("new text"); + Element element1 = new Element("at0001", "text element", text); + + DvQuantity dvq = new DvQuantity(10.0); + Element element2 = new Element("at0002", "dvq element", dvq); + + List items = new ArrayList(); + items.add(element1); + items.add(element2); + + ItemTree tree = new ItemTree("at0003", "item tree", items); + + //printXML(tree); + + Object obj = binding.bindToXML(tree); + + assertTrue("XML class wrong", obj instanceof ITEMTREE); + + ITEMTREE xmlTree = (ITEMTREE) obj; + + //System.out.println(xmlTree.toString()); + + assertEquals("items.size wrong", 2, xmlTree.getItemsArray().length); + + ELEMENT xmlItem1 = (ELEMENT) xmlTree.getItemsArray()[0]; + + assertTrue("item1 type wrong", xmlItem1.getValue() instanceof DVTEXT); + assertEquals("new text", ((DVTEXT) xmlItem1.getValue()).getValue()); + + ELEMENT xmlItem2 = (ELEMENT) xmlTree.getItemsArray()[1]; + assertTrue("item2 type wrong", xmlItem2.getValue() instanceof DVQUANTITY); + assertEquals(10.0, ((DVQUANTITY) xmlItem2.getValue()).getMagnitude()); + } + + public void testBindObservationToXML() throws Exception { + DvText text = new DvText("new text"); + Element element1 = new Element("at0001", "text element", text); + + DvQuantity dvq = new DvQuantity(10.0); + Element element2 = new Element("at0002", "dvq element", dvq); + + List items = new ArrayList(); + items.add(element1); + items.add(element2); + + ItemTree tree = new ItemTree("at0003", "item tree", items); + + String archetypeNodeId="openEHR-EHR-OBSERVATION.laboratory-lipids.v1"; + DvText name = new DvText("Lipids"); + CodePhrase language = new CodePhrase("ISO_639-1", "en"); + CodePhrase encoding = new CodePhrase("IANA_character-sets", "UTF-8"); + PartyProxy subject = new PartySelf(); + PartyProxy provider = null; + DvDateTime time = new DvDateTime("2008-05-22T20:04:26"); + PointEvent event = new PointEvent("at0002", + new DvText("Any event"), time, tree); + Archetyped archetypeDetails = new Archetyped( + new ArchetypeID(archetypeNodeId), "1.0.2"); + List> events = new ArrayList>(); + events.add(event); + + History data = new History("at0005", "data", + new DvDateTime("2008-05-17T10:00:00"), events); + + TerminologyService terminologyService = + SimpleTerminologyService.getInstance(); + + Observation obs = new Observation(archetypeNodeId, name, + archetypeDetails, language, encoding, subject, provider, + data, terminologyService); + + //printXML(obs); + + Object obj = binding.bindToXML(obs); + + // System.out.println(obj.toString()); + + assertTrue("unexpected XML class: " + obj.getClass(), + obj instanceof OBSERVATION); + } + + // TODO shortcut solution, load a versioned_composition + // thru xml file and bind it to RM objects + public void testBindVersionedCompositionToXML() throws Exception { + VERSION xobj = VersionDocument.Factory.parse( + fromClasspath("original_version_002.xml")).getVersion(); + + assertTrue("expected originial_version, but got: " + + (xobj == null ? null : xobj.getClass()), + xobj instanceof ORIGINALVERSION); + + // do the data binding + Object rmObj = binding.bindToRM(xobj); + +// assertTrue("rmObj not a OriginalVersion, got " +// + (rmObj == null ? null : rmObj.getClass()), +// rmObj instanceof OriginalVersion); + + OriginalVersion orgVer = (OriginalVersion) rmObj; + + // Will throw exceptions if faulty + Object obj = binding.bindToXML(orgVer); + + + // *** Code that exemplifies pretty printing with namespace tweaks + XmlOptions xopt = new XmlOptions(); + + xopt.setSaveOuter(); + xopt.setSaveSyntheticDocumentElement(new QName(XMLBinding.SCHEMA_OPENEHR_ORG_V1, "version")); + + HashMap uriToPrefixMap = new HashMap(); + //uriToPrefixMap.put(XMLBinding.SCHEMA_OPENEHR_ORG_V1, "v1"); + xopt.setSaveSuggestedPrefixes(uriToPrefixMap); + + xopt.setSaveNamespacesFirst(); + xopt.setSaveAggressiveNamespaces(); + xopt.setSavePrettyPrint(); + xopt.setCharacterEncoding("UTF-8"); + + // Uncomment two lines below if less prefixing is desired, but repeated + // namespace declarations are ok (in nodes containing xsi:type) + uriToPrefixMap.put(XMLBinding.SCHEMA_OPENEHR_ORG_V1, ""); + xopt.setUseDefaultNamespace(); + + + // System.out.println(">>>>>>>>>> \n\r" + ((XmlObject)obj).xmlText(xopt)); + } +} diff --git a/xml-binding/src/test/java/org/openehr/binding/CreateXMLObjectTest.java b/xml-binding/src/test/java/org/openehr/binding/CreateXMLObjectTest.java new file mode 100644 index 00000000..cbeac36e --- /dev/null +++ b/xml-binding/src/test/java/org/openehr/binding/CreateXMLObjectTest.java @@ -0,0 +1,176 @@ +package org.openehr.binding; + +import java.io.File; +import java.lang.reflect.Method; + +import org.apache.commons.io.FileUtils; +import org.openehr.schemas.v1.*; + +public class CreateXMLObjectTest extends XMLBindingTestBase { + + public void testCreateDVTEXT() throws Exception { + DVTEXT dvtext = DVTEXT.Factory.newInstance(); + dvtext.setValue("test value"); + } + + public void testCreateDvQuantity() throws Exception { + DVQUANTITY dvq = DVQUANTITY.Factory.newInstance(); + dvq.setUnits("mmol/l"); + dvq.setMagnitude(6.1); + } + + public void testCreateElement() throws Exception { + ELEMENT element = ELEMENT.Factory.newInstance(); + element.setName(dvText("name")); + element.setValue(dvQuantity(6.1, "mmol/l")); + } + + public void testCreateItemTree() throws Exception { + ITEMTREE tree = ITEMTREE.Factory.newInstance(); + tree.setName(dvText("item tree")); + ELEMENT element = element("element", 6.1, "mmol/l"); + tree.insertNewItems(0); + tree.setItemsArray(0, element); + + assertNotNull(tree.getItemsArray(0)); + assertEquals("element", + ((ELEMENT) tree.getItemsArray(0)).getName().getValue()); + } + + public void testCreatePointEvent() throws Exception { + POINTEVENT pe = POINTEVENT.Factory.newInstance(); + pe.setName(dvText("any event")); + pe.setTime(dvDateTime("2008-05-22T20:04:26")); + pe.setData(itemTree()); + } + + public void testCreateObservation() throws Exception { + OBSERVATION obs = OBSERVATION.Factory.newInstance(); + obs.setName(dvText("Lipid studies")); + obs.setArchetypeNodeId("openEHR-EHR-OBSERVATION.laboratory-lipids.v1"); + obs.setLanguage(codePhrase("ISO_639-1", "en")); + obs.setEncoding(codePhrase("IANA_character-sets", "UTF-8")); + obs.setArchetypeDetails(archetyped( + "openEHR-EHR-OBSERVATION.laboratory-lipids.v1", + "Lipids", "1.0.1")); + obs.setSubject(partySelf()); + obs.setData(history()); + //FileUtils.writeStringToFile(new File("xml.txt"), obs.toString(), null); + } + + public void testCreateInstanceWithReflection() throws Exception { + Class klass = Class.forName("org.openehr.schemas.v1.DVTEXT"); + Class factoryClass = klass.getClasses()[0]; + Method factoryMethod = factoryClass.getMethod("newInstance", null); + Object obj = factoryMethod.invoke(null, null); + assertTrue(obj instanceof DVTEXT); + } + + public void testCallSetterWithReflection() throws Exception { + Class klass = Class.forName("org.openehr.schemas.v1.DVTEXT"); + Class factoryClass = klass.getClasses()[0]; + Method factoryMethod = factoryClass.getMethod("newInstance", null); + Object obj = factoryMethod.invoke(null, null); + Method setterMethod = klass.getMethod("setValue", String.class); + setterMethod.invoke(obj, "new value"); + + assertEquals("new value", ((DVTEXT) obj).getValue()); + } + + private HISTORY history() { + HISTORY history = HISTORY.Factory.newInstance(); + history.setName(dvText("data")); + history.setOrigin(dvDateTime("2008-05-22T20:04:26")); + history.insertNewEvents(0); + history.setEventsArray(0, pointEvent()); + return history; + } + + private PARTYSELF partySelf() { + return PARTYSELF.Factory.newInstance(); + } + + private ARCHETYPED archetyped(String archetypeId, String templateId, + String rmVersion) { + ARCHETYPED archetyped = ARCHETYPED.Factory.newInstance(); + archetyped.setArchetypeId(archetypeId(archetypeId)); + archetyped.setTemplateId(templateId(templateId)); + archetyped.setRmVersion(rmVersion); + return archetyped; + } + + private TEMPLATEID templateId(String value) { + TEMPLATEID tid = TEMPLATEID.Factory.newInstance(); + tid.setValue(value); + return tid; + } + + private ARCHETYPEID archetypeId(String value) { + ARCHETYPEID aid = ARCHETYPEID.Factory.newInstance(); + aid.setValue(value); + return aid; + } + + private TERMINOLOGYID terminologyId(String value) { + TERMINOLOGYID tid = TERMINOLOGYID.Factory.newInstance(); + tid.setValue(value); + return tid; + } + + private CODEPHRASE codePhrase(String terminologyId, String code) { + CODEPHRASE cp = CODEPHRASE.Factory.newInstance(); + cp.setTerminologyId(terminologyId(terminologyId)); + cp.setCodeString(code); + return cp; + } + + private POINTEVENT pointEvent() { + POINTEVENT pe = POINTEVENT.Factory.newInstance(); + pe.setName(dvText("any event")); + pe.setTime(dvDateTime("2008-05-22T20:04:26")); + pe.setData(itemTree()); + return pe; + } + + private ITEMTREE itemTree() { + ITEMTREE tree = ITEMTREE.Factory.newInstance(); + tree.setName(dvText("data")); + ELEMENT element = null; + + element = element("Total Cholesterol", 6.1, "mmol/l"); + tree.insertNewItems(0); + tree.setItemsArray(0, element); + + element = element("Triglycerides", 2.3, "mmol/l"); + tree.insertNewItems(1); + tree.setItemsArray(1, element); + + return tree; + } + + private ELEMENT element(String name, double value, String units) { + ELEMENT element = ELEMENT.Factory.newInstance(); + element.setName(dvText(name)); + element.setValue(dvQuantity(value, units)); + return element; + } + + private DVDATETIME dvDateTime(String value) { + DVDATETIME datetime = DVDATETIME.Factory.newInstance(); + datetime.setValue(value); + return datetime; + } + + private DVTEXT dvText(String value) { + DVTEXT text = DVTEXT.Factory.newInstance(); + text.setValue(value); + return text; + } + + private DVQUANTITY dvQuantity(double magnitude, String units) { + DVQUANTITY dvq = DVQUANTITY.Factory.newInstance(); + dvq.setUnits(units); + dvq.setMagnitude(magnitude); + return dvq; + } +} diff --git a/xml-binding/src/test/java/org/openehr/binding/RMBindingTest.java b/xml-binding/src/test/java/org/openehr/binding/RMBindingTest.java new file mode 100644 index 00000000..7ad76504 --- /dev/null +++ b/xml-binding/src/test/java/org/openehr/binding/RMBindingTest.java @@ -0,0 +1,117 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Class RMBindingTest" + * keywords: "XML binding test" + * + * author: "Rong Chen " + * 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.binding; + +import org.openehr.rm.common.changecontrol.OriginalVersion; +import org.openehr.rm.composition.Composition; +import org.openehr.rm.composition.content.entry.Observation; +import org.openehr.rm.composition.content.navigation.Section; +import org.openehr.rm.datastructure.itemstructure.ItemTree; +import org.openehr.schemas.v1.ORIGINALVERSION; +import org.openehr.schemas.v1.VERSION; +import org.openehr.schemas.v1.VersionDocument; + +public class RMBindingTest extends XMLBindingTestBase { + + // Parse a complete versioned_composition from a XML file + // and bind the data to RM objects and then inspect the details + public void testParseAndBindToOriginalVersion() throws Exception { + VERSION xobj = VersionDocument.Factory.parse( + fromClasspath("original_version_002.xml")).getVersion(); + + assertTrue("expected originial_version, but got: " + + (xobj == null ? null : xobj.getClass()), + xobj instanceof ORIGINALVERSION); + + // do the data binding + Object rmObj = binding.bindToRM(xobj); + + assertTrue("rmObj not a OriginalVersion, got " + + (rmObj == null ? null : rmObj.getClass()), + rmObj instanceof OriginalVersion); + + OriginalVersion orgVer = (OriginalVersion) rmObj; + + Composition comp = (Composition) orgVer.getData(); + Section section = (Section) comp.getContent().get(0); + + assertEquals("section.items.size wrong", 1, section.getItems().size()); + + Observation obser = (Observation) section.getItems().get(0); + + assertNotNull("observation is null", obser); + + assertEquals("openEHR-EHR-OBSERVATION.laboratory-lipids.v1", + obser.getArchetypeNodeId()); + + //printXML(orgVer); + + String path; + + // verify the versioned_composition + assertEquals("93658", orgVer.getContribution().getId().getValue()); + assertEquals("creation", orgVer.getCommitAudit().getChangeType().getValue()); + + // verify the composition + assertEquals("Lipids", comp.itemAtPath("/name/value")); + assertEquals("Event", comp.itemAtPath("/category/value")); + assertEquals("Lipids", comp.itemAtPath("/archetype_details/template_id/value")); + + // verify the observation + assertEquals("openEHR-EHR-OBSERVATION.laboratory-lipids.v1", obser.getArchetypeNodeId()); + + path = "/content[openEHR-EHR-SECTION.findings.v1]"; + assertTrue(comp.itemAtPath(path) instanceof Section); + + path += "/items[openEHR-EHR-OBSERVATION.laboratory-lipids.v1]"; + + assertTrue(comp.itemAtPath(path) instanceof Observation); + assertEquals("Lipid studies", comp.itemAtPath(path + "/name/value")); + + // verify the item_structure + path += "/data/events[at0002]/data"; + assertTrue(comp.itemAtPath(path) instanceof ItemTree); + + assertEquals("Total Cholesterol", + comp.itemAtPath(path + "/items[at0013.1]/name/value")); + + assertEquals(6.1, + comp.itemAtPath(path + "/items[at0013.1]/value/magnitude")); + } +} +/* + * ***** 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 RMBindingTest.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/xml-binding/src/test/java/org/openehr/binding/VersionedDocumentTest.java b/xml-binding/src/test/java/org/openehr/binding/VersionedDocumentTest.java new file mode 100644 index 00000000..88eb99c1 --- /dev/null +++ b/xml-binding/src/test/java/org/openehr/binding/VersionedDocumentTest.java @@ -0,0 +1,12 @@ +package org.openehr.binding; + +import org.openehr.schemas.v1.VersionDocument; + +public class VersionedDocumentTest extends XMLBindingTestBase { + + public void testParsingVersionedDocument() throws Exception { + VersionDocument vd = + VersionDocument.Factory.parse( + fromClasspath("original_version_002.xml")); + } +} diff --git a/xml-binding/src/test/java/org/openehr/binding/XMLBindingTestBase.java b/xml-binding/src/test/java/org/openehr/binding/XMLBindingTestBase.java new file mode 100644 index 00000000..9ba1832d --- /dev/null +++ b/xml-binding/src/test/java/org/openehr/binding/XMLBindingTestBase.java @@ -0,0 +1,30 @@ +package org.openehr.binding; + +import java.io.InputStream; + +import com.thoughtworks.xstream.XStream; + +import junit.framework.TestCase; + +public class XMLBindingTestBase extends TestCase { + + public void setUp() throws Exception { + binding = new XMLBinding(); + } + + protected InputStream fromClasspath(String filename) throws Exception { + return this.getClass().getClassLoader().getResourceAsStream(filename); + } + + protected String toXML(Object obj) throws Exception { + XStream xstream = new XStream(); + String xml = xstream.toXML(obj); + return xml; + } + + protected void printXML(Object obj) throws Exception { + System.out.println(toXML(obj)); + } + + protected XMLBinding binding; +} diff --git a/xml-binding/src/test/java/org/openehr/binding/XMLParsingTest.java b/xml-binding/src/test/java/org/openehr/binding/XMLParsingTest.java new file mode 100644 index 00000000..6eeacfa2 --- /dev/null +++ b/xml-binding/src/test/java/org/openehr/binding/XMLParsingTest.java @@ -0,0 +1,145 @@ +/* + * component: "openEHR Java Reference Implementation" + * description: "Class XMLParsingTest" + * keywords: "XML binding testing" + * + * author: "Rong Chen " + * 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.binding; + +import java.io.*; + +import org.openehr.rm.datastructure.itemstructure.ItemTree; +import org.openehr.schemas.v1.*; +import junit.framework.TestCase; + +/** + * Verify XML parsing is OK + * + * @author Rong.Chen + */ +public class XMLParsingTest extends TestCase { + + public void testParseItemTree() throws Exception { + ItemsDocument xobj = ItemsDocument.Factory.parse(fromClasspath("item_tree.xml")); + Object obj = xobj.getItems(); + assertTrue("expected ITEM_TREE, but got: " + obj.getClass(), + obj instanceof ITEMTREE); + ITEMTREE tree = (ITEMTREE) obj; + assertEquals("tree.name wrong", "Tree", tree.getName().getValue()); + + ELEMENT element = (ELEMENT) tree.getItemsArray(0); + assertEquals("element.name wrong", "Blood glucose", + element.getName().getValue()); + + DVQUANTITY quantity = (DVQUANTITY) element.getValue(); + assertEquals("quantity.magnitude wrong", 100.0, quantity.getMagnitude()); + } + + public void testParseItemTree2() throws Exception { + ItemsDocument xobj = ItemsDocument.Factory.parse(fromClasspath("item_tree_002.xml")); + Object obj = xobj.getItems(); + assertTrue("expected ITEM_TREE, but got: " + obj.getClass(), + obj instanceof ITEMTREE); + ITEMTREE tree = (ITEMTREE) obj; + assertEquals("tree.name wrong", "data", tree.getName().getValue()); + + } + + public void testParseCompositionAndVerifyTheContent() throws Exception { + CompositionDocument compDoc = CompositionDocument.Factory.parse( + fromClasspath("composition.xml")); + + assertNotNull("compositionDocument null", compDoc); + + COMPOSITION comp = compDoc.getComposition(); + + // set of queries to make sure we get the data right + assertEquals("name wrong", "Lipids", comp.getName().getValue()); + assertEquals("territory wrong", "AU", comp.getTerritory().getCodeString()); + + assertEquals("context startTime wrong", "20080522T200427,833+0930", + comp.getContext().getStartTime().getValue()); + + OBSERVATION obs = (OBSERVATION) ((SECTION)comp.getContentArray(0)).getItemsArray()[0]; + + //assertTrue(((SECTION) comp.getContentArray(0)).getItemsArray()).getData() + // .getEventsArray(0)).getData() instanceof OBSERVATION); + + //assertTrue("observation.data.events[0].items[0]", + // (((OBSERVATION)((SECTION) comp.getContentArray(0))).getItemsArray()).getData() + // .getEventsArray(0).getData() instanceof ITEMTREE); + + ITEMTREE itemTree = (ITEMTREE) obs.getData().getEventsArray(0).getData(); + ELEMENT element = (ELEMENT) itemTree.getItemsArray(0); + + assertEquals("observation.data.events[0].items[0].data.value.magnitude", + 6.1, ((DVQUANTITY) element.getValue()).getMagnitude()); + } + + public void testParseOriginalVersion() throws Exception { + VERSION xobj = VersionDocument.Factory.parse(fromClasspath( + "original_version_001.xml")).getVersion(); + + assertTrue("expected originial_version, but got: " + xobj.getClass(), + xobj instanceof ORIGINALVERSION); + + + ORIGINALVERSION orgVer = (ORIGINALVERSION) xobj; + + assertEquals("originalVersion.uid wrong", + "c7ff23f4-6ad2-4ff9-bedf-fb60be37666e::10aec661-5458-4ff6-8e63-c2265537196d::1", + orgVer.getUid().getValue()); + + assertTrue(orgVer.getData() instanceof COMPOSITION); + + COMPOSITION comp = (COMPOSITION) orgVer.getData(); + assertEquals(1, comp.getContentArray().length); + + Object item = comp.getContentArray()[0]; + assertTrue("unexpected class: " + item.getClass(), + item instanceof SECTION); + + SECTION section = (SECTION) item; + OBSERVATION obser = (OBSERVATION) section.getItemsArray()[0]; + + assertEquals("openEHR-EHR-OBSERVATION.laboratory-lipids.v1", + obser.getArchetypeNodeId()); + } + + private InputStream fromClasspath(String filename) throws Exception { + return this.getClass().getClassLoader().getResourceAsStream( + filename); + } +} +/* + * ***** 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 XMLParsingTest.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/xml-binding/src/test/resources/composition-discharge.xml b/xml-binding/src/test/resources/composition-discharge.xml new file mode 100644 index 00000000..22cdea30 --- /dev/null +++ b/xml-binding/src/test/resources/composition-discharge.xml @@ -0,0 +1,185 @@ + + + Discharge Summary + + + + openehr + + en + + + + ISO 1366 + + 036 + + + event + + + openehr + + 433 + + + + Peri Yankemout + + + + 2006-11-22T18:57:06 + + + unknown + + + openehr + + 251 + + + + + Tree + + + + Episode identifier + + + 2c4a06c2-e3bd-4cd3-a6bb-1fd83df66107 + + + + + HappyBubs Hospital + + + + + Interventions + + + + Vitamin K + + + + openehr + + en + + + + IANA + + utf-8 + + + + + + Medication description + + + + Name of medication + + + Vitamin K + + + + + + self + + + openehr + + 0 + + + + + + + + + + + + + + + + Hepatitis B + + + + openehr + + en + + + + IANA + + utf-8 + + + + + + Vaccine description + + + + Vaccine + + + Hepatitis B + + + + + Administration information + + + + Sequence number + + + 1 + + + + + + + self + + + openehr + + 0 + + + + + + + + + + + + + + + diff --git a/xml-binding/src/test/resources/composition-prescription.xml b/xml-binding/src/test/resources/composition-prescription.xml new file mode 100644 index 00000000..7356c60e --- /dev/null +++ b/xml-binding/src/test/resources/composition-prescription.xml @@ -0,0 +1,313 @@ + + + + Prescription + + + + openehr + + en + + + + ISO 1366 + + 036 + + + event + + + openehr + + 433 + + + + Dr J Pyle + + + + 2006-11-22T18:57:04 + + + unknown + + + openehr + + 251 + + + + + + Medications + + + + antibiotics + + + + openehr + + en + + + + IANA + + utf-8 + + + + + + + + Medication activity + + + + Medication description + + + + Name of medication + + + Amoxil + + + + + Administration instructions + + + Take 500 mg every eight hours for five days. + + + + + Strength per dose unit + + + 500 + mg + 0 + + + + + Form + + + Tablet + + + snomed + + 385055001 + + + + + + Dose + + + 1 + + + + + Dose unit + + + mg + + + snomed + + 258684004 + + + + + + Dose duration + + + 6 + d + 0 + + + + + Route + + + Medication administration: oral + + + snomed + + 386359008 + + + + + + Is long term + + + false + + + + + Indications + + + + Indication + + + Acute bacterial tonsillitis + + + snomed + + 195671000 + + + + + + + Generic name + + + local + + at0012 + + + + Oral form amoxicillin + + + snomed + + 350162003 + + + + + + Safety limits + + + + Maximum dose unit frequency + + + 2 + {QUALIFIED REAL/TIME} + 0 + + + + + Minimum dose interval + + + 12 + h + 0 + + + + + Maximum dose interval + + + 6 + h + 0 + + + + + + Administration information + + + + Date of first administration + + + 2005-10-26T00:00:00 + + + + + Sequence number + + + 1 + + + + + + Dispensing information + + + + Dispensing information + + + 9000 + mg + 0 + + + + + Number of authorised repeat dispensing + + + 1 + + + + + Dispensed product + + + Amoxil + + + + + Brand substitution allowed + + + true + + + + + + + + + openEHR-EHR-ACTION.medication.v1 + + + + diff --git a/xml-binding/src/test/resources/composition.xml b/xml-binding/src/test/resources/composition.xml new file mode 100644 index 00000000..93ebf849 --- /dev/null +++ b/xml-binding/src/test/resources/composition.xml @@ -0,0 +1,162 @@ + + + Lipids + + + c7ff23f4-6ad2-4ff9-bedf-fb60be37666e::10aec661-5458-4ff6-8e63-c2265537196d::1 + + + + openEHR-EHR-COMPOSITION.report.v1 + + + Lipids + + 1.0.1 + + + + ISO_639-1 + + en + + + + ISO_3166-1 + + AU + + + Event + + + openehr + + 433 + + + + guest + + + + 20080522T200427,833+0930 + + + unknown + + + openehr + + 228 + + + + Ocean health + + + + + Clinical findings + + + + Lipid studies + + + + ISO_639-1 + + en + + + + IANA_character-sets + + UTF-8 + + + + openEHR-EHR-OBSERVATION.laboratory-lipids.v1 + + + Lipids + + 1.0.1 + + + + + data + + + 2008-05-22T20:04:26 + + + + Any event + + + + + data + + + + Total Cholesterol + + + 6.1 + mmol/l + + + + + Triglycerides + + + 2.3 + mmol/l + + + + + Fractions + + + + HDL-Cholesterol + + + 0.9 + mmol/l + + + + + LDL-Cholesterol + + + 5.2 + mmol/l + + + + + + Overall Comment + + + high cardiac risk + + + + + + + + \ No newline at end of file diff --git a/xml-binding/src/test/resources/dv_proportion.xml b/xml-binding/src/test/resources/dv_proportion.xml new file mode 100644 index 00000000..3243dc7f --- /dev/null +++ b/xml-binding/src/test/resources/dv_proportion.xml @@ -0,0 +1,7 @@ + + 0.0 + 0.5 + 1.0 + 0 + 1 + \ No newline at end of file diff --git a/xml-binding/src/test/resources/empty_item_tree.xml b/xml-binding/src/test/resources/empty_item_tree.xml new file mode 100644 index 00000000..7ec31308 --- /dev/null +++ b/xml-binding/src/test/resources/empty_item_tree.xml @@ -0,0 +1,8 @@ + + + item tree + + \ No newline at end of file diff --git a/xml-binding/src/test/resources/item_tree.xml b/xml-binding/src/test/resources/item_tree.xml new file mode 100644 index 00000000..34bb5e95 --- /dev/null +++ b/xml-binding/src/test/resources/item_tree.xml @@ -0,0 +1,17 @@ + + + Tree + + + + Blood glucose + + + 100 + mmol/l + 0 + + + \ No newline at end of file diff --git a/xml-binding/src/test/resources/item_tree_002.xml b/xml-binding/src/test/resources/item_tree_002.xml new file mode 100644 index 00000000..313a05e0 --- /dev/null +++ b/xml-binding/src/test/resources/item_tree_002.xml @@ -0,0 +1,56 @@ + + + data + + + + Total Cholesterol + + + 6.1 + mmol/l + + + + + Triglycerides + + + 2.3 + mmol/l + + + + + Fractions + + + + HDL-Cholesterol + + + 0.9 + mmol/l + + + + + LDL-Cholesterol + + + 52 + mmol/l + + + + + + Overall Comment + + + high cardiac risk + + + \ No newline at end of file diff --git a/xml-binding/src/test/resources/item_tree_003.xml b/xml-binding/src/test/resources/item_tree_003.xml new file mode 100644 index 00000000..f590f33f --- /dev/null +++ b/xml-binding/src/test/resources/item_tree_003.xml @@ -0,0 +1,18 @@ + + + Tree + + + + Blood glucose + + + 0.0 + 0.5 + 1.0 + 0 + + + \ No newline at end of file diff --git a/xml-binding/src/test/resources/log4j.properties b/xml-binding/src/test/resources/log4j.properties new file mode 100644 index 00000000..6316ae58 --- /dev/null +++ b/xml-binding/src/test/resources/log4j.properties @@ -0,0 +1,9 @@ +# Set root logger level to DEBUG and its only appender to stdout. +log4j.rootLogger=ERROR, 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.binding= \ No newline at end of file diff --git a/xml-binding/src/test/resources/original_version_001.xml b/xml-binding/src/test/resources/original_version_001.xml new file mode 100644 index 00000000..ac0d39a9 --- /dev/null +++ b/xml-binding/src/test/resources/original_version_001.xml @@ -0,0 +1,192 @@ + + + + + 93658 + + + + + + + 10aec661-5458-4ff6-8e63-c2265537196d + + guest + + + 2008-05-22T10:34:28,1141Z + + + creation + + + openehr + + 249 + + + + + c7ff23f4-6ad2-4ff9-bedf-fb60be37666e::10aec661-5458-4ff6-8e63-c2265537196d::1 + + + + Lipids + + + c7ff23f4-6ad2-4ff9-bedf-fb60be37666e::10aec661-5458-4ff6-8e63-c2265537196d::1 + + + + openEHR-EHR-COMPOSITION.report.v1 + + + Lipids + + 1.0.1 + + + + + + + + + + ISO 1366 + + 036 + + + Event + + + openehr + + 433 + + + + guest + + + + 2008-05-22T20:04:27,833+0930 + + + unknown + + + openehr + + 251 + + + + Ocean health + + + + + Clinical findings + + + + Lipid studies + + + + ISO 639 + + en + + + + IANA + + utf-8 + + + + + data + + + 2008-05-22T20:04:26,8801+0930 + + + + Any event + + + + + data + + + + Total Cholesterol + + + 6.1 + mmol/l + + + + + Triglycerides + + + 2.3 + mmol/l + + + + + Fractions + + + + HDL-Cholesterol + + + 0.9 + mmol/l + + + + + LDL-Cholesterol + + + 52 + mmol/l + + + + + + Overall Comment + + + high cardiac risk + + + + + + + + + + completed + + + openehr + + 532 + + + diff --git a/xml-binding/src/test/resources/original_version_002.xml b/xml-binding/src/test/resources/original_version_002.xml new file mode 100644 index 00000000..adc28f93 --- /dev/null +++ b/xml-binding/src/test/resources/original_version_002.xml @@ -0,0 +1,201 @@ + + + + + 93658 + local + + EHR + COMPOSITION + + + 10aec661-5458-4ff6-8e63-c2265537196d + + guest + + + 2008-05-22T10:34:28 + + + creation + + + openehr + + 249 + + + + + c7ff23f4-6ad2-4ff9-bedf-fb60be37666e::10aec661-5458-4ff6-8e63-c2265537196d::1 + + + + Lipids + + + c7ff23f4-6ad2-4ff9-bedf-fb60be37666e::10aec661-5458-4ff6-8e63-c2265537196d::1 + + + + openEHR-EHR-COMPOSITION.report.v1 + + + Lipids + + 1.0.1 + + + + ISO_639-1 + + en + + + + ISO_3166-1 + + AU + + + Event + + + openehr + + 433 + + + + guest + + + + 2008-05-22T20:04:27,833+0930 + + + unknown + + + openehr + + 228 + + + + Ocean health + + + + + Clinical findings + + + + Lipid studies + + + + ISO_639-1 + + en + + + + IANA_character-sets + + UTF-8 + + + + openEHR-EHR-OBSERVATION.laboratory-lipids.v1 + + + Lipids + + 1.0.1 + + + + + data + + + 2008-05-22T20:04:26 + + + + Any event + + + + + data + + + + Total Cholesterol + + + 6.1 + mmol/l + + + + + Triglycerides + + + 2.3 + mmol/l + + + + + Fractions + + + + HDL-Cholesterol + + + 0.9 + mmol/l + + + + + LDL-Cholesterol + + + 5.2 + mmol/l + + + + + + Overall Comment + + + high cardiac risk + + + + + + + + + + completed + + + openehr + + 532 + + + \ No newline at end of file diff --git a/xml-binding/src/test/resources/simple_composition.xml b/xml-binding/src/test/resources/simple_composition.xml new file mode 100644 index 00000000..f4dfd5b0 --- /dev/null +++ b/xml-binding/src/test/resources/simple_composition.xml @@ -0,0 +1,122 @@ + + + Lipids + + + c7ff23f4-6ad2-4ff9-bedf-fb60be37666e::10aec661-5458-4ff6-8e63-c2265537196d::1 + + + + openEHR-EHR-COMPOSITION.report.v1 + + + Lipids + + 1.0.1 + + + + ISO_639-1 + + en + + + + ISO_3166-1 + + AU + + + Event + + + openehr + + 433 + + + + guest + + + + 20080522T200427,833+0930 + + + unknown + + + openehr + + 228 + + + + Ocean health + + + + + Clinical findings + + + + Lipid studies + + + + ISO_639-1 + + en + + + + IANA_character-sets + + UTF-8 + + + + openEHR-EHR-OBSERVATION.laboratory-lipids.v1 + + + Lipids + + 1.0.1 + + + + + data + + + 2008-05-22T20:04:26 + + + + Any event + + + + + data + + + + Total Cholesterol + + + 6.1 + mmol/l + + + + + + + + \ No newline at end of file diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml new file mode 100644 index 00000000..db1119c4 --- /dev/null +++ b/xml-serializer/pom.xml @@ -0,0 +1,66 @@ + + 4.0.0 + + openehr + ref_impl_java + 1.0.5-SNAPSHOT + + xml-serializer + jar + XML Serializer + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2004 + + Java XML Serializer of the Archetype Object Model + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + openehr-aom + ${project.version} + + + openehr + openehr-ap + ${project.version} + + + commons-lang + commons-lang + 2.6 + + + jdom + jdom + 1.0 + compile + + + commons-io + commons-io + 1.2 + test + + + junit + junit + 3.8.1 + test + + + \ No newline at end of file diff --git a/xml-serializer/readme.txt b/xml-serializer/readme.txt new file mode 100644 index 00000000..3fb5b5bb --- /dev/null +++ b/xml-serializer/readme.txt @@ -0,0 +1 @@ +XML serializer of the Archetype Object Model 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 new file mode 100644 index 00000000..986b42a8 --- /dev/null +++ b/xml-serializer/src/main/java/org/openehr/am/serialize/XMLSerializer.java @@ -0,0 +1,1091 @@ +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. + * + * ***** END LICENSE BLOCK ***** */ \ No newline at end of file From 22cbaf29629214502b518127734c15253ba69f1a Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Fri, 7 Feb 2014 11:03:18 +0000 Subject: [PATCH 010/213] (CDS) CDS-130 Added target folders to ignore list. git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk@471944 24d5da94-7af6-7447-9e6c-d9f96020beb6 From 6235f73f4035ff369f3f883e1304f869b40344dd Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Fri, 7 Feb 2014 11:41:52 +0000 Subject: [PATCH 011/213] (CDS) CDS-130 Added release and cobertura plugin. git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk@471997 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- pom.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pom.xml b/pom.xml index d0f576e6..cfd7841e 100644 --- a/pom.xml +++ b/pom.xml @@ -58,6 +58,25 @@ true + + org.apache.maven.plugins + maven-release-plugin + 2.3.2 + + (CDS) + + + + org.codehaus.mojo + cobertura-maven-plugin + 2.5.1 + + + + xml + + + From 5716050f73ee6005789c45b19d1da9c8c15e2f09 Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Fri, 7 Feb 2014 13:12:19 +0000 Subject: [PATCH 012/213] (CDS) CDS-177 Fixed scm from git to svn. git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk@472047 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index cfd7841e..3f24e6f6 100644 --- a/pom.xml +++ b/pom.xml @@ -12,9 +12,9 @@ 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 + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ + https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ From 1c4ca810a6e807e529b0c022d423c873bee7065b Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Fri, 7 Feb 2014 13:23:03 +0000 Subject: [PATCH 013/213] (CDS)prepare release ref_impl_java-1.0.5 git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk@472051 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 156 +++++++++++----------- archetype-validator/pom.xml | 176 ++++++++++++------------- dadl-binding/pom.xml | 168 +++++++++++------------ dadl-parser/pom.xml | 160 +++++++++++----------- measure-serv/pom.xml | 80 +++++------ mini-termserv/pom.xml | 90 ++++++------- oet-parser/pom.xml | 238 ++++++++++++++++----------------- openehr-aom/pom.xml | 92 ++++++------- openehr-ap/pom.xml | 112 ++++++++-------- openehr-rm-core/pom.xml | 90 ++++++------- openehr-rm-domain/pom.xml | 92 ++++++------- pom.xml | 200 ++++++++++++++-------------- rm-builder/pom.xml | 120 ++++++++--------- rm-skeleton/pom.xml | 188 +++++++++++++------------- xml-binding/pom.xml | 256 ++++++++++++++++++------------------ xml-serializer/pom.xml | 130 +++++++++--------- 17 files changed, 1174 insertions(+), 1176 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 1a2efa4e..ceb6b2b8 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.5-SNAPSHOT + 1.0.5 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 0d39ed21..4f00a14c 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -1,78 +1,78 @@ - - 4.0.0 - - openehr - ref_impl_java - 1.0.5-SNAPSHOT - - adl-serializer - jar - ADL Serializer - http://www.openehr.org/projects/java.html - - openEHR - http://www.openehr.org/ - - 2004 - - java ADL Serializer for Archetype Object Model - - - - - src/test/adl - - - - - - - openehr - openehr-rm-core - ${project.version} - - - openehr - openehr-rm-domain - ${project.version} - - - openehr - openehr-aom - ${project.version} - - - openehr - openehr-ap - ${project.version} - - - openehr - mini-termserv - ${project.version} - - - openehr - adl-parser - ${project.version} - test - - - commons-lang - commons-lang - 2.6 - - - commons-io - commons-io - 1.2 - test - - - junit - junit - 3.8.1 - test - - - + + 4.0.0 + + openehr + ref_impl_java + 1.0.5 + + adl-serializer + jar + ADL Serializer + http://www.openehr.org/projects/java.html + + openEHR + http://www.openehr.org/ + + 2004 + + java ADL Serializer for Archetype Object Model + + + + + src/test/adl + + + + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + openehr-aom + ${project.version} + + + openehr + openehr-ap + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + openehr + adl-parser + ${project.version} + test + + + commons-lang + commons-lang + 2.6 + + + commons-io + commons-io + 1.2 + test + + + junit + junit + 3.8.1 + test + + + diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 2992000a..8e800019 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -1,89 +1,87 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.5-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.5 - 1.5 - - - - - - - - commons-lang - commons-lang - 2.4 - - - log4j - log4j - 1.2.13 - - - openehr - openehr-rm-core - ${project.version} - - - openehr - openehr-rm-domain - ${project.version} - - - openehr - openehr-aom - ${project.version} - - - openehr - openehr-ap - ${project.version} - - - openehr - mini-termserv - ${project.version} - - - openehr - measure-serv - ${project.version} - - - openehr - adl-parser - ${project.version} - test - - - junit - junit - 3.8.1 - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5 + + 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.5 + 1.5 + + + + + + + + commons-lang + commons-lang + 2.4 + + + log4j + log4j + 1.2.13 + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + openehr-aom + ${project.version} + + + openehr + openehr-ap + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + openehr + measure-serv + ${project.version} + + + openehr + adl-parser + ${project.version} + test + + + junit + junit + 3.8.1 + + + diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index c81942cc..06ce401f 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -1,84 +1,84 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.5-SNAPSHOT - - dadl-binding - jar - java dADL Binding - http://www.openehr.org/svn/ref_impl_java/TRUNK/project_page.htm - - openEHR - http://www.openehr.org/ - - 2008 - java openEHR RM and dADL Binding Component - - - - openehr - openehr-rm-core - ${project.version} - - - - - openehr - openehr-aom - ${project.version} - - - - - openehr - adl-parser - ${project.version} - - - - - openehr - openehr-rm-domain - ${project.version} - - - openehr - mini-termserv - ${project.version} - - - openehr - measure-serv - ${project.version} - - - openehr - rm-builder - ${project.version} - - - openehr - dadl-parser - ${project.version} - - - junit - junit - 3.8.1 - test - - - commons-jxpath - commons-jxpath - 1.3 - - - commons-io - commons-io - 2.3 - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5 + + dadl-binding + jar + java dADL Binding + http://www.openehr.org/svn/ref_impl_java/TRUNK/project_page.htm + + openEHR + http://www.openehr.org/ + + 2008 + java openEHR RM and dADL Binding Component + + + + openehr + openehr-rm-core + ${project.version} + + + + + openehr + openehr-aom + ${project.version} + + + + + openehr + adl-parser + ${project.version} + + + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + openehr + measure-serv + ${project.version} + + + openehr + rm-builder + ${project.version} + + + openehr + dadl-parser + ${project.version} + + + junit + junit + 3.8.1 + test + + + commons-jxpath + commons-jxpath + 1.3 + + + commons-io + commons-io + 2.3 + + + diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 496f33f1..f4cf7ae3 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -1,80 +1,80 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.5-SNAPSHOT - - dadl-parser - jar - java dADL Parser - http://svn.openehr.org/ref_impl_java/TRUNK/project_page.htm - - openEHR - http://www.openehr.org/ - - 2007 - - java dADL Parser - - - - - org.codehaus.mojo - javacc-maven-plugin - 2.6 - - - - javacc - - - - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.codehaus.mojo - javacc-maven-plugin - [2.1,) - - javacc - - - - - - - - - - - - - - - - - openehr - openehr-rm-core - ${project.version} - - - junit - junit - 3.8.1 - test - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5 + + dadl-parser + jar + java dADL Parser + http://svn.openehr.org/ref_impl_java/TRUNK/project_page.htm + + openEHR + http://www.openehr.org/ + + 2007 + + java dADL Parser + + + + + org.codehaus.mojo + javacc-maven-plugin + 2.6 + + + + javacc + + + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.codehaus.mojo + javacc-maven-plugin + [2.1,) + + javacc + + + + + + + + + + + + + + + + + openehr + openehr-rm-core + ${project.version} + + + junit + junit + 3.8.1 + test + + + diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 2efaca6d..6c2d9404 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -1,40 +1,40 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.5-SNAPSHOT - - measure-serv - jar - openEHR Measurement Service Implementation - http://www.openehr.org/projects/java.html - - - openEHR - http://www.openehr.org/ - - 2007 - - Java implementation of the openEHR Measurement Service - - - - commons-lang - commons-lang - 2.6 - - - junit - junit - 3.8.1 - test - - - javax.measure - jsr-275 - 0.9.4 - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5 + + measure-serv + jar + openEHR Measurement Service Implementation + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2007 + + Java implementation of the openEHR Measurement Service + + + + commons-lang + commons-lang + 2.6 + + + junit + junit + 3.8.1 + test + + + javax.measure + jsr-275 + 0.9.4 + + + diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index bfd23682..dfd19fad 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -1,45 +1,45 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.5-SNAPSHOT - - mini-termserv - jar - openEHR Minimum Terminology Service - http://www.openehr.org/projects/java.html - - - openEHR - http://www.openehr.org/ - - 2007 - - The minimum terminology service required by the Java kernel - - - - openehr - openehr-rm-core - ${project.version} - - - jdom - jdom - 1.0 - - - log4j - log4j - 1.2.8 - - - junit - junit - 3.8.1 - test - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5 + + mini-termserv + jar + openEHR Minimum Terminology Service + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2007 + + The minimum terminology service required by the Java kernel + + + + openehr + openehr-rm-core + ${project.version} + + + jdom + jdom + 1.0 + + + log4j + log4j + 1.2.8 + + + junit + junit + 3.8.1 + test + + + diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 55f0f184..2734d7b2 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -1,119 +1,119 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.5-SNAPSHOT - - oet-parser - jar - openEHR OET Template Parser and Flattener - - - rong.chen - Rong Chen - rong.acode@gmail.com - - - - - openEHR - http://www.openehr.org/ - - 2007 - Java implementation of openEHR OET Template Parser and Flattener - - UTF-8 - - - - - 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} - - - openehr - openehr-aom - ${project.version} - - - openehr - adl-parser - ${project.version} - - - org.apache.xmlbeans - xmlbeans - 2.3.0 - - - javax.xml.bind - jsr173_api - 1.0 - - - openehr - measure-serv - ${project.version} - - - openehr - mini-termserv - ${project.version} - - - junit - junit - 3.8.1 - test - - - com.thoughtworks.xstream - xstream - 1.3.1 - test - - - openehr - adl-serializer - ${project.version} - - - log4j - log4j - 1.2.13 - - - commons-io - commons-io - 1.4 - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5 + + oet-parser + jar + openEHR OET Template Parser and Flattener + + + rong.chen + Rong Chen + rong.acode@gmail.com + + + + + openEHR + http://www.openehr.org/ + + 2007 + Java implementation of openEHR OET Template Parser and Flattener + + UTF-8 + + + + + 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} + + + openehr + openehr-aom + ${project.version} + + + openehr + adl-parser + ${project.version} + + + org.apache.xmlbeans + xmlbeans + 2.3.0 + + + javax.xml.bind + jsr173_api + 1.0 + + + openehr + measure-serv + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + junit + junit + 3.8.1 + test + + + com.thoughtworks.xstream + xstream + 1.3.1 + test + + + openehr + adl-serializer + ${project.version} + + + log4j + log4j + 1.2.13 + + + commons-io + commons-io + 1.4 + + + diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 862b9fad..1eab25fc 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -1,46 +1,46 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.5-SNAPSHOT - - openehr-aom - jar - openEHR Archetype Object Model - http://www.openehr.org/projects/java.html - - - openEHR - http://www.openehr.org/ - - 2004 - - Java implementation of the openEHR Archetype Object Model - - - - - openehr - openehr-rm-core - ${project.version} - - - openehr - openehr-rm-domain - ${project.version} - - - commons-lang - commons-lang - 2.6 - - - junit - junit - 3.8.1 - test - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5 + + openehr-aom + jar + openEHR Archetype Object Model + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2004 + + Java implementation of the openEHR Archetype Object Model + + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + commons-lang + commons-lang + 2.6 + + + junit + junit + 3.8.1 + test + + + diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 5d1d9027..e4dba22f 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -1,56 +1,56 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.5-SNAPSHOT - - openehr-ap - jar - openEHR Archetype Profile - http://www.openehr.org/projects/java.html - - - openEHR - http://www.openehr.org/ - - 2004 - - Java implementation of the openEHR Archetype Profile - - - - openehr - openehr-rm-core - ${project.version} - - - openehr - openehr-rm-domain - ${project.version} - - - openehr - openehr-aom - ${project.version} - - - openehr - measure-serv - ${project.version} - test - - - commons-lang - commons-lang - 2.6 - - - junit - junit - 3.8.1 - test - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5 + + openehr-ap + jar + openEHR Archetype Profile + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2004 + + Java implementation of the openEHR Archetype Profile + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + openehr-aom + ${project.version} + + + openehr + measure-serv + ${project.version} + test + + + commons-lang + commons-lang + 2.6 + + + junit + junit + 3.8.1 + test + + + diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 50bba5b4..d8c20ab5 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -1,45 +1,45 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.5-SNAPSHOT - - openehr-rm-core - jar - openEHR Reference Model Core - http://www.openehr.org/projects/java.html - - - openEHR - http://www.openehr.org/ - - 2004 - - Java implementation of the openEHR Reference Model Core - - - - commons-lang - commons-lang - 2.6 - - - joda-time - joda-time - 2.2 - - - junit - junit - 3.8.1 - test - - - openehr - measure-serv - ${project.version} - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5 + + openehr-rm-core + jar + openEHR Reference Model Core + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2004 + + Java implementation of the openEHR Reference Model Core + + + + commons-lang + commons-lang + 2.6 + + + joda-time + joda-time + 2.2 + + + junit + junit + 3.8.1 + test + + + openehr + measure-serv + ${project.version} + + + diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index e0cb2e57..47be11c9 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -1,46 +1,46 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.5-SNAPSHOT - - openehr-rm-domain - jar - openEHR Reference Model Domain - http://www.openehr.org/projects/java.html - - - openEHR - http://www.openehr.org/ - - 2004 - - Java implementation of the openEHR Reference Model Domain - - - - openehr - openehr-rm-core - ${project.version} - - - openehr - mini-termserv - ${project.version} - test - - - commons-lang - commons-lang - 2.6 - - - junit - junit - 3.8.1 - test - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5 + + openehr-rm-domain + jar + openEHR Reference Model Domain + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2004 + + Java implementation of the openEHR Reference Model Domain + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + mini-termserv + ${project.version} + test + + + commons-lang + commons-lang + 2.6 + + + junit + junit + 3.8.1 + test + + + diff --git a/pom.xml b/pom.xml index 3f24e6f6..b04e6c2b 100644 --- a/pom.xml +++ b/pom.xml @@ -1,101 +1,101 @@ - - 4.0.0 - openehr - ref_impl_java - pom - 1.0.5-SNAPSHOT - The openEHR Reference Java Implementation - - The openEHR Foundation - - - UTF-8 - - - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ - https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ - - - - - maven-compiler-plugin - 2.3.2 - - 1.6 - 1.6 - - - - - 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 - - - - org.apache.maven.plugins - maven-release-plugin - 2.3.2 - - (CDS) - - - - org.codehaus.mojo - cobertura-maven-plugin - 2.5.1 - - - - xml - - - - - - - - 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 - + + 4.0.0 + openehr + ref_impl_java + pom + 1.0.5 + The openEHR Reference Java Implementation + + The openEHR Foundation + + + UTF-8 + + + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.5 + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.5 + https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.5 + + + + + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + + + + + 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 + + + + org.apache.maven.plugins + maven-release-plugin + 2.3.2 + + (CDS) + + + + org.codehaus.mojo + cobertura-maven-plugin + 2.5.1 + + + + xml + + + + + + + + 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 + \ No newline at end of file diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 9c61b917..4a47cbfb 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -1,60 +1,60 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.5-SNAPSHOT - - rm-builder - jar - openEHR Reference Model Object Builder - http://www.openehr.org/projects/java.html - - - openEHR - http://www.openehr.org/ - - 2004 - - Reference Model objects creation named class and values - - - - openehr - openehr-rm-core - ${project.version} - - - openehr - openehr-rm-domain - ${project.version} - - - openehr - mini-termserv - ${project.version} - - - openehr - measure-serv - ${project.version} - - - commons-lang - commons-lang - 2.6 - - - log4j - log4j - 1.2.13 - - - junit - junit - 3.8.1 - test - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5 + + rm-builder + jar + openEHR Reference Model Object Builder + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2004 + + Reference Model objects creation named class and values + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + openehr + measure-serv + ${project.version} + + + commons-lang + commons-lang + 2.6 + + + log4j + log4j + 1.2.13 + + + junit + junit + 3.8.1 + test + + + diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index ab0b199f..bd06990d 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -1,94 +1,94 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.5-SNAPSHOT - - rm-skeleton - jar - openEHR RM Skeleton Instance Generator - - - - openehr - openehr-rm-core - ${project.version} - - - openehr - openehr-rm-domain - ${project.version} - - - openehr - openehr-aom - ${project.version} - - - openehr - adl-parser - ${project.version} - - - openehr - dadl-parser - ${project.version} - - - openehr - oet-parser - ${project.version} - - - openehr - measure-serv - ${project.version} - - - openehr - mini-termserv - ${project.version} - - - openehr - dadl-binding - ${project.version} - - - openehr - xml-binding - ${project.version} - - - junit - junit - 4.5 - test - - - com.thoughtworks.xstream - xstream - 1.3.1 - test - - - openehr - adl-serializer - ${project.version} - test - - - log4j - log4j - 1.2.13 - - - commons-io - commons-io - 1.4 - test - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.5 + + rm-skeleton + jar + openEHR RM Skeleton Instance Generator + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + openehr-aom + ${project.version} + + + openehr + adl-parser + ${project.version} + + + openehr + dadl-parser + ${project.version} + + + openehr + oet-parser + ${project.version} + + + openehr + measure-serv + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + openehr + dadl-binding + ${project.version} + + + openehr + xml-binding + ${project.version} + + + junit + junit + 4.5 + test + + + com.thoughtworks.xstream + xstream + 1.3.1 + test + + + openehr + adl-serializer + ${project.version} + test + + + log4j + log4j + 1.2.13 + + + commons-io + commons-io + 1.4 + test + + + diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index e9d040f4..e5ddd411 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -1,128 +1,128 @@ - - - 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 + + openehr + ref_impl_java + 1.0.5 + + 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} + + + diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index db1119c4..e71f8e92 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -1,66 +1,66 @@ - - 4.0.0 - - openehr - ref_impl_java - 1.0.5-SNAPSHOT - - xml-serializer - jar - XML Serializer - http://www.openehr.org/projects/java.html - - - openEHR - http://www.openehr.org/ - - 2004 - - Java XML Serializer of the Archetype Object Model - - - - openehr - openehr-rm-core - ${project.version} - - - openehr - openehr-rm-domain - ${project.version} - - - openehr - openehr-aom - ${project.version} - - - openehr - openehr-ap - ${project.version} - - - commons-lang - commons-lang - 2.6 - - - jdom - jdom - 1.0 - compile - - - commons-io - commons-io - 1.2 - test - - - junit - junit - 3.8.1 - test - - + + 4.0.0 + + openehr + ref_impl_java + 1.0.5 + + xml-serializer + jar + XML Serializer + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2004 + + Java XML Serializer of the Archetype Object Model + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + openehr-aom + ${project.version} + + + openehr + openehr-ap + ${project.version} + + + commons-lang + commons-lang + 2.6 + + + jdom + jdom + 1.0 + compile + + + commons-io + commons-io + 1.2 + test + + + junit + junit + 3.8.1 + test + + \ No newline at end of file From 6e75b40f3def4aa13c88ce9270622b5d6ba8bf22 Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Fri, 7 Feb 2014 13:23:12 +0000 Subject: [PATCH 014/213] (CDS)prepare for next development iteration git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk@472053 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 8 ++++---- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 20 insertions(+), 20 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index ceb6b2b8..355d6c9f 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.5 + 1.0.6-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 4f00a14c..e80cc64c 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.5 + 1.0.6-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 8e800019..68224a55 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.5 + 1.0.6-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 06ce401f..d70f6d53 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.5 + 1.0.6-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index f4cf7ae3..872c721e 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.5 + 1.0.6-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 6c2d9404..3430a600 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.5 + 1.0.6-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index dfd19fad..9a7bc346 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.5 + 1.0.6-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 2734d7b2..2dbe7ca2 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.5 + 1.0.6-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 1eab25fc..0e2167df 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.5 + 1.0.6-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index e4dba22f..3e9c97ca 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.5 + 1.0.6-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index d8c20ab5..0635f0a7 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.5 + 1.0.6-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 47be11c9..8b51ed1d 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.5 + 1.0.6-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index b04e6c2b..42cc924b 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java pom - 1.0.5 + 1.0.6-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -12,9 +12,9 @@ UTF-8 - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.5 - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.5 - https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.5 + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ + https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 4a47cbfb..449a2032 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.5 + 1.0.6-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index bd06990d..55d56451 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.5 + 1.0.6-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index e5ddd411..f89970b8 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.5 + 1.0.6-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index e71f8e92..1bf1ed7d 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.5 + 1.0.6-SNAPSHOT xml-serializer jar From 9f4f10a1b0e9b8a6b20d89d22d35eb46635eb1ea Mon Sep 17 00:00:00 2001 From: "Iago.Corbal" Date: Fri, 7 Feb 2014 14:03:50 +0000 Subject: [PATCH 015/213] (CDS) removing dadl binding git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk@472058 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- dadl-binding/tree_2_slots.dadl | 164 -------------------------- rm-skeleton/hypersensitivity_max.dadl | 136 --------------------- rm-skeleton/hypersensitivity_min.dadl | 136 --------------------- 3 files changed, 436 deletions(-) delete mode 100644 dadl-binding/tree_2_slots.dadl delete mode 100644 rm-skeleton/hypersensitivity_max.dadl delete mode 100644 rm-skeleton/hypersensitivity_min.dadl diff --git a/dadl-binding/tree_2_slots.dadl b/dadl-binding/tree_2_slots.dadl deleted file mode 100644 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/rm-skeleton/hypersensitivity_max.dadl b/rm-skeleton/hypersensitivity_max.dadl deleted file mode 100644 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_min.dadl b/rm-skeleton/hypersensitivity_min.dadl deleted file mode 100644 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"> - > - > -> From febda6e1f72dc1a99eb5a6ae4976e13519b06fda Mon Sep 17 00:00:00 2001 From: "Iago.Corbal" Date: Fri, 7 Feb 2014 14:06:34 +0000 Subject: [PATCH 016/213] (CDS) removing dadl binding git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk@472059 24d5da94-7af6-7447-9e6c-d9f96020beb6 From 4daf4134691fa3f744368e1c0740807cf14ad50b Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Fri, 7 Feb 2014 14:14:48 +0000 Subject: [PATCH 017/213] (CDS) CDS-177 Added distribution management. git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk@472061 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- pom.xml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 42cc924b..16cc7ac5 100644 --- a/pom.xml +++ b/pom.xml @@ -97,5 +97,18 @@ dadl-binding rm-skeleton archetype-validator - + + + + repo.cambio.se_releases + releases + http://repo.cambio.se/content/repositories/releases + + + repo.cambio.se_snapshots + snapshots + http://repo.cambio.se/content/repositories/snapshots + false + + \ No newline at end of file From 9979c15eae67b78baaa2e5aa51f8c8aa34e38459 Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Tue, 18 Mar 2014 10:54:01 +0000 Subject: [PATCH 018/213] (CDS) CDS-247 Updated modules to use java 1.5 as compiler target, and updated all dependencies to the new snapshots. git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk@495580 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 16cc7ac5..e0181193 100644 --- a/pom.xml +++ b/pom.xml @@ -22,8 +22,8 @@ maven-compiler-plugin 2.3.2 - 1.6 - 1.6 + 1.5 + 1.5 From e6efb862fed88f545344714f0c41ee64645ba63f Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Tue, 18 Mar 2014 12:27:24 +0000 Subject: [PATCH 019/213] (CDS)prepare release ref_impl_java-1.0.6 git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk@495669 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 34 +++++++++++++++++----------------- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 33 insertions(+), 33 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 355d6c9f..2c226f83 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index e80cc64c..49442bfd 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 68224a55..95f3342f 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index d70f6d53..e6c39648 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 872c721e..1a7834cc 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 3430a600..df8f0a5b 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 9a7bc346..08e4e2e6 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 2dbe7ca2..ddf79e09 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 0e2167df..1991be8d 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 3e9c97ca..42a805f0 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 0635f0a7..736ce371 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 8b51ed1d..a8011e30 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index e0181193..5d799e32 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java pom - 1.0.6-SNAPSHOT + 1.0.6 The openEHR Reference Java Implementation The openEHR Foundation @@ -12,9 +12,9 @@ UTF-8 - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ - https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.6 + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.6 + https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.6 @@ -97,18 +97,18 @@ dadl-binding rm-skeleton archetype-validator - - - - repo.cambio.se_releases - releases - http://repo.cambio.se/content/repositories/releases - - - repo.cambio.se_snapshots - snapshots - http://repo.cambio.se/content/repositories/snapshots - false - + + + + repo.cambio.se_releases + releases + http://repo.cambio.se/content/repositories/releases + + + repo.cambio.se_snapshots + snapshots + http://repo.cambio.se/content/repositories/snapshots + false + \ No newline at end of file diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 449a2032..5d7c19eb 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 55d56451..0038cc58 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index f89970b8..eeb8e285 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 1bf1ed7d..949d485c 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 xml-serializer jar From cf84a1d832d6588816966812c913b0bd0aa965f4 Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Tue, 18 Mar 2014 12:27:30 +0000 Subject: [PATCH 020/213] (CDS)prepare for next development iteration git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk@495671 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 8 ++++---- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 20 insertions(+), 20 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 2c226f83..ebb5db5e 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 49442bfd..18973051 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 95f3342f..408922bd 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index e6c39648..d27dd44e 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 1a7834cc..9c5147b7 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index df8f0a5b..c066249d 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 08e4e2e6..4fa2664a 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index ddf79e09..91134c3e 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 1991be8d..f1bcb5d5 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 42a805f0..2dadf7ec 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 736ce371..6a5888e2 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index a8011e30..ab38e46a 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 5d799e32..0e85d0f1 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java pom - 1.0.6 + 1.0.7-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -12,9 +12,9 @@ UTF-8 - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.6 - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.6 - https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.6 + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ + https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 5d7c19eb..a3742151 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 0038cc58..ca83e765 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index eeb8e285..f898c99a 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 949d485c..1697e6f0 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT xml-serializer jar From 4f5d1e0f7f30665718060d4f72011ebefd4fb2d9 Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Tue, 18 Mar 2014 12:38:25 +0000 Subject: [PATCH 021/213] (CDS)rollback the release of ref_impl_java-1.0.6 git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk@495692 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 28 ++++++++++++++-------------- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 30 insertions(+), 30 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index ebb5db5e..355d6c9f 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.6-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 18973051..e80cc64c 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.6-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 408922bd..68224a55 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.6-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index d27dd44e..d70f6d53 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.6-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 9c5147b7..872c721e 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.6-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index c066249d..3430a600 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.6-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 4fa2664a..9a7bc346 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.6-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 91134c3e..2dbe7ca2 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.6-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index f1bcb5d5..0e2167df 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.6-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 2dadf7ec..3e9c97ca 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.6-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 6a5888e2..0635f0a7 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.6-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index ab38e46a..8b51ed1d 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.6-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 0e85d0f1..e0181193 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java pom - 1.0.7-SNAPSHOT + 1.0.6-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -97,18 +97,18 @@ dadl-binding rm-skeleton archetype-validator - - - - repo.cambio.se_releases - releases - http://repo.cambio.se/content/repositories/releases - - - repo.cambio.se_snapshots - snapshots - http://repo.cambio.se/content/repositories/snapshots - false - + + + + repo.cambio.se_releases + releases + http://repo.cambio.se/content/repositories/releases + + + repo.cambio.se_snapshots + snapshots + http://repo.cambio.se/content/repositories/snapshots + false + \ No newline at end of file diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index a3742151..449a2032 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.6-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index ca83e765..55d56451 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.6-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index f898c99a..f89970b8 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.6-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 1697e6f0..1bf1ed7d 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.6-SNAPSHOT xml-serializer jar From b83a3bd55912c78a05b717b1859ca89ca2a95cbc Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Tue, 18 Mar 2014 12:49:20 +0000 Subject: [PATCH 022/213] (CDS)prepare release ref_impl_java-1.0.6 git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk@495706 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 34 +++++++++++++++++----------------- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 33 insertions(+), 33 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 355d6c9f..2c226f83 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index e80cc64c..49442bfd 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 68224a55..95f3342f 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index d70f6d53..e6c39648 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 872c721e..1a7834cc 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 3430a600..df8f0a5b 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 9a7bc346..08e4e2e6 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 2dbe7ca2..ddf79e09 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 0e2167df..1991be8d 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 3e9c97ca..42a805f0 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 0635f0a7..736ce371 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 8b51ed1d..a8011e30 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index e0181193..5d799e32 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java pom - 1.0.6-SNAPSHOT + 1.0.6 The openEHR Reference Java Implementation The openEHR Foundation @@ -12,9 +12,9 @@ UTF-8 - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ - https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.6 + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.6 + https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.6 @@ -97,18 +97,18 @@ dadl-binding rm-skeleton archetype-validator - - - - repo.cambio.se_releases - releases - http://repo.cambio.se/content/repositories/releases - - - repo.cambio.se_snapshots - snapshots - http://repo.cambio.se/content/repositories/snapshots - false - + + + + repo.cambio.se_releases + releases + http://repo.cambio.se/content/repositories/releases + + + repo.cambio.se_snapshots + snapshots + http://repo.cambio.se/content/repositories/snapshots + false + \ No newline at end of file diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 449a2032..5d7c19eb 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 55d56451..0038cc58 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index f89970b8..eeb8e285 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 1bf1ed7d..949d485c 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.6-SNAPSHOT + 1.0.6 xml-serializer jar From e3e7dd22405ee9726da3db264891bbc11e89052c Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Tue, 18 Mar 2014 12:49:26 +0000 Subject: [PATCH 023/213] (CDS)prepare for next development iteration git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk@495708 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 8 ++++---- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 20 insertions(+), 20 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 2c226f83..ebb5db5e 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 49442bfd..18973051 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 95f3342f..408922bd 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index e6c39648..d27dd44e 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 1a7834cc..9c5147b7 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index df8f0a5b..c066249d 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 08e4e2e6..4fa2664a 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index ddf79e09..91134c3e 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 1991be8d..f1bcb5d5 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 42a805f0..2dadf7ec 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 736ce371..6a5888e2 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index a8011e30..ab38e46a 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 5d799e32..0e85d0f1 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java pom - 1.0.6 + 1.0.7-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -12,9 +12,9 @@ UTF-8 - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.6 - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.6 - https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.6 + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ + https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 5d7c19eb..a3742151 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 0038cc58..ca83e765 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index eeb8e285..f898c99a 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 949d485c..1697e6f0 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.6 + 1.0.7-SNAPSHOT xml-serializer jar From dcc75b0e397461c904b6e55566a54f5674d81806 Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Tue, 18 Mar 2014 13:06:11 +0000 Subject: [PATCH 024/213] (CDS)prepare release ref_impl_java-1.0.7 git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk@495738 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 8 ++++---- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 20 insertions(+), 20 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index ebb5db5e..d161334c 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.7 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 18973051..83b8b29b 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.7 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 408922bd..4c3ffa1b 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.7 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index d27dd44e..0f723384 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.7 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 9c5147b7..6cac2ced 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.7 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index c066249d..59c16b4f 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.7 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 4fa2664a..9e4b597e 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.7 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 91134c3e..9adf0d8c 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.7 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index f1bcb5d5..98885e34 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.7 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 2dadf7ec..809b1a4b 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.7 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 6a5888e2..0549f4b4 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.7 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index ab38e46a..e44682a9 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.7 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 0e85d0f1..a6c63627 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java pom - 1.0.7-SNAPSHOT + 1.0.7 The openEHR Reference Java Implementation The openEHR Foundation @@ -12,9 +12,9 @@ UTF-8 - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ - https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.7 + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.7 + https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.7 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index a3742151..a67ce0fd 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.7 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index ca83e765..c565a826 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.7 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index f898c99a..15fdf941 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.7 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 1697e6f0..d8182788 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.7-SNAPSHOT + 1.0.7 xml-serializer jar From 26c1d2e0b4324654bcd7b78082ff52ece7ae09e6 Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Tue, 18 Mar 2014 13:06:18 +0000 Subject: [PATCH 025/213] (CDS)prepare for next development iteration git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk@495740 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 8 ++++---- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 20 insertions(+), 20 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index d161334c..63a4d4f3 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7 + 1.0.8-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 83b8b29b..0255be7e 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.7 + 1.0.8-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 4c3ffa1b..5c2c3532 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7 + 1.0.8-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 0f723384..8a2b6cc7 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7 + 1.0.8-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 6cac2ced..524e1b25 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7 + 1.0.8-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 59c16b4f..b5c1ea28 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7 + 1.0.8-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 9e4b597e..97f491a8 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7 + 1.0.8-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 9adf0d8c..a292f32d 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7 + 1.0.8-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 98885e34..eb755ec2 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7 + 1.0.8-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 809b1a4b..bbe66a6f 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7 + 1.0.8-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 0549f4b4..21c1d509 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7 + 1.0.8-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index e44682a9..3807662a 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7 + 1.0.8-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index a6c63627..14630995 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java pom - 1.0.7 + 1.0.8-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -12,9 +12,9 @@ UTF-8 - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.7 - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.7 - https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/tags/ref_impl_java-1.0.7 + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ + https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index a67ce0fd..b8d8eabf 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7 + 1.0.8-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index c565a826..18e39f42 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7 + 1.0.8-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 15fdf941..9ff8eefb 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.7 + 1.0.8-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index d8182788..08115648 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.7 + 1.0.8-SNAPSHOT xml-serializer jar From 0e4e08264f970e2b72c52af28cd84378b6420921 Mon Sep 17 00:00:00 2001 From: Bert Verhees Date: Fri, 21 Mar 2014 14:23:16 +0100 Subject: [PATCH 026/213] NodeID is added to path ArchetypeInternalRef Make sure NodeID is added to path if appropriate, see unit-test ArchetypeInternalRefTest.java->testParseCheckIfNodeIsIsTakenIntoAccount for example --- .../openehr/parser/ArchetypeInternalRefTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) 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..fb45f31b 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,6 +6,18 @@ import org.openehr.rm.support.basic.Interval; public class ArchetypeInternalRefTest extends ParserTestBase { + 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( From fc8d22156a4746efbf1aa6fe2eb2274a06625c3a Mon Sep 17 00:00:00 2001 From: Bert Verhees Date: Fri, 21 Mar 2014 14:28:48 +0100 Subject: [PATCH 027/213] NodeID is added to path ArchetypeInternalRef Make sure NodeID is added to path if appropriate, see unit-test ArchetypeInternalRefTest.java->testParseCheckIfNodeIsIsTakenIntoAccount for example --- adl-parser/src/main/javacc/adl.jj | 36 ++++++++++++++++++------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/adl-parser/src/main/javacc/adl.jj b/adl-parser/src/main/javacc/adl.jj index c82bde0e..a17aac01 100755 --- a/adl-parser/src/main/javacc/adl.jj +++ b/adl-parser/src/main/javacc/adl.jj @@ -2316,23 +2316,29 @@ ConstraintRef constraint_ref_obj(String path, CAttribute parent) : } } -ArchetypeInternalRef archetype_internal_ref(String path, CAttribute -parent) : +ArchetypeInternalRef archetype_internal_ref(String path, CAttribute parent) : { - String type; - Interval occurrences = new Interval(1, 1); - String target; - String nodeID = null; + String type; + Interval occurrences = new Interval(1, 1); + String target; + String nodeID = null; } { - type = type_identifier() - [ nodeID = constraint_ref() ] - [ occurrences = c_occurrences() ] - target = absolute_path() - { - return new ArchetypeInternalRef(path, type, occurrences, nodeID, 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); + } } ArchetypeSlot archetype_slot(String path, CAttribute parent) : @@ -3405,4 +3411,4 @@ String path_segment() : * the specific language governing rights and limitations under the License. * * ***** END LICENSE BLOCK ***** - */ \ No newline at end of file + */ From e196c7304ef56c87e571b45ed3104cd7bbd8889b Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Mon, 24 Mar 2014 14:04:14 +0000 Subject: [PATCH 028/213] (CDS) CDS-254 Renaming foldre to match artifact. git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk@497920 24d5da94-7af6-7447-9e6c-d9f96020beb6 From 2f4106f03977873fced2fbdd39e03b0831a8a936 Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Mon, 24 Mar 2014 14:10:42 +0000 Subject: [PATCH 029/213] (CDS) CDS-254 Updated SCM paths to match renamed folder. git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk@497921 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 14630995..1cdd6a93 100644 --- a/pom.xml +++ b/pom.xml @@ -12,9 +12,9 @@ UTF-8 - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ - https://subversion.cambio.se/PC/Standard/CDS/openehr/java-libs/trunk/ + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk/ + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk/ + https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk/ From 0e65e1193ea2e2becae40d8302fcca45e0e0cfb8 Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Wed, 26 Mar 2014 09:52:01 +0000 Subject: [PATCH 030/213] (CDS) Added changelog.txt with commit history and released versions. git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk@498974 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- changelog.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 changelog.txt diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 00000000..02b2087b --- /dev/null +++ b/changelog.txt @@ -0,0 +1,17 @@ +(CDS) CDS-254 Updated SCM paths to match renamed folder. +(CDS) CDS-254 Renaming foldre to match artifact. + +1.0.7 + +1.0.6 + +(CDS) CDS-247 Updated modules to use java 1.5 as compiler target, and updated all dependencies to the new snapshots. +(CDS) CDS-177 Added distribution management. +(CDS) removing dadl binding + +1.0.5 + +(CDS) CDS-177 Fixed scm from git to svn. +(CDS) CDS-130 Added release and cobertura plugin. +(CDS) CDS-130 Added target folders to ignore list. +(CDS) CDS-130 Added all files from github without modifications. From 9f9e5a75cb39063aece499bfa3ce41ad6854e649 Mon Sep 17 00:00:00 2001 From: "JLuin.Valtech" Date: Thu, 24 Apr 2014 12:52:01 +0000 Subject: [PATCH 031/213] (CDS) SWE-4352 Correctly parse DvQuantity values with no unit It was possible to serialise DvQuantity values into a format that caused InvalidArgumentException when parsed. git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk@510981 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- .../rm/datatypes/quantity/DvQuantity.java | 50 ++++++++++--------- .../rm/datatypes/quantity/DvQuantityTest.java | 27 ++++++---- 2 files changed, 43 insertions(+), 34 deletions(-) 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..4283f552 100644 --- 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 @@ -67,15 +67,15 @@ public DvQuantity(@Attribute (name = "otherReferenceRanges") List= 0) { + num = value.substring(0, i); + units = value.substring(i + 1); + } int precision = 0; i = num.indexOf(DECIMAL_SEPARATOR); if(i >= 0) { @@ -190,11 +192,11 @@ public DvQuantity parse(String value) { double magnitude = Double.parseDouble(num); return new DvQuantity(units, magnitude, precision); } catch(NumberFormatException nfe) { - throw new IllegalArgumentException("failed to parse quantity[" + 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,8 +209,8 @@ 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, + getNormalStatus(), getAccuracy(), isAccuracyPercent(), + getMagnitudeStatus(), getUnits(), magnitude + qt.magnitude, precision, measurementService); } @@ -224,8 +226,8 @@ 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, + getNormalStatus(), getAccuracy(), isAccuracyPercent(), + getMagnitudeStatus(), getUnits(), magnitude - qt.magnitude, precision, measurementService); } @@ -247,8 +249,8 @@ public Class getDiffType() { * @return negated version */ public DvQuantity negate() { - return new DvQuantity(getOtherReferenceRanges(), getNormalRange(), - getNormalStatus(), getAccuracy(), isAccuracyPercent(), + return new DvQuantity(getOtherReferenceRanges(), getNormalRange(), + getNormalStatus(), getAccuracy(), isAccuracyPercent(), getMagnitudeStatus(), getUnits(), -magnitude, precision, measurementService); } @@ -347,7 +349,7 @@ public void setMagnitude(double magnitude) { public void setPrecision(int precision) { this.precision = precision; - } + } // POJO end /* fields */ @@ -355,9 +357,9 @@ public void setPrecision(int precision) { private int precision; // add final private final String units; private MeasurementService measurementService; // add final - + public static final char DECIMAL_SEPARATOR = '.'; - + @Override public String getReferenceModelName() { return ReferenceModelName.DV_QUANTITY.getName(); @@ -397,4 +399,4 @@ public String serialise() { * License. * * ***** END LICENSE BLOCK ***** - */ \ No newline at end of file + */ 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..2eb6f181 100644 --- 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,43 @@ 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 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(); } /* @@ -163,4 +170,4 @@ public void testCreateWithUnlimitedPrecision() { * License. * * ***** END LICENSE BLOCK ***** - */ \ No newline at end of file + */ From d5b3e159b4889dce2349ce24dae6b8a2ecbf76f9 Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Thu, 24 Apr 2014 14:51:10 +0000 Subject: [PATCH 032/213] (CDS) Updated changelog.txt git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk@511028 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- changelog.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/changelog.txt b/changelog.txt index 02b2087b..0c314597 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,6 @@ +1.0.8 + +(CDS) SWE-4332 Correctly parse DvQuantity values with no unit. It was possible to serialise DvQuantity values into a format that caused InvalidArgumentException when parsed. (CDS) CDS-254 Updated SCM paths to match renamed folder. (CDS) CDS-254 Renaming foldre to match artifact. From 09ffa199882a0790bf96fee48493a5a6b82a6b51 Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Thu, 24 Apr 2014 14:59:51 +0000 Subject: [PATCH 033/213] (CDS)prepare release ref_impl_java-1.0.8 git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk@511033 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 8 ++++---- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 20 insertions(+), 20 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 63a4d4f3..9c116777 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 0255be7e..377cf3ea 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 5c2c3532..2257bcfd 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 8a2b6cc7..36d3b885 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 524e1b25..0c970374 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index b5c1ea28..407ca70d 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 97f491a8..7df7764b 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index a292f32d..c58e5a50 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index eb755ec2..3f0d0e04 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index bbe66a6f..528b43b7 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 21c1d509..98f810dc 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 3807662a..513dc5e1 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 1cdd6a93..7522d074 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java pom - 1.0.8-SNAPSHOT + 1.0.8 The openEHR Reference Java Implementation The openEHR Foundation @@ -12,9 +12,9 @@ UTF-8 - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk/ - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk/ - https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk/ + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/tags/ref_impl_java-1.0.8 + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/tags/ref_impl_java-1.0.8 + https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/tags/ref_impl_java-1.0.8 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index b8d8eabf..24b31ce9 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 18e39f42..026d8bb6 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 9ff8eefb..38d741a6 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 08115648..df0ba843 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 xml-serializer jar From c8a2468fe9fd108cb843dff4cd50df456eeeb39e Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Thu, 24 Apr 2014 15:00:09 +0000 Subject: [PATCH 034/213] (CDS)prepare for next development iteration git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk@511035 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 8 ++++---- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 20 insertions(+), 20 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 9c116777..400276c1 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 377cf3ea..09771831 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 2257bcfd..0567c24f 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 36d3b885..380191f8 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 0c970374..884e929c 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 407ca70d..a0830ad1 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 7df7764b..7b54547b 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index c58e5a50..86c7dee2 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 3f0d0e04..7aa1e65b 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 528b43b7..c231bc5f 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 98f810dc..0ddeb412 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 513dc5e1..07352dcc 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 7522d074..ba074149 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java pom - 1.0.8 + 1.0.9-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -12,9 +12,9 @@ UTF-8 - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/tags/ref_impl_java-1.0.8 - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/tags/ref_impl_java-1.0.8 - https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/tags/ref_impl_java-1.0.8 + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk/ + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk/ + https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk/ diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 24b31ce9..a0b8d424 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 026d8bb6..6ef5a56a 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 38d741a6..8127404e 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index df0ba843..3ed05da4 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT xml-serializer jar From 037ce40329cde71d58bf4c981ad475ec159c6b4c Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Thu, 24 Apr 2014 15:04:09 +0000 Subject: [PATCH 035/213] (CDS)rollback the release of ref_impl_java-1.0.8 git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk@511037 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 2 +- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 400276c1..63a4d4f3 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9-SNAPSHOT + 1.0.8-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 09771831..0255be7e 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.9-SNAPSHOT + 1.0.8-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 0567c24f..5c2c3532 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9-SNAPSHOT + 1.0.8-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 380191f8..8a2b6cc7 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9-SNAPSHOT + 1.0.8-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 884e929c..524e1b25 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9-SNAPSHOT + 1.0.8-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index a0830ad1..b5c1ea28 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9-SNAPSHOT + 1.0.8-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 7b54547b..97f491a8 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9-SNAPSHOT + 1.0.8-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 86c7dee2..a292f32d 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9-SNAPSHOT + 1.0.8-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 7aa1e65b..eb755ec2 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9-SNAPSHOT + 1.0.8-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index c231bc5f..bbe66a6f 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9-SNAPSHOT + 1.0.8-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 0ddeb412..21c1d509 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9-SNAPSHOT + 1.0.8-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 07352dcc..3807662a 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9-SNAPSHOT + 1.0.8-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index ba074149..1cdd6a93 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java pom - 1.0.9-SNAPSHOT + 1.0.8-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index a0b8d424..b8d8eabf 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9-SNAPSHOT + 1.0.8-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 6ef5a56a..18e39f42 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9-SNAPSHOT + 1.0.8-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 8127404e..9ff8eefb 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9-SNAPSHOT + 1.0.8-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 3ed05da4..08115648 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.9-SNAPSHOT + 1.0.8-SNAPSHOT xml-serializer jar From fe19f42313dfc1b145963e28b8ec07e1f0d53c7c Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Thu, 24 Apr 2014 15:11:44 +0000 Subject: [PATCH 036/213] (CDS)prepare release ref_impl_java-1.0.8 git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk@511039 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 8 ++++---- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 20 insertions(+), 20 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 63a4d4f3..9c116777 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 0255be7e..377cf3ea 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 5c2c3532..2257bcfd 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 8a2b6cc7..36d3b885 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 524e1b25..0c970374 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index b5c1ea28..407ca70d 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 97f491a8..7df7764b 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index a292f32d..c58e5a50 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index eb755ec2..3f0d0e04 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index bbe66a6f..528b43b7 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 21c1d509..98f810dc 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 3807662a..513dc5e1 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 1cdd6a93..7522d074 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java pom - 1.0.8-SNAPSHOT + 1.0.8 The openEHR Reference Java Implementation The openEHR Foundation @@ -12,9 +12,9 @@ UTF-8 - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk/ - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk/ - https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk/ + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/tags/ref_impl_java-1.0.8 + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/tags/ref_impl_java-1.0.8 + https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/tags/ref_impl_java-1.0.8 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index b8d8eabf..24b31ce9 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 18e39f42..026d8bb6 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 9ff8eefb..38d741a6 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 08115648..df0ba843 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.8-SNAPSHOT + 1.0.8 xml-serializer jar From 74e72e3838a704814fa5825b0e6c16c5d9f60950 Mon Sep 17 00:00:00 2001 From: "john.harelius" Date: Thu, 24 Apr 2014 15:11:50 +0000 Subject: [PATCH 037/213] (CDS)prepare for next development iteration git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk@511041 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 8 ++++---- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 20 insertions(+), 20 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 9c116777..400276c1 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 377cf3ea..09771831 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 2257bcfd..0567c24f 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 36d3b885..380191f8 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 0c970374..884e929c 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 407ca70d..a0830ad1 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 7df7764b..7b54547b 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index c58e5a50..86c7dee2 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 3f0d0e04..7aa1e65b 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 528b43b7..c231bc5f 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 98f810dc..0ddeb412 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 513dc5e1..07352dcc 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 7522d074..ba074149 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java pom - 1.0.8 + 1.0.9-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -12,9 +12,9 @@ UTF-8 - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/tags/ref_impl_java-1.0.8 - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/tags/ref_impl_java-1.0.8 - https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/tags/ref_impl_java-1.0.8 + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk/ + scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk/ + https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk/ diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 24b31ce9..a0b8d424 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 026d8bb6..6ef5a56a 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 38d741a6..8127404e 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index df0ba843..3ed05da4 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.8 + 1.0.9-SNAPSHOT xml-serializer jar From 0d8bd54cf305a08f4f5ad2a5b2e4bfc264961fb9 Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Wed, 7 May 2014 16:05:41 +0200 Subject: [PATCH 038/213] Add xml Serialisation of the translations section, previously flagged as todo, --- .../openehr/am/serialize/XMLSerializer.java | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) 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..85f7f770 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 @@ -7,6 +7,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import org.jdom.Document; @@ -55,6 +56,7 @@ 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.text.CodePhrase; import org.openehr.rm.support.basic.Interval; import org.openehr.rm.support.identification.ArchetypeID; @@ -150,7 +152,7 @@ protected void printHeader(Archetype archetype, Element out) { printDescription(archetype.getDescription(), out); - //TODO printTranslations + printTranslations(archetype.getTranslations(), out); Element archetypeId = new Element("archetype_id", defaultNamespace); out.getChildren().add(archetypeId); @@ -160,7 +162,7 @@ protected void printHeader(Archetype archetype, Element out) { if (archetype.getUid() != null) { printString("uid", archetype.getUid().toString(), out); } - + printString("concept", archetype.getConcept(), out); final ArchetypeID parentID = archetype.getParentArchetypeId(); @@ -172,6 +174,33 @@ protected void printHeader(Archetype archetype, Element out) { } + 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) { From c4e9640abcca99c5cc7aed836475488665fc0d62 Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Wed, 7 May 2014 18:11:51 +0200 Subject: [PATCH 039/213] The XML Serialiser should also print the mandatory value of the DV_CODED_TEXT symbol inside an Ordinal, even if empty --- .../main/java/org/openehr/am/serialize/XMLSerializer.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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 85f7f770..804a688f 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 @@ -645,9 +645,13 @@ protected void printCDvOrdinal(CDvOrdinal cordinal, Element out) { children.getChildren().add(list); printString("value", String.valueOf(ordinal.getValue()), list); Element symbol = new Element("symbol", defaultNamespace); - list.getChildren().add(symbol); + 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); } } From 73412f244fa3a3108b199132b8bcc7aaf074bc9f Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Fri, 9 May 2014 17:41:41 +0200 Subject: [PATCH 040/213] XMLSerialiser should serialise the assumedVvalue of an COrdinal XMLSerialiser should serialise the symbol of an ordinal XMLSerialiser should serialise the precision XMLSerialiser should serialise the CDuration pattern as the pattern, not the value XMLSerialiser should serialise an empty range for a CDuration as lower_unbounded and upper_unbounded =true (insead of not at all) XMLSerialiser needs to correctly serialise a DV_INTERVAL (e.g.) as just that, not as DV_INTERVAL<_DV_QUANTITY> (which previous to this commit happens due to the camelcase conversion algorithm --- .../openehr/am/serialize/XMLSerializer.java | 53 +++++++++++++------ 1 file changed, 36 insertions(+), 17 deletions(-) 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 804a688f..63600276 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 @@ -634,29 +634,39 @@ protected void printCDvOrdinal(CDvOrdinal cordinal, Element out) { 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 Set ordinals = cordinal.getList(); Ordinal ordinal; for (Iterator it = ordinals.iterator(); it.hasNext();) { - ordinal = it.next(); + 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); - - 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); + 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 printCDvQuantity(CDvQuantity cquantity, Element out) { Element children = new Element("children", defaultNamespace); @@ -685,6 +695,11 @@ protected void printCDvQuantity(CDvQuantity cquantity, Element out) { 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); } @@ -918,14 +933,17 @@ protected void printCTime(CTime ctime, Element out) { protected void printCDuration(CDuration cduration, Element out) { - if (cduration.getValue() != null) { - printString("pattern", cduration.getValue().toString(), out); + if (cduration.getPattern() != null) { + printString("pattern", cduration.getPattern().toString(), out); } - - if(cduration.getInterval() != null) { - Element range = new Element("range", defaultNamespace); - out.getChildren().add(range); + 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()) { @@ -1047,7 +1065,8 @@ private String getUpperCaseWithUnderscoreFromCamelCase(String str) { */ for( int i = 0; i < str.length(); i++ ) { char c = str.charAt( i ); - if(! Character.isUpperCase(prevChar) && + if(! Character.isUpperCase(prevChar) && + !(prevChar=='<') && // without this DV_INTERVAL --> DV_INTERVAL<_DV_QUANTITY> !(prevChar=='_') && Character.isLetter(c) && Character.isUpperCase(c)) From 569c3535ab2593b161efce906769b216f4e0958f Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Mon, 12 May 2014 14:09:51 +0200 Subject: [PATCH 041/213] CReal should have Real as corresponding type, not double. --- .../openehr/am/validation/RMInspector.java | 5 ++++- .../constraintmodel/primitive/CReal.java | 20 ++++++++++++++----- .../constraintmodel/primitive/CRealTest.java | 1 + 3 files changed, 20 insertions(+), 6 deletions(-) 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 index 377f71f5..5c41cbb3 100644 --- a/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java @@ -118,7 +118,7 @@ private Map loadTypeMap() throws ClassNotFoundException { Integer.class, String.class, Boolean.class, - Double.class, + Double.class, // Also the corresponding class for the Real assumed type. // common classes PartySelf.class, @@ -196,6 +196,9 @@ private Map loadTypeMap() throws ClassNotFoundException { upperCaseMap = new HashMap(); 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); } 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..64f47c2f 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,12 +14,14 @@ */ 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; -import java.util.*; - /** * Constraint on instances of Double number. Immutable. * @@ -67,8 +69,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,6 +89,7 @@ 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) @@ -127,9 +131,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 +155,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/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); From e66abc4b013f6590b5ba6ab5793a5480ee618cba Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Tue, 13 May 2014 13:09:35 +0200 Subject: [PATCH 042/213] - Set the value of a DvDuration when constructed via getInstance. This is especially important when the period is 0 but we still want to know if it is 0s or 0h, etc. - XmlSerialiser: Add serialisation of assumed values for a CodePhrase and DvQuantity --- .../quantity/datetime/DvDuration.java | 7 ++- .../quantity/datetime/DvDurationTest.java | 7 ++- .../openehr/am/serialize/XMLSerializer.java | 60 ++++++++++++++----- 3 files changed, 56 insertions(+), 18 deletions(-) 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..76574083 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 @@ -22,7 +22,6 @@ import org.joda.time.MutablePeriod; import org.joda.time.Period; import org.joda.time.format.ISOPeriodFormat; -import org.joda.time.format.PeriodFormatter; import org.openehr.rm.Attribute; import org.openehr.rm.FullConstructor; import org.openehr.rm.datatypes.basic.ReferenceModelName; @@ -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/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..b068304a 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,12 +31,14 @@ 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 { } @@ -209,11 +211,14 @@ public void testToString() throws Exception { 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/xml-serializer/src/main/java/org/openehr/am/serialize/XMLSerializer.java b/xml-serializer/src/main/java/org/openehr/am/serialize/XMLSerializer.java index 63600276..e1b91314 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 @@ -57,6 +57,7 @@ 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; @@ -183,10 +184,10 @@ private void printTranslations(Map translations, Ele // 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(); @@ -611,6 +612,14 @@ protected void printCCodePhrase(CCodePhrase ccp, Element out) { 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); @@ -663,7 +672,7 @@ private void printSymbolOfOrdinal(Ordinal ordinal, Element list) { 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); } @@ -675,6 +684,23 @@ protected void printCDvQuantity(CDvQuantity cquantity, Element out) { 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) { @@ -690,22 +716,26 @@ protected void printCDvQuantity(CDvQuantity cquantity, Element out) { 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); - } - if(item.getPrecision() != null) { - Element precision = new Element("precision", defaultNamespace); - lst.getChildren().add(precision); - printInterval(item.getPrecision(), precision); - } - - printString("units", item.getUnits(), 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) { From 2fa7fbc1e46c1b8618bd3113af26e3bd33ed8615 Mon Sep 17 00:00:00 2001 From: "Iago.Corbal" Date: Tue, 27 May 2014 14:02:22 +0000 Subject: [PATCH 043/213] (CDS) CDS-114 Fixing problem related to unknown archetypes needed by templates. Current modification will notify the missing archetype (or template) using exception UnknownArchetypeException/UnknwonTemplateException git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk@524381 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- .../org/openehr/am/template/Flattener.java | 6 +++--- .../template/UnknownArchetypeException.java | 20 ++++++++++++++++++ .../am/template/UnknownTemplateException.java | 21 +++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) create mode 100755 oet-parser/src/main/java/org/openehr/am/template/UnknownArchetypeException.java create mode 100755 oet-parser/src/main/java/org/openehr/am/template/UnknownTemplateException.java 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..7a7421e6 100644 --- a/oet-parser/src/main/java/org/openehr/am/template/Flattener.java +++ b/oet-parser/src/main/java/org/openehr/am/template/Flattener.java @@ -1586,7 +1586,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 +1596,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 +1729,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/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; + } + +} From 88c2ec9aa7a5eaec8c00d78bcb338f3c01442cf6 Mon Sep 17 00:00:00 2001 From: "Iago.Corbal" Date: Tue, 15 Jul 2014 10:38:51 +0000 Subject: [PATCH 044/213] (CDS) Fixed the access to elements in locatable without need to specify attributes e.g. data/event/time git-svn-id: https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk@540357 24d5da94-7af6-7447-9e6c-d9f96020beb6 --- .../rm/common/archetyped/Locatable.java | 172 +++++++++--------- 1 file changed, 89 insertions(+), 83 deletions(-) mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/common/archetyped/Locatable.java 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 old mode 100644 new mode 100755 index 01d0ec13..eb8c4f41 --- 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,32 @@ 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(); if (next.matches(".+\\[.+[^\\]]$")) { - do { + do { next = next + "/" + tokens.nextToken(); - } while (!next.matches(".*]$")); + } 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 +205,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,22 +265,22 @@ 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 @@ -284,7 +290,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 +299,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 +314,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 +333,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. @@ -362,7 +368,7 @@ public Object itemAtPath(String path) { } return genericPathEvaluator(path, this); } - + /* * Retrieves the value of named attribute of given object */ @@ -371,7 +377,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 +388,7 @@ private Object getAttributeValue(Object obj, String attribute) { } return value; } - + /* * Sets the value of named attribute of given object */ @@ -395,14 +401,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 +418,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 +431,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 +461,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 +474,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 +512,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); - } + } } /** @@ -572,7 +578,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 +626,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 +657,7 @@ protected void setFeederAudit(FeederAudit feederAudit) { protected void setLinks(Set links) { this.links = links; - } + } // POJO end /** @@ -659,7 +665,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 +674,7 @@ protected void setLinks(Set links) { private Archetyped archetypeDetails; private FeederAudit feederAudit; private Set links; - + } /* From dd7757010d7ce954b072ea07b1921f58ef228de8 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Wed, 6 Aug 2014 17:29:39 +0200 Subject: [PATCH 045/213] (CDS) fixing scm --- pom.xml | 170 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 84 insertions(+), 86 deletions(-) diff --git a/pom.xml b/pom.xml index ba074149..d3dda312 100644 --- a/pom.xml +++ b/pom.xml @@ -1,45 +1,44 @@ + - 4.0.0 - openehr - ref_impl_java - pom - 1.0.9-SNAPSHOT - The openEHR Reference Java Implementation - - The openEHR Foundation - - - UTF-8 - - - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk/ - scm:svn:https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk/ - https://subversion.cambio.se/PC/Standard/CDS/openehr/ref_impl_java/trunk/ - - - - - maven-compiler-plugin - 2.3.2 - - 1.5 - 1.5 - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.9 - - org.umlgraph.doclet.UmlGraphDoc - - - org.umlgraph - umlgraph - 5.6 - - + 4.0.0 + openehr + ref_impl_java + pom + 1.0.9-SNAPSHOT + The openEHR Reference Java Implementation + + The openEHR Foundation + + + UTF-8 + + + scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git + + + + + maven-compiler-plugin + 2.3.2 + + 1.5 + 1.5 + + + + + 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 @@ -55,49 +54,48 @@ -nodefonttagname "Trebuchet MS" - true - - - - org.apache.maven.plugins - maven-release-plugin - 2.3.2 - - (CDS) - - - - org.codehaus.mojo - cobertura-maven-plugin - 2.5.1 - - - - xml - - - - - - - - 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 - + true + + + + org.apache.maven.plugins + maven-release-plugin + 2.3.2 + + (CDS) + + + + org.codehaus.mojo + cobertura-maven-plugin + 2.5.1 + + + + xml + + + + + + + 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 + repo.cambio.se_releases @@ -110,5 +108,5 @@ http://repo.cambio.se/content/repositories/snapshots false - - \ No newline at end of file + + From cb0c4e7bb9b4cdcad5ae1823abc7161c43e8cfe2 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Thu, 14 Aug 2014 09:48:04 +0200 Subject: [PATCH 046/213] Added measure serv module as a full dependency (javadoc) --- openehr-ap/pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index c231bc5f..ea6b6ff1 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -39,7 +39,6 @@ openehr measure-serv ${project.version} - test commons-lang From 7d7b8ba50e9f908fdc14998f2c17eb8de25125a0 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Thu, 14 Aug 2014 10:51:38 +0200 Subject: [PATCH 047/213] Updated release plugin --- pom.xml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index d3dda312..7ccf4392 100644 --- a/pom.xml +++ b/pom.xml @@ -60,10 +60,7 @@ org.apache.maven.plugins maven-release-plugin - 2.3.2 - - (CDS) - + 2.5 org.codehaus.mojo From 8cc04a45bf49b0b8c51686b029c5368ad398cadc Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Thu, 14 Aug 2014 11:07:09 +0200 Subject: [PATCH 048/213] Updated release plugin --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7ccf4392..1ee6d492 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ org.apache.maven.plugins maven-release-plugin - 2.5 + 2.4.2 org.codehaus.mojo From be6f94a9cc3d5dd7fedb010f28e6a492871702b9 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Thu, 14 Aug 2014 11:15:38 +0200 Subject: [PATCH 049/213] Updated release plugin --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1ee6d492..522e4ff5 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ org.apache.maven.plugins maven-release-plugin - 2.4.2 + 2.3.2 org.codehaus.mojo From 3a34648cbb2d8b893215985598301009f4952990 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Thu, 14 Aug 2014 11:34:28 +0200 Subject: [PATCH 050/213] [maven-release-plugin] prepare release ref_impl_java-1.0.9 --- adl-parser/pom.xml | 260 ++++++++++++++++++------------------ adl-serializer/pom.xml | 156 +++++++++++----------- archetype-validator/pom.xml | 174 ++++++++++++------------ dadl-binding/pom.xml | 168 +++++++++++------------ dadl-parser/pom.xml | 160 +++++++++++----------- measure-serv/pom.xml | 80 +++++------ mini-termserv/pom.xml | 90 ++++++------- oet-parser/pom.xml | 238 ++++++++++++++++----------------- openehr-aom/pom.xml | 92 ++++++------- openehr-ap/pom.xml | 110 +++++++-------- openehr-rm-core/pom.xml | 90 ++++++------- openehr-rm-domain/pom.xml | 92 ++++++------- pom.xml | 219 +++++++++++++++--------------- rm-builder/pom.xml | 120 ++++++++--------- rm-skeleton/pom.xml | 188 +++++++++++++------------- xml-binding/pom.xml | 256 +++++++++++++++++------------------ xml-serializer/pom.xml | 130 +++++++++--------- 17 files changed, 1312 insertions(+), 1311 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 400276c1..b6b20fa7 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -1,130 +1,130 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.9-SNAPSHOT - - adl-parser - jar - java ADL Parser - http://www.openehr.org/projects/java.html - - openEHR - http://www.openehr.org/ - - 2004 - - java ADL Parser - - - - - org.codehaus.mojo - javacc-maven-plugin - 2.6 - - se.acode.openehr.parser - - - - - javacc - - - - - - - maven-assembly-plugin - - - jar-with-dependencies - - - - se.acode.openehr.parser.ADLParser - - - - - - package - - assembly - - - - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.codehaus.mojo - javacc-maven-plugin - [2.1,) - - javacc - - - - - - - - - - - - - - - - - openehr - openehr-rm-core - ${project.version} - - - openehr - openehr-rm-domain - ${project.version} - - - openehr - openehr-aom - ${project.version} - - - openehr - openehr-ap - ${project.version} - - - openehr - measure-serv - ${project.version} - - - openehr - mini-termserv - ${project.version} - - - junit - junit - 3.8.1 - test - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.9 + + adl-parser + jar + java ADL Parser + http://www.openehr.org/projects/java.html + + openEHR + http://www.openehr.org/ + + 2004 + + java ADL Parser + + + + + org.codehaus.mojo + javacc-maven-plugin + 2.6 + + se.acode.openehr.parser + + + + + javacc + + + + + + + maven-assembly-plugin + + + jar-with-dependencies + + + + se.acode.openehr.parser.ADLParser + + + + + + package + + assembly + + + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.codehaus.mojo + javacc-maven-plugin + [2.1,) + + javacc + + + + + + + + + + + + + + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + openehr-aom + ${project.version} + + + openehr + openehr-ap + ${project.version} + + + openehr + measure-serv + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + junit + junit + 3.8.1 + test + + + diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 09771831..99565bef 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -1,78 +1,78 @@ - - 4.0.0 - - openehr - ref_impl_java - 1.0.9-SNAPSHOT - - adl-serializer - jar - ADL Serializer - http://www.openehr.org/projects/java.html - - openEHR - http://www.openehr.org/ - - 2004 - - java ADL Serializer for Archetype Object Model - - - - - src/test/adl - - - - - - - openehr - openehr-rm-core - ${project.version} - - - openehr - openehr-rm-domain - ${project.version} - - - openehr - openehr-aom - ${project.version} - - - openehr - openehr-ap - ${project.version} - - - openehr - mini-termserv - ${project.version} - - - openehr - adl-parser - ${project.version} - test - - - commons-lang - commons-lang - 2.6 - - - commons-io - commons-io - 1.2 - test - - - junit - junit - 3.8.1 - test - - - + + 4.0.0 + + openehr + ref_impl_java + 1.0.9 + + adl-serializer + jar + ADL Serializer + http://www.openehr.org/projects/java.html + + openEHR + http://www.openehr.org/ + + 2004 + + java ADL Serializer for Archetype Object Model + + + + + src/test/adl + + + + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + openehr-aom + ${project.version} + + + openehr + openehr-ap + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + openehr + adl-parser + ${project.version} + test + + + commons-lang + commons-lang + 2.6 + + + commons-io + commons-io + 1.2 + test + + + junit + junit + 3.8.1 + test + + + diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 0567c24f..8e9c0b84 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -1,87 +1,87 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.9-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.5 - 1.5 - - - - - - - - commons-lang - commons-lang - 2.4 - - - log4j - log4j - 1.2.13 - - - openehr - openehr-rm-core - ${project.version} - - - openehr - openehr-rm-domain - ${project.version} - - - openehr - openehr-aom - ${project.version} - - - openehr - openehr-ap - ${project.version} - - - openehr - mini-termserv - ${project.version} - - - openehr - measure-serv - ${project.version} - - - openehr - adl-parser - ${project.version} - test - - - junit - junit - 3.8.1 - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.9 + + 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.5 + 1.5 + + + + + + + + commons-lang + commons-lang + 2.4 + + + log4j + log4j + 1.2.13 + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + openehr-aom + ${project.version} + + + openehr + openehr-ap + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + openehr + measure-serv + ${project.version} + + + openehr + adl-parser + ${project.version} + test + + + junit + junit + 3.8.1 + + + diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 380191f8..14777c5e 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -1,84 +1,84 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.9-SNAPSHOT - - dadl-binding - jar - java dADL Binding - http://www.openehr.org/svn/ref_impl_java/TRUNK/project_page.htm - - openEHR - http://www.openehr.org/ - - 2008 - java openEHR RM and dADL Binding Component - - - - openehr - openehr-rm-core - ${project.version} - - - - - openehr - openehr-aom - ${project.version} - - - - - openehr - adl-parser - ${project.version} - - - - - openehr - openehr-rm-domain - ${project.version} - - - openehr - mini-termserv - ${project.version} - - - openehr - measure-serv - ${project.version} - - - openehr - rm-builder - ${project.version} - - - openehr - dadl-parser - ${project.version} - - - junit - junit - 3.8.1 - test - - - commons-jxpath - commons-jxpath - 1.3 - - - commons-io - commons-io - 2.3 - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.9 + + dadl-binding + jar + java dADL Binding + http://www.openehr.org/svn/ref_impl_java/TRUNK/project_page.htm + + openEHR + http://www.openehr.org/ + + 2008 + java openEHR RM and dADL Binding Component + + + + openehr + openehr-rm-core + ${project.version} + + + + + openehr + openehr-aom + ${project.version} + + + + + openehr + adl-parser + ${project.version} + + + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + openehr + measure-serv + ${project.version} + + + openehr + rm-builder + ${project.version} + + + openehr + dadl-parser + ${project.version} + + + junit + junit + 3.8.1 + test + + + commons-jxpath + commons-jxpath + 1.3 + + + commons-io + commons-io + 2.3 + + + diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 884e929c..36363664 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -1,80 +1,80 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.9-SNAPSHOT - - dadl-parser - jar - java dADL Parser - http://svn.openehr.org/ref_impl_java/TRUNK/project_page.htm - - openEHR - http://www.openehr.org/ - - 2007 - - java dADL Parser - - - - - org.codehaus.mojo - javacc-maven-plugin - 2.6 - - - - javacc - - - - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.codehaus.mojo - javacc-maven-plugin - [2.1,) - - javacc - - - - - - - - - - - - - - - - - openehr - openehr-rm-core - ${project.version} - - - junit - junit - 3.8.1 - test - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.9 + + dadl-parser + jar + java dADL Parser + http://svn.openehr.org/ref_impl_java/TRUNK/project_page.htm + + openEHR + http://www.openehr.org/ + + 2007 + + java dADL Parser + + + + + org.codehaus.mojo + javacc-maven-plugin + 2.6 + + + + javacc + + + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.codehaus.mojo + javacc-maven-plugin + [2.1,) + + javacc + + + + + + + + + + + + + + + + + openehr + openehr-rm-core + ${project.version} + + + junit + junit + 3.8.1 + test + + + diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index a0830ad1..7aca4ba0 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -1,40 +1,40 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.9-SNAPSHOT - - measure-serv - jar - openEHR Measurement Service Implementation - http://www.openehr.org/projects/java.html - - - openEHR - http://www.openehr.org/ - - 2007 - - Java implementation of the openEHR Measurement Service - - - - commons-lang - commons-lang - 2.6 - - - junit - junit - 3.8.1 - test - - - javax.measure - jsr-275 - 0.9.4 - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.9 + + measure-serv + jar + openEHR Measurement Service Implementation + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2007 + + Java implementation of the openEHR Measurement Service + + + + commons-lang + commons-lang + 2.6 + + + junit + junit + 3.8.1 + test + + + javax.measure + jsr-275 + 0.9.4 + + + diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 7b54547b..216675d1 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -1,45 +1,45 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.9-SNAPSHOT - - mini-termserv - jar - openEHR Minimum Terminology Service - http://www.openehr.org/projects/java.html - - - openEHR - http://www.openehr.org/ - - 2007 - - The minimum terminology service required by the Java kernel - - - - openehr - openehr-rm-core - ${project.version} - - - jdom - jdom - 1.0 - - - log4j - log4j - 1.2.8 - - - junit - junit - 3.8.1 - test - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.9 + + mini-termserv + jar + openEHR Minimum Terminology Service + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2007 + + The minimum terminology service required by the Java kernel + + + + openehr + openehr-rm-core + ${project.version} + + + jdom + jdom + 1.0 + + + log4j + log4j + 1.2.8 + + + junit + junit + 3.8.1 + test + + + diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 86c7dee2..dc054671 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -1,119 +1,119 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.9-SNAPSHOT - - oet-parser - jar - openEHR OET Template Parser and Flattener - - - rong.chen - Rong Chen - rong.acode@gmail.com - - - - - openEHR - http://www.openehr.org/ - - 2007 - Java implementation of openEHR OET Template Parser and Flattener - - UTF-8 - - - - - 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} - - - openehr - openehr-aom - ${project.version} - - - openehr - adl-parser - ${project.version} - - - org.apache.xmlbeans - xmlbeans - 2.3.0 - - - javax.xml.bind - jsr173_api - 1.0 - - - openehr - measure-serv - ${project.version} - - - openehr - mini-termserv - ${project.version} - - - junit - junit - 3.8.1 - test - - - com.thoughtworks.xstream - xstream - 1.3.1 - test - - - openehr - adl-serializer - ${project.version} - - - log4j - log4j - 1.2.13 - - - commons-io - commons-io - 1.4 - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.9 + + oet-parser + jar + openEHR OET Template Parser and Flattener + + + rong.chen + Rong Chen + rong.acode@gmail.com + + + + + openEHR + http://www.openehr.org/ + + 2007 + Java implementation of openEHR OET Template Parser and Flattener + + UTF-8 + + + + + 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} + + + openehr + openehr-aom + ${project.version} + + + openehr + adl-parser + ${project.version} + + + org.apache.xmlbeans + xmlbeans + 2.3.0 + + + javax.xml.bind + jsr173_api + 1.0 + + + openehr + measure-serv + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + junit + junit + 3.8.1 + test + + + com.thoughtworks.xstream + xstream + 1.3.1 + test + + + openehr + adl-serializer + ${project.version} + + + log4j + log4j + 1.2.13 + + + commons-io + commons-io + 1.4 + + + diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 7aa1e65b..f9205457 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -1,46 +1,46 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.9-SNAPSHOT - - openehr-aom - jar - openEHR Archetype Object Model - http://www.openehr.org/projects/java.html - - - openEHR - http://www.openehr.org/ - - 2004 - - Java implementation of the openEHR Archetype Object Model - - - - - openehr - openehr-rm-core - ${project.version} - - - openehr - openehr-rm-domain - ${project.version} - - - commons-lang - commons-lang - 2.6 - - - junit - junit - 3.8.1 - test - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.9 + + openehr-aom + jar + openEHR Archetype Object Model + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2004 + + Java implementation of the openEHR Archetype Object Model + + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + commons-lang + commons-lang + 2.6 + + + junit + junit + 3.8.1 + test + + + diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index ea6b6ff1..45e5516b 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -1,55 +1,55 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.9-SNAPSHOT - - openehr-ap - jar - openEHR Archetype Profile - http://www.openehr.org/projects/java.html - - - openEHR - http://www.openehr.org/ - - 2004 - - Java implementation of the openEHR Archetype Profile - - - - openehr - openehr-rm-core - ${project.version} - - - openehr - openehr-rm-domain - ${project.version} - - - openehr - openehr-aom - ${project.version} - - - openehr - measure-serv - ${project.version} - - - commons-lang - commons-lang - 2.6 - - - junit - junit - 3.8.1 - test - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.9 + + openehr-ap + jar + openEHR Archetype Profile + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2004 + + Java implementation of the openEHR Archetype Profile + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + openehr-aom + ${project.version} + + + openehr + measure-serv + ${project.version} + + + commons-lang + commons-lang + 2.6 + + + junit + junit + 3.8.1 + test + + + diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 0ddeb412..7a121ed2 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -1,45 +1,45 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.9-SNAPSHOT - - openehr-rm-core - jar - openEHR Reference Model Core - http://www.openehr.org/projects/java.html - - - openEHR - http://www.openehr.org/ - - 2004 - - Java implementation of the openEHR Reference Model Core - - - - commons-lang - commons-lang - 2.6 - - - joda-time - joda-time - 2.2 - - - junit - junit - 3.8.1 - test - - - openehr - measure-serv - ${project.version} - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.9 + + openehr-rm-core + jar + openEHR Reference Model Core + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2004 + + Java implementation of the openEHR Reference Model Core + + + + commons-lang + commons-lang + 2.6 + + + joda-time + joda-time + 2.2 + + + junit + junit + 3.8.1 + test + + + openehr + measure-serv + ${project.version} + + + diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 07352dcc..5b6e797b 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -1,46 +1,46 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.9-SNAPSHOT - - openehr-rm-domain - jar - openEHR Reference Model Domain - http://www.openehr.org/projects/java.html - - - openEHR - http://www.openehr.org/ - - 2004 - - Java implementation of the openEHR Reference Model Domain - - - - openehr - openehr-rm-core - ${project.version} - - - openehr - mini-termserv - ${project.version} - test - - - commons-lang - commons-lang - 2.6 - - - junit - junit - 3.8.1 - test - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.9 + + openehr-rm-domain + jar + openEHR Reference Model Domain + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2004 + + Java implementation of the openEHR Reference Model Domain + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + mini-termserv + ${project.version} + test + + + commons-lang + commons-lang + 2.6 + + + junit + junit + 3.8.1 + test + + + diff --git a/pom.xml b/pom.xml index 522e4ff5..fdbc7377 100644 --- a/pom.xml +++ b/pom.xml @@ -1,109 +1,110 @@ - - - 4.0.0 - openehr - ref_impl_java - pom - 1.0.9-SNAPSHOT - The openEHR Reference Java Implementation - - The openEHR Foundation - - - UTF-8 - - - scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - - - - - maven-compiler-plugin - 2.3.2 - - 1.5 - 1.5 - - - - - 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 - - - - org.apache.maven.plugins - maven-release-plugin - 2.3.2 - - - org.codehaus.mojo - cobertura-maven-plugin - 2.5.1 - - - - xml - - - - - - - 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 - - - - repo.cambio.se_releases - releases - http://repo.cambio.se/content/repositories/releases - - - repo.cambio.se_snapshots - snapshots - http://repo.cambio.se/content/repositories/snapshots - false - - - + + + 4.0.0 + openehr + ref_impl_java + pom + 1.0.9 + The openEHR Reference Java Implementation + + The openEHR Foundation + + + UTF-8 + + + scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git + ref_impl_java-1.0.9 + + + + + maven-compiler-plugin + 2.3.2 + + 1.5 + 1.5 + + + + + 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 + + + + org.apache.maven.plugins + maven-release-plugin + 2.3.2 + + + org.codehaus.mojo + cobertura-maven-plugin + 2.5.1 + + + + xml + + + + + + + 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 + + + + repo.cambio.se_releases + releases + http://repo.cambio.se/content/repositories/releases + + + repo.cambio.se_snapshots + snapshots + http://repo.cambio.se/content/repositories/snapshots + false + + + diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index a0b8d424..a710941e 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -1,60 +1,60 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.9-SNAPSHOT - - rm-builder - jar - openEHR Reference Model Object Builder - http://www.openehr.org/projects/java.html - - - openEHR - http://www.openehr.org/ - - 2004 - - Reference Model objects creation named class and values - - - - openehr - openehr-rm-core - ${project.version} - - - openehr - openehr-rm-domain - ${project.version} - - - openehr - mini-termserv - ${project.version} - - - openehr - measure-serv - ${project.version} - - - commons-lang - commons-lang - 2.6 - - - log4j - log4j - 1.2.13 - - - junit - junit - 3.8.1 - test - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.9 + + rm-builder + jar + openEHR Reference Model Object Builder + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2004 + + Reference Model objects creation named class and values + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + openehr + measure-serv + ${project.version} + + + commons-lang + commons-lang + 2.6 + + + log4j + log4j + 1.2.13 + + + junit + junit + 3.8.1 + test + + + diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 6ef5a56a..06757f15 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -1,94 +1,94 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.9-SNAPSHOT - - rm-skeleton - jar - openEHR RM Skeleton Instance Generator - - - - openehr - openehr-rm-core - ${project.version} - - - openehr - openehr-rm-domain - ${project.version} - - - openehr - openehr-aom - ${project.version} - - - openehr - adl-parser - ${project.version} - - - openehr - dadl-parser - ${project.version} - - - openehr - oet-parser - ${project.version} - - - openehr - measure-serv - ${project.version} - - - openehr - mini-termserv - ${project.version} - - - openehr - dadl-binding - ${project.version} - - - openehr - xml-binding - ${project.version} - - - junit - junit - 4.5 - test - - - com.thoughtworks.xstream - xstream - 1.3.1 - test - - - openehr - adl-serializer - ${project.version} - test - - - log4j - log4j - 1.2.13 - - - commons-io - commons-io - 1.4 - test - - - + + + 4.0.0 + + openehr + ref_impl_java + 1.0.9 + + rm-skeleton + jar + openEHR RM Skeleton Instance Generator + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + openehr-aom + ${project.version} + + + openehr + adl-parser + ${project.version} + + + openehr + dadl-parser + ${project.version} + + + openehr + oet-parser + ${project.version} + + + openehr + measure-serv + ${project.version} + + + openehr + mini-termserv + ${project.version} + + + openehr + dadl-binding + ${project.version} + + + openehr + xml-binding + ${project.version} + + + junit + junit + 4.5 + test + + + com.thoughtworks.xstream + xstream + 1.3.1 + test + + + openehr + adl-serializer + ${project.version} + test + + + log4j + log4j + 1.2.13 + + + commons-io + commons-io + 1.4 + test + + + diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 8127404e..49bd9b68 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -1,128 +1,128 @@ - - - 4.0.0 - - openehr - ref_impl_java - 1.0.9-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 + + openehr + ref_impl_java + 1.0.9 + + 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} + + + diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 3ed05da4..87bd142e 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -1,66 +1,66 @@ - - 4.0.0 - - openehr - ref_impl_java - 1.0.9-SNAPSHOT - - xml-serializer - jar - XML Serializer - http://www.openehr.org/projects/java.html - - - openEHR - http://www.openehr.org/ - - 2004 - - Java XML Serializer of the Archetype Object Model - - - - openehr - openehr-rm-core - ${project.version} - - - openehr - openehr-rm-domain - ${project.version} - - - openehr - openehr-aom - ${project.version} - - - openehr - openehr-ap - ${project.version} - - - commons-lang - commons-lang - 2.6 - - - jdom - jdom - 1.0 - compile - - - commons-io - commons-io - 1.2 - test - - - junit - junit - 3.8.1 - test - - + + 4.0.0 + + openehr + ref_impl_java + 1.0.9 + + xml-serializer + jar + XML Serializer + http://www.openehr.org/projects/java.html + + + openEHR + http://www.openehr.org/ + + 2004 + + Java XML Serializer of the Archetype Object Model + + + + openehr + openehr-rm-core + ${project.version} + + + openehr + openehr-rm-domain + ${project.version} + + + openehr + openehr-aom + ${project.version} + + + openehr + openehr-ap + ${project.version} + + + commons-lang + commons-lang + 2.6 + + + jdom + jdom + 1.0 + compile + + + commons-io + commons-io + 1.2 + test + + + junit + junit + 3.8.1 + test + + \ No newline at end of file From e2213f7f2ca4bf00759a56d2c65a054d422e7769 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Thu, 14 Aug 2014 11:35:01 +0200 Subject: [PATCH 051/213] [maven-release-plugin] prepare for next development iteration --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index b6b20fa7..356e070b 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9 + 1.0.10-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 99565bef..c3e61eac 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.9 + 1.0.10-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 8e9c0b84..4cdf2e44 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9 + 1.0.10-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 14777c5e..858abfb5 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9 + 1.0.10-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 36363664..c7893dc0 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9 + 1.0.10-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 7aca4ba0..fa6111ae 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9 + 1.0.10-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 216675d1..70db2d6c 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9 + 1.0.10-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index dc054671..b73042d5 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9 + 1.0.10-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index f9205457..f7e1adcc 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9 + 1.0.10-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 45e5516b..914587b4 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9 + 1.0.10-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 7a121ed2..fb9cebe4 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9 + 1.0.10-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 5b6e797b..6d8af71c 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9 + 1.0.10-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index fdbc7377..1ea8bea7 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.9 + 1.0.10-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - ref_impl_java-1.0.9 + HEAD diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index a710941e..3ee5c519 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9 + 1.0.10-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 06757f15..3484c926 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9 + 1.0.10-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 49bd9b68..e93476d3 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.9 + 1.0.10-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 87bd142e..a932c30f 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.9 + 1.0.10-SNAPSHOT xml-serializer jar From cb3188ffeaae563d0929e26df23634fa20fef53d Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Fri, 15 Aug 2014 10:50:07 +0200 Subject: [PATCH 052/213] Fixing maven release plugin version --- pom.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 1ea8bea7..4dfe378a 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,7 @@ org.apache.maven.plugins maven-release-plugin - 2.3.2 + 2.5 org.codehaus.mojo @@ -104,7 +104,6 @@ repo.cambio.se_snapshots snapshots http://repo.cambio.se/content/repositories/snapshots - false From 5f4a0cc60f46cf4cc168d8fe0ff18dcf7ecfa398 Mon Sep 17 00:00:00 2001 From: MPalacio Date: Mon, 15 Sep 2014 16:54:43 +0200 Subject: [PATCH 053/213] Create jar with source code that will be published to Nexus along with the binaries. When the sources are published, IDEs will automatically import them thus reducing the burden to set up source dependencies for a particular version of a module --- pom.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pom.xml b/pom.xml index 4dfe378a..b56e1124 100644 --- a/pom.xml +++ b/pom.xml @@ -74,6 +74,17 @@ + + maven-source-plugin + + + attach-sources + + jar-no-fork + + + + From 34f732b72fc0c870335cbb27dfbf1a1f723bfa07 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Wed, 15 Oct 2014 10:56:29 +0200 Subject: [PATCH 054/213] Fixing XPath Utils issues --- .../org/openehr/rm/binding/XPathUtil.java | 316 +++++++++--------- .../org/openehr/rm/binding/XPathTest.java | 14 +- 2 files changed, 169 insertions(+), 161 deletions(-) mode change 100644 => 100755 dadl-binding/src/main/java/org/openehr/rm/binding/XPathUtil.java mode change 100644 => 100755 dadl-binding/src/test/java/org/openehr/rm/binding/XPathTest.java 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 old mode 100644 new mode 100755 index 50e512c9..1d2c53a8 --- 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,213 @@ 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(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); + } + } + } } 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() : "")); + //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); - Set set = paths.get(apath); - if(set == null) { - set = new HashSet(); - paths.put(apath, set); - } - set.add(xpath); + } else if(obj instanceof Locatable) { - } else if(obj instanceof Locatable) { + Locatable locatable = (Locatable) obj; - Locatable locatable = (Locatable) obj; + inspector.retrieveRMAttributes(obj.getClass().getSimpleName()); + Class klass = obj.getClass(); + String className = klass.getSimpleName(); - inspector.retrieveRMAttributes(obj.getClass().getSimpleName()); - Class klass = obj.getClass(); - String className = klass.getSimpleName(); + //System.out.println(">>> className: " + className); - //System.out.println(">>> className: " + className); + Map attributeMap = inspector.attributeMap(klass); + for(String attributeName : attributeMap.keySet()) { - Map attributeMap = inspector.attributeMap(klass); - for(String attributeName : attributeMap.keySet()) { + //System.out.println("Attribute name: " + attributeName); - //System.out.println("Attribute name: " + attributeName); + Attribute attribute = attributeMap.get(attributeName); - Attribute attribute = attributeMap.get(attributeName); + 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); - //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")) { + //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()); + } + } - //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); - } - } - } + //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); + } + } + } } private RMInspector inspector = RMInspector.getInstance(); 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 old mode 100644 new mode 100755 index 700570c8..393a5636 --- a/dadl-binding/src/test/java/org/openehr/rm/binding/XPathTest.java +++ b/dadl-binding/src/test/java/org/openehr/rm/binding/XPathTest.java @@ -1,12 +1,7 @@ package org.openehr.rm.binding; -import java.io.File; -import java.io.InputStream; -import java.util.*; - import org.apache.commons.io.FileUtils; import org.apache.commons.jxpath.JXPathContext; -import org.openehr.am.archetype.Archetype; import org.openehr.rm.Attribute; import org.openehr.rm.common.archetyped.Archetyped; import org.openehr.rm.composition.Composition; @@ -20,6 +15,13 @@ import org.openehr.rm.datatypes.text.DvText; import org.openehr.rm.support.measurement.MeasurementService; +import java.io.File; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + public class XPathTest extends DADLBindingTestBase { public void testCreatePathMapWithOrderSet() throws Exception { @@ -562,12 +564,10 @@ public static MeasurementService getInstance() { return new TestMeasurementService(); } - @Override public boolean unitsComparable(String units1, String units2) { return true; } - @Override public int compare(String units1, Double value1, String units2, Double value2) { return 0; From c1b329fcedbd7fc776e56a4d790f1f3326891a22 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 4 Nov 2014 16:36:27 +0100 Subject: [PATCH 055/213] [maven-release-plugin] prepare release ref_impl_java-1.0.10 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 356e070b..44dc536e 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10-SNAPSHOT + 1.0.10 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index c3e61eac..f42d2120 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.10-SNAPSHOT + 1.0.10 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 4cdf2e44..b697bcd6 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10-SNAPSHOT + 1.0.10 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 858abfb5..cd62492c 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10-SNAPSHOT + 1.0.10 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index c7893dc0..ac774016 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10-SNAPSHOT + 1.0.10 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index fa6111ae..c6e36db3 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10-SNAPSHOT + 1.0.10 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 70db2d6c..568902f2 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10-SNAPSHOT + 1.0.10 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index b73042d5..fb59aa0d 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10-SNAPSHOT + 1.0.10 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index f7e1adcc..f2a4e274 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10-SNAPSHOT + 1.0.10 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 914587b4..be214ad8 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10-SNAPSHOT + 1.0.10 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index fb9cebe4..890d4fdd 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10-SNAPSHOT + 1.0.10 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 6d8af71c..f24ec2c2 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10-SNAPSHOT + 1.0.10 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index b56e1124..51d87dd4 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.10-SNAPSHOT + 1.0.10 The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - HEAD + ref_impl_java-1.0.10 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 3ee5c519..3abba2c0 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10-SNAPSHOT + 1.0.10 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 3484c926..91c9bf21 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10-SNAPSHOT + 1.0.10 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index e93476d3..02bad3e1 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10-SNAPSHOT + 1.0.10 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index a932c30f..dda7cd3b 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.10-SNAPSHOT + 1.0.10 xml-serializer jar From c716fe4741e6ba24dfce94b0b4237c878f8de561 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 4 Nov 2014 16:36:45 +0100 Subject: [PATCH 056/213] [maven-release-plugin] prepare for next development iteration --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 44dc536e..6ad26c90 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10 + 1.0.11-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index f42d2120..67ed8c69 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.10 + 1.0.11-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index b697bcd6..242b7988 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10 + 1.0.11-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index cd62492c..00f0ac5c 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10 + 1.0.11-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index ac774016..007d01e8 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10 + 1.0.11-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index c6e36db3..2d96adff 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10 + 1.0.11-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 568902f2..7be78de2 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10 + 1.0.11-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index fb59aa0d..793a6ead 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10 + 1.0.11-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index f2a4e274..a9a48798 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10 + 1.0.11-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index be214ad8..dc1d9b7d 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10 + 1.0.11-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 890d4fdd..0857de6d 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10 + 1.0.11-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index f24ec2c2..3330341c 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10 + 1.0.11-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 51d87dd4..9925a562 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.10 + 1.0.11-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - ref_impl_java-1.0.10 + HEAD diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 3abba2c0..f8124543 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10 + 1.0.11-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 91c9bf21..9431b9f2 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10 + 1.0.11-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 02bad3e1..6abcc7bd 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.10 + 1.0.11-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index dda7cd3b..5ff58d21 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.10 + 1.0.11-SNAPSHOT xml-serializer jar From 301b0f12f3340bb300cae0719fa7f25210d71a19 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Mon, 1 Dec 2014 09:52:14 +0100 Subject: [PATCH 057/213] Setting as public some of the variables --- .../main/java/org/openehr/rm/RMObject.java | 2 +- .../openehr/rm/datatypes/basic/DvBoolean.java | 32 ++++++++++--------- .../rm/datatypes/quantity/DvQuantity.java | 11 +++++-- xml-serializer/pom.xml | 2 +- 4 files changed, 27 insertions(+), 20 deletions(-) mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/RMObject.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvBoolean.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvQuantity.java 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 old mode 100644 new mode 100755 index 23700ebc..b671a535 --- 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/datatypes/basic/DvBoolean.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvBoolean.java old mode 100644 new mode 100755 index dabaae20..ae3ddcbe --- 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; @@ -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/quantity/DvQuantity.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvQuantity.java old mode 100644 new mode 100755 index 4283f552..ca8e8e13 --- 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 * @@ -347,6 +348,10 @@ public void setMagnitude(double magnitude) { this.magnitude = magnitude; } + public void setUnits(String units) { + this.units = units; + } + public void setPrecision(int precision) { this.precision = precision; } @@ -355,7 +360,7 @@ public void setPrecision(int precision) { /* 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 = '.'; diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 5ff58d21..d5aaacc6 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -63,4 +63,4 @@ test - \ No newline at end of file + From 60388ab618d4e8cd20418419e4506411dc16033a Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Wed, 10 Dec 2014 11:15:25 +0100 Subject: [PATCH 058/213] Section.items cardinality should be validated against 0..*, not 1..* (unlike cluster.items) --- .../openehr/am/validation/RMInspector.java | 3 +- .../am/validation/SectionCardinalityTest.java | 17 +++++++ ...HR-EHR-SECTION.testitemscardinality.v1.adl | 51 +++++++++++++++++++ 3 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SectionCardinalityTest.java create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-SECTION.testitemscardinality.v1.adl 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 index 5c41cbb3..a9cf776e 100644 --- a/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java @@ -524,8 +524,7 @@ Interval defaultCardinalityInterval(CMultipleAttribute cattr, CObject p log.debug("Checking: "+ cattr.getRmAttributeName() +"; "+ parentObj.getRmTypeName() +" at "+cattr.path() +" parent path: "+parentObj.path()); if (cattr.getRmAttributeName().equals("items")) { - if (parentObj.getRmTypeName().equalsIgnoreCase("CLUSTER") || - parentObj.getRmTypeName().equalsIgnoreCase("SECTION")) { + if (parentObj.getRmTypeName().equalsIgnoreCase("CLUSTER") ) { // Note: For SECTION items, the intention seems to be cardinality = 0 log.debug("--> >=1"); return new Interval(1,null); } 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/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 = <"*"> + > + > + > + > From 15b514c9697f4e94a70a9f1bc7a516b89514535b Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Mon, 1 Dec 2014 09:52:14 +0100 Subject: [PATCH 059/213] Setting as public some of the variables --- .../main/java/org/openehr/rm/RMObject.java | 2 +- .../openehr/rm/datatypes/basic/DvBoolean.java | 32 ++++++++++--------- .../rm/datatypes/quantity/DvQuantity.java | 11 +++++-- xml-serializer/pom.xml | 2 +- 4 files changed, 27 insertions(+), 20 deletions(-) mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/RMObject.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvBoolean.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvQuantity.java 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 old mode 100644 new mode 100755 index 23700ebc..b671a535 --- 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/datatypes/basic/DvBoolean.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DvBoolean.java old mode 100644 new mode 100755 index dabaae20..ae3ddcbe --- 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; @@ -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/quantity/DvQuantity.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvQuantity.java old mode 100644 new mode 100755 index 4283f552..ca8e8e13 --- 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 * @@ -347,6 +348,10 @@ public void setMagnitude(double magnitude) { this.magnitude = magnitude; } + public void setUnits(String units) { + this.units = units; + } + public void setPrecision(int precision) { this.precision = precision; } @@ -355,7 +360,7 @@ public void setPrecision(int precision) { /* 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 = '.'; diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 5ff58d21..d5aaacc6 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -63,4 +63,4 @@ test - \ No newline at end of file + From cd9870529034b948a5247ffe9bffc85f2628e2b8 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Thu, 18 Dec 2014 10:11:50 +0100 Subject: [PATCH 060/213] Adding version to missing plugin on pom.xml. Adding serialVersionUID to CodePhrase. Removing changelog --- changelog.txt | 20 ------------------- .../openehr/rm/datatypes/text/CodePhrase.java | 2 ++ pom.xml | 1 + 3 files changed, 3 insertions(+), 20 deletions(-) delete mode 100644 changelog.txt mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/CodePhrase.java diff --git a/changelog.txt b/changelog.txt deleted file mode 100644 index 0c314597..00000000 --- a/changelog.txt +++ /dev/null @@ -1,20 +0,0 @@ -1.0.8 - -(CDS) SWE-4332 Correctly parse DvQuantity values with no unit. It was possible to serialise DvQuantity values into a format that caused InvalidArgumentException when parsed. -(CDS) CDS-254 Updated SCM paths to match renamed folder. -(CDS) CDS-254 Renaming foldre to match artifact. - -1.0.7 - -1.0.6 - -(CDS) CDS-247 Updated modules to use java 1.5 as compiler target, and updated all dependencies to the new snapshots. -(CDS) CDS-177 Added distribution management. -(CDS) removing dadl binding - -1.0.5 - -(CDS) CDS-177 Fixed scm from git to svn. -(CDS) CDS-130 Added release and cobertura plugin. -(CDS) CDS-130 Added target folders to ignore list. -(CDS) CDS-130 Added all files from github without modifications. 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 old mode 100644 new mode 100755 index 752bd1c2..f54ec256 --- 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/pom.xml b/pom.xml index 9925a562..3ba0e08e 100644 --- a/pom.xml +++ b/pom.xml @@ -76,6 +76,7 @@ maven-source-plugin + 2.1.2 attach-sources From 4ba9e906321fed17e0497953cf8107f5fdc49213 Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Wed, 10 Dec 2014 11:15:25 +0100 Subject: [PATCH 061/213] Section.items cardinality should be validated against 0..*, not 1..* (unlike cluster.items) --- .../openehr/am/validation/RMInspector.java | 3 +- .../am/validation/SectionCardinalityTest.java | 17 +++++++ ...HR-EHR-SECTION.testitemscardinality.v1.adl | 51 +++++++++++++++++++ 3 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 archetype-validator/src/test/java/org/openehr/am/validation/SectionCardinalityTest.java create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-SECTION.testitemscardinality.v1.adl 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 index 377f71f5..2b540dc5 100644 --- a/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java @@ -521,8 +521,7 @@ Interval defaultCardinalityInterval(CMultipleAttribute cattr, CObject p log.debug("Checking: "+ cattr.getRmAttributeName() +"; "+ parentObj.getRmTypeName() +" at "+cattr.path() +" parent path: "+parentObj.path()); if (cattr.getRmAttributeName().equals("items")) { - if (parentObj.getRmTypeName().equalsIgnoreCase("CLUSTER") || - parentObj.getRmTypeName().equalsIgnoreCase("SECTION")) { + if (parentObj.getRmTypeName().equalsIgnoreCase("CLUSTER") ) { // Note: For SECTION items, the intention seems to be cardinality = 0 log.debug("--> >=1"); return new Interval(1,null); } 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/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 = <"*"> + > + > + > + > From c403132f9f33b51c1a79e1f2547b9e7e8aa4b536 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Thu, 18 Dec 2014 10:11:50 +0100 Subject: [PATCH 062/213] Adding version to missing plugin on pom.xml. Adding serialVersionUID to CodePhrase. Removing changelog --- changelog.txt | 20 ------------------- .../openehr/rm/datatypes/text/CodePhrase.java | 2 ++ pom.xml | 1 + 3 files changed, 3 insertions(+), 20 deletions(-) delete mode 100644 changelog.txt mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/CodePhrase.java diff --git a/changelog.txt b/changelog.txt deleted file mode 100644 index 0c314597..00000000 --- a/changelog.txt +++ /dev/null @@ -1,20 +0,0 @@ -1.0.8 - -(CDS) SWE-4332 Correctly parse DvQuantity values with no unit. It was possible to serialise DvQuantity values into a format that caused InvalidArgumentException when parsed. -(CDS) CDS-254 Updated SCM paths to match renamed folder. -(CDS) CDS-254 Renaming foldre to match artifact. - -1.0.7 - -1.0.6 - -(CDS) CDS-247 Updated modules to use java 1.5 as compiler target, and updated all dependencies to the new snapshots. -(CDS) CDS-177 Added distribution management. -(CDS) removing dadl binding - -1.0.5 - -(CDS) CDS-177 Fixed scm from git to svn. -(CDS) CDS-130 Added release and cobertura plugin. -(CDS) CDS-130 Added target folders to ignore list. -(CDS) CDS-130 Added all files from github without modifications. 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 old mode 100644 new mode 100755 index 752bd1c2..f54ec256 --- 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/pom.xml b/pom.xml index 9925a562..3ba0e08e 100644 --- a/pom.xml +++ b/pom.xml @@ -76,6 +76,7 @@ maven-source-plugin + 2.1.2 attach-sources From 47b72a7263fa0196ba2fb0094d2edd87aee3ae46 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Dec 2014 11:15:11 +0100 Subject: [PATCH 063/213] [maven-release-plugin] prepare release ref_impl_java-1.0.11 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 6ad26c90..e7cac1d5 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11-SNAPSHOT + 1.0.11 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 67ed8c69..4a483036 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.11-SNAPSHOT + 1.0.11 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 242b7988..a23b4cbb 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11-SNAPSHOT + 1.0.11 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 00f0ac5c..5b3e330d 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11-SNAPSHOT + 1.0.11 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 007d01e8..76abc7a2 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11-SNAPSHOT + 1.0.11 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 2d96adff..bf7f005e 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11-SNAPSHOT + 1.0.11 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 7be78de2..82d97cd7 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11-SNAPSHOT + 1.0.11 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 793a6ead..a75c629d 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11-SNAPSHOT + 1.0.11 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index a9a48798..34534957 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11-SNAPSHOT + 1.0.11 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index dc1d9b7d..0b4f8138 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11-SNAPSHOT + 1.0.11 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 0857de6d..519ca639 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11-SNAPSHOT + 1.0.11 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 3330341c..286145dc 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11-SNAPSHOT + 1.0.11 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 3ba0e08e..86e356e3 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.11-SNAPSHOT + 1.0.11 The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - HEAD + ref_impl_java-1.0.11 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index f8124543..9eafd4d1 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11-SNAPSHOT + 1.0.11 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 9431b9f2..60a9e488 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11-SNAPSHOT + 1.0.11 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 6abcc7bd..3a02aeb2 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11-SNAPSHOT + 1.0.11 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index d5aaacc6..2ebe0937 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.11-SNAPSHOT + 1.0.11 xml-serializer jar From 0dfea262c034964b553c429b66edcab732fc6cb2 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Dec 2014 11:15:33 +0100 Subject: [PATCH 064/213] [maven-release-plugin] prepare for next development iteration --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index e7cac1d5..5f29713c 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11 + 1.0.12-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 4a483036..652807ee 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.11 + 1.0.12-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index a23b4cbb..55a9b711 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11 + 1.0.12-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 5b3e330d..a11b4a52 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11 + 1.0.12-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 76abc7a2..01dfb0b2 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11 + 1.0.12-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index bf7f005e..1073c211 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11 + 1.0.12-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 82d97cd7..dabab456 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11 + 1.0.12-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index a75c629d..73747989 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11 + 1.0.12-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 34534957..fedb588f 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11 + 1.0.12-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 0b4f8138..af73a807 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11 + 1.0.12-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 519ca639..ed4bcdf7 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11 + 1.0.12-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 286145dc..204caa46 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11 + 1.0.12-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 86e356e3..d7903fdf 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.11 + 1.0.12-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - ref_impl_java-1.0.11 + HEAD diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 9eafd4d1..d0f1ea9d 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11 + 1.0.12-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 60a9e488..79fc3b8c 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11 + 1.0.12-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 3a02aeb2..9202ad85 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.11 + 1.0.12-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 2ebe0937..f97a20b9 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.11 + 1.0.12-SNAPSHOT xml-serializer jar From c7e98e92df70e8f6f92d2b82bcfa1898ecb691a0 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Thu, 29 Jan 2015 14:58:13 +0100 Subject: [PATCH 065/213] Adding DvParsable as supported data value --- .../org/openehr/rm/datatypes/basic/DataValue.java | 6 ++++-- .../rm/datatypes/basic/ReferenceModelName.java | 4 ++-- .../rm/datatypes/encapsulated/DvParsable.java | 13 +++++++++++-- .../rm/datatypes/basic/ParseDataValueTest.java | 7 +++++++ 4 files changed, 24 insertions(+), 6 deletions(-) mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DataValue.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/ReferenceModelName.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/encapsulated/DvParsable.java mode change 100644 => 100755 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/basic/ParseDataValueTest.java 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 old mode 100644 new mode 100755 index 3d5504dd..61df2834 --- 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 @@ -17,6 +17,7 @@ import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; import org.openehr.rm.RMObject; +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; @@ -119,8 +120,9 @@ public DataValue parse(String value) { dataValueMap.put(ReferenceModelName.DV_DATE_TIME.getName(), new DvDateTime("2001-02-11T00")); 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_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/ReferenceModelName.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/ReferenceModelName.java old mode 100644 new mode 100755 index ac0dc98b..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 @@ -13,8 +13,8 @@ public enum ReferenceModelName { DV_DATE_TIME("DV_DATE_TIME"), DV_DATE("DV_DATE"), DV__TIME("DV_TIME"), - DV_DURATION("DV_DURATION"); - + 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/DvParsable.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/encapsulated/DvParsable.java old mode 100644 new mode 100755 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/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 100644 new mode 100755 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; } From 9179fb6a7b9315910d230572e79cdd822a814b15 Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Fri, 30 Jan 2015 10:29:14 +0100 Subject: [PATCH 066/213] Add Welsh languages to the terminology --- mini-termserv/src/main/resources/external_terminologies_en.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mini-termserv/src/main/resources/external_terminologies_en.xml b/mini-termserv/src/main/resources/external_terminologies_en.xml index 12bf14f4..d65a13b0 100644 --- a/mini-termserv/src/main/resources/external_terminologies_en.xml +++ b/mini-termserv/src/main/resources/external_terminologies_en.xml @@ -389,6 +389,9 @@ + + + From c432f9909b9d32444531a05e732648aa1ab1907b Mon Sep 17 00:00:00 2001 From: MPalacio Date: Tue, 17 Feb 2015 12:20:05 +0100 Subject: [PATCH 067/213] CDS-653 --- .../se/acode/openehr/parser/ArchetypeLanguageTest.java | 9 +++++++++ .../openehr/am/archetype/ontology/ArchetypeOntology.java | 5 +++++ 2 files changed, 14 insertions(+) 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 index 34b7c2ed..d0833ead 100644 --- 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/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 index c98a63cf..21ecb216 100644 --- 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 @@ -62,6 +62,11 @@ public ArchetypeOntology(String primaryLanguage, termDefinitionMap = new HashMap>(); constraintDefinitionMap = new HashMap>(); loadDefs(termDefinitionMap, termDefinitionsList); + + // make sure the languages list is consistent + languages.clear(); + languages.addAll(termDefinitionMap.keySet()); + loadDefs(constraintDefinitionMap, constDefinitionsList); } From 5c958859287769c9e57670ad8d55ff202785c981 Mon Sep 17 00:00:00 2001 From: MPalacio Date: Tue, 17 Feb 2015 12:25:13 +0100 Subject: [PATCH 068/213] CDS-653 --- ...dl-test-entry.archetype_language.test2.adl | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 adl-parser/src/test/resources/adl-test-entry.archetype_language.test2.adl 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 From c2e96f726647e93af97384521f10fb86995b8901 Mon Sep 17 00:00:00 2001 From: MPalacio Date: Tue, 17 Feb 2015 12:29:05 +0100 Subject: [PATCH 069/213] CDS-653 Added NPE check --- .../openehr/am/archetype/ontology/ArchetypeOntology.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 index 21ecb216..48aa9924 100644 --- 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 @@ -64,8 +64,10 @@ public ArchetypeOntology(String primaryLanguage, loadDefs(termDefinitionMap, termDefinitionsList); // make sure the languages list is consistent - languages.clear(); - languages.addAll(termDefinitionMap.keySet()); + if (this.languages != null) { + this.languages.clear(); + this.languages.addAll(termDefinitionMap.keySet()); + } loadDefs(constraintDefinitionMap, constDefinitionsList); } From ef431345deef06b8ac369eda2bce0520c19eec81 Mon Sep 17 00:00:00 2001 From: MPalacio Date: Tue, 17 Feb 2015 12:52:56 +0100 Subject: [PATCH 070/213] copy the list for protection --- .../org/openehr/am/archetype/ontology/ArchetypeOntology.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 index 48aa9924..d0adf586 100644 --- 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; @@ -95,7 +96,7 @@ public String getPrimaryLanguage() { } public List getLanguages() { - return languages; + return new ArrayList(languages); } public List getTerminologies() { From edf8a8f1d7411c9726357725394defc395f00948 Mon Sep 17 00:00:00 2001 From: MPalacio Date: Tue, 17 Feb 2015 15:29:29 +0100 Subject: [PATCH 071/213] avoid NPE when languages is null. Can we add validation? It's no good to pass null around. --- .../org/openehr/am/archetype/ontology/ArchetypeOntology.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 index d0adf586..4ec77fc1 100644 --- 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 @@ -35,6 +35,7 @@ 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 @@ -96,7 +97,7 @@ public String getPrimaryLanguage() { } public List getLanguages() { - return new ArrayList(languages); + return languages != null ? new ArrayList(languages) : null; } public List getTerminologies() { From f8e78c3073c56b93fc4454b9004321d2310a69e7 Mon Sep 17 00:00:00 2001 From: MPalacio Date: Tue, 17 Feb 2015 16:36:20 +0100 Subject: [PATCH 072/213] CDS-653 --- .../openehr/am/archetype/ontology/ArchetypeOntology.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) 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 index 4ec77fc1..d36b114a 100644 --- 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 @@ -53,7 +53,6 @@ public ArchetypeOntology(String primaryLanguage, List termBindingList, List constraintBindingList) { this.primaryLanguage = primaryLanguage; - this.languages = languages; this.terminologies = terminologies; this.termDefinitionsList = termDefinitionsList; this.constraintDefinitionsList = constDefinitionsList; @@ -66,10 +65,8 @@ public ArchetypeOntology(String primaryLanguage, loadDefs(termDefinitionMap, termDefinitionsList); // make sure the languages list is consistent - if (this.languages != null) { - this.languages.clear(); - this.languages.addAll(termDefinitionMap.keySet()); - } + this.languages = new ArrayList(); + this.languages.addAll(termDefinitionMap.keySet()); loadDefs(constraintDefinitionMap, constDefinitionsList); } @@ -97,7 +94,7 @@ public String getPrimaryLanguage() { } public List getLanguages() { - return languages != null ? new ArrayList(languages) : null; + return languages; } public List getTerminologies() { From 1538bc35d1b5bced3b9ff9df135f9e1caf220b97 Mon Sep 17 00:00:00 2001 From: MPalacio Date: Wed, 18 Feb 2015 13:20:09 +0100 Subject: [PATCH 073/213] cleaned up the unused languages parameter --- adl-parser/src/main/javacc/adl.jj | 5 ++--- .../org/openehr/am/serialize/MultipleLanguageTest.java | 9 ++------- .../openehr/am/serialize/MultipleTerminologyTest.java | 4 +--- .../test/java/org/openehr/am/serialize/OntologyTest.java | 4 +--- .../org/openehr/am/serialize/SimpleArchetypeTest.java | 5 ++--- .../openehr/am/archetype/ontology/ArchetypeOntology.java | 2 -- .../am/archetype/ontology/ArchetypeOntologyTest.java | 2 +- 7 files changed, 9 insertions(+), 22 deletions(-) diff --git a/adl-parser/src/main/javacc/adl.jj b/adl-parser/src/main/javacc/adl.jj index c82bde0e..b0c46f96 100644 --- a/adl-parser/src/main/javacc/adl.jj +++ b/adl-parser/src/main/javacc/adl.jj @@ -1007,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(); @@ -1023,7 +1022,7 @@ ArchetypeOntology arch_ontology() : { [primaryLanguage = primary_language()] - [languages = languages_available()] + [languages_available()] [ terminologies = terminologies_available() ] termDefinitionsList = term_definitions_list() @@ -1044,7 +1043,7 @@ ArchetypeOntology arch_ontology() : )* { - return new ArchetypeOntology(primaryLanguage, languages, terminologies, + return new ArchetypeOntology(primaryLanguage, terminologies, termDefinitionsList, constraintDefinitionsList, termBindingList, constraintBindingList); } 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 index 1519ff90..afead957 100644 --- 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 index 936c4999..2c8e16b0 100644 --- 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 index 62fc07d6..5aa60cd4 100644 --- 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/SimpleArchetypeTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/SimpleArchetypeTest.java index 33be739e..1bbea8d7 100644 --- 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/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 index d36b114a..b5b3d73d 100644 --- 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 @@ -38,7 +38,6 @@ public class ArchetypeOntology implements Serializable{ * //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 @@ -46,7 +45,6 @@ public class ArchetypeOntology implements Serializable{ * @param constraintBindingList */ public ArchetypeOntology(String primaryLanguage, - List languages, List terminologies, List termDefinitionsList, List constDefinitionsList, 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 index 892dd7fc..3e665365 100644 --- 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); } From 29ff2a1635dff4d7da294e33ac03b5ce83a731cb Mon Sep 17 00:00:00 2001 From: MPalacio Date: Wed, 18 Feb 2015 16:58:45 +0100 Subject: [PATCH 074/213] rolled back. Removing parameter "softly" caused problems with the javaCC --- adl-parser/src/main/javacc/adl.jj | 5 +++-- .../java/org/openehr/am/serialize/MultipleLanguageTest.java | 2 +- .../org/openehr/am/serialize/MultipleTerminologyTest.java | 2 +- .../src/test/java/org/openehr/am/serialize/OntologyTest.java | 2 +- .../java/org/openehr/am/serialize/SimpleArchetypeTest.java | 2 +- .../org/openehr/am/archetype/ontology/ArchetypeOntology.java | 2 ++ .../openehr/am/archetype/ontology/ArchetypeOntologyTest.java | 2 +- 7 files changed, 10 insertions(+), 7 deletions(-) diff --git a/adl-parser/src/main/javacc/adl.jj b/adl-parser/src/main/javacc/adl.jj index b0c46f96..c82bde0e 100644 --- a/adl-parser/src/main/javacc/adl.jj +++ b/adl-parser/src/main/javacc/adl.jj @@ -1007,6 +1007,7 @@ CComplexObject arch_definition() : ArchetypeOntology arch_ontology() : { String primaryLanguage = null; + List languages = null; List terminologies = null; List termDefinitionsList = new ArrayList(); List constraintDefinitionsList = new ArrayList(); @@ -1022,7 +1023,7 @@ ArchetypeOntology arch_ontology() : { [primaryLanguage = primary_language()] - [languages_available()] + [languages = languages_available()] [ terminologies = terminologies_available() ] termDefinitionsList = term_definitions_list() @@ -1043,7 +1044,7 @@ ArchetypeOntology arch_ontology() : )* { - return new ArchetypeOntology(primaryLanguage, terminologies, + return new ArchetypeOntology(primaryLanguage, languages, terminologies, termDefinitionsList, constraintDefinitionsList, termBindingList, constraintBindingList); } 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 index afead957..1e061623 100644 --- a/adl-serializer/src/test/java/org/openehr/am/serialize/MultipleLanguageTest.java +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/MultipleLanguageTest.java @@ -98,7 +98,7 @@ public void testPrintOntology() throws Exception { definitions = new OntologyDefinitions("zh", items); constraintDefinitionsList.add(definitions); - ArchetypeOntology ontology = new ArchetypeOntology("en", + ArchetypeOntology ontology = new ArchetypeOntology("en", null, 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 index 2c8e16b0..96d5d5c6 100644 --- a/adl-serializer/src/test/java/org/openehr/am/serialize/MultipleTerminologyTest.java +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/MultipleTerminologyTest.java @@ -84,7 +84,7 @@ public void testPrintOntology() throws Exception { ontologyBind = new OntologyBinding("ICD10",constraintBindList); constraintBindingList.add(ontologyBind); - ArchetypeOntology ontology = new ArchetypeOntology("en", + ArchetypeOntology ontology = new ArchetypeOntology("en", null, 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 index 5aa60cd4..f7efd19e 100644 --- a/adl-serializer/src/test/java/org/openehr/am/serialize/OntologyTest.java +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/OntologyTest.java @@ -88,7 +88,7 @@ public void testPrintOntology() throws Exception { new ArrayList(); constraintBindingList.add(ontologyBind); - ArchetypeOntology ontology = new ArchetypeOntology("en", + ArchetypeOntology ontology = new ArchetypeOntology("en", null, terminologies, termDefinitionsList, constraintDefinitionsList, termBindingList, constraintBindingList); clean(); 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 index 1bbea8d7..8d761b71 100644 --- a/adl-serializer/src/test/java/org/openehr/am/serialize/SimpleArchetypeTest.java +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/SimpleArchetypeTest.java @@ -62,7 +62,7 @@ public void testPrintArchetypeLanguagePart() throws Exception { List termBindingList = null; List constraintBindingList = null; - ArchetypeOntology ontology = new ArchetypeOntology("en", + ArchetypeOntology ontology = new ArchetypeOntology("en", null, terminologies, termDefinitionsList, constraintDefinitionsList, termBindingList, constraintBindingList); 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 index b5b3d73d..d36b114a 100644 --- 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 @@ -38,6 +38,7 @@ public class ArchetypeOntology implements Serializable{ * //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 @@ -45,6 +46,7 @@ public class ArchetypeOntology implements Serializable{ * @param constraintBindingList */ public ArchetypeOntology(String primaryLanguage, + List languages, List terminologies, List termDefinitionsList, List constDefinitionsList, 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 index 3e665365..b63ff417 100644 --- 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, + ontology = new ArchetypeOntology(primaryLanguage, null, terminologies, termDefinitionsList, constDefinitionsList, null, null); } From 1a03300db4aa97688ae191c46b77ee1746698a19 Mon Sep 17 00:00:00 2001 From: MPalacio Date: Wed, 18 Feb 2015 17:03:50 +0100 Subject: [PATCH 075/213] cleaned up the unused languages parameter --- adl-parser/src/main/javacc/adl.jj | 5 ++--- .../java/org/openehr/am/serialize/MultipleLanguageTest.java | 2 +- .../org/openehr/am/serialize/MultipleTerminologyTest.java | 2 +- .../src/test/java/org/openehr/am/serialize/OntologyTest.java | 2 +- .../java/org/openehr/am/serialize/SimpleArchetypeTest.java | 2 +- .../org/openehr/am/archetype/ontology/ArchetypeOntology.java | 2 -- .../openehr/am/archetype/ontology/ArchetypeOntologyTest.java | 2 +- 7 files changed, 7 insertions(+), 10 deletions(-) diff --git a/adl-parser/src/main/javacc/adl.jj b/adl-parser/src/main/javacc/adl.jj index c82bde0e..b0c46f96 100644 --- a/adl-parser/src/main/javacc/adl.jj +++ b/adl-parser/src/main/javacc/adl.jj @@ -1007,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(); @@ -1023,7 +1022,7 @@ ArchetypeOntology arch_ontology() : { [primaryLanguage = primary_language()] - [languages = languages_available()] + [languages_available()] [ terminologies = terminologies_available() ] termDefinitionsList = term_definitions_list() @@ -1044,7 +1043,7 @@ ArchetypeOntology arch_ontology() : )* { - return new ArchetypeOntology(primaryLanguage, languages, terminologies, + return new ArchetypeOntology(primaryLanguage, terminologies, termDefinitionsList, constraintDefinitionsList, termBindingList, constraintBindingList); } 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 index 1e061623..afead957 100644 --- a/adl-serializer/src/test/java/org/openehr/am/serialize/MultipleLanguageTest.java +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/MultipleLanguageTest.java @@ -98,7 +98,7 @@ public void testPrintOntology() throws Exception { definitions = new OntologyDefinitions("zh", items); constraintDefinitionsList.add(definitions); - ArchetypeOntology ontology = new ArchetypeOntology("en", null, + 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 index 96d5d5c6..2c8e16b0 100644 --- a/adl-serializer/src/test/java/org/openehr/am/serialize/MultipleTerminologyTest.java +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/MultipleTerminologyTest.java @@ -84,7 +84,7 @@ public void testPrintOntology() throws Exception { ontologyBind = new OntologyBinding("ICD10",constraintBindList); constraintBindingList.add(ontologyBind); - ArchetypeOntology ontology = new ArchetypeOntology("en", null, + 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 index f7efd19e..5aa60cd4 100644 --- a/adl-serializer/src/test/java/org/openehr/am/serialize/OntologyTest.java +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/OntologyTest.java @@ -88,7 +88,7 @@ public void testPrintOntology() throws Exception { new ArrayList(); constraintBindingList.add(ontologyBind); - ArchetypeOntology ontology = new ArchetypeOntology("en", null, + ArchetypeOntology ontology = new ArchetypeOntology("en", terminologies, termDefinitionsList, constraintDefinitionsList, termBindingList, constraintBindingList); clean(); 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 index 8d761b71..1bbea8d7 100644 --- a/adl-serializer/src/test/java/org/openehr/am/serialize/SimpleArchetypeTest.java +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/SimpleArchetypeTest.java @@ -62,7 +62,7 @@ public void testPrintArchetypeLanguagePart() throws Exception { List termBindingList = null; List constraintBindingList = null; - ArchetypeOntology ontology = new ArchetypeOntology("en", null, + ArchetypeOntology ontology = new ArchetypeOntology("en", terminologies, termDefinitionsList, constraintDefinitionsList, termBindingList, constraintBindingList); 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 index d36b114a..b5b3d73d 100644 --- 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 @@ -38,7 +38,6 @@ public class ArchetypeOntology implements Serializable{ * //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 @@ -46,7 +45,6 @@ public class ArchetypeOntology implements Serializable{ * @param constraintBindingList */ public ArchetypeOntology(String primaryLanguage, - List languages, List terminologies, List termDefinitionsList, List constDefinitionsList, 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 index b63ff417..3e665365 100644 --- 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, null, + ontology = new ArchetypeOntology(primaryLanguage, terminologies, termDefinitionsList, constDefinitionsList, null, null); } From 5283499069aa2d83b7d7e3fa11c2044e0e28f73e Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Fri, 20 Feb 2015 10:42:27 +0100 Subject: [PATCH 076/213] Adding sinhala language support --- mini-termserv/src/main/resources/external_terminologies_en.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) mode change 100644 => 100755 mini-termserv/src/main/resources/external_terminologies_en.xml diff --git a/mini-termserv/src/main/resources/external_terminologies_en.xml b/mini-termserv/src/main/resources/external_terminologies_en.xml old mode 100644 new mode 100755 index 12bf14f4..f07e9cc3 --- a/mini-termserv/src/main/resources/external_terminologies_en.xml +++ b/mini-termserv/src/main/resources/external_terminologies_en.xml @@ -357,7 +357,8 @@ - + + From f14140cd6abbc174df41812f3c3d88e1edf8bd92 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Feb 2015 16:18:44 +0100 Subject: [PATCH 077/213] [maven-release-plugin] prepare release ref_impl_java-1.0.12 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 5f29713c..6e17e586 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12-SNAPSHOT + 1.0.12 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 652807ee..51d11533 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.12-SNAPSHOT + 1.0.12 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 55a9b711..b19afe51 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12-SNAPSHOT + 1.0.12 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index a11b4a52..f7af845f 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12-SNAPSHOT + 1.0.12 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 01dfb0b2..df5d766d 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12-SNAPSHOT + 1.0.12 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 1073c211..0c18a09f 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12-SNAPSHOT + 1.0.12 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index dabab456..c91db75b 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12-SNAPSHOT + 1.0.12 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 73747989..e4a83d19 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12-SNAPSHOT + 1.0.12 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index fedb588f..fed34863 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12-SNAPSHOT + 1.0.12 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index af73a807..52013d59 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12-SNAPSHOT + 1.0.12 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index ed4bcdf7..7052102c 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12-SNAPSHOT + 1.0.12 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 204caa46..e70c34fc 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12-SNAPSHOT + 1.0.12 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index d7903fdf..672b0baf 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.12-SNAPSHOT + 1.0.12 The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - HEAD + ref_impl_java-1.0.12 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index d0f1ea9d..675026bc 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12-SNAPSHOT + 1.0.12 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 79fc3b8c..51915f6b 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12-SNAPSHOT + 1.0.12 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 9202ad85..03ad83e4 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12-SNAPSHOT + 1.0.12 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index f97a20b9..b36602e1 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.12-SNAPSHOT + 1.0.12 xml-serializer jar From 6ee1b92c4e3a305803a41d4e43180642de24ed82 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Feb 2015 16:18:48 +0100 Subject: [PATCH 078/213] [maven-release-plugin] prepare for next development iteration --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 6e17e586..8a7e9861 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12 + 1.0.13-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 51d11533..41e2639c 100644 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.12 + 1.0.13-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index b19afe51..830c796a 100644 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12 + 1.0.13-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index f7af845f..1d96a880 100644 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12 + 1.0.13-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index df5d766d..e1ce48db 100644 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12 + 1.0.13-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 0c18a09f..814b2690 100644 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12 + 1.0.13-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index c91db75b..bf3a2ea4 100644 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12 + 1.0.13-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index e4a83d19..7711cc50 100644 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12 + 1.0.13-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index fed34863..1d74420a 100644 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12 + 1.0.13-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 52013d59..54feed55 100644 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12 + 1.0.13-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 7052102c..dec32599 100644 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12 + 1.0.13-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index e70c34fc..1fb3dbc9 100644 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12 + 1.0.13-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 672b0baf..8c867eee 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.12 + 1.0.13-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - ref_impl_java-1.0.12 + HEAD diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 675026bc..61ff417c 100644 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12 + 1.0.13-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 51915f6b..1fce1d00 100644 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12 + 1.0.13-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 03ad83e4..00eb46b2 100644 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.12 + 1.0.13-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index b36602e1..30fc0361 100644 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.12 + 1.0.13-SNAPSHOT xml-serializer jar From 888c4c9a8529b30560fc797040891b04f690910b Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Tue, 16 Jun 2015 16:26:05 +0200 Subject: [PATCH 079/213] Fixing issues with boolean constructor and caching of cosntructors on RMObjectBuilder --- .../openehr/rm/datatypes/basic/DvBoolean.java | 6 +- .../org/openehr/build/RMObjectBuilder.java | 1357 +++++++++-------- .../org/openehr/build/DataTypesBuildTest.java | 22 +- 3 files changed, 729 insertions(+), 656 deletions(-) mode change 100644 => 100755 rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java mode change 100644 => 100755 rm-builder/src/test/java/org/openehr/build/DataTypesBuildTest.java 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 ae3ddcbe..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 @@ -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)); } diff --git a/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java b/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java old mode 100644 new mode 100755 index d539ce10..f480a316 --- a/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java +++ b/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java @@ -15,673 +15,728 @@ 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 java.lang.annotation.Annotation; import java.lang.reflect.Constructor; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; /** * 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 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 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 (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); + + // 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 (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. + private final Map constructorMap = 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/test/java/org/openehr/build/DataTypesBuildTest.java b/rm-builder/src/test/java/org/openehr/build/DataTypesBuildTest.java old mode 100644 new mode 100755 index ff14d505..bcf62401 --- 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 { From 451f83a17e404841094adfa154503ccfbdf2013d Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Wed, 17 Jun 2015 16:39:54 +0200 Subject: [PATCH 080/213] Changing implementation of Constructor map to synchronized (ensuring multithread safety) --- .../src/main/java/org/openehr/build/RMObjectBuilder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 f480a316..4533f469 100755 --- a/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java +++ b/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java @@ -75,6 +75,7 @@ import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -728,7 +729,7 @@ private Object defaultValue(Class type) { 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 = new HashMap(); + private final Map constructorMap = Collections.synchronizedMap(new HashMap()); static { // so far only types from quantity.datetime From bc3c097a1d7f4d0992c37bdaaccb5de83467adbe Mon Sep 17 00:00:00 2001 From: Malik Firose Date: Fri, 26 Jun 2015 15:12:43 +0530 Subject: [PATCH 081/213] Equals method implemented for Observation and evaluation objects. --- .../composition/content/entry/Evaluation.java | 45 ++++++ .../content/entry/Observation.java | 54 +++++++ .../content/entry/EvaluationTest.java | 103 +++++++++++++ .../content/entry/ObservationTest.java | 144 ++++++++++++++++++ 4 files changed, 346 insertions(+) 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..1d764424 100644 --- 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,51 @@ void setData(ItemStructure data) { } // POJO end + + @Override + public boolean equals(Object obj) { + 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/Observation.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Observation.java index e16c815d..278ee0bc 100644 --- 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,60 @@ void setState(History state) { private History data; private History state; + @Override + public boolean equals(Object obj) { + 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/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 index ee62520b..4734470c 100644 --- 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/ObservationTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ObservationTest.java index e527d37f..940cbf68 100644 --- 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; From fe44871d297230aa331716d53928c9867f9199b8 Mon Sep 17 00:00:00 2001 From: Malik Firose Date: Fri, 26 Jun 2015 15:14:20 +0530 Subject: [PATCH 082/213] CInteger System crash when this is called with other type of objects other than Integer. --- .../constraintmodel/primitive/CInteger.java | 13 ++++++++++--- .../constraintmodel/primitive/CIntegerTest.java | 5 +++++ 2 files changed, 15 insertions(+), 3 deletions(-) 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 index 7d15bd57..24adcb45 100644 --- 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/test/java/org/openehr/am/archetype/constraintmodel/primitive/CIntegerTest.java b/openehr-aom/src/test/java/org/openehr/am/archetype/constraintmodel/primitive/CIntegerTest.java index cb32e2cc..a94393ad 100644 --- 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,11 @@ 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")); + assertTrue(!ci.validValue("")); + assertTrue(!ci.validValue("-1")); + } } From a891d5a69e865b026010e1527fdcd278548c7427 Mon Sep 17 00:00:00 2001 From: Malik Firose Date: Fri, 26 Jun 2015 15:15:29 +0530 Subject: [PATCH 083/213] Performance improvement in RMObjectBuilder --- .../main/java/org/openehr/binding/XMLBinding.java | 15 +++++++++++++-- .../org/openehr/binding/BindDataTypesTest.java | 12 ++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) 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..5ba90bfd 100644 --- 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; @@ -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/test/java/org/openehr/binding/BindDataTypesTest.java b/xml-binding/src/test/java/org/openehr/binding/BindDataTypesTest.java index 6e01cb23..b80ff06f 100644 --- 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")); From fc79fbd8da599163685389d211c9ab23c81cc2d5 Mon Sep 17 00:00:00 2001 From: Malik Firose Date: Fri, 26 Jun 2015 16:10:59 +0530 Subject: [PATCH 084/213] Equals method implemented for Item structures objects --- .../datastructure/itemstructure/ItemList.java | 56 ++- .../itemstructure/ItemSingle.java | 31 ++ .../itemstructure/ItemTable.java | 34 +- .../datastructure/itemstructure/ItemTree.java | 334 +++++++++--------- .../itemstructure/representation/Cluster.java | 36 ++ .../itemstructure/representation/Item.java | 9 +- .../java/org/openehr/rm/util/ItemUtil.java | 56 +++ .../itemstructure/ItemListTest.java | 90 +++++ .../itemstructure/ItemSingleTest.java | 30 ++ .../itemstructure/ItemTableTest.java | 62 ++++ .../itemstructure/ItemTreeTest.java | 80 +++++ 11 files changed, 632 insertions(+), 186 deletions(-) create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/util/ItemUtil.java 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..c4d0b76d 100644 --- 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,40 @@ 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 (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 +217,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..5dce1fdb 100644 --- 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,37 @@ 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 (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/ItemTable.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemTable.java index 3afa4a68..1afc9fbe 100644 --- 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,39 @@ 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 (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..79cb3503 100644 --- 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. @@ -37,137 +37,150 @@ */ public final class ItemTree extends ItemStructure { - /** - * Constructs an ItemTree - * - * @param uid - * @param archetypeNodeId - * @param name - * @param archetypeDetails - * @param feederAudit - * @param links - * @param items null if unspecified - */ - @FullConstructor - public ItemTree(@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 = "items") List items) { - super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, - links, parent); - this.items = items; - } - - /** - * Constructs a ItemStructure - * - * @param archetypeNodeId - * @param name - * @param items null if unspecified - */ - public ItemTree(String archetypeNodeId, DvText name, List items) { - this(null, archetypeNodeId, name, null, null, null, null, items); - } - - /** - * Constructs a ItemStructure - * - * @param archetypeNodeId - * @param name - * @param items null if unspecified - */ - public ItemTree(String archetypeNodeId, String name, List items) { - this(archetypeNodeId, new DvText(name), items); - } - - /** - * True if given path is a valid leaf path - * - * @param path - * @return ture if path is valid - * @throws IllegalArgumentException if path null or empty - */ - public boolean hasElementPath(String path) { - Object value = itemAtPath(path); - return value != null; - - } - - /** - * Return the leaf element at the path - * - * @param path - * @return element found - * @throws IllegalArgumentException if path is not valid - * or element doesn't exist at given path - */ - public Element elementAtPath(String path) { - Object node = itemAtPath(path); - if(node instanceof Element) { - return (Element) node; - } - throw new IllegalArgumentException("Invalid path: " + path); - } - - /** - * Gets the items - * - * @return null if unspecified - */ - 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(); - } - - /** - * Return a hash code of this actor - * - * @return hash code - */ - public int hashCode() { - return new HashCodeBuilder(17, 23) - .appendSuper(super.hashCode()) - .append(items) - .toHashCode(); - } - - /** - * Return the path to an item relative to the root of this - * archetyped structure. - * - * @param item - * @return path of given item - */ - public String pathOfItem(Pathable item) { - return null; // todo: implement this method - } - - @Override + /** + * Constructs an ItemTree + * + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @param items + * null if unspecified + */ + @FullConstructor + public ItemTree( + @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 = "items") List items) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, + parent); + this.items = items; + } + + /** + * Constructs a ItemStructure + * + * @param archetypeNodeId + * @param name + * @param items + * null if unspecified + */ + public ItemTree(String archetypeNodeId, DvText name, List items) { + this(null, archetypeNodeId, name, null, null, null, null, items); + } + + /** + * Constructs a ItemStructure + * + * @param archetypeNodeId + * @param name + * @param items + * null if unspecified + */ + public ItemTree(String archetypeNodeId, String name, List items) { + this(archetypeNodeId, new DvText(name), items); + } + + /** + * True if given path is a valid leaf path + * + * @param path + * @return ture if path is valid + * @throws IllegalArgumentException + * if path null or empty + */ + public boolean hasElementPath(String path) { + Object value = itemAtPath(path); + return value != null; + + } + + /** + * Return the leaf element at the path + * + * @param path + * @return element found + * @throws IllegalArgumentException + * if path is not valid or element doesn't exist at given path + */ + public Element elementAtPath(String path) { + Object node = itemAtPath(path); + if (node instanceof Element) { + return (Element) node; + } + throw new IllegalArgumentException("Invalid path: " + path); + } + + /** + * Gets the items + * + * @return null if unspecified + */ + public List getItems() { + return items; + } + + @Override + public boolean equals(Object obj) { + 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 archetyped + * structure. + * + * @param item + * @return path of given item + */ + public String pathOfItem(Pathable item) { + return null; // todo: implement this method + } + + @Override public Item asHierarchy() { // TODO Auto-generated method stub return null; } - + @Override public List itemsAtPath(String path) { // TODO Auto-generated method stub @@ -186,40 +199,37 @@ public boolean pathUnique(String path) { return false; } - // POJO start - ItemTree() { - } - // POJO end + // POJO start + ItemTree() { + } + + // POJO end private List items; } /* - * ***** 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 ItemTree.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): - * + * ***** 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. - * - * ***** END LICENSE BLOCK ***** + * 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 ItemTree.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-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..44ee3781 100644 --- 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,40 @@ 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 (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/Item.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/representation/Item.java index 4a2f4c9d..74c7155b 100644 --- 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 @@ -14,15 +14,15 @@ */ package org.openehr.rm.datastructure.itemstructure.representation; +import java.util.Set; + 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.support.identification.UIDBasedID; import org.openehr.rm.datatypes.text.DvText; - -import java.util.Set; +import org.openehr.rm.support.identification.UIDBasedID; /** * The abstract parent of CLUSTER and ELEMENT representation classes. @@ -30,7 +30,7 @@ * @author Rong Chen * @version 1.0 */ -public abstract class Item extends Locatable { +public abstract class Item extends Locatable{ /** * Constructs an Item @@ -65,6 +65,7 @@ protected Item(String archetypeNodeId, DvText name) { protected Item() { } // POJO end + } /* 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/datastructure/itemstructure/ItemListTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datastructure/itemstructure/ItemListTest.java index aaf3a35d..52873759 100644 --- 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,96 @@ 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 index 0a584e25..1b437473 100644 --- 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 index fa58991e..b9a35fae 100644 --- 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 index 49f1371a..d1ae0257 100644 --- 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; From 25d456df7545f3e3ebf2fe66c0fa7572f1a2cf1c Mon Sep 17 00:00:00 2001 From: Malik Firose Date: Tue, 30 Jun 2015 11:48:43 +0530 Subject: [PATCH 085/213] Assert false used --- .../archetype/constraintmodel/primitive/CIntegerTest.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) 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 index a94393ad..7d026246 100644 --- 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 @@ -69,10 +69,9 @@ public void testValidValue() { assertTrue(!ci.validValue(new Integer(-1))); assertTrue(!ci.validValue(new Integer(1))); - assertTrue(ci.validValue("2")); - assertTrue(!ci.validValue("")); - assertTrue(!ci.validValue("-1")); - + assertTrue(ci.validValue("2")); + assertFalse(ci.validValue("")); + assertFalse(ci.validValue("-1")); } } From 2b53a190607f34d91a48e35570ba23cf8a50c3db Mon Sep 17 00:00:00 2001 From: Malik Firose Date: Tue, 30 Jun 2015 11:51:05 +0530 Subject: [PATCH 086/213] Brace style changed --- .../datastructure/itemstructure/ItemListTest.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) 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 index 52873759..22c0e6ff 100644 --- 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 @@ -97,9 +97,8 @@ public void testEquals() { assertTrue(itemListOne.equals(itemListTwo)); } - - public void testEqualsElementsInMixedOrder() - { + + public void testEqualsElementsInMixedOrder() { List elementsOne = new ArrayList(); elementsOne.add(element(NAMES[0], VALUES[0])); @@ -120,9 +119,8 @@ public void testEqualsElementsInMixedOrder() assertTrue(itemListOne.equals(itemListTwo)); } - - public void testNotEqualSize() - { + + public void testNotEqualSize() { List elementsOne = new ArrayList(); elementsOne.add(element(NAMES[0], VALUES[0])); @@ -142,9 +140,8 @@ public void testNotEqualSize() assertFalse(itemListOne.equals(itemListTwo)); } - - public void testNotEqual() - { + + public void testNotEqual() { List elementsOne = new ArrayList(); elementsOne.add(element(NAMES[0], VALUES[0])); From d8da046f94346fee8b143469a6167602e61cd79c Mon Sep 17 00:00:00 2001 From: Malik Firose Date: Tue, 30 Jun 2015 11:52:02 +0530 Subject: [PATCH 087/213] changes discarded --- .../datastructure/itemstructure/representation/Item.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) 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 index 74c7155b..4a2f4c9d 100644 --- 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 @@ -14,15 +14,15 @@ */ package org.openehr.rm.datastructure.itemstructure.representation; -import java.util.Set; - 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.datatypes.text.DvText; import org.openehr.rm.support.identification.UIDBasedID; +import org.openehr.rm.datatypes.text.DvText; + +import java.util.Set; /** * The abstract parent of CLUSTER and ELEMENT representation classes. @@ -30,7 +30,7 @@ * @author Rong Chen * @version 1.0 */ -public abstract class Item extends Locatable{ +public abstract class Item extends Locatable { /** * Constructs an Item @@ -65,7 +65,6 @@ protected Item(String archetypeNodeId, DvText name) { protected Item() { } // POJO end - } /* From cbdcc4f9c99261c1d3a8726044e04cb65ea68791 Mon Sep 17 00:00:00 2001 From: Malik Firose Date: Tue, 30 Jun 2015 11:53:08 +0530 Subject: [PATCH 088/213] changes limited only to the new methods --- .../datastructure/itemstructure/ItemTree.java | 261 +++++++++--------- 1 file changed, 132 insertions(+), 129 deletions(-) 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 79cb3503..66c264c9 100644 --- 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 @@ -37,97 +37,97 @@ */ public final class ItemTree extends ItemStructure { + /** + * Constructs an ItemTree + * + * @param uid + * @param archetypeNodeId + * @param name + * @param archetypeDetails + * @param feederAudit + * @param links + * @param items null if unspecified + */ + @FullConstructor + public ItemTree(@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 = "items") List items) { + super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, + links, parent); + this.items = items; + } + + /** + * Constructs a ItemStructure + * + * @param archetypeNodeId + * @param name + * @param items null if unspecified + */ + public ItemTree(String archetypeNodeId, DvText name, List items) { + this(null, archetypeNodeId, name, null, null, null, null, items); + } + + /** + * Constructs a ItemStructure + * + * @param archetypeNodeId + * @param name + * @param items null if unspecified + */ + public ItemTree(String archetypeNodeId, String name, List items) { + this(archetypeNodeId, new DvText(name), items); + } + + /** + * True if given path is a valid leaf path + * + * @param path + * @return ture if path is valid + * @throws IllegalArgumentException if path null or empty + */ + public boolean hasElementPath(String path) { + Object value = itemAtPath(path); + return value != null; + + } + + /** + * Return the leaf element at the path + * + * @param path + * @return element found + * @throws IllegalArgumentException if path is not valid + * or element doesn't exist at given path + */ + public Element elementAtPath(String path) { + Object node = itemAtPath(path); + if(node instanceof Element) { + return (Element) node; + } + throw new IllegalArgumentException("Invalid path: " + path); + } + + /** + * Gets the items + * + * @return null if unspecified + */ + public List getItems() { + return items; + } + /** - * Constructs an ItemTree + * Equals if two item_tree has same values * - * @param uid - * @param archetypeNodeId - * @param name - * @param archetypeDetails - * @param feederAudit - * @param links - * @param items - * null if unspecified + * @param o + * @return equals if true */ - @FullConstructor - public ItemTree( - @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 = "items") List items) { - super(uid, archetypeNodeId, name, archetypeDetails, feederAudit, links, - parent); - this.items = items; - } - - /** - * Constructs a ItemStructure - * - * @param archetypeNodeId - * @param name - * @param items - * null if unspecified - */ - public ItemTree(String archetypeNodeId, DvText name, List items) { - this(null, archetypeNodeId, name, null, null, null, null, items); - } - - /** - * Constructs a ItemStructure - * - * @param archetypeNodeId - * @param name - * @param items - * null if unspecified - */ - public ItemTree(String archetypeNodeId, String name, List items) { - this(archetypeNodeId, new DvText(name), items); - } - - /** - * True if given path is a valid leaf path - * - * @param path - * @return ture if path is valid - * @throws IllegalArgumentException - * if path null or empty - */ - public boolean hasElementPath(String path) { - Object value = itemAtPath(path); - return value != null; - - } - - /** - * Return the leaf element at the path - * - * @param path - * @return element found - * @throws IllegalArgumentException - * if path is not valid or element doesn't exist at given path - */ - public Element elementAtPath(String path) { - Object node = itemAtPath(path); - if (node instanceof Element) { - return (Element) node; - } - throw new IllegalArgumentException("Invalid path: " + path); - } - - /** - * Gets the items - * - * @return null if unspecified - */ - public List getItems() { - return items; - } - - @Override public boolean equals(Object obj) { if (this == obj) { return true; @@ -163,24 +163,24 @@ public int hashCode() { result = prime * result + ((items == null) ? 0 : items.hashCode()); return result; } - - /** - * Return the path to an item relative to the root of this archetyped - * structure. - * - * @param item - * @return path of given item - */ - public String pathOfItem(Pathable item) { - return null; // todo: implement this method - } - - @Override + + /** + * Return the path to an item relative to the root of this + * archetyped structure. + * + * @param item + * @return path of given item + */ + public String pathOfItem(Pathable item) { + return null; // todo: implement this method + } + + @Override public Item asHierarchy() { // TODO Auto-generated method stub return null; } - + @Override public List itemsAtPath(String path) { // TODO Auto-generated method stub @@ -199,37 +199,40 @@ public boolean pathUnique(String path) { return false; } - // POJO start - ItemTree() { - } - - // POJO end + // POJO start + ItemTree() { + } + // POJO end private List items; } /* - * ***** 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 ItemTree.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): - * + * ***** 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 ItemTree.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 ***** + * 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 From e4182833c6dda2290dcb64af4b8f218077c18ea0 Mon Sep 17 00:00:00 2001 From: Malik Firose Date: Tue, 30 Jun 2015 11:54:42 +0530 Subject: [PATCH 089/213] Equals method added to Instruction and Action. --- .../rm/composition/content/entry/Action.java | 72 ++++++++- .../composition/content/entry/Activity.java | 53 ++++++- .../content/entry/ISMTransition.java | 50 ++++++ .../content/entry/Instruction.java | 76 +++++++++- .../content/entry/InstructionDetails.java | 50 ++++++ .../composition/content/entry/ActionTest.java | 62 ++++++++ .../content/entry/InstructionTest.java | 142 ++++++++++++++++++ 7 files changed, 498 insertions(+), 7 deletions(-) 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 index dd881646..81f0d443 100644 --- 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,9 +186,78 @@ 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; + private ItemStructure description; private ISMTransition ismTransition; private InstructionDetails instructionDetails; 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 index 68225226..dcff245d 100644 --- 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 @@ -149,7 +149,58 @@ public void setActionArchetypeId(String actionArchetypeId){ this.actionArchetypeId = actionArchetypeId; } - //POJO end + // 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; 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 index 5b112c2b..3fccf455 100644 --- 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 @@ -115,6 +115,56 @@ void setTransition(DvCodedText transition) { } //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()); + 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; + } + return true; + } + /* fields */ private DvCodedText currentState; private DvCodedText transition; 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 index 1fa0c606..325bed59 100644 --- 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,12 +220,80 @@ 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; - private List activities; + /* fields */ + private DvText narrative; + private List activities; private DvDateTime expiryTime; private DvParsable wfDefinition; } 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 index 91c4b3d6..6b4264f0 100644 --- 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/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..78d66e3d 100644 --- 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 @@ -22,6 +22,7 @@ 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; @@ -96,6 +97,67 @@ public void testItemAtPathTime() { 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, 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); + + Action action2 = 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); + 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, 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, 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; } 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 index d3e77c48..51b5773d 100644 --- 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 = "/"; From 7f5be056135377a88beda9b5ddb64b226399312e Mon Sep 17 00:00:00 2001 From: Malik Firose Date: Thu, 2 Jul 2015 13:40:44 +0530 Subject: [PATCH 090/213] Space removed --- .../java/org/openehr/rm/composition/content/entry/Action.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 81f0d443..1c703c3a 100644 --- 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 @@ -257,7 +257,7 @@ public boolean equals(Object obj) { /* fields */ private DvDateTime time; - private ItemStructure description; + private ItemStructure description; private ISMTransition ismTransition; private InstructionDetails instructionDetails; From 8900ea19f67a26792404d12f4effac90dfea47ff Mon Sep 17 00:00:00 2001 From: Malik Firose Date: Thu, 2 Jul 2015 13:47:35 +0530 Subject: [PATCH 091/213] Space changes --- .../openehr/rm/composition/content/entry/Instruction.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 index 325bed59..f905c427 100644 --- 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 @@ -291,9 +291,9 @@ public boolean equals(Object obj) { return true; } - /* fields */ - private DvText narrative; - private List activities; + /* fields */ + private DvText narrative; + private List activities; private DvDateTime expiryTime; private DvParsable wfDefinition; } From 3ae55fa2253792a1c75c70c6a8e60219b4b1862c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Jul 2015 14:05:54 +0200 Subject: [PATCH 092/213] [maven-release-plugin] prepare release ref_impl_java-1.0.13 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 8a7e9861..e38aad01 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13-SNAPSHOT + 1.0.13 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 41e2639c..4d344dc1 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.13-SNAPSHOT + 1.0.13 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 1c0e38a6..844d9b12 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13-SNAPSHOT + 1.0.13 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 1d96a880..e986e0a6 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13-SNAPSHOT + 1.0.13 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index e1ce48db..512d4c8d 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13-SNAPSHOT + 1.0.13 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 814b2690..99de2317 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13-SNAPSHOT + 1.0.13 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index bf3a2ea4..bd459d24 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13-SNAPSHOT + 1.0.13 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 7711cc50..26da2cf6 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13-SNAPSHOT + 1.0.13 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 1d74420a..6c3784d2 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13-SNAPSHOT + 1.0.13 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 0a750d80..296f2030 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13-SNAPSHOT + 1.0.13 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index dec32599..3c0e649c 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13-SNAPSHOT + 1.0.13 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 1fb3dbc9..37923698 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13-SNAPSHOT + 1.0.13 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 8c867eee..8e78ea1c 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.13-SNAPSHOT + 1.0.13 The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - HEAD + ref_impl_java-1.0.13 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 61ff417c..5620d6f6 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13-SNAPSHOT + 1.0.13 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 1fce1d00..ae5aa3c7 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13-SNAPSHOT + 1.0.13 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 00eb46b2..ef8ed2d2 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13-SNAPSHOT + 1.0.13 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 30199b3d..2389a915 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.13-SNAPSHOT + 1.0.13 xml-serializer jar From d77a9e67a5374d82dff923e95b851a003fcfff86 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Jul 2015 14:05:58 +0200 Subject: [PATCH 093/213] [maven-release-plugin] prepare for next development iteration --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index e38aad01..7b8c0d74 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13 + 1.0.14-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 4d344dc1..1522d5d5 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.13 + 1.0.14-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 844d9b12..5e91f7aa 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13 + 1.0.14-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index e986e0a6..cd2213a3 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13 + 1.0.14-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 512d4c8d..95ba67f6 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13 + 1.0.14-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 99de2317..f42489c6 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13 + 1.0.14-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index bd459d24..318a0ced 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13 + 1.0.14-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 26da2cf6..5541d8b2 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13 + 1.0.14-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 6c3784d2..efaa9b62 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13 + 1.0.14-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 296f2030..30fdd038 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13 + 1.0.14-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 3c0e649c..4e174ab5 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13 + 1.0.14-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 37923698..b9a75f7f 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13 + 1.0.14-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 8e78ea1c..5f7849c4 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.13 + 1.0.14-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - ref_impl_java-1.0.13 + HEAD diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 5620d6f6..b1296eeb 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13 + 1.0.14-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index ae5aa3c7..cf8f1340 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13 + 1.0.14-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index ef8ed2d2..23aa0840 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.13 + 1.0.14-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 2389a915..d7142447 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.13 + 1.0.14-SNAPSHOT xml-serializer jar From 321dfb1db3d47574ad832f9160df88940e652ebb Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Thu, 27 Aug 2015 11:51:24 +0200 Subject: [PATCH 094/213] CDS-868 Fix Sonar critical issues on adl-serializer --- .../main/java/org/openehr/am/serialize/ADLSerializer.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) mode change 100644 => 100755 adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java 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 100644 new mode 100755 index af138e25..cb926db3 --- a/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java +++ b/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java @@ -221,9 +221,10 @@ protected void printLanguage(AuthoredResource authored, newline(out); Map translations = authored.getTranslations(); - for(String lang : translations.keySet()) { - TranslationDetails td = translations.get(lang); - + for(Map.Entry entry: translations.entrySet()) { + String lang = entry.getKey(); + TranslationDetails td = entry.getValue(); + indent(2, out); out.write("[\""); out.write(lang); From 05e14652cd47a54725360263ed473b3167a45557 Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Thu, 27 Aug 2015 14:41:41 +0200 Subject: [PATCH 095/213] CDS-868 Fix SonarCube critical issues in adl-serializer, measure-serv, mini-termserv, openehr-aom, openehr-ap, openehr-rm-domain, rm-skeleton, xml-binding and xml-serializer --- .../org/openehr/am/serialize/ADLSerializer.java | 14 +++++++------- .../rm/support/measurement/MeasurementService.java | 8 ++++---- .../measurement/SimpleMeasurementService.java | 2 +- .../terminology/SimpleTerminologyAccess.java | 5 +++-- .../am/archetype/assertion/ExpressionLeaf.java | 4 ++-- .../am/archetype/constraintmodel/CAttribute.java | 5 +++-- .../datatypes/quantity/CDvQuantity.java | 5 +++-- .../org/openehr/rm/composition/Composition.java | 10 +++++----- .../rm/composition/content/entry/Evaluation.java | 3 +++ .../rm/composition/content/entry/Observation.java | 5 ++++- .../org/openehr/rm/util/SkeletonGenerator.java | 13 +++---------- .../main/java/org/openehr/binding/XMLBinding.java | 2 +- .../org/openehr/am/serialize/XMLSerializer.java | 8 ++++---- 13 files changed, 43 insertions(+), 41 deletions(-) mode change 100644 => 100755 measure-serv/src/main/java/org/openehr/rm/support/measurement/MeasurementService.java mode change 100644 => 100755 measure-serv/src/main/java/org/openehr/rm/support/measurement/SimpleMeasurementService.java mode change 100644 => 100755 mini-termserv/src/main/java/org/openehr/terminology/SimpleTerminologyAccess.java mode change 100644 => 100755 openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionLeaf.java mode change 100644 => 100755 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CAttribute.java mode change 100644 => 100755 openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvQuantity.java mode change 100644 => 100755 openehr-rm-domain/src/main/java/org/openehr/rm/composition/Composition.java mode change 100644 => 100755 openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Evaluation.java mode change 100644 => 100755 openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Observation.java mode change 100644 => 100755 rm-skeleton/src/main/java/org/openehr/rm/util/SkeletonGenerator.java mode change 100644 => 100755 xml-binding/src/main/java/org/openehr/binding/XMLBinding.java 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 index cb926db3..c72743c8 100755 --- a/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java +++ b/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java @@ -282,12 +282,12 @@ protected void printMap(Map map, Writer out, int indent) if(map == null || map.size() == 0) { return; } - for(String key : map.keySet()) { + for(Map.Entry entry: map.entrySet()) { indent(indent, out); out.write("[\""); - out.write(key); + out.write(entry.getKey()); out.write("\"] = <\""); - out.write(map.get(key)); + out.write(entry.getValue()); out.write("\">"); newline(out); } @@ -307,9 +307,9 @@ protected void printDescription(ResourceDescription description, Writer out) out.write("original_author = <"); newline(out); Map map = description.getOriginalAuthor(); - for (String key : map.keySet()) { + for (Map.Entry entry: map.entrySet()) { indent(2, out); - out.write("[\"" + key + "\"] = <\"" + map.get(key) + "\">"); + out.write("[\"" + entry.getKey() + "\"] = <\"" + entry.getValue() + "\">"); newline(out); } indent(1, out); @@ -413,9 +413,9 @@ private void printNonEmptyStringMap(String label, Map map, out.write(" = <"); newline(out); - for (String key : map.keySet()) { + for (Map.Entry entry: map.entrySet()) { indent(2, out); - out.write("[\"" + key + "\"] = <\"" + map.get(key) + "\">"); + out.write("[\"" + entry.getKey() + "\"] = <\"" + entry.getValue() + "\">"); newline(out); } 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 old mode 100644 new mode 100755 index 4c8aea2a..ff616f08 --- 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 100644 new mode 100755 index 4e294532..59db611e --- 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 @@ -29,7 +29,7 @@ * @version 1.0 * */ -public class SimpleMeasurementService implements MeasurementService { +public final class SimpleMeasurementService implements MeasurementService { /** * diff --git a/mini-termserv/src/main/java/org/openehr/terminology/SimpleTerminologyAccess.java b/mini-termserv/src/main/java/org/openehr/terminology/SimpleTerminologyAccess.java old mode 100644 new mode 100755 index ffd6b06a..779d8b16 --- 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/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 old mode 100644 new mode 100755 index 3236a149..64da1e6c --- 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/constraintmodel/CAttribute.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CAttribute.java old mode 100644 new mode 100755 index c1154a8b..39675493 --- 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-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 old mode 100644 new mode 100755 index adea374d..4589b90d --- 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-rm-domain/src/main/java/org/openehr/rm/composition/Composition.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/Composition.java old mode 100644 new mode 100755 index 2854eda6..6238cd32 --- 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 @@ -83,6 +83,11 @@ public Composition(@Attribute(name = "uid") UIDBasedID uid, throw new IllegalArgumentException("empty content"); } + if (category == null) { + throw new IllegalArgumentException("null category"); + } + + // Is_persistent_validity: is_persistent implies context = Void if (isPersistent(category) && context != null) { throw new IllegalArgumentException("invalid persistent category"); } @@ -96,11 +101,6 @@ public Composition(@Attribute(name = "uid") UIDBasedID uid, 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) 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 old mode 100644 new mode 100755 index 1d764424..6d8711b3 --- 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 @@ -141,6 +141,9 @@ void setData(ItemStructure data) { @Override public boolean equals(Object obj) { + if(obj == null) { + return false; + } if (this == obj) { return true; } 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 old mode 100644 new mode 100755 index 278ee0bc..59e8190c --- 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 @@ -188,7 +188,10 @@ void setState(History state) { @Override public boolean equals(Object obj) { - if (this == obj) { + if(obj == null) { + return false; + } + if (this == obj) { return true; } if (getClass() != obj.getClass()) { 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 old mode 100644 new mode 100755 index 999f1ee8..fc878312 --- 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()); @@ -701,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) { diff --git a/xml-binding/src/main/java/org/openehr/binding/XMLBinding.java b/xml-binding/src/main/java/org/openehr/binding/XMLBinding.java old mode 100644 new mode 100755 index 5ba90bfd..7d7a640f --- a/xml-binding/src/main/java/org/openehr/binding/XMLBinding.java +++ b/xml-binding/src/main/java/org/openehr/binding/XMLBinding.java @@ -199,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); 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 b6d2fd26..30a68c1f 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 @@ -259,12 +259,12 @@ private void printCodePhrase(CodePhrase cp, Element out) { private void printStringMap(String label, Map map, Element out) { if(map != null && !map.isEmpty()) { - for(String key : map.keySet()) { + for(Map.Entry entry : map.entrySet()) { Element elm = new Element(label, defaultNamespace); out.getChildren().add(elm); - elm.setAttribute("id", key); - if (map.get(key) != null) { - elm.setText(map.get(key)); + elm.setAttribute("id", entry.getKey()); + if (entry.getValue() != null) { + elm.setText(map.get(entry.getValue())); } } } From 3e3e798d615ad10beae3c51fbbb308bbd276ab15 Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Thu, 27 Aug 2015 15:03:26 +0200 Subject: [PATCH 096/213] Add .gitignore to the ref_impl_java project --- .gitignore | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100755 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100755 index 00000000..6da410cc --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +.idea/ +adl-parser/adl-parser.iml +adl-parser/target/ +adl-serializer/adl-serializer.iml +adl-serializer/target/ +archetype-validator/archetype-validator.iml +archetype-validator/target/ +dadl-binding/dadl-binding.iml +dadl-binding/target/ +dadl-binding/tree_2_slots.dadl +dadl-parser/dadl-parser.iml +dadl-parser/target/ +measure-serv/measure-serv.iml +measure-serv/target/ +mini-termserv/mini-termserv.iml +mini-termserv/target/ +oet-parser/oet-parser.iml +oet-parser/target/ +oet-parser/term_map.txt +oet-parser/test_paths.txt +openehr-aom/openehr-aom.iml +openehr-aom/target/ +openehr-ap/openehr-ap.iml +openehr-ap/target/ +openehr-rm-core/openehr-rm-core.iml +openehr-rm-core/target/ +openehr-rm-domain/openehr-rm-domain.iml +openehr-rm-domain/target/ +ref_impl_java.iml +rm-builder/rm-builder.iml +rm-builder/target/ +rm-skeleton/hypersensitivity_max.dadl +rm-skeleton/hypersensitivity_min.dadl +rm-skeleton/rm-skeleton.iml +rm-skeleton/target/ +target/ +xml-binding/target/ +xml-binding/xml-binding.iml +xml-serializer/target/ +xml-serializer/xml-serializer.iml \ No newline at end of file From a93dc821bdc99def2bd752b11334ada1ddea3018 Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Thu, 27 Aug 2015 17:58:04 +0200 Subject: [PATCH 097/213] CDS-868 Fix SonarCube critical issues on adl-serializer, oet-parser, openehr-rm-core, rm-builder and xml-binding --- .../openehr/am/serialize/ADLSerializer.java | 27 ++++++++------- .../org/openehr/am/template/Flattener.java | 24 +++++--------- .../java/org/openehr/am/template/PathMap.java | 5 +-- .../java/org/openehr/am/template/TermMap.java | 30 ++++++++--------- .../datatypes/quantity/datetime/DvDate.java | 10 ++++++ .../quantity/datetime/DvDateTime.java | 17 ++++++---- .../datatypes/quantity/datetime/DvTime.java | 23 +++++++------ .../org/openehr/build/RMObjectBuilder.java | 33 ++++++++++--------- .../java/org/openehr/binding/RMInspector.java | 33 +++---------------- 9 files changed, 90 insertions(+), 112 deletions(-) mode change 100644 => 100755 oet-parser/src/main/java/org/openehr/am/template/Flattener.java mode change 100644 => 100755 oet-parser/src/main/java/org/openehr/am/template/PathMap.java mode change 100644 => 100755 oet-parser/src/main/java/org/openehr/am/template/TermMap.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDate.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTime.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvTime.java mode change 100644 => 100755 rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java mode change 100644 => 100755 xml-binding/src/main/java/org/openehr/binding/RMInspector.java 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 index c72743c8..a8049ff0 100755 --- a/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java +++ b/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java @@ -477,21 +477,20 @@ protected void printOccurrences(Interval occurrences, Writer out) 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("}"); + + 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, 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 old mode 100644 new mode 100755 index 7a7421e6..a9db2108 --- 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; 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 old mode 100644 new mode 100755 index e04927be..2d424055 --- 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 old mode 100644 new mode 100755 index 43ff7eb4..da10b53b --- 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/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 old mode 100644 new mode 100755 index a498086a..6d9c68f9 --- 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; @@ -222,6 +223,7 @@ public boolean isStrictlyComparableTo(DvOrdered ordered) { return false; } + @Override public boolean equals(Object o) { if (!super.equals(o)) return false; @@ -235,6 +237,14 @@ 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. 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 old mode 100644 new mode 100755 index efdee72c..e9416363 --- 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; @@ -305,12 +306,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,6 +321,15 @@ 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) { 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 old mode 100644 new mode 100755 index 3545ed07..2d103b24 --- 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 @@ -15,6 +15,7 @@ package org.openehr.rm.datatypes.quantity.datetime; 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; @@ -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,6 +284,15 @@ 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) { diff --git a/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java b/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java old mode 100644 new mode 100755 index 4533f469..73359a19 --- a/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java +++ b/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java @@ -339,8 +339,8 @@ public RMObject construct(String rmClassName, 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); Map typeMap = attributeType(rmClass); @@ -348,7 +348,8 @@ public RMObject construct(String rmClassName, Map valueMap) Map attributeMap = attributeMap(rmClass); Object[] valueArray = new Object[indexMap.size()]; - for (String name : typeMap.keySet()) { + for (Map.Entry entry : typeMap.entrySet()) { + String name = entry.getKey(); Object value = filteredMap.get(name); @@ -356,7 +357,7 @@ public RMObject construct(String rmClassName, Map valueMap) throw new RMObjectBuildingException("unknown attribute " + name); } - Class type = typeMap.get(name); + Class type = entry.getValue(); Integer index = indexMap.get(name); Attribute attribute = attributeMap.get(name); @@ -417,7 +418,7 @@ else if (value instanceof String) { // for DvProportion.precision } else if (type.equals(Integer.class)) { - value = new Integer(str); + value = Integer.valueOf(str); // for DvBoolean.value } else if (type.equals(boolean.class)) { @@ -451,7 +452,7 @@ else if (value instanceof String) { value = set; } // check type - else if (value != null && !type.isPrimitive()) { + else if (!type.isPrimitive()) { try { type.cast(value); } catch (ClassCastException e) { @@ -503,10 +504,10 @@ else if (value != null && value.getClass().equals(Long.class)) private String toString(Map map) { StringBuffer buf = new StringBuffer(); - for (String key : map.keySet()) { - buf.append(key); + for (Map.Entry entry : map.entrySet()) { + buf.append(entry.getKey()); buf.append("="); - Object value = map.get(key); + Object value = entry.getValue(); if (value != null) { buf.append(value.getClass().getName()); buf.append(":"); @@ -607,8 +608,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); @@ -694,15 +695,15 @@ private Object defaultValue(Class type) { } else if (type == float.class) { return new Float(0); } else if (type == int.class) { - return new Integer(0); + return Integer.valueOf(0); } else if (type == short.class) { - return new Short((short) 0); + return Short.valueOf((short) 0); } else if (type == long.class) { - return new Long(0); + return Long.valueOf(0); } else if (type == char.class) { - return new Character((char) 0); + return Character.valueOf((char) 0); } else if (type == byte.class) { - return new Byte((byte) 0); + return Byte.valueOf((byte) 0); } return null; } diff --git a/xml-binding/src/main/java/org/openehr/binding/RMInspector.java b/xml-binding/src/main/java/org/openehr/binding/RMInspector.java old mode 100644 new mode 100755 index 8bfdb086..95c9a884 --- 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 From 7213c9d2dbe820e4ae2f9182f994d3f5565c42bf Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Thu, 27 Aug 2015 19:55:44 +0200 Subject: [PATCH 098/213] CDS-868 Fix SonarCube critical issues on archetype-validator, dadl-binding and openehr-rm-core --- .../am/validation/ArchetypeValidator.java | 9 +++-- .../openehr/am/validation/RMInspector.java | 35 +++--------------- .../SpecialisedArchetypeValidator.java | 15 ++++---- .../org/openehr/rm/binding/DADLBinding.java | 10 ++--- .../org/openehr/rm/binding/RMInspector.java | 34 +++-------------- .../org/openehr/rm/binding/XPathUtil.java | 37 ++++++------------- .../src/test/resources/log4j.properties | 4 +- .../rm/common/archetyped/Locatable.java | 9 +++-- .../common/changecontrol/VersionedObject.java | 31 ++++++++-------- .../datastructure/itemstructure/ItemList.java | 3 ++ .../itemstructure/ItemSingle.java | 4 ++ .../itemstructure/ItemTable.java | 6 ++- .../datastructure/itemstructure/ItemTree.java | 4 ++ .../itemstructure/representation/Cluster.java | 4 ++ .../rm/datatypes/quantity/DvCount.java | 2 +- .../datatypes/quantity/datetime/DvDate.java | 10 ++--- .../quantity/datetime/DvDateTime.java | 10 ++--- .../quantity/datetime/DvDateTimeParser.java | 3 +- .../quantity/datetime/DvDuration.java | 1 - .../datatypes/quantity/datetime/DvTime.java | 10 ++--- 20 files changed, 94 insertions(+), 147 deletions(-) mode change 100644 => 100755 archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java mode change 100644 => 100755 archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java mode change 100644 => 100755 dadl-binding/src/main/java/org/openehr/rm/binding/DADLBinding.java mode change 100644 => 100755 dadl-binding/src/main/java/org/openehr/rm/binding/RMInspector.java mode change 100644 => 100755 dadl-binding/src/test/resources/log4j.properties mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/VersionedObject.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemList.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemSingle.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemTable.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemTree.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/representation/Cluster.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvCount.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeParser.java 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 old mode 100644 new mode 100755 index 79e749c5..b3c4eb06 --- a/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java @@ -878,13 +878,14 @@ private void validateCCodePhrase(CCodePhrase ccodephrase, ccodephrase.getTerminologyId().toString())) { return; } - String codes = ""; + StringBuffer buf = new StringBuffer(); for(String code : ccodephrase.getCodeList()) { if( ! openEHRTerminology.allCodes().contains( new CodePhrase(TerminologyService.OPENEHR, code))) { - codes += code + ", "; + buf.append(code + ", "); } } + String codes = buf.toString(); if(codes.length() != 0) { ValidationError error = new ValidationError(ErrorType.VOTC, null, codes, ccodephrase.path()); @@ -893,7 +894,7 @@ private void validateCCodePhrase(CCodePhrase ccodephrase, } /** - * @param cobj + * @param cpobj * @param archetype * @param errors */ @@ -1490,7 +1491,7 @@ protected String getIntervalFormalString(Interval interval) { protected String getIntervalFormalString(Integer lower, Integer upper, boolean isUpperUnbounded) { if (lower == null) { - lower = new Integer(0); + lower = Integer.valueOf(0); } String formal= ""+lower.intValue() +".."; 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 index 7afbcb0f..37445cd7 100755 --- a/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java @@ -318,7 +318,6 @@ public Class retrieveRMType(String rmClassName) { * * @param rmClassName * @return - * @throws RMObjectBuildingException */ public Map retrieveRMAttributes(String rmClassName) { Class rmClass = retrieveRMType(rmClassName); @@ -329,10 +328,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; } @@ -343,7 +343,6 @@ public Map retrieveRMAttributes(String rmClassName) { * * @param rmClassName * @return - * @throws RMObjectBuildingException */ public Set retrieveRMAttributeNames(String rmClassName) { Class rmClass = retrieveRMType(rmClassName); @@ -411,8 +410,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); @@ -489,28 +488,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; - } - /** 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, 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 old mode 100644 new mode 100755 index e7aa9dfb..7d6a1f8e --- a/archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java @@ -209,9 +209,7 @@ private void checkSpecialisedAttribute(CAttribute cattr, Archetype archetype, if (parentNodeInParentArchetype == null) { log.debug("PARENT NODE IN PARENT ARCHETYPE IS NULL"); - } - - if (parentNodeInParentArchetype instanceof CComplexObject) { + } else 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? @@ -608,10 +606,11 @@ private void checkSpecialisedRMTypeCompatiblityOfValueChildren(CAttribute cattr, if (!assignable) { log.debug("VSONCT error: at "+child.path()); - String parentRefTypes = ""; + StringBuffer buf = new StringBuffer(); for (Entry parentToRMTypeWithoutGenerics: parentObjectsToRMTypesWithoutGenerics.entrySet()) { - parentRefTypes += parentToRMTypeWithoutGenerics.getValue().getSimpleName() +", "; + buf.append(parentToRMTypeWithoutGenerics.getValue().getSimpleName() +", "); } + String parentRefTypes = buf.toString(); parentRefTypes = parentRefTypes.substring(0,parentRefTypes.length()-2); if (parentObjectsToRMTypesWithoutGenerics.size() ==1) { @@ -674,6 +673,7 @@ private String getExpectedPathInParentArchetype(String path, int parentArchetype 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))); + StringBuffer buffer = new StringBuffer(expectedPath); for (String pathPart : pathParts) { String pathEnd = ""; @@ -691,11 +691,12 @@ private String getExpectedPathInParentArchetype(String path, int parentArchetype 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); + log.debug("Path ends with at0: "+ pathPart +" "+ buffer.toString()); return null; } - expectedPath += pathPart + pathEnd+sep; + buffer.append(pathPart + pathEnd+sep); } + expectedPath = buffer.toString(); if (expectedPath.length() >1 && expectedPath.endsWith(sep)) { expectedPath = expectedPath.substring(0,expectedPath.length()-1); // get rid of tailing separator } 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 old mode 100644 new mode 100755 index 025803ef..db2dba0c --- 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/RMInspector.java b/dadl-binding/src/main/java/org/openehr/rm/binding/RMInspector.java old mode 100644 new mode 100755 index 84e72fa0..6dcd6326 --- a/dadl-binding/src/main/java/org/openehr/rm/binding/RMInspector.java +++ b/dadl-binding/src/main/java/org/openehr/rm/binding/RMInspector.java @@ -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 1d2c53a8..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 @@ -38,10 +38,10 @@ private void buildPath(Object obj, String path, Set paths) throws Except inspector.retrieveRMAttributes(obj.getClass().getSimpleName()); Class klass = obj.getClass(); - String className = klass.getSimpleName(); Map attributeMap = inspector.attributeMap(klass); - for(String attributeName : attributeMap.keySet()) { - Attribute attribute = attributeMap.get(attributeName); + for(Map.Entry entry : attributeMap.entrySet()) { + String attributeName = entry.getKey(); + Attribute attribute = entry.getValue(); if(attribute.system()) { continue; @@ -78,9 +78,9 @@ private void buildPaths(Object obj, String apath, String xpath, Map>> className: " + className); - Map attributeMap = inspector.attributeMap(klass); - for(String attributeName : attributeMap.keySet()) { - - //System.out.println("Attribute name: " + attributeName); - Attribute attribute = attributeMap.get(attributeName); + for(Map.Entry entry : attributeMap.entrySet()) { + String attributeName = entry.getKey(); + Attribute attribute = entry.getValue(); if(attribute.system()) { continue; @@ -125,8 +120,6 @@ private void buildPaths(Object obj, String apath, String xpath, Map "+currentAPath); buildPaths(value, currentAPath, currentXPath, paths); } } - } else { - //System.out.println("---- skip class: " + obj.getClass().getSimpleName()); } } @@ -168,8 +157,6 @@ public Set extractRootXPaths(Locatable root) throws Exception { 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 paths) throws Ex } inspector.retrieveRMAttributes(obj.getClass().getSimpleName()); Class klass = obj.getClass(); - String className = klass.getSimpleName(); Map attributeMap = inspector.attributeMap(klass); - for(String attributeName : attributeMap.keySet()) { - Attribute attribute = attributeMap.get(attributeName); + for(Map.Entry entry : attributeMap.entrySet()) { + String attributeName = entry.getKey(); + Attribute attribute = entry.getValue(); if(attribute.system()) { continue; // skip system attributes diff --git a/dadl-binding/src/test/resources/log4j.properties b/dadl-binding/src/test/resources/log4j.properties old mode 100644 new mode 100755 index b67fb578..0b885667 --- 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/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 eb8c4f41..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 @@ -185,9 +185,11 @@ public static List dividePathIntoSegments(String path) { StringTokenizer tokens = new StringTokenizer(path, "/"); while(tokens.hasMoreTokens()) { String next = tokens.nextToken(); + StringBuffer buffer = new StringBuffer(); if (next.matches(".+\\[.+[^\\]]$")) { do { - next = next + "/" + tokens.nextToken(); + buffer.append(next + "/" + tokens.nextToken()); + next = buffer.toString(); } while (!next.matches(".*]$")); } segments.add(next); @@ -282,7 +284,6 @@ public String toFirstUpperCaseCamelCase(String name) { * for example: [at0001, 'node name'] * * @param expression - * @param value * @return null if there is no match */ Object processPredicate(String expression, Object object) { @@ -361,7 +362,7 @@ 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; @@ -565,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; } 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 old mode 100644 new mode 100755 index 0a2c178c..0495dd61 --- 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/datastructure/itemstructure/ItemList.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemList.java old mode 100644 new mode 100755 index c4d0b76d..dacbfe42 --- 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 @@ -170,6 +170,9 @@ public int hashCode() { @Override public boolean equals(Object obj) { + if(obj == null) { + return false; + } if (this == obj) { return true; } 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 old mode 100644 new mode 100755 index 5dce1fdb..b15918df --- 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 @@ -147,6 +147,10 @@ public int hashCode() { @Override public boolean equals(Object obj) { + if(obj == null) { + return false; + } + if (this == obj) { return true; } 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 old mode 100644 new mode 100755 index 1afc9fbe..d3e56336 --- 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 @@ -366,7 +366,11 @@ public int hashCode() { @Override //Generated by Eclipse public boolean equals(Object obj) { - if (this == obj) + if(obj == null) { + return false; + } + + if (this == obj) return true; if (getClass() != obj.getClass()) return false; 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 old mode 100644 new mode 100755 index 66c264c9..cb7c65ac --- 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 @@ -129,6 +129,10 @@ public List getItems() { * @return equals if true */ public boolean equals(Object obj) { + if(obj == null) { + return false; + } + if (this == obj) { return true; } 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 old mode 100644 new mode 100755 index 44ee3781..892933bc --- 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 @@ -157,6 +157,10 @@ public int hashCode() { @Override public boolean equals(Object obj) { + if(obj == null) { + return false; + } + if (this == obj) { return true; } 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 old mode 100644 new mode 100755 index e0d6b536..27e42530 --- 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); } /** 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 6d9c68f9..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 @@ -251,14 +251,10 @@ public int hashCode() { */ 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 e9416363..70454084 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 @@ -332,14 +332,10 @@ public int 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 old mode 100644 new mode 100755 index 15d24129..2c6052e9 --- 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 88afcef1..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 @@ -160,7 +160,6 @@ protected DvDuration(List> referenceRanges, */ 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())); } 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 2d103b24..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 @@ -295,14 +295,10 @@ public int 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; } From 8ad179f48c7e1d8dafe5eb8e3ba4d830943b0c52 Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Fri, 28 Aug 2015 08:32:32 +0200 Subject: [PATCH 099/213] Fix unnecessary output in unit tests within rm-builder --- rm-builder/src/main/resources/log4j.properties | 4 ++-- .../java/org/openehr/build/DataTypesBuildTest.java | 11 ++++------- 2 files changed, 6 insertions(+), 9 deletions(-) mode change 100644 => 100755 rm-builder/src/main/resources/log4j.properties mode change 100644 => 100755 rm-builder/src/test/java/org/openehr/build/DataTypesBuildTest.java diff --git a/rm-builder/src/main/resources/log4j.properties b/rm-builder/src/main/resources/log4j.properties old mode 100644 new mode 100755 index ebb694fb..969642f8 --- 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/DataTypesBuildTest.java b/rm-builder/src/test/java/org/openehr/build/DataTypesBuildTest.java old mode 100644 new mode 100755 index bcf62401..f8e905e9 --- a/rm-builder/src/test/java/org/openehr/build/DataTypesBuildTest.java +++ b/rm-builder/src/test/java/org/openehr/build/DataTypesBuildTest.java @@ -181,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; @@ -199,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); @@ -226,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); From e202bb59b6f8df500d4b16335d27f8a8dc70e837 Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Fri, 4 Sep 2015 16:01:19 +0200 Subject: [PATCH 100/213] Correct xml-serialisation of UID. Update archetype-validator source to 1.7 --- archetype-validator/pom.xml | 4 ++-- .../java/org/openehr/am/serialize/XMLSerializer.java | 10 +++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 5e91f7aa..6a32525d 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -24,8 +24,8 @@ org.apache.maven.plugins maven-compiler-plugin - 1.5 - 1.5 + 1.7 + 1.7 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 b6d2fd26..07fbd552 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 @@ -155,14 +155,18 @@ protected void printHeader(Archetype archetype, Element 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); - if (archetype.getUid() != null) { - printString("uid", archetype.getUid().toString(), out); - } + printString("concept", archetype.getConcept(), out); From 38885fef2874023ae3c3d69f4f8b2aba185465bc Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Fri, 11 Sep 2015 16:59:36 +0200 Subject: [PATCH 101/213] Updating to use css-cds-3 repo --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 pom.xml diff --git a/pom.xml b/pom.xml old mode 100644 new mode 100755 index 5f7849c4..9ec62cd9 --- a/pom.xml +++ b/pom.xml @@ -110,12 +110,12 @@ repo.cambio.se_releases releases - http://repo.cambio.se/content/repositories/releases + http://css-cds-3:8081/nexus/content/repositories/releases repo.cambio.se_snapshots snapshots - http://repo.cambio.se/content/repositories/snapshots + http://css-cds-3:8081/nexus/content/repositories/snapshots From d569f925abd48cfdd2f729720a376724469db08a Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Mon, 19 Oct 2015 10:31:46 +0200 Subject: [PATCH 102/213] Simplifying gitignore --- .gitignore | 36 ++---------------------------------- 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/.gitignore b/.gitignore index 6da410cc..1135625c 100755 --- a/.gitignore +++ b/.gitignore @@ -1,40 +1,8 @@ .idea/ -adl-parser/adl-parser.iml -adl-parser/target/ -adl-serializer/adl-serializer.iml -adl-serializer/target/ -archetype-validator/archetype-validator.iml -archetype-validator/target/ -dadl-binding/dadl-binding.iml -dadl-binding/target/ +*.iml +target dadl-binding/tree_2_slots.dadl -dadl-parser/dadl-parser.iml -dadl-parser/target/ -measure-serv/measure-serv.iml -measure-serv/target/ -mini-termserv/mini-termserv.iml -mini-termserv/target/ -oet-parser/oet-parser.iml -oet-parser/target/ oet-parser/term_map.txt oet-parser/test_paths.txt -openehr-aom/openehr-aom.iml -openehr-aom/target/ -openehr-ap/openehr-ap.iml -openehr-ap/target/ -openehr-rm-core/openehr-rm-core.iml -openehr-rm-core/target/ -openehr-rm-domain/openehr-rm-domain.iml -openehr-rm-domain/target/ -ref_impl_java.iml -rm-builder/rm-builder.iml -rm-builder/target/ rm-skeleton/hypersensitivity_max.dadl rm-skeleton/hypersensitivity_min.dadl -rm-skeleton/rm-skeleton.iml -rm-skeleton/target/ -target/ -xml-binding/target/ -xml-binding/xml-binding.iml -xml-serializer/target/ -xml-serializer/xml-serializer.iml \ No newline at end of file From 2ae51145aa143096adac4e4fa930d07d9d66b0f0 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Oct 2015 10:47:53 +0200 Subject: [PATCH 103/213] [maven-release-plugin] prepare release ref_impl_java-1.0.14 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 7b8c0d74..92b215b9 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 1522d5d5..cf55acfe 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 5e91f7aa..07280b47 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index cd2213a3..9fc9f17a 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 95ba67f6..5b6e0946 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index f42489c6..3251c00d 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 318a0ced..f6821d80 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 5541d8b2..1e876fa6 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index efaa9b62..8e30a6d2 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 30fdd038..7b4610e1 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 4e174ab5..097a890f 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index b9a75f7f..d15c0cd3 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 9ec62cd9..86e8d6b0 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.14-SNAPSHOT + 1.0.14 The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - HEAD + ref_impl_java-1.0.14 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index b1296eeb..0d736efb 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index cf8f1340..e9c2e23c 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 23aa0840..3fa570eb 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index d7142447..4e42f6b4 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 xml-serializer jar From 2c59534f012301f4ed97d60b89310acf6b717ebd Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Oct 2015 10:48:02 +0200 Subject: [PATCH 104/213] [maven-release-plugin] prepare for next development iteration --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 92b215b9..cb853c20 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index cf55acfe..57c4842a 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 07280b47..65f11769 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 9fc9f17a..eb6d5017 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 5b6e0946..5e33de4a 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 3251c00d..51f66e44 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index f6821d80..feb63190 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 1e876fa6..ca727aa1 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 8e30a6d2..18bb7ae8 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 7b4610e1..8e044377 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 097a890f..f79fca81 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index d15c0cd3..36566fc2 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 86e8d6b0..34fef468 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.14 + 1.0.15-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - ref_impl_java-1.0.14 + HEAD diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 0d736efb..47243de4 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index e9c2e23c..405f8bf8 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 3fa570eb..94aad897 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 4e42f6b4..b819f977 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT xml-serializer jar From 48b476cda447ab7cc948ee5e02336d2260677b9e Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Mon, 19 Oct 2015 11:23:26 +0200 Subject: [PATCH 105/213] Providing a fix for the release issue --- pom.xml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 34fef468..c8d30958 100755 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,23 @@ - + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + openehr-rm-core openehr-rm-domain From e67145ff8035b79d876d962fa9b0bc28d3be5181 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Oct 2015 11:45:20 +0200 Subject: [PATCH 106/213] [maven-release-plugin] prepare release ref_impl_java-1.0.15 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index cb853c20..aff68468 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 57c4842a..e6695574 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 65f11769..f1846126 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index eb6d5017..724701b3 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 5e33de4a..530c6abd 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 51f66e44..aa8e5135 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index feb63190..fdec44ae 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index ca727aa1..02419359 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 18bb7ae8..d4194eb5 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 8e044377..774209f7 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index f79fca81..f29d9dc5 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 36566fc2..521c7b83 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index c8d30958..76d1abd4 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.15-SNAPSHOT + 1.0.15 The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - HEAD + ref_impl_java-1.0.15 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 47243de4..fcec5913 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 405f8bf8..64112f1f 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 94aad897..75bb16ef 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index b819f977..8b4923c0 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 xml-serializer jar From b173251c1c8ce76b3a8ede01ed975669f4b97435 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Oct 2015 11:45:29 +0200 Subject: [PATCH 107/213] [maven-release-plugin] prepare for next development iteration --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index aff68468..330f2dec 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index e6695574..576478ac 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index f1846126..5f609b1e 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 724701b3..efe3b8dd 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 530c6abd..ccc99314 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index aa8e5135..cb4dd474 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index fdec44ae..d8e8be1e 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 02419359..bcf1fa40 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index d4194eb5..b70bf8ff 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 774209f7..28b05320 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index f29d9dc5..85bebf48 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 521c7b83..52a47358 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 76d1abd4..eb530dec 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.15 + 1.0.16-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - ref_impl_java-1.0.15 + HEAD diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index fcec5913..dd89d7dc 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 64112f1f..976157b6 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 75bb16ef..4392b913 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 8b4923c0..7453c711 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT xml-serializer jar From 29db841bdc26591b3abd1b4fccba1cfd5c94e11e Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Mon, 19 Oct 2015 12:19:43 +0200 Subject: [PATCH 108/213] Updating the sources plugin --- pom.xml | 36 ++++++++++-------------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/pom.xml b/pom.xml index eb530dec..6b74456a 100755 --- a/pom.xml +++ b/pom.xml @@ -75,34 +75,18 @@ - maven-source-plugin - 2.1.2 - - - attach-sources - - jar-no-fork - - - - - - - - - org.apache.maven.plugins - maven-source-plugin - + maven-source-plugin + 2.4 + - attach-sources - - jar - + attach-sources + + jar-no-fork + - - - - + + + openehr-rm-core From 914e0325ad70f83a49a938484cba4de271f94dcc Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Mon, 19 Oct 2015 13:02:17 +0200 Subject: [PATCH 109/213] Removing the jar-no-fork to avoid problems when releasing sources --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6b74456a..72e355e7 100755 --- a/pom.xml +++ b/pom.xml @@ -81,7 +81,7 @@ attach-sources - jar-no-fork + jar From d281ee486dc9aae30aa09627b390883d0e03dc58 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Oct 2015 13:09:10 +0200 Subject: [PATCH 110/213] [maven-release-plugin] prepare release ref_impl_java-1.0.16 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 330f2dec..2f2b8bd7 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 576478ac..7eac42f8 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 5f609b1e..58a29f64 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index efe3b8dd..ba2dbf9e 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index ccc99314..3fbcc7c8 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index cb4dd474..88a07380 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index d8e8be1e..2733944b 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index bcf1fa40..c962059f 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index b70bf8ff..1365b5fd 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 28b05320..14391780 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 85bebf48..d5c3dc01 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 52a47358..aaf5a00a 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 72e355e7..f70bc830 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.16-SNAPSHOT + 1.0.16 The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - HEAD + ref_impl_java-1.0.16 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index dd89d7dc..1c263879 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 976157b6..b9e2e651 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 4392b913..87dec210 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 7453c711..5c586555 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 xml-serializer jar From 2705d9eae08db6975efcf9f27d3d7913688bbb62 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Oct 2015 13:09:19 +0200 Subject: [PATCH 111/213] [maven-release-plugin] prepare for next development iteration --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 2f2b8bd7..bb677901 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 7eac42f8..2d4d737f 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 58a29f64..e08d6dd2 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index ba2dbf9e..9cdc7577 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 3fbcc7c8..2e7eacdf 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 88a07380..2ef3f32f 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 2733944b..9ac20a68 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index c962059f..9e5c1178 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 1365b5fd..04ea4532 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 14391780..731b01ce 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index d5c3dc01..4b235567 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index aaf5a00a..5ae1c064 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index f70bc830..df89a255 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.16 + 1.0.17-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - ref_impl_java-1.0.16 + HEAD diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 1c263879..cd448d7d 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index b9e2e651..3db7bed9 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 87dec210..af85ce2f 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 5c586555..30643d10 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT xml-serializer jar From e56b87b8175ed0faa2bab7266e292c6100009f9b Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Oct 2015 13:43:35 +0200 Subject: [PATCH 112/213] [maven-release-plugin] prepare release ref_impl_java-1.0.17 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index bb677901..e2a5490c 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 2d4d737f..d68f82cd 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index e08d6dd2..7d9d531c 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 9cdc7577..af6bde74 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 2e7eacdf..ff3e0ccf 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 2ef3f32f..8940bf6c 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 9ac20a68..b976d69d 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 9e5c1178..ab5e7324 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 04ea4532..46625752 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 731b01ce..fea588ad 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 4b235567..5c4f9634 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 5ae1c064..9b7c2e44 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index df89a255..fb851336 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.17-SNAPSHOT + 1.0.17 The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - HEAD + ref_impl_java-1.0.17 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index cd448d7d..c25c0198 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 3db7bed9..a12a5586 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index af85ce2f..4eaa2d69 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 30643d10..79716013 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 xml-serializer jar From 3b8185af11299c21f7749a0a3873abf2944f867b Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Oct 2015 13:43:44 +0200 Subject: [PATCH 113/213] [maven-release-plugin] prepare for next development iteration --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index e2a5490c..0c4fe06d 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index d68f82cd..a40a0473 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 7d9d531c..94bf3767 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index af6bde74..fe60a7dd 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index ff3e0ccf..79240a4e 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 8940bf6c..743e9e35 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index b976d69d..1ac90c2b 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index ab5e7324..96ea6eb3 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 46625752..1633e0ef 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index fea588ad..b58a52fb 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 5c4f9634..d90363ea 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 9b7c2e44..7c6ed97f 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index fb851336..ada0070b 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.17 + 1.0.18-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - ref_impl_java-1.0.17 + HEAD diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index c25c0198..2d012f4f 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index a12a5586..8dfd8e8f 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 4eaa2d69..e4ebedd5 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 79716013..15a179a7 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT xml-serializer jar From ca3e32d4e59dd3438e9003098d1bde28a4fb6224 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Mon, 19 Oct 2015 13:50:05 +0200 Subject: [PATCH 114/213] Fixing issue with the forked execution --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ada0070b..adb3e566 100755 --- a/pom.xml +++ b/pom.xml @@ -80,8 +80,9 @@ attach-sources + verify - jar + jar-no-fork From 90fcc5f9bb54343f73659a532fd027a6e450d938 Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Thu, 19 Nov 2015 13:29:57 +0100 Subject: [PATCH 115/213] Change DvOrdinal.list from Set to List; Verify duplicated int values are supported by CDVOrdinal and ADL parsing --- .gitignore | 1 + adl-parser/src/main/javacc/adl.jj | 2 +- .../acode/openehr/parser/CDvOrdinalTest.java | 45 ++++++++++++------- .../adl-test-entry.c_dv_ordinal.test.adl | 12 ++++- .../openehr/am/serialize/CDvOrdinalTest.java | 11 ++--- .../am/validation/ArchetypeValidator.java | 10 ++--- .../datatypes/quantity/CDvOrdinal.java | 23 ++++------ .../datatypes/quantity/CDvOrdinalTest.java | 10 ++--- .../openehr/rm/util/SkeletonGenerator.java | 2 +- .../openehr/am/serialize/XMLSerializer.java | 2 +- 10 files changed, 66 insertions(+), 52 deletions(-) mode change 100644 => 100755 adl-parser/src/test/java/se/acode/openehr/parser/CDvOrdinalTest.java mode change 100644 => 100755 adl-parser/src/test/resources/adl-test-entry.c_dv_ordinal.test.adl mode change 100644 => 100755 adl-serializer/src/test/java/org/openehr/am/serialize/CDvOrdinalTest.java mode change 100644 => 100755 openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvOrdinal.java mode change 100644 => 100755 openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvOrdinalTest.java diff --git a/.gitignore b/.gitignore index 1135625c..e1526075 100755 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ 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/adl-parser/src/main/javacc/adl.jj b/adl-parser/src/main/javacc/adl.jj index 0404c63e..885472ef 100755 --- a/adl-parser/src/main/javacc/adl.jj +++ b/adl-parser/src/main/javacc/adl.jj @@ -2814,7 +2814,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; 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 old mode 100644 new mode 100755 index 3da83dbd..78d0efe3 --- 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/resources/adl-test-entry.c_dv_ordinal.test.adl b/adl-parser/src/test/resources/adl-test-entry.c_dv_ordinal.test.adl old mode 100644 new mode 100755 index 1c2761fd..8e0abec5 --- 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-serializer/src/test/java/org/openehr/am/serialize/CDvOrdinalTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/CDvOrdinalTest.java old mode 100644 new mode 100755 index 74d79657..82ef53eb --- 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/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java index b3c4eb06..94f9dc9f 100755 --- a/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java @@ -119,7 +119,7 @@ public final void setReportConstraintsOnCommonFunctionalPropertiesAsInfo( * Validates the given archetype * * @param archetype - * @param reportConstraintsOnFunctionalPropertiesAsInfo 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. + * @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 */ @@ -725,7 +725,7 @@ private void checkCardinalityConformsToRMCardinality(CMultipleAttribute cattr, C /** Checks the assertions of an archetype for validity - * @param cobj + * @param slot * @param rmAttrType * @param archetype * @param errors @@ -840,7 +840,7 @@ private void checkOneArchetypeId(ArchetypeSlot slot, List error * * TODO: does not report a problem on values that have a higher precision than specified * - * @param cobj + * @param cdtobj * @param archetype * @param errors */ @@ -1407,7 +1407,7 @@ void fetchATCodes(CObject cobj, Set codes) { } } else if(cobj instanceof CDvOrdinal) { CDvOrdinal cord = (CDvOrdinal) cobj; - Set list = cord.getList(); + List list = cord.getList(); if(list != null) { for(Ordinal ord : list) { CodePhrase code = ord.getSymbol(); @@ -1479,7 +1479,7 @@ void fetchACCodes(CObject cobj, Set codes) { } /** Constructs a formal String for representing this Interval - * @param Interval + * @param interval * @return */ protected String getIntervalFormalString(Interval interval) { 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 old mode 100644 new mode 100755 index 23cca8f7..ced92cb4 --- 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/test/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvOrdinalTest.java b/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvOrdinalTest.java old mode 100644 new mode 100755 index 8e797e54..0e0612e3 --- 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/rm-skeleton/src/main/java/org/openehr/rm/util/SkeletonGenerator.java b/rm-skeleton/src/main/java/org/openehr/rm/util/SkeletonGenerator.java index fc878312..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 @@ -777,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/xml-serializer/src/main/java/org/openehr/am/serialize/XMLSerializer.java b/xml-serializer/src/main/java/org/openehr/am/serialize/XMLSerializer.java index 30a68c1f..6ff2e089 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 @@ -652,7 +652,7 @@ protected void printCDvOrdinal(CDvOrdinal cordinal, Element out) { } if(cordinal.getList() != null) { - final Set ordinals = cordinal.getList(); + final List ordinals = cordinal.getList(); Ordinal ordinal; for (Iterator it = ordinals.iterator(); it.hasNext();) { From e91e1ef642c3d59c5398a1098c2ba70dc2f0341c Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Wed, 25 Nov 2015 07:52:37 +0100 Subject: [PATCH 116/213] Minor changes in javadoc and parameter naming --- .../java/org/openehr/rm/datatypes/quantity/DvOrdered.java | 2 +- .../java/org/openehr/rm/datatypes/quantity/DvOrdinal.java | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvOrdered.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvOrdinal.java 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 old mode 100644 new mode 100755 index 00451b23..c8a92d4c --- 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 old mode 100644 new mode 100755 index f670b5e8..95f537ba --- 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 @@ -93,11 +93,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)); } /** From c04465aec0cdc72aa9b0ce6e97a7c31278a6c880 Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Mon, 30 Nov 2015 13:24:47 +0100 Subject: [PATCH 117/213] Remove unnecessary comment in testcase --- .../org/openehr/rm/datatypes/quantity/DvOrdinalTest.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) mode change 100644 => 100755 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvOrdinalTest.java 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 old mode 100644 new mode 100755 index ca711db6..1d4f6f7e --- 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); From 3069e981dcae82748ac95b063cb5ae0847823131 Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Fri, 6 May 2016 19:22:52 +0200 Subject: [PATCH 118/213] Add DvCodedText.valueOf() --- .../rm/datatypes/text/DvCodedText.java | 22 +++++++++++-------- .../rm/datatypes/text/DvCodedTextTest.java | 6 +++++ 2 files changed, 19 insertions(+), 9 deletions(-) mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvCodedText.java mode change 100644 => 100755 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/text/DvCodedTextTest.java 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 old mode 100644 new mode 100755 index a83bc762..553c7f7b --- 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/test/java/org/openehr/rm/datatypes/text/DvCodedTextTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/text/DvCodedTextTest.java old mode 100644 new mode 100755 index a03962b1..c059dc5d --- 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 From 4e8af6e60864b30ee1ded318d97dc9870e9a893f Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Fri, 6 May 2016 19:31:39 +0200 Subject: [PATCH 119/213] Add DvOrdinal.valueOf() --- .../rm/datatypes/quantity/DvOrdinal.java | 79 ++++++++++--------- .../rm/datatypes/quantity/DvOrdinalTest.java | 8 ++ 2 files changed, 50 insertions(+), 37 deletions(-) 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 95f537ba..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"); @@ -99,7 +100,7 @@ public DvOrdinal(int value, DvCodedText symbol) { * @throws IllegalArgumentException */ public DvOrdinal(int value, String dvCodedTextValue, String dvCodedTextTerminology, String dvCodedTextCode) { - this(null, null, value, new DvCodedText(dvCodedTextValue, dvCodedTextTerminology, dvCodedTextCode)); + this(null, null, value, new DvCodedText(dvCodedTextValue, dvCodedTextTerminology, dvCodedTextCode)); } /** @@ -108,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. */ @@ -155,7 +156,7 @@ public DvCodedText getSymbol() { public ReferenceRange limits() { return getOtherReferenceRanges().get(limitsIndex); } - + /** * Equals if value and symbol equal in value * @@ -164,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; @@ -193,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; @@ -206,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; } @@ -239,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/test/java/org/openehr/rm/datatypes/quantity/DvOrdinalTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvOrdinalTest.java index 1d4f6f7e..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 @@ -25,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", From 3f1a196d686255f9f7abaecc90bcaf877b4e12be Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Fri, 6 May 2016 19:56:37 +0200 Subject: [PATCH 120/213] Add valueOf() to DvCount, DvQuantity, DvDateTime and DvText --- .../rm/datatypes/quantity/DvCount.java | 4 + .../rm/datatypes/quantity/DvQuantity.java | 122 +++++++++--------- .../quantity/datetime/DvDateTime.java | 7 +- .../org/openehr/rm/datatypes/text/DvText.java | 7 +- .../rm/datatypes/quantity/DvCountTest.java | 6 + .../rm/datatypes/quantity/DvQuantityTest.java | 13 ++ .../quantity/datetime/DvDateTest.java | 0 .../quantity/datetime/DvDateTimeTest.java | 10 ++ 8 files changed, 105 insertions(+), 64 deletions(-) mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvText.java mode change 100644 => 100755 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvCountTest.java mode change 100644 => 100755 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTest.java mode change 100644 => 100755 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeTest.java 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 27e42530..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 @@ -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/DvQuantity.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvQuantity.java index ca8e8e13..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 @@ -51,26 +51,26 @@ 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) { + 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); + accuracyPercent, magnitudeStatus); if (precision < -1) { throw new IllegalArgumentException("negative precision"); @@ -145,7 +145,7 @@ public DvQuantity(double magnitude, int precision, * @param precision */ public DvQuantity(String units, double magnitude, int precision) { - this(units, magnitude, precision, null); + this(units, magnitude, precision, null); } /** @@ -172,30 +172,34 @@ public Double getMagnitude() { * @return units */ public String getUnits() { - return units; + return units; } public DvQuantity parse(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); - } + 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); + } } /** @@ -210,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); } /** @@ -227,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); } /** @@ -251,8 +255,8 @@ public Class getDiffType() { */ public DvQuantity negate() { return new DvQuantity(getOtherReferenceRanges(), getNormalRange(), - getNormalStatus(), getAccuracy(), isAccuracyPercent(), - getMagnitudeStatus(), getUnits(), -magnitude, + getNormalStatus(), getAccuracy(), isAccuracyPercent(), + getMagnitudeStatus(), getUnits(), -magnitude, precision, measurementService); } @@ -278,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; } @@ -287,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. */ @@ -305,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; @@ -320,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; @@ -365,15 +369,15 @@ public void setPrecision(int precision) { public static final char DECIMAL_SEPARATOR = '.'; - @Override - public String getReferenceModelName() { - return ReferenceModelName.DV_QUANTITY.getName(); - } + @Override + public String getReferenceModelName() { + return ReferenceModelName.DV_QUANTITY.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/quantity/datetime/DvDateTime.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTime.java index 70454084..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 @@ -173,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); } @@ -291,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) { 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 old mode 100644 new mode 100755 index 370cd952..acbf5e16 --- 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/test/java/org/openehr/rm/datatypes/quantity/DvCountTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvCountTest.java old mode 100644 new mode 100755 index 972ec277..8ac206ab --- 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/DvQuantityTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvQuantityTest.java index caf5b72e..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 @@ -111,6 +111,19 @@ public void testParseQuantityWithPrecision() throws Exception { 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); diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTest.java old mode 100644 new mode 100755 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 old mode 100644 new mode 100755 index 2948f908..1494d208 --- 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 ***** From d70fc3e4374fc595c5defc76c2f11f4328beda71 Mon Sep 17 00:00:00 2001 From: jenkins Date: Fri, 6 May 2016 20:16:01 +0200 Subject: [PATCH 121/213] [maven-release-plugin] prepare release ref_impl_java-1.0.18 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 0c4fe06d..2c925844 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index a40a0473..efbc0947 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 94bf3767..7e1925f2 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index fe60a7dd..65dfbd4d 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 79240a4e..81cfdc73 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 743e9e35..cd401206 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 1ac90c2b..981ec9a6 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 96ea6eb3..9a386c17 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 1633e0ef..ac48e79f 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index b58a52fb..d495473b 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index d90363ea..d78f3e26 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 7c6ed97f..f91ff3b1 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index adb3e566..37893c6c 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.18-SNAPSHOT + 1.0.18 The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - HEAD + ref_impl_java-1.0.18 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 2d012f4f..89819a22 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 8dfd8e8f..1919082a 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index e4ebedd5..94ecc3f1 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 15a179a7..18b1a7c6 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 xml-serializer jar From 1afa52035175a19fd187d0407525903766d7f99b Mon Sep 17 00:00:00 2001 From: jenkins Date: Fri, 6 May 2016 20:16:05 +0200 Subject: [PATCH 122/213] [maven-release-plugin] prepare for next development iteration --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 2c925844..ae6d1e7f 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index efbc0947..ce27dc6a 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 7e1925f2..92f121a2 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 65dfbd4d..f812412e 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 81cfdc73..794c1068 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index cd401206..5cc34545 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 981ec9a6..d1337d6a 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 9a386c17..ed5100ec 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index ac48e79f..a9c5d0a6 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index d495473b..c52c1ba9 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index d78f3e26..e2815327 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index f91ff3b1..929b61e0 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 37893c6c..7e5e502e 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.18 + 1.0.19-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - ref_impl_java-1.0.18 + HEAD diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 89819a22..3355fafe 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 1919082a..be3054ea 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 94ecc3f1..dabf121e 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 18b1a7c6..47b33cbe 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT xml-serializer jar From f1f9918d7554fbd46af8a9088b162a0671f993ed Mon Sep 17 00:00:00 2001 From: jenkins Date: Fri, 6 May 2016 22:28:47 +0200 Subject: [PATCH 123/213] [maven-release-plugin] prepare release ref_impl_java-1.0.18 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index ae6d1e7f..2c925844 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index ce27dc6a..efbc0947 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 92f121a2..7e1925f2 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index f812412e..65dfbd4d 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 794c1068..81cfdc73 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 5cc34545..cd401206 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index d1337d6a..981ec9a6 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index ed5100ec..9a386c17 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index a9c5d0a6..ac48e79f 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index c52c1ba9..d495473b 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index e2815327..d78f3e26 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 929b61e0..f91ff3b1 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 7e5e502e..37893c6c 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.19-SNAPSHOT + 1.0.18 The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - HEAD + ref_impl_java-1.0.18 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 3355fafe..89819a22 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index be3054ea..1919082a 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index dabf121e..94ecc3f1 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 47b33cbe..18b1a7c6 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 xml-serializer jar From ec8feea558b6e01f6e05ad04228bca334d999c89 Mon Sep 17 00:00:00 2001 From: Manuel Palacio Date: Mon, 9 May 2016 10:31:40 +0200 Subject: [PATCH 124/213] fix version number in pom --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 3 +-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 17 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 2c925844..ae6d1e7f 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index efbc0947..ce27dc6a 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 7e1925f2..92f121a2 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 65dfbd4d..f812412e 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 81cfdc73..794c1068 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index cd401206..5cc34545 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 981ec9a6..d1337d6a 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 9a386c17..ed5100ec 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index ac48e79f..a9c5d0a6 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index d495473b..c52c1ba9 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index d78f3e26..e2815327 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index f91ff3b1..929b61e0 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 37893c6c..a24dfb1e 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.18 + 1.0.19-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,6 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - ref_impl_java-1.0.18 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 89819a22..3355fafe 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 1919082a..be3054ea 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 94ecc3f1..dabf121e 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 18b1a7c6..47b33cbe 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT xml-serializer jar From 7023d14aa129a4d064aa7616cb1009abf54c548a Mon Sep 17 00:00:00 2001 From: jenkins Date: Mon, 9 May 2016 10:38:33 +0200 Subject: [PATCH 125/213] [maven-release-plugin] prepare release ref_impl_java-1.0.19 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 3 ++- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 17 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index ae6d1e7f..cae9ec3b 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index ce27dc6a..c3e8001f 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 92f121a2..c92ad11f 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index f812412e..b5948cf0 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 794c1068..6fd77b0b 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 5cc34545..f3f839c7 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index d1337d6a..16d63940 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index ed5100ec..e57805aa 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index a9c5d0a6..93535114 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index c52c1ba9..612ca665 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index e2815327..fd27a5f5 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 929b61e0..e6aa53e0 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index a24dfb1e..df106ed5 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.19-SNAPSHOT + 1.0.19 The openEHR Reference Java Implementation The openEHR Foundation @@ -14,6 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git + ref_impl_java-1.0.19 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 3355fafe..59e51ea2 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index be3054ea..b9978685 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index dabf121e..9df625f6 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 47b33cbe..e47286a6 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 xml-serializer jar From b2e654e9b72aac17188566ca663378b299e274d1 Mon Sep 17 00:00:00 2001 From: jenkins Date: Mon, 9 May 2016 10:38:38 +0200 Subject: [PATCH 126/213] [maven-release-plugin] prepare for next development iteration --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index cae9ec3b..81b57b40 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index c3e8001f..53f9ce81 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index c92ad11f..73928725 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index b5948cf0..e742d1f7 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 6fd77b0b..873fb2fd 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index f3f839c7..b0da953a 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 16d63940..4dfc3742 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index e57805aa..918a0c31 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 93535114..59150a70 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 612ca665..24947e09 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index fd27a5f5..79417b30 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index e6aa53e0..3ed41f32 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index df106ed5..155e2dee 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.19 + 1.0.20-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - ref_impl_java-1.0.19 + HEAD diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 59e51ea2..b027ba8e 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index b9978685..38e9e78c 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 9df625f6..0f057f72 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index e47286a6..bf5dc90c 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT xml-serializer jar From fe15688052aa2e68fe08d6a77593975e4002c493 Mon Sep 17 00:00:00 2001 From: Manuel Palacio Date: Mon, 9 May 2016 11:06:56 +0200 Subject: [PATCH 127/213] use 0-SNAPSHOT before moving to teamcity --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 174 +++++++++++------------------------- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 70 insertions(+), 136 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 81b57b40..3e21beb5 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 53f9ce81..d6b4bbe0 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 73928725..7d90ed3a 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index e742d1f7..2e4d30a5 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 873fb2fd..e597192e 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index b0da953a..fec1a897 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 4dfc3742..86705472 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 918a0c31..b933b845 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 59150a70..f28d599a 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 24947e09..97be5a12 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 79417b30..4918b269 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 3ed41f32..b5a3219e 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 155e2dee..bdeb8972 100755 --- a/pom.xml +++ b/pom.xml @@ -1,122 +1,56 @@ - - 4.0.0 - openehr - ref_impl_java - pom - 1.0.20-SNAPSHOT - The openEHR Reference Java Implementation - - The openEHR Foundation - - - UTF-8 - - - scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - HEAD - - - - - maven-compiler-plugin - 2.3.2 - - 1.5 - 1.5 - - - - - 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 - - - - org.apache.maven.plugins - maven-release-plugin - 2.5 - - - org.codehaus.mojo - cobertura-maven-plugin - 2.5.1 - - - - xml - - - - - maven-source-plugin - 2.4 - - - attach-sources - verify - - jar-no-fork - - - - - - - - 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 - - - - repo.cambio.se_releases - releases - http://css-cds-3:8081/nexus/content/repositories/releases - - - repo.cambio.se_snapshots - snapshots - http://css-cds-3:8081/nexus/content/repositories/snapshots - - + + + se.cambio.cds + mig-project + 1.9 + + 4.0.0 + openehr + ref_impl_java + pom + 0-SNAPSHOT + The openEHR Reference Java Implementation + + The openEHR Foundation + + + scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git + HEAD + + + + + org.codehaus.mojo + versions-maven-plugin + 2.1 + + + maven-scm-plugin + 1.8.1 + + ${project.artifactId}-${project.version} + + + + + + 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 + diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index b027ba8e..09c81bcc 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 38e9e78c..45e2ee4f 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 0f057f72..6fcd6216 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index bf5dc90c..44baee3d 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT xml-serializer jar From 00e8d3296f863b077df65ad890964b026cabef02 Mon Sep 17 00:00:00 2001 From: Manuel Palacio Date: Mon, 9 May 2016 11:16:45 +0200 Subject: [PATCH 128/213] change groupId to se.cambio.cds --- adl-parser/pom.xml | 14 +++++++------- adl-serializer/pom.xml | 14 +++++++------- archetype-validator/pom.xml | 16 ++++++++-------- dadl-binding/pom.xml | 18 +++++++++--------- dadl-parser/pom.xml | 4 ++-- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 4 ++-- oet-parser/pom.xml | 16 ++++++++-------- openehr-aom/pom.xml | 6 +++--- openehr-ap/pom.xml | 10 +++++----- openehr-rm-core/pom.xml | 4 ++-- openehr-rm-domain/pom.xml | 6 +++--- pom.xml | 1 - rm-builder/pom.xml | 10 +++++----- rm-skeleton/pom.xml | 24 ++++++++++++------------ xml-binding/pom.xml | 14 +++++++------- xml-serializer/pom.xml | 10 +++++----- 17 files changed, 86 insertions(+), 87 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 3e21beb5..9d8c5248 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -91,32 +91,32 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} - openehr + se.cambio.cds openehr-aom ${project.version} - openehr + se.cambio.cds openehr-ap ${project.version} - openehr + se.cambio.cds measure-serv ${project.version} - openehr + se.cambio.cds mini-termserv ${project.version} diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index d6b4bbe0..6fbf41c8 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -1,7 +1,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -27,32 +27,32 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} - openehr + se.cambio.cds openehr-aom ${project.version} - openehr + se.cambio.cds openehr-ap ${project.version} - openehr + se.cambio.cds mini-termserv ${project.version} - openehr + se.cambio.cds adl-parser ${project.version} test diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 7d90ed3a..a8ad84c4 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -43,37 +43,37 @@ 1.2.13 - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} - openehr + se.cambio.cds openehr-aom ${project.version} - openehr + se.cambio.cds openehr-ap ${project.version} - openehr + se.cambio.cds mini-termserv ${project.version} - openehr + se.cambio.cds measure-serv ${project.version} - openehr + se.cambio.cds adl-parser ${project.version} test diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 2e4d30a5..57963f13 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -19,48 +19,48 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-aom ${project.version} - openehr + se.cambio.cds adl-parser ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} - openehr + se.cambio.cds mini-termserv ${project.version} - openehr + se.cambio.cds measure-serv ${project.version} - openehr + se.cambio.cds rm-builder ${project.version} - openehr + se.cambio.cds dadl-parser ${project.version} diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index e597192e..e302e708 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -66,7 +66,7 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index fec1a897..245bff49 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 86705472..b2e45f8c 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -21,7 +21,7 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index b933b845..54b6526a 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -49,22 +49,22 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} - openehr + se.cambio.cds openehr-aom ${project.version} - openehr + se.cambio.cds adl-parser ${project.version} @@ -79,12 +79,12 @@ 1.0 - openehr + se.cambio.cds measure-serv ${project.version} - openehr + se.cambio.cds mini-termserv ${project.version} @@ -101,7 +101,7 @@ test - openehr + se.cambio.cds adl-serializer ${project.version} diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index f28d599a..a9a13b09 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -22,12 +22,12 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 97be5a12..5a99d9c0 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -21,22 +21,22 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} - openehr + se.cambio.cds openehr-aom ${project.version} - openehr + se.cambio.cds measure-serv ${project.version} diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 4918b269..77d79b0f 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -37,7 +37,7 @@ test - openehr + se.cambio.cds measure-serv ${project.version} diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index b5a3219e..7a20892b 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -21,12 +21,12 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds mini-termserv ${project.version} test diff --git a/pom.xml b/pom.xml index bdeb8972..2dc5f2c5 100755 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,6 @@ 1.9 4.0.0 - openehr ref_impl_java pom 0-SNAPSHOT diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 09c81bcc..454ba93e 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -21,22 +21,22 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} - openehr + se.cambio.cds mini-termserv ${project.version} - openehr + se.cambio.cds measure-serv ${project.version} diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 45e2ee4f..6d556495 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -12,52 +12,52 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} - openehr + se.cambio.cds openehr-aom ${project.version} - openehr + se.cambio.cds adl-parser ${project.version} - openehr + se.cambio.cds dadl-parser ${project.version} - openehr + se.cambio.cds oet-parser ${project.version} - openehr + se.cambio.cds measure-serv ${project.version} - openehr + se.cambio.cds mini-termserv ${project.version} - openehr + se.cambio.cds dadl-binding ${project.version} - openehr + se.cambio.cds xml-binding ${project.version} @@ -74,7 +74,7 @@ test - openehr + se.cambio.cds adl-serializer ${project.version} test diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 6fcd6216..1541883f 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -49,12 +49,12 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} @@ -64,17 +64,17 @@ 2.3.0 - openehr + se.cambio.cds measure-serv ${project.version} - openehr + se.cambio.cds mini-termserv ${project.version} - openehr + se.cambio.cds ${project.version} rm-builder @@ -120,7 +120,7 @@ test - openehr + se.cambio.cds oet-parser ${project.version} diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 44baee3d..be3a7375 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -1,7 +1,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -20,22 +20,22 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} - openehr + se.cambio.cds openehr-aom ${project.version} - openehr + se.cambio.cds openehr-ap ${project.version} From 290849976e48f7f8fda90f907744900ac1b280c6 Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Thu, 9 Jun 2016 11:31:30 +0200 Subject: [PATCH 129/213] Archetype Validator: Error for duplicate language sections --- .../am/validation/ArchetypeValidator.java | 48 +++++++++++++++---- .../org/openehr/am/validation/ErrorType.java | 1 + .../src/main/resources/validations.properties | 6 ++- .../main/resources/validations_de.properties | 4 +- .../main/resources/validations_ru.properties | 4 +- .../validation/ArchetypeTermValidityTest.java | 20 ++++++++ 6 files changed, 69 insertions(+), 14 deletions(-) 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 index 79e749c5..81ad855c 100644 --- a/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java @@ -163,8 +163,15 @@ public void checkDescription(Archetype archetype, List errors) return; } + ArrayList checkedLanguages = new ArrayList(); // check purpose in each available language for (ResourceDescriptionItem detail : archetype.getDescription().getDetails()) { + 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()); @@ -680,16 +687,24 @@ private void checkCardinalityConformsToChildrenOccurrences( 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 (TBD) + // 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) - ); - + cmattr.path(), getIntervalFormalString(cardinalityInterval), getIntervalFormalString(minOcc, maxOcc, isOccUpperUnbounded)); if( ! errors.contains(error)) { errors.add(error); } } + + // "Sum of minimal occurrences of elements < minimal cardinality of container"? + /* if (!cardinalityInterval.isLowerUnbounded() && minOcc < cardinalityInterval.getLower().intValue()) { + // While it is perfectly legal to do this (and might even be used as a way to force a selection of various items) + // in practice this most often happens if a mandatory element was removed, but the min. cardinality hasn't been decreased. + // This results in ugly problems for implementers downstream and therefore we warn here. + ValidationError error = new ValidationError(ErrorType.W, null, + cmattr.path(), getIntervalFormalString(cardinalityInterval), getIntervalFormalString(minOcc, maxOcc, isOccUpperUnbounded)); + } + */ } private void checkCardinalityConformsToRMCardinality(CMultipleAttribute cattr, CObject cobj, List errors) { @@ -864,7 +879,7 @@ private void validateCDomainType(CDomainType cdtobj, Archetype archetype, log.debug("validating CDVQuantity object at "+cdtobj.path()); checkArchetypeUnitsValidity((CDvQuantity)cdtobj, errors); } - + } /* @@ -1085,10 +1100,12 @@ public void checkOntologyTranslation(Archetype archetype, List errors) { Set languages = archetype.languagesAvailable(); String primaryLang = archetype.getOriginalLanguage().getCodeString(); - List termDefList = - archetype.getOntology().getTermDefinitionsList(); - List constraintDefList = - archetype.getOntology().getConstraintDefinitionsList(); + 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; @@ -1096,7 +1113,7 @@ public void checkOntologyTranslation(Archetype archetype, if(primaryLang.equals(lang)) { continue; } - if( ! termDefLangs.contains(lang)) { + if(!termDefLangs.contains(lang)) { error = new ValidationError(ErrorType.VOTM, "TERM", lang); errors.add(error); @@ -1111,6 +1128,17 @@ public void checkOntologyTranslation(Archetype archetype, } } + 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) { 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 index 161d9d18..4133dfe6 100644 --- a/archetype-validator/src/main/java/org/openehr/am/validation/ErrorType.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ErrorType.java @@ -49,6 +49,7 @@ public enum ErrorType { 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. diff --git a/archetype-validator/src/main/resources/validations.properties b/archetype-validator/src/main/resources/validations.properties index 81381f48..0e6fbb9e 100644 --- a/archetype-validator/src/main/resources/validations.properties +++ b/archetype-validator/src/main/resources/validations.properties @@ -42,11 +42,12 @@ WACMC=Cardinality/occurrences validity warning: where occurrences and cardinalit 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}). +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}. @@ -110,4 +111,5 @@ 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. \ No newline at end of file +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_de.properties b/archetype-validator/src/main/resources/validations_de.properties index 75d1c2f6..8c15a02b 100644 --- a/archetype-validator/src/main/resources/validations_de.properties +++ b/archetype-validator/src/main/resources/validations_de.properties @@ -42,6 +42,7 @@ WACMC=(de)Cardinality/occurrences validity warning: where occurrences and cardin 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. @@ -110,4 +111,5 @@ WITB_PATH_TEXT=(de)The path of the term binding {0} does not exist in the archet 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. \ No newline at end of file +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_ru.properties b/archetype-validator/src/main/resources/validations_ru.properties index e4b648d1..86040836 100644 --- a/archetype-validator/src/main/resources/validations_ru.properties +++ b/archetype-validator/src/main/resources/validations_ru.properties @@ -42,6 +42,7 @@ 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. @@ -110,4 +111,5 @@ WITB_PATH_TEXT=(ru)The path of the term binding {0} does not exist in the archet 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. \ No newline at end of file +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/ArchetypeTermValidityTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeTermValidityTest.java index b6a03919..fd9b59ea 100644 --- a/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeTermValidityTest.java +++ b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeTermValidityTest.java @@ -61,6 +61,26 @@ public void testCheckTermWithDoubleEntryInOntology() throws Exception { } } + public void testCheckDoubleLanguage_Description() throws Exception { + archetype = loadArchetype("adl-test-ENTRY.term_definition.v5"); + validator.checkDescription(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()); + } + } + + 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); From df2a8d02cc84597c7b530a24055177535ab2c265 Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Fri, 17 Jun 2016 14:19:17 +0200 Subject: [PATCH 130/213] - Archetype Validator: Error for duplicate language sections (Add missing test adl files for test cases) - Replace the existing UCUM validator (too outdated because of missing UCUM units in the Java Units implementation) with a new (simple) UCUM validator. --- .../adl-test-ENTRY.term_definition.v5 | 47 ++ .../adl-test-ENTRY.term_definition.v6 | 45 ++ .../measurement/SimpleMeasurementService.java | 19 +- .../measurement/SimpleUCUMValidator.java | 207 ++++++ .../SimpleMeasurementServiceTest.java | 595 +++++++++++++++++- 5 files changed, 891 insertions(+), 22 deletions(-) create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v5 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v6 create mode 100644 measure-serv/src/main/java/org/openehr/rm/support/measurement/SimpleUCUMValidator.java 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/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 index 4e294532..86578cfc 100644 --- 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 @@ -92,13 +92,15 @@ private SimpleMeasurementService() { "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" + "{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 currrently assumes case-sensitive UCUM format. + * Note that this implementation currently assumes case-sensitive UCUM format. * * @param units * @return true if units valid @@ -109,9 +111,16 @@ public boolean isValidUnitsString(String units) { 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)) { +/* if (commonUCUMCodes.contains(units)) { return true; } @@ -124,7 +133,7 @@ public boolean isValidUnitsString(String 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)); @@ -141,7 +150,7 @@ public boolean isValidUnitsString(String units) { System.out.println("Unit NOT parsed CI: "+ units); } */ - return unit!= null; + // return unit!= null; } /** 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 index e5d26eed..bed4c9e7 100644 --- 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 @@ -6,31 +6,31 @@ 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", "MG")); - assertFalse(service.unitsEquivalent("mg", "mG")); - assertTrue(service.unitsEquivalent("A", "C/s")); - - 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")); @@ -42,16 +42,577 @@ public void testunitsValid() throws Exception { 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 + assertTrue(service.isValidUnitsString("")); + 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}")); + assertTrue(service.isValidUnitsString("1{c}")); + assertFalse(service.isValidUnitsString("{|}1")); + 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]")); + + // According to the UCUM test cases, this is valid, but not sure why. "g.m/{hb}.m2" could be valid, but "g.m/{hb}m2" ? + // The Bacus-Naur at http://unitsofmeasure.org/ucum.html seems to suggest it is not valid + //assertTrue(service.isValidUnitsString("g.m/{hb}m2")); + + 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; } From 6f8134565dfbf5b0ab830cf5809d23502a3fe4ed Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Tue, 21 Jun 2016 13:09:57 +0200 Subject: [PATCH 131/213] Minor update to the tests of the UCUM validator --- .../measurement/SimpleMeasurementServiceTest.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) 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 index bed4c9e7..c9a27940 100644 --- 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 @@ -73,7 +73,9 @@ public void testunitsValid() throws Exception { assertTrue(service.isValidUnitsString("m")); assertFalse(service.isValidUnitsString("m/")); // / is not followed by a term - assertTrue(service.isValidUnitsString("")); + + //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")); @@ -88,10 +90,10 @@ public void testunitsValid() throws Exception { /** 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}")); + 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")); + assertFalse(service.isValidUnitsString("{|}1")); // Cannot start a symbol with an annotation assertTrue(service.isValidUnitsString("{e}")); assertTrue(service.isValidUnitsString("%")); @@ -391,9 +393,8 @@ public void testunitsValid() throws Exception { assertTrue(service.isValidUnitsString("osm")); assertTrue(service.isValidUnitsString("[mclg'U]")); - // According to the UCUM test cases, this is valid, but not sure why. "g.m/{hb}.m2" could be valid, but "g.m/{hb}m2" ? - // The Bacus-Naur at http://unitsofmeasure.org/ucum.html seems to suggest it is not valid - //assertTrue(service.isValidUnitsString("g.m/{hb}m2")); + 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")); From 7f16e2402496e351242cef28063182209cfcc9c1 Mon Sep 17 00:00:00 2001 From: Manuel Palacio Date: Mon, 4 Jul 2016 18:02:06 +0200 Subject: [PATCH 132/213] add junit and update ref to parent pom --- pom.xml | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/pom.xml b/pom.xml index 2dc5f2c5..8e8016f0 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ se.cambio.cds mig-project - 1.9 + 1.0.23 4.0.0 ref_impl_java @@ -15,25 +15,9 @@ The openEHR Foundation - scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git + ${scm.url} HEAD - - - - org.codehaus.mojo - versions-maven-plugin - 2.1 - - - maven-scm-plugin - 1.8.1 - - ${project.artifactId}-${project.version} - - - - openehr-rm-core openehr-rm-domain @@ -52,4 +36,14 @@ rm-skeleton archetype-validator + + + + junit + junit + 4.12 + test + + + From 0034440740ad84125f8c47627955c8b42220eb43 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Wed, 10 Aug 2016 15:57:11 +0200 Subject: [PATCH 133/213] Resolving mig project version conflict --- pom.xml | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index 8e8016f0..3be0e852 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ se.cambio.cds mig-project - 1.0.23 + 1.43 4.0.0 ref_impl_java @@ -15,9 +15,25 @@ The openEHR Foundation - ${scm.url} + scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git HEAD + + + + org.codehaus.mojo + versions-maven-plugin + 2.1 + + + maven-scm-plugin + 1.8.1 + + ${project.artifactId}-${project.version} + + + + openehr-rm-core openehr-rm-domain @@ -36,14 +52,4 @@ rm-skeleton archetype-validator - - - - junit - junit - 4.12 - test - - - From 1b7468ae58bae4145a960c3b385a2472da12fa84 Mon Sep 17 00:00:00 2001 From: Manuel Palacio Date: Wed, 10 Aug 2016 17:22:51 +0200 Subject: [PATCH 134/213] Update ref to parent pom --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8e8016f0..dc2bf21b 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ se.cambio.cds mig-project - 1.0.23 + 1.0.43 4.0.0 ref_impl_java From 1a51871d73661af166bd04785b00a58c74ccc083 Mon Sep 17 00:00:00 2001 From: Manuel Palacio Date: Wed, 10 Aug 2016 17:23:17 +0200 Subject: [PATCH 135/213] Update ref to parent pom --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3be0e852..e5e19333 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ se.cambio.cds mig-project - 1.43 + 1.0.43 4.0.0 ref_impl_java From 2e7e0efbe22f8812dd5c101202b043ad80f31d99 Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Thu, 3 Nov 2016 16:27:41 +0100 Subject: [PATCH 136/213] Add string value to the exception message --- .../src/main/java/org/openehr/rm/datatypes/basic/DataValue.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DataValue.java 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 old mode 100644 new mode 100755 index 61df2834..a81fac9e --- 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 @@ -78,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); From a65edd28a8786479e254e052e0a71f7b60198f6d Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Thu, 12 Jan 2017 14:38:03 +0100 Subject: [PATCH 137/213] Fixed problem with HashMap caused by Java8 Upgrade as found by https://github.com/dngferreira https://github.com/openEHR/java-libs/pull/19/commits/e85c53f042ef0b8e410d536c82b1030fb4561e48 --- .../openehr/am/validation/RMInspector.java | 5 +- .../org/openehr/rm/binding/RMInspector.java | 6 +- .../org/openehr/build/RMObjectBuilder.java | 5 +- .../java/org/openehr/binding/RMInspector.java | 1044 ++++++++--------- 4 files changed, 531 insertions(+), 529 deletions(-) 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 index 7afbcb0f..7757c20c 100755 --- a/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java @@ -5,6 +5,7 @@ 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; @@ -192,8 +193,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(); if (klass.getSimpleName().equalsIgnoreCase("Double")) { 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..238ff00d 100644 --- 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); 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 4533f469..827294d0 100644 --- a/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java +++ b/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java @@ -78,6 +78,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -205,8 +206,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); 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..2a15910b 100644 --- a/xml-binding/src/main/java/org/openehr/binding/RMInspector.java +++ b/xml-binding/src/main/java/org/openehr/binding/RMInspector.java @@ -1,523 +1,523 @@ -package org.openehr.binding; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Constructor; +package org.openehr.binding; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; import java.util.*; - -import org.apache.commons.lang.StringUtils; -import org.apache.log4j.Logger; - -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.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.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.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.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, - - // 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, - UUID.class, - VersionTreeID.class, - - // datatypes classes - DvBoolean.class, - DvURI.class, - DvState.class, - DvIdentifier.class, - DvText.class, - DvCodedText.class, - DvParagraph.class, - CodePhrase.class, - DvCount.class, - DvOrdinal.class, - DvQuantity.class, - DvInterval.class, - DvProportion.class, - ProportionKind.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, 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 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) { - Class rmClass = typeMap.get(rmClassName); - if (rmClass == null) { - rmClass = upperCaseMap.get(rmClassName.replace("_", "")); - } - 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); - - 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; - } - - /* - * 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)); - } -} + +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; +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.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.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.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.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, + + // 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, + UUID.class, + VersionTreeID.class, + + // datatypes classes + DvBoolean.class, + DvURI.class, + DvState.class, + DvIdentifier.class, + DvText.class, + DvCodedText.class, + DvParagraph.class, + CodePhrase.class, + DvCount.class, + DvOrdinal.class, + DvQuantity.class, + DvInterval.class, + DvProportion.class, + ProportionKind.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, 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 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) { + Class rmClass = typeMap.get(rmClassName); + if (rmClass == null) { + rmClass = upperCaseMap.get(rmClassName.replace("_", "")); + } + 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); + + 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; + } + + /* + * 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)); + } +} From c6c4fc9ca72a387c9d08b9a8b0178bc08774667e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20N=C3=A6ss?= Date: Thu, 2 Feb 2017 01:03:52 +0100 Subject: [PATCH 138/213] Added .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..f5099798 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.iml +.idea/* +*/target/* From 0a5b7cd5516a5531e1a7df1d5ea9d7af9eecc448 Mon Sep 17 00:00:00 2001 From: Marko Pipan Date: Thu, 16 Mar 2017 13:55:54 +0100 Subject: [PATCH 139/213] Escape quotes in serialized strings --- .../openehr/am/serialize/ADLSerializer.java | 185 ++++++++---------- .../am/serialize/StringEscapeTest.java | 61 ++++++ 2 files changed, 139 insertions(+), 107 deletions(-) create mode 100644 adl-serializer/src/test/java/org/openehr/am/serialize/StringEscapeTest.java 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 index af138e25..d4258c7f 100644 --- a/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java +++ b/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java @@ -14,47 +14,13 @@ */ 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.archetype.constraintmodel.*; +import org.openehr.am.archetype.constraintmodel.primitive.*; +import org.openehr.am.archetype.ontology.*; import org.openehr.am.openehrprofile.datatypes.quantity.CDvOrdinal; import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantity; import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantityItem; @@ -70,6 +36,13 @@ import org.openehr.rm.support.identification.ArchetypeID; import org.openehr.rm.support.identification.ObjectID; +import java.io.*; +import java.nio.charset.Charset; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + /** * ADL serializer for the openEHR Java kernel * @@ -225,9 +198,9 @@ protected void printLanguage(AuthoredResource authored, TranslationDetails td = translations.get(lang); indent(2, out); - out.write("[\""); - out.write(lang); - out.write("\"] = <"); + out.write("["); + out.write(quoteString(lang)); + out.write("] = <"); newline(out); indent(3, out); @@ -250,9 +223,9 @@ protected void printLanguage(AuthoredResource authored, if(td.getAccreditation() != null) { indent(3, out); - out.write("accreditation = <\""); - out.write(td.getAccreditation()); - out.write("\">"); + out.write("accreditation = <"); + out.write(quoteString(td.getAccreditation())); + out.write(">"); newline(out); } @@ -283,11 +256,11 @@ protected void printMap(Map map, Writer out, int indent) } for(String key : map.keySet()) { indent(indent, out); - out.write("[\""); - out.write(key); - out.write("\"] = <\""); - out.write(map.get(key)); - out.write("\">"); + out.write("["); + out.write(quoteString(key)); + out.write("] = <"); + out.write(quoteString(map.get(key))); + out.write(">"); newline(out); } } @@ -308,7 +281,7 @@ protected void printDescription(ResourceDescription description, Writer out) Map map = description.getOriginalAuthor(); for (String key : map.keySet()) { indent(2, out); - out.write("[\"" + key + "\"] = <\"" + map.get(key) + "\">"); + out.write("[" + quoteString(key) + "] = <" + quoteString(map.get(key)) + ">"); newline(out); } indent(1, out); @@ -316,9 +289,9 @@ protected void printDescription(ResourceDescription description, Writer out) newline(out); indent(1, out); - out.write("lifecycle_state = <\""); - out.write(description.getLifecycleState()); - out.write("\">"); + out.write("lifecycle_state = <"); + out.write(quoteString(description.getLifecycleState())); + out.write(">"); newline(out); printNonEmptyString("resource_package_uri", description.getResourcePackageUri(), 1, out); @@ -337,9 +310,9 @@ protected void printDescription(ResourceDescription description, Writer out) protected void printDescriptionItem(ResourceDescriptionItem item, int indent, Writer out) throws IOException { indent(indent, out); - out.write("[\""); - out.write(item.getLanguage().getCodeString()); - out.write("\"] = <"); + out.write("["); + out.write(quoteString(item.getLanguage().getCodeString())); + out.write("] = <"); newline(out); indent(indent + 1, out); @@ -374,9 +347,9 @@ private void printNonEmptyString(String label, String value, int indent, } indent(indent, out); out.write(label); - out.write(" = <\""); - out.write(value); - out.write("\">"); + out.write(" = <"); + out.write(quoteString(value)); + out.write(">"); newline(out); } @@ -390,9 +363,7 @@ private void printNonEmptyStringList(String label, List list, out.write(label); out.write(" = <"); for (int i = 0, j = list.size(); i < j; i++) { - out.write("\""); - out.write(list.get(i)); - out.write("\""); + out.write(quoteString(list.get(i))); if (i != j - 1) { out.write(","); } @@ -414,7 +385,7 @@ private void printNonEmptyStringMap(String label, Map map, for (String key : map.keySet()) { indent(2, out); - out.write("[\"" + key + "\"] = <\"" + map.get(key) + "\">"); + out.write("[" + quoteString(key) + "] = <" + quoteString(map.get(key)) + ">"); newline(out); } @@ -804,14 +775,14 @@ protected void printCDvQuantity(CDvQuantity cquantity, int indent, int index = 1; for (CDvQuantityItem item : list) { indent(indent + 2, out); - out.write("[\""); - out.write(Integer.toString(index)); - out.write("\"] = <"); + out.write("["); + out.write(quoteString(Integer.toString(index))); + out.write("] = <"); newline(out); indent(indent + 3, out); - out.write("units = <\""); - out.write(item.getUnits()); - out.write("\">"); + out.write("units = <"); + out.write(quoteString(item.getUnits())); + out.write(">"); newline(out); Interval value = item.getMagnitude(); if (value != null) { @@ -879,9 +850,9 @@ protected void printDvQuantity(DvQuantity quantity, int indent, Writer out) } protected void printUnits(String units, Writer out) throws IOException { - out.write("units = <\""); - out.write(units); - out.write("\">"); + out.write("units = <"); + out.write(quoteString(units)); + out.write(">"); } protected void printOntology(ArchetypeOntology ontology, Writer out) @@ -894,9 +865,8 @@ protected void printOntology(ArchetypeOntology ontology, Writer out) indent(1, out); out.write("terminologies_available = <"); for (String terminology : ontology.getTerminologies()) { - out.write("\""); - out.write(terminology); - out.write("\", "); + out.write(quoteString(terminology)); + out.write(", "); } out.write("...>"); newline(out); @@ -932,9 +902,9 @@ protected void printOntology(ArchetypeOntology ontology, Writer 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("\"] = <"); + out.write("["); + out.write(quoteString(bind.getTerminology())); + out.write("] = <"); newline(out); indent(3, out); out.write("items = <"); @@ -946,9 +916,9 @@ protected void printOntology(ArchetypeOntology ontology, Writer out) .getTermBindingList().get(i).getBindingList() .get(j); indent(4, out); - out.write("[\""); - out.write(item.getCode()); - out.write("\"] = <"); + out.write("["); + out.write(quoteString(item.getCode())); + out.write("] = <"); out.write(item.getTerms().get(0)); if (item.getTerms().size() > 1) { @@ -980,9 +950,9 @@ protected void printOntology(ArchetypeOntology ontology, Writer out) OntologyBinding bind = ontology.getConstraintBindingList().get( i); indent(2, out); - out.write("[\""); - out.write(bind.getTerminology()); - out.write("\"] = <"); + out.write("["); + out.write(quoteString(bind.getTerminology())); + out.write("] = <"); newline(out); indent(3, out); out.write("items = <"); @@ -994,9 +964,9 @@ protected void printOntology(ArchetypeOntology ontology, Writer out) .getConstraintBindingList().get(i).getBindingList() .get(j); indent(4, out); - out.write("[\""); - out.write(item.getCode()); - out.write("\"] = <"); + out.write("["); + out.write(quoteString(item.getCode())); + out.write("] = <"); out.write(item.getQuery().getUrl()); out.write(">"); newline(out); @@ -1013,29 +983,33 @@ protected void printOntology(ArchetypeOntology ontology, Writer out) } } - private void printDefinitionList(Writer 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(defs.getLanguage()); - out.write("\"] = <"); + 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(term.getCode()); - out.write("\"] = <"); + 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(entry.getValue()); - out.write("\">"); + out.write(" = <"); + out.write(quoteString(entry.getValue())); + out.write(">"); newline(out); } newline(out); @@ -1184,13 +1158,11 @@ protected void printCString(CString cstring, Writer out) throws IOException { } else if(cstring.getList() != null){ printList(cstring.getList(), out, true); } else if(cstring.defaultValue() != null) { - out.write("\""); - out.write(cstring.defaultValue()); - out.write("\""); + out.write(quoteString(cstring.defaultValue())); } if(cstring.hasAssumedValue()) { out.write("; "); - out.write("\"" + cstring.assumedValue() + "\""); + out.write(quoteString(ObjectUtils.toString(cstring.assumedValue(), ""))); } } @@ -1204,13 +1176,12 @@ protected void printList(List list, Writer out, boolean string) if (i != 0) { out.write(","); } + String item = list.get(i).toString(); if (string) { - out.write("\""); - } - out.write(list.get(i).toString()); - if (string) { - out.write("\""); - } + out.write(quoteString(item)); + } else { + out.write(item); + } } } 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); + } + +} From 1cc6a8f253f105e26412e282cba3685f423df236 Mon Sep 17 00:00:00 2001 From: Marko Pipan Date: Thu, 16 Mar 2017 13:57:55 +0100 Subject: [PATCH 140/213] Add a separator between adl_version and uid header attributes when both are present --- .../org/openehr/am/serialize/ADLSerializer.java | 5 ++++- .../org/openehr/am/serialize/CommonTest.java | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) 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 index d4258c7f..2f6bf29b 100644 --- a/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java +++ b/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java @@ -147,7 +147,10 @@ protected void printHeader(String adlVersion, out.write(adlVersion); } if(uid != null && StringUtils.isNotEmpty(uid.toString())) { - out.write("uid="); + if (StringUtils.isNotEmpty(adlVersion)) { + out.write("; "); + } + out.write("uid="); out.write(uid.toString()); } if(StringUtils.isNotEmpty(adlVersion) || (uid!=null &&StringUtils.isNotEmpty(uid.toString()))) { 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 index 72f559ed..d2a88517 100644 --- 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); From 6f7375d165350d8fd04330cacae1a446f7f011f5 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Fri, 2 Jun 2017 15:06:36 +0200 Subject: [PATCH 141/213] Fixing issues with Resource description list --- adl-parser/src/main/javacc/adl.jj | 4 +-- .../parser/ArchetypeDescriptionTest.java | 8 +++--- .../openehr/parser/MissingPurposeTest.java | 2 +- .../openehr/am/serialize/ADLSerializer.java | 2 +- .../openehr/am/serialize/DescriptionTest.java | 6 ++--- .../am/validation/ArchetypeValidator.java | 2 +- .../rm/common/resource/AuthoredResource.java | 8 +++--- .../common/resource/ResourceDescription.java | 14 +++++------ .../resource/ResourceDescriptionTest.java | 4 ++- .../rm/common/resource/ResourceTestBase.java | 11 +++++--- pom.xml | 25 +++++++++++-------- .../org/openehr/build/RMObjectBuilder.java | 15 +++-------- .../openehr/am/serialize/XMLSerializer.java | 2 +- 13 files changed, 51 insertions(+), 52 deletions(-) diff --git a/adl-parser/src/main/javacc/adl.jj b/adl-parser/src/main/javacc/adl.jj index 885472ef..82b1c2e0 100755 --- a/adl-parser/src/main/javacc/adl.jj +++ b/adl-parser/src/main/javacc/adl.jj @@ -858,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; @@ -879,7 +879,7 @@ ResourceDescription arch_description() throws Exception : LOOKAHEAD(2) item = arch_description_item() { - details.add(item); + details.put(item.getLanguage().getCodeString(),item); } )+ ">" 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 index f3bff7ca..80db7576 100644 --- 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/MissingPurposeTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/MissingPurposeTest.java index 0c1b6ca0..114ac38b 100644 --- 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-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java b/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java index a8049ff0..6d9a40d6 100755 --- a/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java +++ b/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java @@ -327,7 +327,7 @@ protected void printDescription(ResourceDescription description, Writer out) indent(1, out); out.write("details = <"); newline(out); - for (ResourceDescriptionItem item : description.getDetails()) { + for (ResourceDescriptionItem item : description.getDetails().values()) { printDescriptionItem(item, 2, out); } indent(1, 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 index 3fc3916f..22397d57 100644 --- a/adl-serializer/src/test/java/org/openehr/am/serialize/DescriptionTest.java +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/DescriptionTest.java @@ -68,8 +68,8 @@ public void testPrintDescription() throws Exception { Map authorMap = new HashMap(); authorMap.put("name", author); - List items = - new ArrayList(); + Map items = + new HashMap<>(); String[][] others = { { "revision", "1.1" }, { "adl_version", "1.4" }, { "rights", "all rights reserved" } }; Map otherDetails = new HashMap(); @@ -79,7 +79,7 @@ public void testPrintDescription() throws Exception { TerminologyService service = SimpleTerminologyService.getInstance(); ResourceDescriptionItem item = new ResourceDescriptionItem(ENGLISH, "purpose of this archetype", service); - items.add(item); + items.put(ENGLISH.getCodeString(),item); ResourceDescription description = new ResourceDescription(authorMap, null, status, items, null, null, null); 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 index 94f9dc9f..01b20c14 100755 --- a/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java @@ -164,7 +164,7 @@ public void checkDescription(Archetype archetype, List errors) } // check purpose in each available language - for (ResourceDescriptionItem detail : archetype.getDescription().getDetails()) { + for (ResourceDescriptionItem detail : archetype.getDescription().getDetails().values()) { if (StringUtils.isBlank(detail.getPurpose()) || StringUtils.containsIgnoreCase(detail.getPurpose(),"unknown")) { ValidationError error = new ValidationError(ErrorType.VDSCR, "PURPOSE", detail.getLanguage().getCodeString()); 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 index 3c462733..c7e7cb46 100644 --- 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 index 0a58f669..227ae6f3 100644 --- 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 @@ -41,7 +41,7 @@ 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 = "details", required = true) Map details, @Attribute(name = "resourcePackageUri") String resourcePackageUri, @Attribute(name = "otherDetails") Map otherDetails, @Attribute(name = "parentResource") AuthoredResource parentResource ){ @@ -70,7 +70,7 @@ public ResourceDescription( * * @return details */ - public List getDetails() { + public Map getDetails() { return details; } @@ -136,7 +136,7 @@ public String getResourcePackageUri() { public ResourceDescription() { } - void setDetails(List details) { + void setDetails(Map details) { this.details = details; } @@ -173,10 +173,10 @@ void setParentResource(AuthoredResource parentResource) { } } - void languageValidCheck(AuthoredResource parent, List details) { + void languageValidCheck(AuthoredResource parent, Map details) { Set languages = parent.languagesAvailable(); - for(ResourceDescriptionItem rdi : details) { - if(!languages.contains(rdi.getLanguage().getCodeString())) { + for(String code : details.keySet()) { + if(!languages.contains(code)) { throw new IllegalArgumentException("breach of language validity"); } } @@ -188,7 +188,7 @@ void languageValidCheck(AuthoredResource parent, List d private Map originalAuthor; private List otherContributors; private String lifecycleState; - private List details; + private Map details; private String resourcePackageUri; private Map otherDetails; private AuthoredResource parentResource; 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 index b0f2792a..97ddd72b 100644 --- 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 index 2a7ee53d..17c92297 100644 --- 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/pom.xml b/pom.xml index e5e19333..b66d6dce 100755 --- a/pom.xml +++ b/pom.xml @@ -1,12 +1,8 @@ - - se.cambio.cds - mig-project - 1.0.43 - 4.0.0 + openehr ref_impl_java pom 0-SNAPSHOT @@ -14,9 +10,14 @@ The openEHR Foundation + + UTF-8 + UTF-8 + - scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - HEAD + 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 @@ -26,12 +27,14 @@ 2.1 - maven-scm-plugin - 1.8.1 + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 - ${project.artifactId}-${project.version} + 1.8 + 1.8 - + 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 73359a19..8b571928 100755 --- a/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java +++ b/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java @@ -70,18 +70,11 @@ 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; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; +import java.util.*; /** * Reference model class instances builder @@ -205,8 +198,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); 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 6ff2e089..b0bd5b98 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 @@ -219,7 +219,7 @@ protected void printDescription(ResourceDescription description, Element out) { } printStringMap("other_details", description.getOtherDetails(), des); - for (ResourceDescriptionItem item : description.getDetails()) { + for (ResourceDescriptionItem item : description.getDetails().values()) { Element details = new Element("details", defaultNamespace); des.getChildren().add(details); printDescriptionItem(item, details); From c1723455516676cb3d0c1fed49085abaed71f9bb Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Fri, 2 Jun 2017 16:25:51 +0200 Subject: [PATCH 142/213] Adding fixes provided on the opensource project --- .../openehr/am/serialize/ADLSerializer.java | 230 +++--- .../org/openehr/am/serialize/CommonTest.java | 17 + .../am/serialize/StringEscapeTest.java | 61 ++ archetype-validator/pom.xml | 4 +- .../am/validation/ArchetypeValidator.java | 720 +++++++++--------- .../org/openehr/am/validation/ErrorType.java | 1 + .../openehr/am/validation/RMInspector.java | 40 +- .../SpecialisedArchetypeValidator.java | 15 +- .../src/main/resources/validations.properties | 6 +- .../validation/ArchetypeTermValidityTest.java | 10 + .../adl-test-ENTRY.term_definition.v5 | 47 ++ .../adl-test-ENTRY.term_definition.v6 | 45 ++ .../measurement/SimpleMeasurementService.java | 21 +- .../measurement/SimpleUCUMValidator.java | 207 +++++ .../SimpleMeasurementServiceTest.java | 596 ++++++++++++++- 15 files changed, 1502 insertions(+), 518 deletions(-) mode change 100755 => 100644 adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java create mode 100644 adl-serializer/src/test/java/org/openehr/am/serialize/StringEscapeTest.java mode change 100755 => 100644 archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v5 create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.term_definition.v6 mode change 100755 => 100644 measure-serv/src/main/java/org/openehr/rm/support/measurement/SimpleMeasurementService.java create mode 100644 measure-serv/src/main/java/org/openehr/rm/support/measurement/SimpleUCUMValidator.java 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 6d9a40d6..be491a5e --- a/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java +++ b/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java @@ -14,47 +14,13 @@ */ 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.archetype.constraintmodel.*; +import org.openehr.am.archetype.constraintmodel.primitive.*; +import org.openehr.am.archetype.ontology.*; import org.openehr.am.openehrprofile.datatypes.quantity.CDvOrdinal; import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantity; import org.openehr.am.openehrprofile.datatypes.quantity.CDvQuantityItem; @@ -70,6 +36,13 @@ import org.openehr.rm.support.identification.ArchetypeID; import org.openehr.rm.support.identification.ObjectID; +import java.io.*; +import java.nio.charset.Charset; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + /** * ADL serializer for the openEHR Java kernel * @@ -174,7 +147,10 @@ protected void printHeader(String adlVersion, out.write(adlVersion); } if(uid != null && StringUtils.isNotEmpty(uid.toString())) { - out.write("uid="); + if (StringUtils.isNotEmpty(adlVersion)) { + out.write("; "); + } + out.write("uid="); out.write(uid.toString()); } if(StringUtils.isNotEmpty(adlVersion) || (uid!=null &&StringUtils.isNotEmpty(uid.toString()))) { @@ -221,14 +197,13 @@ protected void printLanguage(AuthoredResource authored, newline(out); Map translations = authored.getTranslations(); - for(Map.Entry entry: translations.entrySet()) { - String lang = entry.getKey(); - TranslationDetails td = entry.getValue(); - + for(String lang : translations.keySet()) { + TranslationDetails td = translations.get(lang); + indent(2, out); - out.write("[\""); - out.write(lang); - out.write("\"] = <"); + out.write("["); + out.write(quoteString(lang)); + out.write("] = <"); newline(out); indent(3, out); @@ -251,9 +226,9 @@ protected void printLanguage(AuthoredResource authored, if(td.getAccreditation() != null) { indent(3, out); - out.write("accreditation = <\""); - out.write(td.getAccreditation()); - out.write("\">"); + out.write("accreditation = <"); + out.write(quoteString(td.getAccreditation())); + out.write(">"); newline(out); } @@ -282,13 +257,13 @@ protected void printMap(Map map, Writer out, int indent) if(map == null || map.size() == 0) { return; } - for(Map.Entry entry: map.entrySet()) { + for(String key : map.keySet()) { indent(indent, out); - out.write("[\""); - out.write(entry.getKey()); - out.write("\"] = <\""); - out.write(entry.getValue()); - out.write("\">"); + out.write("["); + out.write(quoteString(key)); + out.write("] = <"); + out.write(quoteString(map.get(key))); + out.write(">"); newline(out); } } @@ -307,9 +282,9 @@ protected void printDescription(ResourceDescription description, Writer out) out.write("original_author = <"); newline(out); Map map = description.getOriginalAuthor(); - for (Map.Entry entry: map.entrySet()) { + for (String key : map.keySet()) { indent(2, out); - out.write("[\"" + entry.getKey() + "\"] = <\"" + entry.getValue() + "\">"); + out.write("[" + quoteString(key) + "] = <" + quoteString(map.get(key)) + ">"); newline(out); } indent(1, out); @@ -317,9 +292,9 @@ protected void printDescription(ResourceDescription description, Writer out) newline(out); indent(1, out); - out.write("lifecycle_state = <\""); - out.write(description.getLifecycleState()); - out.write("\">"); + out.write("lifecycle_state = <"); + out.write(quoteString(description.getLifecycleState())); + out.write(">"); newline(out); printNonEmptyString("resource_package_uri", description.getResourcePackageUri(), 1, out); @@ -338,9 +313,9 @@ protected void printDescription(ResourceDescription description, Writer out) protected void printDescriptionItem(ResourceDescriptionItem item, int indent, Writer out) throws IOException { indent(indent, out); - out.write("[\""); - out.write(item.getLanguage().getCodeString()); - out.write("\"] = <"); + out.write("["); + out.write(quoteString(item.getLanguage().getCodeString())); + out.write("] = <"); newline(out); indent(indent + 1, out); @@ -375,9 +350,9 @@ private void printNonEmptyString(String label, String value, int indent, } indent(indent, out); out.write(label); - out.write(" = <\""); - out.write(value); - out.write("\">"); + out.write(" = <"); + out.write(quoteString(value)); + out.write(">"); newline(out); } @@ -391,9 +366,7 @@ private void printNonEmptyStringList(String label, List list, out.write(label); out.write(" = <"); for (int i = 0, j = list.size(); i < j; i++) { - out.write("\""); - out.write(list.get(i)); - out.write("\""); + out.write(quoteString(list.get(i))); if (i != j - 1) { out.write(","); } @@ -413,9 +386,9 @@ private void printNonEmptyStringMap(String label, Map map, out.write(" = <"); newline(out); - for (Map.Entry entry: map.entrySet()) { + for (String key : map.keySet()) { indent(2, out); - out.write("[\"" + entry.getKey() + "\"] = <\"" + entry.getValue() + "\">"); + out.write("[" + quoteString(key) + "] = <" + quoteString(map.get(key)) + ">"); newline(out); } @@ -477,20 +450,21 @@ protected void printOccurrences(Interval occurrences, Writer out) if(occurrences == null || defaultOccurrences.equals(occurrences)) { return; } - - 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())); + 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("}"); } - out.write("}"); } protected void printArchetypeInternalRef(ArchetypeInternalRef ref, @@ -804,14 +778,14 @@ protected void printCDvQuantity(CDvQuantity cquantity, int indent, int index = 1; for (CDvQuantityItem item : list) { indent(indent + 2, out); - out.write("[\""); - out.write(Integer.toString(index)); - out.write("\"] = <"); + out.write("["); + out.write(quoteString(Integer.toString(index))); + out.write("] = <"); newline(out); indent(indent + 3, out); - out.write("units = <\""); - out.write(item.getUnits()); - out.write("\">"); + out.write("units = <"); + out.write(quoteString(item.getUnits())); + out.write(">"); newline(out); Interval value = item.getMagnitude(); if (value != null) { @@ -879,9 +853,9 @@ protected void printDvQuantity(DvQuantity quantity, int indent, Writer out) } protected void printUnits(String units, Writer out) throws IOException { - out.write("units = <\""); - out.write(units); - out.write("\">"); + out.write("units = <"); + out.write(quoteString(units)); + out.write(">"); } protected void printOntology(ArchetypeOntology ontology, Writer out) @@ -894,9 +868,8 @@ protected void printOntology(ArchetypeOntology ontology, Writer out) indent(1, out); out.write("terminologies_available = <"); for (String terminology : ontology.getTerminologies()) { - out.write("\""); - out.write(terminology); - out.write("\", "); + out.write(quoteString(terminology)); + out.write(", "); } out.write("...>"); newline(out); @@ -932,9 +905,9 @@ protected void printOntology(ArchetypeOntology ontology, Writer 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("\"] = <"); + out.write("["); + out.write(quoteString(bind.getTerminology())); + out.write("] = <"); newline(out); indent(3, out); out.write("items = <"); @@ -946,9 +919,9 @@ protected void printOntology(ArchetypeOntology ontology, Writer out) .getTermBindingList().get(i).getBindingList() .get(j); indent(4, out); - out.write("[\""); - out.write(item.getCode()); - out.write("\"] = <"); + out.write("["); + out.write(quoteString(item.getCode())); + out.write("] = <"); out.write(item.getTerms().get(0)); if (item.getTerms().size() > 1) { @@ -980,9 +953,9 @@ protected void printOntology(ArchetypeOntology ontology, Writer out) OntologyBinding bind = ontology.getConstraintBindingList().get( i); indent(2, out); - out.write("[\""); - out.write(bind.getTerminology()); - out.write("\"] = <"); + out.write("["); + out.write(quoteString(bind.getTerminology())); + out.write("] = <"); newline(out); indent(3, out); out.write("items = <"); @@ -994,9 +967,9 @@ protected void printOntology(ArchetypeOntology ontology, Writer out) .getConstraintBindingList().get(i).getBindingList() .get(j); indent(4, out); - out.write("[\""); - out.write(item.getCode()); - out.write("\"] = <"); + out.write("["); + out.write(quoteString(item.getCode())); + out.write("] = <"); out.write(item.getQuery().getUrl()); out.write(">"); newline(out); @@ -1013,29 +986,33 @@ protected void printOntology(ArchetypeOntology ontology, Writer out) } } - private void printDefinitionList(Writer 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(defs.getLanguage()); - out.write("\"] = <"); + 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(term.getCode()); - out.write("\"] = <"); + 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(entry.getValue()); - out.write("\">"); + out.write(" = <"); + out.write(quoteString(entry.getValue())); + out.write(">"); newline(out); } newline(out); @@ -1184,13 +1161,11 @@ protected void printCString(CString cstring, Writer out) throws IOException { } else if(cstring.getList() != null){ printList(cstring.getList(), out, true); } else if(cstring.defaultValue() != null) { - out.write("\""); - out.write(cstring.defaultValue()); - out.write("\""); + out.write(quoteString(cstring.defaultValue())); } if(cstring.hasAssumedValue()) { out.write("; "); - out.write("\"" + cstring.assumedValue() + "\""); + out.write(quoteString(ObjectUtils.toString(cstring.assumedValue(), ""))); } } @@ -1204,13 +1179,12 @@ protected void printList(List list, Writer out, boolean string) if (i != 0) { out.write(","); } + String item = list.get(i).toString(); if (string) { - out.write("\""); - } - out.write(list.get(i).toString()); - if (string) { - out.write("\""); - } + out.write(quoteString(item)); + } else { + out.write(item); + } } } 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 index 72f559ed..d2a88517 100644 --- 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/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 index a8ad84c4..18154d4e 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -24,8 +24,8 @@ org.apache.maven.plugins maven-compiler-plugin - 1.5 - 1.5 + 1.7 + 1.7 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 index 01b20c14..722beb52 100755 --- a/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java @@ -65,7 +65,7 @@ /** * Validator for archetypes *

- * + *

* It checks the following * .archetype term validity * .constraint code validity @@ -78,7 +78,7 @@ * .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 + * .object constraint type name validity * .archetype concept specialisation depth * .use_node type validity * .use_node path validity @@ -86,8 +86,7 @@ * .archetype specialisation parent identifier validity * * @author rong.chen - * @author sebastian.garde - * + * @author sebastian.garde * @version 1.0 */ public class ArchetypeValidator { @@ -100,13 +99,13 @@ public ArchetypeValidator() { try { this.termService = SimpleTerminologyService.getInstance(); - this.openEHRTerminology = termService.terminology( + this.openEHRTerminology = termService.terminology( TerminologyService.OPENEHR); - } catch(Exception e) { + } catch (Exception e) { log.error("failed to start the terminology service", e); } - } + } private boolean reportConstraintsOnCommonFunctionalPropertiesAsInfo = false; @@ -116,14 +115,14 @@ public final void setReportConstraintsOnCommonFunctionalPropertiesAsInfo( } /** - * Validates the given archetype - * + * 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) + public List validate(Archetype archetype, boolean reportConstraintsOnCommonFunctionalPropertiesAsInfo) throws RMInspectionException { this.reportConstraintsOnCommonFunctionalPropertiesAsInfo = reportConstraintsOnCommonFunctionalPropertiesAsInfo; List errors = new ArrayList(); @@ -145,31 +144,36 @@ public List validate(Archetype archetype, boolean reportConstra } - /** - * Validates the given archetype - * + * Validates the given archetype + * * @param archetype * @return list of validation errors or empty list if valid */ - public List validate(Archetype archetype) + public List validate(Archetype archetype) throws RMInspectionException { return validate(archetype, false); } public void checkDescription(Archetype archetype, List errors) { - if (archetype.getDescription() ==null) { + if (archetype.getDescription() == null) { return; } + ArrayList checkedLanguages = new ArrayList<>(); // check purpose in each available language for (ResourceDescriptionItem detail : archetype.getDescription().getDetails().values()) { - if (StringUtils.isBlank(detail.getPurpose()) || StringUtils.containsIgnoreCase(detail.getPurpose(),"unknown")) { - ValidationError error = new ValidationError(ErrorType.VDSCR, "PURPOSE", + 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 @@ -197,12 +201,12 @@ public void checkDescription(Archetype archetype, List errors) } } - public void checkArchetypeDefinitionCodeValidity(Archetype archetype, - List errors) { + 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); + if (!concept.equals(rootNodeId)) { + ValidationError error = new ValidationError(ErrorType.VACCD, null); errors.add(error); } @@ -217,39 +221,39 @@ public void checkArchetypeUnitsValidity(CDvQuantity cDvQuantity, List errors) { + 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 ); + 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) { + List errors) { if (archetype.getParentArchetypeId() == null) { return; // no specialise clause at all @@ -263,27 +267,26 @@ public void checkSpecializationParentIdentifierValidity(Archetype archetype, 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: " + + log.debug("validating ontology code specialisation of archetype: " + archetype.getArchetypeId()); List specialisation = archetype.getArchetypeId().specialisation(); @@ -300,18 +303,18 @@ public void checkOntologyCodeSpecialisationLevelValidity( checkOntologyDefinitions(list, errors, level); list = archetype.getOntology().getConstraintDefinitionsList(); - checkOntologyDefinitions(list, errors, level); + checkOntologyDefinitions(list, errors, level); } private void checkOntologyDefinitions(List defList, - List errors, int level) { + List errors, int level) { ValidationError error = null; - for(OntologyDefinitions defs : defList) { - for(ArchetypeTerm term : defs.getDefinitions()) { - if(hasGreaterSpecialisationLevel(term.getCode(), level)) { + 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); + errors.add(error); } } } @@ -319,7 +322,7 @@ private void checkOntologyDefinitions(List defList, private boolean hasGreaterSpecialisationLevel(String code, int level) { StringTokenizer tokens = new StringTokenizer(code, "."); - if(tokens.countTokens() - 1 > level) { + if (tokens.countTokens() - 1 > level) { return true; } return false; @@ -328,19 +331,20 @@ private boolean hasGreaterSpecialisationLevel(String code, int level) { /** * Checks various object constraints - * + * * @param archetype * @param errors * @throws RMInspectionException */ - public void checkObjectConstraints(Archetype archetype, - List 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 - * + /** + * checks whether the rmAttrName is a commonly constrained functional property of the parentRMType + * * @param rmAttrName * @param parentRMTypeName * @return @@ -360,10 +364,10 @@ private boolean isCommonFunctionalProperty(String rmAttrName, String parentRMTyp } - private void validateCAttribute(CAttribute cattr, - Map rmAttrs, CComplexObject parent, - Archetype archetype, List errors) - throws RMInspectionException { + private void validateCAttribute(CAttribute cattr, + Map rmAttrs, CComplexObject parent, + Archetype archetype, List errors) + throws RMInspectionException { String rmAttrName = cattr.getRmAttributeName(); @@ -376,33 +380,33 @@ private void validateCAttribute(CAttribute cattr, String parentRmClassName = parent.getRmTypeName(); parentRmClassName = removeGenericTypes(parentRmClassName); String parentGenericTypeName = getGenericType(parent.getRmTypeName()); - log.debug("Generic type name: "+ parentGenericTypeName); + log.debug("Generic type name: " + parentGenericTypeName); Class parentRmClass = rmInspector.retrieveRMType(parentRmClassName); Class parentGenericType = null; - if(parentGenericTypeName != null) { + if (parentGenericTypeName != null) { parentGenericType = rmInspector.retrieveRMType(parentGenericTypeName); } // replace primitive types with object types - if(int.class.equals(rmAttrType)) { + if (int.class.equals(rmAttrType)) { rmAttrType = Integer.class; - } else if(double.class.equals(rmAttrType)) { + } else if (double.class.equals(rmAttrType)) { rmAttrType = Double.class; - } else if(boolean.class.equals(rmAttrType)) { + } else if (boolean.class.equals(rmAttrType)) { rmAttrType = Boolean.class; } log.debug("1- validating attribute [" + rmAttrName + "] of type [" + rmAttrType + "]"); - if( ! rmAttrNames.contains(rmAttrName)) { + 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()); + rmAttrName, cattr.path(), parent.getRmTypeName()); } else { - error = new ValidationError(ErrorType.VCARM, null, + error = new ValidationError(ErrorType.VCARM, null, rmAttrName, parent.getRmTypeName(), cattr.path()); } errors.add(error); @@ -410,7 +414,7 @@ private void validateCAttribute(CAttribute cattr, } if (cattr instanceof CMultipleAttribute) { - CMultipleAttribute cmattr = (CMultipleAttribute)cattr; + CMultipleAttribute cmattr = (CMultipleAttribute) cattr; checkCardinalityConformsToRMCardinality(cmattr, parent, errors); //check Cardinality fits with the minimum and maximum of all occurrences of the children @@ -418,13 +422,13 @@ private void validateCAttribute(CAttribute cattr, } - if(cattr.getChildren() == null) { + if (cattr.getChildren() == null) { return; } - for(CObject cobj : cattr.getChildren()) { + for (CObject cobj : cattr.getChildren()) { - if(cattr instanceof CSingleAttribute) { + if (cattr instanceof CSingleAttribute) { // check rm type String childRMTypeName = cobj.getRmTypeName(); @@ -437,33 +441,33 @@ private void validateCAttribute(CAttribute cattr, Class childRMType = rmInspector.retrieveRMType(childRMTypeName); - if(childRMType == null) { - error = new ValidationError(ErrorType.VCORM, null, + 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()); + 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)){ + } else if (parentRmClass.equals(childRMType)) { log.debug("skipping unnecessary check on " + parentRmClass); continue; - } else if(!rmAttrType.isEnum() - && !(rmAttrType.isAssignableFrom(childRMType))){ + } else if (!rmAttrType.isEnum() + && !(rmAttrType.isAssignableFrom(childRMType))) { - log.debug("3- rmAttrType: "+rmAttrType + " with name [" + - rmAttrName+ "] is NOT assignable from type [" + + log.debug("3- rmAttrType: " + rmAttrType + " with name [" + + rmAttrName + "] is NOT assignable from type [" + childRMType + "]"); ErrorType type = ErrorType.VCORMT; - if(cobj instanceof ArchetypeInternalRef) { + if (cobj instanceof ArchetypeInternalRef) { type = ErrorType.VUNT; - } + } error = new ValidationError(type, "NORMAL", childRMTypeName, cobj.path(), rmAttrType.getSimpleName()); if (!errors.contains(error)) { @@ -475,54 +479,54 @@ private void validateCAttribute(CAttribute cattr, && !(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 [" + + 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) { + if (cobj instanceof ArchetypeInternalRef) { type = ErrorType.VUNT; - } + } error = new ValidationError(type, "PARENT", - parentGenericTypeName, parent.path(), childRMType.getSimpleName(), cobj.path()); + parentGenericTypeName, parent.path(), childRMType.getSimpleName(), cobj.path()); errors.add(error); continue; - } + } log.debug("5- rmAttrType: " + rmAttrType + " with name " + - rmAttrName+ " IS assignable from "+ childRMType); + rmAttrName + " IS assignable from " + childRMType); // check csingle attribute child object occurrences Interval occu = cobj.getOccurrences(); - if(occu != null && occu.isUpperIncluded() + if (occu != null && occu.isUpperIncluded() && occu.getUpper() > 1) { - error = new ValidationError(ErrorType.VACSO, null, + error = new ValidationError(ErrorType.VACSO, null, cobj.path()); errors.add(error); - } - for(CObject cobj2 : cattr.getChildren()) { - if(cobj == cobj2) { + } + for (CObject cobj2 : cattr.getChildren()) { + if (cobj == cobj2) { continue; } // check child uniqueness - if(cobj2.getRmTypeName().equals(cobj.getRmTypeName()) + if (cobj2.getRmTypeName().equals(cobj.getRmTypeName()) && cobj.getNodeId() == null) { error = new ValidationError(ErrorType.VACSU, null, cobj.path()); - if( ! errors.contains(error)) { + if (!errors.contains(error)) { errors.add(error); } } // check child identifier - if(cobj2.getNodeId() != null + if (cobj2.getNodeId() != null && cobj2.getNodeId().equals(cobj.getNodeId())) { error = new ValidationError(ErrorType.VACSI, null, cobj.path()); - if( ! errors.contains(error)) { + if (!errors.contains(error)) { errors.add(error); } } @@ -540,12 +544,12 @@ private void validateCAttribute(CAttribute cattr, } 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)) { + 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(), @@ -554,9 +558,9 @@ private void validateCAttribute(CAttribute cattr, getIntervalFormalString(cobj.getOccurrences()), cattr.path()); - if( ! errors.contains(error)) { + if (!errors.contains(error)) { errors.add(error); - } + } } else if (cobj.getNodeId() == null) { // check missing child identifier @@ -565,34 +569,34 @@ private void validateCAttribute(CAttribute cattr, // 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) { + for (CObject cobj2 : cattr.getChildren()) { + if (cobj == cobj2) { continue; } - if(cobj2.getNodeId()== null && cobj2 instanceof ArchetypeInternalRef && + if (cobj2.getNodeId() == null && cobj2 instanceof ArchetypeInternalRef && ((ArchetypeInternalRef) cobj).getTargetPath().equals(((ArchetypeInternalRef) cobj2).getTargetPath())) { - error = new ValidationError(ErrorType.VACMM, "INTREF", + error = new ValidationError(ErrorType.VACMM, "INTREF", cobj.path()); - if( ! errors.contains(error)) { + if (!errors.contains(error)) { errors.add(error); } } } } else { - error = new ValidationError(ErrorType.VACMI, null, + error = new ValidationError(ErrorType.VACMI, null, cobj.path()); errors.add(error); } } else { // check duplicated child identifier - for(CObject cobj2 : cattr.getChildren()) { - if(cobj == cobj2) { + for (CObject cobj2 : cattr.getChildren()) { + if (cobj == cobj2) { continue; } - if(cobj.getNodeId().equals(cobj2.getNodeId())) { + if (cobj.getNodeId().equals(cobj2.getNodeId())) { error = new ValidationError(ErrorType.VACMM, "NORMAL", cobj.path()); - if( ! errors.contains(error)) { + if (!errors.contains(error)) { errors.add(error); } } @@ -603,22 +607,22 @@ private void validateCAttribute(CAttribute cattr, } if (cobj instanceof CDomainType) { // also includes CDVQuantity! - log.debug("validating CDomainType of node_id: "+ cobj.getNodeId()); + 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()); + log.debug("validating CPrimitiveObject at: " + cobj.path()); validateCPrimitiveObject((CPrimitiveObject) cobj, archetype, errors); - } else if(cobj instanceof CComplexObject) { - log.debug("validating ccobj at: "+ cobj.getNodeId()); + } 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()); + } 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()); + } 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()); + log.debug("not continuing with recursion for class: " + cobj.getClass()); } } } @@ -632,7 +636,7 @@ private void checkCardinalityConformsToChildrenOccurrences( } - Interval cardinalityInterval = + Interval cardinalityInterval = (cmattr).getCardinality().getInterval(); int minOcc = 0; @@ -640,56 +644,54 @@ private void checkCardinalityConformsToChildrenOccurrences( boolean isOccUpperUnbounded = false; for (CObject cobj : cmattr.getChildren()) { - minOcc += cobj.getOccurrences().getLower(); + minOcc += cobj.getOccurrences().getLower(); if (cobj.getOccurrences().isUpperUnbounded()) { isOccUpperUnbounded = true; - } else { + } else { maxOcc += cobj.getOccurrences().getUpper(); } } // check lower: - if (! cardinalityInterval.isUpperUnbounded() && minOcc > cardinalityInterval.getUpper()) { + 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)) { + ); + if (!errors.contains(error)) { errors.add(error); return; // found an error, so can return } } // check upper - if ( !isOccUpperUnbounded + 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)) { + if (!errors.contains(error)) { errors.add(error); - } + } } - if (!cardinalityInterval.isUpperUnbounded() && - minOcc != maxOcc && + 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 (TBD) + // 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) - ); + cmattr.path(), getIntervalFormalString(cardinalityInterval), getIntervalFormalString(minOcc, maxOcc, isOccUpperUnbounded)); - if( ! errors.contains(error)) { + if (!errors.contains(error)) { errors.add(error); - } + } } - } private void checkCardinalityConformsToRMCardinality(CMultipleAttribute cattr, CObject cobj, List errors) { @@ -698,7 +700,7 @@ private void checkCardinalityConformsToRMCardinality(CMultipleAttribute cattr, C 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)); + 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 @@ -708,30 +710,32 @@ private void checkCardinalityConformsToRMCardinality(CMultipleAttribute cattr, C if (!rmCardinality.isUpperUnbounded()) { - if (actualCardinality.isUpperUnbounded() || - (rmCardinality.getUpper().compareTo(actualCardinality.getUpper()) <0)) { + 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)); + cattr.path(), getIntervalFormalString(actualCardinality), getIntervalFormalString(rmCardinality)); errors.add(error); - } else if (rmCardinality.getUpper().compareTo(actualCardinality.getUpper()) ==0) { + } else if (rmCardinality.getUpper().compareTo(actualCardinality.getUpper()) == 0) { //WCACA - } + } } } - /** Checks the assertions of an archetype for validity + /** + * 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) { + List errors) { if (slot.getIncludes() != null) { for (Assertion include : slot.getIncludes()) { checkAssertionHasValidArchetypeIds(include, slot, errors); @@ -744,8 +748,9 @@ private void checkArchetypeSlot(ArchetypeSlot slot, Class rmAttrType, Archetype } } - /** Checks that an assertion contains valid archetype ids - * + /** + * Checks that an assertion contains valid archetype ids + * * @param assertion * @param slot * @param errors @@ -755,39 +760,41 @@ private void checkAssertionHasValidArchetypeIds(Assertion assertion, ArchetypeSl ExpressionBinaryOperator ebo = (ExpressionBinaryOperator) assertion.getExpression(); if (ebo.getRightOperand() instanceof ExpressionLeaf) { - ExpressionLeaf elR =(ExpressionLeaf)ebo.getRightOperand(); + ExpressionLeaf elR = (ExpressionLeaf) ebo.getRightOperand(); if (elR.getItem() != null && elR.getItem() instanceof CString) { - CString elRCStr = (CString)elR.getItem(); - if (elRCStr.getPattern() !=null) { + CString elRCStr = (CString) elR.getItem(); + if (elRCStr.getPattern() != null) { String pattern = elRCStr.getPattern(); - if (!pattern.equals(".*")) { + if (!pattern.equals(".*")) { // make readability modifications for the pattern - while (pattern.indexOf("(-[a-zA-Z0-9_]+)*\\") >0) { + while (pattern.indexOf("(-[a-zA-Z0-9_]+)*\\") > 0) { int i = pattern.indexOf("(-[a-zA-Z0-9_]+)*\\"); 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) { + while (pattern.indexOf("\\.") > 0) { pattern = pattern.replace("\\.", "."); } - while (pattern.indexOf("|") >0) { - String oneId = pattern.substring(0,pattern.indexOf("|") ); - pattern = pattern.substring(pattern.indexOf("|")+1); - checkOneArchetypeId(slot, errors, oneId); + while (pattern.indexOf("|") > 0) { + String oneId = pattern.substring(0, pattern.indexOf("|")); + pattern = pattern.substring(pattern.indexOf("|") + 1); + checkOneArchetypeId(slot, errors, oneId); } // the rest of the pattern is the last archetype id, so test this one too. - checkOneArchetypeId(slot, errors, pattern); - } - } + checkOneArchetypeId(slot, errors, pattern); + } + } } - } + } } } - /** Checks one archetype id to be a valid id or not + /** + * Checks one archetype id to be a valid id or not + * * @param slot * @param errors * @param oneId @@ -797,12 +804,12 @@ private void checkOneArchetypeId(ArchetypeSlot slot, List error boolean containsCorrectNumberOfDots = (StringUtils.countMatches(oneId, ".") == 2); // check that the id ends with .v[0..9]* - boolean endsWithDotVNumber =true; // assume it is ok, until proven false - if (oneId.lastIndexOf(".v")== -1) { + boolean endsWithDotVNumber = true; // assume it is ok, until proven false + if (oneId.lastIndexOf(".v") == -1) { endsWithDotVNumber = false; } else { - String tail = oneId.substring(oneId.lastIndexOf(".v")+2); - log.debug("tail: "+ tail); + String tail = oneId.substring(oneId.lastIndexOf(".v") + 2); + log.debug("tail: " + tail); if (tail.length() == 0 || !StringUtils.isNumeric(tail)) { endsWithDotVNumber = false; } @@ -810,7 +817,7 @@ private void checkOneArchetypeId(ArchetypeSlot slot, List error // check that the first part of the id (the qualified RM Entity) contains the right number of hyphens boolean containsCorrectNumberOfHyphensInQualifiedRMEntity = true; // assume it is ok, until proven wrong - String qualifiedRMEntity = oneId.substring(0, oneId.indexOf(".")); + String qualifiedRMEntity = oneId.substring(0, oneId.indexOf(".")); if (StringUtils.countMatches(qualifiedRMEntity, "-") != 2) { containsCorrectNumberOfHyphensInQualifiedRMEntity = false; } @@ -820,13 +827,13 @@ private void checkOneArchetypeId(ArchetypeSlot slot, List error ValidationError error = new ValidationError(ErrorType.VDFAI, "NUMBEROFDOTS", oneId, slot.path()); errors.add(error); - } - if (!endsWithDotVNumber) { + } + if (!endsWithDotVNumber) { ValidationError error = new ValidationError(ErrorType.VDFAI, "DOTVNUMBER", oneId, slot.path()); errors.add(error); } - if (!containsCorrectNumberOfHyphensInQualifiedRMEntity) { + if (!containsCorrectNumberOfHyphensInQualifiedRMEntity) { ValidationError error = new ValidationError(ErrorType.VDFAI, "NUMBEROFHYPHENS", oneId, slot.path()); errors.add(error); @@ -837,57 +844,57 @@ private void checkOneArchetypeId(ArchetypeSlot slot, List error /** * Validates a given c_domain_type constraint - * - * TODO: does not report a problem on values that have a higher precision than specified - * + *

+ * 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) { + */ + private void validateCDomainType(CDomainType cdtobj, Archetype archetype, + List errors) { if (cdtobj.hasAssumedValue()) { - log.debug("validating assumed value: " +cdtobj.getAssumedValue()); + log.debug("validating assumed value: " + cdtobj.getAssumedValue()); if (!cdtobj.validValue(cdtobj.getAssumedValue())) { - ValidationError error = new ValidationError(ErrorType.VOBAV, null, + 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()); - } + } else { + log.debug("No assumed value found for : " + cdtobj.getRmTypeName() + " at " + cdtobj.path()); + } - if(cdtobj instanceof CCodePhrase) { + 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); - } - + 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) { + private void validateCCodePhrase(CCodePhrase ccodephrase, + List errors) { - if(ccodephrase.getCodeList() == null + if (ccodephrase.getCodeList() == null || !TerminologyService.OPENEHR.equalsIgnoreCase( - ccodephrase.getTerminologyId().toString())) { + ccodephrase.getTerminologyId().toString())) { return; } StringBuffer buf = new StringBuffer(); - for(String code : ccodephrase.getCodeList()) { - if( ! openEHRTerminology.allCodes().contains( + 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, + if (codes.length() != 0) { + ValidationError error = new ValidationError(ErrorType.VOTC, null, codes, ccodephrase.path()); errors.add(error); } @@ -903,26 +910,26 @@ private void validateCPrimitiveObject(CPrimitiveObject cpobj, Archetype archetyp CPrimitive item = cpobj.getItem(); if (item.hasAssumedValue()) { Object assumedValue = item.assumedValue(); - log.debug("Assumed value for CPrimitiveObject: "+assumedValue); + log.debug("Assumed value for CPrimitiveObject: " + assumedValue); - if (!item.validValue(assumedValue)) { - ValidationError error = new ValidationError(ErrorType.VOBAV, null, + 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()); + 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()); + } 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 { + List errors) throws RMInspectionException { - checkGenericTypeName(ccobj, errors); - if(ccobj.getAttributes() == null) { + checkGenericTypeName(ccobj, errors); + if (ccobj.getAttributes() == null) { return; } @@ -935,7 +942,7 @@ private void validateCComplexObject(CComplexObject ccobj, Archetype archetype, rmTypeNameWithoutGeneric); ValidationError error = null; - if(rmAttrNames.isEmpty()) { + if (rmAttrNames.isEmpty()) { error = new ValidationError(ErrorType.VCORM, null, rmTypeNameWithoutGeneric, ccobj.path()); errors.add(error); @@ -943,9 +950,9 @@ private void validateCComplexObject(CComplexObject ccobj, Archetype archetype, } - HashSet attributeNames = new HashSet(); - for(CAttribute cattr : ccobj.getAttributes()) { - validateCAttribute(cattr, rmAttrs, ccobj, archetype, errors); + 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())) { @@ -955,40 +962,42 @@ private void validateCComplexObject(CComplexObject ccobj, Archetype archetype, 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 + /** + * 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); + log.debug("Generic type name: " + genericTypeName); Class genericType = null; - if(genericTypeName != null) { + if (genericTypeName != null) { genericType = rmInspector.retrieveRMType(genericTypeName); - log.debug("Generic type: "+ genericType); + log.debug("Generic type: " + genericType); } - if (genericTypeName != null && genericType == null){ + if (genericTypeName != null && genericType == null) { error = new ValidationError(ErrorType.VCORM, null, - ccobj.getRmTypeName(), ccobj.path()); + 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)) { + if (!DvOrdered.class.isAssignableFrom(genericType)) { error = new ValidationError(ErrorType.VCORMT, "NORMAL", - ccobj.getRmTypeName(), ccobj.path(), genericType.getSimpleName()); + ccobj.getRmTypeName(), ccobj.path(), genericType.getSimpleName()); errors.add(error); - } + } } } protected String removeGenericTypes(String rmTypeName) { - if(rmTypeName.indexOf("<") > 0 && rmTypeName.indexOf(">") > 0) { + if (rmTypeName.indexOf("<") > 0 && rmTypeName.indexOf(">") > 0) { rmTypeName = rmTypeName.substring(0, rmTypeName.indexOf("<")); } return rmTypeName; @@ -999,7 +1008,7 @@ protected String getGenericType(String rmTypeName) { int start = rmTypeName.indexOf("<"); int end = rmTypeName.indexOf(">"); String genericType = null; - if(start > 0 && end > start) { + if (start > 0 && end > start) { genericType = rmTypeName.substring(start + 1, end); } return genericType; @@ -1007,50 +1016,50 @@ protected String getGenericType(String rmTypeName) { /** * Checks the given ArchetypeInternalRef - * + * * @param ref * @param archetype * @param errors */ public void checkArchetypeInternalRef(ArchetypeInternalRef ref, /*Class rmAttributeType,*/ Archetype archetype, - List errors) { + List errors) { log.debug("validating internal_ref of rmType: " + ref.getRmTypeName() + - " at " +ref.path() + " with target " +ref.getTargetPath()); + " 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) { + 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) { + 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) { + 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()); + "Unknown target rm type at path: " + ref.getTargetPath() + + " of internalRef at: " + ref.path()); errors.add(error); - } else if( ! rmType.isAssignableFrom(targetType)) { + } else if (!rmType.isAssignableFrom(targetType)) { error = new ValidationError(ErrorType.VUNP, "INVALIDTARGETRM", targetType, ref.path()); errors.add(error); - } + } } } @@ -1058,63 +1067,77 @@ public void checkArchetypeInternalRef(ArchetypeInternalRef ref, * 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) { + public void checkArchetypeDefinitionTypename(Archetype archetype, + List errors) { String conceptType = archetype.getArchetypeId().rmEntity(); String topType = archetype.getDefinition().getRmTypeName(); ValidationError error = null; - if( ! conceptType.equals(topType)) { + 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 - * + * Checks if languages listed in translation section are provided in + * term_definition and constraint_definition sections + *

* TODO: how about missing individual term_def/constraint_def translations? - * + * * @param archetype * @return errors */ public void checkOntologyTranslation(Archetype archetype, - List errors) { + List errors) { Set languages = archetype.languagesAvailable(); String primaryLang = archetype.getOriginalLanguage().getCodeString(); - List termDefList = - archetype.getOntology().getTermDefinitionsList(); - List constraintDefList = - archetype.getOntology().getConstraintDefinitionsList(); + + 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) { - if(primaryLang.equals(lang)) { + ValidationError error; + for (String lang : languages) { + if (primaryLang.equals(lang)) { continue; } - if( ! termDefLangs.contains(lang)) { + if (!termDefLangs.contains(lang)) { error = new ValidationError(ErrorType.VOTM, "TERM", lang); errors.add(error); } - if(!constraintDefList.isEmpty() + 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) { + for (OntologyDefinitions defs : list) { set.add(defs.getLanguage()); } return set; @@ -1122,7 +1145,7 @@ private Set retrieveLanguageSet(List list) { /** * TODO not used - * + *

* Check internal references * * @return map of node path, target path if any wrong internal references @@ -1134,16 +1157,16 @@ Map checkInternalReferences(Archetype archetype) { } private Map checkInternalReferences(Archetype archetype, - CComplexObject ccobj, - Map errors) { + 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()); + CObject target = (CObject) archetype.node(ref.getTargetPath()); if (target == null || !target.getRmTypeName().equals( - cobj.getRmTypeName())) { + cobj.getRmTypeName())) { // either target unknown or wrong type errors.put(ref.path(), ref.getTargetPath()); } @@ -1158,17 +1181,17 @@ private Map checkInternalReferences(Archetype archetype, } public void checkArchetypeTermValidity(Archetype archetype, - List errors) { - Set codes = fetchAllATCodes(archetype); + List errors) { + Set codes = fetchAllATCodes(archetype); String lang = archetype.getOriginalLanguage().getCodeString(); - List defList = + List defList = archetype.getOntology().getTermDefinitionsList(); OntologyDefinitions priDefs = null; ValidationError error = null; ArrayList secondaryLanguageOntDefs = new ArrayList(); - for(OntologyDefinitions defs : defList) { - if(lang.equals(defs.getLanguage())) { + for (OntologyDefinitions defs : defList) { + if (lang.equals(defs.getLanguage())) { priDefs = defs; } else { secondaryLanguageOntDefs.add(defs); @@ -1177,8 +1200,8 @@ public void checkArchetypeTermValidity(Archetype archetype, // first check for the primary language Set definedCodesPrimLang = new LinkedHashSet(); - if(priDefs == null) { - for(String code : codes) { + if (priDefs == null) { + for (String code : codes) { error = new ValidationError(ErrorType.VATDF, "NORMAL", code); errors.add(error); @@ -1186,12 +1209,12 @@ public void checkArchetypeTermValidity(Archetype archetype, } else { List terms = priDefs.getDefinitions(); - for(ArchetypeTerm term : terms) { + for (ArchetypeTerm term : terms) { definedCodesPrimLang.add(term.getCode()); } - for(String code : codes) { - if( ! definedCodesPrimLang.contains(code)) { - error = new ValidationError(ErrorType.VATDF, "NORMAL", + for (String code : codes) { + if (!definedCodesPrimLang.contains(code)) { + error = new ValidationError(ErrorType.VATDF, "NORMAL", code); errors.add(error); } @@ -1199,16 +1222,16 @@ public void checkArchetypeTermValidity(Archetype archetype, } // now check for the secondary languages - for (OntologyDefinitions secDefs :secondaryLanguageOntDefs) { + for (OntologyDefinitions secDefs : secondaryLanguageOntDefs) { List terms = secDefs.getDefinitions(); Set definedCodesSecLang = new LinkedHashSet(); - for(ArchetypeTerm term : terms) { + for (ArchetypeTerm term : terms) { definedCodesSecLang.add(term.getCode()); } - for(String code : codes) { + for (String code : codes) { // if not present in sec lang, but present in prim lang: - if( ! definedCodesSecLang.contains(code) && definedCodesPrimLang.contains(code)) { + if (!definedCodesSecLang.contains(code) && definedCodesPrimLang.contains(code)) { error = new ValidationError(ErrorType.VONLC, "TERM", code, secDefs.getLanguage()); errors.add(error); @@ -1222,17 +1245,17 @@ public void checkArchetypeTermValidity(Archetype archetype, } public void checkCodeConstraintValidity(Archetype archetype, - List errors) { - Set codes = fetchAllACCodes(archetype); + List errors) { + Set codes = fetchAllACCodes(archetype); String lang = archetype.getOriginalLanguage().getCodeString(); - List defList = + List defList = archetype.getOntology().getConstraintDefinitionsList(); OntologyDefinitions priDefs = null; ValidationError error = null; ArrayList secondaryLanguageOntDefs = new ArrayList(); - for(OntologyDefinitions defs : defList) { - if(lang.equals(defs.getLanguage())) { + for (OntologyDefinitions defs : defList) { + if (lang.equals(defs.getLanguage())) { priDefs = defs; } else { secondaryLanguageOntDefs.add(defs); @@ -1241,19 +1264,19 @@ public void checkCodeConstraintValidity(Archetype archetype, Set definedCodesPrimLang = new LinkedHashSet(); - if(priDefs == null) { - for(String code : codes) { + 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) { + for (ArchetypeTerm term : terms) { definedCodesPrimLang.add(term.getCode()); } - for(String code : codes) { - if( ! definedCodesPrimLang.contains(code)) { + for (String code : codes) { + if (!definedCodesPrimLang.contains(code)) { error = new ValidationError(ErrorType.VACDF, null, code); errors.add(error); @@ -1262,16 +1285,16 @@ public void checkCodeConstraintValidity(Archetype archetype, } // now check for the secondary languages - for (OntologyDefinitions secDefs :secondaryLanguageOntDefs) { + for (OntologyDefinitions secDefs : secondaryLanguageOntDefs) { List terms = secDefs.getDefinitions(); Set definedCodesSecLang = new LinkedHashSet(); - for(ArchetypeTerm term : terms) { + for (ArchetypeTerm term : terms) { definedCodesSecLang.add(term.getCode()); } - for(String code : codes) { + for (String code : codes) { // if not present in sec lang, but present in prim lang: - if( ! definedCodesSecLang.contains(code) && definedCodesPrimLang.contains(code)) { + if (!definedCodesSecLang.contains(code) && definedCodesPrimLang.contains(code)) { error = new ValidationError(ErrorType.VONLC, "CONSTRAINT", code, secDefs.getLanguage()); errors.add(error); @@ -1282,58 +1305,59 @@ public void checkCodeConstraintValidity(Archetype archetype, checkForUnusedCodes(defList, errors, archetype, codes); checkForDoubleCodes(defList, errors, archetype); - } - + } - /** Checks for unused codes in the ontology - * + /** + * Checks for unused codes in the ontology + * * @param defList * @param errors * @param archetype */ private void checkForUnusedCodes(List defList, - List errors, Archetype archetype, Set actuallyUsedCodes) { + 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())) { + 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); - } + errors.add(error); + } } } } } - /** Checks for codes in the ontology that are there more than once - * + /** + * 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) { + List errors, Archetype archetype) { // now check for each code if it exists in the definition ValidationError error = null; - for(OntologyDefinitions defs : defList) { + for (OntologyDefinitions defs : defList) { HashSet foundCodes = new HashSet(); - for(ArchetypeTerm term : defs.getDefinitions()) { - if(foundCodes.contains(term.getCode())) { + 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); + errors.add(error); } else { foundCodes.add(term.getCode()); } @@ -1342,7 +1366,7 @@ private void checkForDoubleCodes(List defList, } public void checkArchetypeTermBindingsValidity(Archetype archetype, - List errors) { + List errors) { List termBindings = archetype.getOntology().getTermBindingList(); ValidationError error = null; @@ -1350,7 +1374,7 @@ public void checkArchetypeTermBindingsValidity(Archetype archetype, 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) { + if (archetype.getOntology().termDefinition(archetype.getOriginalLanguage().getCodeString(), obi.getCode()) == null) { error = new ValidationError(ErrorType.WITB, "ATCODE", obi.getCode()); errors.add(error); @@ -1360,7 +1384,7 @@ public void checkArchetypeTermBindingsValidity(Archetype archetype, error = new ValidationError(ErrorType.WITB, "PATH", obi.getCode()); errors.add(error); - } + } } } } @@ -1370,7 +1394,7 @@ public void checkArchetypeTermBindingsValidity(Archetype archetype, /** * Traverse the archetype and gather all at codes - * + * * @param archetype * @return a set of at codes */ @@ -1387,43 +1411,43 @@ Set fetchAllATCodes(Archetype archetype) { } void fetchATCodes(CObject cobj, Set codes) { - if(cobj.getNodeId() != null) { + if (cobj.getNodeId() != null) { codes.add(cobj.getNodeId()); } - if(cobj instanceof CComplexObject) { - CComplexObject ccobj = (CComplexObject) cobj; + if (cobj instanceof CComplexObject) { + CComplexObject ccobj = (CComplexObject) cobj; List cattrList = ccobj.getAttributes(); - if(cattrList == null) { + if (cattrList == null) { return; } - for(CAttribute cattr : cattrList) { + for (CAttribute cattr : cattrList) { List children = cattr.getChildren(); - if(children == null) { + if (children == null) { continue; } - for(CObject child : children) { + for (CObject child : children) { fetchATCodes(child, codes); } } - } else if(cobj instanceof CDvOrdinal) { + } else if (cobj instanceof CDvOrdinal) { CDvOrdinal cord = (CDvOrdinal) cobj; List list = cord.getList(); - if(list != null) { - for(Ordinal ord : list) { + if (list != null) { + for (Ordinal ord : list) { CodePhrase code = ord.getSymbol(); - if("local".equalsIgnoreCase( + if ("local".equalsIgnoreCase( code.getTerminologyId().name())) { codes.add(code.getCodeString()); - } + } } } - } else if(cobj instanceof CCodePhrase) { + } else if (cobj instanceof CCodePhrase) { CCodePhrase ccod = (CCodePhrase) cobj; List list = ccod.getCodeList(); - if("local".equalsIgnoreCase(ccod.getTerminologyId().name()) + if ("local".equalsIgnoreCase(ccod.getTerminologyId().name()) && list != null) { - for(String code : list) { - if(code.startsWith("at")) { + for (String code : list) { + if (code.startsWith("at")) { codes.add(code); } } @@ -1433,52 +1457,54 @@ void fetchATCodes(CObject cobj, Set codes) { /** * 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); + 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; + if (cobj instanceof CComplexObject) { + CComplexObject ccobj = (CComplexObject) cobj; List cattrList = ccobj.getAttributes(); - if(cattrList == null) { + if (cattrList == null) { return; } - for(CAttribute cattr : cattrList) { + for (CAttribute cattr : cattrList) { List children = cattr.getChildren(); - if(children == null) { + if (children == null) { continue; } - for(CObject child : children) { + for (CObject child : children) { fetchACCodes(child, codes); } } - } else if(cobj instanceof CCodePhrase) { + } else if (cobj instanceof CCodePhrase) { CCodePhrase ccod = (CCodePhrase) cobj; List list = ccod.getCodeList(); - if(list != null) { - for(String code : list) { - if(code.startsWith("ac")) { + if (list != null) { + for (String code : list) { + if (code.startsWith("ac")) { codes.add(code); } } - } - } else if(cobj instanceof ConstraintRef) { + } + } else if (cobj instanceof ConstraintRef) { ConstraintRef ref = (ConstraintRef) cobj; - if(ref.getReference().startsWith("ac")) { + if (ref.getReference().startsWith("ac")) { codes.add(ref.getReference()); } } } - /** Constructs a formal String for representing this Interval + /** + * Constructs a formal String for representing this Interval + * * @param interval * @return */ @@ -1494,14 +1520,14 @@ protected String getIntervalFormalString(Integer lower, Integer upper, boolean i lower = Integer.valueOf(0); } - String formal= ""+lower.intValue() +".."; + String formal = "" + lower.intValue() + ".."; if (isUpperUnbounded) { formal += "*"; } else { formal += upper.intValue(); } - return formal; + return formal; } 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 index 161d9d18..4133dfe6 100644 --- a/archetype-validator/src/main/java/org/openehr/am/validation/ErrorType.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ErrorType.java @@ -49,6 +49,7 @@ public enum ErrorType { 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. 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 index 37445cd7..7757c20c 100755 --- a/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java @@ -5,6 +5,7 @@ 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; @@ -192,8 +193,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(); if (klass.getSimpleName().equalsIgnoreCase("Double")) { @@ -318,6 +319,7 @@ public Class retrieveRMType(String rmClassName) { * * @param rmClassName * @return + * @throws RMObjectBuildingException */ public Map retrieveRMAttributes(String rmClassName) { Class rmClass = retrieveRMType(rmClassName); @@ -328,11 +330,10 @@ public Map retrieveRMAttributes(String rmClassName) { Map map = attributeType(rmClass); Map ret = new HashMap(); - for(Map.Entry entry : map.entrySet()) { - String name = entry.getKey(); - ret.put(toUnderscoreSeparated(name), entry.getValue()); + for(String name : map.keySet()) { + ret.put(toUnderscoreSeparated(name), map.get(name)); - log.debug("rmattribute: " +name +": "+ entry.getValue()); + log.debug("rmattribute: " +name +": "+ map.get(name)); } return ret; } @@ -343,6 +344,7 @@ public Map retrieveRMAttributes(String rmClassName) { * * @param rmClassName * @return + * @throws RMObjectBuildingException */ public Set retrieveRMAttributeNames(String rmClassName) { Class rmClass = retrieveRMType(rmClassName); @@ -410,8 +412,8 @@ public String findMatchingRMClass(Map valueMap) { // replace underscore separated names with camel case Map filteredMap = new HashMap(); - for (Map.Entry entry : valueMap.entrySet()) { - filteredMap.put(toCamelCase(entry.getKey()), entry.getValue()); + for (String name : valueMap.keySet()) { + filteredMap.put(toCamelCase(name), valueMap.get(name)); } Constructor constructor = fullConstructor(rmClass); @@ -488,6 +490,28 @@ 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; + } + /** 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, 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 old mode 100755 new mode 100644 index 7d6a1f8e..e7aa9dfb --- a/archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java @@ -209,7 +209,9 @@ private void checkSpecialisedAttribute(CAttribute cattr, Archetype archetype, if (parentNodeInParentArchetype == null) { log.debug("PARENT NODE IN PARENT ARCHETYPE IS NULL"); - } else if (parentNodeInParentArchetype instanceof CComplexObject) { + } + + 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? @@ -606,11 +608,10 @@ private void checkSpecialisedRMTypeCompatiblityOfValueChildren(CAttribute cattr, if (!assignable) { log.debug("VSONCT error: at "+child.path()); - StringBuffer buf = new StringBuffer(); + String parentRefTypes = ""; for (Entry parentToRMTypeWithoutGenerics: parentObjectsToRMTypesWithoutGenerics.entrySet()) { - buf.append(parentToRMTypeWithoutGenerics.getValue().getSimpleName() +", "); + parentRefTypes += parentToRMTypeWithoutGenerics.getValue().getSimpleName() +", "; } - String parentRefTypes = buf.toString(); parentRefTypes = parentRefTypes.substring(0,parentRefTypes.length()-2); if (parentObjectsToRMTypesWithoutGenerics.size() ==1) { @@ -673,7 +674,6 @@ private String getExpectedPathInParentArchetype(String path, int parentArchetype 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))); - StringBuffer buffer = new StringBuffer(expectedPath); for (String pathPart : pathParts) { String pathEnd = ""; @@ -691,12 +691,11 @@ private String getExpectedPathInParentArchetype(String path, int parentArchetype 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 +" "+ buffer.toString()); + log.debug("Path ends with at0: "+ pathPart +" "+expectedPath); return null; } - buffer.append(pathPart + pathEnd+sep); + expectedPath += pathPart + pathEnd+sep; } - expectedPath = buffer.toString(); if (expectedPath.length() >1 && expectedPath.endsWith(sep)) { expectedPath = expectedPath.substring(0,expectedPath.length()-1); // get rid of tailing separator } diff --git a/archetype-validator/src/main/resources/validations.properties b/archetype-validator/src/main/resources/validations.properties index 81381f48..0e6fbb9e 100644 --- a/archetype-validator/src/main/resources/validations.properties +++ b/archetype-validator/src/main/resources/validations.properties @@ -42,11 +42,12 @@ WACMC=Cardinality/occurrences validity warning: where occurrences and cardinalit 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}). +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}. @@ -110,4 +111,5 @@ 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. \ No newline at end of file +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/test/java/org/openehr/am/validation/ArchetypeTermValidityTest.java b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeTermValidityTest.java index b6a03919..f43de6c8 100644 --- a/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeTermValidityTest.java +++ b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeTermValidityTest.java @@ -61,6 +61,16 @@ public void testCheckTermWithDoubleEntryInOntology() throws Exception { } } + 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/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/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 59db611e..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 @@ -29,7 +29,7 @@ * @version 1.0 * */ -public final class SimpleMeasurementService implements MeasurementService { +public class SimpleMeasurementService implements MeasurementService { /** * @@ -92,13 +92,15 @@ private SimpleMeasurementService() { "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" + "{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 currrently assumes case-sensitive UCUM format. + * Note that this implementation currently assumes case-sensitive UCUM format. * * @param units * @return true if units valid @@ -109,9 +111,16 @@ public boolean isValidUnitsString(String units) { 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)) { +/* if (commonUCUMCodes.contains(units)) { return true; } @@ -124,7 +133,7 @@ public boolean isValidUnitsString(String 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)); @@ -141,7 +150,7 @@ public boolean isValidUnitsString(String units) { System.out.println("Unit NOT parsed CI: "+ units); } */ - return unit!= null; + // return unit!= null; } /** 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 index e5d26eed..c9a27940 100644 --- 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 @@ -6,31 +6,31 @@ 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", "MG")); - assertFalse(service.unitsEquivalent("mg", "mG")); - assertTrue(service.unitsEquivalent("A", "C/s")); - - 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")); @@ -42,16 +42,578 @@ public void testunitsValid() throws Exception { 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; } From af0626e7806f1ffdb8c65d54961f62f7434938a0 Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Thu, 27 Aug 2015 11:51:24 +0200 Subject: [PATCH 143/213] CDS-868 Fix Sonar critical issues on adl-serializer --- .../main/java/org/openehr/am/serialize/ADLSerializer.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) mode change 100644 => 100755 adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java 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 100644 new mode 100755 index 2f6bf29b..01b72cea --- a/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java +++ b/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java @@ -197,9 +197,10 @@ protected void printLanguage(AuthoredResource authored, newline(out); Map translations = authored.getTranslations(); - for(String lang : translations.keySet()) { - TranslationDetails td = translations.get(lang); - + for(Map.Entry entry: translations.entrySet()) { + String lang = entry.getKey(); + TranslationDetails td = entry.getValue(); + indent(2, out); out.write("["); out.write(quoteString(lang)); From 88a92007eab87aa05ec322935943f0ab9733d660 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Wed, 7 Jun 2017 10:36:30 +0200 Subject: [PATCH 144/213] Merging with pubic repository --- .../openehr/am/serialize/ADLSerializer.java | 241 +++++++++--------- .../measurement/MeasurementService.java | 8 +- .../measurement/SimpleMeasurementService.java | 2 +- .../terminology/SimpleTerminologyAccess.java | 5 +- .../archetype/assertion/ExpressionLeaf.java | 4 +- .../archetype/constraintmodel/CAttribute.java | 5 +- .../datatypes/quantity/CDvQuantity.java | 5 +- .../openehr/rm/composition/Composition.java | 10 +- .../composition/content/entry/Evaluation.java | 3 + .../content/entry/Observation.java | 5 +- .../openehr/rm/util/SkeletonGenerator.java | 13 +- .../java/org/openehr/binding/XMLBinding.java | 2 +- .../openehr/am/serialize/XMLSerializer.java | 8 +- 13 files changed, 156 insertions(+), 155 deletions(-) mode change 100644 => 100755 measure-serv/src/main/java/org/openehr/rm/support/measurement/MeasurementService.java mode change 100644 => 100755 measure-serv/src/main/java/org/openehr/rm/support/measurement/SimpleMeasurementService.java mode change 100644 => 100755 mini-termserv/src/main/java/org/openehr/terminology/SimpleTerminologyAccess.java mode change 100644 => 100755 openehr-aom/src/main/java/org/openehr/am/archetype/assertion/ExpressionLeaf.java mode change 100644 => 100755 openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CAttribute.java mode change 100644 => 100755 openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvQuantity.java mode change 100644 => 100755 openehr-rm-domain/src/main/java/org/openehr/rm/composition/Composition.java mode change 100644 => 100755 openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Evaluation.java mode change 100644 => 100755 openehr-rm-domain/src/main/java/org/openehr/rm/composition/content/entry/Observation.java mode change 100644 => 100755 rm-skeleton/src/main/java/org/openehr/rm/util/SkeletonGenerator.java mode change 100644 => 100755 xml-binding/src/main/java/org/openehr/binding/XMLBinding.java 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 index 01b72cea..8b749261 100755 --- a/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java +++ b/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java @@ -45,11 +45,11 @@ /** * ADL serializer for the openEHR Java kernel - * + * * @author Rong Chen * @author Mattias Forss, Johan Hjalmarsson * @author Sebastian Garde - * + * * @version 1.0 */ public class ADLSerializer { @@ -65,7 +65,7 @@ public ADLSerializer() { /** * Output given archetype as string in ADL format - * + * * @param archetype * @return a string in ADL format * @throws IOException @@ -76,9 +76,9 @@ public String output(Archetype archetype) throws IOException { return writer.toString(); } - /** + /** * Output archetype DEFINITION as string in ADL format - * + * * @param archetype * @return a string in ADL format * @throws IOException @@ -87,13 +87,13 @@ 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 @@ -107,40 +107,40 @@ public void output(Archetype archetype, OutputStream out) /** * 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(), + 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); + 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 { + 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) || (uid != null && StringUtils.isNotEmpty(uid.toString()))) { + out.write(" ("); + } if(StringUtils.isNotEmpty(adlVersion)) { out.write("adl_version="); @@ -151,11 +151,11 @@ protected void printHeader(String adlVersion, out.write("; "); } out.write("uid="); - out.write(uid.toString()); - } - if(StringUtils.isNotEmpty(adlVersion) || (uid!=null &&StringUtils.isNotEmpty(uid.toString()))) { - out.write(")"); - } + 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()); @@ -176,9 +176,9 @@ protected void printHeader(String adlVersion, out.write("[" + conceptCode + "]"); newline(out); } - + protected void printLanguage(AuthoredResource authored, - Writer out) throws IOException { + Writer out) throws IOException { out.write("language"); newline(out); @@ -195,18 +195,17 @@ protected void printLanguage(AuthoredResource authored, indent(1, out); out.write("translations = <"); newline(out); - Map translations = - authored.getTranslations(); - for(Map.Entry entry: translations.entrySet()) { - String lang = entry.getKey(); - TranslationDetails td = entry.getValue(); + 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("["); @@ -216,15 +215,15 @@ protected void printLanguage(AuthoredResource authored, out.write("]"); out.write(">"); newline(out); - + indent(3, out); out.write("author = <"); - newline(out); - printMap(td.getAuthor(), out, 4); + newline(out); + printMap(td.getAuthor(), out, 4); indent(3, out); out.write(">"); newline(out); - + if(td.getAccreditation() != null) { indent(3, out); out.write("accreditation = <"); @@ -232,19 +231,19 @@ protected void printLanguage(AuthoredResource authored, out.write(">"); newline(out); } - + if(td.getOtherDetails() != null) { indent(3, out); out.write("other_details = <"); - newline(out); - printMap(td.getOtherDetails(), out, 4); + newline(out); + printMap(td.getOtherDetails(), out, 4); indent(3, out); out.write(">"); newline(out); } - + indent(2, out); - out.write(">"); + out.write(">"); newline(out); } indent(1, out); @@ -252,18 +251,18 @@ protected void printLanguage(AuthoredResource authored, newline(out); } } - - protected void printMap(Map map, Writer out, int indent) + + protected void printMap(Map map, Writer out, int indent) throws IOException { if(map == null || map.size() == 0) { return; } - for(String key : map.keySet()) { + for(Map.Entry entry: map.entrySet()) { indent(indent, out); out.write("["); - out.write(quoteString(key)); + out.write(quoteString(entry.getKey())); out.write("] = <"); - out.write(quoteString(map.get(key))); + out.write(quoteString(entry.getValue())); out.write(">"); newline(out); } @@ -283,9 +282,9 @@ protected void printDescription(ResourceDescription description, Writer out) out.write("original_author = <"); newline(out); Map map = description.getOriginalAuthor(); - for (String key : map.keySet()) { + for (Map.Entry entry: map.entrySet()) { indent(2, out); - out.write("[" + quoteString(key) + "] = <" + quoteString(map.get(key)) + ">"); + out.write("[" + quoteString(entry.getKey()) + "] = <" + quoteString(entry.getValue()) + ">"); newline(out); } indent(1, out); @@ -299,7 +298,7 @@ protected void printDescription(ResourceDescription description, Writer out) newline(out); printNonEmptyString("resource_package_uri", description.getResourcePackageUri(), 1, out); - + indent(1, out); out.write("details = <"); newline(out); @@ -312,7 +311,7 @@ protected void printDescription(ResourceDescription description, Writer out) } protected void printDescriptionItem(ResourceDescriptionItem item, - int indent, Writer out) throws IOException { + int indent, Writer out) throws IOException { indent(indent, out); out.write("["); out.write(quoteString(item.getLanguage().getCodeString())); @@ -327,7 +326,7 @@ protected void printDescriptionItem(ResourceDescriptionItem item, out.write(item.getLanguage().getCodeString()); out.write("]>"); newline(out); - + printNonEmptyString("purpose", item.getPurpose(), indent + 1, out); printNonEmptyStringList("keywords", item.getKeywords(), indent + 1, out); @@ -344,7 +343,7 @@ protected void printDescriptionItem(ResourceDescriptionItem item, } private void printNonEmptyString(String label, String value, int indent, - Writer out) throws IOException { + Writer out) throws IOException { if (StringUtils.isEmpty(value)) { return; @@ -358,7 +357,7 @@ private void printNonEmptyString(String label, String value, int indent, } private void printNonEmptyStringList(String label, List list, - int indent, Writer out) throws IOException { + int indent, Writer out) throws IOException { if (list == null || list.isEmpty()) { return; @@ -377,7 +376,7 @@ private void printNonEmptyStringList(String label, List list, } private void printNonEmptyStringMap(String label, Map map, - int indent, Writer out) throws IOException { + int indent, Writer out) throws IOException { if (map == null || map.isEmpty()) { return; } @@ -387,9 +386,9 @@ private void printNonEmptyStringMap(String label, Map map, out.write(" = <"); newline(out); - for (String key : map.keySet()) { + for (Map.Entry entry: map.entrySet()) { indent(2, out); - out.write("[" + quoteString(key) + "] = <" + quoteString(map.get(key)) + ">"); + out.write("[" + quoteString(entry.getKey()) + "] = <" + quoteString(entry.getValue()) + ">"); newline(out); } @@ -408,16 +407,16 @@ protected void printDefinition(CComplexObject definition, Writer out) } protected void printCComplexObject(CComplexObject ccobj, int indent, - Writer out) throws IOException { - + Writer out) throws IOException { + // TODO skip c_obj with [0,0] occurrences Interval occurrences = ccobj.getOccurrences(); - if(occurrences != null + if(occurrences != null && (Integer.valueOf(0).equals(occurrences.getLower())) && (Integer.valueOf(0).equals(occurrences.getUpper()))) { - return; + return; } - + // print rmTypeName and nodeId indent(indent, out); @@ -469,12 +468,12 @@ protected void printOccurrences(Interval occurrences, Writer out) } protected void printArchetypeInternalRef(ArchetypeInternalRef ref, - int indent, Writer out) throws IOException { + 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(" "); out.write(ref.getTargetPath()); newline(out); } @@ -503,33 +502,33 @@ protected void printArchetypeSlot(ArchetypeSlot slot, int indent, Writer out) } newline(out); indent(indent, out); - out.write("}"); + out.write("}"); } newline(out); } - + private void printAssertions(Set assertions, String purpose, - int indent, Writer out) throws IOException { + 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 + + // 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: // @@ -552,7 +551,7 @@ protected void printCAttribute(CAttribute cattribute, int indent, Writer out) CMultipleAttribute cma = (CMultipleAttribute) cattribute; if(cma.getCardinality() != null) { out.write(" "); - printCardinality(cma.getCardinality(), out); + printCardinality(cma.getCardinality(), out); } } List children = cattribute.getChildren(); @@ -604,7 +603,7 @@ protected void printCObject(CObject cobj, int indent, Writer out) printConstraintRef((ConstraintRef) cobj, indent, out); } } - + protected void printConstraintRef(ConstraintRef ref, int indent, Writer out) throws IOException { indent(indent, out); out.write("["); @@ -650,9 +649,9 @@ protected void printCDomainType(CDomainType cdomain, int indent, Writer out) 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); + } + else if (cdomain instanceof CCodePhrase) { + printCCodePhrase((CCodePhrase) cdomain, indent, out); } // unknow CDomainType } @@ -661,7 +660,7 @@ protected void printCCodePhrase(CCodePhrase ccoded, int indent, Writer out) throws IOException { indent(indent, out); - + if(ccoded.isAnyAllowed()) { out.write("C_CODE_PHRASE <"); newline(out); @@ -704,7 +703,7 @@ protected void printCCodePhrase(CCodePhrase ccoded, int indent, Writer out) } out.write("]"); newline(out); - } + } } else { out.write("]"); newline(out); @@ -725,9 +724,9 @@ protected void printCDvOrdinal(CDvOrdinal cordinal, int indent, Writer out) newline(out); } else { - for (Iterator it = cordinal.getList().iterator(); - it.hasNext();) { - Ordinal ordinal = it.next(); + for (Iterator it = cordinal.getList().iterator(); + it.hasNext();) { + Ordinal ordinal = it.next(); indent(indent, out); printOrdinal(ordinal, out); if (it.hasNext()) { @@ -735,17 +734,17 @@ protected void printCDvOrdinal(CDvOrdinal cordinal, int indent, Writer out) } else if(cordinal.hasAssumedValue()) { out.write(";"); } - newline(out); + newline(out); } if(cordinal.hasAssumedValue()) { printOrdinal(cordinal.getAssumedValue(), out); newline(out); } - } + } } - protected void printOrdinal(Ordinal ordinal, Writer out) + protected void printOrdinal(Ordinal ordinal, Writer out) throws IOException { CodePhrase symbol = ordinal.getSymbol(); out.write(Integer.toString(ordinal.getValue())); @@ -753,11 +752,11 @@ protected void printOrdinal(Ordinal ordinal, Writer out) out.write(symbol.getTerminologyId().getValue()); out.write("::"); out.write(symbol.getCodeString()); - out.write("]"); + out.write("]"); } protected void printCDvQuantity(CDvQuantity cquantity, int indent, - Writer out) throws IOException { + Writer out) throws IOException { indent(indent, out); out.write("C_DV_QUANTITY <"); newline(out); @@ -772,7 +771,7 @@ protected void printCDvQuantity(CDvQuantity cquantity, int indent, } List list = cquantity.getList(); if (list != null) { - newline(out); + newline(out); indent(indent + 1, out); out.write("list = <"); newline(out); @@ -796,7 +795,7 @@ protected void printCDvQuantity(CDvQuantity cquantity, int indent, out.write(">"); newline(out); } - + Interval precision = item.getPrecision(); if (precision != null) { indent(indent + 3, out); @@ -814,10 +813,10 @@ protected void printCDvQuantity(CDvQuantity cquantity, int indent, out.write(">"); newline(out); } - - + + if(cquantity.getAssumedValue() != null) { - newline(out); + newline(out); indent(indent + 1, out); out.write("assumed_value = <"); newline(out); @@ -825,20 +824,20 @@ protected void printCDvQuantity(CDvQuantity cquantity, int indent, indent(indent + 1, out); out.write(">"); newline(out); - } - + } + indent(indent, out); out.write(">"); newline(out); } - - protected void printDvQuantity(DvQuantity quantity, int indent, Writer 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 = <"); @@ -852,7 +851,7 @@ protected void printDvQuantity(DvQuantity quantity, int indent, Writer out) out.write(">"); newline(out); } - + protected void printUnits(String units, Writer out) throws IOException { out.write("units = <"); out.write(quoteString(units)); @@ -927,8 +926,8 @@ protected void printOntology(ArchetypeOntology ontology, Writer out) if (item.getTerms().size() > 1) { for (int k = 1; k < item.getTerms().size(); k++) { - out.write("," + item.getTerms().get(k)); - } + out.write("," + item.getTerms().get(k)); + } } out.write(">"); @@ -987,12 +986,12 @@ protected void printOntology(ArchetypeOntology ontology, Writer out) } } - private String quoteString(String value) { - return "\"" + value.replaceAll("[\"]", "\\\\$0") + "\""; - } + private String quoteString(String value) { + return "\"" + value.replaceAll("[\"]", "\\\\$0") + "\""; + } private void printDefinitionList(Writer out, - List termDefinitionsList) throws IOException { + List termDefinitionsList) throws IOException { for (OntologyDefinitions defs : termDefinitionsList) { indent(2, out); out.write("["); @@ -1070,7 +1069,7 @@ protected void printCBoolean(CBoolean cboolean, Writer out) } else { out.write("false"); } - } + } } protected void printCDate(CDate cdate, Writer out) throws IOException { @@ -1184,8 +1183,8 @@ protected void printList(List list, Writer out, boolean string) if (string) { out.write(quoteString(item)); } else { - out.write(item); - } + out.write(item); + } } } @@ -1194,7 +1193,7 @@ protected void printInterval(Interval interval, Writer out) out.write("|"); if (interval.getLower() != null && interval.getUpper() != null) { if(interval.getLower().equals(interval.getUpper()) - && interval.isLowerIncluded() + && interval.isLowerIncluded() && interval.isUpperIncluded()) { out.write(interval.getLower().toString()); } else { @@ -1239,27 +1238,27 @@ private void indent(int level, Writer out) throws IOException { } /* * ***** 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, + * + * 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 ***** - */ + */ \ No newline at end of file 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 old mode 100644 new mode 100755 index 4c8aea2a..ff616f08 --- 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 100644 new mode 100755 index 86578cfc..8ca2b4fe --- 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 @@ -29,7 +29,7 @@ * @version 1.0 * */ -public class SimpleMeasurementService implements MeasurementService { +public final class SimpleMeasurementService implements MeasurementService { /** * diff --git a/mini-termserv/src/main/java/org/openehr/terminology/SimpleTerminologyAccess.java b/mini-termserv/src/main/java/org/openehr/terminology/SimpleTerminologyAccess.java old mode 100644 new mode 100755 index ffd6b06a..779d8b16 --- 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/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 old mode 100644 new mode 100755 index 3236a149..64da1e6c --- 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/constraintmodel/CAttribute.java b/openehr-aom/src/main/java/org/openehr/am/archetype/constraintmodel/CAttribute.java old mode 100644 new mode 100755 index c1154a8b..39675493 --- 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-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 old mode 100644 new mode 100755 index adea374d..4589b90d --- 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-rm-domain/src/main/java/org/openehr/rm/composition/Composition.java b/openehr-rm-domain/src/main/java/org/openehr/rm/composition/Composition.java old mode 100644 new mode 100755 index 2854eda6..6238cd32 --- 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 @@ -83,6 +83,11 @@ public Composition(@Attribute(name = "uid") UIDBasedID uid, throw new IllegalArgumentException("empty content"); } + if (category == null) { + throw new IllegalArgumentException("null category"); + } + + // Is_persistent_validity: is_persistent implies context = Void if (isPersistent(category) && context != null) { throw new IllegalArgumentException("invalid persistent category"); } @@ -96,11 +101,6 @@ public Composition(@Attribute(name = "uid") UIDBasedID uid, 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) 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 old mode 100644 new mode 100755 index 1d764424..6d8711b3 --- 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 @@ -141,6 +141,9 @@ void setData(ItemStructure data) { @Override public boolean equals(Object obj) { + if(obj == null) { + return false; + } if (this == obj) { return true; } 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 old mode 100644 new mode 100755 index 278ee0bc..59e8190c --- 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 @@ -188,7 +188,10 @@ void setState(History state) { @Override public boolean equals(Object obj) { - if (this == obj) { + if(obj == null) { + return false; + } + if (this == obj) { return true; } if (getClass() != obj.getClass()) { 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 old mode 100644 new mode 100755 index 999f1ee8..fc878312 --- 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()); @@ -701,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) { diff --git a/xml-binding/src/main/java/org/openehr/binding/XMLBinding.java b/xml-binding/src/main/java/org/openehr/binding/XMLBinding.java old mode 100644 new mode 100755 index 5ba90bfd..7d7a640f --- a/xml-binding/src/main/java/org/openehr/binding/XMLBinding.java +++ b/xml-binding/src/main/java/org/openehr/binding/XMLBinding.java @@ -199,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); 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 07fbd552..57a77d87 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 @@ -263,12 +263,12 @@ private void printCodePhrase(CodePhrase cp, Element out) { private void printStringMap(String label, Map map, Element out) { if(map != null && !map.isEmpty()) { - for(String key : map.keySet()) { + for(Map.Entry entry : map.entrySet()) { Element elm = new Element(label, defaultNamespace); out.getChildren().add(elm); - elm.setAttribute("id", key); - if (map.get(key) != null) { - elm.setText(map.get(key)); + elm.setAttribute("id", entry.getKey()); + if (entry.getValue() != null) { + elm.setText(map.get(entry.getValue())); } } } From 22b59b128981c1b2278e368995d288a2793821d6 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Wed, 7 Jun 2017 10:38:04 +0200 Subject: [PATCH 145/213] Merging with pubic repository --- .gitignore | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) mode change 100644 => 100755 .gitignore diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index f5099798..6da410cc --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,40 @@ -*.iml -.idea/* -*/target/* +.idea/ +adl-parser/adl-parser.iml +adl-parser/target/ +adl-serializer/adl-serializer.iml +adl-serializer/target/ +archetype-validator/archetype-validator.iml +archetype-validator/target/ +dadl-binding/dadl-binding.iml +dadl-binding/target/ +dadl-binding/tree_2_slots.dadl +dadl-parser/dadl-parser.iml +dadl-parser/target/ +measure-serv/measure-serv.iml +measure-serv/target/ +mini-termserv/mini-termserv.iml +mini-termserv/target/ +oet-parser/oet-parser.iml +oet-parser/target/ +oet-parser/term_map.txt +oet-parser/test_paths.txt +openehr-aom/openehr-aom.iml +openehr-aom/target/ +openehr-ap/openehr-ap.iml +openehr-ap/target/ +openehr-rm-core/openehr-rm-core.iml +openehr-rm-core/target/ +openehr-rm-domain/openehr-rm-domain.iml +openehr-rm-domain/target/ +ref_impl_java.iml +rm-builder/rm-builder.iml +rm-builder/target/ +rm-skeleton/hypersensitivity_max.dadl +rm-skeleton/hypersensitivity_min.dadl +rm-skeleton/rm-skeleton.iml +rm-skeleton/target/ +target/ +xml-binding/target/ +xml-binding/xml-binding.iml +xml-serializer/target/ +xml-serializer/xml-serializer.iml \ No newline at end of file From e65bbd1ca1d99dbf3a89fa17a8089691ca570ec1 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Wed, 7 Jun 2017 10:46:25 +0200 Subject: [PATCH 146/213] Merging with pubic repository --- .../openehr/am/serialize/ADLSerializer.java | 27 +- .../org/openehr/am/template/Flattener.java | 24 +- .../java/org/openehr/am/template/PathMap.java | 5 +- .../java/org/openehr/am/template/TermMap.java | 30 +- .../datatypes/quantity/datetime/DvDate.java | 10 + .../quantity/datetime/DvDateTime.java | 17 +- .../datatypes/quantity/datetime/DvTime.java | 23 +- .../org/openehr/build/RMObjectBuilder.java | 33 +- .../java/org/openehr/binding/RMInspector.java | 1019 ++++++++--------- 9 files changed, 583 insertions(+), 605 deletions(-) mode change 100644 => 100755 oet-parser/src/main/java/org/openehr/am/template/Flattener.java mode change 100644 => 100755 oet-parser/src/main/java/org/openehr/am/template/PathMap.java mode change 100644 => 100755 oet-parser/src/main/java/org/openehr/am/template/TermMap.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDate.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTime.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvTime.java mode change 100644 => 100755 rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java mode change 100644 => 100755 xml-binding/src/main/java/org/openehr/binding/RMInspector.java 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 index 8b749261..1593f7de 100755 --- a/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java +++ b/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java @@ -450,21 +450,20 @@ protected void printOccurrences(Interval occurrences, Writer out) 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("}"); + + 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, 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 old mode 100644 new mode 100755 index 7a7421e6..a9db2108 --- 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; 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 old mode 100644 new mode 100755 index e04927be..2d424055 --- 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 old mode 100644 new mode 100755 index 43ff7eb4..da10b53b --- 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/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 old mode 100644 new mode 100755 index a498086a..6d9c68f9 --- 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; @@ -222,6 +223,7 @@ public boolean isStrictlyComparableTo(DvOrdered ordered) { return false; } + @Override public boolean equals(Object o) { if (!super.equals(o)) return false; @@ -235,6 +237,14 @@ 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. 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 old mode 100644 new mode 100755 index efdee72c..e9416363 --- 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; @@ -305,12 +306,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,6 +321,15 @@ 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) { 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 old mode 100644 new mode 100755 index 3545ed07..2d103b24 --- 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 @@ -15,6 +15,7 @@ package org.openehr.rm.datatypes.quantity.datetime; 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; @@ -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,6 +284,15 @@ 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) { diff --git a/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java b/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java old mode 100644 new mode 100755 index 827294d0..6e814d99 --- a/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java +++ b/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java @@ -340,8 +340,8 @@ public RMObject construct(String rmClassName, 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); Map typeMap = attributeType(rmClass); @@ -349,7 +349,8 @@ public RMObject construct(String rmClassName, Map valueMap) Map attributeMap = attributeMap(rmClass); Object[] valueArray = new Object[indexMap.size()]; - for (String name : typeMap.keySet()) { + for (Map.Entry entry : typeMap.entrySet()) { + String name = entry.getKey(); Object value = filteredMap.get(name); @@ -357,7 +358,7 @@ public RMObject construct(String rmClassName, Map valueMap) throw new RMObjectBuildingException("unknown attribute " + name); } - Class type = typeMap.get(name); + Class type = entry.getValue(); Integer index = indexMap.get(name); Attribute attribute = attributeMap.get(name); @@ -418,7 +419,7 @@ else if (value instanceof String) { // for DvProportion.precision } else if (type.equals(Integer.class)) { - value = new Integer(str); + value = Integer.valueOf(str); // for DvBoolean.value } else if (type.equals(boolean.class)) { @@ -452,7 +453,7 @@ else if (value instanceof String) { value = set; } // check type - else if (value != null && !type.isPrimitive()) { + else if (!type.isPrimitive()) { try { type.cast(value); } catch (ClassCastException e) { @@ -504,10 +505,10 @@ else if (value != null && value.getClass().equals(Long.class)) private String toString(Map map) { StringBuffer buf = new StringBuffer(); - for (String key : map.keySet()) { - buf.append(key); + for (Map.Entry entry : map.entrySet()) { + buf.append(entry.getKey()); buf.append("="); - Object value = map.get(key); + Object value = entry.getValue(); if (value != null) { buf.append(value.getClass().getName()); buf.append(":"); @@ -608,8 +609,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); @@ -695,15 +696,15 @@ private Object defaultValue(Class type) { } else if (type == float.class) { return new Float(0); } else if (type == int.class) { - return new Integer(0); + return Integer.valueOf(0); } else if (type == short.class) { - return new Short((short) 0); + return Short.valueOf((short) 0); } else if (type == long.class) { - return new Long(0); + return Long.valueOf(0); } else if (type == char.class) { - return new Character((char) 0); + return Character.valueOf((char) 0); } else if (type == byte.class) { - return new Byte((byte) 0); + return Byte.valueOf((byte) 0); } return null; } diff --git a/xml-binding/src/main/java/org/openehr/binding/RMInspector.java b/xml-binding/src/main/java/org/openehr/binding/RMInspector.java old mode 100644 new mode 100755 index 2a15910b..95c9a884 --- a/xml-binding/src/main/java/org/openehr/binding/RMInspector.java +++ b/xml-binding/src/main/java/org/openehr/binding/RMInspector.java @@ -1,523 +1,498 @@ -package org.openehr.binding; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Constructor; +package org.openehr.binding; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; import java.util.*; - -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; -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.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.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.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.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, - - // 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, - UUID.class, - VersionTreeID.class, - - // datatypes classes - DvBoolean.class, - DvURI.class, - DvState.class, - DvIdentifier.class, - DvText.class, - DvCodedText.class, - DvParagraph.class, - CodePhrase.class, - DvCount.class, - DvOrdinal.class, - DvQuantity.class, - DvInterval.class, - DvProportion.class, - ProportionKind.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, 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 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) { - Class rmClass = typeMap.get(rmClassName); - if (rmClass == null) { - rmClass = upperCaseMap.get(rmClassName.replace("_", "")); - } - 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); - - 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; - } - - /* - * 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)); - } -} + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +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.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.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.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.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, + + // 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, + UUID.class, + VersionTreeID.class, + + // datatypes classes + DvBoolean.class, + DvURI.class, + DvState.class, + DvIdentifier.class, + DvText.class, + DvCodedText.class, + DvParagraph.class, + CodePhrase.class, + DvCount.class, + DvOrdinal.class, + DvQuantity.class, + DvInterval.class, + DvProportion.class, + ProportionKind.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, 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 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) { + Class rmClass = typeMap.get(rmClassName); + if (rmClass == null) { + rmClass = upperCaseMap.get(rmClassName.replace("_", "")); + } + return rmClass; + } + + /** + * Retrieves Map of attribute classes indexed by names of given class + * + * @param rmClassName + * @return + */ + 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(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; + } + + /** + * Retrieves list of attribute names of given class; each name is converted + * from camel case to underscore delimited form + * + * @param rmClassName + * @return + */ + public Set retrieveRMAttributeNames(String rmClassName) { + Class rmClass = retrieveRMType(rmClassName); + + 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(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 " + + 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; + } + + /* + * 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)); + } +} From 311e7d1eef5d966eced41a200f5954db4754a156 Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Thu, 27 Aug 2015 19:55:44 +0200 Subject: [PATCH 147/213] CDS-868 Fix SonarCube critical issues on archetype-validator, dadl-binding and openehr-rm-core --- .../am/validation/ArchetypeValidator.java | 9 +++-- .../openehr/am/validation/RMInspector.java | 35 +++--------------- .../SpecialisedArchetypeValidator.java | 15 ++++---- .../org/openehr/rm/binding/DADLBinding.java | 10 ++--- .../org/openehr/rm/binding/RMInspector.java | 34 +++-------------- .../org/openehr/rm/binding/XPathUtil.java | 37 ++++++------------- .../src/test/resources/log4j.properties | 4 +- .../rm/common/archetyped/Locatable.java | 9 +++-- .../common/changecontrol/VersionedObject.java | 31 ++++++++-------- .../datastructure/itemstructure/ItemList.java | 3 ++ .../itemstructure/ItemSingle.java | 4 ++ .../itemstructure/ItemTable.java | 6 ++- .../datastructure/itemstructure/ItemTree.java | 4 ++ .../itemstructure/representation/Cluster.java | 4 ++ .../rm/datatypes/quantity/DvCount.java | 2 +- .../datatypes/quantity/datetime/DvDate.java | 10 ++--- .../quantity/datetime/DvDateTime.java | 10 ++--- .../quantity/datetime/DvDateTimeParser.java | 3 +- .../quantity/datetime/DvDuration.java | 1 - .../datatypes/quantity/datetime/DvTime.java | 10 ++--- 20 files changed, 94 insertions(+), 147 deletions(-) mode change 100644 => 100755 archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java mode change 100644 => 100755 archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java mode change 100644 => 100755 dadl-binding/src/main/java/org/openehr/rm/binding/DADLBinding.java mode change 100644 => 100755 dadl-binding/src/main/java/org/openehr/rm/binding/RMInspector.java mode change 100644 => 100755 dadl-binding/src/test/resources/log4j.properties mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/common/changecontrol/VersionedObject.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemList.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemSingle.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemTable.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemTree.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/representation/Cluster.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvCount.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeParser.java 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 old mode 100644 new mode 100755 index 81ad855c..5b6a3856 --- a/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java @@ -893,13 +893,14 @@ private void validateCCodePhrase(CCodePhrase ccodephrase, ccodephrase.getTerminologyId().toString())) { return; } - String codes = ""; + StringBuffer buf = new StringBuffer(); for(String code : ccodephrase.getCodeList()) { if( ! openEHRTerminology.allCodes().contains( new CodePhrase(TerminologyService.OPENEHR, code))) { - codes += code + ", "; + buf.append(code + ", "); } } + String codes = buf.toString(); if(codes.length() != 0) { ValidationError error = new ValidationError(ErrorType.VOTC, null, codes, ccodephrase.path()); @@ -908,7 +909,7 @@ private void validateCCodePhrase(CCodePhrase ccodephrase, } /** - * @param cobj + * @param cpobj * @param archetype * @param errors */ @@ -1518,7 +1519,7 @@ protected String getIntervalFormalString(Interval interval) { protected String getIntervalFormalString(Integer lower, Integer upper, boolean isUpperUnbounded) { if (lower == null) { - lower = new Integer(0); + lower = Integer.valueOf(0); } String formal= ""+lower.intValue() +".."; 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 index 7757c20c..e9521202 100755 --- a/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java @@ -319,7 +319,6 @@ public Class retrieveRMType(String rmClassName) { * * @param rmClassName * @return - * @throws RMObjectBuildingException */ public Map retrieveRMAttributes(String rmClassName) { Class rmClass = retrieveRMType(rmClassName); @@ -330,10 +329,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; } @@ -344,7 +344,6 @@ public Map retrieveRMAttributes(String rmClassName) { * * @param rmClassName * @return - * @throws RMObjectBuildingException */ public Set retrieveRMAttributeNames(String rmClassName) { Class rmClass = retrieveRMType(rmClassName); @@ -412,8 +411,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); @@ -490,28 +489,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; - } - /** 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, 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 old mode 100644 new mode 100755 index e7aa9dfb..7d6a1f8e --- a/archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java @@ -209,9 +209,7 @@ private void checkSpecialisedAttribute(CAttribute cattr, Archetype archetype, if (parentNodeInParentArchetype == null) { log.debug("PARENT NODE IN PARENT ARCHETYPE IS NULL"); - } - - if (parentNodeInParentArchetype instanceof CComplexObject) { + } else 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? @@ -608,10 +606,11 @@ private void checkSpecialisedRMTypeCompatiblityOfValueChildren(CAttribute cattr, if (!assignable) { log.debug("VSONCT error: at "+child.path()); - String parentRefTypes = ""; + StringBuffer buf = new StringBuffer(); for (Entry parentToRMTypeWithoutGenerics: parentObjectsToRMTypesWithoutGenerics.entrySet()) { - parentRefTypes += parentToRMTypeWithoutGenerics.getValue().getSimpleName() +", "; + buf.append(parentToRMTypeWithoutGenerics.getValue().getSimpleName() +", "); } + String parentRefTypes = buf.toString(); parentRefTypes = parentRefTypes.substring(0,parentRefTypes.length()-2); if (parentObjectsToRMTypesWithoutGenerics.size() ==1) { @@ -674,6 +673,7 @@ private String getExpectedPathInParentArchetype(String path, int parentArchetype 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))); + StringBuffer buffer = new StringBuffer(expectedPath); for (String pathPart : pathParts) { String pathEnd = ""; @@ -691,11 +691,12 @@ private String getExpectedPathInParentArchetype(String path, int parentArchetype 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); + log.debug("Path ends with at0: "+ pathPart +" "+ buffer.toString()); return null; } - expectedPath += pathPart + pathEnd+sep; + buffer.append(pathPart + pathEnd+sep); } + expectedPath = buffer.toString(); if (expectedPath.length() >1 && expectedPath.endsWith(sep)) { expectedPath = expectedPath.substring(0,expectedPath.length()-1); // get rid of tailing separator } 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 old mode 100644 new mode 100755 index 025803ef..db2dba0c --- 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/RMInspector.java b/dadl-binding/src/main/java/org/openehr/rm/binding/RMInspector.java old mode 100644 new mode 100755 index 238ff00d..4707a8fd --- a/dadl-binding/src/main/java/org/openehr/rm/binding/RMInspector.java +++ b/dadl-binding/src/main/java/org/openehr/rm/binding/RMInspector.java @@ -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 1d2c53a8..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 @@ -38,10 +38,10 @@ private void buildPath(Object obj, String path, Set paths) throws Except inspector.retrieveRMAttributes(obj.getClass().getSimpleName()); Class klass = obj.getClass(); - String className = klass.getSimpleName(); Map attributeMap = inspector.attributeMap(klass); - for(String attributeName : attributeMap.keySet()) { - Attribute attribute = attributeMap.get(attributeName); + for(Map.Entry entry : attributeMap.entrySet()) { + String attributeName = entry.getKey(); + Attribute attribute = entry.getValue(); if(attribute.system()) { continue; @@ -78,9 +78,9 @@ private void buildPaths(Object obj, String apath, String xpath, Map>> className: " + className); - Map attributeMap = inspector.attributeMap(klass); - for(String attributeName : attributeMap.keySet()) { - - //System.out.println("Attribute name: " + attributeName); - Attribute attribute = attributeMap.get(attributeName); + for(Map.Entry entry : attributeMap.entrySet()) { + String attributeName = entry.getKey(); + Attribute attribute = entry.getValue(); if(attribute.system()) { continue; @@ -125,8 +120,6 @@ private void buildPaths(Object obj, String apath, String xpath, Map "+currentAPath); buildPaths(value, currentAPath, currentXPath, paths); } } - } else { - //System.out.println("---- skip class: " + obj.getClass().getSimpleName()); } } @@ -168,8 +157,6 @@ public Set extractRootXPaths(Locatable root) throws Exception { 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 paths) throws Ex } inspector.retrieveRMAttributes(obj.getClass().getSimpleName()); Class klass = obj.getClass(); - String className = klass.getSimpleName(); Map attributeMap = inspector.attributeMap(klass); - for(String attributeName : attributeMap.keySet()) { - Attribute attribute = attributeMap.get(attributeName); + for(Map.Entry entry : attributeMap.entrySet()) { + String attributeName = entry.getKey(); + Attribute attribute = entry.getValue(); if(attribute.system()) { continue; // skip system attributes diff --git a/dadl-binding/src/test/resources/log4j.properties b/dadl-binding/src/test/resources/log4j.properties old mode 100644 new mode 100755 index b67fb578..0b885667 --- 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/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 eb8c4f41..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 @@ -185,9 +185,11 @@ public static List dividePathIntoSegments(String path) { StringTokenizer tokens = new StringTokenizer(path, "/"); while(tokens.hasMoreTokens()) { String next = tokens.nextToken(); + StringBuffer buffer = new StringBuffer(); if (next.matches(".+\\[.+[^\\]]$")) { do { - next = next + "/" + tokens.nextToken(); + buffer.append(next + "/" + tokens.nextToken()); + next = buffer.toString(); } while (!next.matches(".*]$")); } segments.add(next); @@ -282,7 +284,6 @@ public String toFirstUpperCaseCamelCase(String name) { * for example: [at0001, 'node name'] * * @param expression - * @param value * @return null if there is no match */ Object processPredicate(String expression, Object object) { @@ -361,7 +362,7 @@ 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; @@ -565,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; } 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 old mode 100644 new mode 100755 index 0a2c178c..0495dd61 --- 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/datastructure/itemstructure/ItemList.java b/openehr-rm-core/src/main/java/org/openehr/rm/datastructure/itemstructure/ItemList.java old mode 100644 new mode 100755 index c4d0b76d..dacbfe42 --- 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 @@ -170,6 +170,9 @@ public int hashCode() { @Override public boolean equals(Object obj) { + if(obj == null) { + return false; + } if (this == obj) { return true; } 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 old mode 100644 new mode 100755 index 5dce1fdb..b15918df --- 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 @@ -147,6 +147,10 @@ public int hashCode() { @Override public boolean equals(Object obj) { + if(obj == null) { + return false; + } + if (this == obj) { return true; } 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 old mode 100644 new mode 100755 index 1afc9fbe..d3e56336 --- 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 @@ -366,7 +366,11 @@ public int hashCode() { @Override //Generated by Eclipse public boolean equals(Object obj) { - if (this == obj) + if(obj == null) { + return false; + } + + if (this == obj) return true; if (getClass() != obj.getClass()) return false; 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 old mode 100644 new mode 100755 index 66c264c9..cb7c65ac --- 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 @@ -129,6 +129,10 @@ public List getItems() { * @return equals if true */ public boolean equals(Object obj) { + if(obj == null) { + return false; + } + if (this == obj) { return true; } 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 old mode 100644 new mode 100755 index 44ee3781..892933bc --- 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 @@ -157,6 +157,10 @@ public int hashCode() { @Override public boolean equals(Object obj) { + if(obj == null) { + return false; + } + if (this == obj) { return true; } 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 old mode 100644 new mode 100755 index e0d6b536..27e42530 --- 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); } /** 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 6d9c68f9..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 @@ -251,14 +251,10 @@ public int hashCode() { */ 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 e9416363..70454084 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 @@ -332,14 +332,10 @@ public int 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 old mode 100644 new mode 100755 index 15d24129..2c6052e9 --- 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 88afcef1..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 @@ -160,7 +160,6 @@ protected DvDuration(List> referenceRanges, */ 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())); } 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 2d103b24..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 @@ -295,14 +295,10 @@ public int 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; } From 06a65136bc30775c2590a7a067fa545617bb574e Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Fri, 28 Aug 2015 08:32:32 +0200 Subject: [PATCH 148/213] Fix unnecessary output in unit tests within rm-builder --- rm-builder/src/main/resources/log4j.properties | 4 ++-- .../java/org/openehr/build/DataTypesBuildTest.java | 11 ++++------- 2 files changed, 6 insertions(+), 9 deletions(-) mode change 100644 => 100755 rm-builder/src/main/resources/log4j.properties mode change 100644 => 100755 rm-builder/src/test/java/org/openehr/build/DataTypesBuildTest.java diff --git a/rm-builder/src/main/resources/log4j.properties b/rm-builder/src/main/resources/log4j.properties old mode 100644 new mode 100755 index ebb694fb..969642f8 --- 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/DataTypesBuildTest.java b/rm-builder/src/test/java/org/openehr/build/DataTypesBuildTest.java old mode 100644 new mode 100755 index bcf62401..f8e905e9 --- a/rm-builder/src/test/java/org/openehr/build/DataTypesBuildTest.java +++ b/rm-builder/src/test/java/org/openehr/build/DataTypesBuildTest.java @@ -181,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; @@ -199,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); @@ -226,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); From 52527aa4f654ebf8fc24aa29977f6ccb2cf29ff2 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Fri, 11 Sep 2015 16:59:36 +0200 Subject: [PATCH 149/213] Updating to use css-cds-3 repo --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 pom.xml diff --git a/pom.xml b/pom.xml old mode 100644 new mode 100755 index 5f7849c4..9ec62cd9 --- a/pom.xml +++ b/pom.xml @@ -110,12 +110,12 @@ repo.cambio.se_releases releases - http://repo.cambio.se/content/repositories/releases + http://css-cds-3:8081/nexus/content/repositories/releases repo.cambio.se_snapshots snapshots - http://repo.cambio.se/content/repositories/snapshots + http://css-cds-3:8081/nexus/content/repositories/snapshots From 9efc28719e50da58ec8feafbede961e6a6842c8a Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Mon, 19 Oct 2015 10:31:46 +0200 Subject: [PATCH 150/213] Simplifying gitignore --- .gitignore | 36 ++---------------------------------- 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/.gitignore b/.gitignore index 6da410cc..1135625c 100755 --- a/.gitignore +++ b/.gitignore @@ -1,40 +1,8 @@ .idea/ -adl-parser/adl-parser.iml -adl-parser/target/ -adl-serializer/adl-serializer.iml -adl-serializer/target/ -archetype-validator/archetype-validator.iml -archetype-validator/target/ -dadl-binding/dadl-binding.iml -dadl-binding/target/ +*.iml +target dadl-binding/tree_2_slots.dadl -dadl-parser/dadl-parser.iml -dadl-parser/target/ -measure-serv/measure-serv.iml -measure-serv/target/ -mini-termserv/mini-termserv.iml -mini-termserv/target/ -oet-parser/oet-parser.iml -oet-parser/target/ oet-parser/term_map.txt oet-parser/test_paths.txt -openehr-aom/openehr-aom.iml -openehr-aom/target/ -openehr-ap/openehr-ap.iml -openehr-ap/target/ -openehr-rm-core/openehr-rm-core.iml -openehr-rm-core/target/ -openehr-rm-domain/openehr-rm-domain.iml -openehr-rm-domain/target/ -ref_impl_java.iml -rm-builder/rm-builder.iml -rm-builder/target/ rm-skeleton/hypersensitivity_max.dadl rm-skeleton/hypersensitivity_min.dadl -rm-skeleton/rm-skeleton.iml -rm-skeleton/target/ -target/ -xml-binding/target/ -xml-binding/xml-binding.iml -xml-serializer/target/ -xml-serializer/xml-serializer.iml \ No newline at end of file From 0bb9409e8b7a05867422a584943855b9eaf52562 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Oct 2015 10:47:53 +0200 Subject: [PATCH 151/213] [maven-release-plugin] prepare release ref_impl_java-1.0.14 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 7b8c0d74..92b215b9 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 1522d5d5..cf55acfe 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 6a32525d..c9df096a 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index cd2213a3..9fc9f17a 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 95ba67f6..5b6e0946 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index f42489c6..3251c00d 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 318a0ced..f6821d80 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 5541d8b2..1e876fa6 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index efaa9b62..8e30a6d2 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 30fdd038..7b4610e1 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 4e174ab5..097a890f 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index b9a75f7f..d15c0cd3 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 9ec62cd9..86e8d6b0 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.14-SNAPSHOT + 1.0.14 The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - HEAD + ref_impl_java-1.0.14 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index b1296eeb..0d736efb 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index cf8f1340..e9c2e23c 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 23aa0840..3fa570eb 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index d7142447..4e42f6b4 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.14-SNAPSHOT + 1.0.14 xml-serializer jar From ebb9baf1c864c620f68e573e199028d6233284c7 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Oct 2015 10:48:02 +0200 Subject: [PATCH 152/213] [maven-release-plugin] prepare for next development iteration --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 92b215b9..cb853c20 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index cf55acfe..57c4842a 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index c9df096a..796f0b01 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 9fc9f17a..eb6d5017 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 5b6e0946..5e33de4a 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 3251c00d..51f66e44 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index f6821d80..feb63190 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 1e876fa6..ca727aa1 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 8e30a6d2..18bb7ae8 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 7b4610e1..8e044377 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 097a890f..f79fca81 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index d15c0cd3..36566fc2 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 86e8d6b0..34fef468 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.14 + 1.0.15-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - ref_impl_java-1.0.14 + HEAD diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 0d736efb..47243de4 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index e9c2e23c..405f8bf8 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 3fa570eb..94aad897 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 4e42f6b4..b819f977 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.14 + 1.0.15-SNAPSHOT xml-serializer jar From 90a5ab7aa850378dbc6e40a17a99ee20b5435557 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Mon, 19 Oct 2015 11:23:26 +0200 Subject: [PATCH 153/213] Providing a fix for the release issue --- pom.xml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 34fef468..c8d30958 100755 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,23 @@ - + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + openehr-rm-core openehr-rm-domain From 04344ea100b06d81e3ef9fd892d48fab549dae2d Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Oct 2015 11:45:20 +0200 Subject: [PATCH 154/213] [maven-release-plugin] prepare release ref_impl_java-1.0.15 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index cb853c20..aff68468 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 57c4842a..e6695574 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 796f0b01..b65aba87 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index eb6d5017..724701b3 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 5e33de4a..530c6abd 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 51f66e44..aa8e5135 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index feb63190..fdec44ae 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index ca727aa1..02419359 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 18bb7ae8..d4194eb5 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 8e044377..774209f7 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index f79fca81..f29d9dc5 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 36566fc2..521c7b83 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index c8d30958..76d1abd4 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.15-SNAPSHOT + 1.0.15 The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - HEAD + ref_impl_java-1.0.15 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 47243de4..fcec5913 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 405f8bf8..64112f1f 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 94aad897..75bb16ef 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index b819f977..8b4923c0 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.15-SNAPSHOT + 1.0.15 xml-serializer jar From 7172930fb4718750958301a3e040c5c27370d980 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Oct 2015 11:45:29 +0200 Subject: [PATCH 155/213] [maven-release-plugin] prepare for next development iteration --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index aff68468..330f2dec 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index e6695574..576478ac 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index b65aba87..1d7c4f69 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 724701b3..efe3b8dd 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 530c6abd..ccc99314 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index aa8e5135..cb4dd474 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index fdec44ae..d8e8be1e 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 02419359..bcf1fa40 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index d4194eb5..b70bf8ff 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 774209f7..28b05320 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index f29d9dc5..85bebf48 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 521c7b83..52a47358 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 76d1abd4..eb530dec 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.15 + 1.0.16-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - ref_impl_java-1.0.15 + HEAD diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index fcec5913..dd89d7dc 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 64112f1f..976157b6 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 75bb16ef..4392b913 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 8b4923c0..7453c711 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.15 + 1.0.16-SNAPSHOT xml-serializer jar From 0039f45f0059808a99357218b6ba77aabd06a8bc Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Mon, 19 Oct 2015 12:19:43 +0200 Subject: [PATCH 156/213] Updating the sources plugin --- pom.xml | 36 ++++++++++-------------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/pom.xml b/pom.xml index eb530dec..6b74456a 100755 --- a/pom.xml +++ b/pom.xml @@ -75,34 +75,18 @@ - maven-source-plugin - 2.1.2 - - - attach-sources - - jar-no-fork - - - - - - - - - org.apache.maven.plugins - maven-source-plugin - + maven-source-plugin + 2.4 + - attach-sources - - jar - + attach-sources + + jar-no-fork + - - - - + + + openehr-rm-core From e051f58833b18b4429ce315c0d0a6aeac7ac57f4 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Mon, 19 Oct 2015 13:02:17 +0200 Subject: [PATCH 157/213] Removing the jar-no-fork to avoid problems when releasing sources --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6b74456a..72e355e7 100755 --- a/pom.xml +++ b/pom.xml @@ -81,7 +81,7 @@ attach-sources - jar-no-fork + jar From 47f3d8bf2521c9e2b234c409d198ce53a692976f Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Oct 2015 13:09:10 +0200 Subject: [PATCH 158/213] [maven-release-plugin] prepare release ref_impl_java-1.0.16 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 330f2dec..2f2b8bd7 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 576478ac..7eac42f8 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 1d7c4f69..f3ffce26 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index efe3b8dd..ba2dbf9e 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index ccc99314..3fbcc7c8 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index cb4dd474..88a07380 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index d8e8be1e..2733944b 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index bcf1fa40..c962059f 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index b70bf8ff..1365b5fd 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 28b05320..14391780 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 85bebf48..d5c3dc01 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 52a47358..aaf5a00a 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 72e355e7..f70bc830 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.16-SNAPSHOT + 1.0.16 The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - HEAD + ref_impl_java-1.0.16 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index dd89d7dc..1c263879 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 976157b6..b9e2e651 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 4392b913..87dec210 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 7453c711..5c586555 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.16-SNAPSHOT + 1.0.16 xml-serializer jar From f061cca817fa5a5a2f1ba275c564d817a2e26813 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Oct 2015 13:09:19 +0200 Subject: [PATCH 159/213] [maven-release-plugin] prepare for next development iteration --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 2f2b8bd7..bb677901 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 7eac42f8..2d4d737f 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index f3ffce26..3c62f996 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index ba2dbf9e..9cdc7577 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 3fbcc7c8..2e7eacdf 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 88a07380..2ef3f32f 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 2733944b..9ac20a68 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index c962059f..9e5c1178 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 1365b5fd..04ea4532 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 14391780..731b01ce 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index d5c3dc01..4b235567 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index aaf5a00a..5ae1c064 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index f70bc830..df89a255 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.16 + 1.0.17-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - ref_impl_java-1.0.16 + HEAD diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 1c263879..cd448d7d 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index b9e2e651..3db7bed9 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 87dec210..af85ce2f 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 5c586555..30643d10 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.16 + 1.0.17-SNAPSHOT xml-serializer jar From 80d921d8b8167a776924e9113134089e08460079 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Oct 2015 13:43:35 +0200 Subject: [PATCH 160/213] [maven-release-plugin] prepare release ref_impl_java-1.0.17 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index bb677901..e2a5490c 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 2d4d737f..d68f82cd 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 3c62f996..088f4993 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 9cdc7577..af6bde74 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 2e7eacdf..ff3e0ccf 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 2ef3f32f..8940bf6c 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 9ac20a68..b976d69d 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 9e5c1178..ab5e7324 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 04ea4532..46625752 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 731b01ce..fea588ad 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 4b235567..5c4f9634 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 5ae1c064..9b7c2e44 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index df89a255..fb851336 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.17-SNAPSHOT + 1.0.17 The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - HEAD + ref_impl_java-1.0.17 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index cd448d7d..c25c0198 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 3db7bed9..a12a5586 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index af85ce2f..4eaa2d69 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 30643d10..79716013 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.17-SNAPSHOT + 1.0.17 xml-serializer jar From c36d3f8aad3344f65d505467902e8d49c4411b34 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Oct 2015 13:43:44 +0200 Subject: [PATCH 161/213] [maven-release-plugin] prepare for next development iteration --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index e2a5490c..0c4fe06d 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index d68f82cd..a40a0473 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 088f4993..d0c479f6 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index af6bde74..fe60a7dd 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index ff3e0ccf..79240a4e 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 8940bf6c..743e9e35 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index b976d69d..1ac90c2b 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index ab5e7324..96ea6eb3 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 46625752..1633e0ef 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index fea588ad..b58a52fb 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 5c4f9634..d90363ea 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 9b7c2e44..7c6ed97f 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index fb851336..ada0070b 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.17 + 1.0.18-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - ref_impl_java-1.0.17 + HEAD diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index c25c0198..2d012f4f 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index a12a5586..8dfd8e8f 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 4eaa2d69..e4ebedd5 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 79716013..15a179a7 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.17 + 1.0.18-SNAPSHOT xml-serializer jar From a3588549ee506c10a1da45820e04105929301f4a Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Mon, 19 Oct 2015 13:50:05 +0200 Subject: [PATCH 162/213] Fixing issue with the forked execution --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ada0070b..adb3e566 100755 --- a/pom.xml +++ b/pom.xml @@ -80,8 +80,9 @@ attach-sources + verify - jar + jar-no-fork From c75ef5f985488373be7f556360897dbc176f760a Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Thu, 19 Nov 2015 13:29:57 +0100 Subject: [PATCH 163/213] Change DvOrdinal.list from Set to List; Verify duplicated int values are supported by CDVOrdinal and ADL parsing --- .gitignore | 1 + adl-parser/src/main/javacc/adl.jj | 2 +- .../acode/openehr/parser/CDvOrdinalTest.java | 45 ++++++++++++------- .../adl-test-entry.c_dv_ordinal.test.adl | 12 ++++- .../openehr/am/serialize/CDvOrdinalTest.java | 11 ++--- .../am/validation/ArchetypeValidator.java | 10 ++--- .../datatypes/quantity/CDvOrdinal.java | 23 ++++------ .../datatypes/quantity/CDvOrdinalTest.java | 10 ++--- .../openehr/rm/util/SkeletonGenerator.java | 2 +- .../openehr/am/serialize/XMLSerializer.java | 2 +- 10 files changed, 66 insertions(+), 52 deletions(-) mode change 100644 => 100755 adl-parser/src/test/java/se/acode/openehr/parser/CDvOrdinalTest.java mode change 100644 => 100755 adl-parser/src/test/resources/adl-test-entry.c_dv_ordinal.test.adl mode change 100644 => 100755 adl-serializer/src/test/java/org/openehr/am/serialize/CDvOrdinalTest.java mode change 100644 => 100755 openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvOrdinal.java mode change 100644 => 100755 openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvOrdinalTest.java diff --git a/.gitignore b/.gitignore index 1135625c..e1526075 100755 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ 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/adl-parser/src/main/javacc/adl.jj b/adl-parser/src/main/javacc/adl.jj index 0404c63e..885472ef 100755 --- a/adl-parser/src/main/javacc/adl.jj +++ b/adl-parser/src/main/javacc/adl.jj @@ -2814,7 +2814,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; 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 old mode 100644 new mode 100755 index 3da83dbd..78d0efe3 --- 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/resources/adl-test-entry.c_dv_ordinal.test.adl b/adl-parser/src/test/resources/adl-test-entry.c_dv_ordinal.test.adl old mode 100644 new mode 100755 index 1c2761fd..8e0abec5 --- 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-serializer/src/test/java/org/openehr/am/serialize/CDvOrdinalTest.java b/adl-serializer/src/test/java/org/openehr/am/serialize/CDvOrdinalTest.java old mode 100644 new mode 100755 index 74d79657..82ef53eb --- 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/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java index 5b6a3856..224f600f 100755 --- a/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java @@ -119,7 +119,7 @@ public final void setReportConstraintsOnCommonFunctionalPropertiesAsInfo( * Validates the given archetype * * @param archetype - * @param reportConstraintsOnFunctionalPropertiesAsInfo 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. + * @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 */ @@ -740,7 +740,7 @@ private void checkCardinalityConformsToRMCardinality(CMultipleAttribute cattr, C /** Checks the assertions of an archetype for validity - * @param cobj + * @param slot * @param rmAttrType * @param archetype * @param errors @@ -855,7 +855,7 @@ private void checkOneArchetypeId(ArchetypeSlot slot, List error * * TODO: does not report a problem on values that have a higher precision than specified * - * @param cobj + * @param cdtobj * @param archetype * @param errors */ @@ -1435,7 +1435,7 @@ void fetchATCodes(CObject cobj, Set codes) { } } else if(cobj instanceof CDvOrdinal) { CDvOrdinal cord = (CDvOrdinal) cobj; - Set list = cord.getList(); + List list = cord.getList(); if(list != null) { for(Ordinal ord : list) { CodePhrase code = ord.getSymbol(); @@ -1507,7 +1507,7 @@ void fetchACCodes(CObject cobj, Set codes) { } /** Constructs a formal String for representing this Interval - * @param Interval + * @param interval * @return */ protected String getIntervalFormalString(Interval interval) { 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 old mode 100644 new mode 100755 index 23cca8f7..ced92cb4 --- 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/test/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvOrdinalTest.java b/openehr-ap/src/test/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvOrdinalTest.java old mode 100644 new mode 100755 index 8e797e54..0e0612e3 --- 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/rm-skeleton/src/main/java/org/openehr/rm/util/SkeletonGenerator.java b/rm-skeleton/src/main/java/org/openehr/rm/util/SkeletonGenerator.java index fc878312..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 @@ -777,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/xml-serializer/src/main/java/org/openehr/am/serialize/XMLSerializer.java b/xml-serializer/src/main/java/org/openehr/am/serialize/XMLSerializer.java index 57a77d87..ccb4f346 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 @@ -656,7 +656,7 @@ protected void printCDvOrdinal(CDvOrdinal cordinal, Element out) { } if(cordinal.getList() != null) { - final Set ordinals = cordinal.getList(); + final List ordinals = cordinal.getList(); Ordinal ordinal; for (Iterator it = ordinals.iterator(); it.hasNext();) { From 8c38b3044c51d0e1d2c5cc563412b122f47255f3 Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Wed, 25 Nov 2015 07:52:37 +0100 Subject: [PATCH 164/213] Minor changes in javadoc and parameter naming --- .../java/org/openehr/rm/datatypes/quantity/DvOrdered.java | 2 +- .../java/org/openehr/rm/datatypes/quantity/DvOrdinal.java | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvOrdered.java mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvOrdinal.java 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 old mode 100644 new mode 100755 index 00451b23..c8a92d4c --- 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 old mode 100644 new mode 100755 index f670b5e8..95f537ba --- 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 @@ -93,11 +93,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)); } /** From a6c908e71778e38f34d73685c867e1ac04ed6f33 Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Mon, 30 Nov 2015 13:24:47 +0100 Subject: [PATCH 165/213] Remove unnecessary comment in testcase --- .../org/openehr/rm/datatypes/quantity/DvOrdinalTest.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) mode change 100644 => 100755 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvOrdinalTest.java 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 old mode 100644 new mode 100755 index ca711db6..1d4f6f7e --- 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); From c29f1d7d658529934b9fa59d58e43cc5e847b545 Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Fri, 6 May 2016 19:22:52 +0200 Subject: [PATCH 166/213] Add DvCodedText.valueOf() --- .../rm/datatypes/text/DvCodedText.java | 22 +++++++++++-------- .../rm/datatypes/text/DvCodedTextTest.java | 6 +++++ 2 files changed, 19 insertions(+), 9 deletions(-) mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvCodedText.java mode change 100644 => 100755 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/text/DvCodedTextTest.java 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 old mode 100644 new mode 100755 index a83bc762..553c7f7b --- 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/test/java/org/openehr/rm/datatypes/text/DvCodedTextTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/text/DvCodedTextTest.java old mode 100644 new mode 100755 index a03962b1..c059dc5d --- 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 From f473b3d48f6d442f54fadecf72277545974a77e8 Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Fri, 6 May 2016 19:31:39 +0200 Subject: [PATCH 167/213] Add DvOrdinal.valueOf() --- .../rm/datatypes/quantity/DvOrdinal.java | 79 ++++++++++--------- .../rm/datatypes/quantity/DvOrdinalTest.java | 8 ++ 2 files changed, 50 insertions(+), 37 deletions(-) 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 95f537ba..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"); @@ -99,7 +100,7 @@ public DvOrdinal(int value, DvCodedText symbol) { * @throws IllegalArgumentException */ public DvOrdinal(int value, String dvCodedTextValue, String dvCodedTextTerminology, String dvCodedTextCode) { - this(null, null, value, new DvCodedText(dvCodedTextValue, dvCodedTextTerminology, dvCodedTextCode)); + this(null, null, value, new DvCodedText(dvCodedTextValue, dvCodedTextTerminology, dvCodedTextCode)); } /** @@ -108,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. */ @@ -155,7 +156,7 @@ public DvCodedText getSymbol() { public ReferenceRange limits() { return getOtherReferenceRanges().get(limitsIndex); } - + /** * Equals if value and symbol equal in value * @@ -164,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; @@ -193,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; @@ -206,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; } @@ -239,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/test/java/org/openehr/rm/datatypes/quantity/DvOrdinalTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvOrdinalTest.java index 1d4f6f7e..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 @@ -25,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", From 921a169d64e90a206e46a7b921b13e5fcacf91f6 Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Fri, 6 May 2016 19:56:37 +0200 Subject: [PATCH 168/213] Add valueOf() to DvCount, DvQuantity, DvDateTime and DvText --- .../rm/datatypes/quantity/DvCount.java | 4 + .../rm/datatypes/quantity/DvQuantity.java | 122 +++++++++--------- .../quantity/datetime/DvDateTime.java | 7 +- .../org/openehr/rm/datatypes/text/DvText.java | 7 +- .../rm/datatypes/quantity/DvCountTest.java | 6 + .../rm/datatypes/quantity/DvQuantityTest.java | 13 ++ .../quantity/datetime/DvDateTest.java | 0 .../quantity/datetime/DvDateTimeTest.java | 10 ++ 8 files changed, 105 insertions(+), 64 deletions(-) mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/text/DvText.java mode change 100644 => 100755 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvCountTest.java mode change 100644 => 100755 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTest.java mode change 100644 => 100755 openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTimeTest.java 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 27e42530..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 @@ -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/DvQuantity.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvQuantity.java index ca8e8e13..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 @@ -51,26 +51,26 @@ 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) { + 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); + accuracyPercent, magnitudeStatus); if (precision < -1) { throw new IllegalArgumentException("negative precision"); @@ -145,7 +145,7 @@ public DvQuantity(double magnitude, int precision, * @param precision */ public DvQuantity(String units, double magnitude, int precision) { - this(units, magnitude, precision, null); + this(units, magnitude, precision, null); } /** @@ -172,30 +172,34 @@ public Double getMagnitude() { * @return units */ public String getUnits() { - return units; + return units; } public DvQuantity parse(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); - } + 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); + } } /** @@ -210,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); } /** @@ -227,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); } /** @@ -251,8 +255,8 @@ public Class getDiffType() { */ public DvQuantity negate() { return new DvQuantity(getOtherReferenceRanges(), getNormalRange(), - getNormalStatus(), getAccuracy(), isAccuracyPercent(), - getMagnitudeStatus(), getUnits(), -magnitude, + getNormalStatus(), getAccuracy(), isAccuracyPercent(), + getMagnitudeStatus(), getUnits(), -magnitude, precision, measurementService); } @@ -278,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; } @@ -287,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. */ @@ -305,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; @@ -320,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; @@ -365,15 +369,15 @@ public void setPrecision(int precision) { public static final char DECIMAL_SEPARATOR = '.'; - @Override - public String getReferenceModelName() { - return ReferenceModelName.DV_QUANTITY.getName(); - } + @Override + public String getReferenceModelName() { + return ReferenceModelName.DV_QUANTITY.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/quantity/datetime/DvDateTime.java b/openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTime.java index 70454084..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 @@ -173,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); } @@ -291,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) { 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 old mode 100644 new mode 100755 index 370cd952..acbf5e16 --- 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/test/java/org/openehr/rm/datatypes/quantity/DvCountTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvCountTest.java old mode 100644 new mode 100755 index 972ec277..8ac206ab --- 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/DvQuantityTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/DvQuantityTest.java index caf5b72e..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 @@ -111,6 +111,19 @@ public void testParseQuantityWithPrecision() throws Exception { 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); diff --git a/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/datatypes/quantity/datetime/DvDateTest.java old mode 100644 new mode 100755 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 old mode 100644 new mode 100755 index 2948f908..1494d208 --- 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 ***** From ba882d3ec1fc7aad830e8e0ad5c5ca0a0aea9ecd Mon Sep 17 00:00:00 2001 From: jenkins Date: Fri, 6 May 2016 20:16:01 +0200 Subject: [PATCH 169/213] [maven-release-plugin] prepare release ref_impl_java-1.0.18 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 0c4fe06d..2c925844 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index a40a0473..efbc0947 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index d0c479f6..1382deaa 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index fe60a7dd..65dfbd4d 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 79240a4e..81cfdc73 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 743e9e35..cd401206 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 1ac90c2b..981ec9a6 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 96ea6eb3..9a386c17 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 1633e0ef..ac48e79f 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index b58a52fb..d495473b 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index d90363ea..d78f3e26 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 7c6ed97f..f91ff3b1 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index adb3e566..37893c6c 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.18-SNAPSHOT + 1.0.18 The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - HEAD + ref_impl_java-1.0.18 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 2d012f4f..89819a22 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 8dfd8e8f..1919082a 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index e4ebedd5..94ecc3f1 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 15a179a7..18b1a7c6 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.18-SNAPSHOT + 1.0.18 xml-serializer jar From 2a3c182dd3fde74436ac16166263808d9d2f52db Mon Sep 17 00:00:00 2001 From: jenkins Date: Fri, 6 May 2016 20:16:05 +0200 Subject: [PATCH 170/213] [maven-release-plugin] prepare for next development iteration --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 2c925844..ae6d1e7f 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index efbc0947..ce27dc6a 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 1382deaa..5f944579 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 65dfbd4d..f812412e 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 81cfdc73..794c1068 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index cd401206..5cc34545 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 981ec9a6..d1337d6a 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 9a386c17..ed5100ec 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index ac48e79f..a9c5d0a6 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index d495473b..c52c1ba9 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index d78f3e26..e2815327 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index f91ff3b1..929b61e0 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 37893c6c..7e5e502e 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.18 + 1.0.19-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - ref_impl_java-1.0.18 + HEAD diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 89819a22..3355fafe 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 1919082a..be3054ea 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 94ecc3f1..dabf121e 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 18b1a7c6..47b33cbe 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT xml-serializer jar From 900d64b6f76fa7f063969a70ec695b5b8bebff94 Mon Sep 17 00:00:00 2001 From: jenkins Date: Fri, 6 May 2016 22:28:47 +0200 Subject: [PATCH 171/213] [maven-release-plugin] prepare release ref_impl_java-1.0.18 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index ae6d1e7f..2c925844 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index ce27dc6a..efbc0947 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 5f944579..1382deaa 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index f812412e..65dfbd4d 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 794c1068..81cfdc73 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 5cc34545..cd401206 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index d1337d6a..981ec9a6 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index ed5100ec..9a386c17 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index a9c5d0a6..ac48e79f 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index c52c1ba9..d495473b 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index e2815327..d78f3e26 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 929b61e0..f91ff3b1 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 7e5e502e..37893c6c 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.19-SNAPSHOT + 1.0.18 The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - HEAD + ref_impl_java-1.0.18 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 3355fafe..89819a22 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index be3054ea..1919082a 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index dabf121e..94ecc3f1 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 47b33cbe..18b1a7c6 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.18 xml-serializer jar From 073e61c6e9c071a55bc8cc1ec17edd1b83ef8e6d Mon Sep 17 00:00:00 2001 From: Manuel Palacio Date: Mon, 9 May 2016 10:31:40 +0200 Subject: [PATCH 172/213] fix version number in pom --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 3 +-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 17 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 2c925844..ae6d1e7f 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index efbc0947..ce27dc6a 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 1382deaa..5f944579 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 65dfbd4d..f812412e 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 81cfdc73..794c1068 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index cd401206..5cc34545 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 981ec9a6..d1337d6a 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 9a386c17..ed5100ec 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index ac48e79f..a9c5d0a6 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index d495473b..c52c1ba9 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index d78f3e26..e2815327 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index f91ff3b1..929b61e0 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 37893c6c..a24dfb1e 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.18 + 1.0.19-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,6 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - ref_impl_java-1.0.18 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 89819a22..3355fafe 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 1919082a..be3054ea 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 94ecc3f1..dabf121e 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 18b1a7c6..47b33cbe 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.18 + 1.0.19-SNAPSHOT xml-serializer jar From fe13d958c018cf6ca02c1220106f413b32a3ff1e Mon Sep 17 00:00:00 2001 From: jenkins Date: Mon, 9 May 2016 10:38:33 +0200 Subject: [PATCH 173/213] [maven-release-plugin] prepare release ref_impl_java-1.0.19 --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 3 ++- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 17 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index ae6d1e7f..cae9ec3b 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index ce27dc6a..c3e8001f 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 5f944579..140436e1 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index f812412e..b5948cf0 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 794c1068..6fd77b0b 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 5cc34545..f3f839c7 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index d1337d6a..16d63940 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index ed5100ec..e57805aa 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index a9c5d0a6..93535114 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index c52c1ba9..612ca665 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index e2815327..fd27a5f5 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 929b61e0..e6aa53e0 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index a24dfb1e..df106ed5 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.19-SNAPSHOT + 1.0.19 The openEHR Reference Java Implementation The openEHR Foundation @@ -14,6 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git + ref_impl_java-1.0.19 diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 3355fafe..59e51ea2 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index be3054ea..b9978685 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index dabf121e..9df625f6 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 47b33cbe..e47286a6 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.19-SNAPSHOT + 1.0.19 xml-serializer jar From 08d5ca3cce4f623cdb3d42e05d4f52cdfb92c6c9 Mon Sep 17 00:00:00 2001 From: jenkins Date: Mon, 9 May 2016 10:38:38 +0200 Subject: [PATCH 174/213] [maven-release-plugin] prepare for next development iteration --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 4 ++-- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index cae9ec3b..81b57b40 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index c3e8001f..53f9ce81 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 140436e1..7a4ed1c8 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index b5948cf0..e742d1f7 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 6fd77b0b..873fb2fd 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index f3f839c7..b0da953a 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 16d63940..4dfc3742 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index e57805aa..918a0c31 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 93535114..59150a70 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 612ca665..24947e09 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index fd27a5f5..79417b30 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index e6aa53e0..3ed41f32 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index df106ed5..155e2dee 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java pom - 1.0.19 + 1.0.20-SNAPSHOT The openEHR Reference Java Implementation The openEHR Foundation @@ -14,7 +14,7 @@ scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - ref_impl_java-1.0.19 + HEAD diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 59e51ea2..b027ba8e 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index b9978685..38e9e78c 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 9df625f6..0f057f72 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index e47286a6..bf5dc90c 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.19 + 1.0.20-SNAPSHOT xml-serializer jar From e9e339a659b3469b7a5a5ec252710781f05258a2 Mon Sep 17 00:00:00 2001 From: Manuel Palacio Date: Mon, 9 May 2016 11:06:56 +0200 Subject: [PATCH 175/213] use 0-SNAPSHOT before moving to teamcity --- adl-parser/pom.xml | 2 +- adl-serializer/pom.xml | 2 +- archetype-validator/pom.xml | 2 +- dadl-binding/pom.xml | 2 +- dadl-parser/pom.xml | 2 +- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 2 +- oet-parser/pom.xml | 2 +- openehr-aom/pom.xml | 2 +- openehr-ap/pom.xml | 2 +- openehr-rm-core/pom.xml | 2 +- openehr-rm-domain/pom.xml | 2 +- pom.xml | 174 +++++++++++------------------------- rm-builder/pom.xml | 2 +- rm-skeleton/pom.xml | 2 +- xml-binding/pom.xml | 2 +- xml-serializer/pom.xml | 2 +- 17 files changed, 70 insertions(+), 136 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 81b57b40..3e21beb5 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT adl-parser jar diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 53f9ce81..d6b4bbe0 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT adl-serializer jar diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 7a4ed1c8..321f85d1 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT archetype-validator jar diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index e742d1f7..2e4d30a5 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT dadl-binding jar diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 873fb2fd..e597192e 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT dadl-parser jar diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index b0da953a..fec1a897 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT measure-serv jar diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 4dfc3742..86705472 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT mini-termserv jar diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 918a0c31..b933b845 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT oet-parser jar diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index 59150a70..f28d599a 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT openehr-aom jar diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 24947e09..97be5a12 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT openehr-ap jar diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 79417b30..4918b269 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT openehr-rm-core jar diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 3ed41f32..b5a3219e 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT openehr-rm-domain jar diff --git a/pom.xml b/pom.xml index 155e2dee..bdeb8972 100755 --- a/pom.xml +++ b/pom.xml @@ -1,122 +1,56 @@ - - 4.0.0 - openehr - ref_impl_java - pom - 1.0.20-SNAPSHOT - The openEHR Reference Java Implementation - - The openEHR Foundation - - - UTF-8 - - - scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git - HEAD - - - - - maven-compiler-plugin - 2.3.2 - - 1.5 - 1.5 - - - - - 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 - - - - org.apache.maven.plugins - maven-release-plugin - 2.5 - - - org.codehaus.mojo - cobertura-maven-plugin - 2.5.1 - - - - xml - - - - - maven-source-plugin - 2.4 - - - attach-sources - verify - - jar-no-fork - - - - - - - - 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 - - - - repo.cambio.se_releases - releases - http://css-cds-3:8081/nexus/content/repositories/releases - - - repo.cambio.se_snapshots - snapshots - http://css-cds-3:8081/nexus/content/repositories/snapshots - - + + + se.cambio.cds + mig-project + 1.9 + + 4.0.0 + openehr + ref_impl_java + pom + 0-SNAPSHOT + The openEHR Reference Java Implementation + + The openEHR Foundation + + + scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git + HEAD + + + + + org.codehaus.mojo + versions-maven-plugin + 2.1 + + + maven-scm-plugin + 1.8.1 + + ${project.artifactId}-${project.version} + + + + + + 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 + diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index b027ba8e..09c81bcc 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT rm-builder jar diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 38e9e78c..45e2ee4f 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT rm-skeleton jar diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 0f057f72..6fcd6216 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -4,7 +4,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT xml-binding jar diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index bf5dc90c..44baee3d 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -3,7 +3,7 @@ openehr ref_impl_java - 1.0.20-SNAPSHOT + 0-SNAPSHOT xml-serializer jar From 74f8c9284375b2b77afc2ec77521bed6df9e4cfd Mon Sep 17 00:00:00 2001 From: Manuel Palacio Date: Mon, 9 May 2016 11:16:45 +0200 Subject: [PATCH 176/213] change groupId to se.cambio.cds --- adl-parser/pom.xml | 14 +++++++------- adl-serializer/pom.xml | 14 +++++++------- archetype-validator/pom.xml | 16 ++++++++-------- dadl-binding/pom.xml | 18 +++++++++--------- dadl-parser/pom.xml | 4 ++-- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 4 ++-- oet-parser/pom.xml | 16 ++++++++-------- openehr-aom/pom.xml | 6 +++--- openehr-ap/pom.xml | 10 +++++----- openehr-rm-core/pom.xml | 4 ++-- openehr-rm-domain/pom.xml | 6 +++--- pom.xml | 1 - rm-builder/pom.xml | 10 +++++----- rm-skeleton/pom.xml | 24 ++++++++++++------------ xml-binding/pom.xml | 14 +++++++------- xml-serializer/pom.xml | 10 +++++----- 17 files changed, 86 insertions(+), 87 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 3e21beb5..9d8c5248 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -91,32 +91,32 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} - openehr + se.cambio.cds openehr-aom ${project.version} - openehr + se.cambio.cds openehr-ap ${project.version} - openehr + se.cambio.cds measure-serv ${project.version} - openehr + se.cambio.cds mini-termserv ${project.version} diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index d6b4bbe0..6fbf41c8 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -1,7 +1,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -27,32 +27,32 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} - openehr + se.cambio.cds openehr-aom ${project.version} - openehr + se.cambio.cds openehr-ap ${project.version} - openehr + se.cambio.cds mini-termserv ${project.version} - openehr + se.cambio.cds adl-parser ${project.version} test diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 321f85d1..18154d4e 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -43,37 +43,37 @@ 1.2.13 - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} - openehr + se.cambio.cds openehr-aom ${project.version} - openehr + se.cambio.cds openehr-ap ${project.version} - openehr + se.cambio.cds mini-termserv ${project.version} - openehr + se.cambio.cds measure-serv ${project.version} - openehr + se.cambio.cds adl-parser ${project.version} test diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 2e4d30a5..57963f13 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -19,48 +19,48 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-aom ${project.version} - openehr + se.cambio.cds adl-parser ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} - openehr + se.cambio.cds mini-termserv ${project.version} - openehr + se.cambio.cds measure-serv ${project.version} - openehr + se.cambio.cds rm-builder ${project.version} - openehr + se.cambio.cds dadl-parser ${project.version} diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index e597192e..e302e708 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -66,7 +66,7 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index fec1a897..245bff49 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 86705472..b2e45f8c 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -21,7 +21,7 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index b933b845..54b6526a 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -49,22 +49,22 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} - openehr + se.cambio.cds openehr-aom ${project.version} - openehr + se.cambio.cds adl-parser ${project.version} @@ -79,12 +79,12 @@ 1.0 - openehr + se.cambio.cds measure-serv ${project.version} - openehr + se.cambio.cds mini-termserv ${project.version} @@ -101,7 +101,7 @@ test - openehr + se.cambio.cds adl-serializer ${project.version} diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index f28d599a..a9a13b09 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -22,12 +22,12 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 97be5a12..5a99d9c0 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -21,22 +21,22 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} - openehr + se.cambio.cds openehr-aom ${project.version} - openehr + se.cambio.cds measure-serv ${project.version} diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 4918b269..77d79b0f 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -37,7 +37,7 @@ test - openehr + se.cambio.cds measure-serv ${project.version} diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index b5a3219e..7a20892b 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -21,12 +21,12 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds mini-termserv ${project.version} test diff --git a/pom.xml b/pom.xml index bdeb8972..2dc5f2c5 100755 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,6 @@ 1.9 4.0.0 - openehr ref_impl_java pom 0-SNAPSHOT diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 09c81bcc..454ba93e 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -21,22 +21,22 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} - openehr + se.cambio.cds mini-termserv ${project.version} - openehr + se.cambio.cds measure-serv ${project.version} diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 45e2ee4f..6d556495 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -12,52 +12,52 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} - openehr + se.cambio.cds openehr-aom ${project.version} - openehr + se.cambio.cds adl-parser ${project.version} - openehr + se.cambio.cds dadl-parser ${project.version} - openehr + se.cambio.cds oet-parser ${project.version} - openehr + se.cambio.cds measure-serv ${project.version} - openehr + se.cambio.cds mini-termserv ${project.version} - openehr + se.cambio.cds dadl-binding ${project.version} - openehr + se.cambio.cds xml-binding ${project.version} @@ -74,7 +74,7 @@ test - openehr + se.cambio.cds adl-serializer ${project.version} test diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 6fcd6216..1541883f 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -49,12 +49,12 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} @@ -64,17 +64,17 @@ 2.3.0 - openehr + se.cambio.cds measure-serv ${project.version} - openehr + se.cambio.cds mini-termserv ${project.version} - openehr + se.cambio.cds ${project.version} rm-builder @@ -120,7 +120,7 @@ test - openehr + se.cambio.cds oet-parser ${project.version} diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 44baee3d..be3a7375 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -1,7 +1,7 @@ 4.0.0 - openehr + se.cambio.cds ref_impl_java 0-SNAPSHOT @@ -20,22 +20,22 @@ - openehr + se.cambio.cds openehr-rm-core ${project.version} - openehr + se.cambio.cds openehr-rm-domain ${project.version} - openehr + se.cambio.cds openehr-aom ${project.version} - openehr + se.cambio.cds openehr-ap ${project.version} From b450a2e864d553adc9c8b694158d7c7dcab2443f Mon Sep 17 00:00:00 2001 From: Manuel Palacio Date: Mon, 4 Jul 2016 18:02:06 +0200 Subject: [PATCH 177/213] add junit and update ref to parent pom --- pom.xml | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/pom.xml b/pom.xml index 2dc5f2c5..8e8016f0 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ se.cambio.cds mig-project - 1.9 + 1.0.23 4.0.0 ref_impl_java @@ -15,25 +15,9 @@ The openEHR Foundation - scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git + ${scm.url} HEAD - - - - org.codehaus.mojo - versions-maven-plugin - 2.1 - - - maven-scm-plugin - 1.8.1 - - ${project.artifactId}-${project.version} - - - - openehr-rm-core openehr-rm-domain @@ -52,4 +36,14 @@ rm-skeleton archetype-validator + + + + junit + junit + 4.12 + test + + + From c7a64e3858438710123f0652643cf3fd4b92b5e7 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Wed, 10 Aug 2016 15:57:11 +0200 Subject: [PATCH 178/213] Resolving mig project version conflict --- pom.xml | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index 8e8016f0..3be0e852 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ se.cambio.cds mig-project - 1.0.23 + 1.43 4.0.0 ref_impl_java @@ -15,9 +15,25 @@ The openEHR Foundation - ${scm.url} + scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git HEAD + + + + org.codehaus.mojo + versions-maven-plugin + 2.1 + + + maven-scm-plugin + 1.8.1 + + ${project.artifactId}-${project.version} + + + + openehr-rm-core openehr-rm-domain @@ -36,14 +52,4 @@ rm-skeleton archetype-validator - - - - junit - junit - 4.12 - test - - - From f6701d8aca105b34cda012e08f8657795fd867e8 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Wed, 7 Jun 2017 10:47:07 +0200 Subject: [PATCH 179/213] Merging with pubic repository --- pom.xml | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/pom.xml b/pom.xml index 3be0e852..dc2bf21b 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ se.cambio.cds mig-project - 1.43 + 1.0.43 4.0.0 ref_impl_java @@ -15,25 +15,9 @@ The openEHR Foundation - scm:git:ssh://git@css-cds-3:7999/cds/ref_impl_java.git + ${scm.url} HEAD - - - - org.codehaus.mojo - versions-maven-plugin - 2.1 - - - maven-scm-plugin - 1.8.1 - - ${project.artifactId}-${project.version} - - - - openehr-rm-core openehr-rm-domain @@ -52,4 +36,14 @@ rm-skeleton archetype-validator + + + + junit + junit + 4.12 + test + + + From 64dc58886c7ac4bdb825fc0cce0e3702e8a05f38 Mon Sep 17 00:00:00 2001 From: Rong Chen Date: Thu, 3 Nov 2016 16:27:41 +0100 Subject: [PATCH 180/213] Add string value to the exception message --- .../src/main/java/org/openehr/rm/datatypes/basic/DataValue.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/basic/DataValue.java 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 old mode 100644 new mode 100755 index 61df2834..a81fac9e --- 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 @@ -78,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); From ffaac419d3e882d0a624510d07a1765392c8445a Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Wed, 7 Jun 2017 10:55:16 +0200 Subject: [PATCH 181/213] Merging with pubic repository --- adl-parser/src/main/javacc/adl.jj | 4 +- .../parser/ArchetypeDescriptionTest.java | 8 +-- .../openehr/parser/MissingPurposeTest.java | 2 +- .../openehr/am/serialize/ADLSerializer.java | 2 +- .../openehr/am/serialize/DescriptionTest.java | 6 +-- .../am/validation/ArchetypeValidator.java | 50 ++++--------------- .../rm/common/resource/AuthoredResource.java | 8 ++- .../common/resource/ResourceDescription.java | 14 +++--- .../resource/ResourceDescriptionTest.java | 4 +- .../rm/common/resource/ResourceTestBase.java | 11 ++-- pom.xml | 43 +++++++++------- .../org/openehr/build/RMObjectBuilder.java | 16 ++---- .../openehr/am/serialize/XMLSerializer.java | 2 +- 13 files changed, 73 insertions(+), 97 deletions(-) diff --git a/adl-parser/src/main/javacc/adl.jj b/adl-parser/src/main/javacc/adl.jj index 885472ef..82b1c2e0 100755 --- a/adl-parser/src/main/javacc/adl.jj +++ b/adl-parser/src/main/javacc/adl.jj @@ -858,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; @@ -879,7 +879,7 @@ ResourceDescription arch_description() throws Exception : LOOKAHEAD(2) item = arch_description_item() { - details.add(item); + details.put(item.getLanguage().getCodeString(),item); } )+ ">" 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 index f3bff7ca..80db7576 100644 --- 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/MissingPurposeTest.java b/adl-parser/src/test/java/se/acode/openehr/parser/MissingPurposeTest.java index 0c1b6ca0..114ac38b 100644 --- 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-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java b/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java index 1593f7de..c7b8f66b 100755 --- a/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java +++ b/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java @@ -302,7 +302,7 @@ protected void printDescription(ResourceDescription description, Writer out) indent(1, out); out.write("details = <"); newline(out); - for (ResourceDescriptionItem item : description.getDetails()) { + for (ResourceDescriptionItem item : description.getDetails().values()) { printDescriptionItem(item, 2, out); } indent(1, 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 index 3fc3916f..22397d57 100644 --- a/adl-serializer/src/test/java/org/openehr/am/serialize/DescriptionTest.java +++ b/adl-serializer/src/test/java/org/openehr/am/serialize/DescriptionTest.java @@ -68,8 +68,8 @@ public void testPrintDescription() throws Exception { Map authorMap = new HashMap(); authorMap.put("name", author); - List items = - new ArrayList(); + Map items = + new HashMap<>(); String[][] others = { { "revision", "1.1" }, { "adl_version", "1.4" }, { "rights", "all rights reserved" } }; Map otherDetails = new HashMap(); @@ -79,7 +79,7 @@ public void testPrintDescription() throws Exception { TerminologyService service = SimpleTerminologyService.getInstance(); ResourceDescriptionItem item = new ResourceDescriptionItem(ENGLISH, "purpose of this archetype", service); - items.add(item); + items.put(ENGLISH.getCodeString(),item); ResourceDescription description = new ResourceDescription(authorMap, null, status, items, null, null, null); 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 index 224f600f..01b20c14 100755 --- a/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java @@ -163,15 +163,8 @@ public void checkDescription(Archetype archetype, List errors) return; } - ArrayList checkedLanguages = new ArrayList(); // check purpose in each available language - for (ResourceDescriptionItem detail : archetype.getDescription().getDetails()) { - if (!checkedLanguages.contains(detail.getLanguage().getCodeString())) { - checkedLanguages.add(detail.getLanguage().getCodeString()); - } else { - errors.add(new ValidationError(ErrorType.VDL, null, detail.getLanguage().getCodeString())); - } - + for (ResourceDescriptionItem detail : archetype.getDescription().getDetails().values()) { if (StringUtils.isBlank(detail.getPurpose()) || StringUtils.containsIgnoreCase(detail.getPurpose(),"unknown")) { ValidationError error = new ValidationError(ErrorType.VDSCR, "PURPOSE", detail.getLanguage().getCodeString()); @@ -687,24 +680,16 @@ private void checkCardinalityConformsToChildrenOccurrences( 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. + // This may not be an error, but should at least be a warning (TBD) ValidationError error = new ValidationError(ErrorType.WACMC, null, - cmattr.path(), getIntervalFormalString(cardinalityInterval), getIntervalFormalString(minOcc, maxOcc, isOccUpperUnbounded)); + cmattr.path(), getIntervalFormalString(cardinalityInterval), getIntervalFormalString(minOcc, maxOcc, isOccUpperUnbounded) + ); + if( ! errors.contains(error)) { errors.add(error); } } - - // "Sum of minimal occurrences of elements < minimal cardinality of container"? - /* if (!cardinalityInterval.isLowerUnbounded() && minOcc < cardinalityInterval.getLower().intValue()) { - // While it is perfectly legal to do this (and might even be used as a way to force a selection of various items) - // in practice this most often happens if a mandatory element was removed, but the min. cardinality hasn't been decreased. - // This results in ugly problems for implementers downstream and therefore we warn here. - ValidationError error = new ValidationError(ErrorType.W, null, - cmattr.path(), getIntervalFormalString(cardinalityInterval), getIntervalFormalString(minOcc, maxOcc, isOccUpperUnbounded)); - } - */ } private void checkCardinalityConformsToRMCardinality(CMultipleAttribute cattr, CObject cobj, List errors) { @@ -879,7 +864,7 @@ private void validateCDomainType(CDomainType cdtobj, Archetype archetype, log.debug("validating CDVQuantity object at "+cdtobj.path()); checkArchetypeUnitsValidity((CDvQuantity)cdtobj, errors); } - + } /* @@ -1101,12 +1086,10 @@ 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); - + List termDefList = + archetype.getOntology().getTermDefinitionsList(); + List constraintDefList = + archetype.getOntology().getConstraintDefinitionsList(); Set termDefLangs = retrieveLanguageSet(termDefList); Set constraintDefLangs = retrieveLanguageSet(constraintDefList); ValidationError error = null; @@ -1114,7 +1097,7 @@ public void checkOntologyTranslation(Archetype archetype, if(primaryLang.equals(lang)) { continue; } - if(!termDefLangs.contains(lang)) { + if( ! termDefLangs.contains(lang)) { error = new ValidationError(ErrorType.VOTM, "TERM", lang); errors.add(error); @@ -1129,17 +1112,6 @@ public void checkOntologyTranslation(Archetype archetype, } } - 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) { 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 index 3c462733..c7e7cb46 100644 --- 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 index 0a58f669..227ae6f3 100644 --- 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 @@ -41,7 +41,7 @@ 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 = "details", required = true) Map details, @Attribute(name = "resourcePackageUri") String resourcePackageUri, @Attribute(name = "otherDetails") Map otherDetails, @Attribute(name = "parentResource") AuthoredResource parentResource ){ @@ -70,7 +70,7 @@ public ResourceDescription( * * @return details */ - public List getDetails() { + public Map getDetails() { return details; } @@ -136,7 +136,7 @@ public String getResourcePackageUri() { public ResourceDescription() { } - void setDetails(List details) { + void setDetails(Map details) { this.details = details; } @@ -173,10 +173,10 @@ void setParentResource(AuthoredResource parentResource) { } } - void languageValidCheck(AuthoredResource parent, List details) { + void languageValidCheck(AuthoredResource parent, Map details) { Set languages = parent.languagesAvailable(); - for(ResourceDescriptionItem rdi : details) { - if(!languages.contains(rdi.getLanguage().getCodeString())) { + for(String code : details.keySet()) { + if(!languages.contains(code)) { throw new IllegalArgumentException("breach of language validity"); } } @@ -188,7 +188,7 @@ void languageValidCheck(AuthoredResource parent, List d private Map originalAuthor; private List otherContributors; private String lifecycleState; - private List details; + private Map details; private String resourcePackageUri; private Map otherDetails; private AuthoredResource parentResource; 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 index b0f2792a..97ddd72b 100644 --- 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 index 2a7ee53d..17c92297 100644 --- 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/pom.xml b/pom.xml index dc2bf21b..b66d6dce 100755 --- a/pom.xml +++ b/pom.xml @@ -1,12 +1,8 @@ - - se.cambio.cds - mig-project - 1.0.43 - 4.0.0 + openehr ref_impl_java pom 0-SNAPSHOT @@ -14,10 +10,33 @@ The openEHR Foundation + + UTF-8 + UTF-8 + - ${scm.url} - HEAD + 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 + 3.5.1 + + 1.8 + 1.8 + + + + openehr-rm-core openehr-rm-domain @@ -36,14 +55,4 @@ rm-skeleton archetype-validator - - - - junit - junit - 4.12 - test - - - 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 6e814d99..8b571928 100755 --- a/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java +++ b/rm-builder/src/main/java/org/openehr/build/RMObjectBuilder.java @@ -70,19 +70,11 @@ 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; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; +import java.util.*; /** * Reference model class instances builder @@ -206,8 +198,8 @@ private Map loadTypeMap() throws ClassNotFoundException { Organisation.class, Person.class, Contact.class, PartyRelationship.class, Role.class, Capability.class}; - typeMap = new LinkedHashMap(); - upperCaseMap = new LinkedHashMap(); + typeMap = new LinkedHashMap<>(); + upperCaseMap = new LinkedHashMap<>(); for (Class klass : classes) { String name = klass.getSimpleName(); typeMap.put(name, klass); 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 ccb4f346..f5b10a4a 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 @@ -223,7 +223,7 @@ protected void printDescription(ResourceDescription description, Element out) { } printStringMap("other_details", description.getOtherDetails(), des); - for (ResourceDescriptionItem item : description.getDetails()) { + for (ResourceDescriptionItem item : description.getDetails().values()) { Element details = new Element("details", defaultNamespace); des.getChildren().add(details); printDescriptionItem(item, details); From bcf07606ee94db4af1b4d27705e79539dcbd8db1 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Wed, 7 Jun 2017 11:00:23 +0200 Subject: [PATCH 182/213] Merging with pubic repository --- .../openehr/am/serialize/ADLSerializer.java | 265 +++---- .../am/validation/ArchetypeValidator.java | 720 +++++++++--------- .../openehr/am/validation/RMInspector.java | 35 +- .../SpecialisedArchetypeValidator.java | 15 +- .../validation/ArchetypeTermValidityTest.java | 10 - .../measurement/SimpleMeasurementService.java | 2 +- 6 files changed, 543 insertions(+), 504 deletions(-) mode change 100755 => 100644 adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java mode change 100755 => 100644 archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java mode change 100755 => 100644 measure-serv/src/main/java/org/openehr/rm/support/measurement/SimpleMeasurementService.java 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 c7b8f66b..be491a5e --- a/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java +++ b/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java @@ -45,11 +45,11 @@ /** * ADL serializer for the openEHR Java kernel - * + * * @author Rong Chen * @author Mattias Forss, Johan Hjalmarsson * @author Sebastian Garde - * + * * @version 1.0 */ public class ADLSerializer { @@ -65,7 +65,7 @@ public ADLSerializer() { /** * Output given archetype as string in ADL format - * + * * @param archetype * @return a string in ADL format * @throws IOException @@ -76,9 +76,9 @@ public String output(Archetype archetype) throws IOException { return writer.toString(); } - /** + /** * Output archetype DEFINITION as string in ADL format - * + * * @param archetype * @return a string in ADL format * @throws IOException @@ -87,13 +87,13 @@ 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 @@ -107,40 +107,40 @@ public void output(Archetype archetype, OutputStream out) /** * 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(), + 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); + 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 { + 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) || (uid != null && StringUtils.isNotEmpty(uid.toString()))) { + out.write(" ("); + } if(StringUtils.isNotEmpty(adlVersion)) { out.write("adl_version="); @@ -151,11 +151,11 @@ protected void printHeader(String adlVersion, out.write("; "); } out.write("uid="); - out.write(uid.toString()); - } - if(StringUtils.isNotEmpty(adlVersion) || (uid!=null &&StringUtils.isNotEmpty(uid.toString()))) { - out.write(")"); - } + 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()); @@ -176,9 +176,9 @@ protected void printHeader(String adlVersion, out.write("[" + conceptCode + "]"); newline(out); } - + protected void printLanguage(AuthoredResource authored, - Writer out) throws IOException { + Writer out) throws IOException { out.write("language"); newline(out); @@ -195,17 +195,17 @@ protected void printLanguage(AuthoredResource authored, indent(1, out); out.write("translations = <"); newline(out); - Map translations = - authored.getTranslations(); + 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("["); @@ -215,15 +215,15 @@ protected void printLanguage(AuthoredResource authored, out.write("]"); out.write(">"); newline(out); - + indent(3, out); out.write("author = <"); - newline(out); - printMap(td.getAuthor(), out, 4); + newline(out); + printMap(td.getAuthor(), out, 4); indent(3, out); out.write(">"); newline(out); - + if(td.getAccreditation() != null) { indent(3, out); out.write("accreditation = <"); @@ -231,19 +231,19 @@ protected void printLanguage(AuthoredResource authored, out.write(">"); newline(out); } - + if(td.getOtherDetails() != null) { indent(3, out); out.write("other_details = <"); - newline(out); - printMap(td.getOtherDetails(), out, 4); + newline(out); + printMap(td.getOtherDetails(), out, 4); indent(3, out); out.write(">"); newline(out); } - + indent(2, out); - out.write(">"); + out.write(">"); newline(out); } indent(1, out); @@ -251,18 +251,18 @@ protected void printLanguage(AuthoredResource authored, newline(out); } } - - protected void printMap(Map map, Writer out, int indent) + + protected void printMap(Map map, Writer out, int indent) throws IOException { if(map == null || map.size() == 0) { return; } - for(Map.Entry entry: map.entrySet()) { + for(String key : map.keySet()) { indent(indent, out); out.write("["); - out.write(quoteString(entry.getKey())); + out.write(quoteString(key)); out.write("] = <"); - out.write(quoteString(entry.getValue())); + out.write(quoteString(map.get(key))); out.write(">"); newline(out); } @@ -282,9 +282,9 @@ protected void printDescription(ResourceDescription description, Writer out) out.write("original_author = <"); newline(out); Map map = description.getOriginalAuthor(); - for (Map.Entry entry: map.entrySet()) { + for (String key : map.keySet()) { indent(2, out); - out.write("[" + quoteString(entry.getKey()) + "] = <" + quoteString(entry.getValue()) + ">"); + out.write("[" + quoteString(key) + "] = <" + quoteString(map.get(key)) + ">"); newline(out); } indent(1, out); @@ -298,7 +298,7 @@ protected void printDescription(ResourceDescription description, Writer out) newline(out); printNonEmptyString("resource_package_uri", description.getResourcePackageUri(), 1, out); - + indent(1, out); out.write("details = <"); newline(out); @@ -311,7 +311,7 @@ protected void printDescription(ResourceDescription description, Writer out) } protected void printDescriptionItem(ResourceDescriptionItem item, - int indent, Writer out) throws IOException { + int indent, Writer out) throws IOException { indent(indent, out); out.write("["); out.write(quoteString(item.getLanguage().getCodeString())); @@ -326,7 +326,7 @@ protected void printDescriptionItem(ResourceDescriptionItem item, out.write(item.getLanguage().getCodeString()); out.write("]>"); newline(out); - + printNonEmptyString("purpose", item.getPurpose(), indent + 1, out); printNonEmptyStringList("keywords", item.getKeywords(), indent + 1, out); @@ -343,7 +343,7 @@ protected void printDescriptionItem(ResourceDescriptionItem item, } private void printNonEmptyString(String label, String value, int indent, - Writer out) throws IOException { + Writer out) throws IOException { if (StringUtils.isEmpty(value)) { return; @@ -357,7 +357,7 @@ private void printNonEmptyString(String label, String value, int indent, } private void printNonEmptyStringList(String label, List list, - int indent, Writer out) throws IOException { + int indent, Writer out) throws IOException { if (list == null || list.isEmpty()) { return; @@ -376,7 +376,7 @@ private void printNonEmptyStringList(String label, List list, } private void printNonEmptyStringMap(String label, Map map, - int indent, Writer out) throws IOException { + int indent, Writer out) throws IOException { if (map == null || map.isEmpty()) { return; } @@ -386,9 +386,9 @@ private void printNonEmptyStringMap(String label, Map map, out.write(" = <"); newline(out); - for (Map.Entry entry: map.entrySet()) { + for (String key : map.keySet()) { indent(2, out); - out.write("[" + quoteString(entry.getKey()) + "] = <" + quoteString(entry.getValue()) + ">"); + out.write("[" + quoteString(key) + "] = <" + quoteString(map.get(key)) + ">"); newline(out); } @@ -407,16 +407,16 @@ protected void printDefinition(CComplexObject definition, Writer out) } protected void printCComplexObject(CComplexObject ccobj, int indent, - Writer out) throws IOException { - + Writer out) throws IOException { + // TODO skip c_obj with [0,0] occurrences Interval occurrences = ccobj.getOccurrences(); - if(occurrences != null + if(occurrences != null && (Integer.valueOf(0).equals(occurrences.getLower())) && (Integer.valueOf(0).equals(occurrences.getUpper()))) { - return; + return; } - + // print rmTypeName and nodeId indent(indent, out); @@ -450,29 +450,30 @@ protected void printOccurrences(Interval occurrences, Writer out) if(occurrences == null || defaultOccurrences.equals(occurrences)) { return; } - - 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())); + 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("}"); } - out.write("}"); } protected void printArchetypeInternalRef(ArchetypeInternalRef ref, - int indent, Writer out) throws IOException { + 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(" "); out.write(ref.getTargetPath()); newline(out); } @@ -501,33 +502,33 @@ protected void printArchetypeSlot(ArchetypeSlot slot, int indent, Writer out) } newline(out); indent(indent, out); - out.write("}"); + out.write("}"); } newline(out); } - + private void printAssertions(Set assertions, String purpose, - int indent, Writer out) throws IOException { + 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 + + // 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: // @@ -550,7 +551,7 @@ protected void printCAttribute(CAttribute cattribute, int indent, Writer out) CMultipleAttribute cma = (CMultipleAttribute) cattribute; if(cma.getCardinality() != null) { out.write(" "); - printCardinality(cma.getCardinality(), out); + printCardinality(cma.getCardinality(), out); } } List children = cattribute.getChildren(); @@ -602,7 +603,7 @@ protected void printCObject(CObject cobj, int indent, Writer out) printConstraintRef((ConstraintRef) cobj, indent, out); } } - + protected void printConstraintRef(ConstraintRef ref, int indent, Writer out) throws IOException { indent(indent, out); out.write("["); @@ -648,9 +649,9 @@ protected void printCDomainType(CDomainType cdomain, int indent, Writer out) 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); + } + else if (cdomain instanceof CCodePhrase) { + printCCodePhrase((CCodePhrase) cdomain, indent, out); } // unknow CDomainType } @@ -659,7 +660,7 @@ protected void printCCodePhrase(CCodePhrase ccoded, int indent, Writer out) throws IOException { indent(indent, out); - + if(ccoded.isAnyAllowed()) { out.write("C_CODE_PHRASE <"); newline(out); @@ -702,7 +703,7 @@ protected void printCCodePhrase(CCodePhrase ccoded, int indent, Writer out) } out.write("]"); newline(out); - } + } } else { out.write("]"); newline(out); @@ -723,9 +724,9 @@ protected void printCDvOrdinal(CDvOrdinal cordinal, int indent, Writer out) newline(out); } else { - for (Iterator it = cordinal.getList().iterator(); - it.hasNext();) { - Ordinal ordinal = it.next(); + for (Iterator it = cordinal.getList().iterator(); + it.hasNext();) { + Ordinal ordinal = it.next(); indent(indent, out); printOrdinal(ordinal, out); if (it.hasNext()) { @@ -733,17 +734,17 @@ protected void printCDvOrdinal(CDvOrdinal cordinal, int indent, Writer out) } else if(cordinal.hasAssumedValue()) { out.write(";"); } - newline(out); + newline(out); } if(cordinal.hasAssumedValue()) { printOrdinal(cordinal.getAssumedValue(), out); newline(out); } - } + } } - protected void printOrdinal(Ordinal ordinal, Writer out) + protected void printOrdinal(Ordinal ordinal, Writer out) throws IOException { CodePhrase symbol = ordinal.getSymbol(); out.write(Integer.toString(ordinal.getValue())); @@ -751,11 +752,11 @@ protected void printOrdinal(Ordinal ordinal, Writer out) out.write(symbol.getTerminologyId().getValue()); out.write("::"); out.write(symbol.getCodeString()); - out.write("]"); + out.write("]"); } protected void printCDvQuantity(CDvQuantity cquantity, int indent, - Writer out) throws IOException { + Writer out) throws IOException { indent(indent, out); out.write("C_DV_QUANTITY <"); newline(out); @@ -770,7 +771,7 @@ protected void printCDvQuantity(CDvQuantity cquantity, int indent, } List list = cquantity.getList(); if (list != null) { - newline(out); + newline(out); indent(indent + 1, out); out.write("list = <"); newline(out); @@ -794,7 +795,7 @@ protected void printCDvQuantity(CDvQuantity cquantity, int indent, out.write(">"); newline(out); } - + Interval precision = item.getPrecision(); if (precision != null) { indent(indent + 3, out); @@ -812,10 +813,10 @@ protected void printCDvQuantity(CDvQuantity cquantity, int indent, out.write(">"); newline(out); } - - + + if(cquantity.getAssumedValue() != null) { - newline(out); + newline(out); indent(indent + 1, out); out.write("assumed_value = <"); newline(out); @@ -823,20 +824,20 @@ protected void printCDvQuantity(CDvQuantity cquantity, int indent, indent(indent + 1, out); out.write(">"); newline(out); - } - + } + indent(indent, out); out.write(">"); newline(out); } - - protected void printDvQuantity(DvQuantity quantity, int indent, Writer 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 = <"); @@ -850,7 +851,7 @@ protected void printDvQuantity(DvQuantity quantity, int indent, Writer out) out.write(">"); newline(out); } - + protected void printUnits(String units, Writer out) throws IOException { out.write("units = <"); out.write(quoteString(units)); @@ -925,8 +926,8 @@ protected void printOntology(ArchetypeOntology ontology, Writer out) if (item.getTerms().size() > 1) { for (int k = 1; k < item.getTerms().size(); k++) { - out.write("," + item.getTerms().get(k)); - } + out.write("," + item.getTerms().get(k)); + } } out.write(">"); @@ -985,12 +986,12 @@ protected void printOntology(ArchetypeOntology ontology, Writer out) } } - private String quoteString(String value) { - return "\"" + value.replaceAll("[\"]", "\\\\$0") + "\""; - } + private String quoteString(String value) { + return "\"" + value.replaceAll("[\"]", "\\\\$0") + "\""; + } private void printDefinitionList(Writer out, - List termDefinitionsList) throws IOException { + List termDefinitionsList) throws IOException { for (OntologyDefinitions defs : termDefinitionsList) { indent(2, out); out.write("["); @@ -1068,7 +1069,7 @@ protected void printCBoolean(CBoolean cboolean, Writer out) } else { out.write("false"); } - } + } } protected void printCDate(CDate cdate, Writer out) throws IOException { @@ -1182,8 +1183,8 @@ protected void printList(List list, Writer out, boolean string) if (string) { out.write(quoteString(item)); } else { - out.write(item); - } + out.write(item); + } } } @@ -1192,7 +1193,7 @@ protected void printInterval(Interval interval, Writer out) out.write("|"); if (interval.getLower() != null && interval.getUpper() != null) { if(interval.getLower().equals(interval.getUpper()) - && interval.isLowerIncluded() + && interval.isLowerIncluded() && interval.isUpperIncluded()) { out.write(interval.getLower().toString()); } else { @@ -1237,27 +1238,27 @@ private void indent(int level, Writer out) throws IOException { } /* * ***** 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, + * + * 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 ***** - */ \ No newline at end of file + */ 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 index 01b20c14..722beb52 100755 --- a/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java @@ -65,7 +65,7 @@ /** * Validator for archetypes *

- * + *

* It checks the following * .archetype term validity * .constraint code validity @@ -78,7 +78,7 @@ * .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 + * .object constraint type name validity * .archetype concept specialisation depth * .use_node type validity * .use_node path validity @@ -86,8 +86,7 @@ * .archetype specialisation parent identifier validity * * @author rong.chen - * @author sebastian.garde - * + * @author sebastian.garde * @version 1.0 */ public class ArchetypeValidator { @@ -100,13 +99,13 @@ public ArchetypeValidator() { try { this.termService = SimpleTerminologyService.getInstance(); - this.openEHRTerminology = termService.terminology( + this.openEHRTerminology = termService.terminology( TerminologyService.OPENEHR); - } catch(Exception e) { + } catch (Exception e) { log.error("failed to start the terminology service", e); } - } + } private boolean reportConstraintsOnCommonFunctionalPropertiesAsInfo = false; @@ -116,14 +115,14 @@ public final void setReportConstraintsOnCommonFunctionalPropertiesAsInfo( } /** - * Validates the given archetype - * + * 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) + public List validate(Archetype archetype, boolean reportConstraintsOnCommonFunctionalPropertiesAsInfo) throws RMInspectionException { this.reportConstraintsOnCommonFunctionalPropertiesAsInfo = reportConstraintsOnCommonFunctionalPropertiesAsInfo; List errors = new ArrayList(); @@ -145,31 +144,36 @@ public List validate(Archetype archetype, boolean reportConstra } - /** - * Validates the given archetype - * + * Validates the given archetype + * * @param archetype * @return list of validation errors or empty list if valid */ - public List validate(Archetype archetype) + public List validate(Archetype archetype) throws RMInspectionException { return validate(archetype, false); } public void checkDescription(Archetype archetype, List errors) { - if (archetype.getDescription() ==null) { + if (archetype.getDescription() == null) { return; } + ArrayList checkedLanguages = new ArrayList<>(); // check purpose in each available language for (ResourceDescriptionItem detail : archetype.getDescription().getDetails().values()) { - if (StringUtils.isBlank(detail.getPurpose()) || StringUtils.containsIgnoreCase(detail.getPurpose(),"unknown")) { - ValidationError error = new ValidationError(ErrorType.VDSCR, "PURPOSE", + 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 @@ -197,12 +201,12 @@ public void checkDescription(Archetype archetype, List errors) } } - public void checkArchetypeDefinitionCodeValidity(Archetype archetype, - List errors) { + 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); + if (!concept.equals(rootNodeId)) { + ValidationError error = new ValidationError(ErrorType.VACCD, null); errors.add(error); } @@ -217,39 +221,39 @@ public void checkArchetypeUnitsValidity(CDvQuantity cDvQuantity, List errors) { + 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 ); + 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) { + List errors) { if (archetype.getParentArchetypeId() == null) { return; // no specialise clause at all @@ -263,27 +267,26 @@ public void checkSpecializationParentIdentifierValidity(Archetype archetype, 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: " + + log.debug("validating ontology code specialisation of archetype: " + archetype.getArchetypeId()); List specialisation = archetype.getArchetypeId().specialisation(); @@ -300,18 +303,18 @@ public void checkOntologyCodeSpecialisationLevelValidity( checkOntologyDefinitions(list, errors, level); list = archetype.getOntology().getConstraintDefinitionsList(); - checkOntologyDefinitions(list, errors, level); + checkOntologyDefinitions(list, errors, level); } private void checkOntologyDefinitions(List defList, - List errors, int level) { + List errors, int level) { ValidationError error = null; - for(OntologyDefinitions defs : defList) { - for(ArchetypeTerm term : defs.getDefinitions()) { - if(hasGreaterSpecialisationLevel(term.getCode(), level)) { + 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); + errors.add(error); } } } @@ -319,7 +322,7 @@ private void checkOntologyDefinitions(List defList, private boolean hasGreaterSpecialisationLevel(String code, int level) { StringTokenizer tokens = new StringTokenizer(code, "."); - if(tokens.countTokens() - 1 > level) { + if (tokens.countTokens() - 1 > level) { return true; } return false; @@ -328,19 +331,20 @@ private boolean hasGreaterSpecialisationLevel(String code, int level) { /** * Checks various object constraints - * + * * @param archetype * @param errors * @throws RMInspectionException */ - public void checkObjectConstraints(Archetype archetype, - List 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 - * + /** + * checks whether the rmAttrName is a commonly constrained functional property of the parentRMType + * * @param rmAttrName * @param parentRMTypeName * @return @@ -360,10 +364,10 @@ private boolean isCommonFunctionalProperty(String rmAttrName, String parentRMTyp } - private void validateCAttribute(CAttribute cattr, - Map rmAttrs, CComplexObject parent, - Archetype archetype, List errors) - throws RMInspectionException { + private void validateCAttribute(CAttribute cattr, + Map rmAttrs, CComplexObject parent, + Archetype archetype, List errors) + throws RMInspectionException { String rmAttrName = cattr.getRmAttributeName(); @@ -376,33 +380,33 @@ private void validateCAttribute(CAttribute cattr, String parentRmClassName = parent.getRmTypeName(); parentRmClassName = removeGenericTypes(parentRmClassName); String parentGenericTypeName = getGenericType(parent.getRmTypeName()); - log.debug("Generic type name: "+ parentGenericTypeName); + log.debug("Generic type name: " + parentGenericTypeName); Class parentRmClass = rmInspector.retrieveRMType(parentRmClassName); Class parentGenericType = null; - if(parentGenericTypeName != null) { + if (parentGenericTypeName != null) { parentGenericType = rmInspector.retrieveRMType(parentGenericTypeName); } // replace primitive types with object types - if(int.class.equals(rmAttrType)) { + if (int.class.equals(rmAttrType)) { rmAttrType = Integer.class; - } else if(double.class.equals(rmAttrType)) { + } else if (double.class.equals(rmAttrType)) { rmAttrType = Double.class; - } else if(boolean.class.equals(rmAttrType)) { + } else if (boolean.class.equals(rmAttrType)) { rmAttrType = Boolean.class; } log.debug("1- validating attribute [" + rmAttrName + "] of type [" + rmAttrType + "]"); - if( ! rmAttrNames.contains(rmAttrName)) { + 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()); + rmAttrName, cattr.path(), parent.getRmTypeName()); } else { - error = new ValidationError(ErrorType.VCARM, null, + error = new ValidationError(ErrorType.VCARM, null, rmAttrName, parent.getRmTypeName(), cattr.path()); } errors.add(error); @@ -410,7 +414,7 @@ private void validateCAttribute(CAttribute cattr, } if (cattr instanceof CMultipleAttribute) { - CMultipleAttribute cmattr = (CMultipleAttribute)cattr; + CMultipleAttribute cmattr = (CMultipleAttribute) cattr; checkCardinalityConformsToRMCardinality(cmattr, parent, errors); //check Cardinality fits with the minimum and maximum of all occurrences of the children @@ -418,13 +422,13 @@ private void validateCAttribute(CAttribute cattr, } - if(cattr.getChildren() == null) { + if (cattr.getChildren() == null) { return; } - for(CObject cobj : cattr.getChildren()) { + for (CObject cobj : cattr.getChildren()) { - if(cattr instanceof CSingleAttribute) { + if (cattr instanceof CSingleAttribute) { // check rm type String childRMTypeName = cobj.getRmTypeName(); @@ -437,33 +441,33 @@ private void validateCAttribute(CAttribute cattr, Class childRMType = rmInspector.retrieveRMType(childRMTypeName); - if(childRMType == null) { - error = new ValidationError(ErrorType.VCORM, null, + 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()); + 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)){ + } else if (parentRmClass.equals(childRMType)) { log.debug("skipping unnecessary check on " + parentRmClass); continue; - } else if(!rmAttrType.isEnum() - && !(rmAttrType.isAssignableFrom(childRMType))){ + } else if (!rmAttrType.isEnum() + && !(rmAttrType.isAssignableFrom(childRMType))) { - log.debug("3- rmAttrType: "+rmAttrType + " with name [" + - rmAttrName+ "] is NOT assignable from type [" + + log.debug("3- rmAttrType: " + rmAttrType + " with name [" + + rmAttrName + "] is NOT assignable from type [" + childRMType + "]"); ErrorType type = ErrorType.VCORMT; - if(cobj instanceof ArchetypeInternalRef) { + if (cobj instanceof ArchetypeInternalRef) { type = ErrorType.VUNT; - } + } error = new ValidationError(type, "NORMAL", childRMTypeName, cobj.path(), rmAttrType.getSimpleName()); if (!errors.contains(error)) { @@ -475,54 +479,54 @@ private void validateCAttribute(CAttribute cattr, && !(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 [" + + 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) { + if (cobj instanceof ArchetypeInternalRef) { type = ErrorType.VUNT; - } + } error = new ValidationError(type, "PARENT", - parentGenericTypeName, parent.path(), childRMType.getSimpleName(), cobj.path()); + parentGenericTypeName, parent.path(), childRMType.getSimpleName(), cobj.path()); errors.add(error); continue; - } + } log.debug("5- rmAttrType: " + rmAttrType + " with name " + - rmAttrName+ " IS assignable from "+ childRMType); + rmAttrName + " IS assignable from " + childRMType); // check csingle attribute child object occurrences Interval occu = cobj.getOccurrences(); - if(occu != null && occu.isUpperIncluded() + if (occu != null && occu.isUpperIncluded() && occu.getUpper() > 1) { - error = new ValidationError(ErrorType.VACSO, null, + error = new ValidationError(ErrorType.VACSO, null, cobj.path()); errors.add(error); - } - for(CObject cobj2 : cattr.getChildren()) { - if(cobj == cobj2) { + } + for (CObject cobj2 : cattr.getChildren()) { + if (cobj == cobj2) { continue; } // check child uniqueness - if(cobj2.getRmTypeName().equals(cobj.getRmTypeName()) + if (cobj2.getRmTypeName().equals(cobj.getRmTypeName()) && cobj.getNodeId() == null) { error = new ValidationError(ErrorType.VACSU, null, cobj.path()); - if( ! errors.contains(error)) { + if (!errors.contains(error)) { errors.add(error); } } // check child identifier - if(cobj2.getNodeId() != null + if (cobj2.getNodeId() != null && cobj2.getNodeId().equals(cobj.getNodeId())) { error = new ValidationError(ErrorType.VACSI, null, cobj.path()); - if( ! errors.contains(error)) { + if (!errors.contains(error)) { errors.add(error); } } @@ -540,12 +544,12 @@ private void validateCAttribute(CAttribute cattr, } 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)) { + 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(), @@ -554,9 +558,9 @@ private void validateCAttribute(CAttribute cattr, getIntervalFormalString(cobj.getOccurrences()), cattr.path()); - if( ! errors.contains(error)) { + if (!errors.contains(error)) { errors.add(error); - } + } } else if (cobj.getNodeId() == null) { // check missing child identifier @@ -565,34 +569,34 @@ private void validateCAttribute(CAttribute cattr, // 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) { + for (CObject cobj2 : cattr.getChildren()) { + if (cobj == cobj2) { continue; } - if(cobj2.getNodeId()== null && cobj2 instanceof ArchetypeInternalRef && + if (cobj2.getNodeId() == null && cobj2 instanceof ArchetypeInternalRef && ((ArchetypeInternalRef) cobj).getTargetPath().equals(((ArchetypeInternalRef) cobj2).getTargetPath())) { - error = new ValidationError(ErrorType.VACMM, "INTREF", + error = new ValidationError(ErrorType.VACMM, "INTREF", cobj.path()); - if( ! errors.contains(error)) { + if (!errors.contains(error)) { errors.add(error); } } } } else { - error = new ValidationError(ErrorType.VACMI, null, + error = new ValidationError(ErrorType.VACMI, null, cobj.path()); errors.add(error); } } else { // check duplicated child identifier - for(CObject cobj2 : cattr.getChildren()) { - if(cobj == cobj2) { + for (CObject cobj2 : cattr.getChildren()) { + if (cobj == cobj2) { continue; } - if(cobj.getNodeId().equals(cobj2.getNodeId())) { + if (cobj.getNodeId().equals(cobj2.getNodeId())) { error = new ValidationError(ErrorType.VACMM, "NORMAL", cobj.path()); - if( ! errors.contains(error)) { + if (!errors.contains(error)) { errors.add(error); } } @@ -603,22 +607,22 @@ private void validateCAttribute(CAttribute cattr, } if (cobj instanceof CDomainType) { // also includes CDVQuantity! - log.debug("validating CDomainType of node_id: "+ cobj.getNodeId()); + 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()); + log.debug("validating CPrimitiveObject at: " + cobj.path()); validateCPrimitiveObject((CPrimitiveObject) cobj, archetype, errors); - } else if(cobj instanceof CComplexObject) { - log.debug("validating ccobj at: "+ cobj.getNodeId()); + } 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()); + } 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()); + } 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()); + log.debug("not continuing with recursion for class: " + cobj.getClass()); } } } @@ -632,7 +636,7 @@ private void checkCardinalityConformsToChildrenOccurrences( } - Interval cardinalityInterval = + Interval cardinalityInterval = (cmattr).getCardinality().getInterval(); int minOcc = 0; @@ -640,56 +644,54 @@ private void checkCardinalityConformsToChildrenOccurrences( boolean isOccUpperUnbounded = false; for (CObject cobj : cmattr.getChildren()) { - minOcc += cobj.getOccurrences().getLower(); + minOcc += cobj.getOccurrences().getLower(); if (cobj.getOccurrences().isUpperUnbounded()) { isOccUpperUnbounded = true; - } else { + } else { maxOcc += cobj.getOccurrences().getUpper(); } } // check lower: - if (! cardinalityInterval.isUpperUnbounded() && minOcc > cardinalityInterval.getUpper()) { + 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)) { + ); + if (!errors.contains(error)) { errors.add(error); return; // found an error, so can return } } // check upper - if ( !isOccUpperUnbounded + 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)) { + if (!errors.contains(error)) { errors.add(error); - } + } } - if (!cardinalityInterval.isUpperUnbounded() && - minOcc != maxOcc && + 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 (TBD) + // 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) - ); + cmattr.path(), getIntervalFormalString(cardinalityInterval), getIntervalFormalString(minOcc, maxOcc, isOccUpperUnbounded)); - if( ! errors.contains(error)) { + if (!errors.contains(error)) { errors.add(error); - } + } } - } private void checkCardinalityConformsToRMCardinality(CMultipleAttribute cattr, CObject cobj, List errors) { @@ -698,7 +700,7 @@ private void checkCardinalityConformsToRMCardinality(CMultipleAttribute cattr, C 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)); + 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 @@ -708,30 +710,32 @@ private void checkCardinalityConformsToRMCardinality(CMultipleAttribute cattr, C if (!rmCardinality.isUpperUnbounded()) { - if (actualCardinality.isUpperUnbounded() || - (rmCardinality.getUpper().compareTo(actualCardinality.getUpper()) <0)) { + 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)); + cattr.path(), getIntervalFormalString(actualCardinality), getIntervalFormalString(rmCardinality)); errors.add(error); - } else if (rmCardinality.getUpper().compareTo(actualCardinality.getUpper()) ==0) { + } else if (rmCardinality.getUpper().compareTo(actualCardinality.getUpper()) == 0) { //WCACA - } + } } } - /** Checks the assertions of an archetype for validity + /** + * 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) { + List errors) { if (slot.getIncludes() != null) { for (Assertion include : slot.getIncludes()) { checkAssertionHasValidArchetypeIds(include, slot, errors); @@ -744,8 +748,9 @@ private void checkArchetypeSlot(ArchetypeSlot slot, Class rmAttrType, Archetype } } - /** Checks that an assertion contains valid archetype ids - * + /** + * Checks that an assertion contains valid archetype ids + * * @param assertion * @param slot * @param errors @@ -755,39 +760,41 @@ private void checkAssertionHasValidArchetypeIds(Assertion assertion, ArchetypeSl ExpressionBinaryOperator ebo = (ExpressionBinaryOperator) assertion.getExpression(); if (ebo.getRightOperand() instanceof ExpressionLeaf) { - ExpressionLeaf elR =(ExpressionLeaf)ebo.getRightOperand(); + ExpressionLeaf elR = (ExpressionLeaf) ebo.getRightOperand(); if (elR.getItem() != null && elR.getItem() instanceof CString) { - CString elRCStr = (CString)elR.getItem(); - if (elRCStr.getPattern() !=null) { + CString elRCStr = (CString) elR.getItem(); + if (elRCStr.getPattern() != null) { String pattern = elRCStr.getPattern(); - if (!pattern.equals(".*")) { + if (!pattern.equals(".*")) { // make readability modifications for the pattern - while (pattern.indexOf("(-[a-zA-Z0-9_]+)*\\") >0) { + while (pattern.indexOf("(-[a-zA-Z0-9_]+)*\\") > 0) { int i = pattern.indexOf("(-[a-zA-Z0-9_]+)*\\"); 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) { + while (pattern.indexOf("\\.") > 0) { pattern = pattern.replace("\\.", "."); } - while (pattern.indexOf("|") >0) { - String oneId = pattern.substring(0,pattern.indexOf("|") ); - pattern = pattern.substring(pattern.indexOf("|")+1); - checkOneArchetypeId(slot, errors, oneId); + while (pattern.indexOf("|") > 0) { + String oneId = pattern.substring(0, pattern.indexOf("|")); + pattern = pattern.substring(pattern.indexOf("|") + 1); + checkOneArchetypeId(slot, errors, oneId); } // the rest of the pattern is the last archetype id, so test this one too. - checkOneArchetypeId(slot, errors, pattern); - } - } + checkOneArchetypeId(slot, errors, pattern); + } + } } - } + } } } - /** Checks one archetype id to be a valid id or not + /** + * Checks one archetype id to be a valid id or not + * * @param slot * @param errors * @param oneId @@ -797,12 +804,12 @@ private void checkOneArchetypeId(ArchetypeSlot slot, List error boolean containsCorrectNumberOfDots = (StringUtils.countMatches(oneId, ".") == 2); // check that the id ends with .v[0..9]* - boolean endsWithDotVNumber =true; // assume it is ok, until proven false - if (oneId.lastIndexOf(".v")== -1) { + boolean endsWithDotVNumber = true; // assume it is ok, until proven false + if (oneId.lastIndexOf(".v") == -1) { endsWithDotVNumber = false; } else { - String tail = oneId.substring(oneId.lastIndexOf(".v")+2); - log.debug("tail: "+ tail); + String tail = oneId.substring(oneId.lastIndexOf(".v") + 2); + log.debug("tail: " + tail); if (tail.length() == 0 || !StringUtils.isNumeric(tail)) { endsWithDotVNumber = false; } @@ -810,7 +817,7 @@ private void checkOneArchetypeId(ArchetypeSlot slot, List error // check that the first part of the id (the qualified RM Entity) contains the right number of hyphens boolean containsCorrectNumberOfHyphensInQualifiedRMEntity = true; // assume it is ok, until proven wrong - String qualifiedRMEntity = oneId.substring(0, oneId.indexOf(".")); + String qualifiedRMEntity = oneId.substring(0, oneId.indexOf(".")); if (StringUtils.countMatches(qualifiedRMEntity, "-") != 2) { containsCorrectNumberOfHyphensInQualifiedRMEntity = false; } @@ -820,13 +827,13 @@ private void checkOneArchetypeId(ArchetypeSlot slot, List error ValidationError error = new ValidationError(ErrorType.VDFAI, "NUMBEROFDOTS", oneId, slot.path()); errors.add(error); - } - if (!endsWithDotVNumber) { + } + if (!endsWithDotVNumber) { ValidationError error = new ValidationError(ErrorType.VDFAI, "DOTVNUMBER", oneId, slot.path()); errors.add(error); } - if (!containsCorrectNumberOfHyphensInQualifiedRMEntity) { + if (!containsCorrectNumberOfHyphensInQualifiedRMEntity) { ValidationError error = new ValidationError(ErrorType.VDFAI, "NUMBEROFHYPHENS", oneId, slot.path()); errors.add(error); @@ -837,57 +844,57 @@ private void checkOneArchetypeId(ArchetypeSlot slot, List error /** * Validates a given c_domain_type constraint - * - * TODO: does not report a problem on values that have a higher precision than specified - * + *

+ * 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) { + */ + private void validateCDomainType(CDomainType cdtobj, Archetype archetype, + List errors) { if (cdtobj.hasAssumedValue()) { - log.debug("validating assumed value: " +cdtobj.getAssumedValue()); + log.debug("validating assumed value: " + cdtobj.getAssumedValue()); if (!cdtobj.validValue(cdtobj.getAssumedValue())) { - ValidationError error = new ValidationError(ErrorType.VOBAV, null, + 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()); - } + } else { + log.debug("No assumed value found for : " + cdtobj.getRmTypeName() + " at " + cdtobj.path()); + } - if(cdtobj instanceof CCodePhrase) { + 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); - } - + 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) { + private void validateCCodePhrase(CCodePhrase ccodephrase, + List errors) { - if(ccodephrase.getCodeList() == null + if (ccodephrase.getCodeList() == null || !TerminologyService.OPENEHR.equalsIgnoreCase( - ccodephrase.getTerminologyId().toString())) { + ccodephrase.getTerminologyId().toString())) { return; } StringBuffer buf = new StringBuffer(); - for(String code : ccodephrase.getCodeList()) { - if( ! openEHRTerminology.allCodes().contains( + 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, + if (codes.length() != 0) { + ValidationError error = new ValidationError(ErrorType.VOTC, null, codes, ccodephrase.path()); errors.add(error); } @@ -903,26 +910,26 @@ private void validateCPrimitiveObject(CPrimitiveObject cpobj, Archetype archetyp CPrimitive item = cpobj.getItem(); if (item.hasAssumedValue()) { Object assumedValue = item.assumedValue(); - log.debug("Assumed value for CPrimitiveObject: "+assumedValue); + log.debug("Assumed value for CPrimitiveObject: " + assumedValue); - if (!item.validValue(assumedValue)) { - ValidationError error = new ValidationError(ErrorType.VOBAV, null, + 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()); + 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()); + } 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 { + List errors) throws RMInspectionException { - checkGenericTypeName(ccobj, errors); - if(ccobj.getAttributes() == null) { + checkGenericTypeName(ccobj, errors); + if (ccobj.getAttributes() == null) { return; } @@ -935,7 +942,7 @@ private void validateCComplexObject(CComplexObject ccobj, Archetype archetype, rmTypeNameWithoutGeneric); ValidationError error = null; - if(rmAttrNames.isEmpty()) { + if (rmAttrNames.isEmpty()) { error = new ValidationError(ErrorType.VCORM, null, rmTypeNameWithoutGeneric, ccobj.path()); errors.add(error); @@ -943,9 +950,9 @@ private void validateCComplexObject(CComplexObject ccobj, Archetype archetype, } - HashSet attributeNames = new HashSet(); - for(CAttribute cattr : ccobj.getAttributes()) { - validateCAttribute(cattr, rmAttrs, ccobj, archetype, errors); + 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())) { @@ -955,40 +962,42 @@ private void validateCComplexObject(CComplexObject ccobj, Archetype archetype, 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 + /** + * 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); + log.debug("Generic type name: " + genericTypeName); Class genericType = null; - if(genericTypeName != null) { + if (genericTypeName != null) { genericType = rmInspector.retrieveRMType(genericTypeName); - log.debug("Generic type: "+ genericType); + log.debug("Generic type: " + genericType); } - if (genericTypeName != null && genericType == null){ + if (genericTypeName != null && genericType == null) { error = new ValidationError(ErrorType.VCORM, null, - ccobj.getRmTypeName(), ccobj.path()); + 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)) { + if (!DvOrdered.class.isAssignableFrom(genericType)) { error = new ValidationError(ErrorType.VCORMT, "NORMAL", - ccobj.getRmTypeName(), ccobj.path(), genericType.getSimpleName()); + ccobj.getRmTypeName(), ccobj.path(), genericType.getSimpleName()); errors.add(error); - } + } } } protected String removeGenericTypes(String rmTypeName) { - if(rmTypeName.indexOf("<") > 0 && rmTypeName.indexOf(">") > 0) { + if (rmTypeName.indexOf("<") > 0 && rmTypeName.indexOf(">") > 0) { rmTypeName = rmTypeName.substring(0, rmTypeName.indexOf("<")); } return rmTypeName; @@ -999,7 +1008,7 @@ protected String getGenericType(String rmTypeName) { int start = rmTypeName.indexOf("<"); int end = rmTypeName.indexOf(">"); String genericType = null; - if(start > 0 && end > start) { + if (start > 0 && end > start) { genericType = rmTypeName.substring(start + 1, end); } return genericType; @@ -1007,50 +1016,50 @@ protected String getGenericType(String rmTypeName) { /** * Checks the given ArchetypeInternalRef - * + * * @param ref * @param archetype * @param errors */ public void checkArchetypeInternalRef(ArchetypeInternalRef ref, /*Class rmAttributeType,*/ Archetype archetype, - List errors) { + List errors) { log.debug("validating internal_ref of rmType: " + ref.getRmTypeName() + - " at " +ref.path() + " with target " +ref.getTargetPath()); + " 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) { + 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) { + 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) { + 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()); + "Unknown target rm type at path: " + ref.getTargetPath() + + " of internalRef at: " + ref.path()); errors.add(error); - } else if( ! rmType.isAssignableFrom(targetType)) { + } else if (!rmType.isAssignableFrom(targetType)) { error = new ValidationError(ErrorType.VUNP, "INVALIDTARGETRM", targetType, ref.path()); errors.add(error); - } + } } } @@ -1058,63 +1067,77 @@ public void checkArchetypeInternalRef(ArchetypeInternalRef ref, * 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) { + public void checkArchetypeDefinitionTypename(Archetype archetype, + List errors) { String conceptType = archetype.getArchetypeId().rmEntity(); String topType = archetype.getDefinition().getRmTypeName(); ValidationError error = null; - if( ! conceptType.equals(topType)) { + 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 - * + * Checks if languages listed in translation section are provided in + * term_definition and constraint_definition sections + *

* TODO: how about missing individual term_def/constraint_def translations? - * + * * @param archetype * @return errors */ public void checkOntologyTranslation(Archetype archetype, - List errors) { + List errors) { Set languages = archetype.languagesAvailable(); String primaryLang = archetype.getOriginalLanguage().getCodeString(); - List termDefList = - archetype.getOntology().getTermDefinitionsList(); - List constraintDefList = - archetype.getOntology().getConstraintDefinitionsList(); + + 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) { - if(primaryLang.equals(lang)) { + ValidationError error; + for (String lang : languages) { + if (primaryLang.equals(lang)) { continue; } - if( ! termDefLangs.contains(lang)) { + if (!termDefLangs.contains(lang)) { error = new ValidationError(ErrorType.VOTM, "TERM", lang); errors.add(error); } - if(!constraintDefList.isEmpty() + 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) { + for (OntologyDefinitions defs : list) { set.add(defs.getLanguage()); } return set; @@ -1122,7 +1145,7 @@ private Set retrieveLanguageSet(List list) { /** * TODO not used - * + *

* Check internal references * * @return map of node path, target path if any wrong internal references @@ -1134,16 +1157,16 @@ Map checkInternalReferences(Archetype archetype) { } private Map checkInternalReferences(Archetype archetype, - CComplexObject ccobj, - Map errors) { + 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()); + CObject target = (CObject) archetype.node(ref.getTargetPath()); if (target == null || !target.getRmTypeName().equals( - cobj.getRmTypeName())) { + cobj.getRmTypeName())) { // either target unknown or wrong type errors.put(ref.path(), ref.getTargetPath()); } @@ -1158,17 +1181,17 @@ private Map checkInternalReferences(Archetype archetype, } public void checkArchetypeTermValidity(Archetype archetype, - List errors) { - Set codes = fetchAllATCodes(archetype); + List errors) { + Set codes = fetchAllATCodes(archetype); String lang = archetype.getOriginalLanguage().getCodeString(); - List defList = + List defList = archetype.getOntology().getTermDefinitionsList(); OntologyDefinitions priDefs = null; ValidationError error = null; ArrayList secondaryLanguageOntDefs = new ArrayList(); - for(OntologyDefinitions defs : defList) { - if(lang.equals(defs.getLanguage())) { + for (OntologyDefinitions defs : defList) { + if (lang.equals(defs.getLanguage())) { priDefs = defs; } else { secondaryLanguageOntDefs.add(defs); @@ -1177,8 +1200,8 @@ public void checkArchetypeTermValidity(Archetype archetype, // first check for the primary language Set definedCodesPrimLang = new LinkedHashSet(); - if(priDefs == null) { - for(String code : codes) { + if (priDefs == null) { + for (String code : codes) { error = new ValidationError(ErrorType.VATDF, "NORMAL", code); errors.add(error); @@ -1186,12 +1209,12 @@ public void checkArchetypeTermValidity(Archetype archetype, } else { List terms = priDefs.getDefinitions(); - for(ArchetypeTerm term : terms) { + for (ArchetypeTerm term : terms) { definedCodesPrimLang.add(term.getCode()); } - for(String code : codes) { - if( ! definedCodesPrimLang.contains(code)) { - error = new ValidationError(ErrorType.VATDF, "NORMAL", + for (String code : codes) { + if (!definedCodesPrimLang.contains(code)) { + error = new ValidationError(ErrorType.VATDF, "NORMAL", code); errors.add(error); } @@ -1199,16 +1222,16 @@ public void checkArchetypeTermValidity(Archetype archetype, } // now check for the secondary languages - for (OntologyDefinitions secDefs :secondaryLanguageOntDefs) { + for (OntologyDefinitions secDefs : secondaryLanguageOntDefs) { List terms = secDefs.getDefinitions(); Set definedCodesSecLang = new LinkedHashSet(); - for(ArchetypeTerm term : terms) { + for (ArchetypeTerm term : terms) { definedCodesSecLang.add(term.getCode()); } - for(String code : codes) { + for (String code : codes) { // if not present in sec lang, but present in prim lang: - if( ! definedCodesSecLang.contains(code) && definedCodesPrimLang.contains(code)) { + if (!definedCodesSecLang.contains(code) && definedCodesPrimLang.contains(code)) { error = new ValidationError(ErrorType.VONLC, "TERM", code, secDefs.getLanguage()); errors.add(error); @@ -1222,17 +1245,17 @@ public void checkArchetypeTermValidity(Archetype archetype, } public void checkCodeConstraintValidity(Archetype archetype, - List errors) { - Set codes = fetchAllACCodes(archetype); + List errors) { + Set codes = fetchAllACCodes(archetype); String lang = archetype.getOriginalLanguage().getCodeString(); - List defList = + List defList = archetype.getOntology().getConstraintDefinitionsList(); OntologyDefinitions priDefs = null; ValidationError error = null; ArrayList secondaryLanguageOntDefs = new ArrayList(); - for(OntologyDefinitions defs : defList) { - if(lang.equals(defs.getLanguage())) { + for (OntologyDefinitions defs : defList) { + if (lang.equals(defs.getLanguage())) { priDefs = defs; } else { secondaryLanguageOntDefs.add(defs); @@ -1241,19 +1264,19 @@ public void checkCodeConstraintValidity(Archetype archetype, Set definedCodesPrimLang = new LinkedHashSet(); - if(priDefs == null) { - for(String code : codes) { + 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) { + for (ArchetypeTerm term : terms) { definedCodesPrimLang.add(term.getCode()); } - for(String code : codes) { - if( ! definedCodesPrimLang.contains(code)) { + for (String code : codes) { + if (!definedCodesPrimLang.contains(code)) { error = new ValidationError(ErrorType.VACDF, null, code); errors.add(error); @@ -1262,16 +1285,16 @@ public void checkCodeConstraintValidity(Archetype archetype, } // now check for the secondary languages - for (OntologyDefinitions secDefs :secondaryLanguageOntDefs) { + for (OntologyDefinitions secDefs : secondaryLanguageOntDefs) { List terms = secDefs.getDefinitions(); Set definedCodesSecLang = new LinkedHashSet(); - for(ArchetypeTerm term : terms) { + for (ArchetypeTerm term : terms) { definedCodesSecLang.add(term.getCode()); } - for(String code : codes) { + for (String code : codes) { // if not present in sec lang, but present in prim lang: - if( ! definedCodesSecLang.contains(code) && definedCodesPrimLang.contains(code)) { + if (!definedCodesSecLang.contains(code) && definedCodesPrimLang.contains(code)) { error = new ValidationError(ErrorType.VONLC, "CONSTRAINT", code, secDefs.getLanguage()); errors.add(error); @@ -1282,58 +1305,59 @@ public void checkCodeConstraintValidity(Archetype archetype, checkForUnusedCodes(defList, errors, archetype, codes); checkForDoubleCodes(defList, errors, archetype); - } - + } - /** Checks for unused codes in the ontology - * + /** + * Checks for unused codes in the ontology + * * @param defList * @param errors * @param archetype */ private void checkForUnusedCodes(List defList, - List errors, Archetype archetype, Set actuallyUsedCodes) { + 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())) { + 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); - } + errors.add(error); + } } } } } - /** Checks for codes in the ontology that are there more than once - * + /** + * 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) { + List errors, Archetype archetype) { // now check for each code if it exists in the definition ValidationError error = null; - for(OntologyDefinitions defs : defList) { + for (OntologyDefinitions defs : defList) { HashSet foundCodes = new HashSet(); - for(ArchetypeTerm term : defs.getDefinitions()) { - if(foundCodes.contains(term.getCode())) { + 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); + errors.add(error); } else { foundCodes.add(term.getCode()); } @@ -1342,7 +1366,7 @@ private void checkForDoubleCodes(List defList, } public void checkArchetypeTermBindingsValidity(Archetype archetype, - List errors) { + List errors) { List termBindings = archetype.getOntology().getTermBindingList(); ValidationError error = null; @@ -1350,7 +1374,7 @@ public void checkArchetypeTermBindingsValidity(Archetype archetype, 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) { + if (archetype.getOntology().termDefinition(archetype.getOriginalLanguage().getCodeString(), obi.getCode()) == null) { error = new ValidationError(ErrorType.WITB, "ATCODE", obi.getCode()); errors.add(error); @@ -1360,7 +1384,7 @@ public void checkArchetypeTermBindingsValidity(Archetype archetype, error = new ValidationError(ErrorType.WITB, "PATH", obi.getCode()); errors.add(error); - } + } } } } @@ -1370,7 +1394,7 @@ public void checkArchetypeTermBindingsValidity(Archetype archetype, /** * Traverse the archetype and gather all at codes - * + * * @param archetype * @return a set of at codes */ @@ -1387,43 +1411,43 @@ Set fetchAllATCodes(Archetype archetype) { } void fetchATCodes(CObject cobj, Set codes) { - if(cobj.getNodeId() != null) { + if (cobj.getNodeId() != null) { codes.add(cobj.getNodeId()); } - if(cobj instanceof CComplexObject) { - CComplexObject ccobj = (CComplexObject) cobj; + if (cobj instanceof CComplexObject) { + CComplexObject ccobj = (CComplexObject) cobj; List cattrList = ccobj.getAttributes(); - if(cattrList == null) { + if (cattrList == null) { return; } - for(CAttribute cattr : cattrList) { + for (CAttribute cattr : cattrList) { List children = cattr.getChildren(); - if(children == null) { + if (children == null) { continue; } - for(CObject child : children) { + for (CObject child : children) { fetchATCodes(child, codes); } } - } else if(cobj instanceof CDvOrdinal) { + } else if (cobj instanceof CDvOrdinal) { CDvOrdinal cord = (CDvOrdinal) cobj; List list = cord.getList(); - if(list != null) { - for(Ordinal ord : list) { + if (list != null) { + for (Ordinal ord : list) { CodePhrase code = ord.getSymbol(); - if("local".equalsIgnoreCase( + if ("local".equalsIgnoreCase( code.getTerminologyId().name())) { codes.add(code.getCodeString()); - } + } } } - } else if(cobj instanceof CCodePhrase) { + } else if (cobj instanceof CCodePhrase) { CCodePhrase ccod = (CCodePhrase) cobj; List list = ccod.getCodeList(); - if("local".equalsIgnoreCase(ccod.getTerminologyId().name()) + if ("local".equalsIgnoreCase(ccod.getTerminologyId().name()) && list != null) { - for(String code : list) { - if(code.startsWith("at")) { + for (String code : list) { + if (code.startsWith("at")) { codes.add(code); } } @@ -1433,52 +1457,54 @@ void fetchATCodes(CObject cobj, Set codes) { /** * 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); + 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; + if (cobj instanceof CComplexObject) { + CComplexObject ccobj = (CComplexObject) cobj; List cattrList = ccobj.getAttributes(); - if(cattrList == null) { + if (cattrList == null) { return; } - for(CAttribute cattr : cattrList) { + for (CAttribute cattr : cattrList) { List children = cattr.getChildren(); - if(children == null) { + if (children == null) { continue; } - for(CObject child : children) { + for (CObject child : children) { fetchACCodes(child, codes); } } - } else if(cobj instanceof CCodePhrase) { + } else if (cobj instanceof CCodePhrase) { CCodePhrase ccod = (CCodePhrase) cobj; List list = ccod.getCodeList(); - if(list != null) { - for(String code : list) { - if(code.startsWith("ac")) { + if (list != null) { + for (String code : list) { + if (code.startsWith("ac")) { codes.add(code); } } - } - } else if(cobj instanceof ConstraintRef) { + } + } else if (cobj instanceof ConstraintRef) { ConstraintRef ref = (ConstraintRef) cobj; - if(ref.getReference().startsWith("ac")) { + if (ref.getReference().startsWith("ac")) { codes.add(ref.getReference()); } } } - /** Constructs a formal String for representing this Interval + /** + * Constructs a formal String for representing this Interval + * * @param interval * @return */ @@ -1494,14 +1520,14 @@ protected String getIntervalFormalString(Integer lower, Integer upper, boolean i lower = Integer.valueOf(0); } - String formal= ""+lower.intValue() +".."; + String formal = "" + lower.intValue() + ".."; if (isUpperUnbounded) { formal += "*"; } else { formal += upper.intValue(); } - return formal; + return formal; } 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 index e9521202..7757c20c 100755 --- a/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java @@ -319,6 +319,7 @@ public Class retrieveRMType(String rmClassName) { * * @param rmClassName * @return + * @throws RMObjectBuildingException */ public Map retrieveRMAttributes(String rmClassName) { Class rmClass = retrieveRMType(rmClassName); @@ -329,11 +330,10 @@ public Map retrieveRMAttributes(String rmClassName) { Map map = attributeType(rmClass); Map ret = new HashMap(); - for(Map.Entry entry : map.entrySet()) { - String name = entry.getKey(); - ret.put(toUnderscoreSeparated(name), entry.getValue()); + for(String name : map.keySet()) { + ret.put(toUnderscoreSeparated(name), map.get(name)); - log.debug("rmattribute: " +name +": "+ entry.getValue()); + log.debug("rmattribute: " +name +": "+ map.get(name)); } return ret; } @@ -344,6 +344,7 @@ public Map retrieveRMAttributes(String rmClassName) { * * @param rmClassName * @return + * @throws RMObjectBuildingException */ public Set retrieveRMAttributeNames(String rmClassName) { Class rmClass = retrieveRMType(rmClassName); @@ -411,8 +412,8 @@ public String findMatchingRMClass(Map valueMap) { // replace underscore separated names with camel case Map filteredMap = new HashMap(); - for (Map.Entry entry : valueMap.entrySet()) { - filteredMap.put(toCamelCase(entry.getKey()), entry.getValue()); + for (String name : valueMap.keySet()) { + filteredMap.put(toCamelCase(name), valueMap.get(name)); } Constructor constructor = fullConstructor(rmClass); @@ -489,6 +490,28 @@ 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; + } + /** 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, 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 old mode 100755 new mode 100644 index 7d6a1f8e..e7aa9dfb --- a/archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java @@ -209,7 +209,9 @@ private void checkSpecialisedAttribute(CAttribute cattr, Archetype archetype, if (parentNodeInParentArchetype == null) { log.debug("PARENT NODE IN PARENT ARCHETYPE IS NULL"); - } else if (parentNodeInParentArchetype instanceof CComplexObject) { + } + + 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? @@ -606,11 +608,10 @@ private void checkSpecialisedRMTypeCompatiblityOfValueChildren(CAttribute cattr, if (!assignable) { log.debug("VSONCT error: at "+child.path()); - StringBuffer buf = new StringBuffer(); + String parentRefTypes = ""; for (Entry parentToRMTypeWithoutGenerics: parentObjectsToRMTypesWithoutGenerics.entrySet()) { - buf.append(parentToRMTypeWithoutGenerics.getValue().getSimpleName() +", "); + parentRefTypes += parentToRMTypeWithoutGenerics.getValue().getSimpleName() +", "; } - String parentRefTypes = buf.toString(); parentRefTypes = parentRefTypes.substring(0,parentRefTypes.length()-2); if (parentObjectsToRMTypesWithoutGenerics.size() ==1) { @@ -673,7 +674,6 @@ private String getExpectedPathInParentArchetype(String path, int parentArchetype 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))); - StringBuffer buffer = new StringBuffer(expectedPath); for (String pathPart : pathParts) { String pathEnd = ""; @@ -691,12 +691,11 @@ private String getExpectedPathInParentArchetype(String path, int parentArchetype 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 +" "+ buffer.toString()); + log.debug("Path ends with at0: "+ pathPart +" "+expectedPath); return null; } - buffer.append(pathPart + pathEnd+sep); + expectedPath += pathPart + pathEnd+sep; } - expectedPath = buffer.toString(); if (expectedPath.length() >1 && expectedPath.endsWith(sep)) { expectedPath = expectedPath.substring(0,expectedPath.length()-1); // get rid of tailing separator } 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 index fd9b59ea..f43de6c8 100644 --- a/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeTermValidityTest.java +++ b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeTermValidityTest.java @@ -61,16 +61,6 @@ public void testCheckTermWithDoubleEntryInOntology() throws Exception { } } - public void testCheckDoubleLanguage_Description() throws Exception { - archetype = loadArchetype("adl-test-ENTRY.term_definition.v5"); - validator.checkDescription(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()); - } - } - public void testCheckDoubleLanguage_Ontology() throws Exception { archetype = loadArchetype("adl-test-ENTRY.term_definition.v6"); validator.checkOntologyTranslation(archetype, errors); 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 8ca2b4fe..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 @@ -29,7 +29,7 @@ * @version 1.0 * */ -public final class SimpleMeasurementService implements MeasurementService { +public class SimpleMeasurementService implements MeasurementService { /** * From 9be8502dd5cf0e64b566f16411f63d85b9cc2e93 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Wed, 7 Jun 2017 11:15:58 +0200 Subject: [PATCH 183/213] Fixing group id --- adl-parser/pom.xml | 14 +++++++------- adl-serializer/pom.xml | 14 +++++++------- archetype-validator/pom.xml | 16 ++++++++-------- dadl-binding/pom.xml | 18 +++++++++--------- dadl-parser/pom.xml | 4 ++-- measure-serv/pom.xml | 2 +- mini-termserv/pom.xml | 4 ++-- oet-parser/pom.xml | 16 ++++++++-------- openehr-aom/pom.xml | 6 +++--- openehr-ap/pom.xml | 10 +++++----- openehr-rm-core/pom.xml | 4 ++-- openehr-rm-domain/pom.xml | 6 +++--- pom.xml | 2 +- rm-builder/pom.xml | 10 +++++----- rm-skeleton/pom.xml | 24 ++++++++++++------------ xml-binding/pom.xml | 14 +++++++------- xml-serializer/pom.xml | 10 +++++----- 17 files changed, 87 insertions(+), 87 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 9d8c5248..3f835b6a 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - se.cambio.cds + org.openehr ref_impl_java 0-SNAPSHOT @@ -91,32 +91,32 @@ - se.cambio.cds + org.openehr openehr-rm-core ${project.version} - se.cambio.cds + org.openehr openehr-rm-domain ${project.version} - se.cambio.cds + org.openehr openehr-aom ${project.version} - se.cambio.cds + org.openehr openehr-ap ${project.version} - se.cambio.cds + org.openehr measure-serv ${project.version} - se.cambio.cds + org.openehr mini-termserv ${project.version} diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index 6fbf41c8..b3a2806a 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -1,7 +1,7 @@ 4.0.0 - se.cambio.cds + org.openehr ref_impl_java 0-SNAPSHOT @@ -27,32 +27,32 @@ - se.cambio.cds + org.openehr openehr-rm-core ${project.version} - se.cambio.cds + org.openehr openehr-rm-domain ${project.version} - se.cambio.cds + org.openehr openehr-aom ${project.version} - se.cambio.cds + org.openehr openehr-ap ${project.version} - se.cambio.cds + org.openehr mini-termserv ${project.version} - se.cambio.cds + org.openehr adl-parser ${project.version} test diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 18154d4e..2ba9a0fe 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - se.cambio.cds + org.openehr ref_impl_java 0-SNAPSHOT @@ -43,37 +43,37 @@ 1.2.13 - se.cambio.cds + org.openehr openehr-rm-core ${project.version} - se.cambio.cds + org.openehr openehr-rm-domain ${project.version} - se.cambio.cds + org.openehr openehr-aom ${project.version} - se.cambio.cds + org.openehr openehr-ap ${project.version} - se.cambio.cds + org.openehr mini-termserv ${project.version} - se.cambio.cds + org.openehr measure-serv ${project.version} - se.cambio.cds + org.openehr adl-parser ${project.version} test diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 57963f13..17f05b73 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - se.cambio.cds + org.openehr ref_impl_java 0-SNAPSHOT @@ -19,48 +19,48 @@ - se.cambio.cds + org.openehr openehr-rm-core ${project.version} - se.cambio.cds + org.openehr openehr-aom ${project.version} - se.cambio.cds + org.openehr adl-parser ${project.version} - se.cambio.cds + org.openehr openehr-rm-domain ${project.version} - se.cambio.cds + org.openehr mini-termserv ${project.version} - se.cambio.cds + org.openehr measure-serv ${project.version} - se.cambio.cds + org.openehr rm-builder ${project.version} - se.cambio.cds + org.openehr dadl-parser ${project.version} diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index e302e708..9f927b19 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - se.cambio.cds + org.openehr ref_impl_java 0-SNAPSHOT @@ -66,7 +66,7 @@ - se.cambio.cds + org.openehr openehr-rm-core ${project.version} diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index 245bff49..ae93cc2e 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - se.cambio.cds + org.openehr ref_impl_java 0-SNAPSHOT diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index b2e45f8c..2c8c4cb8 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - se.cambio.cds + org.openehr ref_impl_java 0-SNAPSHOT @@ -21,7 +21,7 @@ - se.cambio.cds + org.openehr openehr-rm-core ${project.version} diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 54b6526a..7b81504e 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - se.cambio.cds + org.openehr ref_impl_java 0-SNAPSHOT @@ -49,22 +49,22 @@ - se.cambio.cds + org.openehr openehr-rm-core ${project.version} - se.cambio.cds + org.openehr openehr-rm-domain ${project.version} - se.cambio.cds + org.openehr openehr-aom ${project.version} - se.cambio.cds + org.openehr adl-parser ${project.version} @@ -79,12 +79,12 @@ 1.0 - se.cambio.cds + org.openehr measure-serv ${project.version} - se.cambio.cds + org.openehr mini-termserv ${project.version} @@ -101,7 +101,7 @@ test - se.cambio.cds + org.openehr adl-serializer ${project.version} diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index a9a13b09..f0623159 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - se.cambio.cds + org.openehr ref_impl_java 0-SNAPSHOT @@ -22,12 +22,12 @@ - se.cambio.cds + org.openehr openehr-rm-core ${project.version} - se.cambio.cds + org.openehr openehr-rm-domain ${project.version} diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 5a99d9c0..4bc87ce3 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - se.cambio.cds + org.openehr ref_impl_java 0-SNAPSHOT @@ -21,22 +21,22 @@ - se.cambio.cds + org.openehr openehr-rm-core ${project.version} - se.cambio.cds + org.openehr openehr-rm-domain ${project.version} - se.cambio.cds + org.openehr openehr-aom ${project.version} - se.cambio.cds + org.openehr measure-serv ${project.version} diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 77d79b0f..1a25225c 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - se.cambio.cds + org.openehr ref_impl_java 0-SNAPSHOT @@ -37,7 +37,7 @@ test - se.cambio.cds + org.openehr measure-serv ${project.version} diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 7a20892b..23429cba 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - se.cambio.cds + org.openehr ref_impl_java 0-SNAPSHOT @@ -21,12 +21,12 @@ - se.cambio.cds + org.openehr openehr-rm-core ${project.version} - se.cambio.cds + org.openehr mini-termserv ${project.version} test diff --git a/pom.xml b/pom.xml index b66d6dce..b6d10cd9 100755 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - openehr + org.openehr ref_impl_java pom 0-SNAPSHOT diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 454ba93e..09e7d89d 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - se.cambio.cds + org.openehr ref_impl_java 0-SNAPSHOT @@ -21,22 +21,22 @@ - se.cambio.cds + org.openehr openehr-rm-core ${project.version} - se.cambio.cds + org.openehr openehr-rm-domain ${project.version} - se.cambio.cds + org.openehr mini-termserv ${project.version} - se.cambio.cds + org.openehr measure-serv ${project.version} diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 6d556495..90794487 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - se.cambio.cds + org.openehr ref_impl_java 0-SNAPSHOT @@ -12,52 +12,52 @@ - se.cambio.cds + org.openehr openehr-rm-core ${project.version} - se.cambio.cds + org.openehr openehr-rm-domain ${project.version} - se.cambio.cds + org.openehr openehr-aom ${project.version} - se.cambio.cds + org.openehr adl-parser ${project.version} - se.cambio.cds + org.openehr dadl-parser ${project.version} - se.cambio.cds + org.openehr oet-parser ${project.version} - se.cambio.cds + org.openehr measure-serv ${project.version} - se.cambio.cds + org.openehr mini-termserv ${project.version} - se.cambio.cds + org.openehr dadl-binding ${project.version} - se.cambio.cds + org.openehr xml-binding ${project.version} @@ -74,7 +74,7 @@ test - se.cambio.cds + org.openehr adl-serializer ${project.version} test diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index 1541883f..dcbdd2d8 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - se.cambio.cds + org.openehr ref_impl_java 0-SNAPSHOT @@ -49,12 +49,12 @@ - se.cambio.cds + org.openehr openehr-rm-core ${project.version} - se.cambio.cds + org.openehr openehr-rm-domain ${project.version} @@ -64,17 +64,17 @@ 2.3.0 - se.cambio.cds + org.openehr measure-serv ${project.version} - se.cambio.cds + org.openehr mini-termserv ${project.version} - se.cambio.cds + org.openehr ${project.version} rm-builder @@ -120,7 +120,7 @@ test - se.cambio.cds + org.openehr oet-parser ${project.version} diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index be3a7375..5e076672 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -1,7 +1,7 @@ 4.0.0 - se.cambio.cds + org.openehr ref_impl_java 0-SNAPSHOT @@ -20,22 +20,22 @@ - se.cambio.cds + org.openehr openehr-rm-core ${project.version} - se.cambio.cds + org.openehr openehr-rm-domain ${project.version} - se.cambio.cds + org.openehr openehr-aom ${project.version} - se.cambio.cds + org.openehr openehr-ap ${project.version} From a89d16233e7c2a8b9376de8f9f3467c3c7805169 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Wed, 7 Jun 2017 11:19:46 +0200 Subject: [PATCH 184/213] Adding gitlab ci script --- .gitlab-ci.yml | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .gitlab-ci.yml 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 From 8dacdcb6db03546ad3c729b8a822d10127c69df0 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Wed, 16 Aug 2017 15:33:49 +0200 Subject: [PATCH 185/213] Adding distribution management --- pom.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pom.xml b/pom.xml index b6d10cd9..238b5c13 100755 --- a/pom.xml +++ b/pom.xml @@ -55,4 +55,18 @@ rm-skeleton archetype-validator + + + + 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 + + From 4009708f1a9e2c4766b5882c9f2fd426718cacc2 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Thu, 24 Aug 2017 13:50:33 +0200 Subject: [PATCH 186/213] Fixing README --- INSTALL.txt | 10 ---------- README.md | 18 ++++++++++++++++++ README.txt | 5 ----- 3 files changed, 18 insertions(+), 15 deletions(-) delete mode 100644 INSTALL.txt create mode 100644 README.md delete mode 100644 README.txt diff --git a/INSTALL.txt b/INSTALL.txt deleted file mode 100644 index 4589e0b7..00000000 --- a/INSTALL.txt +++ /dev/null @@ -1,10 +0,0 @@ -REQUIREMENTS: - -Java 1.6 or higher -Maven 3.0.4 or higher - -INSTALATION INSTRUCTIONS: - -INSTALLATION: - -java-libs/mvn clean install \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 00000000..9308346c --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# java-libs +Java openEHR Implementation project + +## Getting Started + +### Requirements + +* Java 8 or higher +* Maven 3.0.4 or higher + +### Installation + +To build the whole project, 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 100644 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 From 199c5413c3a78d28050b2395150493d8cf58ed07 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Thu, 24 Aug 2017 13:52:59 +0200 Subject: [PATCH 187/213] Adding ADL version --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9308346c..bbfab457 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # java-libs -Java openEHR Implementation project +Java openEHR Implementation project (ADL 1.4) ## Getting Started From 65a6366cb8297b726d7f6b44eeb8b60ef0548828 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Thu, 24 Aug 2017 14:13:38 +0200 Subject: [PATCH 188/213] Fixing group id names --- adl-parser/pom.xml | 16 ++++++++-------- adl-serializer/pom.xml | 16 ++++++++-------- archetype-validator/pom.xml | 18 +++++++++--------- dadl-binding/pom.xml | 20 ++++++++++---------- dadl-parser/pom.xml | 6 +++--- measure-serv/pom.xml | 4 ++-- mini-termserv/pom.xml | 6 +++--- oet-parser/pom.xml | 18 +++++++++--------- openehr-aom/pom.xml | 8 ++++---- openehr-ap/pom.xml | 12 ++++++------ openehr-rm-core/pom.xml | 6 +++--- openehr-rm-domain/pom.xml | 8 ++++---- pom.xml | 4 ++-- rm-builder/pom.xml | 12 ++++++------ rm-skeleton/pom.xml | 26 +++++++++++++------------- xml-binding/pom.xml | 16 ++++++++-------- xml-serializer/pom.xml | 12 ++++++------ 17 files changed, 104 insertions(+), 104 deletions(-) diff --git a/adl-parser/pom.xml b/adl-parser/pom.xml index 3f835b6a..ebc5b0f7 100644 --- a/adl-parser/pom.xml +++ b/adl-parser/pom.xml @@ -2,8 +2,8 @@ 4.0.0 - org.openehr - ref_impl_java + org.openehr.java-libs + java-libs 0-SNAPSHOT adl-parser @@ -91,32 +91,32 @@ - org.openehr + org.openehr.java-libs openehr-rm-core ${project.version} - org.openehr + org.openehr.java-libs openehr-rm-domain ${project.version} - org.openehr + org.openehr.java-libs openehr-aom ${project.version} - org.openehr + org.openehr.java-libs openehr-ap ${project.version} - org.openehr + org.openehr.java-libs measure-serv ${project.version} - org.openehr + org.openehr.java-libs mini-termserv ${project.version} diff --git a/adl-serializer/pom.xml b/adl-serializer/pom.xml index b3a2806a..e6fc1ab7 100755 --- a/adl-serializer/pom.xml +++ b/adl-serializer/pom.xml @@ -1,8 +1,8 @@ 4.0.0 - org.openehr - ref_impl_java + org.openehr.java-libs + java-libs 0-SNAPSHOT adl-serializer @@ -27,32 +27,32 @@ - org.openehr + org.openehr.java-libs openehr-rm-core ${project.version} - org.openehr + org.openehr.java-libs openehr-rm-domain ${project.version} - org.openehr + org.openehr.java-libs openehr-aom ${project.version} - org.openehr + org.openehr.java-libs openehr-ap ${project.version} - org.openehr + org.openehr.java-libs mini-termserv ${project.version} - org.openehr + org.openehr.java-libs adl-parser ${project.version} test diff --git a/archetype-validator/pom.xml b/archetype-validator/pom.xml index 2ba9a0fe..5114e79c 100755 --- a/archetype-validator/pom.xml +++ b/archetype-validator/pom.xml @@ -2,8 +2,8 @@ 4.0.0 - org.openehr - ref_impl_java + org.openehr.java-libs + java-libs 0-SNAPSHOT archetype-validator @@ -43,37 +43,37 @@ 1.2.13 - org.openehr + org.openehr.java-libs openehr-rm-core ${project.version} - org.openehr + org.openehr.java-libs openehr-rm-domain ${project.version} - org.openehr + org.openehr.java-libs openehr-aom ${project.version} - org.openehr + org.openehr.java-libs openehr-ap ${project.version} - org.openehr + org.openehr.java-libs mini-termserv ${project.version} - org.openehr + org.openehr.java-libs measure-serv ${project.version} - org.openehr + org.openehr.java-libs adl-parser ${project.version} test diff --git a/dadl-binding/pom.xml b/dadl-binding/pom.xml index 17f05b73..37822cb9 100755 --- a/dadl-binding/pom.xml +++ b/dadl-binding/pom.xml @@ -2,8 +2,8 @@ 4.0.0 - org.openehr - ref_impl_java + org.openehr.java-libs + java-libs 0-SNAPSHOT dadl-binding @@ -19,48 +19,48 @@ - org.openehr + org.openehr.java-libs openehr-rm-core ${project.version} - org.openehr + org.openehr.java-libs openehr-aom ${project.version} - org.openehr + org.openehr.java-libs adl-parser ${project.version} - org.openehr + org.openehr.java-libs openehr-rm-domain ${project.version} - org.openehr + org.openehr.java-libs mini-termserv ${project.version} - org.openehr + org.openehr.java-libs measure-serv ${project.version} - org.openehr + org.openehr.java-libs rm-builder ${project.version} - org.openehr + org.openehr.java-libs dadl-parser ${project.version} diff --git a/dadl-parser/pom.xml b/dadl-parser/pom.xml index 9f927b19..b49fdf4d 100755 --- a/dadl-parser/pom.xml +++ b/dadl-parser/pom.xml @@ -2,8 +2,8 @@ 4.0.0 - org.openehr - ref_impl_java + org.openehr.java-libs + java-libs 0-SNAPSHOT dadl-parser @@ -66,7 +66,7 @@ - org.openehr + org.openehr.java-libs openehr-rm-core ${project.version} diff --git a/measure-serv/pom.xml b/measure-serv/pom.xml index ae93cc2e..79573c53 100755 --- a/measure-serv/pom.xml +++ b/measure-serv/pom.xml @@ -2,8 +2,8 @@ 4.0.0 - org.openehr - ref_impl_java + org.openehr.java-libs + java-libs 0-SNAPSHOT measure-serv diff --git a/mini-termserv/pom.xml b/mini-termserv/pom.xml index 2c8c4cb8..b226f4cb 100755 --- a/mini-termserv/pom.xml +++ b/mini-termserv/pom.xml @@ -2,8 +2,8 @@ 4.0.0 - org.openehr - ref_impl_java + org.openehr.java-libs + java-libs 0-SNAPSHOT mini-termserv @@ -21,7 +21,7 @@ - org.openehr + org.openehr.java-libs openehr-rm-core ${project.version} diff --git a/oet-parser/pom.xml b/oet-parser/pom.xml index 7b81504e..cd03ff31 100755 --- a/oet-parser/pom.xml +++ b/oet-parser/pom.xml @@ -2,8 +2,8 @@ 4.0.0 - org.openehr - ref_impl_java + org.openehr.java-libs + java-libs 0-SNAPSHOT oet-parser @@ -49,22 +49,22 @@ - org.openehr + org.openehr.java-libs openehr-rm-core ${project.version} - org.openehr + org.openehr.java-libs openehr-rm-domain ${project.version} - org.openehr + org.openehr.java-libs openehr-aom ${project.version} - org.openehr + org.openehr.java-libs adl-parser ${project.version} @@ -79,12 +79,12 @@ 1.0 - org.openehr + org.openehr.java-libs measure-serv ${project.version} - org.openehr + org.openehr.java-libs mini-termserv ${project.version} @@ -101,7 +101,7 @@ test - org.openehr + org.openehr.java-libs adl-serializer ${project.version} diff --git a/openehr-aom/pom.xml b/openehr-aom/pom.xml index f0623159..f51b58bc 100755 --- a/openehr-aom/pom.xml +++ b/openehr-aom/pom.xml @@ -2,8 +2,8 @@ 4.0.0 - org.openehr - ref_impl_java + org.openehr.java-libs + java-libs 0-SNAPSHOT openehr-aom @@ -22,12 +22,12 @@ - org.openehr + org.openehr.java-libs openehr-rm-core ${project.version} - org.openehr + org.openehr.java-libs openehr-rm-domain ${project.version} diff --git a/openehr-ap/pom.xml b/openehr-ap/pom.xml index 4bc87ce3..b0a0dd95 100755 --- a/openehr-ap/pom.xml +++ b/openehr-ap/pom.xml @@ -2,8 +2,8 @@ 4.0.0 - org.openehr - ref_impl_java + org.openehr.java-libs + java-libs 0-SNAPSHOT openehr-ap @@ -21,22 +21,22 @@ - org.openehr + org.openehr.java-libs openehr-rm-core ${project.version} - org.openehr + org.openehr.java-libs openehr-rm-domain ${project.version} - org.openehr + org.openehr.java-libs openehr-aom ${project.version} - org.openehr + org.openehr.java-libs measure-serv ${project.version} diff --git a/openehr-rm-core/pom.xml b/openehr-rm-core/pom.xml index 1a25225c..adf8bb3b 100755 --- a/openehr-rm-core/pom.xml +++ b/openehr-rm-core/pom.xml @@ -2,8 +2,8 @@ 4.0.0 - org.openehr - ref_impl_java + org.openehr.java-libs + java-libs 0-SNAPSHOT openehr-rm-core @@ -37,7 +37,7 @@ test - org.openehr + org.openehr.java-libs measure-serv ${project.version} diff --git a/openehr-rm-domain/pom.xml b/openehr-rm-domain/pom.xml index 23429cba..7a88620e 100755 --- a/openehr-rm-domain/pom.xml +++ b/openehr-rm-domain/pom.xml @@ -2,8 +2,8 @@ 4.0.0 - org.openehr - ref_impl_java + org.openehr.java-libs + java-libs 0-SNAPSHOT openehr-rm-domain @@ -21,12 +21,12 @@ - org.openehr + org.openehr.java-libs openehr-rm-core ${project.version} - org.openehr + org.openehr.java-libs mini-termserv ${project.version} test diff --git a/pom.xml b/pom.xml index 238b5c13..043b639e 100755 --- a/pom.xml +++ b/pom.xml @@ -2,8 +2,8 @@ 4.0.0 - org.openehr - ref_impl_java + org.openehr.java-libs + java-libs pom 0-SNAPSHOT The openEHR Reference Java Implementation diff --git a/rm-builder/pom.xml b/rm-builder/pom.xml index 09e7d89d..033fa6f6 100755 --- a/rm-builder/pom.xml +++ b/rm-builder/pom.xml @@ -2,8 +2,8 @@ 4.0.0 - org.openehr - ref_impl_java + org.openehr.java-libs + java-libs 0-SNAPSHOT rm-builder @@ -21,22 +21,22 @@ - org.openehr + org.openehr.java-libs openehr-rm-core ${project.version} - org.openehr + org.openehr.java-libs openehr-rm-domain ${project.version} - org.openehr + org.openehr.java-libs mini-termserv ${project.version} - org.openehr + org.openehr.java-libs measure-serv ${project.version} diff --git a/rm-skeleton/pom.xml b/rm-skeleton/pom.xml index 90794487..cbf0d405 100755 --- a/rm-skeleton/pom.xml +++ b/rm-skeleton/pom.xml @@ -2,8 +2,8 @@ 4.0.0 - org.openehr - ref_impl_java + org.openehr.java-libs + java-libs 0-SNAPSHOT rm-skeleton @@ -12,52 +12,52 @@ - org.openehr + org.openehr.java-libs openehr-rm-core ${project.version} - org.openehr + org.openehr.java-libs openehr-rm-domain ${project.version} - org.openehr + org.openehr.java-libs openehr-aom ${project.version} - org.openehr + org.openehr.java-libs adl-parser ${project.version} - org.openehr + org.openehr.java-libs dadl-parser ${project.version} - org.openehr + org.openehr.java-libs oet-parser ${project.version} - org.openehr + org.openehr.java-libs measure-serv ${project.version} - org.openehr + org.openehr.java-libs mini-termserv ${project.version} - org.openehr + org.openehr.java-libs dadl-binding ${project.version} - org.openehr + org.openehr.java-libs xml-binding ${project.version} @@ -74,7 +74,7 @@ test - org.openehr + org.openehr.java-libs adl-serializer ${project.version} test diff --git a/xml-binding/pom.xml b/xml-binding/pom.xml index dcbdd2d8..c7712109 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -2,8 +2,8 @@ 4.0.0 - org.openehr - ref_impl_java + org.openehr.java-libs + java-libs 0-SNAPSHOT xml-binding @@ -49,12 +49,12 @@ - org.openehr + org.openehr.java-libs openehr-rm-core ${project.version} - org.openehr + org.openehr.java-libs openehr-rm-domain ${project.version} @@ -64,17 +64,17 @@ 2.3.0 - org.openehr + org.openehr.java-libs measure-serv ${project.version} - org.openehr + org.openehr.java-libs mini-termserv ${project.version} - org.openehr + org.openehr.java-libs ${project.version} rm-builder @@ -120,7 +120,7 @@ test - org.openehr + org.openehr.java-libs oet-parser ${project.version} diff --git a/xml-serializer/pom.xml b/xml-serializer/pom.xml index 5e076672..7de958c9 100755 --- a/xml-serializer/pom.xml +++ b/xml-serializer/pom.xml @@ -1,8 +1,8 @@ 4.0.0 - org.openehr - ref_impl_java + org.openehr.java-libs + java-libs 0-SNAPSHOT xml-serializer @@ -20,22 +20,22 @@ - org.openehr + org.openehr.java-libs openehr-rm-core ${project.version} - org.openehr + org.openehr.java-libs openehr-rm-domain ${project.version} - org.openehr + org.openehr.java-libs openehr-aom ${project.version} - org.openehr + org.openehr.java-libs openehr-ap ${project.version} From fa42db4dd7927e767fc3a900772f23f611a5de11 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Thu, 24 Aug 2017 16:10:39 +0200 Subject: [PATCH 189/213] Adding profile for maven central --- pom.xml | 50 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/pom.xml b/pom.xml index 043b639e..2586411c 100755 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ 1.8 1.8 - + @@ -55,18 +55,38 @@ rm-skeleton archetype-validator - - - - 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 - - + + + 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/ + + + + From 0c4a7b5bbb56b1072356acb49a0a667b54df3b8b Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Fri, 25 Aug 2017 11:14:31 +0200 Subject: [PATCH 190/213] Adding group name changes. Adding automatic signing and javadoc/sources generation --- pom.xml | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/pom.xml b/pom.xml index 2586411c..32adfd68 100755 --- a/pom.xml +++ b/pom.xml @@ -7,6 +7,8 @@ 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 @@ -35,8 +37,51 @@ 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 + + + + + false + + + + + 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 @@ -88,5 +133,31 @@ + + release-sign-artifacts + + + performRelease + true + + + + + + org.apache.maven.plugins + maven-gpg-plugin + + + sign-artifacts + verify + + sign + + + + + + + From 894e4eee7b677ad417ea46a971213fbe34180e50 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Fri, 25 Aug 2017 14:05:49 +0200 Subject: [PATCH 191/213] Adding maven central explanation to README --- README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bbfab457..aaf5696a 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,23 @@ Java openEHR Implementation project (ADL 1.4) * 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.70 + +``` + ### Installation -To build the whole project, clone it, and once inside the project's folder (by default _java-libs_), run: +To build the whole project, first clone it, and once inside the project's folder (by default _java-libs_), run: ```bash mvn clean install ``` From 21f02340e2079c02938a7bd88ae015ac08a73392 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Fri, 25 Aug 2017 14:10:37 +0200 Subject: [PATCH 192/213] Updating version of java-libs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aaf5696a..98352717 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ For example, if you need to use the adl-parser, add into your _pom.xml_: org.openehr.java-libs adl-parser - 1.0.70 + 1.0.71 ``` From a9f19a249b1e33cb4b9482e7e85fd7e0eb073330 Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Mon, 18 Dec 2017 15:48:19 +0100 Subject: [PATCH 193/213] Archetype Validator: Correct History/events cardinality validation which is 0..* as well --- .../openehr/am/validation/RMInspector.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) 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 index 7757c20c..bfece661 100755 --- a/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java @@ -114,7 +114,7 @@ public RMInspector() { // using FullConstructor annotation private Map loadTypeMap() throws ClassNotFoundException { Class[] classes = { - + // implied types Integer.class, String.class, @@ -526,33 +526,33 @@ Interval defaultCardinalityInterval(CMultipleAttribute cattr, CObject p 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); + 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); + log.debug("--> >=1"); + return new Interval(1,null); } - /* } else if (cattr.getRmAttributeName().equals("activities")) { // This seems to be incorrect + /* } else if (cattr.getRmAttributeName().equals("activities")) { // This seems to be incorrect if (parentObj.getRmTypeName().equalsIgnoreCase("INSTRUCTION")) { - log.debug("--> >=1"); - return new Interval(1,null); + log.debug("--> >=1"); + return new Interval(1,null); } - */ } else if (cattr.getRmAttributeName().equals("events")) { + *//* } 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); + log.debug("--> >=1"); + return new Interval(1,null); } - } else if (cattr.getRmAttributeName().equals("credentials")) { + */ } else if (cattr.getRmAttributeName().equals("credentials")) { if (parentObj.getRmTypeName().equalsIgnoreCase("CAPABILITY")) { - log.debug("--> ==1"); - return new Interval(1,1); + log.debug("--> ==1"); + return new Interval(1,1); } } - log.debug("--> >=0"); + log.debug("--> >=0"); return new Interval(0,null); // not constrained - + } /* @@ -567,7 +567,7 @@ Interval defaultCardinalityInterval(CMultipleAttribute cattr, CObject p "ObjectVersionID" }; - + /* logger */ private static final Logger log = Logger.getLogger(RMInspector.class); From 1423cc89928e1ec14552f6117c3d4ea655b8d156 Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Thu, 11 Jan 2018 15:42:48 +0100 Subject: [PATCH 194/213] Fix for bug introduced in commit 88a9200 - otherwise XMLSerializer never serialises the text or description of at-codes (and other string maps) --- .../java/org/openehr/am/serialize/XMLSerializer.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) 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 f5b10a4a..d4cdb35e 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 @@ -8,7 +8,6 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; import org.jdom.Document; import org.jdom.Element; @@ -166,7 +165,7 @@ protected void printHeader(Archetype archetype, Element out) { printString("value", archetype.getArchetypeId().toString(), archetypeId); printString("adl_version", archetype.getAdlVersion(), out); - + printString("concept", archetype.getConcept(), out); @@ -268,7 +267,7 @@ private void printStringMap(String label, Map map, Element out) out.getChildren().add(elm); elm.setAttribute("id", entry.getKey()); if (entry.getValue() != null) { - elm.setText(map.get(entry.getValue())); + elm.setText(entry.getValue()); } } } @@ -1101,14 +1100,14 @@ private String getUpperCaseWithUnderscoreFromCamelCase(String str) { char c = str.charAt( i ); if(! Character.isUpperCase(prevChar) && !(prevChar=='<') && // without this DV_INTERVAL --> DV_INTERVAL<_DV_QUANTITY> - !(prevChar=='_') && + !(prevChar=='_') && Character.isLetter(c) && Character.isUpperCase(c)) { result.append("_"); result.append( Character.toUpperCase( c ) ); } - else { + else { result.append( Character.toUpperCase( c ) ); } prevChar = c; @@ -1131,7 +1130,7 @@ private String getUpperCaseWithUnderscoreFromCamelCase(String str) { public static final Namespace xsdNamespace = Namespace.getNamespace("xsd", "http://www.w3.org/2001/XMLSchema"); - /* fields */ + /* fields */ private Charset encoding; private XMLOutputter outputter; From 40d868c4dfcc05cffa7ac552be3fe81509c08c3d Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Fri, 2 Nov 2018 15:09:28 +0100 Subject: [PATCH 195/213] Archetype Validator: Support various regexes for flexible version numbers in SLOT constraints, instead of a fixed number only. --- .../am/validation/ArchetypeValidator.java | 122 +++++++++++------- .../src/main/resources/validations.properties | 2 +- .../main/resources/validations_de.properties | 2 +- .../main/resources/validations_ru.properties | 2 +- 4 files changed, 75 insertions(+), 53 deletions(-) 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 index 722beb52..3a150e3b 100755 --- a/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java @@ -23,6 +23,7 @@ import java.util.Map.Entry; import java.util.Set; import java.util.StringTokenizer; +import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; @@ -202,7 +203,7 @@ public void checkDescription(Archetype archetype, List errors) } public void checkArchetypeDefinitionCodeValidity(Archetype archetype, - List errors) { + List errors) { String concept = archetype.getConcept(); String rootNodeId = archetype.getDefinition().getNodeId(); if (!concept.equals(rootNodeId)) { @@ -232,7 +233,7 @@ public void checkArchetypeUnitsValidity(CDvQuantity cDvQuantity, List errors) { + List errors) { String concept = archetype.getConcept(); List specialization = archetype.getArchetypeId().specialisation(); StringTokenizer tokens = new StringTokenizer(concept, "."); @@ -253,7 +254,7 @@ public void checkConceptSpecializationDepth(Archetype archetype, * @param errors */ public void checkSpecializationParentIdentifierValidity(Archetype archetype, - List errors) { + List errors) { if (archetype.getParentArchetypeId() == null) { return; // no specialise clause at all @@ -307,7 +308,7 @@ public void checkOntologyCodeSpecialisationLevelValidity( } private void checkOntologyDefinitions(List defList, - List errors, int level) { + List errors, int level) { ValidationError error = null; for (OntologyDefinitions defs : defList) { @@ -337,7 +338,7 @@ private boolean hasGreaterSpecialisationLevel(String code, int level) { * @throws RMInspectionException */ public void checkObjectConstraints(Archetype archetype, - List errors) throws RMInspectionException { + List errors) throws RMInspectionException { validateCComplexObject(archetype.getDefinition(), archetype, errors); } @@ -365,9 +366,9 @@ private boolean isCommonFunctionalProperty(String rmAttrName, String parentRMTyp } private void validateCAttribute(CAttribute cattr, - Map rmAttrs, CComplexObject parent, - Archetype archetype, List errors) - throws RMInspectionException { + Map rmAttrs, CComplexObject parent, + Archetype archetype, List errors) + throws RMInspectionException { String rmAttrName = cattr.getRmAttributeName(); @@ -448,7 +449,7 @@ private void validateCAttribute(CAttribute cattr, 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) + // 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); @@ -500,7 +501,7 @@ private void validateCAttribute(CAttribute cattr, log.debug("5- rmAttrType: " + rmAttrType + " with name " + rmAttrName + " IS assignable from " + childRMType); - // check csingle attribute child object occurrences + // check csingle attribute child object occurrences Interval occu = cobj.getOccurrences(); if (occu != null && occu.isUpperIncluded() && occu.getUpper() > 1) { @@ -512,7 +513,7 @@ private void validateCAttribute(CAttribute cattr, if (cobj == cobj2) { continue; } - // check child uniqueness + // check child uniqueness if (cobj2.getRmTypeName().equals(cobj.getRmTypeName()) && cobj.getNodeId() == null) { error = new ValidationError(ErrorType.VACSU, null, @@ -521,7 +522,7 @@ private void validateCAttribute(CAttribute cattr, errors.add(error); } } - // check child identifier + // check child identifier if (cobj2.getNodeId() != null && cobj2.getNodeId().equals(cobj.getNodeId())) { error = new ValidationError(ErrorType.VACSI, null, @@ -529,9 +530,9 @@ private void validateCAttribute(CAttribute cattr, if (!errors.contains(error)) { errors.add(error); } - } - /*VASCIT just seems to be a special case of VACSU?? - * else if (cobj2.getNodeId() == null + } + /*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, @@ -541,15 +542,15 @@ private void validateCAttribute(CAttribute cattr, } } */ } - } else { // CMultipleAttribute + } 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)) { + || cardinalityInterval.getUpper().compareTo( + cobj.getOccurrences().getUpper()) < 0)) { error = new ValidationError(ErrorType.VACMC, "CONTAIN", rmInspector.toUnderscoreSeparated(cobj.getClass().getSimpleName()).toUpperCase(), cobj.getRmTypeName(), @@ -566,7 +567,7 @@ private void validateCAttribute(CAttribute cattr, // 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. + // 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()) { @@ -588,7 +589,7 @@ private void validateCAttribute(CAttribute cattr, errors.add(error); } } else { - // check duplicated child identifier + // check duplicated child identifier for (CObject cobj2 : cattr.getChildren()) { if (cobj == cobj2) { continue; @@ -658,7 +659,7 @@ private void checkCardinalityConformsToChildrenOccurrences( // 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 @@ -672,7 +673,7 @@ private void checkCardinalityConformsToChildrenOccurrences( // 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); @@ -703,7 +704,7 @@ private void checkCardinalityConformsToRMCardinality(CMultipleAttribute cattr, C 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 + //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 } @@ -735,7 +736,7 @@ private void checkCardinalityConformsToRMCardinality(CMultipleAttribute cattr, C * @param errors */ private void checkArchetypeSlot(ArchetypeSlot slot, Class rmAttrType, Archetype archetype, - List errors) { + List errors) { if (slot.getIncludes() != null) { for (Assertion include : slot.getIncludes()) { checkAssertionHasValidArchetypeIds(include, slot, errors); @@ -782,7 +783,7 @@ private void checkAssertionHasValidArchetypeIds(Assertion assertion, ArchetypeSl pattern = pattern.substring(pattern.indexOf("|") + 1); checkOneArchetypeId(slot, errors, oneId); } - // the rest of the pattern is the last archetype id, so test this one too. + // the rest of the pattern is the last archetype id, so test this one too. checkOneArchetypeId(slot, errors, pattern); } } @@ -803,20 +804,41 @@ private void checkOneArchetypeId(ArchetypeSlot slot, List error // check for the right number of dots in the id boolean containsCorrectNumberOfDots = (StringUtils.countMatches(oneId, ".") == 2); - // check that the id ends with .v[0..9]* + // check that the id ends with .v[0..9]+ boolean endsWithDotVNumber = true; // assume it is ok, until proven false if (oneId.lastIndexOf(".v") == -1) { endsWithDotVNumber = false; } else { String tail = oneId.substring(oneId.lastIndexOf(".v") + 2); log.debug("tail: " + tail); - if (tail.length() == 0 || !StringUtils.isNumeric(tail)) { - endsWithDotVNumber = false; + + // 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("[1-9][0-9]*") + )) { + + boolean matchedANumber = false; + for (int testNumber = 0; testNumber <= 1000; testNumber ++) { + if (Pattern.matches(tail, "" + testNumber)) { + matchedANumber = true; + break; + } + } + endsWithDotVNumber = matchedANumber; } } // check that the first part of the id (the qualified RM Entity) contains the right number of hyphens - boolean containsCorrectNumberOfHyphensInQualifiedRMEntity = true; // assume it is ok, until proven wrong + boolean containsCorrectNumberOfHyphensInQualifiedRMEntity = true; // assume it is ok, until proven wrong String qualifiedRMEntity = oneId.substring(0, oneId.indexOf(".")); if (StringUtils.countMatches(qualifiedRMEntity, "-") != 2) { containsCorrectNumberOfHyphensInQualifiedRMEntity = false; @@ -852,7 +874,7 @@ private void checkOneArchetypeId(ArchetypeSlot slot, List error * @param errors */ private void validateCDomainType(CDomainType cdtobj, Archetype archetype, - List errors) { + List errors) { if (cdtobj.hasAssumedValue()) { log.debug("validating assumed value: " + cdtobj.getAssumedValue()); @@ -878,11 +900,11 @@ private void validateCDomainType(CDomainType cdtobj, Archetype archetype, * Checks validity of openEHR codes in given ccodephrase */ private void validateCCodePhrase(CCodePhrase ccodephrase, - List errors) { + List errors) { if (ccodephrase.getCodeList() == null || !TerminologyService.OPENEHR.equalsIgnoreCase( - ccodephrase.getTerminologyId().toString())) { + ccodephrase.getTerminologyId().toString())) { return; } StringBuffer buf = new StringBuffer(); @@ -926,7 +948,7 @@ private void validateCPrimitiveObject(CPrimitiveObject cpobj, Archetype archetyp private void validateCComplexObject(CComplexObject ccobj, Archetype archetype, - List errors) throws RMInspectionException { + List errors) throws RMInspectionException { checkGenericTypeName(ccobj, errors); if (ccobj.getAttributes() == null) { @@ -1021,9 +1043,9 @@ protected String getGenericType(String rmTypeName) { * @param archetype * @param errors */ - public void checkArchetypeInternalRef(ArchetypeInternalRef ref, + public void checkArchetypeInternalRef(ArchetypeInternalRef ref, /*Class rmAttributeType,*/ Archetype archetype, - List errors) { + List errors) { log.debug("validating internal_ref of rmType: " + ref.getRmTypeName() + @@ -1053,7 +1075,7 @@ public void checkArchetypeInternalRef(ArchetypeInternalRef ref, if (targetType == null) { error = new ValidationError(ErrorType.VUNP, "UNKNOWNTARGETRM", "Unknown target rm type at path: " + ref.getTargetPath() + - " of internalRef at: " + ref.path()); + " of internalRef at: " + ref.path()); errors.add(error); } else if (!rmType.isAssignableFrom(targetType)) { error = new ValidationError(ErrorType.VUNP, "INVALIDTARGETRM", @@ -1072,7 +1094,7 @@ public void checkArchetypeInternalRef(ArchetypeInternalRef ref, * @param errors */ public void checkArchetypeDefinitionTypename(Archetype archetype, - List errors) { + List errors) { String conceptType = archetype.getArchetypeId().rmEntity(); String topType = archetype.getDefinition().getRmTypeName(); ValidationError error = null; @@ -1092,7 +1114,7 @@ public void checkArchetypeDefinitionTypename(Archetype archetype, * @return errors */ public void checkOntologyTranslation(Archetype archetype, - List errors) { + List errors) { Set languages = archetype.languagesAvailable(); String primaryLang = archetype.getOriginalLanguage().getCodeString(); @@ -1157,8 +1179,8 @@ Map checkInternalReferences(Archetype archetype) { } private Map checkInternalReferences(Archetype archetype, - CComplexObject ccobj, - Map errors) { + CComplexObject ccobj, + Map errors) { for (CAttribute cattribute : ccobj.getAttributes()) { for (CObject cobj : cattribute.getChildren()) { if (cobj instanceof ArchetypeInternalRef) { @@ -1166,7 +1188,7 @@ private Map checkInternalReferences(Archetype archetype, CObject target = (CObject) archetype.node(ref.getTargetPath()); if (target == null || !target.getRmTypeName().equals( - cobj.getRmTypeName())) { + cobj.getRmTypeName())) { // either target unknown or wrong type errors.put(ref.path(), ref.getTargetPath()); } @@ -1181,7 +1203,7 @@ private Map checkInternalReferences(Archetype archetype, } public void checkArchetypeTermValidity(Archetype archetype, - List errors) { + List errors) { Set codes = fetchAllATCodes(archetype); String lang = archetype.getOriginalLanguage().getCodeString(); List defList = @@ -1245,7 +1267,7 @@ public void checkArchetypeTermValidity(Archetype archetype, } public void checkCodeConstraintValidity(Archetype archetype, - List errors) { + List errors) { Set codes = fetchAllACCodes(archetype); String lang = archetype.getOriginalLanguage().getCodeString(); List defList = @@ -1316,7 +1338,7 @@ public void checkCodeConstraintValidity(Archetype archetype, * @param archetype */ private void checkForUnusedCodes(List defList, - List errors, Archetype archetype, Set actuallyUsedCodes) { + List errors, Archetype archetype, Set actuallyUsedCodes) { int specialisationDepth = StringUtils.countMatches(archetype.getArchetypeId().domainConcept(), "-"); @@ -1325,8 +1347,8 @@ private void checkForUnusedCodes(List defList, 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. + // 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()); @@ -1345,7 +1367,7 @@ private void checkForUnusedCodes(List defList, * @param archetype */ private void checkForDoubleCodes(List defList, - List errors, Archetype archetype) { + List errors, Archetype archetype) { // now check for each code if it exists in the definition ValidationError error = null; @@ -1353,8 +1375,8 @@ private void checkForDoubleCodes(List 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. + // 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); @@ -1366,7 +1388,7 @@ private void checkForDoubleCodes(List defList, } public void checkArchetypeTermBindingsValidity(Archetype archetype, - List errors) { + List errors) { List termBindings = archetype.getOntology().getTermBindingList(); ValidationError error = null; diff --git a/archetype-validator/src/main/resources/validations.properties b/archetype-validator/src/main/resources/validations.properties index 0e6fbb9e..04e47b16 100644 --- a/archetype-validator/src/main/resources/validations.properties +++ b/archetype-validator/src/main/resources/validations.properties @@ -90,7 +90,7 @@ 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[0..9]*. +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. 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}. diff --git a/archetype-validator/src/main/resources/validations_de.properties b/archetype-validator/src/main/resources/validations_de.properties index 8c15a02b..696ca946 100644 --- a/archetype-validator/src/main/resources/validations_de.properties +++ b/archetype-validator/src/main/resources/validations_de.properties @@ -90,7 +90,7 @@ 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[0..9]*. +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. 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}. diff --git a/archetype-validator/src/main/resources/validations_ru.properties b/archetype-validator/src/main/resources/validations_ru.properties index 86040836..2a6987d5 100644 --- a/archetype-validator/src/main/resources/validations_ru.properties +++ b/archetype-validator/src/main/resources/validations_ru.properties @@ -90,7 +90,7 @@ 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[0..9]*. +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. 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}. From 4c9f374fe8a84b0d60d1996254eab8c5b9d595bd Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Thu, 25 Jul 2019 12:29:31 +0200 Subject: [PATCH 196/213] Make Activity/timing optional as per SPECRM-71 / RM 1.0.4 --- .../composition/content/entry/Activity.java | 483 +++++++++--------- 1 file changed, 242 insertions(+), 241 deletions(-) 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 index dcff245d..ef85c004 100644 --- 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,242 +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 - - @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 ***** +/* + * 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 From 8630a07828e41e9f7c5a763b223edc53c672b323 Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Thu, 25 Jul 2019 12:34:29 +0200 Subject: [PATCH 197/213] Add support for "Reason" in ISM_Transition as per SPECRM-71 --- .../content/entry/ISMTransition.java | 423 +++++++++--------- .../composition/content/entry/ActionTest.java | 387 ++++++++-------- .../content/entry/ISMTransitionTest.java | 70 +-- .../java/org/openehr/build/EHRBuildTest.java | 85 ++-- 4 files changed, 498 insertions(+), 467 deletions(-) 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 index 3fccf455..67edd55a 100644 --- 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,203 +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 - - @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()); - 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; - } - return true; - } - - /* 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/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 1669b037..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,193 +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.Test; -import junit.framework.TestSuite; -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; - -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); - } - - 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, 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, 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, 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 ***** +/* + * 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/ISMTransitionTest.java b/openehr-rm-domain/src/test/java/org/openehr/rm/composition/content/entry/ISMTransitionTest.java index 62569b87..d4143e79 100644 --- 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/rm-builder/src/test/java/org/openehr/build/EHRBuildTest.java b/rm-builder/src/test/java/org/openehr/build/EHRBuildTest.java index cadb7686..cdc52646 100644 --- 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); } } From a6caa5914caafb21846066fb4d7a100e720a7007 Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Thu, 25 Jul 2019 12:38:05 +0200 Subject: [PATCH 198/213] Make Participation/mode optional as per SPECRM-21 + correct some minor documentation issues --- .../rm/common/generic/Participation.java | 437 +-- .../rm/support/identification/UID.java | 15 +- .../openehr/am/serialize/XMLSerializer.java | 2348 ++++++++--------- 3 files changed, 1404 insertions(+), 1396 deletions(-) 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 index 602fe14a..088621d5 100644 --- 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/support/identification/UID.java b/openehr-rm-core/src/main/java/org/openehr/rm/support/identification/UID.java index 68d6d428..12e1b142 100644 --- 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/xml-serializer/src/main/java/org/openehr/am/serialize/XMLSerializer.java b/xml-serializer/src/main/java/org/openehr/am/serialize/XMLSerializer.java index d4cdb35e..70d4f5cd 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,1176 +1,1174 @@ -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.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.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) - */ - 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); - - 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 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 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. - * +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.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.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 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 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 From f687844a6931983ac23e381a8fdc01ff1ab1e136 Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Thu, 25 Jul 2019 13:13:49 +0200 Subject: [PATCH 199/213] Make DV_IDENTIFIER features optional (all except id) as per SPECRM-23 --- .../rm/datatypes/basic/DvIdentifier.java | 400 +++++++++--------- 1 file changed, 199 insertions(+), 201 deletions(-) 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 index 6554aa60..6c564ba4 100644 --- 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 From f98e58b8404a0ebdde8caadcac29e9a8304e052f Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Thu, 25 Jul 2019 13:19:50 +0200 Subject: [PATCH 200/213] Remove COMPOSITION invariant preventing context for persistent Compositions as per SPECRM-26 / SPECRM-52 --- .../openehr/rm/composition/Composition.java | 632 +++++++++--------- 1 file changed, 319 insertions(+), 313 deletions(-) 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 6238cd32..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 (category == null) { - throw new IllegalArgumentException("null category"); - } - - // Is_persistent_validity: is_persistent implies context = Void - 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 ***** +/* + * 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 From fdaf4d8a3cbb2c826d3ffb1028018ae29260841a Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Tue, 8 Oct 2019 14:45:30 +0200 Subject: [PATCH 201/213] Fixes: VSONCT validation error text not properly picked up if more than one possible data type (e.g. DV_TEXT and DV_CODED_TEXT in the parent) --- .../SpecialisedArchetypeValidator.java | 166 +++++++++--------- .../am/validation/ValidationError.java | 59 ++++--- 2 files changed, 116 insertions(+), 109 deletions(-) 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 index e7aa9dfb..115b1e37 100644 --- a/archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/SpecialisedArchetypeValidator.java @@ -32,15 +32,15 @@ public SpecialisedArchetypeValidator() { /** - * Validates the given specialised archetype including specialised validation to its stated parent archetype - * + * 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. + * @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) + public List validate(Archetype archetype, Archetype parentArchetype, boolean reportConstraintsOnCommonFunctionalPropertiesAsInfo) throws RMInspectionException { List errors = new ArrayList(); // normal non-specialised validation first. @@ -63,16 +63,16 @@ public void checkSpecialisationHierarchyOfAllAtAndAcCodesInTheDefinition(Archety 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)); + 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)); + errors.add (new ValidationError (ErrorType.VATCD, null, + acCode, StringUtils.countMatches(acCode, "."), childSpecialisationDepth)); } } } @@ -87,7 +87,7 @@ private void validateSpecialisedCComplexObject(CComplexObject ccobj, Archetype a String parentPath = getExpectedPathInParentArchetype(ccobj.path(), childSpecialisationDepth-1); String parentPathOrig = parentPath; - boolean continueWithAttributes = true; + boolean continueWithAttributes = true; if (parentPath != null) { CObject parentNode = (CObject)parentArchetype.node(parentPath); @@ -98,7 +98,7 @@ private void validateSpecialisedCComplexObject(CComplexObject ccobj, Archetype a 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 + // 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); @@ -114,29 +114,29 @@ private void validateSpecialisedCComplexObject(CComplexObject ccobj, Archetype a if (foundParentFurtherUp) { errors.add(new ValidationError(ErrorType.VSONCI, null, ccobj.getNodeId(), parentNode.getNodeId())); - } else if (parentPath != null && parentPath.length() > 0 && (parentPath.endsWith("]") || + } 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 + // 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", + errors.add (new ValidationError (ErrorType.VATDF, "SPECIALISED", parentPath, ccobj.path())); } else { errors.add (new ValidationError (ErrorType.VATDF, "INTRODUCED", parentPath)); - } - } else if (parentPath==null) { + } + } else if (parentPath==null) { errors.add (new ValidationError (ErrorType.VATDF, "INTRODUCED", parentPathOrig)); } continueWithAttributes= false; - // node must be in ontology of parent.... + // 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()); + parentNode = (CObject)parentArchetype.node(((ArchetypeInternalRef) parentNode).getTargetPath()); } if (ccobj.getNodeId() != null) { @@ -166,16 +166,16 @@ private void validateSpecialisedCComplexObject(CComplexObject ccobj, Archetype a // 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); + 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 @@ -184,7 +184,7 @@ private void validateSpecialisedCComplexObject(CComplexObject ccobj, Archetype a private boolean checkDynamicArchetypeType(CObject parentNode, CComplexObject ccobj, List errors) { if (!ccobj.getClass().getSimpleName().equals(parentNode.getClass().getSimpleName())) { - errors.add(new ValidationError(ErrorType.VSONT, null, + errors.add(new ValidationError(ErrorType.VSONT, null, ccobj.getClass().getSimpleName(), ccobj.path(), parentNode.getClass().getSimpleName())); return false; } @@ -211,7 +211,7 @@ private void checkSpecialisedAttribute(CAttribute cattr, Archetype archetype, log.debug("PARENT NODE IN PARENT ARCHETYPE IS NULL"); } - if (parentNodeInParentArchetype instanceof CComplexObject) { + 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? @@ -230,13 +230,13 @@ private void checkSpecialisedAttribute(CAttribute cattr, Archetype archetype, if (cattr.getChildren() != null) { for (CObject cobj : cattr.getChildren()) { log.debug("-----"); - log.debug(cobj.getRmTypeName() + " " +cobj.path()); + 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); } @@ -270,7 +270,7 @@ private void validateSpecialisedCObject(CObject cobj, Archetype 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. - * + * * @param cobj * @param archetype * @param parentArchetype @@ -278,7 +278,7 @@ private void validateSpecialisedCObject(CObject cobj, Archetype archetype, */ private void checkSpecialisedConstraintRefConformance(ConstraintRef cr, Archetype archetype, Archetype parentArchetype, int childSpecialisationDepth, - List errors) { + List errors) { String pathInParent = getExpectedPathInParentArchetype(cr.path(), childSpecialisationDepth-1); if (pathInParent== null) { return; @@ -290,7 +290,7 @@ private void checkSpecialisedConstraintRefConformance(ConstraintRef cr, return; } - /* Not sure what needs to be checked for a VSCNR error, this is not it. + /* 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()); @@ -303,9 +303,9 @@ private void checkSpecialisedConstraintRefConformance(ConstraintRef cr, } - /** Checks that the existence of the parent archetype's corresponding attribute is conformant + /** 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 @@ -314,13 +314,13 @@ private void checkSpecialisedAttributeNodeExistenceConformance( CAttribute cattr, CAttribute attrInParentArchetype, List errors) { - if ((cattr.getExistence() == Existence.OPTIONAL && - (attrInParentArchetype.getExistence() == Existence.REQUIRED || + 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 && + (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, @@ -328,9 +328,9 @@ private void checkSpecialisedAttributeNodeExistenceConformance( } } - /** Checks that the multiplicity of the parent archetype's corresponding attribute is conformant + /** 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 @@ -340,21 +340,21 @@ private void checkSpecialisedAttributeMultiplicityConformance( List errors) { if (cattr instanceof CMultipleAttribute && !(attrInParentArchetype instanceof CMultipleAttribute)) { - errors.add(new ValidationError(ErrorType.VSAM, "MULTIPLE", + 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 + /** 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 @@ -366,7 +366,7 @@ private void checkSpecialisedAttributeNodeCardinalityConformance( // 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; @@ -375,8 +375,8 @@ private void checkSpecialisedAttributeNodeCardinalityConformance( Cardinality cardParentAttr = cmParentAttr.getCardinality(); - if (! cardParentAttr.getInterval().isUpperUnbounded() - && ( cardAttr.getInterval().isUpperUnbounded() + if (! cardParentAttr.getInterval().isUpperUnbounded() + && ( cardAttr.getInterval().isUpperUnbounded() || cardParentAttr.getInterval().getUpper().compareTo( cardAttr.getInterval().getUpper()) <0)) { errors.add(new ValidationError(ErrorType.VSANCC, null, @@ -385,8 +385,8 @@ private void checkSpecialisedAttributeNodeCardinalityConformance( 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())); - } + getIntervalFormalString(cardAttr.getInterval()), cattr.path(), getIntervalFormalString(cardParentAttr.getInterval()), attrInParentArchetype.path())); + } } @@ -394,7 +394,7 @@ private void checkSpecialisedAttributeNodeCardinalityConformance( * @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) { + 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) @@ -404,7 +404,7 @@ private boolean checkSpecialisedNodeIdConformance(CObject parentNode, return true; // correct number of specialisations. } - errors.add(new ValidationError(ErrorType.VSONCI, null, + errors.add(new ValidationError(ErrorType.VSONCI, null, ccobj.getNodeId(), parentNode.getNodeId())); return false; @@ -413,7 +413,7 @@ private boolean checkSpecialisedNodeIdConformance(CObject parentNode, /** 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 @@ -436,7 +436,7 @@ private void checkNodeIdIsSpecialisedIfRequired(CObject parentNode, if (!archetype.getOntology().termDefinition(langPrim, ccobj.getNodeId()).equals( parentArchetype.getOntology().termDefinition(langPrim, ccobj.getNodeId()))) { - if (archetype.getOntology().termDefinition(langPrim, ccobj.getNodeId()) !=null) { + 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()); } @@ -450,7 +450,7 @@ private void checkNodeIdIsSpecialisedIfRequired(CObject parentNode, 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) { @@ -459,19 +459,19 @@ private void checkNodeIdIsSpecialisedIfRequired(CObject parentNode, 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", + 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 @@ -479,18 +479,18 @@ private void checkNodeIdIsSpecialisedIfRequired(CObject parentNode, private void checkSpecialisedOccurrencesCompatiblity(CObject parentNode, CObject ccobj, List errors) { - if (! parentNode.getOccurrences().isUpperUnbounded() - && ( ccobj.getOccurrences().isUpperUnbounded() + 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())); - } + 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. - * + /** 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 @@ -515,7 +515,7 @@ private void checkSpecialisedRMTypeCompatiblityForNonValueItems(CObject parentNo rmInspector.retrieveRMType(rmParent); if (parentRMType == null || rmChild == null) { - errors.add (new ValidationError(ErrorType.VSONCT, "UNKNOWN", + 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)) { @@ -525,8 +525,8 @@ private void checkSpecialisedRMTypeCompatiblityForNonValueItems(CObject parentNo } /** 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. - * + * 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 @@ -543,7 +543,7 @@ private void checkSpecialisedRMTypeCompatiblityOfValueChildren(CAttribute cattr, if (parentPath == null) { return; // nothing to test } - CObject parentNode =(CObject) parentArchetype.node(parentPath); + CObject parentNode =(CObject) parentArchetype.node(parentPath); if (parentNode == null || !(parentNode instanceof CComplexObject)) { return; } @@ -555,15 +555,15 @@ private void checkSpecialisedRMTypeCompatiblityOfValueChildren(CAttribute cattr, HashMap parentObjectsToRMTypesWithoutGenerics = new HashMap(); for (CObject childInParent : parentAttr.getChildren()) { - // for all children - not only CComplexObjects - because of e.g. C_DV_QUANTITY constraints + // 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 { + } else { parentObjectsToRMTypesWithoutGenerics.put(childInParent, parentRMType); - } + } } if (parentObjectsToRMTypesWithoutGenerics.size() == 0) { @@ -589,21 +589,21 @@ private void checkSpecialisedRMTypeCompatiblityOfValueChildren(CAttribute cattr, 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 + // 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; - } - } + break; + } + } } else { assignable = true; break; - } - } + } + } } if (!assignable) { @@ -618,11 +618,11 @@ private void checkSpecialisedRMTypeCompatiblityOfValueChildren(CAttribute cattr, 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, + // more than one RM type possible + errors.add (new ValidationError(ErrorType.VSONCT, "MORETHANONE", childRMType.getSimpleName(), child.path(), parentRefTypes)); } - } + } } } @@ -631,7 +631,7 @@ private void checkTermExistsInParent(Archetype parentArchetype, String code, List errors) { String lang = parentArchetype.getOriginalLanguage().getCodeString(); - List defList = + List defList = parentArchetype.getOntology().getTermDefinitionsList(); OntologyDefinitions priDefs = null; ValidationError error = null; @@ -664,7 +664,7 @@ private void checkTermExistsInParent(Archetype parentArchetype, String code, /** Calculates the expected path in a parent archetype derived from the given path. - * + * * @param path * @return */ @@ -694,7 +694,7 @@ private String getExpectedPathInParentArchetype(String path, int parentArchetype log.debug("Path ends with at0: "+ pathPart +" "+expectedPath); return null; } - expectedPath += pathPart + pathEnd+sep; + expectedPath += pathPart + pathEnd+sep; } if (expectedPath.length() >1 && expectedPath.endsWith(sep)) { expectedPath = expectedPath.substring(0,expectedPath.length()-1); // get rid of tailing separator @@ -706,7 +706,7 @@ private String getExpectedPathInParentArchetype(String path, int parentArchetype } /** 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 @@ -758,7 +758,7 @@ private boolean equalsDirect(CObject c1, CObject c2) { } } } - } + } } return true; // no differences found 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 index 10b178a8..3058bcad 100644 --- a/archetype-validator/src/main/java/org/openehr/am/validation/ValidationError.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ValidationError.java @@ -7,19 +7,15 @@ import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; /** - * Archetype validation error with error type, short text + * 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) { - // this(type, null); - // } - public ValidationError(ErrorType type, String subType, Object... params) { this.type = type; this.subType = subType; @@ -32,15 +28,15 @@ public ErrorType getType() { /** 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 */ @@ -49,7 +45,15 @@ public String getText(Locale locale) { locale = Locale.getDefault(); } - String errorText = ResourceBundle.getBundle("validations", locale, UTF8Control.getInstance()).getString(getTextKey()); + 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); } @@ -57,24 +61,27 @@ public String getText(Locale locale) { } protected String getTextKey() { - if (subType ==null) { + return getTextKey(false); + } + + protected String getTextKey(boolean ignoreSubtype) { + if (ignoreSubtype || subType == null) { return this.type.toString()+"_TEXT"; } else { - return this.type.toString()+"_"+subType+"_TEXT"; + 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 */ @@ -85,7 +92,7 @@ public String getDescription(Locale locale) { return ResourceBundle.getBundle("validations", locale, UTF8Control.getInstance()).getString(this.type.toString()); - } + } /** @@ -103,7 +110,7 @@ public String toString() { public String toString(Locale locale) { return type + ", " + getText(locale) + ", "+ getDescription(locale); } - + @Override public boolean equals(Object obj) { if (obj == null) { return false; } @@ -113,11 +120,11 @@ public boolean equals(Object obj) { } ValidationError ve = (ValidationError) obj; return new EqualsBuilder() - .append(type, ve.type) - .append(subType, ve.subType) - .append(params, ve.params) - // .append(getDescription(), ve.getDescription()) - .isEquals(); + .append(type, ve.type) + .append(subType, ve.subType) + .append(params, ve.params) + // .append(getDescription(), ve.getDescription()) + .isEquals(); } @Override @@ -126,7 +133,7 @@ public int hashCode() { append(type). append(subType). append(params). - // append(getDescription()). + // append(getDescription()). toHashCode(); } From 0cda10c9496ea70089ee9223d31e4d2b00a9d687 Mon Sep 17 00:00:00 2001 From: Iago Corbal Date: Thu, 7 Nov 2019 16:26:57 +0100 Subject: [PATCH 202/213] Removing call to parentResource in ResourceDescription.hashCode() to avoid StackOverflow (due to circular dependency) --- .../org/openehr/rm/common/resource/ResourceDescription.java | 2 -- 1 file changed, 2 deletions(-) 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 index 227ae6f3..0b1cab5c 100644 --- 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 @@ -210,8 +210,6 @@ public int hashCode() { .hashCode()); result = prime * result + ((otherDetails == null) ? 0 : otherDetails.hashCode()); - result = prime * result - + ((parentResource == null) ? 0 : parentResource.hashCode()); result = prime * result + ((resourcePackageUri == null) ? 0 : resourcePackageUri From de2335d6acae537819ddf04342e3035198273acd Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Fri, 8 Nov 2019 09:20:19 +0100 Subject: [PATCH 203/213] Integrate Updates and Corrections of the openEHR terminology and external terminology --- .../resources/external_terminologies_en.xml | 78 +++++++++++++++---- .../main/resources/openehr_terminology_en.xml | 24 +++--- 2 files changed, 78 insertions(+), 24 deletions(-) diff --git a/mini-termserv/src/main/resources/external_terminologies_en.xml b/mini-termserv/src/main/resources/external_terminologies_en.xml index c22707ee..844047dc 100644 --- a/mini-termserv/src/main/resources/external_terminologies_en.xml +++ b/mini-termserv/src/main/resources/external_terminologies_en.xml @@ -333,14 +333,13 @@ - + - @@ -398,16 +397,69 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mini-termserv/src/main/resources/openehr_terminology_en.xml b/mini-termserv/src/main/resources/openehr_terminology_en.xml index e2ac826b..c120da56 100644 --- 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 @@ - - - + + + - - - - + + + + From e186b2a8b49c728367003265c3fbd1a68b92bbc1 Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Thu, 15 Apr 2021 11:52:52 +0200 Subject: [PATCH 204/213] Add support for DV_SCALE --- adl-parser/src/main/javacc/adl.jj | 121 +- .../se/acode/openehr/parser/CDvScaleTest.java | 131 + .../adl-test-entry.c_dv_scale.test.adl | 97 + ...openEHR-EHR-CLUSTER.ordinalandscale.v0.adl | 178 ++ .../openehr/am/serialize/ADLSerializer.java | 2602 +++++++++-------- .../openehr/am/validation/RMInspector.java | 1174 ++++---- .../datatypes/quantity/CDvScale.java | 157 + .../datatypes/quantity/Scale.java | 159 + .../encapsulated/DvEncapsulated.java | 14 +- .../rm/datatypes/quantity/DvScale.java | 310 ++ .../openehr/am/serialize/XMLSerializer.java | 45 +- 11 files changed, 3122 insertions(+), 1866 deletions(-) create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/CDvScaleTest.java create mode 100644 adl-parser/src/test/resources/adl-test-entry.c_dv_scale.test.adl create mode 100644 adl-parser/src/test/resources/openEHR-EHR-CLUSTER.ordinalandscale.v0.adl create mode 100644 openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/CDvScale.java create mode 100644 openehr-ap/src/main/java/org/openehr/am/openehrprofile/datatypes/quantity/Scale.java create mode 100644 openehr-rm-core/src/main/java/org/openehr/rm/datatypes/quantity/DvScale.java diff --git a/adl-parser/src/main/javacc/adl.jj b/adl-parser/src/main/javacc/adl.jj index 82b1c2e0..defd39d8 100755 --- a/adl-parser/src/main/javacc/adl.jj +++ b/adl-parser/src/main/javacc/adl.jj @@ -433,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"] @@ -1719,7 +1719,9 @@ double real_value() : boolean negative = false; } { - [ ( "+" | "-" { negative = true; } ) ] t = + ( + [ ( "+" | "-" { negative = true; } ) ] t = + ) { try { d = Double.parseDouble(t.image); @@ -1733,6 +1735,61 @@ double real_value() : } } +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); + } catch(NumberFormatException e) { + throw new ParseException("Wrong format of double: " + t.image); + } + if(negative) { + d = -d; + } + return d; + } +} + + List real_list_value() : { List list = new ArrayList(); @@ -2287,8 +2344,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) @@ -2424,7 +2484,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; @@ -2433,8 +2493,8 @@ CAttribute c_attribute(String path) : { if( ! path.endsWith("/")) { path += "/"; - } - } + } + } name = attribute_identifier() [ existence = c_existence() ] [ cardinality = c_cardinality() ] @@ -2822,7 +2882,6 @@ CDvOrdinal c_dv_ordinal(String path, CAttribute parent) : Interval occurrences = new Interval(1, 1); } { - o = ordinal() { list.add(o); } ( "," o = ordinal() @@ -2866,6 +2925,54 @@ org.openehr.am.openehrprofile.datatypes.quantity.Ordinal ordinal() : } } +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; 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/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/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-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java b/adl-serializer/src/main/java/org/openehr/am/serialize/ADLSerializer.java index be491a5e..27b08494 100644 --- 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,1264 +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 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.*; -import org.openehr.am.archetype.constraintmodel.primitive.*; -import org.openehr.am.archetype.ontology.*; -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; - -import java.io.*; -import java.nio.charset.Charset; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * 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 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(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 ***** - */ +/* + * 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/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java b/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java index bfece661..2f872d1b 100755 --- a/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/RMInspector.java @@ -1,586 +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.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, - 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)); - } -} +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/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/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-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 index 0c48b184..478f6a2e 100644 --- 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/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/xml-serializer/src/main/java/org/openehr/am/serialize/XMLSerializer.java b/xml-serializer/src/main/java/org/openehr/am/serialize/XMLSerializer.java index 70d4f5cd..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 @@ -51,7 +51,9 @@ 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; @@ -597,6 +599,8 @@ protected void printCDomainType(CDomainType cdomain, Element out) { 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 { @@ -638,7 +642,6 @@ protected void printCCodePhrase(CCodePhrase ccp, Element out) { } protected void printCDvOrdinal(CDvOrdinal cordinal, Element out) { - Element children = new Element("children", defaultNamespace); out.getChildren().add(children); children.setAttribute("type", "C_DV_ORDINAL", xsiNamespace); @@ -677,8 +680,46 @@ private void printSymbolOfOrdinal(Ordinal ordinal, Element list) { printCodePhrase(ordinal.getSymbol(), definingCode); } - protected void printCDvQuantity(CDvQuantity cquantity, Element out) { + 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); From 886ce970c7ed5219ddbf59de900229970e29717f Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Thu, 15 Apr 2021 11:57:53 +0200 Subject: [PATCH 205/213] - update xmlbeans to 3.1.0 for xml-binding - add test for ResourceDescription explicitly setting its parent resource --- .../common/resource/ResourceDescription.java | 596 +++++++++--------- .../common/resource/AuthoredResourceTest.java | 276 ++++---- xml-binding/pom.xml | 261 ++++---- 3 files changed, 572 insertions(+), 561 deletions(-) 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 index 0b1cab5c..416c203e 100644 --- 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,299 +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) 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; - } - - 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 ***** +/* + * 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/test/java/org/openehr/rm/common/resource/AuthoredResourceTest.java b/openehr-rm-core/src/test/java/org/openehr/rm/common/resource/AuthoredResourceTest.java index b1222f3c..0d524878 100644 --- 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/xml-binding/pom.xml b/xml-binding/pom.xml index c7712109..f025b218 100755 --- a/xml-binding/pom.xml +++ b/xml-binding/pom.xml @@ -1,128 +1,133 @@ - - - 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 - - - - - - - - org.openehr.java-libs - openehr-rm-core - ${project.version} - - - org.openehr.java-libs - openehr-rm-domain - ${project.version} - - - org.apache.xmlbeans - xmlbeans - 2.3.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} - - - + + + 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} + + + From b93cd2cfa1b709b47ef4e978294fd178702ca741 Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Thu, 15 Apr 2021 12:00:51 +0200 Subject: [PATCH 206/213] Change default cattribute existence to OPTIONAL in accordance wioth common practice --- .../acode/openehr/parser/ParserTestBase.java | 566 +++++++++--------- .../constraintmodel/CAttributeTest.java | 174 +++--- 2 files changed, 373 insertions(+), 367 deletions(-) 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 index 30d891c7..0f29f45d 100644 --- 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/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 index 23bae574..5678491b 100644 --- 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; + } + } } /* From 04dad7566327dd10cb9452e82ccdb64faccf0466 Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Thu, 15 Apr 2021 13:47:22 +0200 Subject: [PATCH 207/213] Archetype Validation adjustments for DV_SCALE support --- .../openehr/am/validation/ArchetypeValidator.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) 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 index 3a150e3b..19d399c7 100755 --- a/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java @@ -50,7 +50,9 @@ 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; @@ -1463,6 +1465,17 @@ void fetchATCodes(CObject cobj, Set codes) { } } } + } 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(); From 5c2c93ca60644ad491347402bf69b614fcbb80ed Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Fri, 16 Apr 2021 12:04:14 +0200 Subject: [PATCH 208/213] Add Slot validation for "any_allowed xor (includes != void or excludes != void)" contraint on the slot --- .../am/validation/ArchetypeValidator.java | 11 +- .../src/main/resources/validations.properties | 1 + .../main/resources/validations_de.properties | 1 + .../main/resources/validations_ru.properties | 1 + .../am/validation/ArchetypeSlotCheckTest.java | 53 ++++---- .../openEHR-EHR-OBSERVATION.slot.v2.adl | 114 +++++++++--------- .../openEHR-EHR-OBSERVATION.slot.v3.adl | 56 +++++++++ 7 files changed, 151 insertions(+), 86 deletions(-) create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v3.adl 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 index 19d399c7..21d9afdf 100755 --- a/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java @@ -711,7 +711,6 @@ private void checkCardinalityConformsToRMCardinality(CMultipleAttribute cattr, C //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)) { @@ -724,8 +723,6 @@ private void checkCardinalityConformsToRMCardinality(CMultipleAttribute cattr, C //WCACA } } - - } @@ -737,8 +734,7 @@ private void checkCardinalityConformsToRMCardinality(CMultipleAttribute cattr, C * @param archetype * @param errors */ - private void checkArchetypeSlot(ArchetypeSlot slot, Class rmAttrType, Archetype archetype, - List 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); @@ -749,6 +745,11 @@ private void checkArchetypeSlot(ArchetypeSlot slot, Class rmAttrType, Archetype 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); + } } /** diff --git a/archetype-validator/src/main/resources/validations.properties b/archetype-validator/src/main/resources/validations.properties index 04e47b16..00afada8 100644 --- a/archetype-validator/src/main/resources/validations.properties +++ b/archetype-validator/src/main/resources/validations.properties @@ -92,6 +92,7 @@ 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=Archetype Slot at {0} does not allow any archetypes to be included. 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}. diff --git a/archetype-validator/src/main/resources/validations_de.properties b/archetype-validator/src/main/resources/validations_de.properties index 696ca946..e4e724eb 100644 --- a/archetype-validator/src/main/resources/validations_de.properties +++ b/archetype-validator/src/main/resources/validations_de.properties @@ -92,6 +92,7 @@ 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=(de)Archetype Slot at {0} does not allow any archetypes to be included. 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}. diff --git a/archetype-validator/src/main/resources/validations_ru.properties b/archetype-validator/src/main/resources/validations_ru.properties index 2a6987d5..6b6f28a2 100644 --- a/archetype-validator/src/main/resources/validations_ru.properties +++ b/archetype-validator/src/main/resources/validations_ru.properties @@ -92,6 +92,7 @@ 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=(ru)Archetype Slot at {0} does not allow any archetypes to be included. 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}. 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 index 188d58d0..753c886e 100644 --- a/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeSlotCheckTest.java +++ b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeSlotCheckTest.java @@ -1,24 +1,29 @@ -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); - } - - - private void checkSlot(String name) throws Exception { - archetype = loadArchetype(name); - validator.checkObjectConstraints(archetype, errors); - } -} +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 testCheckWithInvalidSlotNoneAllowed() throws Exception { + checkSlot("openEHR-EHR-OBSERVATION.slot.v3.adl"); + // SG: This slot is not giving an error anymore * is the same as unconstrained ?! + // 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/resources/openEHR-EHR-OBSERVATION.slot.v2.adl b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v2.adl index 8c2be792..150bd3df 100644 --- a/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v2.adl +++ b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v2.adl @@ -1,57 +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 = <"*"> - > - > - > - > +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..a747759c --- /dev/null +++ b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v3.adl @@ -0,0 +1,56 @@ +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 { -- incorrect Slot - 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 = <"*"> + > + > + > + > From 9f3f763760417145563013c12dd0bb4a18af5ed4 Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Fri, 16 Apr 2021 12:07:21 +0200 Subject: [PATCH 209/213] Updated (Relaxed) VDFAI validation according to the discussion on VDFAI interpretation at https://discourse.openehr.org/t/vdfai-validation-interpretation/1433/5 --- .../openehr/am/serialize/DescriptionTest.java | 250 +++++++++--------- .../am/validation/ArchetypeValidator.java | 48 ++-- .../am/validation/ArchetypeSlotCheckTest.java | 20 +- .../openEHR-EHR-OBSERVATION.slot.v3.adl | 3 +- .../openEHR-EHR-OBSERVATION.slot.v4.adl | 57 ++++ .../openEHR-EHR-OBSERVATION.slot.v5.adl | 57 ++++ 6 files changed, 286 insertions(+), 149 deletions(-) create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v4.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v5.adl 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 index 22397d57..a3d5cd09 100644 --- 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); - - 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 ***** - */ +/* + * 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/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java index 21d9afdf..fcf3ca13 100755 --- a/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java @@ -804,15 +804,32 @@ private void checkAssertionHasValidArchetypeIds(Assertion assertion, ArchetypeSl * @param oneId */ private void checkOneArchetypeId(ArchetypeSlot slot, List errors, String oneId) { - // check for the right number of dots in the id + // 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 (oneId.lastIndexOf(".v") == -1) { + 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 { - String tail = oneId.substring(oneId.lastIndexOf(".v") + 2); + } 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. @@ -827,6 +844,8 @@ private void checkOneArchetypeId(ArchetypeSlot slot, List error && !tail.equals("[1-9]") && !tail.equals("(0|[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; @@ -840,28 +859,21 @@ private void checkOneArchetypeId(ArchetypeSlot slot, List error } } - // check that the first part of the id (the qualified RM Entity) contains the right number of hyphens - boolean containsCorrectNumberOfHyphensInQualifiedRMEntity = true; // assume it is ok, until proven wrong - String qualifiedRMEntity = oneId.substring(0, oneId.indexOf(".")); - if (StringUtils.countMatches(qualifiedRMEntity, "-") != 2) { - containsCorrectNumberOfHyphensInQualifiedRMEntity = false; - } - - // add all the errors - if (!containsCorrectNumberOfDots) { - ValidationError error = new ValidationError(ErrorType.VDFAI, "NUMBEROFDOTS", oneId, slot.path()); - errors.add(error); - - } 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 + boolean containsCorrectNumberOfHyphensInQualifiedRMEntity = true; // assume it is ok, until proven wrong + String qualifiedRMEntity = idParts[0]; // oneId.substring(0, oneId.indexOf("\\.")); + if (StringUtils.countMatches(qualifiedRMEntity, "-") != 2 && !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 + containsCorrectNumberOfHyphensInQualifiedRMEntity = false; } + if (!containsCorrectNumberOfHyphensInQualifiedRMEntity) { ValidationError error = new ValidationError(ErrorType.VDFAI, "NUMBEROFHYPHENS", oneId, slot.path()); errors.add(error); - } } 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 index 753c886e..53d7991d 100644 --- a/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeSlotCheckTest.java +++ b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeSlotCheckTest.java @@ -15,13 +15,25 @@ public void testCheckWithInvalidSlot() throws Exception { assertSecondErrorType(ErrorType.VDFAI); } - public void testCheckWithInvalidSlotNoneAllowed() throws Exception { + public void testCheckWithValidSlotAllAllowed() throws Exception { checkSlot("openEHR-EHR-OBSERVATION.slot.v3.adl"); - // SG: This slot is not giving an error anymore * is the same as unconstrained ?! - // assertEquals("wrong number of validation errors: " + errors, 1, errors.size()); - // assertFirstErrorType(ErrorType.VDFAI); + // 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); + } + + private void checkSlot(String name) throws Exception { archetype = loadArchetype(name); validator.checkObjectConstraints(archetype, errors); 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 index a747759c..af8e2e80 100644 --- a/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v3.adl +++ b/archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v3.adl @@ -15,7 +15,8 @@ definition data matches { ITEM_TREE[at0003] matches { -- Tree items cardinality matches {0..*; unordered} matches { - allow_archetype CLUSTER[at0004] occurrences matches {0..*} matches { -- incorrect Slot - Validity: any_allowed xor (includes /= Void or excludes /= Void) + 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) } } 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 = <"*"> + > + > + > + > From 6769ce7d7df779bca303545d4aeb76c63e8732f0 Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Wed, 21 Apr 2021 10:24:02 +0200 Subject: [PATCH 210/213] Update the code used for "episodic" to 451, following discussion and conclusion of SPECPR-367 --- mini-termserv/src/main/resources/openehr_terminology_en.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mini-termserv/src/main/resources/openehr_terminology_en.xml b/mini-termserv/src/main/resources/openehr_terminology_en.xml index c120da56..e8a92193 100644 --- a/mini-termserv/src/main/resources/openehr_terminology_en.xml +++ b/mini-termserv/src/main/resources/openehr_terminology_en.xml @@ -34,7 +34,7 @@ - + From 0d2240ab757e1ef8008b78d871511a230c8b251c Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Wed, 21 Apr 2021 15:11:03 +0200 Subject: [PATCH 211/213] Correctly parse DV_DURATION constraints where lower and upper is specified and < and/or > used to indicate non-inclusiveness of the border --- adl-parser/src/main/javacc/adl.jj | 26 +++- .../parser/DvDurationIntervalTest.java | 32 +++++ ...-EHR-CLUSTER.duration_interval_test.v0.adl | 129 ++++++++++++++++++ 3 files changed, 184 insertions(+), 3 deletions(-) create mode 100644 adl-parser/src/test/java/se/acode/openehr/parser/DvDurationIntervalTest.java create mode 100644 adl-parser/src/test/resources/openEHR-EHR-CLUSTER.duration_interval_test.v0.adl diff --git a/adl-parser/src/main/javacc/adl.jj b/adl-parser/src/main/javacc/adl.jj index defd39d8..a10c09af 100755 --- a/adl-parser/src/main/javacc/adl.jj +++ b/adl-parser/src/main/javacc/adl.jj @@ -2208,14 +2208,34 @@ Interval duration_interval_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() { 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/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 = <"*"> + > + > + > + > From dc5e3a0f2ab4bddfa3c104e81a93e5b50d448d5f Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Mon, 14 Feb 2022 14:54:55 +0100 Subject: [PATCH 212/213] Slots with regular expression containing non top-level pipes (inside one archetype id expression), e.g. openEHR-EHR-CLUSTER\.(anatomical_location|anatomical_location_circle)(-[a-zA-Z0-9_]+)*\.v1| openEHR-EHR-CLUSTER\.anatomical_location_relative(-[a-zA-Z0-9_]+)*\.v2 should be considered valid following the discussion at https://discourse.openehr.org/t/medication-order-medication-details-dosage-ready-for-republication-as-a-new-major-version/2208/10 In addition, the the general validity of the regex should be evaluated and reported as a VDFAI error if invalid. --- .../am/validation/ArchetypeValidator.java | 43 +++++++++--- .../src/main/resources/validations.properties | 3 +- .../main/resources/validations_de.properties | 3 +- .../main/resources/validations_ru.properties | 3 +- .../am/validation/ArchetypeSlotCheckTest.java | 12 +++- .../openEHR-EHR-OBSERVATION.slot.v6.adl | 67 +++++++++++++++++++ .../openEHR-EHR-OBSERVATION.slot.v7.adl | 67 +++++++++++++++++++ 7 files changed, 184 insertions(+), 14 deletions(-) create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v6.adl create mode 100644 archetype-validator/src/test/resources/openEHR-EHR-OBSERVATION.slot.v7.adl 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 index fcf3ca13..9eabb8c3 100755 --- a/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java @@ -769,23 +769,50 @@ private void checkAssertionHasValidArchetypeIds(Assertion assertion, ArchetypeSl 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) { - int i = pattern.indexOf("(-[a-zA-Z0-9_]+)*\\"); 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) { - String oneId = pattern.substring(0, pattern.indexOf("|")); + // 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); } @@ -793,7 +820,6 @@ private void checkAssertionHasValidArchetypeIds(Assertion assertion, ArchetypeSl } } } - } /** @@ -843,6 +869,7 @@ private void checkOneArchetypeId(ArchetypeSlot slot, List error && !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 @@ -865,17 +892,13 @@ private void checkOneArchetypeId(ArchetypeSlot slot, List error } // check that the first part of the id (the qualified RM Entity) contains the right number of hyphens - boolean containsCorrectNumberOfHyphensInQualifiedRMEntity = true; // assume it is ok, until proven wrong String qualifiedRMEntity = idParts[0]; // oneId.substring(0, oneId.indexOf("\\.")); - if (StringUtils.countMatches(qualifiedRMEntity, "-") != 2 && !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 - containsCorrectNumberOfHyphensInQualifiedRMEntity = false; - } - - if (!containsCorrectNumberOfHyphensInQualifiedRMEntity) { + 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); } - } diff --git a/archetype-validator/src/main/resources/validations.properties b/archetype-validator/src/main/resources/validations.properties index 00afada8..82f13254 100644 --- a/archetype-validator/src/main/resources/validations.properties +++ b/archetype-validator/src/main/resources/validations.properties @@ -92,7 +92,8 @@ 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=Archetype Slot at {0} does not allow any archetypes to be included. +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}. diff --git a/archetype-validator/src/main/resources/validations_de.properties b/archetype-validator/src/main/resources/validations_de.properties index e4e724eb..d9c3a53f 100644 --- a/archetype-validator/src/main/resources/validations_de.properties +++ b/archetype-validator/src/main/resources/validations_de.properties @@ -92,7 +92,8 @@ 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=(de)Archetype Slot at {0} does not allow any archetypes to be included. +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}. diff --git a/archetype-validator/src/main/resources/validations_ru.properties b/archetype-validator/src/main/resources/validations_ru.properties index 6b6f28a2..3ca17bd2 100644 --- a/archetype-validator/src/main/resources/validations_ru.properties +++ b/archetype-validator/src/main/resources/validations_ru.properties @@ -92,7 +92,8 @@ 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=(ru)Archetype Slot at {0} does not allow any archetypes to be included. +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}. 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 index 53d7991d..cd3ca607 100644 --- a/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeSlotCheckTest.java +++ b/archetype-validator/src/test/java/org/openehr/am/validation/ArchetypeSlotCheckTest.java @@ -33,7 +33,17 @@ public void testCheckWithInvalidInclude() throws Exception { 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/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 = <"*"> + > + > + > + > From 214a1704abadc42034ff01a52961c872080433b8 Mon Sep 17 00:00:00 2001 From: Sebastian Garde Date: Fri, 1 Apr 2022 16:07:04 +0200 Subject: [PATCH 213/213] Add validation check to ensure that the description/details are present for the original language as well as all translations. --- .../am/validation/ArchetypeValidator.java | 31 +++-- .../src/main/resources/validations.properties | 1 + .../main/resources/validations_de.properties | 1 + .../main/resources/validations_ru.properties | 1 + .../OntologyTranslationCheckTest.java | 112 +++++++++--------- .../adl-test-ENTRY.ontology_translation.v8 | 58 +++++++++ 6 files changed, 138 insertions(+), 66 deletions(-) create mode 100644 archetype-validator/src/test/resources/adl-test-ENTRY.ontology_translation.v8 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 index 9eabb8c3..f3be889c 100755 --- a/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java +++ b/archetype-validator/src/main/java/org/openehr/am/validation/ArchetypeValidator.java @@ -24,6 +24,7 @@ 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; @@ -1142,17 +1143,14 @@ public void checkArchetypeDefinitionTypename(Archetype archetype, } } - /** - * Checks if languages listed in translation section are provided in - * term_definition and constraint_definition sections + /** 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) { + * @return errors */ + public void checkOntologyTranslation(Archetype archetype, List errors) { Set languages = archetype.languagesAvailable(); String primaryLang = archetype.getOriginalLanguage().getCodeString(); @@ -1164,21 +1162,28 @@ public void checkOntologyTranslation(Archetype archetype, Set termDefLangs = retrieveLanguageSet(termDefList); Set constraintDefLangs = retrieveLanguageSet(constraintDefList); - ValidationError error; + + 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); + error = new ValidationError(ErrorType.VOTM, "TERM", lang); errors.add(error); } if (!constraintDefList.isEmpty() && !constraintDefLangs.contains(lang)) { - error = new ValidationError(ErrorType.VOTM, "CONSTRAINT", - lang); + error = new ValidationError(ErrorType.VOTM, "CONSTRAINT", lang); errors.add(error); } } diff --git a/archetype-validator/src/main/resources/validations.properties b/archetype-validator/src/main/resources/validations.properties index 82f13254..8ae7cc24 100644 --- a/archetype-validator/src/main/resources/validations.properties +++ b/archetype-validator/src/main/resources/validations.properties @@ -59,6 +59,7 @@ 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. diff --git a/archetype-validator/src/main/resources/validations_de.properties b/archetype-validator/src/main/resources/validations_de.properties index d9c3a53f..e905261b 100644 --- a/archetype-validator/src/main/resources/validations_de.properties +++ b/archetype-validator/src/main/resources/validations_de.properties @@ -59,6 +59,7 @@ 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. diff --git a/archetype-validator/src/main/resources/validations_ru.properties b/archetype-validator/src/main/resources/validations_ru.properties index 3ca17bd2..9b5ba9a0 100644 --- a/archetype-validator/src/main/resources/validations_ru.properties +++ b/archetype-validator/src/main/resources/validations_ru.properties @@ -59,6 +59,7 @@ 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. 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 index 068740ae..33309789 100644 --- a/archetype-validator/src/test/java/org/openehr/am/validation/OntologyTranslationCheckTest.java +++ b/archetype-validator/src/test/java/org/openehr/am/validation/OntologyTranslationCheckTest.java @@ -1,53 +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); - } - - private void checkTranslation(String name) throws Exception { - archetype = loadArchetype(name); - validator.checkOntologyTranslation(archetype, errors); - } -} +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/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