KickJava   Java API By Example, From Geeks To Geeks.

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


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: ProcessingInstructionPattern.java,v 1.7 2004/02/16 22:24:29 minchau Exp $
18  */

19
20 package org.apache.xalan.xsltc.compiler;
21
22 import org.apache.bcel.generic.BranchHandle;
23 import org.apache.bcel.generic.ConstantPoolGen;
24 import org.apache.bcel.generic.GOTO;
25 import org.apache.bcel.generic.IFEQ;
26 import org.apache.bcel.generic.IF_ICMPEQ;
27 import org.apache.bcel.generic.INVOKEINTERFACE;
28 import org.apache.bcel.generic.INVOKEVIRTUAL;
29 import org.apache.bcel.generic.InstructionHandle;
30 import org.apache.bcel.generic.InstructionList;
31 import org.apache.bcel.generic.PUSH;
32 import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
33 import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
34 import org.apache.xalan.xsltc.compiler.util.Type;
35 import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
36 import org.apache.xalan.xsltc.dom.Axis;
37 import org.apache.xml.dtm.DTM;
38
39 /**
40  * @author Morten Jorgensen
41  */

42 final class ProcessingInstructionPattern extends StepPattern {
43
44     private String JavaDoc _name = null;
45     private boolean _typeChecked = false;
46
47     /**
48      * Handles calls with no parameter (current node is implicit parameter).
49      */

50     public ProcessingInstructionPattern(String JavaDoc name) {
51     super(Axis.CHILD, DTM.PROCESSING_INSTRUCTION_NODE, null);
52     _name = name;
53     //if (_name.equals("*")) _typeChecked = true; no wildcard allowed!
54
}
55
56     /**
57      *
58      */

59      public double getDefaultPriority() {
60         return (_name != null) ? 0.0 : -0.5;
61      }
62     public String JavaDoc toString() {
63     if (_predicates == null)
64         return "processing-instruction("+_name+")";
65     else
66         return "processing-instruction("+_name+")"+_predicates;
67     }
68
69     public void reduceKernelPattern() {
70     _typeChecked = true;
71     }
72
73     public boolean isWildcard() {
74     return false;
75     }
76
77     public Type typeCheck(SymbolTable stable) throws TypeCheckError {
78     if (hasPredicates()) {
79         // Type check all the predicates (e -> position() = e)
80
final int n = _predicates.size();
81         for (int i = 0; i < n; i++) {
82         final Predicate pred = (Predicate)_predicates.elementAt(i);
83         pred.typeCheck(stable);
84         }
85     }
86     return Type.NodeSet;
87     }
88
89     public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
90     final ConstantPoolGen cpg = classGen.getConstantPool();
91     final InstructionList il = methodGen.getInstructionList();
92
93     // context node is on the stack
94
int gname = cpg.addInterfaceMethodref(DOM_INTF,
95                           "getNodeName",
96                           "(I)Ljava/lang/String;");
97     int cmp = cpg.addMethodref(STRING_CLASS,
98                    "equals", "(Ljava/lang/Object;)Z");
99
100     // Push current node on the stack
101
il.append(methodGen.loadCurrentNode());
102     il.append(SWAP);
103
104     // Overwrite current node with matching node
105
il.append(methodGen.storeCurrentNode());
106
107     // If pattern not reduced then check kernel
108
if (!_typeChecked) {
109         il.append(methodGen.loadCurrentNode());
110         final int getType = cpg.addInterfaceMethodref(DOM_INTF,
111                               "getExpandedTypeID",
112                                                           "(I)I");
113         il.append(methodGen.loadDOM());
114         il.append(methodGen.loadCurrentNode());
115         il.append(new INVOKEINTERFACE(getType, 2));
116         il.append(new PUSH(cpg, DTM.PROCESSING_INSTRUCTION_NODE));
117         _falseList.add(il.append(new IF_ICMPEQ(null)));
118     }
119
120     // Load the requested processing instruction name
121
il.append(new PUSH(cpg, _name));
122     // Load the current processing instruction's name
123
il.append(methodGen.loadDOM());
124     il.append(methodGen.loadCurrentNode());
125     il.append(new INVOKEINTERFACE(gname, 2));
126     // Compare the two strings
127
il.append(new INVOKEVIRTUAL(cmp));
128     _falseList.add(il.append(new IFEQ(null)));
129         
130     // Compile the expressions within the predicates
131
if (hasPredicates()) {
132         final int n = _predicates.size();
133         for (int i = 0; i < n; i++) {
134         Predicate pred = (Predicate)_predicates.elementAt(i);
135         Expression exp = pred.getExpr();
136         exp.translateDesynthesized(classGen, methodGen);
137         _trueList.append(exp._trueList);
138         _falseList.append(exp._falseList);
139         }
140     }
141
142     // Backpatch true list and restore current iterator/node
143
InstructionHandle restore;
144     restore = il.append(methodGen.storeCurrentNode());
145     backPatchTrueList(restore);
146     BranchHandle skipFalse = il.append(new GOTO(null));
147
148     // Backpatch false list and restore current iterator/node
149
restore = il.append(methodGen.storeCurrentNode());
150     backPatchFalseList(restore);
151     _falseList.add(il.append(new GOTO(null)));
152
153     // True list falls through
154
skipFalse.setTarget(il.append(NOP));
155     }
156 }
157
Popular Tags