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);
       /*    */ }
     /*    */ }
   /*    */ }
示例#3
0
  /**
   * 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);
  }