• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the  "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 /*
19  * $Id: XRTreeFrag.java 469368 2006-10-31 04:41:36Z minchau $
20  */
21 package org.apache.xpath.objects;
22 
23 import org.apache.xml.dtm.DTM;
24 import org.apache.xml.dtm.DTMIterator;
25 import org.apache.xml.utils.XMLString;
26 import org.apache.xpath.Expression;
27 import org.apache.xpath.ExpressionNode;
28 import org.apache.xpath.XPathContext;
29 import org.apache.xpath.axes.RTFIterator;
30 
31 import org.w3c.dom.NodeList;
32 
33 /**
34  * This class represents an XPath result tree fragment object, and is capable of
35  * converting the RTF to other types, such as a string.
36  * @xsl.usage general
37  */
38 public class XRTreeFrag extends XObject implements Cloneable
39 {
40     static final long serialVersionUID = -3201553822254911567L;
41   private DTMXRTreeFrag m_DTMXRTreeFrag;
42   private int m_dtmRoot = DTM.NULL;
43   protected boolean m_allowRelease = false;
44 
45 
46   /**
47    * Create an XRTreeFrag Object.
48    *
49    */
XRTreeFrag(int root, XPathContext xctxt, ExpressionNode parent)50   public XRTreeFrag(int root, XPathContext xctxt, ExpressionNode parent)
51   {
52     super(null);
53     exprSetParent(parent);
54     initDTM(root, xctxt);
55   }
56 
57   /**
58    * Create an XRTreeFrag Object.
59    *
60    */
XRTreeFrag(int root, XPathContext xctxt)61   public XRTreeFrag(int root, XPathContext xctxt)
62   {
63     super(null);
64    initDTM(root, xctxt);
65   }
66 
initDTM(int root, XPathContext xctxt)67   private final void initDTM(int root, XPathContext xctxt){
68     m_dtmRoot = root;
69     final DTM dtm = xctxt.getDTM(root);
70     if(dtm != null){
71       m_DTMXRTreeFrag = xctxt.getDTMXRTreeFrag(xctxt.getDTMIdentity(dtm));
72     }
73   }
74 
75   /**
76    * Return a java object that's closest to the representation
77    * that should be handed to an extension.
78    *
79    * @return The object that this class wraps
80    */
object()81   public Object object()
82   {
83     if (m_DTMXRTreeFrag.getXPathContext() != null)
84       return new org.apache.xml.dtm.ref.DTMNodeIterator((DTMIterator)(new org.apache.xpath.NodeSetDTM(m_dtmRoot, m_DTMXRTreeFrag.getXPathContext().getDTMManager())));
85     else
86       return super.object();
87   }
88 
89   /**
90    * Create an XRTreeFrag Object.
91    *
92    */
XRTreeFrag(Expression expr)93   public XRTreeFrag(Expression expr)
94   {
95     super(expr);
96   }
97 
98   /**
99    * Specify if it's OK for detach to release the iterator for reuse.
100    *
101    * @param allowRelease true if it is OK for detach to release this iterator
102    * for pooling.
103    */
allowDetachToRelease(boolean allowRelease)104   public void allowDetachToRelease(boolean allowRelease)
105   {
106     m_allowRelease = allowRelease;
107   }
108 
109   /**
110    * Detaches the <code>DTMIterator</code> from the set which it iterated
111    * over, releasing any computational resources and placing the iterator
112    * in the INVALID state. After <code>detach</code> has been invoked,
113    * calls to <code>nextNode</code> or <code>previousNode</code> will
114    * raise a runtime exception.
115    *
116    * In general, detach should only be called once on the object.
117    */
detach()118   public void detach(){
119     if(m_allowRelease){
120     	m_DTMXRTreeFrag.destruct();
121       setObject(null);
122     }
123   }
124 
125   /**
126    * Tell what kind of class this is.
127    *
128    * @return type CLASS_RTREEFRAG
129    */
getType()130   public int getType()
131   {
132     return CLASS_RTREEFRAG;
133   }
134 
135   /**
136    * Given a request type, return the equivalent string.
137    * For diagnostic purposes.
138    *
139    * @return type string "#RTREEFRAG"
140    */
getTypeString()141   public String getTypeString()
142   {
143     return "#RTREEFRAG";
144   }
145 
146   /**
147    * Cast result object to a number.
148    *
149    * @return The result tree fragment as a number or NaN
150    */
num()151   public double num()
152     throws javax.xml.transform.TransformerException
153   {
154 
155     XMLString s = xstr();
156 
157     return s.toDouble();
158   }
159 
160   /**
161    * Cast result object to a boolean.  This always returns true for a RTreeFrag
162    * because it is treated like a node-set with a single root node.
163    *
164    * @return true
165    */
bool()166   public boolean bool()
167   {
168     return true;
169   }
170 
171   private XMLString m_xmlStr = null;
172 
173   /**
174    * Cast result object to an XMLString.
175    *
176    * @return The document fragment node data or the empty string.
177    */
xstr()178   public XMLString xstr()
179   {
180     if(null == m_xmlStr)
181       m_xmlStr = m_DTMXRTreeFrag.getDTM().getStringValue(m_dtmRoot);
182 
183     return m_xmlStr;
184   }
185 
186   /**
187    * Cast result object to a string.
188    *
189    * @return The string this wraps or the empty string if null
190    */
appendToFsb(org.apache.xml.utils.FastStringBuffer fsb)191   public void appendToFsb(org.apache.xml.utils.FastStringBuffer fsb)
192   {
193     XString xstring = (XString)xstr();
194     xstring.appendToFsb(fsb);
195   }
196 
197 
198   /**
199    * Cast result object to a string.
200    *
201    * @return The document fragment node data or the empty string.
202    */
str()203   public String str()
204   {
205     String str = m_DTMXRTreeFrag.getDTM().getStringValue(m_dtmRoot).toString();
206 
207     return (null == str) ? "" : str;
208   }
209 
210   /**
211    * Cast result object to a result tree fragment.
212    *
213    * @return The document fragment this wraps
214    */
rtf()215   public int rtf()
216   {
217     return m_dtmRoot;
218   }
219 
220   /**
221    * Cast result object to a DTMIterator.
222    * dml - modified to return an RTFIterator for
223    * benefit of EXSLT object-type function in
224    * {@code org.apache.xalan.lib.ExsltCommon}.
225    * @return The document fragment as a DTMIterator
226    */
asNodeIterator()227   public DTMIterator asNodeIterator()
228   {
229     return new RTFIterator(m_dtmRoot, m_DTMXRTreeFrag.getXPathContext().getDTMManager());
230   }
231 
232   /**
233    * Cast result object to a nodelist. (special function).
234    *
235    * @return The document fragment as a nodelist
236    */
convertToNodeset()237   public NodeList convertToNodeset()
238   {
239 
240     if (m_obj instanceof NodeList)
241       return (NodeList) m_obj;
242     else
243       return new org.apache.xml.dtm.ref.DTMNodeList(asNodeIterator());
244   }
245 
246   /**
247    * Tell if two objects are functionally equal.
248    *
249    * @param obj2 Object to compare this to
250    *
251    * @return True if the two objects are equal
252    *
253    * @throws javax.xml.transform.TransformerException
254    */
equals(XObject obj2)255   public boolean equals(XObject obj2)
256   {
257 
258     try
259     {
260       if (XObject.CLASS_NODESET == obj2.getType())
261       {
262 
263         // In order to handle the 'all' semantics of
264         // nodeset comparisons, we always call the
265         // nodeset function.
266         return obj2.equals(this);
267       }
268       else if (XObject.CLASS_BOOLEAN == obj2.getType())
269       {
270         return bool() == obj2.bool();
271       }
272       else if (XObject.CLASS_NUMBER == obj2.getType())
273       {
274         return num() == obj2.num();
275       }
276       else if (XObject.CLASS_NODESET == obj2.getType())
277       {
278         return xstr().equals(obj2.xstr());
279       }
280       else if (XObject.CLASS_STRING == obj2.getType())
281       {
282         return xstr().equals(obj2.xstr());
283       }
284       else if (XObject.CLASS_RTREEFRAG == obj2.getType())
285       {
286 
287         // Probably not so good.  Think about this.
288         return xstr().equals(obj2.xstr());
289       }
290       else
291       {
292         return super.equals(obj2);
293       }
294     }
295     catch(javax.xml.transform.TransformerException te)
296     {
297       throw new org.apache.xml.utils.WrappedRuntimeException(te);
298     }
299   }
300 
301 }
302