<@doc alias="iter"> A utility class for iterating through a collection of GMLDOM objects, based on the ordering defined by a specified walker function The following example shows the typical way for using the ModelIterator class: method deepStateScan(state) ... var iterator = $ENV.createObject('gml:ModelIterator'); var object; iterator.search(state, walkMembers); while (object = iterator.next()) { ... do something with object ... } ... return; // inner walker function used for the iterator function walkMembers(object, iterator) { iterator.addObject(object); if (!ISA(object, 'gml:State')) return null; return object.members; } end (c) SAP AG 2003-2006. All rights reserved. /////////////////////////////////////////////////////////////////////// // CLASS HEADER Class ModelIterator inherit Object; <@doc> Constructs and initializes a new model iterator constructor() this.clear(); end /////////////////////////////////////////////////////////////////////// // PROPERTIES <@doc>Indicates whether the iterator is at the beginning (before the position of the first object) readonly property bof = false; <@doc>Gets the object at the current iterator position readonly property current = null; <@doc>Indicates whether the iterator is at the end (after the position of the last object) readonly property eof = false; <@doc>Gets the iterator length (number of objects) readonly property length = 0; <@doc scope="private">Gets the iterator objects list readonly property list = null; <@doc>Gets the current iterator position (between 0 and @length-1) readonly property pos = 0; /////////////////////////////////////////////////////////////////////// // METHODS <@doc> A callback method for adding an object to the iterator. The object to add to the iterator This method is intended for use by the walker function during a search method addObject(object) this.list.push(object); this.length = this.list.length; end <@doc> A callback method for adding a list of objects to the iterator. The list of objects to add to the iterator This method is intended for use by the walker function during a search method addObjects(objects) if (ISARRAY(objects)) { for (var i=0, len=objects.length; i Empties the iterator method clear() this.list = []; this.visited = {}; this.rewind(); end <@doc> Moves the iterator to the object at the specified position The new iterator position Returns the object at the new iterator position, or ~null if the iterator is out of bounds The iterator position can be any number between 0 and @length-1. Values smaller than 0 imply the position just before the beginning of the iterator. Values greater than or equal to @length imply the position just after the end of the iterator. method goto(pos) this.pos = MAX(-1, MIN(this.length, pos)); this.bof = (this.pos < 0); this.eof = (this.pos >= this.length); this.current = this.list && this.list[this.pos] || null; return this.current; end <@doc> Advances the iterator to the next object Returns the object at the new iterator position, or ~null if the iterator is out of bounds method next() return this.goto(this.pos+1); end <@doc> Moves the iterator to the previous object Returns the object at the new iterator position, or ~null if the iterator is out of bounds method previous() return this.goto(this.pos-1); end <@doc> Rewinds the iterator to the beginning method rewind() if (!this.list) this.list = []; this.length = this.list.length; this.current = null; this.pos = -1; this.bof = true; this.eof = true; return this.current; end <@doc> Reverses the list of objects in the iterator When the operation is completed the iterator position is reset to the beginning of the reversed iterator (just before the first object). method reverse() if (!this.list) return; this.list.reverse(); this.rewind(); end <@doc> Performs the iterator search by recursively calling the walker function The object from which the search should be started The walker function for iterating over the objects. The ModelIterator constructor performs a search by recursively calling the given ~walker function: The ~walker function has the following signature: walker(object, iterator), where ~object is the object currently in the search focus and ~iterator is this ModelIterator object. The walker function should return the list of objects that will be searched during the next search step using either an array or a hash table. The walker function can return ~null to indicate that there are no more objects to search. Before the walker function returns it can use the @addObject or @addObjects callback methods to add any desired objects to the iterator. The order in which the objects are added defines their order in the iterator. The ~walker function does not need to check for cycles since cyclic references are checked and avoided by the iterator. When the search is completed the iterator is reset to the beginning (just before the first object). method search(start, walker) try { this.walker = walker; this.visited = {}; this.searchNode(start); } catch(e) { #LOG[4, 'ModelIterator: '+e.description]; this.list = []; } this.rewind(); end <@doc scope="private"> Performs the iterator search by recursively calling the walker function The object from which the search should be started The walker function for iterating over the objects. The ModelIterator constructor performs a search by recursively calling the given ~walker function: The ~walker function has the following signature: walker(object, iterator), where ~object is the object currently in the search focus and ~iterator is this ModelIterator object. The walker function should return the list of objects that will be searched during the next search step using either an array or a hash table. The walker function can return ~null to indicate that there are no more objects to search. Before the walker function returns it can use the @addObject or @addObjects callback methods to add any desired objects to the iterator. The order in which the objects are added defines their order in the iterator. The ~walker function does not need to check for cycles since cyclic references are checked and avoided by the iterator. When the search is completed the iterator is reset to the beginning (just before the first object). method searchNode(node) if (!node || !node.id || (node.id in this.visited)) return; this.visited[node.id] = true; var chnodes = this.walker(node, this); if (!chnodes) return; if (ISARRAY(chnodes)) { for (var i=0, len=chnodes.length; i Sorts the list of objects in the iterator by a specified property in alphabetical order When the sort is completed the iterator position is reset to the beginning of the sorted iterator (just before the first object). method sort(prop) if (!this.list) return; SORT(this.list, prop); this.rewind(); end <@doc> Sorts the list of objects in the iterator by a specified property in numeric order When the sort is completed the iterator position is reset to the beginning of the sorted iterator (just before the first object). method sortn(prop) SORTN(this.list, prop); this.rewind(); end