User Documentation for MDHT Runtime APIsv3

advertisement
Revision:
Effective Date:
1
Author:
4/13/11
Allyson Weaver Bunker
User
Documentation
for MDHT
Runtime APIs
User Guide
User Documentation for MDHT Runtime APIs
Document History
Revision History
Revision
Number
Revision Date
1
4/13/2011
2
4/15/2011
Summary of Changes
Author
Allyson Weaver Bunker
Content Development/
Examples
USER DOCUMENTATION FOR MDHT RUNTIME APIS
4/13/2011
Page 2 of 18
Allyson Weaver Bunker
User Documentation for MDHT Runtime APIs
Table of Contents
1. Background ............................................................................................................... 4
2. Introduction – All About JARS ................................................................................... 5
2.1.
Required JARS for Using APIs ........................................................................................................ 5
2.2.
Instructions for Installation ............................................................................................................... 5
2.3.
How to Export .................................................................................................................................. 5
2.4.
MDHT Java Libraries Environment ................................................................................................. 5
2.5.
APIs ................................................................................................................................................. 8
2.6.
Patterns ........................................................................................................................................... 9
3. Using APIs .............................................................................................................. 10
3.1.
Produce ......................................................................................................................................... 10
3.2.
Consume ....................................................................................................................................... 15
3.3.
Validate ........................................................................................... Error! Bookmark not defined.
3.4.
Utility/Convenience ........................................................................................................................ 17
USER DOCUMENTATION FOR MDHT RUNTIME APIS
4/13/2011
Page 3 of 18
User Documentation for MDHT Runtime APIs
1. Background
An adapter for an EMR system essentially does one of the following:
1. Imports CDA documents into the EMR system and extracts information from the documents.
2. Extracts data from the EMR system to create a CDA document.
USER DOCUMENTATION FOR MDHT RUNTIME APIS
4/13/2011
Page 4 of 18
User Documentation for MDHT Runtime APIs
2. Introduction – setting up your environment
2.1.
Required JARS for Using APIs
1. List of required JARS for Using APIs
2.2.
Instructions for Installation
2.3.
How to Export
How to get the JARS out of the environment so that they can be used in an application.
2.4.
MDHT Java Libraries Environment
This describes the steps for creating the java libraries from the MDHT models and packaging them up with
the set of EMF and OCL run-time dependency libraries that are needed to provide a basic runtime library for
using MDHT artifacts.
1. Open the MDHT Workspace containing the models for which the run-time environment is needed.
2. Right-click on one of the projects and select "Export…" from the menu.
3. Expand the "Plug-in Development" folder
USER DOCUMENTATION FOR MDHT RUNTIME APIS
4/13/2011
Page 5 of 18
User Documentation for MDHT Runtime APIs
4. Select "Deployable plug-ins and fragments" and then click on "Next"
5. Select the projects that are to be exported as jar files… If doing all of the current ones then select the
following:
a. org.openhealthtools.mdht.uml.cda
b. org.openhealthtools.mdht.uml.cda.ccd
c. org.openhealthtools.mdht.uml.cda.cdt
d. org.openhealthtools.mdht.uml.cda.consol
e. org.openhealthtools.mdht.uml.cda.hitsp
f. org.openhealthtools.mdht.uml.cda.ihe
g. org.openhealthtools.mdht.uml.cda.datatypes
h. org.openhealthtools.mdht.uml.cda.rim
i. org.openhealthtools.mdht.uml.cda.vocab
USER DOCUMENTATION FOR MDHT RUNTIME APIS
4/13/2011
Page 6 of 18
User Documentation for MDHT Runtime APIs
6. Enter a directory for where to place the jar files on the "Destination" tab.
7. Click on "Finish"
8. This will create a jar file for each of the libraries in the location you specified. The current naming of the
jar files will be <project-name>_<version>.<timestamp>.jar
9. Once the libraries are generated for the MDHT models, you will need some additional eclipse libraries in
order to use these generated libraries. These libraries can be found in the eclipse environment. If you
are using the all-in-one download, then these will be in the eclipse\plugins folder. The following is the list
of libraries that are needed:
a. lpg.runtime.java_2.0.17.v201004271640.jar (NOTE: for Eclipse 3.5.x the OCL parser runtime
library may be net.sourceforge.lpg.lpgjavaruntime_1.1.0.v200803061910.jar)
b. org.eclipse.emf.common_2.6.0.v20100914-1218.jar
c. org.eclipse.emf.ecore_2.6.1.v20100914-1218.jar
d. org.eclipse.emf.ecore.xmi_2.5.0.v20100521-1846.jar
e. org.eclipse.ocl_3.0.1.R30x_v201008251030.jar
f. org.eclipse.ocl.ecore_3.0.1.R30x_v201008251030.jar
USER DOCUMENTATION FOR MDHT RUNTIME APIS
4/13/2011
Page 7 of 18
User Documentation for MDHT Runtime APIs
2.5.
APIs
API’s delivered by the JARS can be divided into three different levels. Each level builds upon the other.
API’s are an artifact that get generated or delivered by MDHT. You don’t need the user interface to be
installed to be able to see the runtime API’s.
HITSP C32, C83 APIs
Higher Level
IHE Patient Care Coordination (PCC) APIs
Continuity of Care Document (CCD) APIs
Base Level
Base Model APIs (CDA, Datatypes, Vocab, RIM)
Core Technology APIs (EMF, OCL)
Java Platform APIs
Low Level
API Descriptions
Low-level Technology APIs
These APIs come from the technology decisions made by the MDHT project. MDHT is based on Eclipse and
the Eclipse Modeling Framework. APIs at this level are related to the underlying EMF model and allow the
programmer to manipulate EMF objects in a uniform way and access metamodel information (e.g. EClasses,
EAnnotations, etc.). Typically, client code would not use the low-level APIs directly, however, there are
certain circumstances where the EMF reflection API is useful.
Generated CDA Base Model APIs
The base model APIs are generated from the MDHT base models for CDA. This includes HL7 CDA R2, HL7
Datatypes R1, HL7 Vocabulary and HL7 RIM. MDHT uses class inheritance in the CDA template models. All
methods defined at this level are inherited and available at higher levels. For example, a convenience method
“addSection” has been added to the ClinicalDocument class. This method can be used to add a Section
object directly to a ClinicalDocument object (without going through component.structuredBody.component).
This method is available in all subclasses of ClinicalDocument (e.g. ContinuityOfCareDocument and HITSP
PatientSummary).
Generated CDA Template Model APIs
This APIs, exist (logically) at a higher level in the stack as they are built on top of the APIs below them. They
typically include domain-specific class names that follow the CDA templates that they represent (e.g. CCD
ProblemAct, HITSP Condition). They also include “getter” methods to access subordinate templates. For
example, if a document-level template has an association to a section-level template in the model, then a
“getter’ method for the section-level template exists in the document-level template class.
USER DOCUMENTATION FOR MDHT RUNTIME APIS
4/13/2011
Page 8 of 18
User Documentation for MDHT Runtime APIs
Utility / Convenience APIs
There are additional Utility APIs that facilitate the process of producing, consuming and validating CDA
documents. The CDAUtil class contains load/save/validate methods, a Query/Filter API, OCL check/query
and a CDAXPath adapter API. The details of these APIs will be discussed later in the document.
2.6.
Patterns
Patterns used in the document are important to notice. There will be patterns that are dictated by the
technology. This determines the way the generated code looks and how the API’s are used to produce,
consume and validate CDA documents.
Interface/Implementation Classes
For every class defined in a CDA template UML model, there is a Java interface and Java implementation
class generated. For example, the ContinuityOfCareDocument class becomes ContinuityOfCareDocument
interface and ContinuityOfCareDocumentImpl class. Any client code that needs to use the
ContinuityOfCareDocument will do so via the ContinuityOfCareDocument interface.
Singleton Factory Class to Create Instances
In order to create an instance of a class, client code must do so via a singleton factory class. Each CDA
template model generates an EMF Package which corresponds to a set of generated Java packages. Each
EMF Package also gets a singleton Factory class to create instances of classes in that package.
ContinuityOfCareDocument ccdDocument =
CCDFactory.eINSTANCE.createContinuityOfCareDocument().init();
ContinuityOfCareDocument
// create an initialize an instance of
This pattern applies to the generated base model APIs as well as the CDA template model APIs. In this
example above, there is an additional method call to init(). This method is called to initialize the object where
all default/fixed values get automatically populated. This reduces the amount of code necessary to create a
conformant object. The init() method is only found in the generated CDA template model APIs
EMF Package Registration for Deserialization
In order to deserialize a CDA document into the appropriate template classes based on template identifiers in
the template instance, EMF Package Registry needs to know what models exist in the environment. When
using MDHT in standalone Java applications, the generated singleton Package class must but “touched”
once at the beginning of the code:
CCDPackage.eINSTANCE.eClass();
// static package registration
In this example, we are telling the EMF Package registry that we have CCD (and all of it’s dependent) models
available in the environment. If the deserializer encounters a template id from CCD, it will deserialize that part
of the XML instance into the template class that corresponds to that template id.
USER DOCUMENTATION FOR MDHT RUNTIME APIS
4/13/2011
Page 9 of 18
User Documentation for MDHT Runtime APIs
3. Using APIs
3.1.
Produce
1. Produce: GOAL Write/produce/construct a CDA document - Using the APIs to programmatically
construct an instance. When someone needs to produce an instance they have clinical data and
want to get it into CDA format. They will use Java APIs to programmatically construct a CDA in XML
format.
// create and initialize an instance of the ContinuityOfCareDocument class
ContinuityOfCareDocument ccdDocument =
CCDFactory.eINSTANCE.createContinuityOfCareDocument().init();
// create a patient role object and add it to the document
PatientRole patientRole = CDAFactory.eINSTANCE.createPatientRole();
ccdDocument.addPatientRole(patientRole);
II id = DatatypesFactory.eINSTANCE.createII();
patientRole.getIds().add(id);
id.setRoot("996-756-495");
id.setExtension("2.16.840.1.113883.19.5");
// create an address object and add it to patient role
AD addr = DatatypesFactory.eINSTANCE.createAD();
patientRole.getAddrs().add(addr);
addr.getUses().add(PostalAddressUse.H);
addr.addStreetAddressLine("1313 Mockingbird Lane");
addr.addCity("Janesville");
addr.addState("WI");
addr.addPostalCode("53545");
// create a patient object and add it to patient role
Patient patient = CDAFactory.eINSTANCE.createPatient();
patientRole.setPatient(patient);
PN name = DatatypesFactory.eINSTANCE.createPN();
patient.getNames().add(name);
name.addGiven("Henry");
name.addFamily("Levin");
CE administrativeGenderCode = DatatypesFactory.eINSTANCE.createCE();
patient.setAdministrativeGenderCode(administrativeGenderCode);
administrativeGenderCode.setCode("M");
administrativeGenderCode.setCodeSystem("2.16.840.1.113883.5.1");
TS birthTime = DatatypesFactory.eINSTANCE.createTS();
patient.setBirthTime(birthTime);
birthTime.setValue("19320924");
USER DOCUMENTATION FOR MDHT RUNTIME APIS
4/13/2011
Page 10 of 18
User Documentation for MDHT Runtime APIs
[Discussion about creating document instance]
// create and initialize the CCD alerts section
AlertsSection alertsSection = CCDFactory.eINSTANCE.createAlertsSection().init();
ccdDocument.addSection(alertsSection);
// set up the narrative (human-readable) text portion of the alerts section
StringBuffer buffer = new StringBuffer();
buffer.append("<table border=\"1\" width=\"100%\">");
buffer.append("<thead>");
buffer.append("<tr>");
buffer.append("<th>Substance</th>");
buffer.append("<th>Reaction</th>");
buffer.append("<th>Status</th>");
buffer.append("</tr>");
buffer.append("</thead>");
buffer.append("<tbody>");
buffer.append("<tr>");
buffer.append("<td>Penicillin</td>");
buffer.append("<td>Hives</td>");
buffer.append("<td>Active</td>");
buffer.append("</tr>");
buffer.append("</tbody>");
buffer.append("</table>");
alertsSection.createStrucDocText(buffer.toString());
[Discussion about creating alerts section and narrative block]
// create and initialize a CCD problem act
ProblemAct problemAct = CCDFactory.eINSTANCE.createProblemAct().init();
alertsSection.addAct(problemAct);
id = DatatypesFactory.eINSTANCE.createII();
problemAct.getIds().add(id);
id.setRoot(UUID.randomUUID().toString());
[Discussion about creating problem act]
// create and initialize an alert observation within the problem act
AlertObservation alertObservation =
CCDFactory.eINSTANCE.createAlertObservation().init();
problemAct.addObservation(alertObservation);
((EntryRelationship)
alertObservation.eContainer()).setTypeCode(x_ActRelationshipEntryRelationship.SU
BJ);
id = DatatypesFactory.eINSTANCE.createII();
alertObservation.getIds().add(id);
id.setRoot(UUID.randomUUID().toString());
USER DOCUMENTATION FOR MDHT RUNTIME APIS
4/13/2011
Page 11 of 18
User Documentation for MDHT Runtime APIs
CD code = DatatypesFactory.eINSTANCE.createCD();
alertObservation.setCode(code);
code.setCode("ASSERTION");
code.setCodeSystem("2.16.840.1.113883.5.4");
CS statusCode = DatatypesFactory.eINSTANCE.createCS();
alertObservation.setStatusCode(statusCode);
statusCode.setCode("completed");
CD value = DatatypesFactory.eINSTANCE.createCD();
alertObservation.getValues().add(value);
value.setCode("282100009");
value.setCodeSystem("2.16.840.1.113883.6.96");
value.setDisplayName("Adverse reaction to substance");
[Discussion about creating alert observation]
// playing entity contains coded information on the substance
Participant2 participant = CDAFactory.eINSTANCE.createParticipant2();
alertObservation.getParticipants().add(participant);
participant.setTypeCode(ParticipationType.CSM);
ParticipantRole participantRole = CDAFactory.eINSTANCE.createParticipantRole();
participant.setParticipantRole(participantRole);
participantRole.setClassCode(RoleClassRoot.MANU);
PlayingEntity playingEntity = CDAFactory.eINSTANCE.createPlayingEntity();
participantRole.setPlayingEntity(playingEntity);
playingEntity.setClassCode(EntityClassRoot.MMAT);
CE playingEntityCode = DatatypesFactory.eINSTANCE.createCE();
playingEntity.setCode(playingEntityCode);
playingEntityCode.setCode("70618");
playingEntityCode.setCodeSystem("2.16.840.1.113883.6.88");
playingEntityCode.setDisplayName("Penicillin");
[Discussion about creating playing entity]
// reaction observation contains coded information on the adverse reaction
ReactionObservation reactionObservation =
CCDFactory.eINSTANCE.createReactionObservation().init();
alertObservation.addObservation(reactionObservation);
((EntryRelationship)
reactionObservation.eContainer()).setTypeCode(x_ActRelationshipEntryRelationship
.MFST);
((EntryRelationship)
reactionObservation.eContainer()).setInversionInd(Boolean.TRUE);
code = DatatypesFactory.eINSTANCE.createCD();
reactionObservation.setCode(code);
USER DOCUMENTATION FOR MDHT RUNTIME APIS
4/13/2011
Page 12 of 18
User Documentation for MDHT Runtime APIs
code.setCode("ASSERTION");
code.setCodeSystem("2.16.840.1.113883.5.4");
statusCode = DatatypesFactory.eINSTANCE.createCS();
reactionObservation.setStatusCode(statusCode);
statusCode.setCode("completed");
value = DatatypesFactory.eINSTANCE.createCD();
reactionObservation.getValues().add(value);
value.setCode("247472004");
value.setCodeSystem("2.16.840.1.113883.6.96");
value.setDisplayName("Hives");
[Discussion about creating reaction observation]
// alert status contains information about whether allergy is currently active
AlertStatusObservation alertStatusObservation =
CCDFactory.eINSTANCE.createAlertStatusObservation().init();
alertObservation.addObservation(alertStatusObservation);
((EntryRelationship)
alertStatusObservation.eContainer()).setTypeCode(x_ActRelationshipEntryRelations
hip.REFR);
CE alertStatusObservationValue = DatatypesFactory.eINSTANCE.createCE();
alertStatusObservation.getValues().add(alertStatusObservationValue);
alertStatusObservationValue.setCode("55561003");
alertStatusObservationValue.setCodeSystem("2.16.840.1.113883.6.96");
alertStatusObservationValue.setDisplayName("Active");
[Discussion about creating alert status]
// write the document out to the console
CDAUtil.save(ccdDocument, System.out);
[Discussion about serializing the document to XML]
<?xml version="1.0" encoding="UTF-8"?>
<ClinicalDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:hl7-org:v3" xsi:schemaLocation="urn:hl7-org:v3 CDA.xsd">
<templateId root="2.16.840.1.113883.10.20.1"/>
<code code="34133-9" codeSystem="2.16.840.1.113883.6.1" codeSystemName="LOINC"
displayName="Summarization of episode note"/>
<recordTarget>
<patientRole>
<id root="996-756-495" extension="2.16.840.1.113883.19.5"/>
<addr use="H"><streetAddressLine>1313 Mockingbird
Lane</streetAddressLine><city>Janesville</city><state>WI</state><postalCode>5354
5</postalCode></addr>
USER DOCUMENTATION FOR MDHT RUNTIME APIS
4/13/2011
Page 13 of 18
User Documentation for MDHT Runtime APIs
<patient>
<name><given>Henry</given><family>Levin</family></name>
<administrativeGenderCode code="M" codeSystem="2.16.840.1.113883.5.1"/>
<birthTime value="19320924"/>
</patient>
</patientRole>
</recordTarget>
<component>
<structuredBody>
<component>
<section>
<templateId root="2.16.840.1.113883.10.20.1.2"/>
<code code="48765-2" codeSystem="2.16.840.1.113883.6.1"
codeSystemName="LOINC" displayName="Allergies, adverse reactions, alerts"/>
<text><table border="1"
width="100%"><thead><tr><th>Substance</th><th>Reaction</th><th>Status</th></tr><
/thead><tbody><tr><td>Penicillin</td><td>Hives</td><td>Active</td></tr></tbody><
/table></text>
<entry>
<act classCode="ACT" moodCode="EVN">
<templateId root="2.16.840.1.113883.10.20.1.27"/>
<id root="a7140229-4a87-457a-b63e-50b79c57dfa1"/>
<code nullFlavor="NA"/>
<entryRelationship typeCode="SUBJ">
<observation moodCode="EVN">
<templateId root="2.16.840.1.113883.10.20.1.18"/>
<id root="85d9039f-d254-4d5b-86d1-7500279f0454"/>
<code code="ASSERTION" codeSystem="2.16.840.1.113883.5.4"/>
<statusCode code="completed"/>
<value xsi:type="CD" code="282100009"
codeSystem="2.16.840.1.113883.6.96" displayName="Adverse reaction to
substance"/>
<participant typeCode="CSM">
<participantRole classCode="MANU">
<playingEntity classCode="MMAT">
<code code="70618" codeSystem="2.16.840.1.113883.6.88"
displayName="Penicillin"/>
</playingEntity>
</participantRole>
</participant>
<entryRelationship typeCode="MFST" inversionInd="true">
<observation classCode="OBS" moodCode="EVN">
<templateId root="2.16.840.1.113883.10.20.1.54"/>
<code code="ASSERTION"
codeSystem="2.16.840.1.113883.5.4"/>
<statusCode code="completed"/>
<value xsi:type="CD" code="247472004"
codeSystem="2.16.840.1.113883.6.96" displayName="Hives"/>
</observation>
</entryRelationship>
<entryRelationship typeCode="REFR">
<observation classCode="OBS" moodCode="EVN">
<templateId root="2.16.840.1.113883.10.20.1.57"/>
<templateId root="2.16.840.1.113883.10.20.1.39"/>
USER DOCUMENTATION FOR MDHT RUNTIME APIS
4/13/2011
Page 14 of 18
User Documentation for MDHT Runtime APIs
<code code="33999-4" codeSystem="2.16.840.1.113883.6.1"
codeSystemName="LOINC" displayName="Status"/>
<statusCode code="completed"/>
<value xsi:type="CE" code="55561003"
codeSystem="2.16.840.1.113883.6.96" displayName="Active"/>
</observation>
</entryRelationship>
</observation>
</entryRelationship>
</act>
</entry>
</section>
</component>
</structuredBody>
</component>
</ClinicalDocument>
[Discussion of XML instance]
3.2.
Consume
1. Consume: Someone sends standard compliance document and needs to extract data and save to
the system. Using API’s to extract specific information.
2. Query Filter Operation
// static package registration
CCDPackage.eINSTANCE.eClass();
[Discussion of static package registration]
// load sample continuity of care document from file
ContinuityOfCareDocument ccdDocument = (ContinuityOfCareDocument)
CDAUtil.load(new FileInputStream("resources/SampleCCDDocument.xml"));
[Discussion of loading document from file]
// get the alerts section from the document using domain-specific "getter"
method
AlertsSection alertsSection = ccdDocument.getAlertsSection();
[Discussion of getting the alerts section from the document]
// for each enclosing problem act
USER DOCUMENTATION FOR MDHT RUNTIME APIS
4/13/2011
Page 15 of 18
User Documentation for MDHT Runtime APIs
for (ProblemAct problemAct : alertsSection.getProblemActs()) {
// look at subordinate observations
//
we don't have a domain-specific "getter" method here so we use
//
entry relationship
for (EntryRelationship entryRelationship :
problemAct.getEntryRelationships()) {
// check for alert observation
if (entryRelationship.getObservation() instanceof AlertObservation) {
// see below for details...
}
}
}
[Discussion of looping over problem acts looking for AlertObservations]
// get coded value from alert observation
AlertObservation alertObservation = (AlertObservation)
entryRelationship.getObservation();
if (!alertObservation.getValues().isEmpty()
&& alertObservation.getValues().get(0) instanceof CD) {
CD value = (CD) alertObservation.getValues().get(0);
System.out.println("alert observation value: " + value.getCode() + ", " +
value.getCodeSystem() + ", " + value.getDisplayName());
}
[Discussion about getting the coded value from the alert observation[
// search through the participants for this alert observation to find
//
the playing entity that contains substance information
PlayingEntity playingEntity = null;
for (Participant2 participant : alertObservation.getParticipants()) {
// here we must match on participation type
if (ParticipationType.CSM.equals(participant.getTypeCode())) {
ParticipantRole participantRole = participant.getParticipantRole();
// here we must match on class code
if (participantRole != null &&
RoleClassRoot.MANU.equals(participantRole.getClassCode())) {
playingEntity = participantRole.getPlayingEntity();
// here we match on class code
if (playingEntity != null
&& EntityClassRoot.MMAT.equals(playingEntity.getClassCode())) {
// we found it
break;
} else {
playingEntity = null;
}
}
}
}
USER DOCUMENTATION FOR MDHT RUNTIME APIS
4/13/2011
Page 16 of 18
User Documentation for MDHT Runtime APIs
if (playingEntity != null) {
CE code = playingEntity.getCode();
if (code != null) {
System.out.println("playing entity value: " + code.getCode() + ", " +
code.getCodeSystem() + ", " + code.getDisplayName());
}
}
[Discussion about playing entity[
// get reaction observations using domain-specific "getter" method
for (ReactionObservation reactionObservation :
alertObservation.getReactionObservations()) {
if (!reactionObservation.getValues().isEmpty()
&& alertObservation.getValues().get(0) instanceof CD) {
CD value = (CD) reactionObservation.getValues().get(0);
System.out.println("reaction observation value: " + value.getCode() + ",
" + value.getCodeSystem() + ", " + value.getDisplayName());
}
[Discussion about getting reaction observations[
// get alert status observation using domain-specific "getter" method
AlertStatusObservation alertStatusObservation =
alertObservation.getAlertStatusObservation();
if (alertStatusObservation != null &&
!alertStatusObservation.getValues().isEmpty()
&& alertObservation.getValues().get(0) instanceof CD) {
CD value = (CD) alertStatusObservation.getValues().get(0);
System.out.println("alert status observation value: " + value.getCode() + ",
" + value.getCodeSystem() + ", " + value.getDisplayName());
}
[Discussion about getting alert status observation]
3.3.
Validate
1. Upfront discussion of how EMF does validation.
Validate: Using general API’s to validate instance against constraints in the model.
3.4.
Utility/Convenience
1. Another case of API’s is separate from the general model code. CDA utilities have numerous
methods.
USER DOCUMENTATION FOR MDHT RUNTIME APIS
4/13/2011
Page 17 of 18
User Documentation for MDHT Runtime APIs
USER DOCUMENTATION FOR MDHT RUNTIME APIS
4/13/2011
Page 18 of 18
Download