001/*
002 * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Alexandre Russel
016 *
017 * $Id$
018 */
019
020package org.nuxeo.ecm.platform.annotations.gwt.client.util;
021
022import com.google.gwt.dom.client.Document;
023import com.google.gwt.dom.client.Node;
024import com.google.gwt.dom.client.NodeList;
025
026/**
027 * @author Alexandre Russel
028 */
029public class Visitor {
030    private final NodeProcessor processor;
031
032    private boolean processing = true;
033
034    private boolean partialVisit = false;
035
036    private Node startNode;
037
038    private Node endNode;
039
040    public Visitor(NodeProcessor visitor) {
041        this.processor = visitor;
042    }
043
044    /**
045     * process all the children of this node.
046     *
047     * @param node
048     */
049    public void process(Node node) {
050        visit(node);
051    }
052
053    /**
054     * process all the node of this document.
055     *
056     * @param document
057     */
058    public void process(Document document) {
059        visit(document);
060    }
061
062    /**
063     * process all the node from startNode to endNode.
064     *
065     * @param startNode
066     * @param endNode
067     */
068    public void process(Node startNode, Node endNode) {
069        this.processing = false;
070        partialVisit = true;
071        this.startNode = startNode;
072        this.endNode = endNode;
073        visit(startNode.getOwnerDocument());
074    }
075
076    public void visit(Node node) {
077        if (startNode == node) {
078            processing = true;
079        } else if (endNode == node) {
080            processing = false;
081        }
082        if (processor.doBreak()) {
083            return;
084        }
085
086        NodeList list = node.getChildNodes();
087        if (list == null || list.getLength() == 0) {
088            processIf(node);
089        } else {
090            int length = list.getLength();
091            Node[] nodes = new Node[list.getLength()];
092            for (int x = 0; x < length; x++) {
093                nodes[x] = list.getItem(x);
094            }
095            processIf(node);
096            for (int x = 0; x < length; x++) {
097                visit(nodes[x]);
098            }
099        }
100
101    }
102
103    private void processIf(Node node) {
104        if (processing || !partialVisit) {
105            processor.process(node);
106        }
107    }
108
109}