* @param methodGen BCEL Java method generator
*/
protected void compileResultTree(ClassGenerator classGen,
MethodGenerator methodGen)
{
final ConstantPoolGen cpg = classGen.getConstantPool();
final InstructionList il = methodGen.getInstructionList();
final Stylesheet stylesheet = classGen.getStylesheet();
boolean isSimple = isSimpleRTF(this);
boolean isAdaptive = false;
if (!isSimple) {
isAdaptive = isAdaptiveRTF(this);
}
int rtfType = isSimple ? DOM.SIMPLE_RTF
: (isAdaptive ? DOM.ADAPTIVE_RTF : DOM.TREE_RTF);
// Save the current handler base on the stack
il.append(methodGen.loadHandler());
final String DOM_CLASS = classGen.getDOMClass();
// Create new instance of DOM class (with RTF_INITIAL_SIZE nodes)
//int index = cpg.addMethodref(DOM_IMPL, "<init>", "(I)V");
//il.append(new NEW(cpg.addClass(DOM_IMPL)));
il.append(methodGen.loadDOM());
int index = cpg.addInterfaceMethodref(DOM_INTF,
"getResultTreeFrag",
"(IIZ)" + DOM_INTF_SIG);
il.append(new PUSH(cpg, RTF_INITIAL_SIZE));
il.append(new PUSH(cpg, rtfType));
il.append(new PUSH(cpg, stylesheet.callsNodeset()));
il.append(new INVOKEINTERFACE(index,4));
il.append(DUP);
// Overwrite old handler with DOM handler
index = cpg.addInterfaceMethodref(DOM_INTF,
"getOutputDomBuilder",
"()" + TRANSLET_OUTPUT_SIG);
il.append(new INVOKEINTERFACE(index,1));
il.append(DUP);
il.append(methodGen.storeHandler());
// Call startDocument on the new handler
il.append(methodGen.startDocument());
// Instantiate result tree fragment
translateContents(classGen, methodGen);
// Call endDocument on the new handler
il.append(methodGen.loadHandler());
il.append(methodGen.endDocument());
// Check if we need to wrap the DOMImpl object in a DOMAdapter object.
// DOMAdapter is not needed if the RTF is a simple RTF and the nodeset()
// function is not used.
if (stylesheet.callsNodeset()
&& !DOM_CLASS.equals(DOM_IMPL_CLASS)) {
// new com.sun.org.apache.xalan.internal.xsltc.dom.DOMAdapter(DOMImpl,String[]);
index = cpg.addMethodref(DOM_ADAPTER_CLASS,
"<init>",
"("+DOM_INTF_SIG+
"["+STRING_SIG+
"["+STRING_SIG+
"[I"+
"["+STRING_SIG+")V");
il.append(new NEW(cpg.addClass(DOM_ADAPTER_CLASS)));
il.append(new DUP_X1());
il.append(SWAP);
/*
* Give the DOM adapter an empty type mapping if the nodeset
* extension function is never called.
*/
if (!stylesheet.callsNodeset()) {
il.append(new ICONST(0));
il.append(new ANEWARRAY(cpg.addClass(STRING)));
il.append(DUP);
il.append(DUP);
il.append(new ICONST(0));
il.append(new NEWARRAY(BasicType.INT));
il.append(SWAP);
il.append(new INVOKESPECIAL(index));
}
else {
// Push name arrays on the stack
il.append(ALOAD_0);
il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS,
NAMES_INDEX,
NAMES_INDEX_SIG)));
il.append(ALOAD_0);
il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS,
URIS_INDEX,
URIS_INDEX_SIG)));
il.append(ALOAD_0);
il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS,
TYPES_INDEX,
TYPES_INDEX_SIG)));
il.append(ALOAD_0);
il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS,
NAMESPACE_INDEX,
NAMESPACE_INDEX_SIG)));
// Initialized DOM adapter
il.append(new INVOKESPECIAL(index));
// Add DOM adapter to MultiDOM class by calling addDOMAdapter()
il.append(DUP);
il.append(methodGen.loadDOM());
il.append(new CHECKCAST(cpg.addClass(classGen.getDOMClass())));
il.append(SWAP);
index = cpg.addMethodref(MULTI_DOM_CLASS,
"addDOMAdapter",
"(" + DOM_ADAPTER_SIG + ")I");
il.append(new INVOKEVIRTUAL(index));
il.append(POP); // ignore mask returned by addDOMAdapter
}