Hi Jim, Rong,

I am not yet up to speed on the Java code, but will give some generic 
answers, based on our previous Australian kernel implementation (based 
on the pre-openEHR GeHR models).

> Rong,
>
> I have a several questions related to the lifecycle of archetypes once 
> they are created.
>
>Question 1
>==========
>
>
> I use The following code fragment to create an object from an archetype
>
> rmobj = archetype.buildRMObject(valueMap, errorMap, sysmap());
>
> One of my constraints for this archetype is optional, as shown below
>
>ELEMENT[at0004] occurrences matches {0..1} matches  {
>value matches {
>    DVTEXT matches {
>        value matches {/.+/}
>    }
>}
>
>
> In the valueMap I don't supply a value for this element and therefore 
> it is not created. The 'rmobj' instance is created as expected.
>
> At some later stage, I want to record a value against ELEMENT[at0004]. 
> Do I need to manipulate the 'rmobj directly as shown below
>
>Account account = (Account)rmobj;
>Element element = new Element("isDebitAccount",
>    new DvText("isDebitAccount"), isDebitAccount);
>account.getDetails().items().add(element);
>
>
> or can I create it using a path expression?

Until we get a proper standardised API defined for this, you can do it 
how you like - as long as the archetype is respected. In our GeHR 
implementation, we had two ways of doing it, approximately as follows:

1. insert_at_path(some_path, an_element)
Note that the path here is the runtime path, which is always unique. You 
can thus always insert exactly where you want.

2. routines which navigated a cursor through a structure and then 
allowed an insert once you had arrived where you wanted. This kind of 
API had a lot of routines, and was a lot like a data structure library.

I now believe the path-based approach to be clearer, more concise (i.e. 
smaller API) and more in line with how people think today (i.e due to 
XML-indoctrination;-). But neither is more right technically speaking.

The main thing is that the insert_at_path() (or whatever you call it) 
call must check the relevant archetype node that the insertion is 
allowable, and it should fail if it is not. Your code should always know 
in advance what node this is, due to the choosing of archetypes 
beforehand (e.g. by the GUI forms).

Consider the example of the Address archetype at 
http://svn.openehr.org/knowledge/archetypes/dev/adl/openehr/demographic/openehr-demographic-address.location_address.draft.html.
 
The user might be trying to add a state/province ELEMENT. Either:
a) your software already created one of these at the create_default() 
stage, just waiting for the value to be filled in
b) since that ELEMENT is optional, your software did not create one, but 
somewhere on your GUI window was a way to add such a node; when the user 
hits the right button, the archetype path will be known, and the check 
can be made.
It might also be that the user wants to add a new ELEMENT which doesn't 
correspond to any of the predefined ELEMENTs; for this the correct 
archetype node is the [at9000] one.

>
>
> Question 2
> ==========
> Is there a programmatic way to validate that an object conforms to the 
> constraints of an archetype?

Every subclass of ARCHETYPE_CONSTRAINT from the archeytpe object model 
(AOM) 
(http://svn.openehr.org/specification/TRUNK/publishing/architecture/am/aom.pdf) 
should implement the method valid_value. Here are the signature from 
theEiffel class C_PRIMITIVE:

deferred class C_PRIMITIVE

inherit
    ANY
        redefine
            out
        end
       
feature -- Access

    default_value: ANY is
            --     generate a default value from this constraint object
        deferred
        ensure
            Result /= Void
        end
       
    assumed_value: like default_value
            -- assumed value for this constraint object
            -- FIXME: consider consolidating with assumed_value in 
C_DOMAIN_TYPE
       
feature -- Status Report

    valid_value (a_value: like default_value): BOOLEAN is
        require
            a_value /= Void
        deferred
        end
       
    has_assumed_value: BOOLEAN is
            -- True if there is an assumed value
        do
            Result := assumed_value /= Void
        end
       
feature -- Modification

    set_assumed_value(a_value: like assumed_value) is
            -- set `assumed_value'
        require
            a_value /= Void and then valid_value(a_value)
        do
            assumed_value := a_value
        ensure
            assumed_value_set: assumed_value = a_value
        end
       
feature -- Output

    as_string:STRING is
        deferred
        ensure
            Result_exists: Result /= Void
        end

    out: STRING is
        do
            Result := as_string
        end

invariant
    Assumed_value_valid: assumed_value /= Void implies 
valid_value(assumed_value)
   
end


These routines should actually be defined on ARCHETYPE_CONSTRAINT, not 
just C_PRIMITIVE, but I have not gotten around to doing this on my 
reference implementation yet. Don't worry too much about assumed_values 
if you don't want to yet, but the valid_value() method is needed. You 
need to implemented it for all the basic types, e.g. like the following 
(unfinished) for C_DATE_TIME:

    valid_value (a_value: DATE_TIME): BOOLEAN is
        do
            if interval /= Void then
                Result := interval.has(a_value)
            else
                -- Result := a_value matches pattern FIXME - to be 
implemented
                Result := True
            end
        end

For the types like C_OBJECT, the implementation of valid_value() just 
needs to be a recursive call to the same function in the children.

The short-term aim is to publish standard algorithms for all of these 
functions (it's only about 20 or less - just add up all the classes in 
Fig 6 and Fig 9 in the AOM.

So the programmatic approach is mostly solved by doing the 
implementation of this function in these classes. You also need to 
provide error messages for when the result is False.


>
> Question 3
> ==========
> This relates to an earlier question. Can you explain the how "|" works 
> in a path expression?

can you give more details on what you mean here?

- thomas

>
>

-
If you have any questions about using this list,
please send a message to d.lloyd at openehr.org

Reply via email to