morten      01/06/11 05:03:50

  Modified:    java/src/org/apache/xalan/xsltc/compiler AttributeSet.java
                        Choose.java Constants.java If.java
                        LiteralElement.java Stylesheet.java
                        UseAttributeSets.java When.java XSLTC.java
                        XslAttribute.java
  Log:
  This putback contains three fixes:
   o) fix for complex <xsl:attribute-set> inheritance structures
   o) fix for xsl:element-available() function used in <xsl:when> or
      <xsl:if> to test support for various extension elements
   o) fix for preserving namespace prefixes for <xsl:attribute> output.
  Submitted by: [EMAIL PROTECTED]
  Reviewed by:  [EMAIL PROTECTED]
  
  Revision  Changes    Path
  1.4       +109 -25   
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/AttributeSet.java
  
  Index: AttributeSet.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/AttributeSet.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- AttributeSet.java 2001/06/06 10:44:38     1.3
  +++ AttributeSet.java 2001/06/11 12:03:28     1.4
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: AttributeSet.java,v 1.3 2001/06/06 10:44:38 morten Exp $
  + * @(#)$Id: AttributeSet.java,v 1.4 2001/06/11 12:03:28 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -58,6 +58,7 @@
    *
    * @author Jacek Ambroziak
    * @author Santiago Pericas-Geertsen
  + * @author Morten Jorgensen
    *
    */
   
  @@ -76,57 +77,140 @@
   import org.apache.xalan.xsltc.compiler.util.*;
   
   final class AttributeSet extends TopLevelElement {
  +
  +    // Error messages
  +    private static final String NO_NAME_ERROR =
  +     "Attribute set missing 'name' attribute.";
  +    private static final String BASTARD_ERROR =
  +     "Attribute sets can only have <xsl:attribute> child elements.";
  +
  +    // This prefix is used for the method name of attribute set methods
       private static final String AttributeSetPrefix = "%as";
       
  +    // Element contents
       private QName            _name;
       private UseAttributeSets _useSets;
  -    private String           _methodName;
  +    private String           _method;
  +    private boolean          _ignore = false;
       
  +    /**
  +     * Returns the QName of this attribute set
  +     */
  +    public QName getName() {
  +     return _name;
  +    }
  +
  +    /**
  +     * Returns the method name of this attribute set. This method name is
  +     * generated by the compiler (XSLTC)
  +     */
  +    public String getMethodName() {
  +     return _method;
  +    }
  +
  +    /**
  +     * Call this method to prevent a method for being compiled for this set.
  +     * This is used in case several <xsl:attribute-set...> elements 
constitute
  +     * a single set (with one name). The last element will merge itself with
  +     * any previous set(s) with the same name and disable the other set(s).
  +     */
  +    public void ignore() {
  +     _ignore = true;
  +    }
  +
  +    /**
  +     * Parse the contents of this attribute set. Recognised attributes are
  +     * "name" (required) and "use-attribute-sets" (optional).
  +     */
       public void parseContents(Parser parser) {
  +     
  +     // Get this attribute set's name
        _name = parser.getQName(getAttribute("name"));
  +     if ((_name == null) || (_name.equals(Constants.EMPTYSTRING))) {
  +         final ErrorMsg msg = new ErrorMsg(NO_NAME_ERROR, getLineNumber());
  +         parser.reportError(Constants.ERROR, msg);
  +     }
  +
  +     // Get any included attribute sets (similar to inheritance...)
        final String useSets = getAttribute("use-attribute-sets");
        if (useSets.length() > 0) {
            _useSets = new UseAttributeSets(useSets, parser);
        }
  -     //!!! add check whether children are XslAttributes
  -     parseChildren(parser);
  -    }
  -    
  -    public QName getName() {
  -     return _name;
  -    }
   
  -    public String getMethodName() {
  -     return _methodName;
  +     // Parse the contents of this node. All child elements must be
  +     // <xsl:attribute> elements. Other elements cause an error.
  +     final Vector contents = getContents();
  +     final int count = contents.size();
  +     for (int i=0; i<count; i++) {
  +         SyntaxTreeNode child = (SyntaxTreeNode)contents.elementAt(i);
  +         if (child instanceof XslAttribute) {
  +             parser.getSymbolTable().setCurrentNode(child);
  +             child.parseContents(parser);
  +         }
  +         else {
  +             final ErrorMsg msg =
  +                 new ErrorMsg(BASTARD_ERROR, getLineNumber());
  +             parser.reportError(Constants.ERROR, msg);
  +         }
  +     }
  +
  +     // Point the symbol table back at us...
  +     parser.getSymbolTable().setCurrentNode(this);
       }
   
  +    /**
  +     * Type check the contents of this element
  +     */
       public Type typeCheck(SymbolTable stable) throws TypeCheckError {
   
  -     final AttributeSet extant = stable.addAttributeSet(this);
  -     if (extant != null) {
  -         merge(extant);
  +     if (_ignore) return (Type.Void);
  +
  +     final AttributeSet other = stable.addAttributeSet(this);
  +     if (other != null) {
  +         _method = other.getMethodName();
  +         merge(other);
  +         other.ignore();
        }
  -     
  -     _methodName = AttributeSetPrefix + getXSLTC().nextAttributeSetSerial();
  -     
  -     if (_useSets != null) {
  -         _useSets.typeCheck(stable);
  +     else {
  +         _method = AttributeSetPrefix + getXSLTC().nextAttributeSetSerial();
        }
  +
  +     if (_useSets != null) _useSets.typeCheck(stable);
        typeCheckContents(stable);
        return Type.Void;
       }
   
  -    private void merge(AttributeSet ext) {
  -     final Enumeration attributes = ext.elements();
  +    /**
  +     * Merge this attribute set with some other one
  +     */
  +    private void merge(AttributeSet other) {
  +     // Both attribute sets may inherit from other sets...
  +     if (_useSets == null)
  +         _useSets = other._useSets;
  +     else
  +         _useSets.addAttributeSets(other.getAttribute("use-attribute-sets"));
  +
  +     // Merge the contents of the two attribute sets...
  +     final Enumeration attributes = other.elements();
        while (attributes.hasMoreElements())
            addElement((XslAttribute)attributes.nextElement());
       }
   
  +    /**
  +     * Compile a method that outputs the attributes in this set
  +     */
       public void translate(ClassGenerator classGen, MethodGenerator 
methodGen) {
  -     methodGen = new AttributeSetMethodGenerator(_methodName, classGen);
  -     if (_useSets != null) {
  -         _useSets.translate(classGen, methodGen);
  -     }
  +
  +     if (_ignore) return;
  +
  +     // Create a new method generator for an attribute set method
  +     methodGen = new AttributeSetMethodGenerator(_method, classGen);
  +
  +     // Translate other used attribute sets first, as local attributes
  +     // take precedence (last attributes overrides first)
  +     if (_useSets != null) _useSets.translate(classGen, methodGen);
  +
  +     // Translate all local attributes
        final Enumeration attributes = elements();
        while (attributes.hasMoreElements()) {
            final XslAttribute attribute =
  
  
  
  1.2       +96 -49    
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Choose.java
  
  Index: Choose.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Choose.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Choose.java       2001/04/17 18:51:22     1.1
  +++ Choose.java       2001/06/11 12:03:29     1.2
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: Choose.java,v 1.1 2001/04/17 18:51:22 sboag Exp $
  + * @(#)$Id: Choose.java,v 1.2 2001/06/11 12:03:29 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -72,6 +72,17 @@
   import org.apache.xalan.xsltc.compiler.util.*;
   
   final class Choose extends Instruction {
  +
  +    private final static String MISSING_WHEN_ERROR =
  +     "At least one When element required in Choose";
  +    private final static String ILLEGAL_ELEMENT_ERROR =
  +     "Only When|Otherwise elements allowed in Choose";
  +    private final static String MULTIPLE_OTHERWISE_ERROR =
  +     "Only one Otherwise element allowed in Choose";
  +
  +    /**
  +     * Display the element contents (a lot of when's and an otherwise)
  +     */
       public void display(int indent) {
        indent(indent);
        Util.println("Choose");
  @@ -79,66 +90,102 @@
        displayContents(indent + IndentIncrement);
       }
        
  +    /**
  +     * Translate this Choose element. Generate a test-chain for the various
  +     * <xsl:when> elements and default to the <xsl:otherwise> if present.
  +     */
       public void translate(ClassGenerator classGen, MethodGenerator 
methodGen) {
        final Vector whenElements = new Vector();
        Otherwise otherwise = null;
        Enumeration elements = elements();
  +
  +     // These two are for reporting errors only
  +     ErrorMsg error = null;
  +     final int line = getLineNumber();
  +
  +     // Traverse all child nodes - must be either When or Otherwise
        while (elements.hasMoreElements()) {
            Object element = elements.nextElement();
  -         if (element instanceof When)
  +         // Add a When child element
  +         if (element instanceof When) {
                whenElements.addElement(element);
  -         else if (element instanceof Otherwise)
  -             if (otherwise == null)
  +         }
  +         // Add an Otherwise child element
  +         else if (element instanceof Otherwise) {
  +             if (otherwise == null) {
                    otherwise = (Otherwise)element;
  -             else
  -                 System.err.println("Only one Otherwise element allowed in 
Choose");
  -         else
  -             System.err.println("Only When|Otherwise elements allowed in 
Choose");
  -     }
  -     if (whenElements.size() > 0) {
  -         InstructionList il = methodGen.getInstructionList();
  -         // next element will hold a handle to the beginning of next
  -         // When/Otherwise if test on current When fails
  -         BranchHandle nextElement = null;
  -         Vector exitHandles = new Vector();
  -         InstructionHandle exit = null;
  -         Enumeration whens = whenElements.elements();
  -         while (whens.hasMoreElements()) {
  -             final When when = (When)whens.nextElement();
  -             final Expression test = when.getTest();
  -             if (nextElement != null)
  -                 nextElement.setTarget(il.append(NOP));
  -             test.translateDesynthesized(classGen, methodGen);
  -             if ((test instanceof FunctionCall) &&
  -                 !(test instanceof ElementAvailableCall) &&
  -                 !(test instanceof ContainsCall))
  -                 test._falseList.add(il.append(new IFEQ(null)));
  -             // remember end of condition
  -             InstructionHandle truec = il.getEnd();
  -             when.translateContents(classGen, methodGen);
  -             // goto exit after executing the body of when
  -             exitHandles.addElement(il.append(new GOTO(null)));
  -             if (whens.hasMoreElements() || otherwise != null) {
  -                 nextElement = il.append(new GOTO(null));
  -                 test.backPatchFalseList(nextElement);
                }
  -             else
  -                 test.backPatchFalseList(exit = il.append(NOP));
  -             test.backPatchTrueList(truec.getNext());
  +             else {
  +                 error = new ErrorMsg(MULTIPLE_OTHERWISE_ERROR, line);
  +                 getParser().reportError(Constants.ERROR, error);
  +             }
            }
  -         if (otherwise != null) {
  -             nextElement.setTarget(il.append(NOP));
  -             otherwise.translateContents(classGen, methodGen);
  -             exit = il.append(NOP);
  +         // It is an error if we find some other element here
  +         else {
  +             error = new ErrorMsg(ILLEGAL_ELEMENT_ERROR, line);
  +             getParser().reportError(Constants.ERROR, error);
            }
  -         // now that end is known set targets of exit gotos
  -         Enumeration exitGotos = exitHandles.elements();
  -         while (exitGotos.hasMoreElements()) {
  -             BranchHandle gotoExit = (BranchHandle)exitGotos.nextElement();
  -             gotoExit.setTarget(exit);
  +     }
  +
  +     // Make sure that there is at least one <xsl:when> element
  +     if (whenElements.size() == 0) {
  +         error = new ErrorMsg(MISSING_WHEN_ERROR, getLineNumber());
  +         getParser().reportError(Constants.ERROR, error);
  +         return;
  +     }
  +
  +     InstructionList il = methodGen.getInstructionList();
  +
  +     // next element will hold a handle to the beginning of next
  +     // When/Otherwise if test on current When fails
  +     BranchHandle nextElement = null;
  +     Vector exitHandles = new Vector();
  +     InstructionHandle exit = null;
  +
  +     Enumeration whens = whenElements.elements();
  +     while (whens.hasMoreElements()) {
  +         final When when = (When)whens.nextElement();
  +         final Expression test = when.getTest();
  +
  +         InstructionHandle truec = il.getEnd();
  +
  +         if (nextElement != null)
  +             nextElement.setTarget(il.append(NOP));
  +         test.translateDesynthesized(classGen, methodGen);
  +         if ((test instanceof FunctionCall) &&
  +             !(test instanceof ElementAvailableCall) &&
  +             !(test instanceof ContainsCall))
  +             test._falseList.add(il.append(new IFEQ(null)));
  +         // remember end of condition
  +         truec = il.getEnd();
  +
  +         // The When object should be ignored completely in case it tests
  +         // for the support of a non-available element
  +         if (!when.ignore()) when.translateContents(classGen, methodGen);
  +
  +         // goto exit after executing the body of when
  +         exitHandles.addElement(il.append(new GOTO(null)));
  +         if (whens.hasMoreElements() || otherwise != null) {
  +             nextElement = il.append(new GOTO(null));
  +             test.backPatchFalseList(nextElement);
            }
  +         else
  +             test.backPatchFalseList(exit = il.append(NOP));
  +         test.backPatchTrueList(truec.getNext());
  +     }
  +     
  +     // Translate any <xsl:otherwise> element
  +     if (otherwise != null) {
  +         nextElement.setTarget(il.append(NOP));
  +         otherwise.translateContents(classGen, methodGen);
  +         exit = il.append(NOP);
  +     }
  +
  +     // now that end is known set targets of exit gotos
  +     Enumeration exitGotos = exitHandles.elements();
  +     while (exitGotos.hasMoreElements()) {
  +         BranchHandle gotoExit = (BranchHandle)exitGotos.nextElement();
  +         gotoExit.setTarget(exit);
        }
  -     else
  -         System.err.println("At least one When element required in Choose");
       }
   }
  
  
  
  1.6       +5 -2      
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Constants.java
  
  Index: Constants.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Constants.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- Constants.java    2001/06/08 12:57:52     1.5
  +++ Constants.java    2001/06/11 12:03:30     1.6
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: Constants.java,v 1.5 2001/06/08 12:57:52 morten Exp $
  + * @(#)$Id: Constants.java,v 1.6 2001/06/11 12:03:30 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -333,6 +333,9 @@
       public static final String RESET             
        = "reset";
   
  +    public static final String ATTR_SET_SIG
  +     = "(" + TRANSLET_OUTPUT_SIG + ")V";
  +
       public static final String GET_NODE_NAME_SIG   
        = "(" + NODE_SIG + ")" + STRING_SIG;
       public static final String CHARACTERSW_SIG     
  @@ -453,7 +456,7 @@
       public static final String XSLT_URI 
        = "http://www.w3.org/1999/XSL/Transform";;
       public static final String TRANSLET_URI 
  -     = "http://www.apache.org/xalan/xsltc";;
  +     = "http://xml.apache.org/xalan/xsltc";;
       public static final String FALLBACK_CLASS
        = "org.apache.xalan.xsltc.compiler.Fallback";
   }
  
  
  
  1.4       +39 -6     
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/If.java
  
  Index: If.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/If.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- If.java   2001/06/06 10:45:01     1.3
  +++ If.java   2001/06/11 12:03:32     1.4
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: If.java,v 1.3 2001/06/06 10:45:01 morten Exp $
  + * @(#)$Id: If.java,v 1.4 2001/06/11 12:03:32 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -58,6 +58,7 @@
    *
    * @author Jacek Ambroziak
    * @author Santiago Pericas-Geertsen
  + * @author Morten Jorgensen
    *
    */
   
  @@ -72,8 +73,13 @@
   import org.apache.xalan.xsltc.compiler.util.*;
   
   final class If extends Instruction {
  +
       private Expression _test;
  +    private boolean    _ignore = false;
   
  +    /**
  +     * Display the contents of this element
  +     */
       public void display(int indent) {
        indent(indent);
        Util.println("If");
  @@ -82,32 +88,59 @@
        Util.println(_test.toString());
        displayContents(indent + IndentIncrement);
       }
  -             
  +
  +    /**
  +     * Parse the "test" expression and contents of this element.
  +     */
       public void parseContents(Parser parser) {
  +     // Parse the "test" expression
        _test = parser.parseExpression(this, "test", null);
  -     parseChildren(parser);
   
  -        // make sure required attribute(s) have been set
  +        // Make sure required attribute(s) have been set
           if (_test.isDummy()) {
            reportError(this, parser, ErrorMsg.NREQATTR_ERR, "test");
            return;
           }
  +
  +     // We will ignore the contents of this <xsl:if> if we know that the
  +     // test will always return 'false'.
  +     if (_test instanceof ElementAvailableCall) {
  +         ElementAvailableCall call = (ElementAvailableCall)_test;
  +         _ignore = !call.getResult();
  +         return;
  +     }
  +
  +     parseChildren(parser);
       }
   
  +    /**
  +     * Type-check the "test" expression and contents of this element.
  +     * The contents will be ignored if we know the test will always fail.
  +     */
       public Type typeCheck(SymbolTable stable) throws TypeCheckError {
  +     // Type-check the "test" expression
        if (_test.typeCheck(stable) instanceof BooleanType == false) {
            _test = new CastExpr(_test, Type.Boolean);
        }
  -     typeCheckContents(stable);
  +     // Type check the element contents
  +     if (!_ignore) {
  +         typeCheckContents(stable);
  +     }
        return Type.Void;
       }
   
  +    /**
  +     * Translate the "test" expression and contents of this element.
  +     * The contents will be ignored if we know the test will always fail.
  +     */
       public void translate(ClassGenerator classGen, MethodGenerator 
methodGen) {
        final InstructionList il = methodGen.getInstructionList();
        _test.translateDesynthesized(classGen, methodGen);
        // remember end of condition
        final InstructionHandle truec = il.getEnd();
  -     translateContents(classGen, methodGen);
  +     if (!_ignore) {
  +         translateContents(classGen, methodGen);
  +     }
        _test.backPatchFalseList(il.append(NOP));
        _test.backPatchTrueList(truec.getNext());
       }
  
  
  
  1.7       +14 -8     
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/LiteralElement.java
  
  Index: LiteralElement.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/LiteralElement.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- LiteralElement.java       2001/06/08 15:28:13     1.6
  +++ LiteralElement.java       2001/06/11 12:03:33     1.7
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: LiteralElement.java,v 1.6 2001/06/08 15:28:13 morten Exp $
  + * @(#)$Id: LiteralElement.java,v 1.7 2001/06/11 12:03:33 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -188,9 +188,9 @@
       }
   
       /**
  -     *
  +     * Add an attribute to this element
        */
  -    private void addAttribute(SyntaxTreeNode attribute) {
  +    public void addAttribute(SyntaxTreeNode attribute) {
        if (_attributeElements == null) {
            _attributeElements = new Vector(2);
        }
  @@ -198,9 +198,9 @@
       }
   
       /**
  -     *
  +     * Set the first attribute of this element
        */
  -    public void addLocalAttribute(SyntaxTreeNode attribute) {
  +    public void setFirstAttribute(SyntaxTreeNode attribute) {
        if (_attributeElements == null) {
            _attributeElements = new Vector(2);
        }
  @@ -208,6 +208,10 @@
       }
   
   
  +    /**
  +     * Type-check the contents of this element. The element itself does not
  +     * need any type checking as it leaves nothign on the JVM's stack.
  +     */
       public Type typeCheck(SymbolTable stable) throws TypeCheckError {
        // Type-check all attributes
        if (_attributeElements != null) {
  @@ -271,11 +275,13 @@
            final QName qname = parser.getQName(_attributes.getQName(i));
            final String val = _attributes.getValue(i);
   
  -         // Handle xsl:use-attribute-sets
  +         // Handle xsl:use-attribute-sets. Attribute sets are placed first
  +         // in the vector or attributes to make sure that later local
  +         // attributes can override an attributes in the set.
            if (qname == parser.getUseAttributeSets()) {
  -             addAttribute(new UseAttributeSets(val, parser));
  +             setFirstAttribute(new UseAttributeSets(val, parser));
            }
  -         // Ignore other attributes in XSL namespace
  +         // Ignore all other attributes in XSL namespace
            else if (qname.getNamespace().equals(XSLT_URI)) {
   
            }
  
  
  
  1.8       +5 -4      
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Stylesheet.java
  
  Index: Stylesheet.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Stylesheet.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- Stylesheet.java   2001/06/07 15:16:00     1.7
  +++ Stylesheet.java   2001/06/11 12:03:34     1.8
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: Stylesheet.java,v 1.7 2001/06/07 15:16:00 morten Exp $
  + * @(#)$Id: Stylesheet.java,v 1.8 2001/06/11 12:03:34 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -418,10 +418,9 @@
            Object element = elements.nextElement();
            // xsl:template
            if (element instanceof Template) {
  -             _templates.addElement(element);
  -             
                // Separate templates by modes
                final Template template = (Template)element;
  +             _templates.addElement(template);
                getMode(template.getModeName()).addTemplate(template);
            }
            // xsl:attribute-set
  @@ -444,7 +443,9 @@
   
        compileConstructor(classGen, lastOutputElement);
   
  -     getXSLTC().dumpClass(classGen.getJavaClass());
  +     if (!getParser().errorsFound()) {
  +         getXSLTC().dumpClass(classGen.getJavaClass());
  +     }
       }
        
       private void compileConstructor(ClassGenerator classGen, Output output) {
  
  
  
  1.3       +60 -21    
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/UseAttributeSets.java
  
  Index: UseAttributeSets.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/UseAttributeSets.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- UseAttributeSets.java     2001/05/02 10:25:12     1.2
  +++ UseAttributeSets.java     2001/06/11 12:03:35     1.3
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: UseAttributeSets.java,v 1.2 2001/05/02 10:25:12 morten Exp $
  + * @(#)$Id: UseAttributeSets.java,v 1.3 2001/06/11 12:03:35 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -58,12 +58,14 @@
    *
    * @author Jacek Ambroziak
    * @author Santiago Pericas-Geertsen
  + * @author Morten Jorgensen
    *
    */
   
   package org.apache.xalan.xsltc.compiler;
   
  -import java.util.Vector;
  +import java.util.HashSet;
  +import java.util.Iterator;
   import java.util.Enumeration;
   import java.util.StringTokenizer;
   
  @@ -72,38 +74,75 @@
   import org.apache.xalan.xsltc.compiler.util.*;
   
   final class UseAttributeSets extends Instruction {
  -    private final Vector _qNames = new Vector(2); // QNames
  -    
  -    public UseAttributeSets(String useSets, Parser parser) {
  +
  +    // Only error that can occur:
  +    private final static String ATTR_SET_NOT_FOUND =
  +     "Attempting to use non-existing attribute set: ";
  +
  +    // Contains the names of all references attribute sets
  +    private final HashSet _sets = new HashSet(3);
  +
  +    /**
  +     * Constructur - define initial attribute sets to use
  +     */
  +    public UseAttributeSets(String setNames, Parser parser) {
        setParser(parser);
  -     final StringTokenizer tokens = new StringTokenizer(useSets);
  -     while (tokens.hasMoreTokens()) {
  -         _qNames.addElement(parser.getQName(tokens.nextToken()));
  +     addAttributeSets(setNames);
  +    }
  +
  +    /**
  +     * This method is made public to enable an AttributeSet object to merge
  +     * itself with another AttributeSet (including any other AttributeSets
  +     * the two may inherit from).
  +     */
  +    public void addAttributeSets(String setNames) {
  +     if ((setNames != null) && (!setNames.equals(Constants.EMPTYSTRING))) {
  +         final StringTokenizer tokens = new StringTokenizer(setNames);
  +         while (tokens.hasMoreTokens()) {
  +             final QName qname = getParser().getQName(tokens.nextToken());
  +             _sets.add(qname);
  +         }
        }
       }
  -    
  +
  +    /**
  +     * Do nada.
  +     */
       public Type typeCheck(SymbolTable stable) throws TypeCheckError {
  -     //!!! check if sets defined
        return Type.Void;
       }
  -    
  +
  +    /**
  +     * Generate a call to the method compiled for this attribute set
  +     */
       public void translate(ClassGenerator classGen, MethodGenerator 
methodGen) {
  +
        final ConstantPoolGen cpg = classGen.getConstantPool();
        final InstructionList il = methodGen.getInstructionList();
        final SymbolTable symbolTable = getParser().getSymbolTable();
  -     final Enumeration calls = _qNames.elements();
  -     while (calls.hasMoreElements()) {
  -         final QName name = (QName)calls.nextElement();
  -         final AttributeSet atts = symbolTable.lookupAttributeSet(name);
  -         if (atts != null) {
  -             final String methodName = atts.getMethodName();
  +
  +     // Get the QNames of the attribut sets we want to use
  +     final Iterator sets = _sets.iterator();
  +     // Go through each attribute set and generate a method call
  +     while (sets.hasNext()) {
  +         // Get the attribute set name
  +         final QName name = (QName)sets.next();
  +         // Get the AttributeSet reference from the symbol table
  +         final AttributeSet attrs = symbolTable.lookupAttributeSet(name);
  +         // Compile the call to the set's method if the set exists
  +         if (attrs != null) {
  +             final String methodName = attrs.getMethodName();
                il.append(classGen.loadTranslet());
                il.append(methodGen.loadHandler());
  -             final int method =
  -                 cpg.addMethodref(classGen.getClassName(),
  -                                  methodName,
  -                                  "(" + TRANSLET_OUTPUT_SIG + ")V");
  +             final int method = cpg.addMethodref(classGen.getClassName(),
  +                                                 methodName, ATTR_SET_SIG);
                il.append(new INVOKESPECIAL(method));
  +         }
  +         // Generate an error if the attribute set does not exist
  +         else {
  +             final ErrorMsg msg =  new ErrorMsg(ATTR_SET_NOT_FOUND+name,
  +                                                getLineNumber());
  +             getParser().reportError(Constants.ERROR, msg);
            }
        }
       }
  
  
  
  1.5       +35 -15    
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/When.java
  
  Index: When.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/When.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- When.java 2001/06/07 15:16:06     1.4
  +++ When.java 2001/06/11 12:03:35     1.5
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: When.java,v 1.4 2001/06/07 15:16:06 morten Exp $
  + * @(#)$Id: When.java,v 1.5 2001/06/11 12:03:35 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -58,6 +58,7 @@
    *
    * @author Jacek Ambroziak
    * @author Santiago Pericas-Geertsen
  + * @author Morten Jorgensen
    *
    */
   
  @@ -66,8 +67,13 @@
   import org.apache.xalan.xsltc.compiler.util.*;
   
   final class When extends Instruction {
  -    private Expression _test;
  +
  +    private static final String NO_CHOOSE_ERROR =
  +     "Instruction 'when' must be used within a 'choose'.";
        
  +    private Expression _test;
  +    private boolean _ignore = false;
  +
       public void display(int indent) {
        indent(indent);
        Util.println("When");
  @@ -81,37 +87,51 @@
        return _test;
       }
   
  +    public boolean ignore() {
  +     return(_ignore);
  +    }
  +
       public void parseContents(Parser parser) {
  -     boolean ignore = false;
        _test = parser.parseExpression(this, "test", null);
        if (_test instanceof ElementAvailableCall) {
            ElementAvailableCall call = (ElementAvailableCall)_test;
  -         ignore = !call.getResult();
  +         _ignore = !call.getResult();
  +         return;
        }
   
  -     if (!ignore) {
  -         parseChildren(parser);
  -     }
  +     parseChildren(parser);
   
  -     // make sure required attribute(s) have been set
  +     // Make sure required attribute(s) have been set
        if (_test.isDummy()) {
            reportError(this, parser, ErrorMsg.NREQATTR_ERR, "test");
  -         return;
        }
       }
  -     
  +
  +    /**
  +     * Type-check this when element. The test should always be type checked,
  +     * while we do not bother with the contents if we know the test fails.
  +     * This is important in cases where the "test" expression tests for
  +     * the support of a non-available element, and the <xsl:when> body 
contains
  +     * this non-available element.
  +     */
       public Type typeCheck(SymbolTable stable) throws TypeCheckError {
  +     // Type-check the test expression
        if (_test.typeCheck(stable) instanceof BooleanType == false) {
            _test = new CastExpr(_test, Type.Boolean);
        }
  -     typeCheckContents(stable);
  +     // Type-check the contents (if necessary)
  +     if (!_ignore) {
  +         typeCheckContents(stable);
  +     }
        return Type.Void;
       }
  -     
  +
  +    /**
  +     * This method should never be called. An Otherwise object will 
explicitly
  +     * translate the "test" expression and and contents of this element.
  +     */
       public void translate(ClassGenerator classGen, MethodGenerator 
methodGen) {
  -     final ErrorMsg msg =
  -         new ErrorMsg("Instruction 'when' must be used within a 'choose'.", 
  -                      getLineNumber());
  +     final ErrorMsg msg = new ErrorMsg(NO_CHOOSE_ERROR, getLineNumber());
        getParser().reportError(Constants.ERROR, msg);
       }
   }
  
  
  
  1.7       +27 -20    
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XSLTC.java
  
  Index: XSLTC.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XSLTC.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- XSLTC.java        2001/06/07 15:16:07     1.6
  +++ XSLTC.java        2001/06/11 12:03:36     1.7
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: XSLTC.java,v 1.6 2001/06/07 15:16:07 morten Exp $
  + * @(#)$Id: XSLTC.java,v 1.7 2001/06/11 12:03:36 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -197,33 +197,40 @@
            
            // Get the root node of the abstract syntax tree
            final SyntaxTreeNode element = _parser.parse(url);
  -         // Process any error and/or warning messages
  +
  +         // Process any error and/or warning messages found so far...
            _parser.printWarnings();
  -         if (_parser.errorsFound()) {
  +         if ((_parser.errorsFound()) || (element == null)) {
                _parser.printErrors();
                return false;
            }
   
  -         if ((!_parser.errorsFound()) && (element != null)) {
  -             _stylesheet = _parser.makeStylesheet(element);
  -             _stylesheet.setURL(url);
  -             // This is the top level stylesheet - it has no parent
  -             _stylesheet.setParentStylesheet(null);
  -             _parser.setCurrentStylesheet(_stylesheet);
  -             _parser.createAST(_stylesheet);
  -             if (_stylesheet != null && _parser.errorsFound() == false) {
  -                 _stylesheet.setMultiDocument(_multiDocument);
  -                 _stylesheet.translate();
  -             }
  -             else {
  -                 _parser.printErrors();
  -             }               
  -         }
  -         else {
  +         // Create the abstract syntax tree and parse each node in it
  +         _stylesheet = _parser.makeStylesheet(element);
  +         _stylesheet.setURL(url);
  +         _stylesheet.setParentStylesheet(null);
  +         _parser.setCurrentStylesheet(_stylesheet);
  +         _parser.createAST(_stylesheet);
  +
  +         // Process any error and/or warning messages found so far...
  +         _parser.printWarnings();
  +         if ((_parser.errorsFound()) || (_stylesheet == null)) {
                _parser.printErrors();
  +             return false;
            }
  +
  +         // Compile the translet
  +         _stylesheet.setMultiDocument(_multiDocument);
  +         _stylesheet.translate();
  +
  +         // Process any error and/or warning messages found so far...
            _parser.printWarnings();
  -         return !_parser.errorsFound();
  +         if ((_parser.errorsFound()) || (_stylesheet == null)) {
  +             _parser.printErrors();
  +             return false;
  +         }
  +
  +         return true;
        }
        catch (CompilerException e) {
            e.printStackTrace();
  
  
  
  1.6       +3 -3      
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XslAttribute.java
  
  Index: XslAttribute.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XslAttribute.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- XslAttribute.java 2001/06/08 15:28:14     1.5
  +++ XslAttribute.java 2001/06/11 12:03:38     1.6
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: XslAttribute.java,v 1.5 2001/06/08 15:28:14 morten Exp $
  + * @(#)$Id: XslAttribute.java,v 1.6 2001/06/11 12:03:38 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -126,7 +126,7 @@
        // Get namespace from namespace attribute?
        if ((namespace != null) && (namespace != Constants.EMPTYSTRING)) {
            // Prefix could be in symbol table
  -         //_prefix = stable.lookupPrefix(namespace);
  +         _prefix = lookupPrefix(namespace);
            _namespace = new AttributeValueTemplate(namespace, parser);
        }
        // Get namespace from prefix in name attribute?
  @@ -169,7 +169,7 @@
        }
   
        if (parent instanceof LiteralElement) {
  -         ((LiteralElement)parent).addLocalAttribute(this);
  +         ((LiteralElement)parent).addAttribute(this);
        }
   
        _name = AttributeValue.create(this, name, parser);
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to