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