Example #1
0
  /**
   * This method returns a vector with variables/params and keys in the order in which they are to
   * be compiled for initialization. The order is determined by analyzing the dependencies between
   * them. The XSLT 1.0 spec does not allow a key to depend on a variable. However, for
   * compatibility with Xalan interpretive, that type of dependency is allowed and, therefore,
   * consider to determine the partial order.
   */
  private Vector resolveDependencies(Vector input) {
    /* DEBUG CODE - INGORE
    for (int i = 0; i < input.size(); i++) {
        final TopLevelElement e = (TopLevelElement) input.elementAt(i);
        System.out.println("e = " + e + " depends on:");
        Vector dep = e.getDependencies();
        for (int j = 0; j < (dep != null ? dep.size() : 0); j++) {
            System.out.println("\t" + dep.elementAt(j));
        }
    }
    System.out.println("=================================");
    */

    Vector result = new Vector();
    while (input.size() > 0) {
      boolean changed = false;
      for (int i = 0; i < input.size(); ) {
        final TopLevelElement vde = (TopLevelElement) input.elementAt(i);
        final Vector dep = vde.getDependencies();
        if (dep == null || result.containsAll(dep)) {
          result.addElement(vde);
          input.remove(i);
          changed = true;
        } else {
          i++;
        }
      }

      // If nothing was changed in this pass then we have a circular ref
      if (!changed) {
        ErrorMsg err = new ErrorMsg(ErrorMsg.CIRCULAR_VARIABLE_ERR, input.toString(), this);
        getParser().reportError(Constants.ERROR, err);
        return (result);
      }
    }

    /* DEBUG CODE - INGORE
    System.out.println("=================================");
    for (int i = 0; i < result.size(); i++) {
        final TopLevelElement e = (TopLevelElement) result.elementAt(i);
        System.out.println("e = " + e);
    }
    */

    return result;
  }
Example #2
0
 /*  27:    */
 /*  28:    */ public void addParentDependency() /*  29:    */ {
   /*  30: 73 */ SyntaxTreeNode node = this;
   /*  31: 74 */ while ((node != null) && (!(node instanceof TopLevelElement))) {
     /*  32: 75 */ node = node.getParent();
     /*  33:    */ }
   /*  34: 78 */ TopLevelElement parent = (TopLevelElement) node;
   /*  35: 79 */ if (parent != null)
   /*  36:    */ {
     /*  37: 80 */ VariableBase var = this._variable;
     /*  38: 81 */ if (this._variable._ignore) {
       /*  39: 82 */ if ((this._variable instanceof Variable)) {
         /*  40: 83 */ var = parent.getSymbolTable().lookupVariable(this._variable._name);
         /*  41: 85 */ } else if ((this._variable instanceof Param)) {
         /*  42: 86 */ var = parent.getSymbolTable().lookupParam(this._variable._name);
         /*  43:    */ }
       /*  44:    */ }
     /*  45: 90 */ parent.addDependency(var);
     /*  46:    */ }
   /*  47:    */ }
Example #3
0
  /**
   * Compile a topLevel() method into the output class. This method is called from transform() to
   * handle all non-template top-level elements. Returns the signature of the topLevel() method.
   *
   * <p>Global variables/params and keys are first sorted to resolve dependencies between them. The
   * XSLT 1.0 spec does not allow a key to depend on a variable. However, for compatibility with
   * Xalan interpretive, that type of dependency is allowed. Note also that the buildKeys() method
   * is still generated as it is used by the LoadDocument class, but it no longer called from
   * transform().
   */
  private String compileTopLevel(ClassGenerator classGen) {

    final ConstantPoolGen cpg = classGen.getConstantPool();

    final com.sun.org.apache.bcel.internal.generic.Type[] argTypes = {
      Util.getJCRefType(DOM_INTF_SIG),
      Util.getJCRefType(NODE_ITERATOR_SIG),
      Util.getJCRefType(TRANSLET_OUTPUT_SIG)
    };

    final String[] argNames = {DOCUMENT_PNAME, ITERATOR_PNAME, TRANSLET_OUTPUT_PNAME};

    final InstructionList il = new InstructionList();

    final MethodGenerator toplevel =
        new MethodGenerator(
            ACC_PUBLIC,
            com.sun.org.apache.bcel.internal.generic.Type.VOID,
            argTypes,
            argNames,
            "topLevel",
            _className,
            il,
            classGen.getConstantPool());

    toplevel.addException("com.sun.org.apache.xalan.internal.xsltc.TransletException");

    // Define and initialize 'current' variable with the root node
    final LocalVariableGen current =
        toplevel.addLocalVariable(
            "current", com.sun.org.apache.bcel.internal.generic.Type.INT, null, null);

    final int setFilter =
        cpg.addInterfaceMethodref(
            DOM_INTF, "setFilter", "(Lcom/sun/org/apache/xalan/internal/xsltc/StripFilter;)V");

    final int gitr = cpg.addInterfaceMethodref(DOM_INTF, "getIterator", "()" + NODE_ITERATOR_SIG);
    il.append(toplevel.loadDOM());
    il.append(new INVOKEINTERFACE(gitr, 1));
    il.append(toplevel.nextNode());
    current.setStart(il.append(new ISTORE(current.getIndex())));

    // Create a new list containing variables/params + keys
    Vector varDepElements = new Vector(_globals);
    Enumeration elements = elements();
    while (elements.hasMoreElements()) {
      final Object element = elements.nextElement();
      if (element instanceof Key) {
        varDepElements.add(element);
      }
    }

    // Determine a partial order for the variables/params and keys
    varDepElements = resolveDependencies(varDepElements);

    // Translate vars/params and keys in the right order
    final int count = varDepElements.size();
    for (int i = 0; i < count; i++) {
      final TopLevelElement tle = (TopLevelElement) varDepElements.elementAt(i);
      tle.translate(classGen, toplevel);
      if (tle instanceof Key) {
        final Key key = (Key) tle;
        _keys.put(key.getName(), key);
      }
    }

    // Compile code for other top-level elements
    Vector whitespaceRules = new Vector();
    elements = elements();
    while (elements.hasMoreElements()) {
      final Object element = elements.nextElement();
      // xsl:decimal-format
      if (element instanceof DecimalFormatting) {
        ((DecimalFormatting) element).translate(classGen, toplevel);
      }
      // xsl:strip/preserve-space
      else if (element instanceof Whitespace) {
        whitespaceRules.addAll(((Whitespace) element).getRules());
      }
    }

    // Translate all whitespace strip/preserve rules
    if (whitespaceRules.size() > 0) {
      Whitespace.translateRules(whitespaceRules, classGen);
    }

    if (classGen.containsMethod(STRIP_SPACE, STRIP_SPACE_PARAMS) != null) {
      il.append(toplevel.loadDOM());
      il.append(classGen.loadTranslet());
      il.append(new INVOKEINTERFACE(setFilter, 2));
    }

    il.append(RETURN);

    // Compute max locals + stack and add method to class
    classGen.addMethod(toplevel);

    return ("(" + DOM_INTF_SIG + NODE_ITERATOR_SIG + TRANSLET_OUTPUT_SIG + ")V");
  }