felix@3038: This document describes how the datacage configuration works, from a user
felix@3038: perspective.  Some rather technical details are omitted and mechanisms
felix@3038: simplified.
felix@3038: 
felix@3033: The datacages behaviour is defined in the file conf/meta-data.xml .
felix@3033: 
felix@3033: The datacage serves two purposes.
felix@3033: It handles automatic 'recommendations', which are instructions
felix@3033: sent by the client to add newly created artifacts to the collection.
felix@3033: From a user perspective, these artifacts mainly represent curves or data
felix@3033: points in the resulting diagrams.
felix@3033: The second task is to let the user add already existing artifacts (i.e.
felix@3033: previous calculations) or new artifacts with access to related data.
felix@3033: 
felix@3033: Irrelevant of the type of elements (recommendations or user picked data) the
felix@3033: datacage can iterate over possible artifacts by accessing its own database.
felix@3033: Thus, to create a list of matching entries, database queries are used.
felix@3033: 
felix@3033: In meta-data.xml, database queries are defined as <dc:statement> elements,
felix@3033: for example
felix@3033:                 <dc:statement>
felix@3033:                   SELECT id          AS prot_id,
felix@3033:                          description AS prot_description
felix@3033:                   FROM wsts WHERE kind = 1 AND river_id = ${river_id}
felix@3033:                 </dc:statement>
felix@3033: 
felix@3033: As can be seen from the example, the datacage configuration file can maintain
felix@3033: its own stack of variables (${river_id} in above example).
felix@3038: 
felix@3038: The database query will usually deliver one or many results, over which is
felix@3038: iterated using the <dc:elements> elements.
felix@3038: 
felix@3038: Information from this results can be used for two goals.
felix@3038: It can be taken as output, in which
felix@3038: case the client will either request the creation of these artifacts (considering
felix@3038: recommendations), or shown by the client in a the 'datacage widget',
felix@3038: the graphical representation of data which can be added in the current
felix@3038: context.  The later is seen when the user clicks on the Datacage button in
felix@3038: a diagram.
felix@3038: Or information can be used to feed a second (or third...) database query.
felix@3038: Following above example:
felix@3038: 
felix@3038:                 <dc:statement>
felix@3038:                   SELECT id          AS prot_id,
felix@3038:                          description AS prot_description
felix@3038:                   FROM wsts WHERE kind = 1 AND river_id = ${river_id}
felix@3038:                 </dc:statement>
felix@3038:                 <dc:elements>
felix@3038:                   <additional>
felix@3038:                     <dc:attribute name="name" value="${prot_description}"/>
felix@3038:                     <dc:context>
felix@3038:                       <dc:statement>
felix@3038:                         SELECT id       AS prot_column_id,
felix@3038:                                name     AS prot_column_name,
felix@3038:                                position AS prot_rel_pos
felix@3038:                         FROM wst_columns WHERE wst_id = ${prot_id}
felix@3038:                         ORDER by position
felix@3038:                       </dc:statement>
felix@3038:                       <!-- ... -->
felix@3038: 
felix@3038: In both cases, an <dc:elements> element makes database queries available.
felix@3038: Also
felix@3038: note how the variables are defined in the first query and reused in the second
felix@3038: query (${prot_it}).
felix@3038: 
felix@3038: Any alement not prefixed with "dc" represents a (sub-) node in the resulting
felix@3038: tree.  The client will display these nodes and maybe subnodes in the datacage
felix@3038: widget - <additional> in above example.  The elements name is translated by
felix@3038: the client.
felix@3038: 
felix@3038: While iterating the final results, <dc:attributes> have to be specified
felix@3038: to define how the artifact is to be created.
felix@3038: 
felix@3038:                       <dc:elements>
felix@3038:                         <column>
felix@3038:                           <dc:attribute name="name" value="${prot_column_name}"/>
felix@3038:                           <dc:attribute name="ids" value="additionals-wstv-${prot_rel_pos}-${prot_id}"/>
felix@3038:                           <dc:attribute name="factory" value="staticwkms"/>
felix@3038:                         </column>
felix@3038:                       </dc:elements>
felix@3038: 
felix@3038: The "name" attribute is what is to be displayed in the client, the "ids" are given
felix@3038: to the server and pass important information about the chosen data.
felix@3038: The "factory" is chosen according to the type of data displayed.
felix@3041: 
felix@3041: So far, three other elements have not yet been mentioned: <dc:comment>,
felix@3041: <dc:if> and the <dc:when><dc:otherwise> structure.
felix@3041: <dc:comment> is an element to allow comments.  Choose these over standard
felix@3041: <!-- --> xml comments, because they are not transferred to the client.
felix@3041: <dc:if> and <dc:when> allow control (rather: definition) flow within
felix@3041: the configuration and work in analogy to the XSL-elements <xsl:if>
felix@3041: and <xsl:when>.
felix@3041: 
felix@3041: When dealing with the behaviour specification of the datacage, multiple
felix@3041: interpretations for the term "context" are possible.
felix@3041: A <dc:context> element essentially means a database binding.  Thus each
felix@3041: query (<dc:statement>) needs to be nested in its own context.
felix@3041: Furthermore, two types of databases with own bindings exist:
felix@3041: The "system" (default for <dc:context>, <dc:context connection="system">)
felix@3041: context allows queries related to the backend database with existing
felix@3041: data (e.g. measurements).
felix@3041: The "user" context (<dc:context connection="user">) allows queries against
felix@3041: the database which stores information about already existing artifacts and
felix@3041: calculations.
felix@3041: 
felix@3041: Another connotation for the term "context" is the situation from which
felix@3041: the datacage is queried.  The standard case is a from the datacage widget.
felix@3041: When the user opens the datacage from the graphical client, this is done
felix@3041: from one of possible multiple diagrams.
felix@3041: When the datacage is queried, it gets as an argument the "out" of
felix@3041: the current artifact.  The out corresponds to the diagram type.
felix@3041: 
felix@3041: For example the inner block of
felix@3041: 
felix@3041:           <dc:if test="dc:contains($artifact-outs, 'longitudinal_section')">
felix@3041:               <longitudinal_section>
felix@3041:                 <dc:call-macro name="annotations"/>
felix@3041:               </longitudinal_section>
felix@3041:           </dc:if>
felix@3041: 
felix@3041: will only be executed if called from the datacage within a
felix@3041: longitudinal_section diagram.
felix@3041: 
felix@3041: In the given example another concept of the datacage configuration is
felix@3041: encountered: Macros.
felix@3041: 
felix@3041: Macros help to avoid duplication of parts of the document.  As the datacage
felix@3041: of some diagrams should include the same type of data, the same query should
felix@3041: be executed in multiple situations.
felix@3041: 
felix@3041: Therefore a macro can be defined, like in
felix@3041: 
felix@3041:         <dc:macro name="basedata_4_heightmarks-wq">
felix@3041:           <heightmarks>
felix@3041:             <dc:context>
felix@3041:               <dc:statement>
felix@3041:                 SELECT id          AS prot_id,
felix@3041:                        description AS prot_description
felix@3041:                 FROM wsts WHERE kind = 4 AND river_id = ${river_id}
felix@3041:               </dc:statement>
felix@3041:               <dc:elements>
felix@3041:               <!-- ... -->
felix@3041:         </dc:macro>
felix@3041: 
felix@3041: and invoked from another location within the document, e.g. with
felix@3041: 
felix@3041:                 <dc:call-macro name="basedata_4_heightmarks"/>
aheinecke@6082: 
aheinecke@6082: Debugging Tips:
aheinecke@6082:   - You can send a message to the Log (log level info) during the evaluation
aheinecke@6082:   of the datacage by using the <dc:message> element.
aheinecke@6082:   For example to activate a basic macro tracing you could do something like:
aheinecke@6082:       %s@\(<dc:macro name="\)\(.*\)\(".*>\)@\1\2\3\r<dc:message>\2</dc:message>
aheinecke@6082:   - To dump the variables that are currently on the stack you can use the
aheinecke@6082:   dc:dump-variables() fuction.
aheinecke@6082:   For example:
aheinecke@6082:     <dc:message>{dc:dump-variables()}</dc:message>