Design document of the Java implementation

Java openEHR Kernel - Design Document

0.Purpose

This document describes the design choices made in our Java implementation of the openEHR kernel. The openEHR specification is made on abstract level and agnostic about implementation technologies, therefore a number of design choices have been made for the work to be carried out. It also describes briefly the design for archetype based object creation, which is not yet covered by openEHR specification.

1.Overview

This software is a Java implementation of the openEHR kernel, which consists of Reference Model (EHR, EHR Extract, Demographic, Common, Data Structures, Data Types and Support) and the Archetype Object Model. Besides, there is support for archetype based object creation and validation implemented in Archetype Object Model classes.

2.Design Goals

  • Faithful to the specification
  • Java look-and-feel
  • Application agnostic

No doubt, being faithful to the specification is what implementation all about, otherwise there is no need for a specification. It all comes down to implement every packages, classes, methods, attributes and invariants.

Since this is a Java implementation, it should look like Java. The code and API should let Java programmers feel familiar to work with. It leads to use Java naming convention for different entities. See below for conversion rules between names in the openEHR specification and the Java code. It is also desired to use well known APIs, including both from the official Java APIs and other well known APIs, e.g. Jarkata Commons. Java idioms and patterns are used when appropriate.

It is intended to make this implementation independent to the environment where it is deployed. It should happily run within a command line tool with no graphic user interface, or within a full blown desktop application or as a component on the server side.

3.Java Platform

The Java platform targeted here is jdk1.5 mainly because of newly added support of generic types, which makes it much easier to implement the openEHR specification than without generics support. Annotations from jdk1.5 is also used to pass constructor parameters information into object creation process.

4.Assumed Types

The list of assumed types are quoted from openEHR Support Information Model document. The mapping to Java types is listed below:
Assumed TypeJava Type| Any | Object |

Boolean

Boolean, boolean

Character

Character, char

Integer

Integer, int

Integer_64

Long, long

Real

Float, float

Double

Double, double

String

String

Container

java.util.Collection

Array<T>

supported as first class object

List<T>

java.util.List<T>

Set<T>

java.util.Set<T>

Bag<T>

org.apache.commons.collections.bag

Interval

not supported

5.Naming

In general, naming of packages, classes, methods and attributes should follow the Java Naming Convention. It should be noticed that the conversion between names in the openEHR specification and names in the Java implementation can be automated.

5.1.Package Names

package names has "org.openehr." prefixed and "_" removed, e.g. rm.ehr_extract -> org.openehr.rm.ehrextract

5.2.Class Names

The first letter of each word in class name becomes upper cased and the rest of letters lower cased, and all "_" are removed, e.g. DV_CODED_TEXT -> DvCodedText

5.3.Attribute Names

Same as class names except the very first letter of the name is in lower case, e.g. calendar_alignment -> calendarAlignment

5.4.Method Names

Same as attribute names, e.g. is_strictly_comparable_to() -> isStrictlyComparableTo()

5.5.Accessors

For attributes (fields) that are declared by the specification are implemented as private fields and public accessors (getters) are provided.

6.Value Objects

Most of the Datatypes classes and classes from some other packages are essentially Value Objects, whose purpose is to pass values around. The equality of Value Object is not based on the identity but instead its values. Both equals() and hashCode() for all Value Objects are overridden to use the values of all relevant fields to obey general contract of both methods.

7.Immutable Objects

Most of classes in the reference model are good candidates of immutable object. Immutable objects are easier to design and implement than mutable objects. They are also easier to use and much safer.

8.Archetype Based Object Creation

warning: this part of work is not specified by openEHR

The logic for archetype based object creation mainly consists of following two parts: reference model class instantiation and archetype object tree traverse.

8.1.Reference Model Class Instantiation

This part of the logic is responsible for creating instance of the reference model classes. To achieve great flexibility, it is desired not to have specific construction knowledge, e.g. parameter validation information, for any reference model classes. The implementation is done in Class RMObjectBuilder in package org.openehr.rm.util together with annotations of constructor parameters in all concrete reference model classes. The interface of the build method takes the name of the class, of which an instance will be created and a collection of named values.

8.2.Archetype Object Tree Traverse

To be able to create upper level reference model classes instances like OBSERVATION and PERSON, lower level classes instances from data_structure and data_types have to be created in advance. Since an archetype instance is a constraint of an object model and dictates which specific object instance can be used for given object node, it makes sense to traverse the archetype model object tree to instantiate the reference model instance at the same time. So essentially the object creation process is traversing the archetype model object tree recursively and calling the RMObjectBuilder with data gathered along the way at each object node.

8.3.Constructor Annotations

Since the Java reflection API dose not support getting parameter names from methods or constructors, annotations is used to pass parameter names, optionalities information into object creation process. It is also used to indicate if the parameter is expected as input from the user or if it is supplied by the system at runtime.

8.4.Leaf Node Object Creation

In practice, it is preferred to have all error messages at once than one for each time. And most of the time, the input from the user is used for construction of leaf object node most likely data_types classes instance. Also sometimes it is possible to create objects by processing constraints from C_PRIMITIVE_OBJECT or C_DOMAIN_TYPE if the value has already been chosen there. Therefore, it is possible to go through all leaf object node to see if the input is required from the user or not, and if the input from the user has violated any leaf constraints before the traverse of object tree starts.

8.5.Input Interface

The input for object creation is assumedly divided into two categories, user input and system input. The system input must be supplied by the runtime system, which is normally achieved by direct programming. In case of user input, if the input from the user is required (not enough with the information from the constraint), a unique input identification is assigned to the node and will be used for binding the input value submitted from the user. All user input are regarded as string value and parsed into to the right type in the process.

8.6.Error Reporting

Errors occurring during the object creation are reported at two stages. At the first stage, all leaf node constraints are evaluated against the input. If there are any errors, they are all reported at the same time. After that, the object traverse starts and if any error occurs, the creation process will halt and report the error with the node path. Currently, there are a number of error types can be reported and the major ones are as following:

  1. MISSING, meaning a required input is missing from the user input
  2. BAD_VALUE, meaning an input is invalid according to the constraint
  3. BAD_FORMAT, meaning an input has wrong format

8.7.To Do

This work is in progress, the list below are the missing features that we are aware of and will try to implement in the future.

  • archetype chaining
  • archetype internal reference
  • dynamically adding children into C_MULTIPLE_ATTRIBUTE

Back to the Java project page