KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > style > AttributeValueTemplate


1 package net.sf.saxon.style;
2 import net.sf.saxon.expr.*;
3 import net.sf.saxon.functions.Concat;
4 import net.sf.saxon.functions.SystemFunction;
5 import net.sf.saxon.instruct.SimpleContentConstructor;
6 import net.sf.saxon.trans.StaticError;
7 import net.sf.saxon.trans.XPathException;
8 import net.sf.saxon.type.Type;
9 import net.sf.saxon.value.Cardinality;
10 import net.sf.saxon.value.StringValue;
11
12 import java.util.ArrayList JavaDoc;
13 import java.util.List JavaDoc;
14
15 /**
16 * This class represents an attribute value template. The class allows an AVT to be parsed, and
17 * can construct an Expression that returns the effective value of the AVT.
18 *
19 * This is an abstract class that is never instantiated, it contains static methods only.
20 */

21
22 public abstract class AttributeValueTemplate {
23
24     private AttributeValueTemplate() {}
25
26
27     /**
28      * Static factory method to create an AVT from an XSLT string representation.
29     */

30
31     public static Expression make(String JavaDoc avt,
32                                   int lineNumber,
33                                   StaticContext env) throws XPathException {
34
35         List JavaDoc components = new ArrayList JavaDoc(5);
36
37         int i0, i1, i8, i9;
38         int len = avt.length();
39         int last = 0;
40         while (last < len) {
41
42             i0 = avt.indexOf("{", last);
43             i1 = avt.indexOf("{{", last);
44             i8 = avt.indexOf("}", last);
45             i9 = avt.indexOf("}}", last);
46
47             if ((i0 < 0 || len < i0) && (i8 < 0 || len < i8)) { // found end of string
48
addStringComponent(components, avt, last, len);
49                 break;
50             } else if (i8 >= 0 && (i0 < 0 || i8 < i0)) { // found a "}"
51
if (i8 != i9) { // a "}" that isn't a "}}"
52
StaticError err = new StaticError(
53                             "Closing curly brace in attribute value template \"" + avt.substring(0,len) + "\" must be doubled");
54                     err.setErrorCode("XTSE0360");
55                     throw err;
56                 }
57                 addStringComponent(components, avt, last, i8 + 1);
58                 last = i8 + 2;
59             } else if (i1 >= 0 && i1 == i0) { // found a doubled "{{"
60
addStringComponent(components, avt, last, i1 + 1);
61                 last = i1 + 2;
62             } else if (i0 >= 0) { // found a single "{"
63
if (i0 > last) {
64                     addStringComponent(components, avt, last, i0);
65                 }
66                 Expression exp;
67                 ExpressionParser parser = new ExpressionParser();
68                 exp = parser.parse(avt, i0 + 1, Token.RCURLY, lineNumber, env);
69                 exp = exp.simplify(env);
70                 last = parser.getTokenizer().currentTokenStartOffset + 1;
71
72                 if (env.isInBackwardsCompatibleMode()) {
73                     components.add(makeFirstItem(exp, env));
74                 } else {
75                     components.add(new SimpleContentConstructor(exp, StringValue.SINGLE_SPACE).simplify(env));
76                 }
77
78             } else {
79                 throw new IllegalStateException JavaDoc("Internal error parsing AVT");
80             }
81         }
82
83         // is it empty?
84

85         if (components.size() == 0) {
86             return StringValue.EMPTY_STRING;
87         }
88
89         // is it a single component?
90

91         if (components.size() == 1) {
92             return ((Expression) components.get(0)).simplify(env);
93         }
94
95         // otherwise, return an expression that concatenates the components
96

97         Concat fn = (Concat) SystemFunction.makeSystemFunction("concat", components.size(), env.getNamePool());
98         Expression[] args = new Expression[components.size()];
99         components.toArray(args);
100         fn.setArguments(args);
101         fn.setLocationId(env.getLocationMap().allocateLocationId(env.getSystemId(), lineNumber));
102         return fn.simplify(env);
103
104     }
105
106     private static void addStringComponent(List JavaDoc components, String JavaDoc avt, int start, int end) {
107         if (start < end) {
108             components.add(StringValue.makeStringValue(avt.substring(start, end)));
109         }
110     }
111
112     /**
113     * Make an expression that extracts the first item of a sequence, after atomization
114     */

115
116     public static Expression makeFirstItem(Expression exp, StaticContext env) {
117         if (!Type.isSubType(exp.getItemType(), Type.ANY_ATOMIC_TYPE)) {
118             exp = new Atomizer(exp, env.getConfiguration());
119         }
120         if (Cardinality.allowsMany(exp.getCardinality())) {
121             exp = new FirstItemExpression(exp);
122         }
123         if (!Type.isSubType(exp.getItemType(), Type.STRING_TYPE)) {
124             exp = new AtomicSequenceConverter(exp, Type.STRING_TYPE);
125         }
126         return exp;
127     }
128
129 }
130
131 //
132
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
133
// you may not use this file except in compliance with the License. You may obtain a copy of the
134
// License at http://www.mozilla.org/MPL/
135
//
136
// Software distributed under the License is distributed on an "AS IS" basis,
137
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
138
// See the License for the specific language governing rights and limitations under the License.
139
//
140
// The Original Code is: all this file.
141
//
142
// The Initial Developer of the Original Code is Michael H. Kay.
143
//
144
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
145
//
146
// Contributor(s): none.
147
//
148
Popular Tags