Jeg har lavet en composite collection over denne xml stuktur ( Site.xml) , hvor hver page som indeholder andre pages er et compositeElementer. og hver page som ikke har nogle children er et Leaf.

CompositeElementer har en Iterator som indeholder den children.
Leaf elementer har en NullIterator, da den ikke har nogle children.

jeg må heller introdukserer jer for noget kode inden jeg beskriver mit problem:

Site.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  
<page id="1" title="" >
    <page id="1.1" title="">
      <page id="1.1.1" title="">
        <page id="1.1.1.1" title="" />
        <page id="1.1.1.2" title="" />
        <page id="1.1.1.3" title="" />
      </page>
      <page id="1.1.2" title="" />
      <page id="1.1.3" title="" />
      <page id="1.1.4" title="" />
      <page id="1.1.5" title="" />
    </page>
    <page id="1.2" title="">
      <page id="1.2.1" title="" />
      <page id="1.2.2" title="" />
      <page id="1.2.3" title="" />
      <page id="1.2.4" title="" />
      <page id="1.2.5" title="" />
    </page>
</page>

Iterator Interface:

1
2
3
4
5
6
7
8
9
  
public interface Iterator
{
  function hasNext():Boolean;
  function hasPrev():Boolean
  function getNext():Object;
  function getPrev():Object;
  function get length():int;
}

Composite Interface:

1
2
3
4
5
6
7
8
9
public interface IPageElement 
{
  function children():Iterator;
  function addChild( child:IPageElement ):void;
  function setParent( parent:IPageElement ):void;
  function getParent():IPageElement;
  function setData( data:Object ):void;
  function getData():Object}

Efter at have travaseret xml'en og lavet min composite struktur, wrapper jeg den i en pageIterator, som skal kunne itererer over hele composite strukturen på den måde at hvis man kalder getNext(), lander man kun på leafs.

så hvis man tager udgangspunkt i Site.xml og kalder getNext() fra (root) får man dette resultat.

1
2
3
4
5
6
7
8
getNext() // 1.1.1.1
getNext() // 1.1.1.2
getNext() // 1.1.1.3
getNext() // 1.1.2  ( springer et level op og finder næste leaf/page ).
getNext() // 1.1.3 
getNext() // 1.1.4 
getNext() // 1.1.5 
gerNext() // 1.2.1 ( springer et level op og finder næste leaf/page ).

her under er min pageIterator, i funktionen findNext, prøver jeg at implementer den logik jeg beskriver, når man kalder getNext() kigger den på om det er et composite element ( subject), hvis det er tilfældet vil prøver jeg det samme for dens children til jeg finder et leaf.
Men jeg har problemer med at få det til at spille Razz Griber jeg det forkert an?

PageIterator:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class PageIterator implements Iterator 
  {
    
    private var _pages:Iterator;
    private var _element:IPageElement;
    
    public function PageIterator(  pages:Iterator ) 
    {
      _pages = pages;
    }
    
    /* INTERFACE iterators.api.Iterator */
    
    public function hasNext():Boolean
    {
      return _pages.hasNext();
    }
  
    
    public function getNext():Object
    {
      findNext( _pages );
      return _element
    }
    
    // ...
    
    
    private function findNext( elements:Iterator ):void 
    {
      _pages = elements;
      
      var o:IPageElement;
      
      if ( _pages.hasNext()) {
    
        o = _pages.getNext() as IPageElement;
        
        if ( o is SubjectElement ) {
          findNext( o.children() );
        }else {
          _element = o.getData();
        }
        
      } else {
        // there is no more pages in this subject
        // so lets go to the subjects parent ( parent.paret );
        var temp:IPageElement = o.getParent();
        
        while ( temp  ) 
        {
          temp = temp.getParent();
          trace( temp );
        }
        
        _pages = temp.children();
 
      }
    }