ADA Documentation

Revision as of 16:05, 23 December 2014 by Mdegraauw (talk | contribs) (Deploying an ADA App)

This chapter contains a walkthrough of ART DECOR Applications (ADA), for those who want to start building and deploying ADA apps. ADA apps are fully functional applications, generated from DECOR datasets, transactions and valueSets.

ADA is an ideal tool for:

  • rapid prototyping, to show care providers what the DECOR specs functionally mean;
  • iterative improvement of DECOR specs, where feedback on the ADA app is used to improve the DECOR specs;
  • creating realistic examples, since care providers themselves can provide those using ADA,
  • to make examples in a simplified XML format, to be used as the basis for conversion to HL7 or other formats.

ADA is not:

  • secure, so never use real patient data in ADA;
  • a complete application (i.e. there is no database with patient data from which to start, one tests only transactions);
  • a UI with the capabilities of a tailor-made interface - the focus is on functional completeness, not necessarily the optimal workflow for a real-life scenario.

Installing ADA

To get started with the examples, you'll need ADA Core checked out to a local directory. Either get it from SourceForge, or install the ADA package in eXist and copy that to disk.

Start with this layout:

 - ada
   - core (for ada/core)
   - projects
     - my-project (we'll use demo1 in this Guide)
       - definitions
       - modules
       - new
       - schemas
       - views
       - xslt

After downloading ADA, ada/projects/empty contains the layout to get you started.

Note: For the time being, and only for a local installation (in the future, the ART DECOR installer will take care of this), ADA needs the following in Orbeon's page-flow.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!-- ADA regex, {hostname}/art-decor/ada/{project-prefix}/views/{form.xhtml?query} , i.e.: http://localhost:8080/art-decor/ada/demo1/meting_formulier.xhtml?id=f44fa79d-6673-425f-af0a-e30feaca5401 -->
<page id="ada" path-info="/ada/([^/]*)/views/([^/]*)" matcher="oxf:perl5-matcher" view="http://localhost:8877/ada/projects/${1}/views/${2}"/>

And the following in properties-local.xml:

<?xml version="1.0" encoding="UTF-8"?>
<property as="xs:anyURI" name="ada.exist.url" value="http://localhost:8877/apps/ada"/>
<property as="xs:anyURI" name="ada.external.exist.url" value="http://localhost:8877/apps/ada"/>

ADA Applications

ADA starts with a DECOR release, as made in the ART project form. Make one (or refer to an existing one), and retrieve the URI to it through: http://localhost:8877/decor/services/ProjectIndex (Throughout this Guide, we'll use localhost:8877 for the host - use another if you don't run a local instance on port 8877). Search for your project, and get an URL like this one: http://localhost:8877/decor/services/RetrieveTransaction?id=2.16.840.1.113883.3.1937.99.62.3.4.2&language=en-US&version=2014-05-12T14:02:55&format=xml

With RetrieveTransaction, a decor/transaction is 'enhanced' with all the goodies the dataset and terminology provide. It is:

  • a decor transaction
  • with the tree view from the dataset
  • all concept adornments (names, valueDomains, you name it) from the dataset
  • for every valueDomain of type 'code', the relevant valueSet pulled in
  • and all this filtered for just one particular language so you don't need to worry about stuff you don't need to worry about.

ADA Definitions

Now make an ADA definition file in /projects/my-project/definitions and call it demoapp-ada.xml. Here's an overview of the structure.

<?xml version="1.0" encoding="UTF-8"?>
<ada ...>
    <project ...>
        <release ...>
    </project>
    <applications>
        <application ...>
            <views>
                <view ...>
                    <name>...</name>
                    <concepts include="all">
                        <concept ...>
                        <concept ...>
                    </concepts>
                </view>
            </views>
        </application>
    </applications>
</ada>

The root is called /ada, below are:

project

<project prefix="demo1-" language="en-US" versionDate="2014-05-12T14:02:55">
     <release baseUri="http://localhost:8877/decor/services/RetrieveTransaction"/>
</project>

Change the following:

  • set project/@prefix to your project prefix (for documentation only)
  • set project/@language to the language from the RetrieveTransaction link
  • set project/@versionDate to the date from the RetrieveTransaction link

ADA retrieves all necessary information from the RetrieveTransaction service. Make sure this is OK (like, all names for the required language are provided, valueSets are present in the concepts etc.). If not all is present - ADA is a really good way to test the completeness of your DECOR specs. Just generate an ADA app, run it and see what's missing.

application

Next comes a bit of housekeeping.

<applications>
    <application version="1">
        <views>
            <view ...>
            </view>
        </views>
    </application>
</applications>

Everything except the application/@version this is just a way to get you to where it really happens: the view. An ADA view is - basically - an enhanced version of the RetrieveTransaction output, just like RetrieveTransaction itself is an enhanced version of a DECOR transaction. The ADA view allows you to add in UI necessities:

  • widgets
  • tabs
  • links between views (such as an index which points to detail views)
  • and more, and still more to come.

view

The ADA view is where it all happens. Views need:

  • a view/@type (we'll use 'crud' and 'index' in this walkthrough)
  • a view/@target (for which we'll explore 'xforms' and 'xquery' - html is another obvious candidate)
  • a view/@transactionId and view/@transactionEffectiveDate (this of course identifies the corresponding DECOR transaction)
  • a view/name (which is shown in the browser)
  • one or more view/concepts. concepts come in two flavors:
    • concepts include='all' (All concepts in the DECOR transaction are shown. No concept children are needed, unless you want special processing for those.)
    • concepts include='only' (No concepts in the DECOR transaction are shown, except the children of <concepts>.)
  • concept/@ref points to a DECOR concept from the DECOR transaction
  • concept/@widget is used for UI specials (In this example, we'll create two tabs - of course, for a tabbed view, you might want to choose concepts groups on the same depth in the DECOR dataset tree.)

This view will constitute the main CRUD view to edit or create instances of this particular transaction. The transaction below is a 'measurement form', where a patient can periodically submit weight measurements to a registry (the example is meant to show all main DECOR constructs, and is admittedly somewhat artificial).

<view type="crud" target="xforms" 
    transactionId="2.16.840.1.113883.3.1937.99.62.3.4.2" 
    transactionEffectiveDate="2012-09-05T16:59:35">
    <name>Measurement Form</name>
    <concepts include="all">
        <concept ref="2.16.840.1.113883.3.1937.99.62.3.2.1" widget="tab"/>
        <concept ref="2.16.840.1.113883.3.1937.99.62.3.2.6" widget="tab"/>
    </concepts>
</view>

We'll make a second view, since we'll need an index of all weight measurements for lookups and edits. We'll list the concepts we want shown in the index (name and date of measurement, here).

<view type="index" target="xquery"
    transactionId="2.16.840.1.113883.3.1937.99.62.3.4.2" 
    transactionEffectiveDate="2012-09-05T16:59:35">
    <name>Metingen Lijst</name>
    <concepts include="only">
        <concept ref="2.16.840.1.113883.3.1937.99.62.3.2.4"/>
        <concept ref="2.16.840.1.113883.3.1937.99.62.3.2.2"/>
    </concepts>
</view>

That's all it takes to define an app! Now it's time for the ADA magic to happen.

Making an ADA release

The next step is to execute some of the ADA stylesheets. Use ada2release.xsl to transform the ADA definitions to a release:

 demoapp-ada.xml -> [ada2release.xsl] -> demoapp-ada-release.xml

This process pulls in all the information from RetrieveTransaction and combines it with the UI logic from ADA.

<view id="1" type="crud" target="xforms"
  transactionId="2.16.840.1.113883.3.1937.99.62.3.4.2" 
  transactionEffectiveDate="2012-09-05T16:59:35">
    <name>Measurement Form</name>
    <implementation shortName="measurement_form"/>
    <dataset id="2.16.840.1.113883.3.1937.99.62.3.1.1" 
      effectiveDate="2012-05-30T11:32:36" statusCode="draft"
      transactionId="2.16.840.1.113883.3.1937.99.62.3.4.2" 
      transactionEffectiveDate="2012-09-05T16:59:35" 
      shortName="measurement_message">
      <concept minimumMultiplicity="0" maximumMultiplicity="*" 
        conformance="" isMandatory="false" 
        id="2.16.840.1.113883.3.1937.99.62.3.2.1"
        statusCode="draft" effectiveDate="2012-05-30T11:32:36" 
        type="group" widget="tab">
        <name language="en-US">Measurement</name>
        <desc language="en-US">Measurement of body weight on a specific date</desc>
        <implementation shortName="measurement" 
          xpath="/hl7:registrationProcess/hl7:organizer"/>

It still looks a lot like an ADA definition, with:

  • a <dataset> element where <concepts> was
  • implementation elements with
    • a @shortName, which is used for (amongst others) XML element names
    • an @xpath expression which shows where this concept resides in a HL7 document (only if all templates and templateAssociations are present).
  • all other information from dataset/concept and transaction/concept
  • plus the ADA such as @widget

Generating an ADA App

The next step is convert demoapp-ada-release.xml to the necessary schemas, forms and other resources

 demoapp-ada-release.xml -> [release2newxml.xsl] -> empty XML
 demoapp-ada-release.xml -> [release2schema.xsl] -> XML Schema
 demoapp-ada-release.xml -> [release2xform.xsl]  -> XForms
 demoapp-ada-release.xml -> [release2xquery.xsl] -> XQuery modules

The ADA XML format

The first transform generates an empty ADA XML instance:

 ada/projects/demoapp/new/measurement_message.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--New XML generator, 2014-05-13T13:17:04.038+02:00-->
<measurement_message id="new" app="demoapp"
  transactionRef="2.16.840.1.113883.3.1937.99.62.3.4.2" 
  transactionEffectiveDate="2012-09-05T16:59:35"
  versionDate="2014-05-13T13:16:14" 
  prefix="demoapp-" language="en-US">
   <measurement conceptId="2.16.840.1.113883.3.1937.99.62.3.2.1">
      <weight conceptId="2.16.840.1.113883.3.1937.99.62.3.2.3" value="" unit="kg"/>
      <weight_gain conceptId="2.16.840.1.113883.3.1937.99.62.3.2.13" value="false"/>
      <weight_gain_data conceptId="2.16.840.1.113883.3.1937.99.62.3.2.18">
         <amount_of_weight_gain conceptId="2.16.840.1.113883.3.1937.99.62.3.2.19" value="" unit="gram"/>
         <cause_of_weight_gain conceptId="2.16.840.1.113883.3.1937.99.62.3.2.20" value=""/>
      </weight_gain_data>
      <datetime conceptId="2.16.840.1.113883.3.1937.99.62.3.2.2" value=""/>
      <measured_by conceptId="2.16.840.1.113883.3.1937.99.62.3.2.5" value="1"/>
      <remarks conceptId="2.16.840.1.113883.3.1937.99.62.3.2.17" value=""/>
   </measurement>
   <person conceptId="2.16.840.1.113883.3.1937.99.62.3.2.6">
      <name conceptId="2.16.840.1.113883.3.1937.99.62.3.2.4" value=""/>
      <bsn conceptId="2.16.840.1.113883.3.1937.99.62.3.2.7" value=""/>
      <date_of_birth conceptId="2.16.840.1.113883.3.1937.99.62.3.2.8" value=""/>
      <length conceptId="2.16.840.1.113883.3.1937.99.62.3.2.15" value="" unit="m"/>
   </person>
</measurement_message>

The ADA XML is a very straightforward XML format. It's design principles are readability, conciseness and following the dataset as closely as possible. It has:

  • an XML element name taken from @shortName (since shortName discards spaces and most special characters, and is all lowercase, DECOR concept names must yield unique shortNames for ADA to work)
  • the tree structure of the dataset, making it easy to navigate
  • an optional conceptId (it may be absent since it can be calculated from the ADA release info, if needed)
  • a @value attribute containing the entered value
  • a @unit attribute for quantities

ADA XML Schema

There are now two schemas:

 ada/projects/demoapp/schemas/measurement_message_draft.xsd
 ada/projects/demoapp/schemas/measurement_message.xsd

Both schemas validate the ADA XML format for measurement_message. The 'draft' version allows incomplete data to be stored in the database, i.e. when someone is filling out a complex form and wants to store it for later completion. A draft schema will allow @value and @unit to be absent on all nodes, even when mandatory in the transaction. The other schema checks all constraints from the dataset and scenario.

ADA Views and Modules

Our two views are stored in:

 ada/projects/demoapp/modules/index.xquery
 ada/projects/demoapp/forms/measurement_form.xhtml

We'll see those in action soon.

Deploying an ADA App

Install ADA into your eXist database. This will provide the following collections:

Collection Contains
apps/ada/core The stylesheets for ADA conversion. Not needed in eXist, but provided to make a complete package. The stylesheets are better run using an XML suite such as Oxygen XML.
apps/ada/helpers Here you'll find XQueries meant to be run in eXist manually (with eXide or from Oxygen). Mostly stuff to help you deploy your ADA apps.
apps/ada/modules Here are the XQueries central to ADA, for saving, getting and manipulating data. There are plenty of goodies for handling ADA data.
apps/ada/projects Each ADA App has its own collection below.
apps/ada/resources For now, ADA.css.

From helpers, open:

 create-project.xquery

Change $prefix to 'demoapp' and run. This will create the collection layout for your app. Then open:

 get-project-from-disk.xquery

Change $project to 'demoapp', $adaDir to the directory where the generated ADA app is, and run. This will import your app into the collection layout.

Collection Contains
apps/ada/projects/demoapp/data Where the ADA XML for this project will live.
apps/ada/projects/demoapp/definitions A copy of the ADA definition and ADA release. Just stored here for archival.
apps/ada/projects/demoapp/modules This now contains index.xquery for demoapp.
apps/ada/projects/demoapp/new The empty ADA XML template. Used in the XForms - don't edit this!
apps/ada/projects/demoapp/schemas Both the ADA XML Schema's.
apps/ada/projects/demoapp/views This now contains measurement_form.xhtml for demoapp.
apps/ada/projects/demoapp/xslt For later use, for stylesheets which transform ADA XML.

You may need to run:

 set-permissions.xquery

from helpers to give users access. This sets rather generous permissions: read access for all, and everyone in eXist group 'ada-user' can add records. Only the creator of a record can alter it.

Running the ADA App

Now point your browser to http://localhost:8877/ada/modules/index.xquery (or where your eXist lives). You may need to log into eXist, and should see something like:

Error creating thumbnail: Unable to save thumbnail to destination

with at least the demoapp included. Click demoapp to view

 http://localhost:8877/ada/projects/demoapp/modules/index.xquery

in action:

Error creating thumbnail: Unable to save thumbnail to destination

Not spectacular yet. Click 'New' to see:

 http://localhost:8080/art-decor/ada/demoapp/views/measurement_form.xhtml?id=new

This link tells ADA to use the measurement_form for a new (empty) instance. Note the red exclamation marks for data which is not yet valid. If you see nothing, or too little, you're probably not logged into ART. ADA uses the ART login for the time being for XForms. At the right top is a 'Login' link.

Error creating thumbnail: Unable to save thumbnail to destination

Fill out the form. You can add a second (or third, etc.) measurement with the '+ Measurement' button.

Error creating thumbnail: Unable to save thumbnail to destination

Don't forget the nice-looking tab2. This is where the ADA widgets came into action to create tabs.

Error creating thumbnail: Unable to save thumbnail to destination

Finally, save the data and return to the demoapp index:

Error creating thumbnail: Unable to save thumbnail to destination

We now see the two columns we defined for the index ('Datetime' and 'Name'). By default, ADA provides the username of the creator and the last update time.

The ADA XML data store

The ADA XML is stored in:

 apps/ada/projects/demoapp/data/491e3a76-bf50-4e21-ac5a-67d93d498aae.xml

or any other uuid your XQuery favors at the moment. In this file, you'll find:

<adaxml>
    <meta status="new" created-by="marc" last-update-by="marc" 
      creation-date="2014-05-12T16:47:48.789+02:00" 
      last-update-date="2014-05-12T16:47:48.789+02:00"/>
    <data>
        <measurement_message app="demoapp" 
        ...
          <weight conceptId="2.16.840.1.113883.3.1937.99.62.3.2.3" 
            value="86" unit="kg"/>
          ...
          <remarks conceptId="2.16.840.1.113883.3.1937.99.62.3.2.17"/>
          ...
        </measurement_message>
    </data>
</adaxml>

The actual ADA XML is wrapped in an adaxml element, with:

  • a <meta> element, with
    • @status ('new', but could be 'sent' or 'failed' etc.)
    • @created-by
    • @last-update-by
    • @creation-date
    • @last-update-date
  • a element, with the actual ADA XML message, note:
    • values and units are provided
    • concepts without values have no @value, ADA will add it upon retrieval for the XForm.

The ADA XML storage format allows for data conversion. I.e. next to adaxml/data a HL7 transformer could create an adaxml/hl7 element with the HL7 message, etc. But that's for later.