This function combines the functionality of checkElementMap(), createElementMap() and putElementsByKeys() functions at once.

It works the following way:

  1. First, it searches the table of all element maps maintained by the generator.

    If the map with the identifier specified in elementMapId parameter already exists, the function does nothing and just returns the number of the key/element associations contained in that map.

    If the map with such an identifier is not found, the function creates a new one according the following steps.

  2. The sourceElements parameter subquery is executed and the source element enumeration produced.

  3. The elements from the enumeration are iterated so that on each iteration every source element is temporary set as the generator context element and the following steps are processed.

  4. The subquery specified in the keysQuery parameter is executed, which produces one or several keys.

  5. If the elementsQuery subquery is specified, it is executed as well. This produces the elements that are actually put in the map: each newly generated element will be associated with every key generated on the step (4).

  6. If the elementsQuery subquery is absent, the currently iterated source element is put in the map together with every key generated on the step (4).

  7. After the iterations are finished, the function returns the number of key/element associations added to the element map.

Parameters:

elementMapId

The object which identifies the element map.

DocFlex generator is able to maintain unlimited number of element maps. So, they themselves are stored in a hashtable and accessed using map identifiers as hash keys.

Therefore, any object representing a map identifier should be good enough to be used as a hashkey. That is, it should have appropriately implemented method Object.hashCode() in the implementing Java class.

The simple data types (like String and Number) do satisfy this. However, in certain situations, it might be tricky to find how to express a hashmap identifier in the form of a simple data type object. (Normally, this would involve writing some complicated expression that converts everything that identifies a hashmap into a single long string.)

The HashKey() function provides a way to solve this problem. Using it, you can create a compound hashkey object which encloses several simple ones.

For example, suppose you need to maintain lots of element maps each of which is connected with a certain element and identified with the element's ID plus a "some-methods" string (that's because you may also have a similar set of element maps connected with the same elements but representing "some-fields" instead). Then, you can create identifiers for those element maps using the following call:

HashKey(element.id, "some-methods")
sourceElements
The enumeration of source elements to be included in the element map (or by which the actual included elements are generated; see elementsQuery parameter for more details).

That element enumeration may be produced by a certain "heavy" query, exactly the one whose repeating the entire element map is supposed to avoid. However, note the following.

FlexQuery processor treats each parameter in a function call as a separate subexpression. Those parameter subexpressions are compiled into separate subqueries. When a function is called, the parameter subqueries are not automatically executed before the call. Instead, they are passed to the function implementation. So, it is the function implementation where the parameter subqueries are actually executed and the parameter values are obtained.

Given this, the prepareElementMap() function is implemented the following way:

  1. First, it obtains the value of the elementMapId parameter and searches the corresponding element map in the generator table.
  2. Only when the map with such an identifier is not found, the sourceElements parameter subquery is executed and a new map is created.
That means, the generation of sourceElements enumeration should be specified entirely within the parameter subexpression.

For example, the call

prepareElementMap (element.id,
  element.findElementsByLPath("Field"), ...)
will work differently (and faster) rather than the expression:
e = element.findElementsByLPath("Field");
prepareElementMap(element.id, e, ...)
Although, the result effect will be the same.

This feature allows you to specify the creation of necessary element maps not only in the initialization expression of the main template (see Template Properties Dialog | Processing | Init/Finish | Template Init Expression), but also in any other location within templates, where an element map may be used to improve performance.

keysQuery
The subquery to generate the hash keys associated with each element from the enumeration provided by sourceElements parameter.

The keys subquery should be created using FlexQuery() function. It should generate one or many keys for the source element passed as the generator context element. <> The result returned by the subquery may be one of the following:

  1. Object[] containing keys
  2. Vector containing keys
  3. any other type is treated as a single key
The null value returned by the subquery is interpreted as no keys. That means, the given source element will not be represented in the element map.
elementsQuery
If this subquery is specified, it is also executed for each iterated source element, by which it may produce one or many other elements. All pairs of those elements and the keys produced by the keysQuery subquery will be put to the element map.

The object returned by this query may be:

  1. A single element
  2. An Enumeration of elements
The null value will be treated as no elements. That is, nothing will be put in the element map on the given iteration.

Returns:

The number of key/element associations contained in the result element map.

See Also:

createElementMap(), checkElementMap(), putElementsByKeys(), HashKey(), FlexQuery()

${include ../../refs/element_map_example.htm}