KickJava   Java API By Example, From Geeks To Geeks.

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


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: ApplyTemplates.java,v 1.21 2004/02/24 03:55:47 zongaro Exp $
18  */

19
20 package org.apache.xalan.xsltc.compiler;
21
22 import java.util.Enumeration JavaDoc;
23 import java.util.Vector JavaDoc;
24
25 import org.apache.bcel.generic.ConstantPoolGen;
26 import org.apache.bcel.generic.INVOKEINTERFACE;
27 import org.apache.bcel.generic.INVOKEVIRTUAL;
28 import org.apache.bcel.generic.InstructionList;
29 import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
30 import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
31 import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
32 import org.apache.xalan.xsltc.compiler.util.NodeSetType;
33 import org.apache.xalan.xsltc.compiler.util.NodeType;
34 import org.apache.xalan.xsltc.compiler.util.ReferenceType;
35 import org.apache.xalan.xsltc.compiler.util.ResultTreeType;
36 import org.apache.xalan.xsltc.compiler.util.Type;
37 import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
38 import org.apache.xalan.xsltc.compiler.util.Util;
39 import org.apache.xml.utils.XMLChar;
40
41 /**
42  * @author Jacek Ambroziak
43  * @author Santiago Pericas-Geertsen
44  */

45 final class ApplyTemplates extends Instruction {
46     private Expression _select;
47     private Type _type = null;
48     private QName _modeName;
49     private String JavaDoc _functionName;
50     
51     public void display(int indent) {
52     indent(indent);
53     Util.println("ApplyTemplates");
54     indent(indent + IndentIncrement);
55     Util.println("select " + _select.toString());
56     if (_modeName != null) {
57         indent(indent + IndentIncrement);
58         Util.println("mode " + _modeName);
59     }
60     }
61
62     public boolean hasWithParams() {
63     return hasContents();
64     }
65
66     public void parseContents(Parser parser) {
67     final String JavaDoc select = getAttribute("select");
68     final String JavaDoc mode = getAttribute("mode");
69     
70     if (select.length() > 0) {
71         _select = parser.parseExpression(this, "select", null);
72
73     }
74     
75     if (mode.length() > 0) {
76             if (!XMLChar.isValidQName(mode)) {
77                 ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, mode, this);
78                 parser.reportError(Constants.ERROR, err);
79             }
80         _modeName = parser.getQNameIgnoreDefaultNs(mode);
81     }
82     
83     // instantiate Mode if needed, cache (apply temp) function name
84
_functionName =
85         parser.getTopLevelStylesheet().getMode(_modeName).functionName();
86     parseChildren(parser);// with-params
87
}
88
89     public Type typeCheck(SymbolTable stable) throws TypeCheckError {
90     if (_select != null) {
91         _type = _select.typeCheck(stable);
92         if (_type instanceof NodeType || _type instanceof ReferenceType) {
93         _select = new CastExpr(_select, Type.NodeSet);
94         _type = Type.NodeSet;
95         }
96         if (_type instanceof NodeSetType||_type instanceof ResultTreeType) {
97         typeCheckContents(stable); // with-params
98
return Type.Void;
99         }
100         throw new TypeCheckError(this);
101     }
102     else {
103         typeCheckContents(stable); // with-params
104
return Type.Void;
105     }
106     }
107
108     /**
109      * Translate call-template. A parameter frame is pushed only if
110      * some template in the stylesheet uses parameters.
111      */

112     public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
113     boolean setStartNodeCalled = false;
114     final Stylesheet stylesheet = classGen.getStylesheet();
115     final ConstantPoolGen cpg = classGen.getConstantPool();
116     final InstructionList il = methodGen.getInstructionList();
117     final int current = methodGen.getLocalIndex("current");
118
119     // check if sorting nodes is required
120
final Vector JavaDoc sortObjects = new Vector JavaDoc();
121     final Enumeration JavaDoc children = elements();
122     while (children.hasMoreElements()) {
123         final Object JavaDoc child = children.nextElement();
124         if (child instanceof Sort) {
125         sortObjects.addElement(child);
126         }
127     }
128
129     // Push a new parameter frame
130
if (stylesheet.hasLocalParams() || hasContents()) {
131         il.append(classGen.loadTranslet());
132         final int pushFrame = cpg.addMethodref(TRANSLET_CLASS,
133                            PUSH_PARAM_FRAME,
134                            PUSH_PARAM_FRAME_SIG);
135         il.append(new INVOKEVIRTUAL(pushFrame));
136         // translate with-params
137
translateContents(classGen, methodGen);
138     }
139
140
141     il.append(classGen.loadTranslet());
142
143     // The 'select' expression is a result-tree
144
if ((_type != null) && (_type instanceof ResultTreeType)) {
145         // <xsl:sort> cannot be applied to a result tree - issue warning
146
if (sortObjects.size() > 0) {
147         ErrorMsg err = new ErrorMsg(ErrorMsg.RESULT_TREE_SORT_ERR,this);
148         getParser().reportError(WARNING, err);
149         }
150         // Put the result tree (a DOM adapter) on the stack
151
_select.translate(classGen, methodGen);
152         // Get back the DOM and iterator (not just iterator!!!)
153
_type.translateTo(classGen, methodGen, Type.NodeSet);
154     }
155     else {
156         il.append(methodGen.loadDOM());
157
158         // compute node iterator for applyTemplates
159
if (sortObjects.size() > 0) {
160         Sort.translateSortIterator(classGen, methodGen,
161                        _select, sortObjects);
162         int setStartNode = cpg.addInterfaceMethodref(NODE_ITERATOR,
163                                  SET_START_NODE,
164                                  "(I)"+
165                                  NODE_ITERATOR_SIG);
166         il.append(methodGen.loadCurrentNode());
167         il.append(new INVOKEINTERFACE(setStartNode,2));
168         setStartNodeCalled = true;
169         }
170         else {
171         if (_select == null)
172             Mode.compileGetChildren(classGen, methodGen, current);
173         else
174             _select.translate(classGen, methodGen);
175         }
176     }
177
178     if (_select != null && !setStartNodeCalled) {
179         _select.startIterator(classGen, methodGen);
180     }
181
182     //!!! need to instantiate all needed modes
183
final String JavaDoc className = classGen.getStylesheet().getClassName();
184     il.append(methodGen.loadHandler());
185     final String JavaDoc applyTemplatesSig = classGen.getApplyTemplatesSig();
186     final int applyTemplates = cpg.addMethodref(className,
187                             _functionName,
188                             applyTemplatesSig);
189     il.append(new INVOKEVIRTUAL(applyTemplates));
190     
191     // Pop parameter frame
192
if (stylesheet.hasLocalParams() || hasContents()) {
193         il.append(classGen.loadTranslet());
194         final int popFrame = cpg.addMethodref(TRANSLET_CLASS,
195                           POP_PARAM_FRAME,
196                           POP_PARAM_FRAME_SIG);
197         il.append(new INVOKEVIRTUAL(popFrame));
198     }
199     }
200 }
201
Popular Tags