sboag       01/03/11 13:44:02

  Modified:    java/src/org/apache/xalan/templates ElemAttribute.java
                        ElemElement.java
  Log:
  Checkin addresses http://nagoya.apache.org/bugzilla/show_bug.cgi?id=923.
  elemAttribute now derives from elemElement so the basic name resolution
  code can be shared.  Breaks attribset24 test, but I think the newer
  behavior is better.  New virtual methods overloaded by elemAttribute are
  constructNode, resolvePrefix, and validateNodeName.  Also, in the
  elemAttribute#execute method, checks are made to make sure an
  element is pending.
  
  Revision  Changes    Path
  1.14      +93 -158   
xml-xalan/java/src/org/apache/xalan/templates/ElemAttribute.java
  
  Index: ElemAttribute.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemAttribute.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- ElemAttribute.java        2001/01/26 01:26:58     1.13
  +++ ElemAttribute.java        2001/03/11 21:44:02     1.14
  @@ -68,6 +68,8 @@
   import org.apache.xalan.transformer.ResultTreeHandler;
   import org.apache.xpath.XPathContext;
   
  +import org.xml.sax.SAXException;
  +
   /**
    * <meta name="usage" content="advanced"/>
    * Implement xsl:attribute.
  @@ -81,62 +83,10 @@
    * </pre>
    * @see <a 
href="http://www.w3.org/TR/xslt#creating-attributes";>creating-attributes in 
XSLT Specification</a>
    */
  -public class ElemAttribute extends ElemTemplateElement
  +public class ElemAttribute extends ElemElement
   {
   
     /**
  -   * The local name which should be used.
  -   * @serial
  -   */
  -  public AVT m_name_avt = null;
  -
  -  /**
  -   * The namespace which should be used.
  -   * @serial
  -   */
  -  public AVT m_namespace_avt = null;
  -
  -  /**
  -   * Set the "name" attribute.
  -   *
  -   * @param name name attribute to set 
  -   */
  -  public void setName(AVT name)
  -  {
  -    m_name_avt = name;
  -  }
  -
  -  /**
  -   * Get the "name" attribute.
  -   *
  -   * @return the "name" attribute.
  -   */
  -  public AVT getName()
  -  {
  -    return m_name_avt;
  -  }
  -
  -  /**
  -   * Set the "namespace" attribute.
  -   *
  -   * @param name Namspace attribute to set
  -   */
  -  public void setNamespace(AVT name)
  -  {
  -    m_namespace_avt = name;
  -  }
  -
  -  /**
  -   * Get the "namespace" attribute.
  -   *
  -   * @return the "namespace" attribute.
  -   */
  -  public AVT getNamespace()
  -  {
  -    return m_namespace_avt;
  -  }
  -
  -  /**
      * Get an int constant identifying the type of element.
      * @see org.apache.xalan.templates.Constants
      *
  @@ -171,135 +121,120 @@
             TransformerImpl transformer, Node sourceNode, QName mode)
               throws TransformerException
     {
  -    try
  +    ResultTreeHandler rhandler = transformer.getResultTreeHandler();
  +
  +    // If they are trying to add an attribute when there isn't an 
  +    // element pending, it is an error.
  +    if (!rhandler.isElementPending())
       {
  +      // Make sure the trace event is sent.
         if (TransformerImpl.S_DEBUG)
           transformer.getTraceManager().fireTraceEvent(sourceNode, mode, this);
   
  -      ResultTreeHandler rhandler = transformer.getResultTreeHandler();
         XPathContext xctxt = transformer.getXPathContext();
  -
  -      // The attribute name has to be evaluated as an AVT.
         String attrName = m_name_avt.evaluate(xctxt, sourceNode, this);
  -      String origAttrName = attrName;  // save original attribute name
  -
  -      // Get the children of the xsl:attribute element as the string value.
  -      String val = transformer.transformToString(this, sourceNode, mode);
  +      transformer.getMsgMgr().warn(this,
  +                                   XSLTErrorResources.WG_ILLEGAL_ATTRIBUTE,
  +                                   new Object[]{ attrName });
   
  -      // If they are trying to add an attribute when there isn't an 
  -      // element pending, it is an error.
  -      if (!rhandler.isElementPending())
  -      {
  -        transformer.getMsgMgr().warn(this,
  -                                     
XSLTErrorResources.WG_ILLEGAL_ATTRIBUTE_NAME,
  -                                     new Object[]{ origAttrName });
  -
  -        return;
  +      return;
   
  -        // warn(templateChild, sourceNode, "Trying to add attribute after 
element child has been added, ignoring...");
  -      }
  -
  -      if (null == attrName)
  -        return;
  +      // warn(templateChild, sourceNode, "Trying to add attribute after 
element child has been added, ignoring...");
  +    }
  +    
  +    super.execute(transformer, sourceNode, mode);
  +    
  +  }
  +  
  +  /**
  +   * Resolve the namespace into a prefix.  At this level, if no prefix 
exists, 
  +   * then return a manufactured prefix.
  +   *
  +   * @param rhandler The current result tree handler.
  +   * @param prefix The probable prefix if already known.
  +   * @param nodeNamespace  The namespace, which should not be null.
  +   *
  +   * @return The prefix to be used.
  +   */
  +  protected String resolvePrefix(ResultTreeHandler rhandler,
  +                                 String prefix, String nodeNamespace)
  +    throws TransformerException
  +  {
   
  -      String attrNameSpace = "";  // by default
  +    if (null != prefix && (prefix.length() == 0 || prefix.equals("xmlns")))
  +    {
  +      // Since we can't use default namespace, in this case we try and 
  +      // see if a prefix has already been defined or this namespace.
  +      prefix = rhandler.getPrefix(nodeNamespace);
   
  -      // Did they declare a namespace attribute?
  -      if (null != m_namespace_avt)
  +      // System.out.println("nsPrefix: "+nsPrefix);           
  +      if (null == prefix || prefix.length() == 0 || prefix.equals("xmlns"))
         {
  -
  -        // The namespace attribute is an AVT also.
  -        attrNameSpace = m_namespace_avt.evaluate(xctxt, sourceNode, this);
  -
  -        if (null != attrNameSpace && attrNameSpace.length() > 0)
  +        if(nodeNamespace.length() > 0)
           {
  -
  -          // Get the prefix for that attribute in the result namespace.
  -          String prefix = rhandler.getPrefix(attrNameSpace);
  -
  -          // If we didn't find the prefix mapping, make up a prefix 
  -          // and have it declared in the result tree.
  -          if (null == prefix)
  -          {
  -            prefix = rhandler.getNewUniqueNSPrefix();
  -
  -            rhandler.startPrefixMapping(prefix, attrNameSpace, false);
  -          }
  -
  -          // add the prefix to the attribute name.
  -          attrName = (prefix + ":" + QName.getLocalPart(attrName));
  +          prefix = rhandler.getNewUniqueNSPrefix();
           }
  +        else
  +          prefix = "";
         }
  -
  -      // Is the attribute xmlns type?
  -      else if (QName.isXMLNSDecl(origAttrName))
  -      {
  -
  -        // Then just declare the namespace prefix and get out.
  -        String prefix = QName.getPrefixFromXMLNSDecl(origAttrName);
  -        String ns = rhandler.getURI(prefix);
  -
  -        if (null == ns)
  -          rhandler.startPrefixMapping(prefix, val, false);
  -
  -        return;
  -      }
  +    }
  +    return prefix;
  +  }
  +  
  +  /**
  +   * Validate that the node name is good.
  +   * 
  +   * @param nodeName Name of the node being constructed, which may be null.
  +   * 
  +   * @return true if the node name is valid, false otherwise.
  +   */
  +   protected boolean validateNodeName(String nodeName)
  +   {
  +      if(null == nodeName)
  +        return false;
  +      if(nodeName.equals("xmlns"))
  +        return false;
  +      return super.validateNodeName(nodeName);
  +   }
  +  
  +  /**
  +   * Construct a node in the result tree.  This method is overloaded by 
  +   * xsl:attribute. At this class level, this method creates an element.
  +   *
  +   * @param nodeName The name of the node, which may be null.
  +   * @param prefix The prefix for the namespace, which may be null.
  +   * @param nodeNamespace The namespace of the node, which may be null.
  +   * @param transformer non-null reference to the the current transform-time 
state.
  +   * @param sourceNode non-null reference to the <a 
href="http://www.w3.org/TR/xslt#dt-current-node";>current source node</a>.
  +   * @param mode reference, which may be null, to the <a 
href="http://www.w3.org/TR/xslt#modes";>current mode</a>.
  +   *
  +   * @throws TransformerException
  +   */
  +  void constructNode(
  +          String nodeName, String prefix, String nodeNamespace, 
TransformerImpl transformer, Node sourceNode, QName mode)
  +            throws TransformerException
  +  {
   
  -      // Note we are using original attribute name for these tests. 
  -      else
  +    if(null != nodeName && nodeName.length() > 0)
  +    {
  +      ResultTreeHandler rhandler = transformer.getResultTreeHandler();
  +      if(prefix != null && prefix.length() > 0)
         {
  -
  -        // Does the attribute name have a prefix?
  -        String nsprefix = QName.getPrefixPart(origAttrName);
  -
  -        if (null == nsprefix)
  -          nsprefix = "";
  -
  -        // We're going to claim that this must be resolved in 
  -        // the result tree namespace.
           try
           {
  -          attrNameSpace = getNamespaceForPrefix(nsprefix);
  -          // System.out.println("attrNameSpace: "+attrNameSpace);
  -
  -          if ((null == attrNameSpace) && (nsprefix.length() > 0))
  -          {
  -            transformer.getMsgMgr().warn(this,
  -                                         
XSLTErrorResources.WG_COULD_NOT_RESOLVE_PREFIX,
  -                                         new Object[]{ nsprefix });
  -
  -            return;
  -          }
  -          else if(null == attrNameSpace)
  -            attrNameSpace = "";
  +          rhandler.startPrefixMapping(prefix, nodeNamespace, false);
           }
  -        catch (Exception ex)
  +        catch(SAXException se)
           {
  -
  -          // Could not resolve prefix
  -
  -          transformer.getMsgMgr().warn(this,
  -                                       
XSLTErrorResources.WG_COULD_NOT_RESOLVE_PREFIX,
  -                                       new Object[]{ nsprefix });
  -
  -          return;
  +          throw new TransformerException(se);
           }
         }
  -
  -      String localName = QName.getLocalPart(attrName);
  -//      System.out.println("rhandler.addAttribute("+attrNameSpace+", "
  -//                                                 +localName+", "
  -//                                                 +attrName+", "
  -//                                                 +"CDATA"+", "
  -//                                                 +val+");");
  -      rhandler.addAttribute(attrNameSpace, localName, attrName, "CDATA", 
val);
  -    }
  -    catch(org.xml.sax.SAXException se)
  -    {
  -      throw new TransformerException(se);
  +      String val = transformer.transformToString(this, sourceNode, mode);
  +      String localName = QName.getLocalPart(nodeName);
  +      rhandler.addAttribute(nodeNamespace, localName, nodeName, "CDATA", 
val);
       }
  -    
     }
  +
   
     /**
      * Add a child to the child list.
  
  
  
  1.18      +187 -113  
xml-xalan/java/src/org/apache/xalan/templates/ElemElement.java
  
  Index: ElemElement.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemElement.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- ElemElement.java  2001/03/06 05:50:22     1.17
  +++ ElemElement.java  2001/03/11 21:44:02     1.18
  @@ -91,7 +91,7 @@
      * attribute value template is not a QName.
      * @serial
      */
  -  private AVT m_name_avt = null;
  +  protected AVT m_name_avt = null;
   
     /**
      * Set the "name" attribute.
  @@ -126,7 +126,7 @@
      * It is not an error if the string is not a syntactically legal URI 
reference.
      * @serial
      */
  -  private AVT m_namespace_avt = null;
  +  protected AVT m_namespace_avt = null;
   
     /**
      * Set the "namespace" attribute.
  @@ -157,12 +157,6 @@
     }
   
     /**
  -   * Cached prefix value... the use of which is dubious.
  -   * @serial
  -   */
  -  private String m_prefix;
  -
  -  /**
      * Get an int constant identifying the type of element.
      * @see org.apache.xalan.templates.Constants
      *
  @@ -184,6 +178,70 @@
     }
     
     /**
  +   * Validate that the node name is good.
  +   * 
  +   * @param nodeName Name of the node being constructed, which may be null.
  +   * 
  +   * @return true if the node name is valid, false otherwise.
  +   */
  +   protected boolean validateNodeName(String nodeName)
  +   {
  +    if(nodeName == null)
  +      return false;
  +      
  +    int indexOfNSSep = nodeName.indexOf(':');
  +    int len = nodeName.length();
  +    
  +    if(len == 0)
  +      return false;
  +      
  +    if(indexOfNSSep + 1 == len)
  +      return false;
  +      
  +    if(indexOfNSSep == 0)
  +      return false;
  +      
  +    String localName = QName.getLocalPart(nodeName);
  +      
  +    if(isValidNCName(localName))
  +    {
  +      String prefix = QName.getPrefixPart(nodeName);
  +      if(prefix.length() == 0)
  +        return true;
  +      if(isValidNCName(prefix))
  +        return true;
  +    }
  +
  +    return false;
  +   }
  +   
  +  /**
  +   * Resolve the namespace into a prefix.  Meant to be
  +   * overidded by elemAttribute if this class is derived.
  +   *
  +   * @param rhandler The current result tree handler.
  +   * @param prefix The probable prefix if already known.
  +   * @param nodeNamespace  The namespace.
  +   *
  +   * @return The prefix to be used.
  +   */
  +  protected String resolvePrefix(ResultTreeHandler rhandler,
  +                                 String prefix, String nodeNamespace)
  +    throws TransformerException
  +  {
  +
  +//    if (null != prefix && prefix.length() == 0)
  +//    {
  +//      String foundPrefix = rhandler.getPrefix(nodeNamespace);
  +//
  +//      // System.out.println("nsPrefix: "+nsPrefix);           
  +//      if (null == foundPrefix)
  +//        foundPrefix = "";
  +//    }
  +    return prefix;
  +  }
  +    
  +  /**
      * Create an element in the result tree.
      * The xsl:element element allows an element to be created with a
      * computed name. The expanded-name of the element to be created
  @@ -201,140 +259,156 @@
             TransformerImpl transformer, Node sourceNode, QName mode)
               throws TransformerException
     {
  -    try
  -    {
   
  -      boolean shouldAddAttrs = true;
  -      ResultTreeHandler rhandler = transformer.getResultTreeHandler();
  -      XPathContext xctxt = transformer.getXPathContext();
  -      String elemName = m_name_avt.evaluate(xctxt, sourceNode, this);
  +    ResultTreeHandler rhandler = transformer.getResultTreeHandler();
  +    XPathContext xctxt = transformer.getXPathContext();
  +    String nodeName = m_name_avt.evaluate(xctxt, sourceNode, this);
  +
  +    // make sure that if a prefix is specified on the attribute name, it is 
valid
  +    int indexOfNSSep = nodeName.indexOf(':');
  +    String prefix = null;
  +    String nodeNamespace = null;
  +
  +    if (nodeName.length() == 0)
  +      nodeName = null;
   
  -      // make sure that if a prefix is specified on the attribute name, it 
is valid
  -      int indexOfNSSep = elemName.indexOf(':');
  -      String prefix = null;
  -      String elemNameSpace = null;
  -      if(elemName.length() == 0)
  -        elemName = null;
  +    if ((null != nodeName) /* && (indexOfNSSep >= 0) */)
  +    {
  +      prefix = (indexOfNSSep > 0) ? nodeName.substring(0, indexOfNSSep) : "";
   
  -      if ((null != elemName) /* && (indexOfNSSep >= 0) */)
  +      // Catch the exception this may cause. We don't want to stop 
processing.
  +      try
         {
  -        prefix = (indexOfNSSep > 0) ? elemName.substring(0, indexOfNSSep) : 
"";
  +        nodeNamespace = getNamespaceForPrefix(prefix);
   
  -        // Catch the exception this may cause. We don't want to stop 
processing.
  -        try
  -        {
  -          elemNameSpace = getNamespaceForPrefix(prefix);
  -          if(null == elemNameSpace && indexOfNSSep <= 0)
  -            elemNameSpace = "";
  -
  -          // Check if valid QName. Assuming that if the prefix is defined,
  -          // it is valid.
  -          int len = elemNameSpace.length();
  -          if ((len > 0 && ((indexOfNSSep + 1 == len)
  -              ||!isValidNCName(elemName.substring(indexOfNSSep + 1)))) ||
  -              ((indexOfNSSep <= 0) && !isValidNCName(elemName)))
  -          {
  -            transformer.getMsgMgr().warn(this,
  -                                         
XSLTErrorResources.WG_ILLEGAL_ATTRIBUTE_NAME,
  -                                         new Object[]{ elemName });
  -            elemName = null;
  -          }
  -          
  -        }
  -        catch (Exception ex)
  +        if (null == nodeNamespace && indexOfNSSep <= 0)
  +          nodeNamespace = "";
  +
  +        // Check if valid QName. Assuming that if the prefix is defined,
  +        // it is valid.
  +        if (!validateNodeName(nodeName))
           {
  -          transformer.getMsgMgr().warn(this,
  -                                       
XSLTErrorResources.WG_COULD_NOT_RESOLVE_PREFIX,
  -                                       new Object[]{ prefix });
  -          shouldAddAttrs = false;
  -          elemName = null;
  +          transformer.getMsgMgr().warn(
  +            this, XSLTErrorResources.WG_ILLEGAL_ATTRIBUTE_NAME,
  +            new Object[]{ nodeName });
  +
  +          nodeName = null;
           }
         }
  +      catch (Exception ex)
  +      {
  +        transformer.getMsgMgr().warn(
  +          this, XSLTErrorResources.WG_COULD_NOT_RESOLVE_PREFIX,
  +          new Object[]{ prefix });
   
  -      // Check if valid QName
  -      else if (null == elemName)
  +        nodeName = null;
  +      }
  +    }
  +
  +    // Check if valid QName
  +    else if (null == nodeName)
  +    {
  +      transformer.getMsgMgr().warn(
  +        this, XSLTErrorResources.WG_ILLEGAL_ATTRIBUTE_NAME,
  +        new Object[]{ nodeName });
  +
  +      nodeName = null;
  +    }
  +    else if (nodeName.length() == 0 ||!isValidNCName(nodeName))
  +    {
  +      transformer.getMsgMgr().warn(
  +        this, XSLTErrorResources.WG_COULD_NOT_RESOLVE_PREFIX,
  +        new Object[]{ nodeName });
  +
  +      nodeName = null;
  +    }
  +
  +    if (null != nodeName)
  +    {
  +      if (null != m_namespace_avt)
         {
  -        transformer.getMsgMgr().warn(this,
  -                                     
XSLTErrorResources.WG_ILLEGAL_ATTRIBUTE_NAME,
  -                                     new Object[]{ elemName });
  +        nodeNamespace = m_namespace_avt.evaluate(xctxt, sourceNode, this);
  +
  +        // System.out.println("nodeNamespace: "+nodeNamespace);
  +        if (null == nodeNamespace)
  +          nodeNamespace = "";
  +
  +        prefix = resolvePrefix(rhandler, prefix, nodeNamespace);
  +        
  +        if (null == prefix)
  +          prefix = "";
   
  -        elemName = null;
  +        if (prefix.length() > 0)
  +          nodeName = (prefix + ":" + QName.getLocalPart(nodeName));
         }
  -      else if (elemName.length() == 0 ||!isValidNCName(elemName))
  +      else if (null != prefix && null == nodeNamespace)
         {
  -        transformer.getMsgMgr().warn(this,
  -                                     
XSLTErrorResources.WG_COULD_NOT_RESOLVE_PREFIX,
  -                                     new Object[]{ elemName });
  +        transformer.getMsgMgr().warn(
  +          this, XSLTErrorResources.WG_COULD_NOT_RESOLVE_PREFIX,
  +          new Object[]{ prefix });
   
  -        elemName = null;
  +        nodeName = null;
         }
  +    }
  +
  +    constructNode(nodeName, prefix, nodeNamespace, transformer, sourceNode,
  +                  mode);
  +  }
  +  
  +  /**
  +   * Construct a node in the result tree.  This method is overloaded by 
  +   * xsl:attribute. At this class level, this method creates an element.
  +   *
  +   * @param nodeName The name of the node, which may be null.
  +   * @param prefix The prefix for the namespace, which may be null.
  +   * @param nodeNamespace The namespace of the node, which may be null.
  +   * @param transformer non-null reference to the the current transform-time 
state.
  +   * @param sourceNode non-null reference to the <a 
href="http://www.w3.org/TR/xslt#dt-current-node";>current source node</a>.
  +   * @param mode reference, which may be null, to the <a 
href="http://www.w3.org/TR/xslt#modes";>current mode</a>.
  +   *
  +   * @throws TransformerException
  +   */
  +  void constructNode(
  +          String nodeName, String prefix, String nodeNamespace, 
TransformerImpl transformer, Node sourceNode, QName mode)
  +            throws TransformerException
  +  {
   
  -      if (null != elemName)
  +    try
  +    {
  +      ResultTreeHandler rhandler = transformer.getResultTreeHandler();
  +
  +      if (null != nodeName)
         {
  -        if (null != m_namespace_avt)
  -        {
  -          elemNameSpace = m_namespace_avt.evaluate(xctxt, sourceNode, this);
  -// System.out.println("elemNameSpace: "+elemNameSpace);
  -          if (null == elemNameSpace)
  -            elemNameSpace = "";
  -            
  -          if(null != prefix)
  -          {
  -            String nsPrefix = rhandler.getPrefix(elemNameSpace);
  - // System.out.println("nsPrefix: "+nsPrefix);           
  -            if (null == nsPrefix)
  -              nsPrefix = "";
  -              
  -//            if(!nsPrefix.equals(prefix))
  -//            {
  -//              prefix="";
  -//              elemName = QName.getLocalPart(elemName);
  -//            }            
  -          }
  -          if(null == prefix)
  -            prefix = "";
  -            
  -          if(prefix.length() > 0)
  -            elemName = (prefix + ":" + QName.getLocalPart(elemName));
  -        }
  -        else if(null != prefix && null == elemNameSpace)
  -        {
  -          transformer.getMsgMgr().warn(this,
  -                                       
XSLTErrorResources.WG_COULD_NOT_RESOLVE_PREFIX,
  -                                       new Object[]{ prefix });
  -          elemName = null;
  -        }
  +
  +        // Add namespace declarations.
  +        executeNSDecls(transformer);
   
  -        if(null != elemName)
  +        if (null != prefix)
           {
  -          // Add namespace declarations.
  -          executeNSDecls(transformer);
  -  
  -          if (null != prefix)
  -          {
  -            rhandler.startPrefixMapping(prefix, elemNameSpace, true);
  -          }
  -  
  -          rhandler.startElement(elemNameSpace, QName.getLocalPart(elemName),
  -                                elemName, null);
  +          rhandler.startPrefixMapping(prefix, nodeNamespace, true);
           }
  +
  +        rhandler.startElement(nodeNamespace, QName.getLocalPart(nodeName),
  +                              nodeName, null);
         }
   
  -      if(null == elemName)
  -        shouldAddAttrs = false;
  -        
  -      if(shouldAddAttrs)
  +      boolean shouldAddAttrs = (null != nodeName);
  +
  +      if (shouldAddAttrs)
           super.execute(transformer, sourceNode, mode);
  -      transformer.executeChildTemplates(this, sourceNode, mode, 
shouldAddAttrs);
  +
  +      transformer.executeChildTemplates(this, sourceNode, mode,
  +                                        shouldAddAttrs);
   
         // Now end the element if name was valid
  -      if (null != elemName)
  +      if (null != nodeName)
         {
  -        rhandler.endElement(elemNameSpace, QName.getLocalPart(elemName), 
elemName);
  +        rhandler.endElement(nodeNamespace, QName.getLocalPart(nodeName),
  +                            nodeName);
           unexecuteNSDecls(transformer);
         }
       }
  -    catch(SAXException se)
  +    catch (SAXException se)
       {
         throw new TransformerException(se);
       }
  
  
  

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

Reply via email to