KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icl > saxon > expr > AttributeValueTemplate


1 package com.icl.saxon.expr;
2 import com.icl.saxon.Context;
3
4
5 /**
6 * This class represents an attribute value template. Although it is not technically
7 * an expression in the sense of XSL syntax, we model it as an expression for inheritance
8 * purposes.
9 */

10
11 public final class AttributeValueTemplate extends Expression {
12
13     private Expression[] components = new Expression[10];
14     private int numberOfComponents;
15
16     /**
17     * Constructor to make an AVT from a list of components. The components are the elements
18     * of the AVT, e.g. abc{def}geh has three components, String "abc", expression "def", and
19     * String "geh"
20     */

21
22     private AttributeValueTemplate(Expression[] components, int numberOfComponents) {
23         this.components = new Expression[numberOfComponents];
24         this.numberOfComponents = numberOfComponents;
25         System.arraycopy(components, 0, this.components, 0, numberOfComponents);
26     }
27     
28     /**
29     * Static factory method to create an AVT from an XSL string representation
30     */

31
32     public static Expression make(String JavaDoc avt, StaticContext env) throws XPathException {
33
34         if ( avt.indexOf("{") < 0 && avt.indexOf("}") < 0) { // fast path: no embedded expressions
35
return new StringValue(avt);
36
37         } else {
38             int nr = 0;
39             Expression[] components = new Expression[avt.length()]; // for once, we'll set a limit!
40
// process embedded expressions within the avt
41
int i0, i1, i2, i8, i9, len, last;
42             char inquote = ' ';
43             last = 0;
44             len = avt.length();
45             while (last<len) {
46                 i0 = avt.indexOf("{", last);
47                 i1 = avt.indexOf("{{", last);
48                 i8 = avt.indexOf("}", last);
49                 i9 = avt.indexOf("}}", last);
50                 //System.err.println("AVT:" + avt + ": " + i0 + "," + i1 + "," + i8 + "," + i9);
51

52                 if (i8>=0 && (i0<0 || i8<i0)) { // found a "}"
53
if (i8 != i9) { // a "}" that isn't a "}}"
54
throw new XPathException("Closing curly brace in attribute value template \"" + avt + "\" must be doubled");
55                     }
56                     components[nr++] = new StringValue(avt.substring(last, i8+1));
57                     last = i8+2;
58                 } else if (i1>=0 && i1==i0) { // found a doubled "{{"
59
components[nr++] = new StringValue(avt.substring(last, i1+1));
60                     last = i1+2;
61                 } else if (i0>=0) { // found a single "{"
62
if (i0>last) {
63                         components[nr++] = new StringValue(avt.substring(last, i0));
64                     }
65                     for (i2=i0+1; i2<len; i2++) {
66                         if (avt.charAt(i2)=='\"') inquote = '\"';
67                         if (avt.charAt(i2)=='\'') inquote = '\'';
68                         if (inquote!=' ') {
69                             i2++;
70                             while (i2<len && avt.charAt(i2)!=inquote) i2++;
71                             inquote = ' ';
72                         } else {
73                             if (avt.charAt(i2)=='}') {
74                                // we're in an expression so we don't need to check for a doubled "}}"
75
break;
76                             }
77                         }
78                     }
79                     if (i2>=len) {
80                         throw new XPathException("No closing \"}\" in attribute value template " + avt);
81                     }
82
83                     String JavaDoc expr = avt.substring(i0+1, i2);
84                     Expression ex = Expression.make(expr, env);
85                     components[nr++] = ex;
86                     last=i2+1;
87                 } else { // didn't find anything
88
components[nr++] = new StringValue(avt.substring(last));
89                     last=len;
90                 }
91             }
92             return (new AttributeValueTemplate(components, nr)).simplify();
93         }
94     }
95
96     /**
97     * Simplify an expression.
98     * @return the simplified expression
99     */

100
101     public Expression simplify() throws XPathException {
102
103         // is it empty?
104
if (numberOfComponents==0) {
105             return new StringValue("");
106         }
107         
108         // if there's only one component, return that
109
if (numberOfComponents==1) {
110             return components[0];
111         }
112
113         // otherwise, simplify each of the components
114
for (int i=0; i<numberOfComponents; i++) {
115             components[i] = components[i].simplify();
116         }
117
118         // TODO: see if adjacent components can be merged.
119
return this;
120     }
121
122     /**
123     * Evaluate an AVT.
124     * @param context The context in which the AVT is to be evaluated
125     * @return the value of the AVT, evaluated in the current context
126     */

127
128     public Value evaluate(Context context) throws XPathException {
129         return new StringValue(evaluateAsString(context));
130     }
131
132     /**
133     * Determine the data type of the expression, if possible
134     * @return Value.STRING
135     */

136
137     public int getDataType() {
138         return Value.STRING;
139     }
140
141     /**
142     * Evaluate an expression as a String.
143     * @param context The context in which the expression is to be evaluated
144     * @return the value of the expression, evaluated in the current context
145     */

146
147     public String JavaDoc evaluateAsString(Context context) throws XPathException {
148         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
149         for (int i=0; i<numberOfComponents; i++) {
150             sb.append(components[i].evaluateAsString(context));
151         }
152         return sb.toString();
153     }
154
155     /**
156     * Determine which aspects of the context the expression depends on. The result is
157     * a bitwise-or'ed value composed from constants such as Context.VARIABLES and
158     * Context.CURRENT_NODE
159     */

160
161     public int getDependencies() {
162         int dep = 0;
163         for (int i=0; i<numberOfComponents; i++) {
164             dep |= components[i].getDependencies();
165         }
166         return dep;
167     }
168
169     /**
170     * Perform a partial evaluation of the expression, by eliminating specified dependencies
171     * on the context.
172     * @param dependencies The dependencies to be removed
173     * @param context The context to be used for the partial evaluation
174     * @return a new expression that does not have any of the specified
175     * dependencies
176     */

177
178     public Expression reduce(int dependencies, Context context) throws XPathException {
179         throw new XPathException("Cannot reduce expressions in an attribute value template");
180     }
181     
182     /**
183     * Diagnostic print of expression structure
184     */

185     
186     public void display(int level) {
187         System.err.println(indent(level) + "{<AVT>}");
188     }
189 }
190
191 //
192
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
193
// you may not use this file except in compliance with the License. You may obtain a copy of the
194
// License at http://www.mozilla.org/MPL/
195
//
196
// Software distributed under the License is distributed on an "AS IS" basis,
197
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
198
// See the License for the specific language governing rights and limitations under the License.
199
//
200
// The Original Code is: all this file.
201
//
202
// The Initial Developer of the Original Code is
203
// Michael Kay of International Computers Limited (mhkay@iclway.co.uk).
204
//
205
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
206
//
207
// Contributor(s): none.
208
//
209
Popular Tags