KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icl > saxon > style > XSLGeneralVariable


1 package com.icl.saxon.style;
2 import com.icl.saxon.tree.AttributeCollection;
3 import com.icl.saxon.*;
4 import com.icl.saxon.om.*;
5 import com.icl.saxon.tree.NodeImpl;
6 import com.icl.saxon.functions.Concat;
7 import com.icl.saxon.expr.*;
8 import com.icl.saxon.output.*;
9 import javax.xml.transform.*;
10 import java.io.*;
11 import java.util.*;
12
13 /**
14 * This class defines common behaviour across xsl:variable, xsl:param, and xsl:with-param
15 */

16
17 public abstract class XSLGeneralVariable extends StyleElement {
18
19     protected int variableFingerprint = -1;
20     protected Expression select = null;
21     protected String JavaDoc simpleText = null;
22     protected boolean global;
23     protected Procedure procedure = null; // used only for global variables
24
protected boolean assignable = false;
25     protected boolean redundant = false;
26
27     /**
28     * Determine whether this type of element is allowed to contain a template-body
29     * @return true: yes, it may contain a template-body
30     */

31
32     public boolean mayContainTemplateBody() {
33         return true;
34     }
35
36     public boolean isGlobal() {
37         return (getParentNode() instanceof XSLStyleSheet);
38     }
39
40     /**
41     * Test whether it is permitted to assign to the variable using the saxon:assign
42     * extension element. This will only be true if the extra attribute saxon:assignable="yes"
43     * is present.
44     */

45
46     public boolean isAssignable() {
47         return assignable;
48     }
49         
50     /**
51     * Get the owning Procedure definition, if this is a local variable
52     */

53
54     public Procedure getOwningProcedure() throws TransformerConfigurationException {
55         NodeInfo node = this;
56         while (true) {
57             NodeInfo next = (NodeInfo)node.getParent();
58             if (next instanceof XSLStyleSheet) {
59                 if (node instanceof XSLTemplate) {
60                     return ((XSLTemplate)node).getProcedure();
61                 } else if (node instanceof XSLGeneralVariable) {
62                     return ((XSLGeneralVariable)node).getProcedure();
63                 } else if (node instanceof SAXONFunction) {
64                     return ((SAXONFunction)node).getProcedure();
65                 } else if (node instanceof XSLAttributeSet) {
66                     return ((XSLAttributeSet)node).getProcedure();
67                 } else {
68                     compileError("Local variable must be declared within a template");
69                     return new Procedure(); // for error recovery
70
}
71             }
72             node=next;
73         }
74     }
75
76     /**
77     * Preprocess: this ensures space is available for local variables declared within
78     * this global variable
79     */

80
81     public void preprocess() throws TransformerConfigurationException
82     {
83         if (global) {
84             getPrincipalStyleSheet().allocateLocalSlots(procedure.getNumberOfVariables());
85         }
86     }
87
88     /**
89     * Get the display name of the variable.
90     */

91
92     public String JavaDoc getVariableName() {
93         return getAttributeValue("", "name");
94     }
95     
96     /**
97     * Get the fingerprint of the variable name
98     */

99     
100     public int getVariableFingerprint() {
101         
102         // if an expression has a forwards reference to this variable, getVariableFingerprint() can be
103
// called before prepareAttributes() is called. We need to allow for this. But we'll
104
// deal with any errors when we come round to processing this attribute, to avoid
105
// duplicate error messages
106

107         if (variableFingerprint==-1) {
108             StandardNames sn = getStandardNames();
109             String JavaDoc nameAttribute = getAttributeValue(sn.NAME & 0xfffff);
110             if (nameAttribute==null) {
111                 return -1; // we'll report the error later
112
}
113             try {
114                 variableFingerprint = makeNameCode(nameAttribute, false) & 0xfffff;
115             } catch (NamespaceException err) {
116                 variableFingerprint = -1;
117             }
118         }
119         return variableFingerprint;
120     }
121
122     public void prepareAttributes() throws TransformerConfigurationException {
123         
124         getVariableFingerprint();
125
126         StandardNames sn = getStandardNames();
127         AttributeCollection atts = getAttributeList();
128         
129         String JavaDoc selectAtt = null;
130         String JavaDoc assignAtt = null;
131         String JavaDoc nameAtt = null;
132                 
133         for (int a=0; a<atts.getLength(); a++) {
134             int nc = atts.getNameCode(a);
135             int f = nc & 0xfffff;
136             if (f==sn.NAME) {
137                 nameAtt = atts.getValue(a);
138             } else if (f==sn.SELECT) {
139                 selectAtt = atts.getValue(a);
140             } else if (f==sn.SAXON_ASSIGNABLE) {
141                 assignAtt = atts.getValue(a);
142             } else {
143                 checkUnknownAttribute(nc);
144             }
145         }
146
147         if (nameAtt==null) {
148             reportAbsence("name");
149         } else if (!Name.isQName(nameAtt)) {
150             compileError("Variable name must be a valid QName");
151         }
152    
153
154         if (selectAtt!=null) {
155             select = makeExpression(selectAtt);
156         }
157
158         if (assignAtt!=null && assignAtt.equals("yes")) {
159             assignable=true;
160         }
161     }
162
163     public void validate() throws TransformerConfigurationException {
164         global = (getParentNode() instanceof XSLStyleSheet);
165         if (global) {
166             procedure = new Procedure();
167         }
168         if (select!=null && getFirstChild()!=null) {
169             compileError("An " + getDisplayName() + " element with a select attribute must be empty");
170         }
171
172         if (select==null) {
173             NodeImpl first = (NodeImpl)getFirstChild();
174             if (first==null) {
175                 select = new StringValue("");
176             } else {
177                 NodeImpl next = (NodeImpl)first.getNextSibling();
178                 if (next==null) {
179                     // there is exactly one child node
180
if (first.getNodeType() == NodeInfo.TEXT) {
181                         // it is a text node: optimize for this case
182
simpleText = first.getStringValue();
183                     }
184                 }
185             }
186         }
187     }
188
189     /**
190     * Check whether this declaration duplicates another one
191     */

192
193     public void checkDuplicateDeclaration() throws TransformerConfigurationException {
194         Binding binding = getVariableBinding(getVariableFingerprint());
195         int thisPrecedence = this.getPrecedence();
196         if (binding!=null) {
197             if (global) {
198                 int otherPrecedence = ((XSLGeneralVariable)binding).getPrecedence();
199                 if (thisPrecedence == otherPrecedence) {
200                     compileError("Duplicate global variable declaration");
201                 } else if (thisPrecedence < otherPrecedence) {
202                     redundant = true;
203                 } else {
204                    ((XSLGeneralVariable)binding).redundant = true;
205                 }
206             } else {
207                 if (!binding.isGlobal()) {
208                     //System.err.println("Clash with line " + ((StyleElement)binding).getLineNumber());
209
compileError("Variable is already declared in this template");
210                 }
211             }
212         }
213     }
214
215
216     /**
217     * Get the value of the select expression if present or the content of the element otherwise
218     */

219
220     protected Value getSelectValue(Context context) throws TransformerException {
221         if (select==null) {
222             SingletonNodeSet fragment;
223             if (simpleText != null) {
224                 fragment = new TextFragmentValue(simpleText,
225                                              getSystemId(),
226                                              context.getController());
227             } else {
228                 Controller c = context.getController();
229                 FragmentValue frag = new FragmentValue(c);
230                 Outputter old = c.getOutputter();
231                 c.changeOutputDestination(null, frag.getEmitter());
232                 if (global && procedure.getNumberOfVariables()>0) {
233                     Bindery bindery = context.getBindery();
234                     bindery.openStackFrame(new ParameterSet());
235                     processChildren(context);
236                     bindery.closeStackFrame();
237                 } else {
238                     processChildren(context);
239                 }
240                 c.resetOutputDestination(old);
241                 frag.setBaseURI(getSystemId());
242                 fragment = frag;
243             }
244             if (forwardsCompatibleModeIsEnabled()) {
245                 fragment.allowGeneralUse();
246             }
247             return fragment;
248
249         } else {
250             context.setStaticContext(staticContext);
251             Value result = select.evaluate(context);
252             if (assignable && (result instanceof NodeSetIntent)) {
253                 result = new NodeSetExtent(((NodeSetIntent)result).enumerate(),
254                                             context.getController());
255             }
256             return result;
257         }
258     }
259
260     /**
261     * Get associated Procedure (for details of stack frame, if this is a global variable containing
262     * local variable declarations)
263     */

264
265     public Procedure getProcedure() {
266         return procedure;
267     }
268
269
270 }
271
272 //
273
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
274
// you may not use this file except in compliance with the License. You may obtain a copy of the
275
// License at http://www.mozilla.org/MPL/
276
//
277
// Software distributed under the License is distributed on an "AS IS" basis,
278
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
279
// See the License for the specific language governing rights and limitations under the License.
280
//
281
// The Original Code is: all this file.
282
//
283
// The Initial Developer of the Original Code is
284
// Michael Kay of International Computers Limited (mhkay@iclway.co.uk).
285
//
286
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
287
//
288
// Contributor(s): none.
289
//
290
Popular Tags