public void translate(ClassGenerator classGen, MethodGenerator methodGen) { final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = methodGen.getInstructionList(); if (!_isLiteral) { // if the ncname is an AVT, then the ncname has to be checked at runtime if it is a valid // ncname LocalVariableGen nameValue = methodGen.addLocalVariable2("nameValue", Util.getJCRefType(STRING_SIG), null); // store the name into a variable first so _name.translate only needs to be called once _name.translate(classGen, methodGen); nameValue.setStart(il.append(new ASTORE(nameValue.getIndex()))); il.append(new ALOAD(nameValue.getIndex())); // call checkNCName if the name is an AVT final int check = cpg.addMethodref(BASIS_LIBRARY_CLASS, "checkNCName", "(" + STRING_SIG + ")V"); il.append(new INVOKESTATIC(check)); // Save the current handler base on the stack il.append(methodGen.loadHandler()); il.append(DUP); // first arg to "attributes" call // load name value again nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex()))); } else { // Save the current handler base on the stack il.append(methodGen.loadHandler()); il.append(DUP); // first arg to "attributes" call // Push attribute name _name.translate(classGen, methodGen); // 2nd arg } il.append(classGen.loadTranslet()); il.append( new GETFIELD( cpg.addFieldref(TRANSLET_CLASS, "stringValueHandler", STRING_VALUE_HANDLER_SIG))); il.append(DUP); il.append(methodGen.storeHandler()); // translate contents with substituted handler translateContents(classGen, methodGen); // get String out of the handler il.append( new INVOKEVIRTUAL( cpg.addMethodref(STRING_VALUE_HANDLER, "getValueOfPI", "()" + STRING_SIG))); // call "processingInstruction" final int processingInstruction = cpg.addInterfaceMethodref( TRANSLET_OUTPUT_INTERFACE, "processingInstruction", "(" + STRING_SIG + STRING_SIG + ")V"); il.append(new INVOKEINTERFACE(processingInstruction, 3)); // Restore old handler base from stack il.append(methodGen.storeHandler()); }
/* */ public void translate(ClassGenerator classGen, MethodGenerator methodGen) /* */ { /* 88 */ ConstantPoolGen cpg = classGen.getConstantPool(); /* 89 */ InstructionList il = methodGen.getInstructionList(); /* 90 */ SymbolTable symbolTable = getParser().getSymbolTable(); /* */ /* 93 */ for (int i = 0; i < this._sets.size(); i++) /* */ { /* 95 */ QName name = (QName) this._sets.elementAt(i); /* */ /* 97 */ AttributeSet attrs = symbolTable.lookupAttributeSet(name); /* */ /* 99 */ if (attrs != null) { /* 100 */ String methodName = attrs.getMethodName(); /* 101 */ il.append(classGen.loadTranslet()); /* 102 */ il.append(methodGen.loadDOM()); /* 103 */ il.append(methodGen.loadIterator()); /* 104 */ il.append(methodGen.loadHandler()); /* 105 */ il.append(methodGen.loadCurrentNode()); /* 106 */ int method = cpg.addMethodref( classGen.getClassName(), methodName, "(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;I)V"); /* */ /* 108 */ il.append(new INVOKESPECIAL(method)); /* */ } /* */ else /* */ { /* 112 */ Parser parser = getParser(); /* 113 */ String atrs = name.toString(); /* 114 */ reportError(this, parser, "ATTRIBSET_UNDEF_ERR", atrs); /* */ } /* */ } /* */ }
/** * 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 com.sun.org.apache.bcel.internal.generic.Type[] argTypes = new com.sun.org.apache.bcel.internal.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, com.sun.org.apache.bcel.internal.generic.Type.VOID, argTypes, argNames, "transform", _className, il, classGen.getConstantPool()); transf.addException("com.sun.org.apache.xalan.internal.xsltc.TransletException"); // Define and initialize current with the root node final LocalVariableGen current = transf.addLocalVariable( "current", com.sun.org.apache.bcel.internal.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()); il.append(new GETFIELD(domField)); // The DOM reference il.append(transf.loadIterator()); il.append(transf.loadHandler()); // The output handler il.append(new INVOKEVIRTUAL(topLevelIdx)); } // start document il.append(transf.loadHandler()); il.append(transf.startDocument()); // push first arg for applyTemplates il.append(classGen.loadTranslet()); // push translet for GETFIELD to get DOM arg il.append(classGen.loadTranslet()); il.append(new GETFIELD(domField)); // push remaining 2 args il.append(transf.loadIterator()); il.append(transf.loadHandler()); il.append(new INVOKEVIRTUAL(applyTemplates)); // endDocument il.append(transf.loadHandler()); il.append(transf.endDocument()); il.append(RETURN); // Compute max locals + stack and add method to class classGen.addMethod(transf); }