Java tutorial
/******************************************************************************* * Copyright (c) 2010, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Sean Muir (JKM Software) -Operation Test and generation * Christian W. Damus - Add NarrativeReferenceTestCase for constraints on CDA R2 narrative text references (artf2815) * Dan Brown (Ai) - Added a few testing constants * *******************************************************************************/ package org.eclipse.mdht.uml.cda.operations; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.FileWriter; import java.io.OutputStream; import java.io.StringReader; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import org.eclipse.emf.common.util.BasicDiagnostic; import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.Diagnostician; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.ecore.util.ExtendedMetaData; import org.eclipse.emf.ecore.util.FeatureMapUtil; import org.eclipse.emf.ecore.xmi.XMLResource; import org.eclipse.emf.ecore.xmi.util.XMLProcessor; import org.eclipse.emf.ecore.xml.type.AnyType; import org.eclipse.mdht.uml.cda.CDAFactory; import org.eclipse.mdht.uml.cda.ClinicalDocument; import org.eclipse.mdht.uml.cda.ClinicalStatement; import org.eclipse.mdht.uml.cda.Entry; import org.eclipse.mdht.uml.cda.Section; import org.eclipse.mdht.uml.cda.StrucDocText; import org.eclipse.mdht.uml.cda.util.CDAUtil; import org.eclipse.mdht.uml.hl7.datatypes.CD; import org.eclipse.mdht.uml.hl7.datatypes.CE; import org.eclipse.mdht.uml.hl7.datatypes.CS; import org.eclipse.mdht.uml.hl7.datatypes.DatatypesFactory; import org.eclipse.mdht.uml.hl7.datatypes.ED; import org.eclipse.mdht.uml.hl7.datatypes.II; import org.eclipse.mdht.uml.hl7.rim.InfrastructureRoot; import org.eclipse.mdht.uml.hl7.vocab.NullFlavor; import org.junit.Assert; import org.xml.sax.InputSource; /** * This class is the super class for all JUnit4 test cases for CDA based * classes. */ @SuppressWarnings("nls") public abstract class CDAValidationTest { protected abstract EObject getObjectToTest(); /** * This is not currently used, but is implemented in many subclasses. * * @return the initialized EObject instance to test */ protected EObject getObjectInitToTest() { return null; } /** * The template id to use for the has* tests. */ protected static final String BAD_TEMPLATE_ID = "1.2.3.4"; protected static final II THE_BAD_II = DatatypesFactory.eINSTANCE.createII(); static { THE_BAD_II.setRoot(BAD_TEMPLATE_ID); } /** * Additional constants for use in testing */ protected static final String BAD_CODESYSTEM_ID = "6.66.666.6.666666.6.666"; protected static final String BAD_CODE_VALUE = "NOTACODE"; protected static final String SNOMEDCT_ID = "2.16.840.1.113883.6.96"; protected static final String LOINC_ID = "2.16.840.1.113883.6.1"; // currently used for date accuracy in multiple test files // eight character date protected static final String PRECISE_TO_DAY = "20091212"; // twelve character date protected static final String PRECISE_TO_MINUTE = "200912121721"; // fourteen character date protected static final String PRECISE_TO_SECOND = "20091212172151"; // fifteen character date with time-zone protected static final String PRECISE_TO_HOUR_WITH_TIMEZONE = "2012091619-0400"; // seventeen character date with time-zone protected static final String PRECISE_TO_MINUTE_WITH_TIMEZONE = "201209161918-0400"; // nineteen character date with time-zone protected static final String PRECISE_TO_SECOND_WITH_TIMEZONE = "20050329171504+0500"; // twenty-three character date with time-zone protected static final String PRECISE_TO_MS_WITH_TIMEZONE = "20091212172151.035-0500"; // protected static int count = 0; protected static Map<Object, Object> map = new HashMap<Object, Object>(); protected List<CDATestCase> getTestCases() { return new ArrayList<CDATestCase>(); } static abstract protected class CDATestCase { private final String testTargetDescription; /** * @param testTargetDescription */ protected CDATestCase(final String testTargetDescription) { this.testTargetDescription = testTargetDescription; } abstract protected void doTest(final EObject objectToTest, final BasicDiagnostic diagnostician, final Map<Object, Object> map); protected String getTestTargetDescription() { return testTargetDescription; } @Override public String toString() { return getTestTargetDescription(); } } // CDATestCase static abstract protected class CDAOperationsTestCase extends CDATestCase { protected CDAOperationsTestCase(final String testTargetDescription) { super(testTargetDescription); } abstract protected void doAdd(EObject objectToTest, EObject eObjectToAdd); abstract protected EObject getEObjectToAdd(); } // CDAOperationsTestCase static abstract protected class CDAAddTestCase extends CDAOperationsTestCase { protected CDAAddTestCase(final String testTargetDescription) { super(testTargetDescription); } @Override protected void doTest(final EObject objectToTest, final BasicDiagnostic diagnostician, final Map<Object, Object> map) { final EObject eObjectToAdd = getEObjectToAdd(); doAdd(objectToTest, eObjectToAdd); final boolean isFound = isFound(objectToTest, eObjectToAdd, getFeature()); assertTrue("Add \"" + getTestTargetDescription() + "\" failed for \"" + objectToTest.eClass().getName() + "\"", isFound); } // doTest abstract protected EStructuralFeature getFeature(); protected boolean isFound(final EObject objectToTest, final EObject eObjectToFind, final EStructuralFeature feature) { return eObjectToFind.eContainingFeature().equals(feature) && eObjectToFind.eContainer().eContainer().equals(objectToTest); } // isFound } // CDAAddTestCase static abstract protected class CDAGetTestCase extends CDAOperationsTestCase { protected CDAGetTestCase(final String testTargetDescription) { super(testTargetDescription); } @Override protected void doTest(final EObject objectToTest, final BasicDiagnostic diagnostician, final Map<Object, Object> map) { final EObject eObjectToAdd = getEObjectToAdd(); doAdd(objectToTest, eObjectToAdd); final Object value = doGet(objectToTest); final boolean getIsGood = isGetGood(eObjectToAdd, value); assertTrue("Get \"" + getTestTargetDescription() + "\" failed for \"" + objectToTest.eClass().getName() + "\"", getIsGood); } // doTest protected boolean isGetGood(final EObject eObjectToAdd, final Object value) { final EList<?> list = (EList<?>) value; return list.size() == 1 && list.get(0).equals(eObjectToAdd); } abstract protected Object doGet(EObject objectToTest); } // CDAGetTestCase static abstract protected class CDAHasTestCase extends CDAOperationsTestCase { protected static final String TEMPLATE_ID = "1.2.3.4"; protected static final II THE_II = DatatypesFactory.eINSTANCE.createII(); protected static final String CODE = "code"; protected static final String CODE_SYSTEM = "codeSystem"; protected static final String CODE_SYSTEM_NAME = "codeSystemName"; protected static final String CODE_DISPLAY_NAME = "codeDisplayName"; protected static final CD THE_CODE = DatatypesFactory.eINSTANCE.createCD(CODE, CODE_SYSTEM, CODE_SYSTEM_NAME, CODE_DISPLAY_NAME); protected static final CE THE_CE_CODE = DatatypesFactory.eINSTANCE.createCE(CODE, CODE_SYSTEM, CODE_SYSTEM_NAME, CODE_DISPLAY_NAME); protected static final CS THE_CS_CODE = DatatypesFactory.eINSTANCE.createCS(CODE); protected CDAHasTestCase(final String testTargetDescription) { super(testTargetDescription); THE_II.setRoot(TEMPLATE_ID); } @Override protected void doTest(final EObject objectToTest, final BasicDiagnostic diagnostician, final Map<Object, Object> map) { final EObject eObjectToAdd = getEObjectToAdd(); doAddTemplateId(eObjectToAdd, THE_II); doAdd(objectToTest, eObjectToAdd); final boolean hasIsGood = doHas(objectToTest, TEMPLATE_ID); assertTrue("Has \"" + getTestTargetDescription() + "\" failed for \"" + objectToTest.eClass().getName() + "\"", hasIsGood); } // doTest protected abstract void doAddTemplateId(EObject objectToTest, II theIi); protected abstract boolean doHas(EObject eObjectToAdd, String templateId); } // CDAHasTestCase static abstract protected class CDAValidationTestCase extends CDATestCase { public CDAValidationTestCase(final String testTargetDescription) { super(testTargetDescription); } abstract protected boolean validate(EObject objectToTest, BasicDiagnostic diagnostician, Map<Object, Object> map); protected void validateExpectSkip(final EObject objectToTest, final BasicDiagnostic diagnostician, final Map<Object, Object> map) { final boolean isValid = validate(objectToTest, diagnostician, map); assertTrue("ERROR EXPECT IGNORE " + CDAValidationTest.createAssertionFailureMessage(diagnostician, getTestTargetDescription()), isValid); } protected void validateExpectPass(final EObject objectToTest, final BasicDiagnostic diagnostician, final Map<Object, Object> map) { final boolean isValid = validate(objectToTest, diagnostician, map); assertTrue("ERROR EXPECT PASS " + CDAValidationTest.createAssertionFailureMessage(diagnostician, getTestTargetDescription()), isValid); } protected void validateExpectFail(final EObject objectToTest, final BasicDiagnostic diagnostician, final Map<Object, Object> map) { final boolean isValid = validate(objectToTest, diagnostician, map); ByteArrayOutputStream out = new ByteArrayOutputStream(); String xml = ""; try { CDAValidationTest.saveTestSnippet(objectToTest, out); xml = out.toString(); } catch (Exception e) { } assertTrue("ERROR EXPECT FAIL " + getTestTargetDescription() + "\" passed when it was expected to fail." + xml, !isValid); } } // CDAValidationTestCase // TemplateID Test Case protected abstract static class TemplateIDValidationTest extends CDAValidationTestCase { private static final String TEMPLATE_ID_FEATURE_NAME = "templateId"; private final String templateID; /** * @param templateID */ public TemplateIDValidationTest(final String templateID) { super(TEMPLATE_ID_FEATURE_NAME); this.templateID = templateID; } @Override public void doTest(final EObject objectToTest, final BasicDiagnostic diagnostician, final Map<Object, Object> map) { try { validateExpectFail(objectToTest, diagnostician, map); getTemplateIds(objectToTest).add(THE_BAD_II); validateExpectFail(objectToTest, diagnostician, map); getTemplateIds(objectToTest).add(createTheValidII()); validateExpectPass(objectToTest, diagnostician, map); } catch (final UnsupportedOperationException uoe) { fail(CDAValidationTest.createUnsupportedOperationFailureMessage(TEMPLATE_ID_FEATURE_NAME, uoe)); } } @SuppressWarnings("unchecked") private EList<II> getTemplateIds(final EObject objectToTest) { return (EList<II>) objectToTest .eGet(objectToTest.eClass().getEStructuralFeature(TEMPLATE_ID_FEATURE_NAME)); } private II createTheValidII() { final II retValue = DatatypesFactory.eINSTANCE.createII(); retValue.setRoot(templateID); return retValue; } } // TemplateIDValidationTest static abstract protected class UndefinedValidationTestCase extends CDAValidationTestCase { private final Set<String> eReferenceNames; protected UndefinedValidationTestCase(final String testTargetDescription, final Set<String> eReferenceNames) { super(testTargetDescription); this.eReferenceNames = eReferenceNames; } protected Set<String> getEReferenceNames() { return eReferenceNames; } protected String createEReferenceNotFoundMessage(final EObject objectToTest, final String eReferenceName) { return "EReference \"" + eReferenceName + "\" not found in \"" + objectToTest.eClass().getName() + "\""; } } // UndefinedValidationTestCase static abstract protected class UndefinedORValidationTestCase extends UndefinedValidationTestCase { public UndefinedORValidationTestCase(final String validationTargetDescription, final Set<String> eReferenceNames) { super(validationTargetDescription, eReferenceNames); } @Override protected void doTest(final EObject objectToTest, final BasicDiagnostic diagnostician, final Map<Object, Object> map) { // Validation should pass here as none of the references are set validateExpectPass(objectToTest, diagnostician, map); // Go through the references of the eObjectToValidate looking for // those which we will set and set them all. those which we will set // and test for validation failure. for (final String eReferenceName : getEReferenceNames()) { final EReference eReference = (EReference) objectToTest.eClass() .getEStructuralFeature(eReferenceName); assertNotNull(createEReferenceNotFoundMessage(objectToTest, eReferenceName), eReference); objectToTest.eSet(eReference, CDAFactory.eINSTANCE.create((EClass) (eReference.getEType()))); } // for each reference // Validation should fail here because not one is invalid validateExpectFail(objectToTest, diagnostician, map); // Now go through the same set unsetting, each in turn and // validating those which we will set and test for validation // failure. for (final String eReferenceName : getEReferenceNames()) { final EReference eReference = (EReference) objectToTest.eClass() .getEStructuralFeature(eReferenceName); final EObject temp = (EObject) objectToTest.eGet(eReference); objectToTest.eUnset(eReference); validateExpectPass(objectToTest, diagnostician, map); objectToTest.eSet(eReference, temp); } // for each reference } // doTest } // UndefinedORValidationTestCase static abstract protected class UndefinedXORValidationTestCase extends UndefinedValidationTestCase { public UndefinedXORValidationTestCase(final String validationTargetDescription, final Set<String> eReferenceNames) { super(validationTargetDescription, eReferenceNames); } @Override protected void doTest(final EObject objectToTest, final BasicDiagnostic diagnostician, final Map<Object, Object> map) { // Validation should fail here as none of the references are set validateExpectFail(objectToTest, diagnostician, map); // Go through the references of the eObjectToValidate looking for // those which we will set and set them all. for (final String eReferenceName : getEReferenceNames()) { final EReference eReference = (EReference) objectToTest.eClass() .getEStructuralFeature(eReferenceName); assertNotNull(createEReferenceNotFoundMessage(objectToTest, eReferenceName), eReference); objectToTest.eSet(eReference, CDAFactory.eINSTANCE.create((EClass) (eReference.getEType()))); } // for each reference // Validation should fail here because not one is invalid validateExpectFail(objectToTest, diagnostician, map); // Now go through the same set unsetting, each in turn and // validating for (final String eReferenceName : getEReferenceNames()) { final EReference eReference = (EReference) objectToTest.eClass() .getEStructuralFeature(eReferenceName); final EObject temp = (EObject) objectToTest.eGet(eReference); objectToTest.eUnset(eReference); validateExpectPass(objectToTest, diagnostician, map); objectToTest.eSet(eReference, temp); } // for each reference } // doTest } // UndefinedXORValidationTestCase static abstract protected class MutualExclusionValidationTestCase extends UndefinedValidationTestCase { public MutualExclusionValidationTestCase(final String validationTargetDescription, final Set<String> eReferenceNames) { super(validationTargetDescription, eReferenceNames); } @Override protected void doTest(final EObject objectToTest, final BasicDiagnostic diagnostician, final Map<Object, Object> map) { // Validation should fail here as none of the references are set validateExpectFail(objectToTest, diagnostician, map); initializeobjectToTest(objectToTest); // Make sure everything is valid now validateExpectPass(objectToTest, diagnostician, map); // Go through the references of the eObjectToValidate set them and // test for validation failure. for (final String eReferenceName : getEReferenceNames()) { final EReference eReference = (EReference) objectToTest.eClass() .getEStructuralFeature(eReferenceName); assertNotNull(createEReferenceNotFoundMessage(objectToTest, eReferenceName), eReference); // This should cause validation failure objectToTest.eSet(eReference, CDAFactory.eINSTANCE.create((EClass) (eReference.getEType()))); // Which we are expecting validateExpectFail(objectToTest, diagnostician, map); // Undo for the next reference objectToTest.eUnset(eReference); } // for each reference } // doTest abstract protected void initializeobjectToTest(EObject objectToTest); } // MutualExclusionValidationTestCase static abstract protected class CDAMutualExclusionValidationTestCase extends MutualExclusionValidationTestCase { /** * This is the list of the names of the EReferences that cannot be set * simultaneously. It is missing the name "act" because that reference * is always set, and the others are set individually in sequence (and * then unSet) to test that they invalidate the test. */ private static final Set<String> MUTUALLY_EXCLUSIVE_EREFERENCE_NAMES = new HashSet<String>( Arrays.asList(/* * "act" * , */"encounter", "observation", "observationMedia", "organizer", "procedure", "regionOfInterest", "substanceAdministration", "supply")); protected CDAMutualExclusionValidationTestCase(final String validationTargetDescription) { super(validationTargetDescription, MUTUALLY_EXCLUSIVE_EREFERENCE_NAMES); } } // CDAMutualExclusionValidationTestCase static protected String createUnsupportedOperationFailureMessage(final String testTargetDescription, final UnsupportedOperationException uoe) { return "The test \"" + testTargetDescription + "\" failed because of \"" + uoe.getMessage() + "\". This is likely due to errors in the OCL."; } static protected String createAssertionFailureMessage(final BasicDiagnostic diagnostician) { return createAssertionFailureMessage(diagnostician, ""); } static protected String createAssertionFailureMessage(final BasicDiagnostic diagnostician, final String source) { final StringBuilder sb = new StringBuilder(source); sb.append(": "); for (final Diagnostic diagnostic : diagnostician.getChildren()) { sb.append(" "); sb.append(diagnostic.getMessage()); } return sb.toString(); } private static void saveTestSnippet(EObject snippet, OutputStream out) throws Exception { ClinicalDocument containerDocument = CDAUtil.getClinicalDocument(snippet); if (containerDocument != null) { CDAUtil.save(EcoreUtil.copy(containerDocument), out); } else { CDAUtil.saveSnippet(EcoreUtil.copy(snippet), out); } } public interface TestObjectFactory<TestObject> { public TestObject create(); } protected abstract static class OperationsTestCase<ValidationTarget> extends CDAValidationTestCase { private boolean skipFailsTest = false; private boolean skipPassTest = false; private boolean skipNullFlavorTest = true; private boolean checkDependency = false; public void skipFailsTest() { skipFailsTest = true; } public void skipNullTest() { skipNullFlavorTest = true; } public void skipPassTest() { skipPassTest = true; } public void runDependencyTest() { checkDependency = true; } public abstract class PassTest { abstract public void updateToPass(ValidationTarget target); } public abstract class FailTest { abstract public void updateToFail(ValidationTarget target); } public void addPassTest(PassTest passTest) { passTests.add(passTest); } public void addFailTests() { } public void addPassTests() { } public void addFailTest(FailTest failTest) { failTests.add(failTest); } ArrayList<PassTest> passTests = new ArrayList<PassTest>(); ArrayList<FailTest> failTests = new ArrayList<FailTest>(); private static final String[] ENDTAGS = { "<failsnippet>", "</failsnippet>", "<passsnippet>", "</passsnippet>" }; private static final int FAILSNIPPET = 0; private static final int PASSSNIPPET = 2; private static String escapeXML(int snippetType, EObject objectToTest) { String xml = ""; try { ByteArrayOutputStream out = new ByteArrayOutputStream(); CDAValidationTest.saveTestSnippet(objectToTest, out); xml = StringEscapeUtils.escapeHtml(out.toString()); xml = xml.replace(System.getProperty("line.separator"), "<br/>"); } catch (Exception e) { } xml = ENDTAGS[snippetType] + "<br/>" + xml + "<br/>" + ENDTAGS[snippetType + 1]; return xml; } private static String generateSkipMessage(int snippetType, String message) { return ENDTAGS[snippetType] + "<br/>" + message + "<br/>" + ENDTAGS[snippetType + 1]; } protected TestObjectFactory<?> testObjectFactory; String testLogDir = null; public OperationsTestCase(String testTargetDescription, String ocl, TestObjectFactory<?> testObjectFactory) { super(testTargetDescription); this.ocl = ocl; this.testObjectFactory = testObjectFactory; testLogDir = System.getProperty("testlogdir"); if (testLogDir == null) { System.out.println(); System.out.println("Running " + getTestTargetDescription()); System.out.println(); } } private void runFails(StringBuffer xmlSnippetsBuffer) { boolean gotDiagnostic = false; for (FailTest failTest : failTests) { ValidationTarget target = (ValidationTarget) testObjectFactory.create(); BasicDiagnostic diagnostician = Diagnostician.INSTANCE.createDefaultDiagnostic((EObject) target); failTest.updateToFail(target); if (testLogDir != null) { xmlSnippetsBuffer.append(escapeXML(FAILSNIPPET, (InfrastructureRoot) target)); } else { try { System.out.println(); System.out.println("Fail Snippet"); CDAValidationTest.saveTestSnippet((EObject) target, System.out); System.out.println(); } catch (Exception e) { } } validateExpectFail((EObject) target, diagnostician, map); if (!gotDiagnostic) { gotDiagnostic = true; for (Diagnostic d : diagnostician.getChildren()) { String message = d.getMessage(); xmlSnippetsBuffer.append("<diagnostic>"); message = StringEscapeUtils.escapeHtml(message); message = message.replace(System.getProperty("line.separator"), "<br/>"); xmlSnippetsBuffer.append(message); xmlSnippetsBuffer.append("</diagnostic>"); } } } } private void runDependencies(StringBuffer xmlSnippetsBuffer) { boolean gotDiagnostic = false; for (FailTest failTest : failTests) { ValidationTarget target = (ValidationTarget) testObjectFactory.create(); BasicDiagnostic diagnostician = Diagnostician.INSTANCE.createDefaultDiagnostic((EObject) target); failTest.updateToFail(target); setDependency(target); if (testLogDir != null) { xmlSnippetsBuffer.append(escapeXML(FAILSNIPPET, (InfrastructureRoot) target)); } else { try { System.out.println(); System.out.println("Dependency Snippet"); CDAValidationTest.saveTestSnippet((EObject) target, System.out); System.out.println(); } catch (Exception e) { } } validateExpectPass((EObject) target, diagnostician, map); if (!gotDiagnostic) { gotDiagnostic = true; for (Diagnostic d : diagnostician.getChildren()) { String message = d.getMessage(); xmlSnippetsBuffer.append("<diagnostic>"); message = StringEscapeUtils.escapeHtml(message); message = message.replace(System.getProperty("line.separator"), "<br/>"); xmlSnippetsBuffer.append(message); xmlSnippetsBuffer.append("</diagnostic>"); } } } } private void runPasses(StringBuffer xmlSnippetsBuffer) { for (PassTest passTest : passTests) { ValidationTarget target = (ValidationTarget) testObjectFactory.create(); BasicDiagnostic diagnostician = Diagnostician.INSTANCE.createDefaultDiagnostic((EObject) target); passTest.updateToPass(target); if (testLogDir != null) { xmlSnippetsBuffer.append(escapeXML(PASSSNIPPET, (InfrastructureRoot) target)); } else { try { System.out.println(); System.out.println("Pass Snippet"); CDAValidationTest.saveTestSnippet((EObject) target, System.out); System.out.println(); } catch (Exception e) { } } validateExpectPass((EObject) target, diagnostician, map); } } private void appendToBuffer(StringBuffer xmlSnippetsBuffer, String startTag, String contents, String endTag) { if (testLogDir != null) { xmlSnippetsBuffer.append(startTag); contents = StringEscapeUtils.escapeHtml(contents); contents = contents.replace(System.getProperty("line.separator"), "<br/>"); xmlSnippetsBuffer.append(contents); xmlSnippetsBuffer.append(endTag); } else { System.out.println(); System.out.println(startTag); System.out.println(contents); System.out.println(endTag); System.out.println(); } } String ocl = null; protected EObject getObjectToSerialze() { return null; } @SuppressWarnings("unchecked") @Override public void doTest(EObject objectToTest, BasicDiagnostic diagnostician, Map<Object, Object> map) { StringBuffer xmlSnippetsBuffer = new StringBuffer(); try { appendToBuffer(xmlSnippetsBuffer, "<ocl>", ocl, "</ocl>"); if (!skipFailsTest) { if (!failTests.isEmpty()) { runFails(xmlSnippetsBuffer); } else { updateToFail((ValidationTarget) objectToTest); EObject objectToSerialize = (getObjectToSerialze() != null ? getObjectToSerialze() : objectToTest); // if (objectToSerialize instanceof EObject) { if (testLogDir != null) { xmlSnippetsBuffer.append(escapeXML(FAILSNIPPET, objectToSerialize)); } else { try { System.out.println(); System.out.println("Fail Snippet"); CDAValidationTest.saveTestSnippet(objectToSerialize, System.out); System.out.println(); } catch (Exception e) { } } // } validateExpectFail(objectToTest, diagnostician, map); for (Diagnostic d : diagnostician.getChildren()) { String message = d.getMessage(); appendToBuffer(xmlSnippetsBuffer, "<diagnostic>", message, "</diagnostic>"); } } } else { if (testLogDir != null) { xmlSnippetsBuffer.append(generateSkipMessage(FAILSNIPPET, "Skip Fail Test")); } else { System.out.println(); System.out.println("Skipped Fail Test"); System.out.println(); } } if (!skipPassTest) { if (!passTests.isEmpty()) { runPasses(xmlSnippetsBuffer); } else { updateToPass((ValidationTarget) objectToTest); EObject objectToSerialize = (getObjectToSerialze() != null ? getObjectToSerialze() : objectToTest); // if (objectToSerialize instanceof InfrastructureRoot) { if (testLogDir != null) { xmlSnippetsBuffer.append(escapeXML(PASSSNIPPET, objectToSerialize)); } else { try { System.out.println(); System.out.println("Pass Snippet"); CDAValidationTest.saveTestSnippet(objectToSerialize, System.out); System.out.println(); } catch (Exception e) { } } // } validateExpectPass(objectToTest, diagnostician, map); } } else { if (testLogDir != null) { xmlSnippetsBuffer.append(generateSkipMessage(FAILSNIPPET, "Skip Pass Test")); } else { System.out.println(); System.out.println("Skipped Pass Test"); System.out.println(); } } if (!skipNullFlavorTest) { EObject nullFlavorTest = (EObject) testObjectFactory.create(); updateToFail((ValidationTarget) nullFlavorTest); updateNullFlavor((ValidationTarget) nullFlavorTest); EObject objectToSerialize = (getObjectToSerialze() != null ? getObjectToSerialze() : nullFlavorTest); // if (objectToSerialize instanceof InfrastructureRoot) { if (testLogDir != null) { xmlSnippetsBuffer.append(escapeXML(PASSSNIPPET, objectToSerialize)); } else { try { System.out.println(); System.out.println("Null Flavor Snippet"); CDAValidationTest.saveTestSnippet(objectToSerialize, System.out); System.out.println(); } catch (Exception e) { } } // } validateExpectPass(nullFlavorTest, diagnostician, map); } else { if (testLogDir != null) { xmlSnippetsBuffer.append(generateSkipMessage(FAILSNIPPET, "Skip Pass Test")); } else { System.out.println(); System.out.println("Skipped Null Flavor Test"); System.out.println(); } } if (checkDependency) { if (!skipFailsTest) { if (!failTests.isEmpty()) { runDependencies(xmlSnippetsBuffer); } else { EObject dependencyTest = (EObject) testObjectFactory.create(); updateToFail((ValidationTarget) dependencyTest); setDependency((ValidationTarget) dependencyTest); EObject objectToSerialize = (getObjectToSerialze() != null ? getObjectToSerialze() : dependencyTest); // if (objectToSerialize instanceof EObject) { if (testLogDir != null) { xmlSnippetsBuffer.append(escapeXML(FAILSNIPPET, objectToSerialize)); } else { try { System.out.println(); System.out.println("Dependency Snippet"); CDAValidationTest.saveTestSnippet(objectToSerialize, System.out); System.out.println(); } catch (Exception e) { } } // } validateExpectPass(dependencyTest, diagnostician, map); for (Diagnostic d : diagnostician.getChildren()) { String message = d.getMessage(); appendToBuffer(xmlSnippetsBuffer, "<diagnostic>", message, "</diagnostic>"); } } } } } finally { try { String testName = String.format("%stest%s", StringUtils.split(this.getClass().getName(), "$")[0] + ".", getTestTargetDescription().substring(0, 1).toUpperCase() + getTestTargetDescription().substring(1)); if (testLogDir != null) { String logFileName = String.format("%s/test%s", testLogDir, getTestTargetDescription().substring(0, 1).toUpperCase() + getTestTargetDescription().substring(1) + ".xml"); FileWriter fstream = new FileWriter(logFileName); BufferedWriter out = new BufferedWriter(fstream); out.flush(); out.write("<testresult name=\"" + testName + "\">" + xmlSnippetsBuffer.toString() + "</testresult>"); out.close(); } else { // System.out.println("<testresult name=\"" + testName + "\">" + xmlSnippetsBuffer.toString() + // "</testresult>"); } } catch (Exception e) { System.err.println("Error: " + e.getMessage()); } } } public void doValidationTest() { addFailTests(); addPassTests(); EObject objectToTest = (EObject) testObjectFactory.create(); BasicDiagnostic diagnostician = Diagnostician.INSTANCE.createDefaultDiagnostic(objectToTest); doTest(objectToTest, diagnostician, map); } protected void updateToFail(ValidationTarget target) { }; protected void updateToPass(ValidationTarget target) { }; protected void setDependency(ValidationTarget target) { } private void setNullFlavor(Object target) { @SuppressWarnings("rawtypes") final java.lang.Class[] nullFlavorArgument = new java.lang.Class[] { org.eclipse.mdht.uml.hl7.vocab.NullFlavor.class }; try { Method initMethod = target.getClass().getMethod("setNullFlavor", nullFlavorArgument); if (initMethod != null) { initMethod.invoke(target, NullFlavor.NA); } } catch (Exception e) { e.printStackTrace(); } } private void setNullFlavors(EObject target, int level) { EClass eClass = target.eClass(); for (EStructuralFeature cdaFeature : eClass.getEAllStructuralFeatures()) { if (cdaFeature instanceof EReference) { EReference cdaReference = (EReference) cdaFeature; if (cdaReference.isMany()) { EList<EObject> eList = (EList<EObject>) (target).eGet(cdaReference); if (!eList.isEmpty()) { for (EObject eo : eList) { setNullFlavor(eo); setNullFlavors(eo, level++); } } else { // if (!cdaReference.getEReferenceType().isAbstract() && level == 1) { // EObject objectToAdd = cdaReference.getEReferenceType().getEPackage().getEFactoryInstance().create( // cdaReference.getEReferenceType()); // setNullFlavor(objectToAdd); // ((EList) (target).eGet(cdaReference)).add(objectToAdd); // } } } else { EObject eObject = (EObject) (target).eGet(cdaReference); if (eObject != null) { setNullFlavor(eObject); setNullFlavors(eObject, level++); } else { // if (!cdaReference.getEReferenceType().isAbstract() && level == 1) { // EObject objectToAdd = cdaReference.getEReferenceType().getEPackage().getEFactoryInstance().create( // cdaReference.getEReferenceType()); // setNullFlavor(objectToAdd); // (target).eSet(cdaReference, objectToAdd); // } } } } } } protected void updateNullFlavor(ValidationTarget target) { // setNullFlavor(NullFlavor newNullFlavor) { setNullFlavor(target); setNullFlavors((EObject) target, 1); }; } /** * An extension of the validation test case framework for testing the constraints that check the resolvability of references to narrative text as * defined in CDA Release 2 Section 4.3.5.1. */ protected static abstract class NarrativeReferenceTestCase<T> extends OperationsTestCase<T> { Section sectionToSerialize = null; @Override protected EObject getObjectToSerialze() { return sectionToSerialize; } public NarrativeReferenceTestCase(String testTargetDescription, String ocl, TestObjectFactory<?> testObjectFactory) { super(testTargetDescription, ocl, testObjectFactory); } protected static EClass getEClass(EPackage epackage, Class<?> instanceClass) { EClass result = null; for (EClassifier next : epackage.getEClassifiers()) { if (next.getInstanceClass() == instanceClass) { result = (EClass) next; break; } } assertNotNull(String.format("Instance class not found in package %s for %s.", epackage.getName(), instanceClass.getName()), result); return result; } protected static void addContainedElement(EObject container, EObject contained) { EReference best = null; for (EReference next : container.eClass().getEAllContainments()) { if (next.getEReferenceType().isInstance(contained)) { // a candidate. Is it better than the one we already have? if (best == null) { best = next; } else if (best.isMany() && !next.isMany()) { // always prefer scalar containment best = next; } else if (best.getEReferenceType().isSuperTypeOf(next.getEReferenceType())) { // prefer the more specific type best = next; } } } assertNotNull(String.format("Could not find containment reference for %s in %s.", contained.eClass().getName(), container.eClass().getName()), best); if (FeatureMapUtil.isMany(container, best)) { @SuppressWarnings("unchecked") Collection<EObject> list = (Collection<EObject>) best.eGet(best); list.add(contained); } else { container.eSet(best, contained); } } protected <S extends Section> S createSectionForClinicalStatement(ClinicalStatement statement, EPackage epackage, Class<? extends S> sectionType) { @SuppressWarnings("unchecked") S result = (S) epackage.getEFactoryInstance().create(getEClass(epackage, sectionType)); try { Method initMethod = result.getClass().getDeclaredMethod("init", new java.lang.Class[0]); if (initMethod != null) { initMethod.invoke(result, new Object[0]); } } catch (Exception e) { // e.printStackTrace(); } // create an entry for the statement and add the entry to the section Entry entry = CDAFactory.eINSTANCE.createEntry(); addContainedElement(entry, statement); result.getEntries().add(entry); return result; } protected CD createCDWithOriginalTextReference(String text, String reference) { CD result = DatatypesFactory.eINSTANCE.createCD(); result.setOriginalText(createEDWithReference(text, reference)); return result; } protected CE createCEWithOriginalTextReference(String text, String reference) { CE result = DatatypesFactory.eINSTANCE.createCE(); result.setOriginalText(createEDWithReference(text, reference)); return result; } protected ED createEDWithReference(String text, String reference) { ED result = DatatypesFactory.eINSTANCE.createED(text); if (!reference.startsWith("#")) { reference = "#" + reference; } result.setReference(DatatypesFactory.eINSTANCE.createTEL(reference)); return result; } protected StrucDocText createStrucDocText(String id, String text) { StrucDocText result = (CDAFactory.eINSTANCE.createStrucDocText()); try { Map<Object, Object> loadOptions = new java.util.HashMap<Object, Object>(); loadOptions.put(XMLResource.OPTION_RECORD_UNKNOWN_FEATURE, true); loadOptions.put(XMLResource.OPTION_SUPPRESS_DOCUMENT_ROOT, true); Resource xml = new XMLProcessor().load(new InputSource( new StringReader(String.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + // "<blurb xmlns=\"urn:hl7-org:v3\" ID=\"%s\">\n" + // " %s\n" + // "</blurb>\n", id, text))), loadOptions); AnyType stuff = (AnyType) xml.getContents().get(0); result.getMixed().add(ExtendedMetaData.INSTANCE.demandFeature("urn:hl7-org:v3", "content", true), stuff); } catch (Exception e) { Assert.fail("Failed to set up structured document text: " + e.getLocalizedMessage()); } return result; } protected void addText(Section section, String id, String text) { section.setText(createStrucDocText(id, text)); sectionToSerialize = section; } } } // CDAValidationTest