diff --git a/configuration/ccdaReferenceValidatorConfig.xml b/configuration/ccdaReferenceValidatorConfig.xml index 63f731ce..452d98d8 100644 --- a/configuration/ccdaReferenceValidatorConfig.xml +++ b/configuration/ccdaReferenceValidatorConfig.xml @@ -1,10 +1,11 @@ + - + ValueSetCodeValidator SHOULD @@ -15,7 +16,7 @@ - + LanguageCodeNodeLanguageCodeValuesetValidator SHALL @@ -25,7 +26,7 @@ - + LanguageCodeNodeCountryCodeValuesetValidator SHALL @@ -39,7 +40,7 @@ - + ValueSetCodeValidator SHALL @@ -50,7 +51,7 @@ - + ValueSetCodeValidator SHALL @@ -61,7 +62,7 @@ - + ValueSetCodeValidator SHALL @@ -72,7 +73,7 @@ - + ValueSetCodeValidator SHALL @@ -83,7 +84,7 @@ - + ValueSetCodeValidator SHALL @@ -94,7 +95,7 @@ - + ValueSetCodeValidator SHALL @@ -105,7 +106,7 @@ - + ValueSetCodeValidator SHALL @@ -116,7 +117,7 @@ - + ValueSetCodeValidator SHALL @@ -130,7 +131,7 @@ - + TextNodeValidator SHALL @@ -141,7 +142,7 @@ - + TextNodeValidator SHALL @@ -152,7 +153,7 @@ - + TextNodeValidator SHALL @@ -163,7 +164,7 @@ - + LanguageCodeNodeLanguageCodeValuesetValidator SHALL @@ -173,7 +174,7 @@ - + LanguageCodeNodeCountryCodeValuesetValidator SHALL @@ -184,7 +185,7 @@ - + ValueSetCodeValidator SHALL @@ -195,7 +196,7 @@ - + ValueSetCodeValidator SHALL @@ -209,7 +210,7 @@ - + ValueSetNodeWithOnlyCodeValidator SHOULD @@ -223,7 +224,7 @@ - + ValueSetCodeValidator SHOULD @@ -237,7 +238,7 @@ - + ValueSetCodeValidator SHOULD @@ -251,7 +252,7 @@ - + ValueSetCodeValidator SHOULD @@ -265,7 +266,7 @@ - + ValueSetCodeValidator SHOULD @@ -279,7 +280,7 @@ - + ValueSetCodeValidator SHOULD @@ -292,7 +293,7 @@ - + ValueSetCodeValidator SHALL @@ -305,7 +306,7 @@ - + ValueSetCodeValidator SHALL @@ -318,7 +319,7 @@ - + ValueSetCodeValidator SHOULD @@ -329,7 +330,7 @@ - + ValueSetCodeValidator SHOULD @@ -342,7 +343,7 @@ - + ValueSetCodeValidator SHALL @@ -353,7 +354,7 @@ - + ValueSetCodeValidator SHOULD @@ -366,7 +367,7 @@ - + ValueSetCodeValidator SHALL @@ -379,7 +380,7 @@ - + ValueSetCodeValidator SHALL @@ -390,7 +391,7 @@ - + ValueSetCodeValidator SHALL @@ -403,7 +404,7 @@ - + ValueSetCodeValidator SHALL @@ -414,7 +415,7 @@ - + ValueSetCodeValidator SHALL @@ -427,7 +428,7 @@ - + ValueSetCodeValidator SHALL @@ -440,7 +441,7 @@ - + ValueSetCodeValidator SHALL @@ -451,7 +452,7 @@ - + ClassCodeValidator SHALL @@ -464,7 +465,7 @@ - + ValueSetCodeValidator SHALL @@ -475,7 +476,7 @@ - + ClassCodeValidator SHALL @@ -486,7 +487,7 @@ - + ValueSetCodeValidator SHOULD @@ -499,7 +500,7 @@ - + ValueSetCodeValidator SHALL @@ -510,7 +511,7 @@ - + ValueSetCodeValidator SHOULD @@ -521,7 +522,7 @@ - + ValueSetCodeValidator SHOULD @@ -532,7 +533,7 @@ - + ValueSetCodeValidator SHOULD @@ -543,7 +544,7 @@ - + ValueSetCodeValidator SHOULD @@ -554,7 +555,7 @@ - + ValueSetCodeValidator SHOULD @@ -565,7 +566,7 @@ - + ValueSetCodeValidator SHOULD @@ -576,7 +577,7 @@ - + ValueSetCodeValidator SHOULD @@ -589,7 +590,7 @@ - + ValueSetCodeValidator SHOULD @@ -600,7 +601,7 @@ - + ValueSetCodeValidator SHOULD @@ -611,7 +612,7 @@ - + ValueSetCodeValidator SHOULD @@ -622,7 +623,7 @@ - + ValueSetCodeValidator SHOULD @@ -635,7 +636,7 @@ - + UnitValidator SHALL @@ -648,7 +649,7 @@ - + ValueSetCodeValidator SHALL @@ -661,7 +662,7 @@ - + ValueSetCodeValidator SHOULD @@ -674,7 +675,7 @@ - + ValueSetCodeValidator SHOULD @@ -687,7 +688,7 @@ - + ValueSetNodeWithOnlyCodeValidator SHALL @@ -700,7 +701,7 @@ - + ValueSetCodeValidator SHOULD @@ -711,7 +712,7 @@ - + ValueSetNodeWithOnlyCodeValidator SHOULD @@ -722,7 +723,7 @@ - + ValueSetCodeValidator SHOULD @@ -735,7 +736,7 @@ - + ValueSetCodeValidator SHOULD @@ -746,7 +747,7 @@ - + ValueSetCodeValidator SHALL @@ -759,7 +760,7 @@ - + ValueSetNodeWithOnlyCodeValidator SHOULD @@ -770,7 +771,7 @@ - + ValueSetNodeWithOnlyCodeValidator SHALL @@ -783,7 +784,7 @@ - + ValueSetCodeValidator SHOULD @@ -796,7 +797,7 @@ - + ValueSetCodeValidator SHOULD @@ -809,7 +810,7 @@ - + ValueSetCodeValidator SHALL @@ -822,7 +823,7 @@ - + ValueSetNodeWithOnlyCodeValidator SHALL @@ -833,7 +834,7 @@ - + ValueSetCodeValidator SHALL @@ -844,7 +845,7 @@ - + ValueSetCodeValidator SHALL @@ -855,7 +856,7 @@ - + UnitValidator SHALL @@ -866,7 +867,7 @@ - + UnitValidator SHALL @@ -879,7 +880,7 @@ - + ValueSetCodeValidator SHALL @@ -892,7 +893,7 @@ - + ValueSetCodeValidator SHALL @@ -905,7 +906,7 @@ - + ValueSetCodeValidator MAY @@ -916,7 +917,7 @@ - + ValueSetCodeValidator SHOULD @@ -929,7 +930,7 @@ - + ValueSetCodeValidator SHOULD @@ -942,7 +943,7 @@ - + ValueSetNodeWithOnlyCodeValidator SHALL @@ -953,7 +954,7 @@ - + ValueSetCodeValidator SHALL @@ -964,7 +965,7 @@ - + ValueSetCodeValidator SHALL @@ -975,7 +976,7 @@ - + UnitValidator SHALL @@ -986,7 +987,7 @@ - + UnitValidator SHALL @@ -997,7 +998,7 @@ - + ValueSetCodeValidator SHALL @@ -1010,7 +1011,7 @@ - + ValueSetCodeValidator SHALL @@ -1023,7 +1024,7 @@ - + ValueSetNodeWithOnlyCodeValidator SHALL @@ -1036,7 +1037,7 @@ - + ValueSetNodeWithOnlyCodeValidator SHALL @@ -1050,7 +1051,7 @@ - + ValueSetCodeValidator SHOULD @@ -1063,7 +1064,7 @@ - + ValueSetCodeValidator SHOULD @@ -1076,7 +1077,7 @@ - + ValueSetCodeValidator SHALL @@ -1087,7 +1088,7 @@ - + ValueSetCodeValidator SHOULD @@ -1098,7 +1099,7 @@ - + ValueSetCodeValidator SHOULD @@ -1111,7 +1112,7 @@ - + ValueSetCodeValidator SHALL @@ -1124,7 +1125,7 @@ - + ValueSetCodeValidator SHOULD @@ -1137,7 +1138,7 @@ - + ValueSetCodeValidator SHALL @@ -1148,7 +1149,7 @@ - + ValueSetCodeValidator SHALL @@ -1159,7 +1160,7 @@ - + UnitValidator SHALL @@ -1172,7 +1173,7 @@ - + ValueSetCodeValidator SHALL @@ -1183,7 +1184,7 @@ - + ValueSetCodeValidator SHALL @@ -1194,7 +1195,7 @@ - + UnitValidator SHALL @@ -1205,7 +1206,7 @@ - + UnitValidator SHALL @@ -1216,7 +1217,7 @@ - + ValueSetCodeValidator SHALL @@ -1229,7 +1230,7 @@ - + ValueSetCodeValidator SHALL @@ -1242,7 +1243,7 @@ - + ValueSetCodeValidator SHALL @@ -1255,7 +1256,7 @@ - + ValueSetCodeValidator SHOULD @@ -1266,7 +1267,7 @@ - + ValueSetCodeValidator SHALL @@ -1277,7 +1278,7 @@ - + ValueSetCodeValidator SHOULD @@ -1290,7 +1291,7 @@ - + ValueSetCodeValidator SHALL @@ -1303,7 +1304,7 @@ - + ValueSetCodeValidator SHOULD @@ -1314,7 +1315,7 @@ - + ValueSetCodeValidator SHOULD @@ -1325,7 +1326,7 @@ - + ValueSetCodeValidator SHALL @@ -1336,14 +1337,14 @@ - + ValueSetCodeValidator SHALL 2.16.840.1.113883.3.88.12.3221.7.4 - + CodeSystemCodeValidator SHALL @@ -1356,7 +1357,7 @@ - + ValueSetCodeValidator SHOULD @@ -1367,7 +1368,7 @@ - + ValueSetCodeValidator SHOULD @@ -1380,7 +1381,7 @@ - + ValueSetCodeValidator SHALL @@ -1403,7 +1404,7 @@ - + ValueSetCodeValidator SHALL @@ -1416,7 +1417,7 @@ - + ValueSetCodeValidator SHALL @@ -1427,7 +1428,7 @@ - + ValueSetCodeValidator SHALL @@ -1441,7 +1442,7 @@ - + CodeSystemCodeValidator SHOULD @@ -1452,7 +1453,7 @@ - + ValueSetCodeValidator SHALL @@ -1463,7 +1464,7 @@ - + ValueSetNodeWithOnlyCodeValidator SHALL @@ -1475,7 +1476,7 @@ - + ValueSetCodeValidator SHALL @@ -1488,7 +1489,7 @@ - + ValueSetCodeValidator SHOULD @@ -1501,7 +1502,7 @@ - + ValueSetCodeValidator SHOULD @@ -1514,7 +1515,7 @@ - + ValueSetCodeValidator SHALL @@ -1528,7 +1529,7 @@ - + CodeSystemCodeValidator SHOULD @@ -1539,7 +1540,7 @@ - + ValueSetNodeWithOnlyCodeValidator SHALL @@ -1550,7 +1551,7 @@ - + UnitValidator SHALL @@ -1564,7 +1565,7 @@ - + CodeSystemCodeValidator SHOULD @@ -1577,7 +1578,7 @@ - + ValueSetCodeValidator SHOULD @@ -1590,7 +1591,7 @@ - + ValueSetCodeValidator SHOULD @@ -1601,7 +1602,7 @@ - + ValueSetCodeValidator SHOULD @@ -1614,7 +1615,7 @@ - + ValueSetCodeValidator SHALL @@ -1626,7 +1627,7 @@ - + UnitValidator SHALL @@ -1639,7 +1640,7 @@ - + ValueSetCodeValidator SHALL @@ -1650,7 +1651,7 @@ - + ValueSetCodeValidator MAY @@ -1663,7 +1664,7 @@ - + ValueSetCodeValidator SHALL @@ -1674,7 +1675,7 @@ - + ValueSetCodeValidator SHALL @@ -1687,7 +1688,7 @@ - + ValueSetCodeValidator SHALL @@ -1700,7 +1701,7 @@ - + ValueSetCodeValidator SHOULD @@ -1711,7 +1712,7 @@ - + UnitValidator SHALL @@ -1724,7 +1725,7 @@ - + ValueSetCodeValidator SHALL @@ -1737,7 +1738,7 @@ - + ValueSetCodeValidator SHALL @@ -1750,7 +1751,7 @@ - + ValueSetCodeValidator SHOULD @@ -1763,7 +1764,7 @@ - + TextNodeValidator SHALL @@ -1775,7 +1776,7 @@ - + TextNodeValidator SHALL @@ -1786,7 +1787,7 @@ - + TextNodeValidator SHOULD @@ -1802,7 +1803,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.6.1 @@ -1813,7 +1814,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.6.1 @@ -1825,7 +1826,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.6.1 @@ -1833,7 +1834,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.5.6 @@ -1841,7 +1842,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.5.4 @@ -1849,7 +1850,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.5.4 @@ -1857,7 +1858,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.6.1 @@ -1865,7 +1866,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.5.4 @@ -1875,7 +1876,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.6.1 @@ -1886,7 +1887,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.6.1 @@ -1897,7 +1898,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.6.1 @@ -1908,7 +1909,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.6.1 @@ -1919,7 +1920,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.6.1 @@ -1931,7 +1932,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.6.1 @@ -1942,7 +1943,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.6.1 @@ -1950,7 +1951,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.5.6 @@ -1962,7 +1963,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.6.1 @@ -1973,7 +1974,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.6.1 @@ -1984,7 +1985,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.6.1 @@ -1995,7 +1996,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.6.1 @@ -2006,7 +2007,7 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.6.1 @@ -2015,11 +2016,1298 @@ - + NodeCodeSystemMatchesConfiguredCodeSystemValidator codeSystem 2.16.840.1.113883.6.96 + + + + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.113883.1.11.16926 + + + + + + LanguageCodeNodeLanguageCodeValuesetValidator + + SHALL + + 2.16.840.1.113883.1.11.11526 + + + + + + LanguageCodeNodeCountryCodeValuesetValidator + + SHALL + + 2.16.840.1.113883.3.88.12.80.63 + + + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.1.11.1 + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.1.11.12212 + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.1.11.19185 + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.1.11.14914 + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.1.11.14914 + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.114222.4.11.837 + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.1.11.19563 + + + + + + + + TextNodeValidator + + SHALL + + 2.16.840.1.113883.3.88.12.80.63 + + + + + + TextNodeValidator + + SHALL + + 2.16.840.1.113883.3.88.12.80.2 + + + + + + TextNodeValidator + + SHALL + + 2.16.840.1.113883.3.88.12.80.1 + + + + + + LanguageCodeNodeLanguageCodeValuesetValidator + + SHALL + + 2.16.840.1.113883.1.11.11526 + + + + + LanguageCodeNodeCountryCodeValuesetValidator + + SHALL + + 2.16.840.1.113883.1.11.11526 + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.1.11.12249 + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.1.11.12199 + + + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.114222.4.11.1066 + + + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.114222.4.11.1066 + + + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.114222.4.11.1066 + + + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.114222.4.11.1066 + + + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.114222.4.11.1066 + + + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.114222.4.11.1066 + + + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.11.20.9.31 + + + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.113883.11.20.9.32 + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.11.20.9.32 + + + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.11.20.4.1 + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.113883.3.88.12.80.33 + + + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.1.11.20.22 + + + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.11.20.1.1 + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.113883.3.88.12.3221.4.2 + + + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.11.20.6.1 + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.114222.4.11.1066 + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.11.20.8.1 + + + + + + UnitValidator + + SHALL + + 2.16.840.1.113883.11.20.9.21 + + + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.3.88.12.80.68 + + + + + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.113883.3.88.12.3221.7.4 + + + + + + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.113883.3.88.12.80.32 + + + + + + ValueSetNodeWithOnlyCodeValidator + + + SHALL + + 2.16.840.1.113883.3.88.12.80.33 + + + + + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.113883.3.88.12.3221.7.2_SNOMED + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.3.88.12.3221.7.4 + + + + + + + + ValueSetNodeWithOnlyCodeValidator + + SHOULD + + 2.16.840.1.113883.1.11.19579 + + + + + + ValueSetNodeWithOnlyCodeValidator + + SHALL + + 2.16.840.1.113883.1.11.1 + + + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.113883.3.88.12.3221.7.4 + + + + + + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.1.11.20.12 + + + + + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.3.88.12.3221.8.7 + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.3.88.12.3221.8.9 + + + + + + UnitValidator + + SHALL + + 2.16.840.1.113883.1.11.12839 + + + + + + UnitValidator + + SHALL + + 2.16.840.1.113883.3.88.12.3221.8.11 + + + + + + + + ValueSetCodeValidator + + SHALL + + + 2.16.840.1.113883.3.88.12.80.22 + + + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.1.11.19717 + + + + + + + + ValueSetCodeValidator + + + SHOULD + + 2.16.840.1.113883.3.88.12.3221.7.2_SNOMED + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.113883.3.88.12.3221.7.4 + + + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.113883.11.20.9.34 + + + + + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.3.88.12.3221.8.7 + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.3.88.12.3221.8.9 + + + + + + UnitValidator + + SHALL + + 2.16.840.1.113883.1.11.12839 + + + + + + UnitValidator + + SHALL + + 2.16.840.1.113883.1.11.12839 + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.3.88.12.3221.8.11 + + + + + + + + ValueSetCodeValidator + + SHALL + + + 2.16.840.1.113883.3.88.12.80.17 + + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.113883.3.88.12.3221.5.2 + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.1.11.10416 + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.113883.1.11.18877 + + + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.113883.3.88.12.3221.7.2_SNOMED + + + + + + ValueSetCodeValidator + + SHOULD + + + 2.16.840.1.113883.3.88.12.3221.7.4 + + + + + + ValueSetCodeValidator + + SHALL + + + 2.16.840.1.113883.3.88.12.3221.7.4 + + + CodeSystemCodeValidator + + SHALL + + ICD10CM + + + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.3.88.12.80.68 + + + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.1.11.16866 + + + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.1.11.16866 + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.3.88.12.3221.8.9 + + + + + + + + + CodeSystemCodeValidator + + SHALL + + CDT,SNOMED-CT + + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.1.11.16866 + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.3.88.12.3221.8.9 + + + + + + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.113883.11.20.9.28 + + + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.113883.11.20.9.29 + + + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.3.88.12.3221.7.4 + + + + + + + + + CodeSystemCodeValidator + + SHOULD + + LOINC + + + + + + ValueSetNodeWithOnlyCodeValidator + + SHALL + + 2.16.840.1.113883.11.20.9.39 + + + + + + + + + + + CodeSystemCodeValidator + + SHOULD + + LOINC + + + + + + + + + + + + + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.3.88.12.3221.6.8 + + + + + + + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.3.88.12.3221.6.2 + + + + + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.3.88.12.3221.6.2 + + + + + + + CodeSystemCodeValidator + + SHALL + + RXNORM + + + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.11.20.9.41 + + + + + + + + ValueSetCodeValidator + + SHOULD + + 2.16.840.1.113883.3.88.12.80.62 + + + + + + + + + + + + + + + + + + + + + + TextNodeValidator + + SHALL + + 2.16.840.1.113883.3.88.12.80.63 + + + + + + + TextNodeValidator + + SHALL + + 2.16.840.1.113883.3.88.12.80.1 + + + + + + TextNodeValidator + + SHOULD + + 2.16.840.1.113883.3.88.12.80.2 + + + + + + + + + + + NodeCodeSystemMatchesConfiguredCodeSystemValidator + codeSystem + 2.16.840.1.113883.6.1 + + + + + + + + + NodeCodeSystemMatchesConfiguredCodeSystemValidator + codeSystem + 2.16.840.1.113883.6.1 + + + + + + + + NodeCodeSystemMatchesConfiguredCodeSystemValidator + codeSystem + 2.16.840.1.113883.6.1 + + + + + + NodeCodeSystemMatchesConfiguredCodeSystemValidator + codeSystem + 2.16.840.1.113883.6.1 + + + + + NodeCodeSystemMatchesConfiguredCodeSystemValidator + codeSystem + 2.16.840.1.113883.6.1 + + + + + NodeCodeSystemMatchesConfiguredCodeSystemValidator + codeSystem + 2.16.840.1.113883.5.4 + + + + + + + NodeCodeSystemMatchesConfiguredCodeSystemValidator + codeSystem + 2.16.840.1.113883.6.1 + + + + + + + + NodeCodeSystemMatchesConfiguredCodeSystemValidator + codeSystem + 2.16.840.1.113883.6.1 + + + + + + + + NodeCodeSystemMatchesConfiguredCodeSystemValidator + codeSystem + 2.16.840.1.113883.6.1 + + + + + + + + + NodeCodeSystemMatchesConfiguredCodeSystemValidator + codeSystem + 2.16.840.1.113883.6.1 + + + + + + + + + NodeCodeSystemMatchesConfiguredCodeSystemValidator + codeSystem + 2.16.840.1.113883.6.1 + + + + + + + + + NodeCodeSystemMatchesConfiguredCodeSystemValidator + codeSystem + 2.16.840.1.113883.6.1 + + + + + + + + + NodeCodeSystemMatchesConfiguredCodeSystemValidator + codeSystem + 2.16.840.1.113883.6.1 + + + + + + NodeCodeSystemMatchesConfiguredCodeSystemValidator + codeSystem + 2.16.840.1.113883.5.6 + + + + + + + + + NodeCodeSystemMatchesConfiguredCodeSystemValidator + codeSystem + 2.16.840.1.113883.6.1 + + + + + + + + + NodeCodeSystemMatchesConfiguredCodeSystemValidator + codeSystem + 2.16.840.1.113883.6.1 + + + + + + + + + NodeCodeSystemMatchesConfiguredCodeSystemValidator + codeSystem + 2.16.840.1.113883.6.1 + + + + + + + + + NodeCodeSystemMatchesConfiguredCodeSystemValidator + codeSystem + 2.16.840.1.113883.6.1 + + + + + + + + + NodeCodeSystemMatchesConfiguredCodeSystemValidator + codeSystem + 2.16.840.1.113883.6.1 + + + + + + NodeCodeSystemMatchesConfiguredCodeSystemValidator + codeSystem + 2.16.840.1.113883.6.96 + + + + + + ValueSetCodeValidator + + SHALL + + 2.16.840.1.113883.1.11.20275 + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index a1cc2a75..e67c12f2 100644 --- a/pom.xml +++ b/pom.xml @@ -2,9 +2,11 @@ 4.0.0 org.sitenv - referenceccdavalidator - 1.0.18 - war + cerner-referenceccdavalidator + 1.0.18-SNAPSHOT + Reference CCDA Validator @@ -12,8 +14,8 @@ 1.7 UTF-8 UTF-8 - 1.0.10 - 1.0.10 + 1.0.10-SNAPSHOT + 1.0.10-SNAPSHOT 3.0.0.20170622 3.0.0.201706220503 @@ -22,7 +24,7 @@ - false + true mdht-libs libs-release @@ -31,12 +33,12 @@ true - + mdht-plugins plugins-release http://devsoap.sitenv.org:8081/artifactory/plugins-release-local - - + + @@ -128,7 +130,7 @@ org.sitenv.vocabulary - codevalidator-api + cerner-codevalidator-api ${code.validator.version} @@ -312,6 +314,17 @@ true + + + org.apache.maven.plugins + maven-compiler-plugin + + + org/sitenv/referenceccda/configuration/ApplicationInitializer.java + + + + org.apache.tomcat.maven tomcat7-maven-plugin @@ -408,6 +421,7 @@ distribution + cerner-referencevalidator-${version} maven-assembly-plugin @@ -436,6 +450,19 @@ **/context.xml + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org/sitenv/referenceccda/configuration/ApplicationInitializer.java + + + + + diff --git a/src/main/java/org/sitenv/referenceccda/assembly/referenceccdaapi.xml b/src/main/java/org/sitenv/referenceccda/assembly/referenceccdaapi.xml index e5a17bce..159d7cdd 100644 --- a/src/main/java/org/sitenv/referenceccda/assembly/referenceccdaapi.xml +++ b/src/main/java/org/sitenv/referenceccda/assembly/referenceccdaapi.xml @@ -21,14 +21,10 @@ configuration ccdaReferenceValidatorConfig.xml - referenceccda-orientdb-server-profiles.xml + referenceccda-orientdb-server-config.xml VocabularyConfiguration - - E:\Brian\Development\Environment\VocabularyConfiguration\scenarios - VocabularyConfiguration\scenarios - E:\Brian\Development\Environment\VocabularyConfiguration\Vocabulary VocabularyConfiguration\Vocabulary diff --git a/src/main/java/org/sitenv/referenceccda/configuration/ApplicationInitializer.java b/src/main/java/org/sitenv/referenceccda/configuration/ApplicationInitializer.java index c2e615cd..5d30d058 100644 --- a/src/main/java/org/sitenv/referenceccda/configuration/ApplicationInitializer.java +++ b/src/main/java/org/sitenv/referenceccda/configuration/ApplicationInitializer.java @@ -1,11 +1,11 @@ package org.sitenv.referenceccda.configuration; +import javax.servlet.ServletContext; + import org.sitenv.contentvalidator.configuration.ContentValidatorApiConfiguration; import org.sitenv.vocabularies.configuration.CodeValidatorApiConfiguration; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; -import javax.servlet.ServletContext; - public class ApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override diff --git a/src/main/java/org/sitenv/referenceccda/configuration/SwaggerConfig.java b/src/main/java/org/sitenv/referenceccda/configuration/SwaggerConfig.java index 92b6f41d..73fee4b6 100644 --- a/src/main/java/org/sitenv/referenceccda/configuration/SwaggerConfig.java +++ b/src/main/java/org/sitenv/referenceccda/configuration/SwaggerConfig.java @@ -3,6 +3,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; + import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; diff --git a/src/main/java/org/sitenv/referenceccda/controllers/ReferenceCCDAValidationController.java b/src/main/java/org/sitenv/referenceccda/controllers/ReferenceCCDAValidationController.java index 65358d3e..910e7486 100644 --- a/src/main/java/org/sitenv/referenceccda/controllers/ReferenceCCDAValidationController.java +++ b/src/main/java/org/sitenv/referenceccda/controllers/ReferenceCCDAValidationController.java @@ -1,8 +1,14 @@ package org.sitenv.referenceccda.controllers; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + import org.sitenv.referenceccda.dto.ValidationResultsDto; import org.sitenv.referenceccda.services.ReferenceCCDAValidationService; import org.sitenv.referenceccda.services.VocabularyService; +import org.sitenv.referenceccda.validators.schema.CCDATypes; +import org.sitenv.referenceccda.validators.schema.OCLLoader; import org.sitenv.vocabularies.validation.entities.Code; import org.sitenv.vocabularies.validation.entities.VsacValueSet; import org.sitenv.vocabularies.validation.services.VocabularyValidationService; @@ -14,12 +20,10 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; -import java.util.Arrays; -import java.util.List; -import java.util.Map; @RestController public class ReferenceCCDAValidationController { + @Autowired ReferenceCCDAValidationService referenceCcdaValidationService; @Autowired @@ -33,8 +37,12 @@ public class ReferenceCCDAValidationController { public ValidationResultsDto doValidation( @RequestParam(value = "validationObjective", required = true) String validationObjective, @RequestParam(value = "referenceFileName", required = true) String referenceFileName, - @RequestParam(value = "ccdaFile", required = true) MultipartFile ccdaFile) { - return referenceCcdaValidationService.validateCCDA(validationObjective, referenceFileName, ccdaFile); + @RequestParam(value = "ccdaFile", required = true) MultipartFile ccdaFile, + @RequestParam(value = "severityLevel", required = false, defaultValue = "info") String severityLevel) { + if (severityLevel==null || severityLevel.equals("")) { + severityLevel="info"; + } + return referenceCcdaValidationService.validateCCDA(validationObjective, referenceFileName, ccdaFile, severityLevel); } @RequestMapping(value = "/getvaluesetsbyoids", method = RequestMethod.GET) @@ -73,4 +81,40 @@ public Map>> getMapOfSenderAndRecieverValidatio return vocabularyService.getMapOfSenderAndRecieverValidationObjectivesWithReferenceFiles(); } + /* + * Following Method is added to support CCDA validation on file reference. + * ccdaReferenceFileName parameter will the file reference path to the CCDA file cache. + * The file cache must be shared and accessible to the service. + */ + //------------------------- INTERNAL CODE CHANGE START -------------------------- + + /* + * Following method is another flavor to validate a CDA document by file. + * Additional parameter severityLevel is passed to filter the results based on the severity. + */ + @RequestMapping(value = "/validateDocumentByFile", headers = "content-type=multipart/*", method = RequestMethod.POST) + public ValidationResultsDto doValidation( + @RequestParam(value = "validationObjective", required = true) String validationObjective, + @RequestParam(value = "referenceFileName", required = true) String referenceFileName, + @RequestParam(value = "ccdaFile", required = true) MultipartFile ccdaFile, + @RequestParam(value = "severityLevel", required = true, defaultValue = "Error") String severityLevel, + @RequestParam(value = "performMDHTValidation", required = false, defaultValue = "true") boolean performMDHTValidation, + @RequestParam(value = "performVocabularyValidation", required = false, defaultValue = "true") boolean performVocabularyValidation, + @RequestParam(value = "performContentValidation", required = false, defaultValue = "false") boolean performContentValidation, + @RequestParam(value = "defaultR21ValidationObjective", required = false, defaultValue = CCDATypes.NON_SPECIFIC_CCDAR2) String defaultR21ValidationObjective, + @RequestParam(value = "defaultR11ValidationObjective", required = false, defaultValue = CCDATypes.NON_SPECIFIC_CCDAR2) String defaultR11ValidationObjective + ) { + + return referenceCcdaValidationService.validateCCDA(validationObjective, referenceFileName, ccdaFile,severityLevel.toUpperCase(), + performMDHTValidation, performVocabularyValidation, performContentValidation, defaultR21ValidationObjective, defaultR11ValidationObjective); + } + + @RequestMapping(value = "/initOCL", method = RequestMethod.GET) + public Map doIniOCL() { + + return OCLLoader.loadocl(); + } + +//------------------------- INTERNAL CODE CHANGE END -------------------------- + } diff --git a/src/main/java/org/sitenv/referenceccda/dto/ResultMetaData.java b/src/main/java/org/sitenv/referenceccda/dto/ResultMetaData.java index 2b10f618..fdedb083 100644 --- a/src/main/java/org/sitenv/referenceccda/dto/ResultMetaData.java +++ b/src/main/java/org/sitenv/referenceccda/dto/ResultMetaData.java @@ -8,7 +8,7 @@ public ResultMetaData(String type, int count) { this.type = type; this.count = count; } - + public String getType() { return type; } @@ -25,6 +25,25 @@ public void setCount(int count) { this.count = count; } + // ------------------------- INTERNAL CODE CHANGE START + private String severity; + + public ResultMetaData(String type, int count, String severity) { + this(type, count); + this.severity = severity; + } + + + public String getSeverity() { + return severity; + } + + public void setSeverity(String severity) { + this.severity = severity; + } + + // ------------------------- INTERNAL CODE CHANGE END + @Override public int hashCode() { final int prime = 31; diff --git a/src/main/java/org/sitenv/referenceccda/dto/ValidationResultsDto.java b/src/main/java/org/sitenv/referenceccda/dto/ValidationResultsDto.java index 54f978ed..070d1f40 100644 --- a/src/main/java/org/sitenv/referenceccda/dto/ValidationResultsDto.java +++ b/src/main/java/org/sitenv/referenceccda/dto/ValidationResultsDto.java @@ -1,9 +1,9 @@ package org.sitenv.referenceccda.dto; -import org.sitenv.referenceccda.validators.RefCCDAValidationResult; - import java.util.List; +import org.sitenv.referenceccda.validators.RefCCDAValidationResult; + public class ValidationResultsDto { private ValidationResultsMetaData resultsMetaData; private List ccdaValidationResults; diff --git a/src/main/java/org/sitenv/referenceccda/dto/ValidationResultsMetaData.java b/src/main/java/org/sitenv/referenceccda/dto/ValidationResultsMetaData.java index f030418f..01f799c3 100644 --- a/src/main/java/org/sitenv/referenceccda/dto/ValidationResultsMetaData.java +++ b/src/main/java/org/sitenv/referenceccda/dto/ValidationResultsMetaData.java @@ -1,13 +1,16 @@ package org.sitenv.referenceccda.dto; -import org.sitenv.referenceccda.validators.enums.ValidationResultType; - import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; +import org.apache.commons.lang3.StringUtils; +import org.sitenv.referenceccda.validators.enums.ValidationResultType; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; public class ValidationResultsMetaData { private String ccdaDocumentType; @@ -17,7 +20,7 @@ public class ValidationResultsMetaData { private String ccdaFileContents; private final Map errorCounts = new LinkedHashMap(); private List resultMetaData; - + public ValidationResultsMetaData() { for (ValidationResultType resultType : ValidationResultType.values()) { errorCounts.put(resultType.getTypePrettyName(), new AtomicInteger(0)); @@ -48,6 +51,50 @@ public void setServiceErrorMessage(String serviceErrorMessage) { this.serviceErrorMessage = serviceErrorMessage; } + // ------------------------- INTERNAL CODE CHANGE START + private static final String INFO = "INFO"; + private static final String WARNING = "WARNING"; + private static final String ERROR = "ERROR"; + private boolean isValid; + private String cdaSchemaValidationErrorMessage; + + @JsonProperty("isValid") + public boolean isValid() { + return isValid; + } + + public void setValid(boolean isValid) { + this.isValid = isValid; + } + + @JsonProperty("resultMetaData") + public List getCustomResultMetaData() { + resultMetaData = new ArrayList(); + for (Map.Entry entry : errorCounts.entrySet()) { + resultMetaData.add(new ResultMetaData(entry.getKey(), entry.getValue().intValue(), getSeverityType(entry.getKey()))); + } + return resultMetaData; + } + + + private String getSeverityType(String key) { + String severityType = (StringUtils.containsIgnoreCase(key, ERROR)) ? ERROR + : (StringUtils.containsIgnoreCase(key, WARNING)) ? WARNING : INFO; + + return severityType; + } + + public String getCdaSchemaValidationErrorMessage() { + return cdaSchemaValidationErrorMessage; + } + + public void setCdaSchemaValidationErrorMessage( + String cdaSchemaValidationErrorMessage) { + this.cdaSchemaValidationErrorMessage = cdaSchemaValidationErrorMessage; + } + + @JsonIgnore + // ------------------------- INTERNAL CODE CHANGE END public List getResultMetaData() { resultMetaData = new ArrayList(); for (Map.Entry entry : errorCounts.entrySet()) { @@ -55,7 +102,7 @@ public List getResultMetaData() { } return resultMetaData; } - + public String getCcdaFileName() { return ccdaFileName; } @@ -71,7 +118,6 @@ public String getCcdaFileContents() { public void setCcdaFileContents(String ccdaFileContents) { this.ccdaFileContents = ccdaFileContents; } - public void addCount(ValidationResultType resultType) { if (errorCounts.containsKey(resultType.getTypePrettyName())) { errorCounts.get(resultType.getTypePrettyName()).addAndGet(1); @@ -79,4 +125,5 @@ public void addCount(ValidationResultType resultType) { errorCounts.put(resultType.getTypePrettyName(), new AtomicInteger(1)); } } + } diff --git a/src/main/java/org/sitenv/referenceccda/services/ReferenceCCDAValidationService.java b/src/main/java/org/sitenv/referenceccda/services/ReferenceCCDAValidationService.java index 21fad65e..98ff0429 100644 --- a/src/main/java/org/sitenv/referenceccda/services/ReferenceCCDAValidationService.java +++ b/src/main/java/org/sitenv/referenceccda/services/ReferenceCCDAValidationService.java @@ -1,31 +1,51 @@ package org.sitenv.referenceccda.services; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; +import java.util.zip.ZipInputStream; + +import javax.annotation.Resource; +import javax.xml.namespace.NamespaceContext; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; import org.apache.commons.io.IOUtils; import org.apache.commons.io.input.BOMInputStream; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.log4j.Logger; +import org.sitenv.referenceccda.dto.ResultMetaData; import org.sitenv.referenceccda.dto.ValidationResultsDto; import org.sitenv.referenceccda.dto.ValidationResultsMetaData; import org.sitenv.referenceccda.validators.RefCCDAValidationResult; import org.sitenv.referenceccda.validators.content.ReferenceContentValidator; +import org.sitenv.referenceccda.validators.enums.ValidationResultType; import org.sitenv.referenceccda.validators.schema.CCDATypes; import org.sitenv.referenceccda.validators.schema.ReferenceCCDAValidator; import org.sitenv.referenceccda.validators.schema.ValidationObjectives; import org.sitenv.referenceccda.validators.vocabulary.VocabularyCCDAValidator; +import org.sitenv.vocabularies.validation.utils.CCDADocumentNamespaces; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.mock.web.MockMultipartFile; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; +import org.w3c.dom.Document; import org.xml.sax.SAXException; @Service public class ReferenceCCDAValidationService { - private static Logger logger = Logger.getLogger(ReferenceCCDAValidationService.class); - + private static Logger logger = Logger.getLogger(ReferenceCCDAValidationService.class); + private ReferenceCCDAValidator referenceCCDAValidator; private VocabularyCCDAValidator vocabularyCCDAValidator; private ReferenceContentValidator goldMatchingValidator; @@ -40,6 +60,16 @@ public class ReferenceCCDAValidationService { private static final String ERROR_SAX_PARSE_EXCEPTION = ERROR_PARSING_PREFIX + "Please verify the document does not contain in-line XSL styling and/or address " + ERROR_FOLLOWING_ERROR_POSTFIX; private static final String ERROR_GENERIC_EXCEPTION = ERROR_GENERAL_PREFIX + ERROR_FOLLOWING_ERROR_POSTFIX; + + @Resource(name = "documentBuilderFactory") + DocumentBuilderFactory documentBuilderFactory; + + @Resource(name = "xPathFactory") + XPathFactory xPathFactory; + + private DocumentBuilder getDocumentBuilder() throws ParserConfigurationException { + return documentBuilderFactory.newDocumentBuilder(); + } @Autowired public ReferenceCCDAValidationService(ReferenceCCDAValidator referenceCCDAValidator, VocabularyCCDAValidator vocabularyCCDAValidator, @@ -48,34 +78,81 @@ public ReferenceCCDAValidationService(ReferenceCCDAValidator referenceCCDAValida this.vocabularyCCDAValidator = vocabularyCCDAValidator; this.goldMatchingValidator = goldValidator; } + + public ValidationResultsDto validateCCDA(String validationObjective, String referenceFileName, + MultipartFile ccdaFile, String severityLevel) { + return validateCCDA(validationObjective, referenceFileName, ccdaFile, severityLevel, true, null, null); + } - public ValidationResultsDto validateCCDA(String validationObjective, String referenceFileName, MultipartFile ccdaFile) { - ValidationResultsDto resultsDto = new ValidationResultsDto(); - ValidationResultsMetaData resultsMetaData = new ValidationResultsMetaData(); - List validatorResults = new ArrayList<>(); - try { - validatorResults = runValidators(validationObjective, referenceFileName, ccdaFile); - resultsMetaData = buildValidationMedata(validatorResults, validationObjective); - resultsMetaData.setCcdaFileName(ccdaFile.getName()); - resultsMetaData.setCcdaFileContents(new String(ccdaFile.getBytes())); - } catch (IOException ioE) { - processValidateCCDAException(resultsMetaData, + public ValidationResultsDto validateCCDA(String validationObjective, String referenceFileName, + MultipartFile ccdaFile, String severityLevel, boolean performContentValidation, + String defaultR21ValidationObjective, String defaultR11ValidationObjective) { + ValidationResultsDto resultsDto = new ValidationResultsDto(); + ValidationResultsMetaData resultsMetaData = new ValidationResultsMetaData(); + List validatorResults = new ArrayList<>(); + + try { + validatorResults = runValidators(validationObjective, referenceFileName, ccdaFile, severityLevel, + performContentValidation, defaultR21ValidationObjective, defaultR11ValidationObjective); + resultsMetaData = buildValidationMedata(validatorResults, validationObjective); + resultsMetaData.setCcdaFileName(ccdaFile.getName()); + resultsMetaData.setCcdaFileContents(new String(ccdaFile.getBytes())); + + // ------------------------- INTERNAL CODE CHANGE START + setDocumentValidity(resultsMetaData); + // ------------------------- INTERNAL CODE CHANGE END + } catch (IOException ioE) { + processValidateCCDAException(resultsMetaData, ERROR_IO_EXCEPTION, validationObjective, ioE); - } catch (SAXException saxE) { - processValidateCCDAException(resultsMetaData, + } catch (SAXException saxE) { + processValidateCCDAException(resultsMetaData, ERROR_SAX_PARSE_EXCEPTION, validationObjective, saxE); + // ------------------------- INTERNAL CODE CHANGE START +// resultsMetaData.setServiceError(false); +// resultsMetaData.setServiceErrorMessage("No service error occurred but recieved an invalid XML document. Error Message :- " + saxE.getMessage()); +// resultsMetaData.setValid(false); +// resultsMetaData.setCdaSchemaValidationErrorMessage(saxE.getMessage()); + // ------------------------- INTERNAL CODE CHANGE END +// resultsMetaData.setCcdaDocumentType(validationObjective); } catch (ClassCastException ccE) { processValidateCCDAException(resultsMetaData, ERROR_CLASS_CAST_EXCEPTION, validationObjective, ccE); } catch (Exception catchAllE) { processValidateCCDAException(resultsMetaData, ERROR_GENERIC_EXCEPTION, validationObjective, catchAllE); - } - resultsDto.setResultsMetaData(resultsMetaData); - resultsDto.setCcdaValidationResults(validatorResults); - return resultsDto; - } - + } + resultsDto.setResultsMetaData(resultsMetaData); + resultsDto.setCcdaValidationResults(validatorResults); + return resultsDto; + } + + protected XPath getNewXpath(final Document doc) { + XPath xpath = xPathFactory.newXPath(); + xpath.setNamespaceContext(new NamespaceContext() { + @Override + public String getNamespaceURI(String prefix) { + String nameSpace; + if (CCDADocumentNamespaces.sdtc.name().equals(prefix)) { + nameSpace = CCDADocumentNamespaces.sdtc.getNamespace(); + } else { + nameSpace = CCDADocumentNamespaces.defaultNameSpaceForCcda.getNamespace(); + } + return nameSpace; + } + + @Override + public String getPrefix(String namespaceURI) { + return null; + } + + @Override + public Iterator getPrefixes(String namespaceURI) { + return null; + } + }); + return xpath; + } + private static void processValidateCCDAException(ValidationResultsMetaData resultsMetaData, String serviceErrorStart, String validationObjective, Exception exception) { resultsMetaData.setServiceError(true); @@ -90,56 +167,115 @@ private static void processValidateCCDAException(ValidationResultsMetaData resul } resultsMetaData.setCcdaDocumentType(validationObjective); } - - private List runValidators(String validationObjective, String referenceFileName, - MultipartFile ccdaFile) throws SAXException, Exception { - List validatorResults = new ArrayList<>(); - InputStream ccdaFileInputStream = null; - try { - ccdaFileInputStream = ccdaFile.getInputStream(); - String ccdaFileContents = IOUtils.toString(new BOMInputStream(ccdaFileInputStream)); - - List mdhtResults = doMDHTValidation(validationObjective, referenceFileName, ccdaFileContents); - if(mdhtResults != null && !mdhtResults.isEmpty()) { + + private List runValidators(String validationObjective, String referenceFileName, + MultipartFile ccdaFile, String severityLevel, boolean performContentValidation, + String defaultR21ValidationObjective, String defaultR11ValidationObjective) + throws SAXException, Exception { + + List validatorResults = new ArrayList<>(); + InputStream ccdaFileInputStream = null; + try { + ccdaFileInputStream = ccdaFile.getInputStream(); + String ccdaFileContents = IOUtils.toString(new BOMInputStream(ccdaFileInputStream)); + + validationObjective = defaultValidationObjectiveIfEmpty(validationObjective, defaultR21ValidationObjective, + defaultR11ValidationObjective, ccdaFileContents); + + List mdhtResults = doMDHTValidation(validationObjective, referenceFileName, ccdaFileContents, severityLevel); + if (mdhtResults != null && !mdhtResults.isEmpty()) { logger.info("Adding MDHT results"); - validatorResults.addAll(mdhtResults); - } - + validatorResults.addAll(mdhtResults); + } + boolean isSchemaErrorInMdhtResults = mdhtResultsHaveSchemaError(mdhtResults); boolean isObjectiveAllowingVocabularyValidation = objectiveAllowsVocabularyValidation(validationObjective); - if (!isSchemaErrorInMdhtResults && isObjectiveAllowingVocabularyValidation) { - List vocabResults = doVocabularyValidation(validationObjective, referenceFileName, ccdaFileContents); - if(vocabResults != null && !vocabResults.isEmpty()) { - logger.info("Adding Vocabulary results"); - validatorResults.addAll(vocabResults); - } - - if(objectiveAllowsContentValidation(validationObjective)) { - List contentResults = doContentValidation(validationObjective, referenceFileName, ccdaFileContents); - if(contentResults != null && !contentResults.isEmpty()) { - logger.info("Adding Content results"); - validatorResults.addAll(contentResults); - } - } else { - logger.info("Skipping Content validation due to: " - + "validationObjective (" + (validationObjective != null ? validationObjective : "null objective") - + ") is not relevant or valid for Content validation"); - } - } else { - String separator = !isObjectiveAllowingVocabularyValidation && isSchemaErrorInMdhtResults ? " and " : ""; - logger.info("Skipping Vocabulary (and thus Content) validation due to: " - + (isObjectiveAllowingVocabularyValidation ? "" : "validationObjective POSTed: " - + (validationObjective != null ? validationObjective : "null objective") + separator) - + (isSchemaErrorInMdhtResults ? "C-CDA Schema error(s) found" : "")); - } - } catch (IOException e) { - throw new RuntimeException("Error getting CCDA contents from provided file", e); - }finally { - closeFileInputStream(ccdaFileInputStream); - } - return validatorResults; - } - + + if (isSchemaErrorInMdhtResults) { + logger.warn("Doc has schemaError, still do Vocab Validation"); + } + + List vocabResults = doVocabularyValidation(validationObjective, referenceFileName, ccdaFileContents, severityLevel); + if (vocabResults != null && !vocabResults.isEmpty()){ + logger.info("Adding Vocabulary results"); + validatorResults.addAll(vocabResults); + } + + // ETT TODO? Pass defaultValidationObjective to doContentValidation(...) + if(performContentValidation && objectiveAllowsContentValidation(validationObjective)) { + List contentResults = doContentValidation(validationObjective, referenceFileName, ccdaFileContents, severityLevel); + if (contentResults != null && !contentResults.isEmpty()) { + logger.info("Adding Content results"); + validatorResults.addAll(contentResults); + } + } else { + logger.info("Skipping Content validation due to: " + + "validationObjective (" + (validationObjective != null ? validationObjective : "null objective") + + ") is not relevant or valid for Content validation"); + } + } catch (IOException e) { + logger.error("runValidators failed: " + e); + throw new RuntimeException("Error getting CCDA contents from provided file", e); + } finally { + if(ccdaFileInputStream != null) { + closeFileInputStream(ccdaFileInputStream); + } + } + return validatorResults; + } + + private String defaultValidationObjectiveIfEmpty(String validationObjective, String defaultR21ValidationObjective, + String defaultR11ValidationObjective, String ccdaFileContents) + throws IOException, SAXException, ParserConfigurationException, XPathExpressionException { + + if(StringUtils.isEmpty(validationObjective) && (!StringUtils.isEmpty(defaultR11ValidationObjective) + || !StringUtils.isEmpty(defaultR21ValidationObjective))) { + + if(defaultR11ValidationObjective.equalsIgnoreCase(defaultR21ValidationObjective)) { + validationObjective = defaultR21ValidationObjective; + } else { + + InputStream inputStream = IOUtils.toInputStream(ccdaFileContents, "UTF-8"); + + Document doc = getDocumentBuilder().parse(inputStream); + + XPath xpath = getNewXpath(doc); + boolean isR11Doc = isDocumentR11CCDA(doc, xpath); + + validationObjective = isR11Doc ? defaultR11ValidationObjective : defaultR21ValidationObjective; + + logger.debug("defaultR21ValidationObjective = " + defaultR21ValidationObjective); + logger.debug("defaultR11ValidationObjective = " + defaultR11ValidationObjective); + + StringBuilder msg = new StringBuilder("The validationObjective given is "); + msg.append(validationObjective == null ? "null" : "empty"); + msg.append(", isR11Doc = "); + msg.append(isR11Doc); + msg.append(", setting validationObjective to "); + msg.append(validationObjective); + logger.warn(msg.toString()); + } + } + + logger.debug("validationObjective = " + validationObjective); + return validationObjective; + } + + private boolean isDocumentR11CCDA(Document doc, XPath xpath) throws XPathExpressionException { + boolean isR11CCDA = false; + Number num = (Number) xpath + .compile("count(/v3:ClinicalDocument/v3:templateId[@root='2.16.840.1.113883.10.20.22.1.1']/@extension)") + .evaluate(doc, XPathConstants.NUMBER); + + if (num.intValue() == 0) {// MU2 CCDA R1.1 document + logger.debug("Validating an MU2 CCDA R1.1 document"); + isR11CCDA = true; + } else { + logger.debug("Validating an MU3 CCDA R2.1 document"); + } + return isR11CCDA; + } + private boolean mdhtResultsHaveSchemaError(List mdhtResults) { for(RefCCDAValidationResult result : mdhtResults){ if(result.isSchemaError()){ @@ -147,8 +283,8 @@ private boolean mdhtResultsHaveSchemaError(List mdhtRes } } return false; - } - + } + private boolean objectiveAllowsVocabularyValidation(String validationObjective) { return !validationObjective.equalsIgnoreCase(ValidationObjectives.Sender.C_CDA_IG_ONLY) && !referenceCCDAValidator.isValidationObjectiveMu2Type() @@ -160,37 +296,317 @@ private boolean objectiveAllowsContentValidation(String validationObjective) { ValidationObjectives.ALL_UNIQUE_CONTENT_ONLY); } - private List doMDHTValidation(String validationObjective, String referenceFileName, String ccdaFileContents) throws SAXException, Exception { - logger.info("Attempting MDHT validation..."); - return referenceCCDAValidator.validateFile(validationObjective, referenceFileName, ccdaFileContents); - } - - private ArrayList doVocabularyValidation(String validationObjective, String referenceFileName, String ccdaFileContents) throws SAXException { + private List doMDHTValidation(String validationObjective, String referenceFileName, + String ccdaFileContents, String severityLevel) + throws SAXException, Exception { + logger.info("Attempting MDHT validation..."); + return referenceCCDAValidator.validateFile(validationObjective, referenceFileName, ccdaFileContents, severityLevel); + } + + private ArrayList doVocabularyValidation(String validationObjective, + String referenceFileName, String ccdaFileContents, String severityLevel) + throws SAXException, ParserConfigurationException { logger.info("Attempting Vocabulary validation..."); - return vocabularyCCDAValidator.validateFile(validationObjective, referenceFileName, ccdaFileContents); - } - - private List doContentValidation(String validationObjective, String referenceFileName, String ccdaFileContents) throws SAXException { + return vocabularyCCDAValidator.validateFile(validationObjective, referenceFileName, ccdaFileContents, severityLevel); + } + + private List doContentValidation(String validationObjective, String referenceFileName, String ccdaFileContents, + String severityLevel) throws SAXException { logger.info("Attempting Content validation..."); - return goldMatchingValidator.validateFile(validationObjective, referenceFileName, ccdaFileContents); + return goldMatchingValidator.validateFile(validationObjective, referenceFileName, ccdaFileContents, severityLevel); } - private ValidationResultsMetaData buildValidationMedata(List validatorResults, String ccdaDocType) { - ValidationResultsMetaData resultsMetaData = new ValidationResultsMetaData(); - for (RefCCDAValidationResult result : validatorResults) { - resultsMetaData.addCount(result.getType()); - } - resultsMetaData.setCcdaDocumentType(ccdaDocType); - return resultsMetaData; - } + private ValidationResultsMetaData buildValidationMedata(List validatorResults, + String ccdaDocType) { + ValidationResultsMetaData resultsMetaData = new ValidationResultsMetaData(); + for (RefCCDAValidationResult result : validatorResults) { + resultsMetaData.addCount(result.getType()); + } + resultsMetaData.setCcdaDocumentType(ccdaDocType); + return resultsMetaData; + } - private void closeFileInputStream(InputStream fileIs) { - if (fileIs != null) { - try { - fileIs.close(); - } catch (IOException e) { - throw new RuntimeException("Error closing CCDA file input stream", e); - } - } - } + private void closeFileInputStream(InputStream fileIs) { + if (fileIs != null) { + try { + fileIs.close(); + } catch (IOException e) { + throw new RuntimeException("Error closing CCDA file input stream", e); + } + } + } + + /* + * Following Method is added to support CCDA validation on file reference. + * ccdaReferenceFileName parameter will contains the file reference path to + * the CCDA file cache. The file cache must be shared and accessible to the + * service. + */ + // ------------------------- INTERNAL CODE CHANGE START + // -------------------------- + + public ValidationResultsDto validateCCDA(String validationObjective, String referenceFileName, + String ccdaReferenceFileName, String severityLevel, boolean performContentValidation, + String defaultR21ValidationObjective, String defaultR11ValidationObjective) { + + MockMultipartFile multipartFile; + try { + File file = new File(ccdaReferenceFileName); + InputStream targetStream = new FileInputStream(file); + multipartFile = new MockMultipartFile("ccdaFile", targetStream); + + // MockMultipartFile is purposely used to support for file to + // Multipart + // conversion rather than the code specified in the comment. + // The commented code is producing a fatal exception '[Fatal Error] + // :1:1: Premature end of file'. + + /* + * + * DiskFileItem fileItem = new DiskFileItem("file", "text/xml", + * false, file.getName(), (int) file.length(), + * file.getParentFile()); try { fileItem.getOutputStream(); } catch + * (IOException e) { throw new RuntimeException( + * "Error getting CCDA contents from provided file", e); } + * MultipartFile multipartFile = new CommonsMultipartFile(fileItem); + * + */ + + } catch (Exception e) { + logger.error("runValidators failed: " + e); + throw new RuntimeException("Error getting CCDA contents from provided file", e); + } + return validateCCDA(validationObjective, referenceFileName, multipartFile, severityLevel, + performContentValidation, defaultR21ValidationObjective, defaultR11ValidationObjective); + } + + /* + * This is an overloaded method that accepts multipartFile for CCDA validation. + * Additionally it will accept severityLevel. The results are filtered based on the + * serverityLevel passed. + */ + public ValidationResultsDto validateCCDA(String validationObjective, String referenceFileName, + MultipartFile ccdaFile, String severityLevel, boolean performMDHTValidation, boolean performVocabularyValidation, + boolean performContentValidation, String defaultR21ValidationObjective, String defaultR11ValidationObjective) { + + ValidationResultsDto resultsDto = new ValidationResultsDto(); + + ValidationResultsMetaData resultsMetaData = new ValidationResultsMetaData(); + List validatorResults = new ArrayList<>(); + + String threadId = Thread.currentThread().getName() + "-" + System.currentTimeMillis() + "-" + ccdaFile.getSize(); + StringBuilder out = new StringBuilder(threadId); + + try { + long startTime = System.currentTimeMillis(); + + validatorResults = runValidators(validationObjective, referenceFileName, ccdaFile, severityLevel, + performMDHTValidation, performVocabularyValidation, performContentValidation, out, + defaultR21ValidationObjective, defaultR11ValidationObjective); + + long stopTime = System.currentTimeMillis(); + + out.append(" runValidators: " + (stopTime - startTime) + " ms," ); + + startTime = stopTime; + + resultsMetaData = buildValidationMedata(validatorResults, validationObjective); + + resultsMetaData.setCcdaFileName(ccdaFile.getOriginalFilename()); + resultsMetaData.setCcdaFileContents(new String(ccdaFile.getBytes())); + + stopTime = System.currentTimeMillis(); + out.append(" buildValidationMedata: " + (stopTime - startTime) + " ms"); + + setDocumentValidity(resultsMetaData); + logger.info(out.toString()); + + } catch (SAXException e) { + resultsMetaData.setServiceError(false); + resultsMetaData.setServiceErrorMessage(null); + resultsMetaData.setCcdaDocumentType(validationObjective); + resultsMetaData.setValid(false); + resultsMetaData.setCdaSchemaValidationErrorMessage(e.getMessage()); + } catch (Exception e) { + resultsMetaData.setServiceError(false); + resultsMetaData.setServiceErrorMessage(null); + resultsMetaData.setCcdaDocumentType(validationObjective); + resultsMetaData.setValid(false); + resultsMetaData.setCdaSchemaValidationErrorMessage(e.getMessage()); + } + + resultsDto.setResultsMetaData(resultsMetaData); + resultsDto.setCcdaValidationResults(validatorResults); + + return resultsDto; + } + + private void setDocumentValidity(ValidationResultsMetaData resultsMetaData) { + boolean isDocValid = true; + List resultMetaData = resultsMetaData.getResultMetaData(); + for (Iterator iterator = resultMetaData.iterator(); iterator.hasNext();) { + ResultMetaData eachResultMetaData = (ResultMetaData) iterator.next(); + if(StringUtils.containsIgnoreCase(eachResultMetaData.getType(), ERROR) && eachResultMetaData.getCount() > 0) { + isDocValid = false; + break; + } + } + resultsMetaData.setValid(isDocValid); + } + + public class ZippedFileInputStream extends InputStream { + + private ZipInputStream is; + + public ZippedFileInputStream(ZipInputStream is){ + this.is = is; + } + + @Override + public int read() throws IOException { + return is.read(); + } + + @Override + public void close() throws IOException { + is.closeEntry(); + } + } + + private List runValidators(String validationObjective, String referenceFileName, + MultipartFile ccdaFile, String severityLevel,boolean performMDHTValidation, boolean performVocabularyValidation, + boolean performContentValidation, StringBuilder out, String defaultR21ValidationObjective, String defaultR11ValidationObjective) throws SAXException, Exception { + + List validatorResults = new ArrayList<>(); + List filterResults = new ArrayList(); + String ccdaFileContents=""; + + try { + long startTime = System.currentTimeMillis(); + + if (ccdaFile.getOriginalFilename().toLowerCase().endsWith(".zip")) { + ZipInputStream zis = new ZipInputStream(ccdaFile.getInputStream()); + while (zis.getNextEntry() != null && ccdaFileContents.length()==0) { + ccdaFileContents = IOUtils.toString(new BOMInputStream(new ZippedFileInputStream(zis))); + } + } else { + ccdaFileContents = IOUtils.toString(new BOMInputStream(ccdaFile.getInputStream())); + } + + long stopTime = System.currentTimeMillis(); + + out.append(" DoctoString:" + (stopTime - startTime) + " ms, "); + + validationObjective = defaultValidationObjectiveIfEmpty(validationObjective, defaultR21ValidationObjective, + defaultR11ValidationObjective, ccdaFileContents); + + boolean isObjectiveAllowingVocabularyValidation = objectiveAllowsVocabularyValidation(validationObjective); + boolean isSchemaErrorInMdhtResults = false; + if (performMDHTValidation) { + + startTime = System.currentTimeMillis(); + + List mdhtResults = doMDHTValidation(validationObjective, referenceFileName, ccdaFileContents, severityLevel); + if(mdhtResults != null && !mdhtResults.isEmpty()) { + logger.info("Adding MDHT results"); + validatorResults.addAll(mdhtResults); + } + + stopTime = System.currentTimeMillis(); + out.append(" MDHT:" + (stopTime - startTime) + " ms, "); + + isSchemaErrorInMdhtResults = mdhtResultsHaveSchemaError(mdhtResults); + + if (isSchemaErrorInMdhtResults) { + logger.warn("Doc has schemaError, still do Vocab Validation"); + } + } + + if (performVocabularyValidation || objectiveAllowsContentValidation(validationObjective)) { + + startTime = System.currentTimeMillis(); + + if (performVocabularyValidation) { + List vocabResults = doVocabularyValidation(validationObjective, referenceFileName, ccdaFileContents, severityLevel); + + if(vocabResults != null && !vocabResults.isEmpty()) { + logger.info("Adding Vocabulary results"); + validatorResults.addAll(vocabResults); + } + } + + stopTime = System.currentTimeMillis(); + out.append(" Vocab:" + (stopTime - startTime) + " ms, " ); + + if (objectiveAllowsContentValidation(validationObjective) && performContentValidation) { + List contentResults = doContentValidation(validationObjective, referenceFileName, ccdaFileContents, severityLevel); + if(contentResults != null && !contentResults.isEmpty()) { + logger.info("Adding Content results"); + validatorResults.addAll(contentResults); + } + } else { + logger.info("Skipping Content validation due to: " + + "validationObjective (" + (validationObjective != null ? validationObjective : "null objective") + + ") is not relevant or valid for Content validation " + + (!performContentValidation ? " (suppressed by performContentValidation=false)" : "")); + } + + } else { + String separator = !isObjectiveAllowingVocabularyValidation && isSchemaErrorInMdhtResults ? " and " : ""; + logger.info("Skipping Vocabulary (and thus Content) validation due to: " + + (isObjectiveAllowingVocabularyValidation ? "" : "validationObjective POSTed: " + + (validationObjective != null ? validationObjective : "null objective") + separator) + + (isSchemaErrorInMdhtResults ? "C-CDA Schema error(s) found" : "")); + } + + startTime = System.currentTimeMillis(); + + filterResults = filterResultsOnSeverity(validatorResults, severityLevel); + + stopTime = System.currentTimeMillis(); + out.append(" Filter:" + (stopTime - startTime) + " ms"); + + } catch (IOException e) { + logger.error("runValidators failed: " + e); + throw new RuntimeException("Error getting CCDA contents from provided file", e); + } + + return filterResults; + } + + private static final String WARNING = "Warning"; + private static final String ERROR = "Error"; + + private List filterResultsOnSeverity(final List validatorResults, final String filterByseverityLevel) { + + List filteredFinalList = new ArrayList(); + + for (Iterator iterator = validatorResults.iterator(); iterator + .hasNext();) { + + RefCCDAValidationResult eachActualValidationResult = (RefCCDAValidationResult) iterator + .next(); + + ValidationResultType actualType = eachActualValidationResult.getType(); + + String validationResultType = actualType.getTypePrettyName(); + + if(filterByseverityLevel.equalsIgnoreCase(ERROR)) { + if(StringUtils.contains(validationResultType, ERROR)) { + filteredFinalList.add(eachActualValidationResult); + } + } else if (filterByseverityLevel.equalsIgnoreCase(WARNING)) { + if (StringUtils.contains(validationResultType, ERROR) + || StringUtils.contains(validationResultType, WARNING)) { + filteredFinalList.add(eachActualValidationResult); + } + } else { + filteredFinalList = validatorResults; + } + } + return filteredFinalList; + } + + + // ------------------------- INTERNAL CODE CHANGE END -------------------------- } diff --git a/src/main/java/org/sitenv/referenceccda/services/VocabularyService.java b/src/main/java/org/sitenv/referenceccda/services/VocabularyService.java index 93c07d82..fb9e3aa3 100644 --- a/src/main/java/org/sitenv/referenceccda/services/VocabularyService.java +++ b/src/main/java/org/sitenv/referenceccda/services/VocabularyService.java @@ -1,5 +1,11 @@ package org.sitenv.referenceccda.services; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + import org.sitenv.referenceccda.services.wrappers.GithubResponseWrapper; import org.sitenv.referenceccda.services.wrappers.TestDataTreeWrapper; import org.sitenv.vocabularies.validation.entities.Code; @@ -13,8 +19,6 @@ import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; -import java.util.*; - /** * Created by Brian on 2/23/2016. */ diff --git a/src/main/java/org/sitenv/referenceccda/services/wrappers/GithubResponseWrapper.java b/src/main/java/org/sitenv/referenceccda/services/wrappers/GithubResponseWrapper.java index 0b226c08..34f966f3 100644 --- a/src/main/java/org/sitenv/referenceccda/services/wrappers/GithubResponseWrapper.java +++ b/src/main/java/org/sitenv/referenceccda/services/wrappers/GithubResponseWrapper.java @@ -1,10 +1,10 @@ package org.sitenv.referenceccda.services.wrappers; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.List; - /** * Created by Brian on 8/24/2016. */ diff --git a/src/main/java/org/sitenv/referenceccda/services/wrappers/TestDataTreeWrapper.java b/src/main/java/org/sitenv/referenceccda/services/wrappers/TestDataTreeWrapper.java index 93967619..99ef9a7b 100644 --- a/src/main/java/org/sitenv/referenceccda/services/wrappers/TestDataTreeWrapper.java +++ b/src/main/java/org/sitenv/referenceccda/services/wrappers/TestDataTreeWrapper.java @@ -1,8 +1,9 @@ package org.sitenv.referenceccda.services.wrappers; +import org.apache.commons.lang3.StringUtils; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import org.apache.commons.lang3.StringUtils; /** * Created by Brian on 8/26/2016. diff --git a/src/main/java/org/sitenv/referenceccda/validators/BaseCCDAValidator.java b/src/main/java/org/sitenv/referenceccda/validators/BaseCCDAValidator.java index 71d0e354..52913d61 100644 --- a/src/main/java/org/sitenv/referenceccda/validators/BaseCCDAValidator.java +++ b/src/main/java/org/sitenv/referenceccda/validators/BaseCCDAValidator.java @@ -1,14 +1,17 @@ package org.sitenv.referenceccda.validators; +import java.io.IOException; +import java.io.StringReader; + +import org.apache.log4j.Logger; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLReaderFactory; -import java.io.IOException; -import java.io.StringReader; - public abstract class BaseCCDAValidator { + private static Logger logger = Logger.getLogger(BaseCCDAValidator.class); + protected static void trackXPathsInXML(XPathIndexer xpathIndexer, String xmlString) throws SAXException{ XMLReader parser = XMLReaderFactory.createXMLReader(); parser.setContentHandler(xpathIndexer); @@ -17,7 +20,7 @@ protected static void trackXPathsInXML(XPathIndexer xpathIndexer, String xmlStri parser.parse(inputSource); } catch (IOException e) { e.printStackTrace(); - System.out.println("Error In Line Number Routine: Bad filename, path or invalid document."); + logger.error("Error In Line Number Routine: Bad filename, path or invalid document."); } } } diff --git a/src/main/java/org/sitenv/referenceccda/validators/CCDAValidator.java b/src/main/java/org/sitenv/referenceccda/validators/CCDAValidator.java index d365cbe8..16e3e30d 100644 --- a/src/main/java/org/sitenv/referenceccda/validators/CCDAValidator.java +++ b/src/main/java/org/sitenv/referenceccda/validators/CCDAValidator.java @@ -1,13 +1,12 @@ package org.sitenv.referenceccda.validators; -import org.xml.sax.SAXException; - import java.util.ArrayList; +import org.xml.sax.SAXException; + /** * Created by Brian on 10/20/2015. */ public interface CCDAValidator { - ArrayList validateFile(String validationObjective, - String referenceFileName, String ccdaFile) throws SAXException, Exception; + ArrayList validateFile(String validationObjective, String referenceFileName, String ccdaFile, String severityLevel) throws SAXException, Exception; } diff --git a/src/main/java/org/sitenv/referenceccda/validators/RefCCDAValidationResult.java b/src/main/java/org/sitenv/referenceccda/validators/RefCCDAValidationResult.java index 48acfa98..565cfa2a 100644 --- a/src/main/java/org/sitenv/referenceccda/validators/RefCCDAValidationResult.java +++ b/src/main/java/org/sitenv/referenceccda/validators/RefCCDAValidationResult.java @@ -1,5 +1,6 @@ package org.sitenv.referenceccda.validators; +import org.apache.commons.lang3.StringUtils; import org.sitenv.referenceccda.validators.enums.ValidationResultType; import org.sitenv.referenceccda.validators.schema.MDHTResultDetails; @@ -11,16 +12,22 @@ public class RefCCDAValidationResult { private final String xPath; private final String validatorConfiguredXpath; private final String documentLineNumber; - + // Only required for MDHT private final MDHTResultDetails mdhtResultDetails; // Only valid for Vocabulary testing + private String ruleID; private String actualCode; private String actualCodeSystem; private String actualCodeSystemName; private String actualDisplayName; + // ------------------------- INTERNAL CODE CHANGE START + private String diagnosticSource; + // ------------------------- INTERNAL CODE CHANGE END + + private RefCCDAValidationResult(RefCCDAValidationResultBuilder builder){ this.description = builder.description; this.xPath = builder.xPath; @@ -30,8 +37,12 @@ private RefCCDAValidationResult(RefCCDAValidationResultBuilder builder){ this.actualCode = builder.actualCode; this.actualCodeSystem = builder.actualCodeSystem; this.actualCodeSystemName = builder.actualCodeSystemName; - this.actualDisplayName = builder.actualDisplayName; - if(builder.mdhtResultDetails != null) { + this.actualDisplayName = builder.actualDisplayName; + // ------------------------- INTERNAL CODE CHANGE START + this.diagnosticSource = builder.diagnosticSource; + this.ruleID = builder.ruleID; + // ------------------------- INTERNAL CODE CHANGE END + if (builder.mdhtResultDetails != null) { this.mdhtResultDetails = builder.mdhtResultDetails; } else { this.mdhtResultDetails = new MDHTResultDetails(false, false, false, false); @@ -57,7 +68,7 @@ public String getValidatorConfiguredXpath() { public String getDocumentLineNumber() { return documentLineNumber; } - + public boolean isSchemaError() { return mdhtResultDetails.isSchemaError(); } @@ -90,6 +101,36 @@ public String getActualCodeSystemName() { return actualCodeSystemName; } + // ------------------------- INTERNAL CODE CHANGE START + + public String getRuleID() { + return this.ruleID; + } + + public void setRuleID(String ruleID) { + this.ruleID = ruleID; + } + + private static final String ERROR = "ERROR"; + private static final String WARNING = "WARNING"; + private static final String INFO = "INFO"; + + public String getDiagnosticSource() { + return diagnosticSource; + } + + public String getSeverity() { + String severityType = getType().getTypePrettyName(); + + String severity = (StringUtils.containsIgnoreCase(severityType, ERROR)) ? ERROR + : (StringUtils.containsIgnoreCase(severityType, WARNING)) ? WARNING + : INFO; + + return severity; + } + // ------------------------- INTERNAL CODE CHANGE END + + //builder pattern public static class RefCCDAValidationResultBuilder{ // Common Error information @@ -98,18 +139,20 @@ public static class RefCCDAValidationResultBuilder{ private final String xPath; private final String validatorConfiguredXpath; private final String documentLineNumber; - + // Only required for MDHT private MDHTResultDetails mdhtResultDetails; // Only valid for Vocabulary testing + private String ruleID; private String actualCodeSystem; private String actualCode; private String actualDisplayName; private String actualCodeSystemName; - + public RefCCDAValidationResultBuilder(String description, String xPath, - String validatorConfiguredXpath, ValidationResultType type, String documentLineNumber) { + String validatorConfiguredXpath, ValidationResultType type, + String documentLineNumber) { this.description = description; this.validatorConfiguredXpath = validatorConfiguredXpath; this.type = type; @@ -117,10 +160,30 @@ public RefCCDAValidationResultBuilder(String description, String xPath, this.documentLineNumber = documentLineNumber; } + // ------------------------- INTERNAL CODE CHANGE START + private String diagnosticSource; + public RefCCDAValidationResultBuilder(String description, String xPath, + String validatorConfiguredXpath, ValidationResultType type, + String documentLineNumber, String diagnosticSource) { + this.description = description; + this.validatorConfiguredXpath = validatorConfiguredXpath; + this.type = type; + this.xPath = xPath; + this.documentLineNumber = documentLineNumber; + this.diagnosticSource = diagnosticSource; + } + public RefCCDAValidationResultBuilder mdhtResultDetails(MDHTResultDetails mdhtResultDetails) { this.mdhtResultDetails = mdhtResultDetails; return this; } + + // ------------------------- INTERNAL CODE CHANGE END + + public RefCCDAValidationResultBuilder ruleID(String ruleID) { + this.ruleID = ruleID; + return this; + } public RefCCDAValidationResultBuilder actualCodeSystem(String actualCodeSystem) { this.actualCodeSystem = actualCodeSystem; @@ -142,7 +205,7 @@ public RefCCDAValidationResultBuilder actualCodeSystemName(String actualCodeSyst return this; } - public RefCCDAValidationResult build() { + public RefCCDAValidationResult build(){ return new RefCCDAValidationResult(this); } } diff --git a/src/main/java/org/sitenv/referenceccda/validators/XPathIndexer.java b/src/main/java/org/sitenv/referenceccda/validators/XPathIndexer.java index 5967dca4..ef609afe 100644 --- a/src/main/java/org/sitenv/referenceccda/validators/XPathIndexer.java +++ b/src/main/java/org/sitenv/referenceccda/validators/XPathIndexer.java @@ -12,15 +12,15 @@ *******************************************************************************/ package org.sitenv.referenceccda.validators; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Stack; + import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.Locator; import org.xml.sax.SAXException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Stack; - /** * XPathIndexer creates and index of line and column number of all elements * within an XML document as supplied by the SAX Locator. The locator is not @@ -63,13 +63,9 @@ static private class ElementEntry { public static class ElementLocationData { public int line; - // public int column; - - // public ElementLocationData(int line, int column) { public ElementLocationData(int line) { super(); this.line = line; - // this.column = column; } }; @@ -211,9 +207,6 @@ public void startElement(String namespace, String local, String name, Attributes currentXMLElement = new ElementEntry(name, index, currentXMLElement); - // ElementLocationData location = new - // ElementLocationData(locator.getLineNumber(), - // locator.getColumnNumber()); ElementLocationData location = new ElementLocationData(locator.getLineNumber()); xpathLocations.put(getXPathFromEntry(currentXMLElement).toUpperCase(), location); diff --git a/src/main/java/org/sitenv/referenceccda/validators/content/ReferenceContentValidator.java b/src/main/java/org/sitenv/referenceccda/validators/content/ReferenceContentValidator.java index e80a8e43..5df06cb7 100644 --- a/src/main/java/org/sitenv/referenceccda/validators/content/ReferenceContentValidator.java +++ b/src/main/java/org/sitenv/referenceccda/validators/content/ReferenceContentValidator.java @@ -27,7 +27,7 @@ public ReferenceContentValidator(ContentValidatorService contentValidatorService } @Override - public ArrayList validateFile(String validationObjective, String referenceFileName, String ccdaFile) throws SAXException { + public ArrayList validateFile(String validationObjective, String referenceFileName, String ccdaFile, String severityLevel) throws SAXException { ArrayList results = null; if (ccdaFile != null) { results = doValidation(validationObjective, referenceFileName, ccdaFile); @@ -54,7 +54,7 @@ private RefCCDAValidationResult createValidationResult(ContentValidationResult r default: type = ValidationResultType.REF_CCDA_INFO; break; } - + return new RefCCDAValidationResult.RefCCDAValidationResultBuilder(result.getMessage(), null, null, type, "0") .build(); } diff --git a/src/main/java/org/sitenv/referenceccda/validators/schema/CCDAIssueStates.java b/src/main/java/org/sitenv/referenceccda/validators/schema/CCDAIssueStates.java new file mode 100644 index 00000000..01f0b736 --- /dev/null +++ b/src/main/java/org/sitenv/referenceccda/validators/schema/CCDAIssueStates.java @@ -0,0 +1,79 @@ +package org.sitenv.referenceccda.validators.schema; + +public class CCDAIssueStates { + + /** + * Intended to flag if the current result has the issue specified + */ + private boolean isIGIssue, isMUIssue, isSchemaError, + isDataTypeSchemaError; + + /** + * Intended to flag if the entire document has a schema error of any kind + */ + private boolean hasSchemaError; + + /** + * Should be reset for each result as unique to each result + */ + public void resetUniqueResultValues() { + this.isIGIssue = false; + this.isMUIssue = false; + this.isSchemaError = false; + // if isDataTypeSchemaError is true, isSchemaError is also true, so + // multiple states are allowed + this.isDataTypeSchemaError = false; + } + + public boolean isBaseLevelIGIssueOnly() { + return this.isIGIssue && !this.isMUIssue; + } + + public boolean isGenericSchemaErrorOnly() { + return this.isSchemaError && !this.isDataTypeSchemaError; + } + + protected void setIsIGIssue(boolean isIGIssue) { + //CCDAIssueStates.isIGIssue = isIGIssue; + this.isIGIssue = isIGIssue; + } + + protected void setIsMUIssue(boolean isMUIssue) { +// CCDAIssueStates.isMUIssue = isMUIssue; + this.isMUIssue = isMUIssue; + } + + protected void setIsSchemaError(boolean isSchemaError) { + //CCDAIssueStates.isSchemaError = isSchemaError; + this.hasSchemaError = isSchemaError; + this.isSchemaError = isSchemaError; + } + + protected void setIsDataTypeSchemaError(boolean isDataTypeSchemaError) { + this.isDataTypeSchemaError = isDataTypeSchemaError; + } + + /** + * @return true if the document has at least one schema error in its results + */ + public boolean hasSchemaError() { + return this.hasSchemaError; + } + + public boolean getCurrentIGIssueState() { + return this.isIGIssue; + } + + public boolean getCurrentMUIssueState() { + return this.isMUIssue; + } + + public boolean getCurrentSchemaErrorState() { + return this.isSchemaError; + } + + public boolean getCurrentDataTypeSchemaErrorState() { + return this.isDataTypeSchemaError; + } + +} diff --git a/src/main/java/org/sitenv/referenceccda/validators/schema/OCLLoader.java b/src/main/java/org/sitenv/referenceccda/validators/schema/OCLLoader.java new file mode 100644 index 00000000..9ed04f39 --- /dev/null +++ b/src/main/java/org/sitenv/referenceccda/validators/schema/OCLLoader.java @@ -0,0 +1,106 @@ +package org.sitenv.referenceccda.validators.schema; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; +import org.springframework.core.type.filter.RegexPatternTypeFilter; + +public class OCLLoader { + + private static ThreadLocal wasInit = new ThreadLocal(); + private static String operations = "org.openhealthtools.mdht.uml.cda.consol.operations"; + private static final Logger logger = Logger.getLogger(OCLLoader.class); + + public static Map loadocl() { + + Map r = new HashMap(); + + if (System.getProperty("mdht-skip-ocl-init") != null) { + logger.info("Skipping OCLLoader.loadocl() call!!"); + return r; + } + + String tn = Thread.currentThread().getName(); + r.put("Thread", tn); + + if (wasInit == null) { + wasInit = new ThreadLocal(); + r.put("TLS", "Initialized"); + } else { + r.put("TLS", "Already initialized"); + } + + if (wasInit.get() == null) { + wasInit.set(Boolean.FALSE); + r.put("TLS-Boolean", "Initialized"); + } else { + r.put("TLS-Boolean", "Already initialized"); + } + + if (wasInit.get()) { + logger.info(tn + " Load OCL done already..."); + r.put("Status", "0"); + r.put("Message", "Load OCL done already..."); + r.put("Elapsed", "0"); + return r; + } + + logger.info(tn + " Loading OCLs..."); + long startTime = System.currentTimeMillis(); + + try { + final ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider( + false); + // add include filters which matches all the classes (or use your + // own) + provider.addIncludeFilter(new RegexPatternTypeFilter(Pattern.compile(".*"))); + + // get matching classes defined in the package + final Set classes = provider + .findCandidateComponents("org.openhealthtools.mdht.uml.cda.consol.operations"); + + for (BeanDefinition bean : classes) { + + Class c2 = Class.forName(bean.getBeanClassName()); + + for (Method method : c2.getDeclaredMethods()) { + // System.out.println(method.getName()); + if (method.getName().startsWith("validate") && Modifier.isStatic(method.getModifiers())) { + try { + logger.debug("Pre-loading: " + c2.getName() + " Method:" + method.getName()); + method.invoke(null, null, null, null); + } catch (IllegalAccessException e) { +// logger.error("Error loading OCLs.", e); + } catch (IllegalArgumentException e) { +// logger.error("Error loading OCLs.", e); + } catch (InvocationTargetException e) { +// logger.error("Error loading OCLs.", e); + } + } + } + } + } catch (Exception e) { + r.put("Error", e.getMessage()); + logger.error("Error loading OCLs.", e); + } + + long endTime = System.currentTimeMillis(); + long elaps = endTime - startTime; + wasInit.set(Boolean.TRUE); + r.put("Status", "1"); + r.put("Message", "Loaded OCL expressions."); + r.put("Elapsed", String.valueOf(elaps)); + logger.warn( + tn + " Thread NOT previously initialized. OCLLoader.init() Execution Time " + elaps + " milliseconds"); + return r; + } + +} diff --git a/src/main/java/org/sitenv/referenceccda/validators/schema/ReferenceCCDAValidator.java b/src/main/java/org/sitenv/referenceccda/validators/schema/ReferenceCCDAValidator.java index ad7937ed..a0d91216 100644 --- a/src/main/java/org/sitenv/referenceccda/validators/schema/ReferenceCCDAValidator.java +++ b/src/main/java/org/sitenv/referenceccda/validators/schema/ReferenceCCDAValidator.java @@ -39,15 +39,16 @@ public boolean isValidationObjectiveMu2Type() { } public ArrayList validateFile(String validationObjective, - String referenceFileName, String ccdaFile) throws SAXException, Exception { + String referenceFileName, String ccdaFile, String severityLevel) throws SAXException, Exception { final XPathIndexer xpathIndexer = new XPathIndexer(); ValidationResult result = new ValidationResult(); InputStream in = null; trackXPathsInXML(xpathIndexer, ccdaFile); - try { - in = IOUtils.toInputStream(ccdaFile, "UTF-8"); + try { + in = IOUtils.toInputStream(ccdaFile, "UTF-8"); +// OCLLoader.loadocl(); validateDocumentByTypeUsingMDHTApi(in, validationObjective, result); - } catch (IOException e) { + } catch (IOException e) { e.printStackTrace(); } finally { if (in != null) { @@ -68,7 +69,7 @@ public ArrayList validateFile(String validationObjectiv logger.info("Processing and returning MDHT validation results"); return processValidationResults(xpathIndexer, result); } - + private void validateDocumentByTypeUsingMDHTApi(InputStream in, String validationObjective, ValidationResult result) throws Exception { if(StringUtils.isEmpty(validationObjective)) { @@ -91,6 +92,7 @@ private void validateDocumentByTypeUsingMDHTApi(InputStream in, String validatio if (isValidationObjectiveCCDAType(mdhtValidationObjective)) { Mu2consolPackage.eINSTANCE.unload(); ConsolPackage.eINSTANCE.eClass(); + OCLLoader.loadocl(); logger.info("Loading mdhtValidationObjective: " + mdhtValidationObjective + " mapped from valdationObjective: " + validationObjective); CDAUtil.load(in, result); @@ -182,7 +184,7 @@ private void addValidationResults(ArrayList results, Va results.add(buildValidationResult(diagnostic, xpathIndexer, currentValidationResultType)); } } - + private RefCCDAValidationResult buildValidationResult(Diagnostic diagnostic, XPathIndexer xPathIndexer, ValidationResultType resultType) { CDADiagnostic diag = new CDADiagnostic(diagnostic); @@ -254,7 +256,7 @@ public String getPath(EObject eObject) { private RefCCDAValidationResult createNewValidationResult(CDADiagnostic cdaDiag, ValidationResultType resultType, String resultLineNumber, MDHTResultDetails mdhtResultDetails) { return new RefCCDAValidationResult.RefCCDAValidationResultBuilder( - cdaDiag.getMessage(), cdaDiag.getPath(), null, resultType, resultLineNumber) + cdaDiag.getMessage(), cdaDiag.getPath(), null, resultType, resultLineNumber, cdaDiag.getSource()) .mdhtResultDetails(mdhtResultDetails) .build(); } diff --git a/src/main/java/org/sitenv/referenceccda/validators/vocabulary/VocabularyCCDAValidator.java b/src/main/java/org/sitenv/referenceccda/validators/vocabulary/VocabularyCCDAValidator.java index 1c609f80..4eb0c448 100644 --- a/src/main/java/org/sitenv/referenceccda/validators/vocabulary/VocabularyCCDAValidator.java +++ b/src/main/java/org/sitenv/referenceccda/validators/vocabulary/VocabularyCCDAValidator.java @@ -1,15 +1,21 @@ package org.sitenv.referenceccda.validators.vocabulary; import java.io.IOException; +import java.io.LineNumberReader; +import java.io.StringReader; import java.util.ArrayList; import java.util.List; +import javax.xml.parsers.ParserConfigurationException; + import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; import org.sitenv.referenceccda.validators.BaseCCDAValidator; import org.sitenv.referenceccda.validators.CCDAValidator; import org.sitenv.referenceccda.validators.RefCCDAValidationResult; import org.sitenv.referenceccda.validators.XPathIndexer; import org.sitenv.referenceccda.validators.enums.ValidationResultType; +import org.sitenv.referenceccda.validators.schema.CCDAIssueStates; import org.sitenv.vocabularies.validation.dto.VocabularyValidationResult; import org.sitenv.vocabularies.validation.services.VocabularyValidationService; import org.springframework.beans.factory.annotation.Autowired; @@ -19,6 +25,7 @@ @Component public class VocabularyCCDAValidator extends BaseCCDAValidator implements CCDAValidator { + private static Logger logger = Logger.getLogger(VocabularyCCDAValidator.class); @Value("${referenceccda.configFile}") private String vocabularyXpathExpressionConfiguration; private VocabularyValidationService vocabularyValidationService; @@ -28,13 +35,13 @@ public VocabularyCCDAValidator(VocabularyValidationService vocabularyValidationS this.vocabularyValidationService = vocabularyValidationService; } - public ArrayList validateFile(String validationObjective, String referenceFileName, String ccdaFile) throws SAXException { + //------------------------- INTERNAL CODE CHANGE START -------------------------- + public ArrayList validateFile(String validationObjective, String referenceFileName, String ccdaFile, String severityLevel) throws SAXException, ParserConfigurationException { + //------------------------- INTERNAL CODE CHANGE END -------------------------- ArrayList results = null; if (ccdaFile != null) { - final XPathIndexer xpathIndexer = new XPathIndexer(); - trackXPathsInXML(xpathIndexer, ccdaFile); try { - results = doValidation(ccdaFile, xpathIndexer); + results = doValidation(ccdaFile, severityLevel); } catch (IOException e) { e.printStackTrace(); } @@ -42,8 +49,37 @@ public ArrayList validateFile(String validationObjectiv return results; } - private ArrayList doValidation(String ccdaFile, XPathIndexer xpathIndexer) throws IOException, SAXException { - List validationResults = vocabularyValidationService.validate(IOUtils.toInputStream(ccdaFile, "UTF-8")); + private ArrayList doValidation(String ccdaFile, String severityLevel) throws IOException, SAXException, ParserConfigurationException { + + // Build arraylist list with offsets of each line in the original file. + List lineOffsets = new ArrayList(); + String w; + int z = 0; + try { + LineNumberReader r = new LineNumberReader(new StringReader(ccdaFile)); + while ((w = r.readLine()) != null) { + z += w.getBytes("UTF8").length; +// logger.info("Line:" + l + " Size:" + w.getBytes("UTF8").length + " z:" + z + " " + w); + z++; // CR + z++; // LF + lineOffsets.add(new Integer(z)); + } + } catch (Exception e) { + throw new IOException(e.getMessage()); + } + + List validationResults = vocabularyValidationService.validate(IOUtils.toInputStream(ccdaFile, "UTF-8"), severityLevel); + ArrayList results = new ArrayList<>(); + for (VocabularyValidationResult result : validationResults) { + results.add(createValidationResult(result, lineOffsets)); + } + return results; + } + + //------------------------- INTERNAL CODE CHANGE START -------------------------- + private ArrayList doValidation(String ccdaFile, XPathIndexer xpathIndexer, String severityLevel) throws IOException, SAXException, ParserConfigurationException { + //------------------------- INTERNAL CODE CHANGE END -------------------------- + List validationResults = vocabularyValidationService.validate(IOUtils.toInputStream(ccdaFile, "UTF-8"), severityLevel); ArrayList results = new ArrayList<>(); for (VocabularyValidationResult result : validationResults) { results.add(createValidationResult(result, xpathIndexer)); @@ -63,9 +99,7 @@ private RefCCDAValidationResult createValidationResult(VocabularyValidationResul } String lineNumber = getLineNumberInXMLUsingXpath(xpathIndexer, result.getNodeValidationResult().getValidatedDocumentXpathExpression()); - return new RefCCDAValidationResult.RefCCDAValidationResultBuilder(result.getMessage(), - result.getNodeValidationResult().getValidatedDocumentXpathExpression(), - result.getNodeValidationResult().getConfiguredXpathExpression(), type, lineNumber) + return new RefCCDAValidationResult.RefCCDAValidationResultBuilder(result.getMessage(), result.getNodeValidationResult().getValidatedDocumentXpathExpression(), result.getNodeValidationResult().getConfiguredXpathExpression(), type, lineNumber) .actualCode(result.getNodeValidationResult().getRequestedCode()) .actualCodeSystem(result.getNodeValidationResult().getRequestedCodeSystem()) .actualCodeSystemName(result.getNodeValidationResult().getRequestedCodeSystemName()) @@ -73,6 +107,38 @@ private RefCCDAValidationResult createValidationResult(VocabularyValidationResul .build(); } + private RefCCDAValidationResult createValidationResult(VocabularyValidationResult result, List lineOffsets) { + ValidationResultType type; + switch(result.getVocabularyValidationResultLevel()){ + case SHALL: type = ValidationResultType.CCDA_VOCAB_CONFORMANCE_ERROR; + break; + case SHOULD: type = ValidationResultType.CCDA_VOCAB_CONFORMANCE_WARN; + break; + default: type = ValidationResultType.CCDA_VOCAB_CONFORMANCE_INFO; + break; + } + + String lineNumber = getLineNumberInXML(result.getNodeValidationResult().getErrorOffset(),lineOffsets); + + return new RefCCDAValidationResult.RefCCDAValidationResultBuilder(result.getMessage(), result.getNodeValidationResult().getValidatedDocumentXpathExpression(), result.getNodeValidationResult().getConfiguredXpathExpression(), type, lineNumber) + .actualCode(result.getNodeValidationResult().getRequestedCode()) + .actualCodeSystem(result.getNodeValidationResult().getRequestedCodeSystem()) + .actualCodeSystemName(result.getNodeValidationResult().getRequestedCodeSystemName()) + .actualDisplayName(result.getNodeValidationResult().getRequestedDisplayName()) + .ruleID(result.getNodeValidationResult().getRuleID()) + .build(); + } + + private String getLineNumberInXML(long offset, List lineOffsets) { + for (int i = 0; i < lineOffsets.size(); i++) { + if (lineOffsets.get(i) > offset) { + //logger.info("getLineNumberInXML Offset:" + offset + " Line:" + (i+1)); + return String.valueOf(i + 1); + } + } + return "0"; + } + private String getLineNumberInXMLUsingXpath(final XPathIndexer xpathIndexer, String xpath) { XPathIndexer.ElementLocationData eld = xpathIndexer.getElementLocationByPath(xpath.toUpperCase()); String lineNumber = eld != null ? Integer.toString(eld.line) : "Line number not available"; diff --git a/src/main/resources/log4j.xml b/src/main/resources/log4j.xml index 449b0e6d..38c85e1c 100644 --- a/src/main/resources/log4j.xml +++ b/src/main/resources/log4j.xml @@ -11,7 +11,11 @@ - + + + @@ -20,15 +24,22 @@ - + + + + + + + + - + - + diff --git a/src/test/java/RefCCDATest.java b/src/test/java/RefCCDATest.java index 78108905..da8bd954 100644 --- a/src/test/java/RefCCDATest.java +++ b/src/test/java/RefCCDATest.java @@ -4,10 +4,8 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; -import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; @@ -484,7 +482,7 @@ private static ValidationResultsDto runReferenceCCDAValidationServiceAndReturnRe + (referenceCcdaValidationService == null ? "null" : "not null") + ("mockSample is " + mockSample == null ? "null" : "not null")); } - return referenceCcdaValidationService.validateCCDA(validationObjective, "", mockSample); + return referenceCcdaValidationService.validateCCDA(validationObjective, "", mockSample, "info"); } private static ArrayList validateDocumentAndReturnResults(String ccdaFileAsString) { @@ -497,7 +495,7 @@ private static ArrayList validateDocumentAndReturnResul ArrayList results = null; try { results = referenceCCDAValidator.validateFile(validationObjective, "Test", - ccdaFileAsString); + ccdaFileAsString, "info"); } catch (SAXException e) { if(LOG_RESULTS_TO_CONSOLE) e.printStackTrace(); } catch (Exception e) { diff --git a/src/test/java/org/sitenv/referenceccda/validations/schema/OCLLoaderTest.java b/src/test/java/org/sitenv/referenceccda/validations/schema/OCLLoaderTest.java new file mode 100644 index 00000000..8f81bf7c --- /dev/null +++ b/src/test/java/org/sitenv/referenceccda/validations/schema/OCLLoaderTest.java @@ -0,0 +1,20 @@ +package org.sitenv.referenceccda.validations.schema; + +import static org.junit.Assert.assertEquals; + +import java.util.Map; + +import org.junit.Test; +import org.sitenv.referenceccda.validators.schema.OCLLoader; + +public class OCLLoaderTest { + + @Test + public void testOCLLoader() { + // First time call + OCLLoader.loadocl(); + // Second time call. + Map result = OCLLoader.loadocl(); + assertEquals("Second time should say already done","0", result.get("Status")); + } +}