
package org.jaxen;

import java.util.List;
import java.util.ArrayList;


import org.dom4j.Document;
import org.dom4j.Attribute;
import org.dom4j.CDATA;
import org.dom4j.Element;
import org.dom4j.DocumentType;
import org.dom4j.Namespace;
import org.dom4j.Comment;
import org.dom4j.ProcessingInstruction;
import org.dom4j.Entity;
import org.dom4j.Text;

/**
 *  Utility class to retrieve an ordered list of
 *  node references for a given context
 *
 * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
 * @version $Revision: 1.15 $
 */
public class ContextGather
{
    /**
     *  Collects an ordered list of the nodes in ta
     *  Context subtree
     *
     *  @param context Context to gether over
     *  @return list or null if unsupported
     */
    public static  List gather( Context context )
    {
        /*
         *  get the current
         */

        List list = new ArrayList();

        List l = context.getNodeSet();

        for( int i = 0; i < l.size(); i++)
        {
            Object o = l.get(i);

            addNodes(o, list);
        }

        if (list.size() > 0)
            return list;

        return null;
    }

    /**
     *  Does the actual gathering work.  Method depends
     *  on object model.
     *
     *  @param o  context node
     *  @param list  list to add references to
     */
    private static void addNodes( Object o, List list )
    {
        /*
         *  dom4j
         */

        if ( o instanceof org.dom4j.tree.AbstractNode )
        {
            Dom4jVisitor dv = new Dom4jVisitor( list );

            ( (org.dom4j.tree.AbstractNode) o).accept( dv );
        }
    }

    /**
     *  Visitor class to gather for dom4j trees
     */
    static class Dom4jVisitor extends org.dom4j.VisitorSupport
    {
        List objList = null;

        public Dom4jVisitor( List l )
        {
            objList = l;
        }

        private Dom4jVisitor()
        {
        }

        public void visit(Document document)
        {
            objList.add( document );
        }

        public void visit(DocumentType documentType)
        {
            objList.add( documentType );
        }

        public void visit(Element node)
        {
            objList.add( node );
        }

        public void visit(Attribute node)
        {
            objList.add( node );
        }

        public void visit(CDATA node)
        {
            objList.add( node );
        }

        public void visit(Comment node)
        {
            objList.add( node );
        }

        public void visit(Entity node)
        {
            objList.add( node );
        }

        public void visit(Namespace namespace)
        {
            objList.add( namespace );
        }

        public void visit(ProcessingInstruction node)
        {
            objList.add( node );
        }

        public void visit(Text node)
        {
            objList.add( node );
        }
    }
}
