KickJava   Java API By Example, From Geeks To Geeks.

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


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: Choose.java,v 1.9 2004/02/16 22:24:29 minchau 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.BranchHandle;
26 import org.apache.bcel.generic.GOTO;
27 import org.apache.bcel.generic.IFEQ;
28 import org.apache.bcel.generic.InstructionHandle;
29 import org.apache.bcel.generic.InstructionList;
30 import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
31 import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
32 import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
33 import org.apache.xalan.xsltc.compiler.util.Type;
34 import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
35 import org.apache.xalan.xsltc.compiler.util.Util;
36
37 /**
38  * @author Jacek Ambroziak
39  * @author Santiago Pericas-Geertsen
40  * @author Morten Jorgensen
41  */

42 final class Choose extends Instruction {
43
44     /**
45      * Display the element contents (a lot of when's and an otherwise)
46      */

47     public void display(int indent) {
48     indent(indent);
49     Util.println("Choose");
50     indent(indent + IndentIncrement);
51     displayContents(indent + IndentIncrement);
52     }
53     
54     /**
55      * Translate this Choose element. Generate a test-chain for the various
56      * <xsl:when> elements and default to the <xsl:otherwise> if present.
57      */

58     public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
59     final Vector JavaDoc whenElements = new Vector JavaDoc();
60     Otherwise otherwise = null;
61     Enumeration JavaDoc elements = elements();
62
63     // These two are for reporting errors only
64
ErrorMsg error = null;
65     final int line = getLineNumber();
66
67     // Traverse all child nodes - must be either When or Otherwise
68
while (elements.hasMoreElements()) {
69         Object JavaDoc element = elements.nextElement();
70         // Add a When child element
71
if (element instanceof When) {
72         whenElements.addElement(element);
73         }
74         // Add an Otherwise child element
75
else if (element instanceof Otherwise) {
76         if (otherwise == null) {
77             otherwise = (Otherwise)element;
78         }
79         else {
80             error = new ErrorMsg(ErrorMsg.MULTIPLE_OTHERWISE_ERR, this);
81             getParser().reportError(Constants.ERROR, error);
82         }
83         }
84         else if (element instanceof Text) {
85         ((Text)element).ignore();
86         }
87         // It is an error if we find some other element here
88
else {
89         error = new ErrorMsg(ErrorMsg.WHEN_ELEMENT_ERR, this);
90         getParser().reportError(Constants.ERROR, error);
91         }
92     }
93
94     // Make sure that there is at least one <xsl:when> element
95
if (whenElements.size() == 0) {
96         error = new ErrorMsg(ErrorMsg.MISSING_WHEN_ERR, this);
97         getParser().reportError(Constants.ERROR, error);
98         return;
99     }
100
101     InstructionList il = methodGen.getInstructionList();
102
103     // next element will hold a handle to the beginning of next
104
// When/Otherwise if test on current When fails
105
BranchHandle nextElement = null;
106     Vector JavaDoc exitHandles = new Vector JavaDoc();
107     InstructionHandle exit = null;
108
109     Enumeration JavaDoc whens = whenElements.elements();
110     while (whens.hasMoreElements()) {
111         final When when = (When)whens.nextElement();
112         final Expression test = when.getTest();
113
114         InstructionHandle truec = il.getEnd();
115
116         if (nextElement != null)
117         nextElement.setTarget(il.append(NOP));
118         test.translateDesynthesized(classGen, methodGen);
119
120         if (test instanceof FunctionCall) {
121         FunctionCall call = (FunctionCall)test;
122         try {
123             Type type = call.typeCheck(getParser().getSymbolTable());
124             if (type != Type.Boolean) {
125             test._falseList.add(il.append(new IFEQ(null)));
126             }
127         }
128         catch (TypeCheckError e) {
129             // handled later!
130
}
131         }
132         // remember end of condition
133
truec = il.getEnd();
134
135         // The When object should be ignored completely in case it tests
136
// for the support of a non-available element
137
if (!when.ignore()) when.translateContents(classGen, methodGen);
138
139         // goto exit after executing the body of when
140
exitHandles.addElement(il.append(new GOTO(null)));
141         if (whens.hasMoreElements() || otherwise != null) {
142         nextElement = il.append(new GOTO(null));
143         test.backPatchFalseList(nextElement);
144         }
145         else
146         test.backPatchFalseList(exit = il.append(NOP));
147         test.backPatchTrueList(truec.getNext());
148     }
149     
150     // Translate any <xsl:otherwise> element
151
if (otherwise != null) {
152         nextElement.setTarget(il.append(NOP));
153         otherwise.translateContents(classGen, methodGen);
154         exit = il.append(NOP);
155     }
156
157     // now that end is known set targets of exit gotos
158
Enumeration JavaDoc exitGotos = exitHandles.elements();
159     while (exitGotos.hasMoreElements()) {
160         BranchHandle gotoExit = (BranchHandle)exitGotos.nextElement();
161         gotoExit.setTarget(exit);
162     }
163     }
164 }
165
Popular Tags