KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icl > saxon > functions > Substring


1 package com.icl.saxon.functions;
2 import com.icl.saxon.*;
3 import com.icl.saxon.expr.*;
4
5 import java.util.*;
6 import java.lang.Math JavaDoc;
7
8 public class Substring extends Function {
9
10     public String JavaDoc getName() {
11         return "substring";
12     };
13
14     /**
15     * Determine the data type of the expression
16     * @return Value.STRING
17     */

18
19     public int getDataType() {
20         return Value.STRING;
21     }
22
23     /**
24     * Simplfy and validate
25     */

26
27     public Expression simplify() throws XPathException {
28         int numArgs = checkArgumentCount(2,3);
29         argument[0] = argument[0].simplify();
30         argument[1] = argument[1].simplify();
31         boolean fixed = (argument[0] instanceof Value) && (argument[1] instanceof Value);
32         if (numArgs==3) {
33             argument[2] = argument[2].simplify();
34             fixed = fixed && (argument[2] instanceof Value);
35         }
36         if (fixed) {
37             return evaluate(null);
38         }
39         return this;
40     }
41
42     /**
43     * Evaluate the function in a string context
44     */

45
46     public String JavaDoc evaluateAsString(Context context) throws XPathException {
47
48         String JavaDoc s = argument[0].evaluateAsString(context);
49         double a = argument[1].evaluateAsNumber(context);
50
51         if (getNumberOfArguments()==2) {
52             return substring(s, a);
53         } else {
54             double b = argument[2].evaluateAsNumber(context);
55             return substring(s, a, b);
56         }
57     }
58
59     /**
60     * Evaluate in a general context
61     */

62
63     public Value evaluate(Context c) throws XPathException {
64         return new StringValue(evaluateAsString(c));
65     }
66     
67     /**
68     * Implement substring function. This follows the algorithm in the spec precisely.
69     */

70
71     private static String JavaDoc substring(String JavaDoc s, double start) {
72         int slength = s.length();
73         int estlength = slength - (int)start+1;
74         if (estlength < 0) estlength = 1;
75         if (estlength > slength) estlength = slength;
76         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(estlength);
77         int pos=1;
78         int cpos=0;
79         double rstart = Round.round(start);
80
81         while (cpos<slength) {
82             if (pos >= rstart) {
83                 sb.append(s.charAt(cpos));
84             }
85
86             int ch = (int)s.charAt(cpos++);
87             if (ch<55296 || ch>56319) pos++; // don't count high surrogates, i.e. D800 to DBFF
88
}
89         return sb.toString();
90     }
91
92     /**
93     * Implement substring function. This follows the algorithm in the spec precisely, except that
94     * we exit the loop once we've exceeded the required length.
95     */

96
97     private static String JavaDoc substring(String JavaDoc s, double start, double len) {
98         int slength = s.length();
99         int estlength = (int)len;
100         if (estlength < 0) estlength = 1;
101         if (estlength > slength) estlength = slength;
102
103         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(estlength);
104         int pos=1;
105         int cpos=0;
106         double rstart = Round.round(start);
107         double rlen = Round.round(len);
108
109         while (cpos<slength) {
110             if (pos >= rstart) {
111                 if (pos < rstart + rlen) {
112                     sb.append(s.charAt(cpos));
113                 } else {
114                     break;
115                 }
116             }
117
118             int ch = (int)s.charAt(cpos++);
119             if (ch<55296 || ch>56319) pos++; // don't count high surrogates, i.e. D800 to DBFF
120
}
121
122         return sb.toString();
123     }
124
125     /**
126     * Get dependencies
127     */

128
129     public int getDependencies() {
130         int dep = argument[0].getDependencies() | argument[1].getDependencies();
131         if (getNumberOfArguments()==3) {
132             dep |= argument[2].getDependencies();
133         }
134         return dep;
135     }
136
137     /**
138     * Remove dependencies
139     */

140
141     public Expression reduce(int dep, Context c) throws XPathException {
142         Substring f = new Substring();
143         f.addArgument(argument[0].reduce(dep, c));
144         f.addArgument(argument[1].reduce(dep, c));
145         if (getNumberOfArguments()==3) {
146             f.addArgument(argument[2].reduce(dep, c));
147         }
148         f.setStaticContext(getStaticContext());
149         return f.simplify();
150     }
151
152 }
153
154
155
156 //
157
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
158
// you may not use this file except in compliance with the License. You may obtain a copy of the
159
// License at http://www.mozilla.org/MPL/
160
//
161
// Software distributed under the License is distributed on an "AS IS" basis,
162
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
163
// See the License for the specific language governing rights and limitations under the License.
164
//
165
// The Original Code is: all this file.
166
//
167
// The Initial Developer of the Original Code is
168
// Michael Kay of International Computers Limited (mhkay@iclway.co.uk).
169
//
170
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
171
//
172
// Contributor(s): none.
173
//
174
Popular Tags