diff --git a/api/src/main/java/org/openmrs/module/radiology/report/template/DefaultMrrtReportTemplateFileParser.java b/api/src/main/java/org/openmrs/module/radiology/report/template/DefaultMrrtReportTemplateFileParser.java index d84ab51e6..bb881a632 100644 --- a/api/src/main/java/org/openmrs/module/radiology/report/template/DefaultMrrtReportTemplateFileParser.java +++ b/api/src/main/java/org/openmrs/module/radiology/report/template/DefaultMrrtReportTemplateFileParser.java @@ -12,6 +12,8 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -78,7 +80,12 @@ public MrrtReportTemplate parse(String mrrtTemplate) throws IOException { final Document doc = Jsoup.parse(mrrtTemplate, ""); final MrrtReportTemplate result = new MrrtReportTemplate(); - initializeTemplate(result, doc); + try { + initializeTemplate(result, doc); + } + catch (ParseException e) { + throw new APIException("radiology.report.template.parser.error", null, e); + } try { addTermsToTemplate(result, doc.getElementsByTag("script") .get(0) @@ -90,7 +97,7 @@ public MrrtReportTemplate parse(String mrrtTemplate) throws IOException { return result; } - private final void initializeTemplate(MrrtReportTemplate template, Document doc) { + private final void initializeTemplate(MrrtReportTemplate template, Document doc) throws ParseException { final Elements metaTags = doc.getElementsByTag("meta"); template.setPath(doc.baseUri()); @@ -125,7 +132,7 @@ private final void initializeTemplate(MrrtReportTemplate template, Document doc) template.setDcTermsLicense(content); break; case DCTERMS_DATE: - template.setDcTermsDate(content); + parseDcTermsDate(template, content); break; case DCTERMS_CREATOR: template.setDcTermsCreator(content); @@ -180,4 +187,8 @@ private final ConceptSource getConceptSourceByName(String name, ConceptService c } return null; } + + private final void parseDcTermsDate(MrrtReportTemplate template, String content) throws ParseException { + template.setDcTermsDate(new SimpleDateFormat(MrrtReportTemplateConstants.DATE_FORMAT).parse(content)); + } } diff --git a/api/src/main/java/org/openmrs/module/radiology/report/template/MetaTagsValidationEngine.java b/api/src/main/java/org/openmrs/module/radiology/report/template/MetaTagsValidationEngine.java index b481e4267..22208be34 100644 --- a/api/src/main/java/org/openmrs/module/radiology/report/template/MetaTagsValidationEngine.java +++ b/api/src/main/java/org/openmrs/module/radiology/report/template/MetaTagsValidationEngine.java @@ -9,11 +9,16 @@ */ package org.openmrs.module.radiology.report.template; -import org.jsoup.select.Elements; - +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + /** * Validates tags of an Mrrt Report Template. */ @@ -24,6 +29,8 @@ class MetaTagsValidationEngine implements ValidationEngine { static String SELECTOR_QUERY_META_ATTRIBUTE_NAME = "meta[name]"; + static String SELECTOR_QUERY_META_ATTRIBUTE_DATE = "meta[name=dcterms.date]"; + private List> rules; public MetaTagsValidationEngine() { @@ -35,6 +42,9 @@ public MetaTagsValidationEngine() { new ElementsExpressionValidationRule("At least one 'meta' element encoding dublin core attributes expected", "radiology.MrrtReportTemplate.validation.error.meta.dublinCore.missing", SELECTOR_QUERY_META_ATTRIBUTE_NAME, subject -> subject.isEmpty())); + rules.add(new ElementsExpressionValidationRule("dcterms.date element should be a valid date", + "radiology.MrrtReportTemplate.validation.error.date.invalid", SELECTOR_QUERY_META_ATTRIBUTE_DATE, + subject -> isDateInvalid(subject))); } /** @@ -53,4 +63,19 @@ public ValidationResult run(Elements subject) { } return validationResult; } + + private final boolean isDateInvalid(Elements elements) { + boolean result = false; + if (elements.isEmpty()) { + return result; + } + Element dcTermsDateElement = elements.get(0); + try { + new SimpleDateFormat(MrrtReportTemplateConstants.DATE_FORMAT).parse(dcTermsDateElement.attr("content")); + } + catch (ParseException ex) { + result = true; + } + return result; + } } diff --git a/api/src/main/java/org/openmrs/module/radiology/report/template/MrrtReportTemplate.java b/api/src/main/java/org/openmrs/module/radiology/report/template/MrrtReportTemplate.java index 31505ce0f..920d42b41 100644 --- a/api/src/main/java/org/openmrs/module/radiology/report/template/MrrtReportTemplate.java +++ b/api/src/main/java/org/openmrs/module/radiology/report/template/MrrtReportTemplate.java @@ -9,6 +9,7 @@ */ package org.openmrs.module.radiology.report.template; +import java.util.Date; import java.util.Set; import org.openmrs.BaseOpenmrsData; @@ -44,7 +45,7 @@ public class MrrtReportTemplate extends BaseOpenmrsData { private String dcTermsLicense; - private String dcTermsDate; + private Date dcTermsDate; private String dcTermsCreator; @@ -148,11 +149,19 @@ public void setDcTermsLicense(String dcTermsLicense) { this.dcTermsLicense = dcTermsLicense; } - public String getDcTermsDate() { - return dcTermsDate; + /** + * Get dcterms date property of an MRRT report template. + * + * @return Date date property of the MRRT report template or null if no date was set + */ + public Date getDcTermsDate() { + if (dcTermsDate == null) { + return dcTermsDate; + } + return new Date(dcTermsDate.getTime()); } - public void setDcTermsDate(String dcTermsDate) { + public void setDcTermsDate(Date dcTermsDate) { this.dcTermsDate = dcTermsDate; } diff --git a/api/src/main/java/org/openmrs/module/radiology/report/template/MrrtReportTemplateConstants.java b/api/src/main/java/org/openmrs/module/radiology/report/template/MrrtReportTemplateConstants.java new file mode 100644 index 000000000..a2e3be473 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/radiology/report/template/MrrtReportTemplateConstants.java @@ -0,0 +1,30 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public License, + * v. 2.0. If a copy of the MPL was not distributed with this file, You can + * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under + * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. + * + * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS + * graphic logo is a trademark of OpenMRS Inc. + */ +package org.openmrs.module.radiology.report.template; + +/** + * Utility class that contains constants which are used within this module. + */ +public final class MrrtReportTemplateConstants { + + + /** + * Constant for dcterms.date format for an {@code MrrtReportTemplate}. + * + * See table "Table 4.105.4.1.2-1: HTTP Query Parameters" on page 27 of + * the MRRT Standards document. + */ + public static final String DATE_FORMAT = "yyyy-MM-dd"; + + private MrrtReportTemplateConstants() { + // Utility class not meant to be instantiated. + } + +} diff --git a/api/src/main/java/org/openmrs/module/radiology/report/template/MrrtReportTemplateValidator.java b/api/src/main/java/org/openmrs/module/radiology/report/template/MrrtReportTemplateValidator.java index 10b47a8cf..8a8ca6982 100644 --- a/api/src/main/java/org/openmrs/module/radiology/report/template/MrrtReportTemplateValidator.java +++ b/api/src/main/java/org/openmrs/module/radiology/report/template/MrrtReportTemplateValidator.java @@ -50,6 +50,7 @@ public interface MrrtReportTemplateValidator { * @should throw api exception if html element does not have a body element * @should throw api exception if html element has more than one body element * @should catch all violation errors and throw an mrrt report template exception + * @should throw an mrrt report template exception if dcterms date of template file is not valid */ public void validate(String mrrtTemplate) throws IOException; } diff --git a/api/src/main/resources/MrrtReportTemplate.hbm.xml b/api/src/main/resources/MrrtReportTemplate.hbm.xml index 4b4885c80..cc5276304 100644 --- a/api/src/main/resources/MrrtReportTemplate.hbm.xml +++ b/api/src/main/resources/MrrtReportTemplate.hbm.xml @@ -33,7 +33,7 @@ - + diff --git a/api/src/main/resources/liquibase.xml b/api/src/main/resources/liquibase.xml index 8228e793e..4e9387d56 100644 --- a/api/src/main/resources/liquibase.xml +++ b/api/src/main/resources/liquibase.xml @@ -568,4 +568,8 @@ + + Change the datatype of dcterms_date from varchar(32) to date + + diff --git a/api/src/test/java/org/openmrs/module/radiology/report/template/MrrtReportTemplateFileParserComponentTest.java b/api/src/test/java/org/openmrs/module/radiology/report/template/MrrtReportTemplateFileParserComponentTest.java index bc26925da..21c18bb54 100644 --- a/api/src/test/java/org/openmrs/module/radiology/report/template/MrrtReportTemplateFileParserComponentTest.java +++ b/api/src/test/java/org/openmrs/module/radiology/report/template/MrrtReportTemplateFileParserComponentTest.java @@ -18,6 +18,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.text.SimpleDateFormat; +import java.util.Date; import org.apache.commons.io.IOUtils; import org.junit.Before; @@ -120,6 +122,7 @@ public void parse_shouldReturnAnMrrtTemplateObjectIfFileIsValid() throws Excepti String templateContent = getFileContent("mrrttemplates/ihe/connectathon/2015/CTChestAbdomen.html"); MrrtReportTemplate template = parser.parse(templateContent); + Date dcTermsDate = new SimpleDateFormat(MrrtReportTemplateConstants.DATE_FORMAT).parse(TEST_DCTERMS_DATE); assertNotNull(template); assertThat(template.getCharset(), is(CHARSET)); @@ -132,7 +135,7 @@ public void parse_shouldReturnAnMrrtTemplateObjectIfFileIsValid() throws Excepti assertThat(template.getDcTermsPublisher(), is(TEST_DCTERMS_PUBLISHER)); assertThat(template.getDcTermsRights(), is(TEST_DCTERMS_RIGHTS)); assertThat(template.getDcTermsLicense(), is(TEST_DCTERMS_LICENSE)); - assertThat(template.getDcTermsDate(), is(TEST_DCTERMS_DATE)); + assertThat(template.getDcTermsDate(), is(dcTermsDate)); assertThat(template.getDcTermsCreator(), is(TEST_DCTERMS_CREATOR)); } diff --git a/api/src/test/java/org/openmrs/module/radiology/report/template/MrrtReportTemplateValidatorComponentTest.java b/api/src/test/java/org/openmrs/module/radiology/report/template/MrrtReportTemplateValidatorComponentTest.java index 386f9a8df..cd8b67fd2 100644 --- a/api/src/test/java/org/openmrs/module/radiology/report/template/MrrtReportTemplateValidatorComponentTest.java +++ b/api/src/test/java/org/openmrs/module/radiology/report/template/MrrtReportTemplateValidatorComponentTest.java @@ -407,4 +407,17 @@ public void validate_catchAllViolationErrorsAndThrowAnMrrtReportTemplateExceptio is(4)); } } + + /** + * @see MrrtReportTemplateValidator#validate(String) + * @verifies throw an mrrt report template exception if dcterms date of template file is not valid + */ + @Test + public void validate_shouldThrowAnMrrtReportTemplateExceptionIfDctermsDateOfTemplateFileIsNotValid() throws Exception { + + String templateContent = getFileContent( + "mrrttemplates/ihe/connectathon/2015/invalidMrrtReportTemplate-dcTermsDateIsNotAValidDateObject.html"); + expectedException.expect(MrrtReportTemplateValidationException.class); + validator.validate(templateContent); + } } diff --git a/api/src/test/resources/mrrttemplates/ihe/connectathon/2015/invalidMrrtReportTemplate-dcTermsDateIsNotAValidDateObject.html b/api/src/test/resources/mrrttemplates/ihe/connectathon/2015/invalidMrrtReportTemplate-dcTermsDateIsNotAValidDateObject.html new file mode 100644 index 000000000..1f2f7a4a4 --- /dev/null +++ b/api/src/test/resources/mrrttemplates/ihe/connectathon/2015/invalidMrrtReportTemplate-dcTermsDateIsNotAValidDateObject.html @@ -0,0 +1,41 @@ + + + + CT Chest-Abdomen + + + + + + + + + + + + + + + +
+
Section Header
+

This is the CT Chest-Abdomen report template

+
+ + \ No newline at end of file diff --git a/omod/src/main/resources/messages.properties b/omod/src/main/resources/messages.properties index 9095c1585..d15ff56aa 100644 --- a/omod/src/main/resources/messages.properties +++ b/omod/src/main/resources/messages.properties @@ -181,6 +181,7 @@ @MODULE_ID@.MrrtReportTemplate.not.imported.empty=Failed to import report template because it was empty @MODULE_ID@.MrrtReportTemplate.validation.error.meta.charset.occurence=Template file should have exactly one 'meta' element with attribute 'charset' @MODULE_ID@.MrrtReportTemplate.validation.error.meta.dublinCore.missing=Template file should have at least one 'meta' element encoding dublin core attributes +@MODULE_ID@.MrrtReportTemplate.validation.error.date.invalid=dcterms.date needs to be of format yyyy-MM-dd like for example 2016-01-24 @MODULE_ID@.patientId=Patient Id @MODULE_ID@.patientFullName=Patient Full Name