* Compile transform() into the output class. This method is used to
* initialize global variables and global parameters. The current node
* is set to be the document's root node.
*/
private void compileTransform(ClassGenerator classGen) {
final ConstantPoolGen cpg = classGen.getConstantPool();
/*
* Define the the method transform with the following signature:
* void transform(DOM, NodeIterator, HandlerBase)
*/
final org.apache.bcel.generic.Type[] argTypes =
new org.apache.bcel.generic.Type[3];
argTypes[0] = Util.getJCRefType(DOM_INTF_SIG);
argTypes[1] = Util.getJCRefType(NODE_ITERATOR_SIG);
argTypes[2] = Util.getJCRefType(TRANSLET_OUTPUT_SIG);
final String[] argNames = new String[3];
argNames[0] = DOCUMENT_PNAME;
argNames[1] = ITERATOR_PNAME;
argNames[2] = TRANSLET_OUTPUT_PNAME;
final InstructionList il = new InstructionList();
final MethodGenerator transf =
new MethodGenerator(ACC_PUBLIC,
org.apache.bcel.generic.Type.VOID,
argTypes, argNames,
"transform",
_className,
il,
classGen.getConstantPool());
transf.addException("org.apache.xalan.xsltc.TransletException");
// Define and initialize current with the root node
final LocalVariableGen current =
transf.addLocalVariable("current",
org.apache.bcel.generic.Type.INT,
null, null);
final String applyTemplatesSig = classGen.getApplyTemplatesSig();
final int applyTemplates = cpg.addMethodref(getClassName(),
"applyTemplates",
applyTemplatesSig);
final int domField = cpg.addFieldref(getClassName(),
DOM_FIELD,
DOM_INTF_SIG);
// push translet for PUTFIELD
il.append(classGen.loadTranslet());
// prepare appropriate DOM implementation
if (isMultiDocument()) {
il.append(new NEW(cpg.addClass(MULTI_DOM_CLASS)));
il.append(DUP);
}
il.append(classGen.loadTranslet());
il.append(transf.loadDOM());
il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS,
"makeDOMAdapter",
"("+DOM_INTF_SIG+")"+
DOM_ADAPTER_SIG)));
// DOMAdapter is on the stack
if (isMultiDocument()) {
final int init = cpg.addMethodref(MULTI_DOM_CLASS,
"<init>",
"("+DOM_INTF_SIG+")V");
il.append(new INVOKESPECIAL(init));
// MultiDOM is on the stack
}
//store to _dom variable
il.append(new PUTFIELD(domField));
// continue with globals initialization
final int gitr = cpg.addInterfaceMethodref(DOM_INTF,
"getIterator",
"()"+NODE_ITERATOR_SIG);
il.append(transf.loadDOM());
il.append(new INVOKEINTERFACE(gitr, 1));
il.append(transf.nextNode());
current.setStart(il.append(new ISTORE(current.getIndex())));
// Transfer the output settings to the output post-processor
il.append(classGen.loadTranslet());
il.append(transf.loadHandler());
final int index = cpg.addMethodref(TRANSLET_CLASS,
"transferOutputSettings",
"("+OUTPUT_HANDLER_SIG+")V");
il.append(new INVOKEVIRTUAL(index));
/*
* Compile buildKeys() method. Note that this method is not
* invoked here as keys for the input document are now created
* in topLevel(). However, this method is still needed by the
* LoadDocument class.
*/
final String keySig = compileBuildKeys(classGen);
final int keyIdx = cpg.addMethodref(getClassName(),
"buildKeys", keySig);
// Look for top-level elements that need handling
final Enumeration toplevel = elements();
if (_globals.size() > 0 || toplevel.hasMoreElements()) {
// Compile method for handling top-level elements
final String topLevelSig = compileTopLevel(classGen);
// Get a reference to that method
final int topLevelIdx = cpg.addMethodref(getClassName(),
"topLevel",
topLevelSig);
// Push all parameters on the stack and call topLevel()
il.append(classGen.loadTranslet()); // The 'this' pointer
il.append(classGen.loadTranslet());