001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements. See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership. The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the  "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    /*
019     * $Id: NodeInfo.java 468639 2006-10-28 06:52:33Z minchau $
020     */
021    
022    package org.apache.xalan.lib;
023    
024    import javax.xml.transform.SourceLocator;
025    
026    import org.apache.xalan.extensions.ExpressionContext;
027    import org.apache.xml.dtm.ref.DTMNodeProxy;
028    
029    import org.w3c.dom.Node;
030    import org.w3c.dom.NodeList;
031    
032    /**
033     * <code>NodeInfo</code> defines a set of XSLT extension functions to be
034     * used from stylesheets.
035     *
036     * @author <a href="mailto:ovidiu@cup.hp.com">Ovidiu Predescu</a>
037     * @since May 24, 2001
038     */
039    public class NodeInfo
040    {
041      /**
042       * <code>systemId</code> returns the system id of the current
043       * context node.
044       *
045       * @param context an <code>ExpressionContext</code> value
046       * @return a <code>String</code> value
047       */
048      public static String systemId(ExpressionContext context)
049      {
050        Node contextNode = context.getContextNode();
051        int nodeHandler = ((DTMNodeProxy)contextNode).getDTMNodeNumber();
052        SourceLocator locator = ((DTMNodeProxy)contextNode).getDTM()
053          .getSourceLocatorFor(nodeHandler);
054    
055        if (locator != null)
056          return locator.getSystemId();
057        else
058          return null;
059      }
060    
061      /**
062       * <code>systemId</code> returns the system id of the node passed as
063       * argument. If a node set is passed as argument, the system id of
064       * the first node in the set is returned.
065       *
066       * @param nodeList a <code>NodeList</code> value
067       * @return a <code>String</code> value
068       */
069      public static String systemId(NodeList nodeList)
070      {
071        if (nodeList == null || nodeList.getLength() == 0)
072          return null;
073        
074        Node node = nodeList.item(0);
075        int nodeHandler = ((DTMNodeProxy)node).getDTMNodeNumber();
076        SourceLocator locator = ((DTMNodeProxy)node).getDTM()
077          .getSourceLocatorFor(nodeHandler);
078    
079        if (locator != null)
080          return locator.getSystemId();
081        else
082          return null;
083      }
084    
085      /**
086       * <code>publicId</code> returns the public identifier of the current
087       * context node.
088       * 
089       * Xalan does not currently record this value, and will return null.
090       *
091       * @param context an <code>ExpressionContext</code> value
092       * @return a <code>String</code> value
093       */
094      public static String publicId(ExpressionContext context)
095      {
096        Node contextNode = context.getContextNode();
097        int nodeHandler = ((DTMNodeProxy)contextNode).getDTMNodeNumber();
098        SourceLocator locator = ((DTMNodeProxy)contextNode).getDTM()
099          .getSourceLocatorFor(nodeHandler);
100    
101        if (locator != null)
102          return locator.getPublicId();
103        else
104          return null;
105      }
106    
107      /**
108       * <code>publicId</code> returns the public identifier of the node passed as
109       * argument. If a node set is passed as argument, the public identifier of
110       * the first node in the set is returned.
111       * 
112       * Xalan does not currently record this value, and will return null.
113       *
114       * @param nodeList a <code>NodeList</code> value
115       * @return a <code>String</code> value
116       */
117      public static String publicId(NodeList nodeList)
118      {
119        if (nodeList == null || nodeList.getLength() == 0)
120          return null;
121        
122        Node node = nodeList.item(0);
123        int nodeHandler = ((DTMNodeProxy)node).getDTMNodeNumber();
124        SourceLocator locator = ((DTMNodeProxy)node).getDTM()
125          .getSourceLocatorFor(nodeHandler);
126    
127        if (locator != null)
128          return locator.getPublicId();
129        else
130          return null;
131      }
132    
133      /**
134       * <code>lineNumber</code> returns the line number of the current
135       * context node.
136       * 
137       * NOTE: Xalan does not normally record location information for each node. 
138       * To obtain it, you must set the custom TrAX attribute 
139       * "http://xml.apache.org/xalan/features/source_location"
140       * true in the TransformerFactory before generating the Transformer and executing
141       * the stylesheet. Storage cost per node will be noticably increased in this mode.
142       *
143       * @param context an <code>ExpressionContext</code> value
144       * @return an <code>int</code> value. This may be -1 to indicate that the
145       * line number is not known.
146       */
147      public static int lineNumber(ExpressionContext context)
148      {
149        Node contextNode = context.getContextNode();
150        int nodeHandler = ((DTMNodeProxy)contextNode).getDTMNodeNumber();
151        SourceLocator locator = ((DTMNodeProxy)contextNode).getDTM()
152          .getSourceLocatorFor(nodeHandler);
153    
154        if (locator != null)
155          return locator.getLineNumber();
156        else
157          return -1;
158      }
159    
160      /**
161       * <code>lineNumber</code> returns the line number of the node
162       * passed as argument. If a node set is passed as argument, the line
163       * number of the first node in the set is returned.
164       *
165       * NOTE: Xalan does not normally record location information for each node. 
166       * To obtain it, you must set the custom TrAX attribute 
167       * "http://xml.apache.org/xalan/features/source_location"
168       * true in the TransformerFactory before generating the Transformer and executing
169       * the stylesheet. Storage cost per node will be noticably increased in this mode.
170       *
171       * @param nodeList a <code>NodeList</code> value
172       * @return an <code>int</code> value. This may be -1 to indicate that the
173       * line number is not known.
174       */
175      public static int lineNumber(NodeList nodeList)
176      {
177        if (nodeList == null || nodeList.getLength() == 0)
178          return -1;
179        
180        Node node = nodeList.item(0);
181        int nodeHandler = ((DTMNodeProxy)node).getDTMNodeNumber();
182        SourceLocator locator = ((DTMNodeProxy)node).getDTM()
183          .getSourceLocatorFor(nodeHandler);
184    
185        if (locator != null)
186          return locator.getLineNumber();
187        else
188          return -1;
189      }
190    
191      /**
192       * <code>columnNumber</code> returns the column number of the
193       * current context node.
194       *
195       * NOTE: Xalan does not normally record location information for each node. 
196       * To obtain it, you must set the custom TrAX attribute 
197       * "http://xml.apache.org/xalan/features/source_location"
198       * true in the TransformerFactory before generating the Transformer and executing
199       * the stylesheet. Storage cost per node will be noticably increased in this mode.
200       *
201       * @param context an <code>ExpressionContext</code> value
202       * @return an <code>int</code> value. This may be -1 to indicate that the
203       * column number is not known.
204       */
205      public static int columnNumber(ExpressionContext context)
206      {
207        Node contextNode = context.getContextNode();
208        int nodeHandler = ((DTMNodeProxy)contextNode).getDTMNodeNumber();
209        SourceLocator locator = ((DTMNodeProxy)contextNode).getDTM()
210          .getSourceLocatorFor(nodeHandler);
211    
212        if (locator != null)
213          return locator.getColumnNumber();
214        else
215          return -1;
216      }
217    
218      /**
219       * <code>columnNumber</code> returns the column number of the node
220       * passed as argument. If a node set is passed as argument, the line
221       * number of the first node in the set is returned.
222       *
223       * NOTE: Xalan does not normally record location information for each node. 
224       * To obtain it, you must set the custom TrAX attribute 
225       * "http://xml.apache.org/xalan/features/source_location"
226       * true in the TransformerFactory before generating the Transformer and executing
227       * the stylesheet. Storage cost per node will be noticably increased in this mode.
228       *
229       * @param nodeList a <code>NodeList</code> value
230       * @return an <code>int</code> value. This may be -1 to indicate that the
231       * column number is not known.
232       */
233      public static int columnNumber(NodeList nodeList)
234      {
235        if (nodeList == null || nodeList.getLength() == 0)
236          return -1;
237        
238        Node node = nodeList.item(0);
239        int nodeHandler = ((DTMNodeProxy)node).getDTMNodeNumber();
240        SourceLocator locator = ((DTMNodeProxy)node).getDTM()
241          .getSourceLocatorFor(nodeHandler);
242    
243        if (locator != null)
244          return locator.getColumnNumber();
245        else
246          return -1;
247      }
248    }