<?php

/*
 * Copyright 2004-2005 The Apache Software Foundation or its licensors,
 *                     as applicable.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


require_once 'PHPCR/ItemVisitor.php';
require_once 'PHPCR/Property.php';
require_once 'PHPCR/RepositoryException.php';
require_once 'PHPCR/Node.php';


/**
 * An implementaion of <code>ItemVisitor</code>.
 * <p/>
 * <b>Level 1 and 2</b>
 * <p/>
 * <code>TraversingItemVisitor</code> is an abstract utility class
 * which allows to easily traverse an <code>Item</code> hierarchy.
 * <p/>
 * <p><code>TraversingItemVisitor</code> makes use of the Visitor Pattern
 * as described in the book 'Design Patterns' by the Gang Of Four
 * (Gamma et al.).
 * <p/>
 * <p>Tree traversal is done observing the left-to-right order of
 * child <code>Item</code>s if such an order is supported and exists.
 *
 * @author Markus Nix <mnix@mayflower.de>
 * @package phpcr
 * @subpackage util
 */
abstract class TraversingItemVisitor implements ItemVisitor
{
    /**$currentQueue
     * indicates if traversal should be done in a breadth-first
     * manner rather than depth-first (which is the default)
     *
     * @var bool
     */
    protected $breadthFirst = false;

    /**
     * the 0-based level up to which the hierarchy should be traversed
     * (if it's -1, the hierarchy will be traversed until there are no
     * more children of the current item)
     *
     * @var int
     */
    protected $maxLevel = -1;

    /**
     * queues used to implement breadth-first traversal
     *
     * @var array
     */
    private $currentQueue;
    private $nextQueue;

    /**
     * used to track hierarchy level of item currently being processed
     *
     * @var int
     */
    private $currentLevel;


    /**
     * Constructs a new instance of this class.
     *
     * @param breadthFirst if <code>breadthFirst</code> is true then traversal
     *                     is done in a breadth-first manner; otherwise it is done in a
     *                     depth-first manner (which is the default behaviour).
     */
    public function __construct( $breadthFirst = false, $maxLevel = -1 ) {
        $this->breadthFirst = $breadthFirst;

        if ( $this->breadthFirst === true ) {
            $this->currentQueue = array();
            $this->nextQueue    = array();
        }

        $this->currentLevel = 0;
        $this->maxLevel = $maxLevel;
    }


    /**
     * Implement this method to add behaviour performed before a
     * <code>Property</code> or <code>Node</code> is visited.
     *
     * @param  entry that is accepting this visitor.
     * @param  level    hierarchy level of this property (the root node starts at level 0)
     * @throws RepositoryException if an error occurrs
     */
    protected abstract function entering( $entry, $level );

    /**
     * Implement this method to add behaviour performed after a
     * <code>Property</code> is visited.
     *
     * @param  entry the <code>Property</code> that is accepting this visitor.
     * @param  level    hierarchy level of this property (the root node starts at level 0)
     * @throws RepositoryException if an error occurrs
     */
    protected abstract function leaving( $entry, $level );

    /**
     * Called when the Visitor is passed to a <code>Node</code>.
     * <p/>
     * It calls <code>TraversingItemVisitor.entering(Node, int)</code> followed by
     * <code>TraversingItemVisitor.leaving(Node, int)</code>. Implement these abstract methods to
     * specify behaviour on 'arrival at' and 'after leaving' the <code>Node</code>.
     * <p/>
     * If this method throws, the visiting process is aborted.
     *
     * @param Either Node or Property that is accepting this visitor.
     * @throws RepositoryException if an error occurrs
     */
    public function visit( $entry ) {
        if ( $entry instanceof Property ) {
            $this->entering( $entry, $this->currentLevel );
            $this->leaving( $entry, $this->currentLevel );
        } else {
            try {
                if ( !$this->breadthFirst ) {
                    // depth-first traversal
                    $this->entering( $entry, $this->currentLevel );

                    if ( $this->maxLevel == -1 || $this->currentLevel < $this->maxLevel ) {
                        $this->currentLevel++;

                        $nodeIter = $entry->getNodes();

                        while ( $nodeIter->hasNext() ) {
                            $nodeIter->nextNode()->accept( $this );
                        }

                        $propIter = $entry->getProperties();

                        while ( $propIter->hasNext()) {
                            $propIter->nextProperty()->accept( $this );
                        }

                        $currentLevel--;
                    }

                    $this->leaving( $entry, $this->currentLevel );
                } else {
                    // breadth-first traversal
                    $this->entering( $entry, $this->currentLevel );
                    $this->leaving( $entry, $this->currentLevel );

                    if ( $this->maxLevel == -1 || $this->currentLevel < $this->maxLevel ) {
                        $nodeIter = $entry->getNodes();

                        while ( $nodeIter->hasNext() ) {
                            $this->nextQueue[] = $nodeIter->nextNode();
                        }

                        $propIter = $entry->getProperties();

                        while ( $propIter->hasNext() ) {
                            $this->nextQueue[] = $propIter->nextProperty();
                        }
                    }

                    while ( !empty( $this->currentQueue ) || !empty( $this->nextQueue ) ) {
                        if ( empty( $this->currentQueue ) ) {
                            $this->currentLevel++;
                            $this->currentQueue = $this->nextQueue;
                            $this->nextQueue = array();
                        }

                        $this->currentQueue = array_shift( $this->currentQueue );
                    }

                    $this->currentLevel = 0;
               }
            } catch ( RepositoryException $re ) {
                $this->currentLevel = 0;
                throw $re;
            }
        }
    }
}

?>