1 /*
2  * reserved comment block
3  * DO NOT REMOVE OR ALTER!
4  */
5 /*
6  * Copyright 1999-2004 The Apache Software Foundation.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 /*
21  * $Id: FuncSubstring.java,v 1.2.4.1 2005/09/14 20:18:45 jeffsuttor Exp $
22  */
23 package com.sun.org.apache.xpath.internal.functions;
24 
25 import com.sun.org.apache.xalan.internal.res.XSLMessages;
26 import com.sun.org.apache.xml.internal.utils.XMLString;
27 import com.sun.org.apache.xpath.internal.XPathContext;
28 import com.sun.org.apache.xpath.internal.objects.XObject;
29 import com.sun.org.apache.xpath.internal.objects.XString;
30 import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
31 
32 /**
33  * Execute the Substring() function.
34  * @xsl.usage advanced
35  */
36 public class FuncSubstring extends Function3Args
37 {
38     static final long serialVersionUID = -5996676095024715502L;
39 
40   /**
41    * Execute the function.  The function must return
42    * a valid object.
43    * @param xctxt The current execution context.
44    * @return A valid XObject.
45    *
46    * @throws javax.xml.transform.TransformerException
47    */
execute(XPathContext xctxt)48   public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
49   {
50 
51     XMLString s1 = m_arg0.execute(xctxt).xstr();
52     double start = m_arg1.execute(xctxt).num();
53     int lenOfS1 = s1.length();
54     XMLString substr;
55 
56     if (lenOfS1 <= 0)
57       return XString.EMPTYSTRING;
58     else
59     {
60       int startIndex;
61 
62       if (Double.isNaN(start))
63       {
64 
65         // Double.MIN_VALUE doesn't work with math below
66         // so just use a big number and hope I never get caught.
67         start = -1000000;
68         startIndex = 0;
69       }
70       else
71       {
72         start = Math.round(start);
73         startIndex = (start > 0) ? (int) start - 1 : 0;
74       }
75 
76       if (null != m_arg2)
77       {
78         double len = m_arg2.num(xctxt);
79         int end = (int) (Math.round(len) + start) - 1;
80 
81         // Normalize end index.
82         if (end < 0)
83           end = 0;
84         else if (end > lenOfS1)
85           end = lenOfS1;
86 
87         if (startIndex > lenOfS1)
88           startIndex = lenOfS1;
89 
90         substr = s1.substring(startIndex, end);
91       }
92       else
93       {
94         if (startIndex > lenOfS1)
95           startIndex = lenOfS1;
96         substr = s1.substring(startIndex);
97       }
98     }
99 
100     return (XString)substr; // cast semi-safe
101   }
102 
103   /**
104    * Check that the number of arguments passed to this function is correct.
105    *
106    *
107    * @param argNum The number of arguments that is being passed to the function.
108    *
109    * @throws WrongNumberArgsException
110    */
checkNumberArgs(int argNum)111   public void checkNumberArgs(int argNum) throws WrongNumberArgsException
112   {
113     if (argNum < 2)
114       reportWrongNumberArgs();
115   }
116 
117   /**
118    * Constructs and throws a WrongNumberArgException with the appropriate
119    * message for this function object.
120    *
121    * @throws WrongNumberArgsException
122    */
reportWrongNumberArgs()123   protected void reportWrongNumberArgs() throws WrongNumberArgsException {
124       throw new WrongNumberArgsException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_TWO_OR_THREE, null)); //"2 or 3");
125   }
126 }
127