1 /* DomXPathResult.java --
2    Copyright (C) 2004 Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 package gnu.xml.dom;
39 
40 import java.util.Collection;
41 import java.util.Iterator;
42 import org.w3c.dom.Node;
43 import org.w3c.dom.xpath.XPathException;
44 import org.w3c.dom.xpath.XPathResult;
45 
46 /**
47  * An XPath result object.
48  *
49  * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
50  */
51 class DomXPathResult
52 implements XPathResult
53 {
54 
55   final Object value;
56   final short type;
57   Iterator iterator;
58 
DomXPathResult(Object value, short requestedType)59   DomXPathResult (Object value, short requestedType)
60   {
61     this.value = value;
62     if (value instanceof Boolean)
63       {
64         type = XPathResult.BOOLEAN_TYPE;
65       }
66     else if (value instanceof Double)
67       {
68         type = XPathResult.NUMBER_TYPE;
69       }
70     else if (value instanceof String)
71       {
72         type = XPathResult.STRING_TYPE;
73       }
74     else if (value instanceof Collection)
75       {
76         Collection ns = (Collection) value;
77         switch (requestedType)
78           {
79           case XPathResult.ANY_TYPE:
80           case XPathResult.ANY_UNORDERED_NODE_TYPE:
81             type = (ns.size () == 1) ? XPathResult.FIRST_ORDERED_NODE_TYPE :
82               XPathResult.ORDERED_NODE_ITERATOR_TYPE;
83             break;
84           default:
85             type = requestedType;
86           }
87         iterator = ns.iterator ();
88       }
89     else
90       {
91         throw new IllegalArgumentException ();
92       }
93   }
94 
getBooleanValue()95   public boolean getBooleanValue()
96   {
97     if (type == XPathResult.BOOLEAN_TYPE)
98       {
99         return ((Boolean) value).booleanValue ();
100       }
101     throw new XPathException (XPathException.TYPE_ERR, value.toString ());
102   }
103 
getInvalidIteratorState()104   public boolean getInvalidIteratorState()
105   {
106     return iterator == null;
107   }
108 
getNumberValue()109   public double getNumberValue()
110   {
111     if (type == XPathResult.NUMBER_TYPE)
112       {
113         return ((Double) value).doubleValue ();
114       }
115     throw new XPathException (XPathException.TYPE_ERR, value.toString ());
116   }
117 
getResultType()118   public short getResultType()
119   {
120     return type;
121   }
122 
getSingleNodeValue()123   public Node getSingleNodeValue()
124   {
125     switch (type)
126       {
127       case XPathResult.FIRST_ORDERED_NODE_TYPE:
128       case XPathResult.ORDERED_NODE_ITERATOR_TYPE:
129       case XPathResult.ORDERED_NODE_SNAPSHOT_TYPE:
130       case XPathResult.UNORDERED_NODE_ITERATOR_TYPE:
131       case XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE:
132         Collection ns = (Collection) value;
133         if (ns.isEmpty ())
134           {
135             return null;
136           }
137         else
138           {
139             return (Node) ns.iterator ().next ();
140           }
141       }
142     throw new XPathException (XPathException.TYPE_ERR, value.toString ());
143   }
144 
getSnapshotLength()145   public int getSnapshotLength()
146   {
147     switch (type)
148       {
149       case XPathResult.FIRST_ORDERED_NODE_TYPE:
150       case XPathResult.ORDERED_NODE_ITERATOR_TYPE:
151       case XPathResult.ORDERED_NODE_SNAPSHOT_TYPE:
152       case XPathResult.UNORDERED_NODE_ITERATOR_TYPE:
153       case XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE:
154         return ((Collection) value).size ();
155       }
156     throw new XPathException (XPathException.TYPE_ERR, value.toString ());
157   }
158 
getStringValue()159   public String getStringValue()
160   {
161     if (type == XPathResult.STRING_TYPE)
162       {
163         return (String) value;
164       }
165     throw new XPathException (XPathException.TYPE_ERR, value.toString ());
166   }
167 
iterateNext()168   public Node iterateNext()
169   {
170     if (iterator != null)
171       {
172         if (iterator.hasNext ())
173           {
174             return (Node) iterator.next ();
175           }
176         else
177           {
178             iterator = null;
179             return null;
180           }
181       }
182     throw new XPathException (XPathException.TYPE_ERR, value.toString ());
183   }
184 
snapshotItem(int index)185   public Node snapshotItem(int index)
186   {
187     switch (type)
188       {
189       case XPathResult.FIRST_ORDERED_NODE_TYPE:
190       case XPathResult.ORDERED_NODE_ITERATOR_TYPE:
191       case XPathResult.ORDERED_NODE_SNAPSHOT_TYPE:
192       case XPathResult.UNORDERED_NODE_ITERATOR_TYPE:
193       case XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE:
194         Collection ns = (Collection) value;
195         Node[] nodes = new Node[ns.size ()];
196         ns.toArray (nodes);
197         return nodes[index];
198       }
199     throw new XPathException (XPathException.TYPE_ERR, value.toString ());
200   }
201 
toString()202   public String toString ()
203   {
204     return getClass ().getName () + "[type=" + typeName (type) + ",value=" +
205       value + ']';
206   }
207 
typeName(short type)208   private String typeName (short type)
209   {
210     switch (type)
211       {
212       case XPathResult.BOOLEAN_TYPE:
213         return "BOOLEAN_TYPE";
214       case XPathResult.NUMBER_TYPE:
215         return "NUMBER_TYPE";
216       case XPathResult.STRING_TYPE:
217         return "STRING_TYPE";
218       case XPathResult.FIRST_ORDERED_NODE_TYPE:
219         return "FIRST_ORDERED_NODE_TYPE";
220       case XPathResult.ORDERED_NODE_ITERATOR_TYPE:
221         return "ORDERED_NODE_ITERATOR_TYPE";
222       case XPathResult.ORDERED_NODE_SNAPSHOT_TYPE:
223         return "ORDERED_NODE_SNAPSHOT_TYPE";
224       case XPathResult.UNORDERED_NODE_ITERATOR_TYPE:
225         return "UNORDERED_NODE_ITERATOR_TYPE";
226       case XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE:
227         return "UNORDERED_NODE_SNAPSHOT_TYPE";
228       default:
229         return "(unknown)";
230       }
231   }
232 
233 }
234