# Example - Treewalk for ELOas

There is a tree walk function available in ELO Automation Services to help process documents. This makes it possible to not only process search areas, but also to run through entire tree structures.

# Introduction

Normally, ELOas performs a search for an index field to determine the list of documents to be processed. Alternatively, however, a "tree walk" can also be performed. With this tree walk, individual branches, or even the complete repository can be run through. Each entry is read twice: once a folder is entered, after which all child entries are run through, and then again when the folder is exited.

Example: We will use a filing cabinet metaphor, with the highest level folder titled "cabinet", then "folder", then "folder tab". The cabinet contains folders 1 and 2. Folder 1 contains folder tab 1.1. The following process then results:

Cabinet (enter)
Folder 1 (enter)
Folder tab 1.1 (enter)
Folder tab 1.1 (exit)
Folder 1 (exit)
Folder 2 (enter)
Folder 2 (exit)
Cabinet (exit)

A script can check whether the ruleset is called in the ascending branch (entering) or in the descending branch (exiting) using the EM_TREE_STATE variable. This contains 0 when entering and 1 when exit. Saving is only performed on exit. Changes that are performed upon entering the branch, however, will be retained until it is exited, even if a number of other objects were edited in the meantime.

A treewalk is initiated when the group name of the search index is entered as "TREEWALK", and as a search term the number of the starting node. No rules can be called on the start node. They are only performed on child entries.

# Usage example

The following example runs through a branch and sets an internal ID (TrackId) for all objects of form type 6 (Track Item). The starting folder has the ID 3352.

In this simple example, no error handling has been provided, and for this reason the error rule is empty.

<ruleset>
    <base>
        <name>Create TrackId</name>
        <search>
            <name>"TREEWALK"</name>
            <value>3352</value>
            <mask>6</mask>
            <max>200</max>
        </search>
        <interval>10M</interval>
    </base>
<rule>
    <name>CreateId</name>
    <script>
        if ((EM_TREE_STATE == 1) &amp;&amp; (EM_ACT_SORD.getMask() == 6)) {
            // Only process TrackItems
            //cnt.createCounter("ETSTrackId", 10000);
            if (ETS_TICK == "") {
                log.debug("Create new TrackId: " + NAME);
                ETS_TICK = cnt.getTrackId("ETSTrackId", "V");
                EM_WRITE_CHANGED = true;
            }
        }
    </script>
</rule>
<rule>
    <name>Global Error Rule</name>
    <condition>OnError</condition>
    <script>
    </script>
</rule>
</ruleset>

The interesting part of the ruleset lies in the script area, which for this reason will be discussed for each line individually in the following:

if ((EM_TREE_STATE == 1) &amp;&amp; (EM_ACT_SORD.getMask() == 6)) {

The script should only be run when exiting the branch (EM_TREE_STATE == 1), and only on objects of type TrackItem (EM_ACT_SORD.getMask() == 6).

// Only process TrackItems
//cnt.createCounter("ETSTrackId", 10000);

The example uses a counter, which must be created in advance, for example through the command entered above. However, it can only be created once, as otherwise the TrackId will be continually reset.

if (ETS_TICK == "") {

A TrackId is only created if one does not exist yet (metadata field ETS_TICK is empty).

log.debug("Create new TrackId: " + NAME)
ETS_TICK = cnt.getTrackId("ETSTrackId", "V")

To create track IDs, there is a practical method in the counter module cnt: getTrackId( <CounterName>, <prefix> ). This method takes a new counter value and supplements it with the prefix and a checksum. In the example, track ID V10001C2 is created from the counter value 10001.

EM_WRITE_CHANGED = true

The object is only saved if a new track ID has been created.

}
}

The ruleset is executed every 10 minutes and passes through the complete track item folder. All entries without a track ID are automatically supplemented, regardless the client they were created with.

# Runtime environment variables

When the ruleset is executed, there are a large number of other variables that can be used for processing in addition to the EM_TREE_STATUS value.

Name Content
EM_TREE_STATUS Specifies whether the ruleset is executed in the ascending branch (0) or descending branch (1).
EM_ACT_SORD Contains the SORD object with the current object data.
EM_PARENT_SORD Contains the SORD object with the data of the parent node. This data can in principle also be changed. However, you have to make sure these changes are saved. In addition, the change must be recognized in the descending branch and the EM\_WRITE\_CHANGED flag set to true.
EM_ROOT_SORD Contains the SORD object with the start node. As the ruleset is not applied to this entry, you will have to save your changes manually. This can take place by setting the variable EM_SAVE_TREE_ROOT.
EM_INDEX_LOADED In contrast to processing after a search, it cannot be assumed with a treewalk that a loaded SORD object has a specific form type. In principle, any form can come up. The preset index variables from the metadata fields can, however, only be generated and filled that have been registered in the definition under <mask\ and under <masks>. In this case, the variable EM_INDEX_LOADED is set to true. If the form is unknown, the metadata fields can only be accessed via the EM_ACT_SORD object; EM_INDEX_LOADED is set to false.
Information: when the index variables are filled, the metadata fields in EM_ACT_SORD should not be directly edited. These changes will then be lost before saving if the index variables are rewritten.
EM_TREE_LEVEL With this variable, you can determine where you are within the treewalk (what level). The child entries in the start node are located at level 0 (for the start node, no rules are called).
EM_TREE_MAX_LEVEL You can set a maximum depth with this rule. Child entries nested deeper than this will be ignored. Normally, this value is set to 32. If it must be changed, it can be set to the desired value before processing in the onstart routine.
EM_SAVE_TREE_ROOT No rules can be called for the treewalk start node. If this has been changed through access via EM_TREE_ROOT or EM_PARENT_SORD, the variable EM_SAVE_TREE_ROOT must be set to register these changes.
<onend>var result = …var oldstate = …EM_SAVE_TREE_ROOT = result != oldstate;log.debug("now save root: " + EM_SAVE_TREE_ROOT);</onend>
EM_TREE_EVAL_CHILDREN If a run determines that a subarea should be excluded from processing, the variable EM_TREE_CHILDREN can be set to false. This value will only be evaluated for an ascending branch (with a descending branch, it would have been too late anyway, as the subarea would already have been processed) and it will be initiated for every object set to true (standard behavior: run through the entire subarea).
EM_TREE_ABORT_WALK If you want to abort a run completely, you can set the flag EM_TREE_ABORT_WALK at any time. In this case, no more child entries are passed through. Additional entries at the same level that have not been processed will also remain unprocessed. This flag can be set to cancel processing after a fatal error.
Information: In the onstart routine, necessary runtime controls can be performed to check whether the treewalk may be performed at all. If not, this flag can be used to cancel the run.
Last updated: September 26, 2023 at 7:46 AM