KickJava   Java API By Example, From Geeks To Geeks.

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


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: WithParam.java,v 1.17 2004/02/24 02:57:28 zongaro Exp $
18  */

19
20 package org.apache.xalan.xsltc.compiler;
21
22 import org.apache.bcel.generic.ConstantPoolGen;
23 import org.apache.bcel.generic.INVOKEVIRTUAL;
24 import org.apache.bcel.generic.InstructionList;
25 import org.apache.bcel.generic.PUSH;
26 import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
27 import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
28 import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
29 import org.apache.xalan.xsltc.compiler.util.ReferenceType;
30 import org.apache.xalan.xsltc.compiler.util.Type;
31 import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
32 import org.apache.xalan.xsltc.compiler.util.Util;
33 import org.apache.xml.utils.XMLChar;
34
35 /**
36  * @author Jacek Ambroziak
37  * @author Santiago Pericas-Geertsen
38  * @author Morten Jorgensen
39  * @author John Howard <JohnH@schemasoft.com>
40  */

41 final class WithParam extends Instruction {
42
43     /**
44      * Parameter's name.
45      */

46     private QName _name;
47     
48     /**
49      * The escaped qname of the with-param.
50      */

51     protected String JavaDoc _escapedName;
52     
53     /**
54      * Parameter's default value.
55      */

56     private Expression _select;
57
58     /**
59      * %OPT% This is set to true when the WithParam is used in a CallTemplate
60      * for a simple named template. If this is true, the parameters are
61      * passed to the named template through method arguments rather than
62      * using the expensive Translet.addParameter() call.
63      */

64     private boolean _doParameterOptimization = false;
65
66     /**
67      * Displays the contents of this element
68      */

69     public void display(int indent) {
70     indent(indent);
71     Util.println("with-param " + _name);
72     if (_select != null) {
73         indent(indent + IndentIncrement);
74         Util.println("select " + _select.toString());
75     }
76     displayContents(indent + IndentIncrement);
77     }
78     
79     /**
80      * Returns the escaped qname of the parameter
81      */

82     public String JavaDoc getEscapedName() {
83     return _escapedName;
84     }
85     
86     /**
87      * Return the name of this WithParam.
88      */

89     public QName getName() {
90         return _name;
91     }
92     
93     /**
94      * Set the name of the variable or paremeter. Escape all special chars.
95      */

96     public void setName(QName name) {
97     _name = name;
98     _escapedName = Util.escape(name.getStringRep());
99     }
100     
101     /**
102      * Set the do parameter optimization flag
103      */

104     public void setDoParameterOptimization(boolean flag) {
105         _doParameterOptimization = flag;
106     }
107     
108     /**
109      * The contents of a <xsl:with-param> elements are either in the element's
110      * 'select' attribute (this has precedence) or in the element body.
111      */

112     public void parseContents(Parser parser) {
113     final String JavaDoc name = getAttribute("name");
114     if (name.length() > 0) {
115             if (!XMLChar.isValidQName(name)) {
116                 ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, name,
117                                             this);
118                 parser.reportError(Constants.ERROR, err);
119             }
120         setName(parser.getQNameIgnoreDefaultNs(name));
121     }
122         else {
123         reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "name");
124         }
125     
126     final String JavaDoc select = getAttribute("select");
127     if (select.length() > 0) {
128         _select = parser.parseExpression(this, "select", null);
129     }
130     
131     parseChildren(parser);
132     }
133
134     /**
135      * Type-check either the select attribute or the element body, depending
136      * on which is in use.
137      */

138     public Type typeCheck(SymbolTable stable) throws TypeCheckError {
139     if (_select != null) {
140         final Type tselect = _select.typeCheck(stable);
141         if (tselect instanceof ReferenceType == false) {
142         _select = new CastExpr(_select, Type.Reference);
143         }
144     }
145     else {
146         typeCheckContents(stable);
147     }
148     return Type.Void;
149     }
150
151     /**
152      * Compile the value of the parameter, which is either in an expression in
153      * a 'select' attribute, or in the with-param element's body
154      */

155     public void translateValue(ClassGenerator classGen,
156                    MethodGenerator methodGen) {
157     // Compile expression is 'select' attribute if present
158
if (_select != null) {
159         _select.translate(classGen, methodGen);
160         _select.startIterator(classGen, methodGen);
161     }
162     // If not, compile result tree from parameter body if present.
163
else if (hasContents()) {
164         compileResultTree(classGen, methodGen);
165     }
166     // If neither are present then store empty string in parameter slot
167
else {
168         final ConstantPoolGen cpg = classGen.getConstantPool();
169         final InstructionList il = methodGen.getInstructionList();
170         il.append(new PUSH(cpg, Constants.EMPTYSTRING));
171     }
172     }
173
174     /**
175      * This code generates a sequence of bytecodes that call the
176      * addParameter() method in AbstractTranslet. The method call will add
177      * (or update) the parameter frame with the new parameter value.
178      */

179     public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
180     final ConstantPoolGen cpg = classGen.getConstantPool();
181     final InstructionList il = methodGen.getInstructionList();
182
183     // Translate the value and put it on the stack
184
if (_doParameterOptimization) {
185         translateValue(classGen, methodGen);
186         return;
187     }
188     
189     // Make name acceptable for use as field name in class
190
String JavaDoc name = Util.escape(getEscapedName());
191
192     // Load reference to the translet (method is in AbstractTranslet)
193
il.append(classGen.loadTranslet());
194
195     // Load the name of the parameter
196
il.append(new PUSH(cpg, name)); // TODO: namespace ?
197
// Generete the value of the parameter (use value in 'select' by def.)
198
translateValue(classGen, methodGen);
199     // Mark this parameter value is not being the default value
200
il.append(new PUSH(cpg, false));
201     // Pass the parameter to the template
202
il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS,
203                              ADD_PARAMETER,
204                              ADD_PARAMETER_SIG)));
205     il.append(POP); // cleanup stack
206
}
207 }
208
Popular Tags