KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xalan > xsltc > compiler > Template


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: Template.java,v 1.25 2004/02/24 03:55:48 zongaro Exp $
18  */

19
20 package org.apache.xalan.xsltc.compiler;
21
22 import java.util.Vector JavaDoc;
23
24 import org.apache.bcel.generic.ConstantPoolGen;
25 import org.apache.bcel.generic.INVOKEVIRTUAL;
26 import org.apache.bcel.generic.InstructionHandle;
27 import org.apache.bcel.generic.InstructionList;
28 import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
29 import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
30 import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
31 import org.apache.xalan.xsltc.compiler.util.NamedMethodGenerator;
32 import org.apache.xalan.xsltc.compiler.util.Type;
33 import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
34 import org.apache.xalan.xsltc.compiler.util.Util;
35 import org.apache.xml.utils.XMLChar;
36
37
38 /**
39  * @author Jacek Ambroziak
40  * @author Santiago Pericas-Geertsen
41  * @author Morten Jorgensen
42  * @author Erwin Bolwidt <ejb@klomp.org>
43  */

44 public final class Template extends TopLevelElement {
45
46     private QName _name; // The name of the template (if any)
47
private QName _mode; // Mode in which this template is instantiated.
48
private Pattern _pattern; // Matching pattern defined for this template.
49
private double _priority; // Matching priority of this template.
50
private int _position; // Position within stylesheet (prio. resolution)
51
private boolean _disabled = false;
52     private boolean _compiled = false;//make sure it is compiled only once
53
private boolean _simplified = false;
54
55     // True if this is a simple named template. A simple named
56
// template is a template which only has a name but no match pattern.
57
private boolean _isSimpleNamedTemplate = false;
58     
59     // The list of parameters in this template. This is only used
60
// for simple named templates.
61
private Vector JavaDoc _parameters = new Vector JavaDoc();
62     
63     public boolean hasParams() {
64     return _parameters.size() > 0;
65     }
66
67     public boolean isSimplified() {
68     return(_simplified);
69     }
70
71     public void setSimplified() {
72     _simplified = true;
73     }
74
75     public boolean isSimpleNamedTemplate() {
76         return _isSimpleNamedTemplate;
77     }
78     
79     public void addParameter(Param param) {
80         _parameters.addElement(param);
81     }
82     
83     public Vector JavaDoc getParameters() {
84         return _parameters;
85     }
86
87     public void disable() {
88     _disabled = true;
89     }
90
91     public boolean disabled() {
92     return(_disabled);
93     }
94
95     public double getPriority() {
96     return _priority;
97     }
98
99     public int getPosition() {
100     return(_position);
101     }
102
103     public boolean isNamed() {
104     return _name != null;
105     }
106
107     public Pattern getPattern() {
108     return _pattern;
109     }
110
111     public QName getName() {
112     return _name;
113     }
114
115     public void setName(QName qname) {
116     if (_name == null) _name = qname;
117     }
118
119     public QName getModeName() {
120     return _mode;
121     }
122
123     /**
124      * Compare this template to another. First checks priority, then position.
125      */

126     public int compareTo(Object JavaDoc template) {
127     Template other = (Template)template;
128     if (_priority > other._priority)
129         return 1;
130     else if (_priority < other._priority)
131         return -1;
132     else if (_position > other._position)
133         return 1;
134     else if (_position < other._position)
135         return -1;
136     else
137         return 0;
138     }
139
140     public void display(int indent) {
141     Util.println('\n');
142     indent(indent);
143     if (_name != null) {
144         indent(indent);
145         Util.println("name = " + _name);
146     }
147     else if (_pattern != null) {
148         indent(indent);
149         Util.println("match = " + _pattern.toString());
150     }
151     if (_mode != null) {
152         indent(indent);
153         Util.println("mode = " + _mode);
154     }
155     displayContents(indent + IndentIncrement);
156     }
157
158     private boolean resolveNamedTemplates(Template other, Parser parser) {
159
160     if (other == null) return true;
161
162     SymbolTable stable = parser.getSymbolTable();
163
164     final int us = this.getImportPrecedence();
165     final int them = other.getImportPrecedence();
166
167     if (us > them) {
168         other.disable();
169         return true;
170     }
171     else if (us < them) {
172         stable.addTemplate(other);
173         this.disable();
174         return true;
175     }
176     else {
177         return false;
178     }
179     }
180
181     private Stylesheet _stylesheet = null;
182
183     public Stylesheet getStylesheet() {
184     return _stylesheet;
185     }
186
187     public void parseContents(Parser parser) {
188
189     final String JavaDoc name = getAttribute("name");
190     final String JavaDoc mode = getAttribute("mode");
191     final String JavaDoc match = getAttribute("match");
192     final String JavaDoc priority = getAttribute("priority");
193
194     _stylesheet = super.getStylesheet();
195
196     if (name.length() > 0) {
197             if (!XMLChar.isValidQName(name)) {
198                 ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, name, this);
199                 parser.reportError(Constants.ERROR, err);
200             }
201         _name = parser.getQNameIgnoreDefaultNs(name);
202     }
203     
204     if (mode.length() > 0) {
205             if (!XMLChar.isValidQName(mode)) {
206                 ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, mode, this);
207                 parser.reportError(Constants.ERROR, err);
208             }
209         _mode = parser.getQNameIgnoreDefaultNs(mode);
210     }
211     
212     if (match.length() > 0) {
213         _pattern = parser.parsePattern(this, "match", null);
214     }
215
216     if (priority.length() > 0) {
217         _priority = Double.parseDouble(priority);
218     }
219     else {
220         if (_pattern != null)
221         _priority = _pattern.getPriority();
222         else
223         _priority = Double.NaN;
224     }
225
226     _position = parser.getTemplateIndex();
227
228     // Add the (named) template to the symbol table
229
if (_name != null) {
230         Template other = parser.getSymbolTable().addTemplate(this);
231         if (!resolveNamedTemplates(other, parser)) {
232         ErrorMsg err =
233             new ErrorMsg(ErrorMsg.TEMPLATE_REDEF_ERR, _name, this);
234         parser.reportError(Constants.ERROR, err);
235         }
236         // Is this a simple named template?
237
if (_pattern == null && _mode == null) {
238             _isSimpleNamedTemplate = true;
239         }
240     }
241
242     if (_parent instanceof Stylesheet) {
243         ((Stylesheet)_parent).addTemplate(this);
244     }
245     
246     parser.setTemplate(this); // set current template
247
parseChildren(parser);
248     parser.setTemplate(null); // clear template
249
}
250
251     /**
252      * When the parser realises that it is dealign with a simplified stylesheet
253      * it will create an empty Stylesheet object with the root element of the
254      * stylesheet (a LiteralElement object) as its only child. The Stylesheet
255      * object will then create this Template object and invoke this method to
256      * force some specific behaviour. What we need to do is:
257      * o) create a pattern matching on the root node
258      * o) add the LRE root node (the only child of the Stylesheet) as our
259      * only child node
260      * o) set the empty Stylesheet as our parent
261      * o) set this template as the Stylesheet's only child
262      */

263     public void parseSimplified(Stylesheet stylesheet, Parser parser) {
264
265     _stylesheet = stylesheet;
266     setParent(stylesheet);
267
268     _name = null;
269     _mode = null;
270     _priority = Double.NaN;
271     _pattern = parser.parsePattern(this, "/");
272
273     final Vector JavaDoc contents = _stylesheet.getContents();
274     final SyntaxTreeNode root = (SyntaxTreeNode)contents.elementAt(0);
275
276     if (root instanceof LiteralElement) {
277         addElement(root);
278         root.setParent(this);
279         contents.set(0, this);
280         parser.setTemplate(this);
281         root.parseContents(parser);
282         parser.setTemplate(null);
283     }
284     }
285
286     public Type typeCheck(SymbolTable stable) throws TypeCheckError {
287     if (_pattern != null) {
288         _pattern.typeCheck(stable);
289     }
290
291     return typeCheckContents(stable);
292     }
293
294     public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
295     final ConstantPoolGen cpg = classGen.getConstantPool();
296     final InstructionList il = methodGen.getInstructionList();
297
298     if (_disabled) return;
299     // bug fix #4433133, add a call to named template from applyTemplates
300
String JavaDoc className = classGen.getClassName();
301
302     if (_compiled && isNamed()){
303         String JavaDoc methodName = Util.escape(_name.toString());
304         il.append(classGen.loadTranslet());
305         il.append(methodGen.loadDOM());
306         il.append(methodGen.loadIterator());
307         il.append(methodGen.loadHandler());
308         il.append(methodGen.loadCurrentNode());
309         il.append(new INVOKEVIRTUAL(cpg.addMethodref(className,
310                              methodName,
311                              "("
312                              + DOM_INTF_SIG
313                              + NODE_ITERATOR_SIG
314                              + TRANSLET_OUTPUT_SIG
315                              + "I)V")));
316         return;
317     }
318
319     if (_compiled) return;
320     _compiled = true;
321         
322     // %OPT% Special handling for simple named templates.
323
if (_isSimpleNamedTemplate && methodGen instanceof NamedMethodGenerator) {
324         int numParams = _parameters.size();
325         NamedMethodGenerator namedMethodGen = (NamedMethodGenerator)methodGen;
326             
327             // Update load/store instructions to access Params from the stack
328
for (int i = 0; i < numParams; i++) {
329             Param param = (Param)_parameters.elementAt(i);
330             param.setLoadInstruction(namedMethodGen.loadParameter(i));
331             param.setStoreInstruction(namedMethodGen.storeParameter(i));
332         }
333     }
334         
335         translateContents(classGen, methodGen);
336     il.setPositions(true);
337     }
338         
339 }
340
Popular Tags