001    /*
002    // $Id: //open/util/resgen/src/org/eigenbase/xom/DefWalker.java#3 $
003    // Package org.eigenbase.xom is an XML Object Mapper.
004    // Copyright (C) 2005-2005 The Eigenbase Project
005    // Copyright (C) 2005-2005 Disruptive Tech
006    // Copyright (C) 2005-2005 LucidEra, Inc.
007    // Portions Copyright (C) 2000-2005 Kana Software, Inc. and others.
008    //
009    // This library is free software; you can redistribute it and/or modify it
010    // under the terms of the GNU Lesser General Public License as published by the
011    // Free Software Foundation; either version 2 of the License, or (at your
012    // option) any later version approved by The Eigenbase Project.
013    //
014    // This library is distributed in the hope that it will be useful, 
015    // but WITHOUT ANY WARRANTY; without even the implied warranty of
016    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017    // GNU Lesser General Public License for more details.
018    // 
019    // You should have received a copy of the GNU Lesser General Public License
020    // along with this library; if not, write to the Free Software
021    // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
022    //
023    // dsommerfield, 18 February, 2001
024    */
025    
026    package org.eigenbase.xom;
027    
028    import java.lang.reflect.Array;
029    import java.util.Vector;
030    
031    /**
032     * DefWalker is a class designed to help users of plugin elements and elements
033     * with content type ANY.  It walks through an array of ElementDef, searching
034     * for and returning portions as the correct types.
035     */
036    public class DefWalker {
037    
038        private NodeDef[] defs;
039        private int pos;
040    
041        /**
042         * Construct a DefWalker, attaching it to a NodeDef array and
043         * specifying a PrintWriter to display error messages for later
044         * consumption.
045         * @param defs a NodeDef array to walk.  All returned objects
046         * come from this array.
047         */
048        public DefWalker(NodeDef[] defs)
049        {
050            this.defs = defs;
051            pos = 0;
052        }
053    
054        /**
055         * Returns the next node in the defs array, but only if it matches
056         * the provided class <i>elemType</i>.
057         * @param elemType the Class of NodeDef to expect.  This class will
058         * always be assignable from the returned object.
059         * @throws XOMException if there are no more nodes in the defs
060         * array or if the next node is of an incorrect type.
061         */
062        public NodeDef expect(Class elemType)
063            throws XOMException
064        {
065            if(pos >= defs.length)
066                throw new XOMException("Expecting a Node of type "
067                                          + elemType.getName() + " but no "
068                                          + "Nodes remain.");
069            if(!(elemType.isAssignableFrom(defs[pos].getClass())))
070                throw new XOMException("Expecting a Node of type "
071                                          + elemType.getName() + " but "
072                                          + "found a Node of type "
073                                          + defs[pos].getClass().getName());
074            return defs[pos++];
075        }
076    
077        /**
078         * Returns a portion of the remaining nodes in the defs array as an
079         * array.  All nodes in the array will be of the specified class
080         * <i>elemType</i>.  The nodes are returned as a generic NodeDef[]
081         * array and may need to be explicitly converted to an array of the
082         * appropriate type by the caller.
083         * @param elemType the Class of NodeDef to expect and return.  This
084         * class will always be assignable from each returned object in the
085         * array.
086         */
087        public NodeDef[] expectArray(Class elemType)
088        {
089            Vector found = new Vector();
090            while(pos < defs.length &&
091                  elemType.isAssignableFrom(defs[pos].getClass()))
092                found.addElement(defs[pos++]);
093    
094            NodeDef[] ret = new NodeDef[found.size()];
095            for(int i=0; i<found.size(); i++)
096                ret[i] = (NodeDef)(found.elementAt(i));
097            return ret;
098        }
099    
100        /**
101         * Returns a portion of the remaining nodes in the defs array as an
102         * array.  All nodes in the array will be of the specified class
103         * <i>elemType</i>.  The nodes are in an array of the specified type,
104         * which will be returned as an object (which must be cast to the
105         * appropriate array type by the caller when needed.
106         * @param elemType the Class of NodeDef to expect and return.  This
107         * class will always be assignable from each returned object in the
108         * array.
109         */
110        public Object expectTypeArray(Class elemType)
111        {
112            Vector found = new Vector();
113            while(pos < defs.length &&
114                  elemType.isAssignableFrom(defs[pos].getClass()))
115                found.addElement(defs[pos++]);
116    
117            Object ret = Array.newInstance(elemType, found.size());
118            for(int i=0; i<found.size(); i++)
119                Array.set(ret, i, found.elementAt(i));
120            return ret;
121        }
122    }
123    
124    
125    // End DefWalker.java