Home | History | Annotate | Download | only in templates
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one
      3  * or more contributor license agreements. See the NOTICE file
      4  * distributed with this work for additional information
      5  * regarding copyright ownership. The ASF licenses this file
      6  * to you under the Apache License, Version 2.0 (the  "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  *     http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  */
     18 /*
     19  * $Id: ElemUse.java 476466 2006-11-18 08:22:31Z minchau $
     20  */
     21 package org.apache.xalan.templates;
     22 
     23 import java.util.Vector;
     24 
     25 import javax.xml.transform.TransformerException;
     26 
     27 import org.apache.xalan.res.XSLMessages;
     28 import org.apache.xalan.res.XSLTErrorResources;
     29 import org.apache.xalan.transformer.TransformerImpl;
     30 import org.apache.xml.utils.QName;
     31 
     32 /**
     33  * Implement xsl:use.
     34  * This acts as a superclass for ElemCopy, ElemAttributeSet,
     35  * ElemElement, and ElemLiteralResult, on order to implement
     36  * shared behavior the use-attribute-sets attribute.
     37  * @see <a href="http://www.w3.org/TR/xslt#attribute-sets">attribute-sets in XSLT Specification</a>
     38  * @xsl.usage advanced
     39  */
     40 public class ElemUse extends ElemTemplateElement
     41 {
     42     static final long serialVersionUID = 5830057200289299736L;
     43 
     44   /**
     45    * The value of the "use-attribute-sets" attribute.
     46    * @serial
     47    */
     48   private QName m_attributeSetsNames[] = null;
     49 
     50   /**
     51    * Set the "use-attribute-sets" attribute.
     52    * Attribute sets are used by specifying a use-attribute-sets
     53    * attribute on xsl:element, xsl:copy (see [7.5 Copying]) or
     54    * xsl:attribute-set elements. The value of the use-attribute-sets
     55    * attribute is a whitespace-separated list of names of attribute
     56    * sets. Each name is specified as a QName, which is expanded as
     57    * described in [2.4 Qualified Names].
     58    *
     59    * @param v The value to set for the "use-attribute-sets" attribute.
     60    */
     61   public void setUseAttributeSets(Vector v)
     62   {
     63 
     64     int n = v.size();
     65 
     66     m_attributeSetsNames = new QName[n];
     67 
     68     for (int i = 0; i < n; i++)
     69     {
     70       m_attributeSetsNames[i] = (QName) v.elementAt(i);
     71     }
     72   }
     73 
     74   /**
     75    * Set the "use-attribute-sets" attribute.
     76    * Attribute sets are used by specifying a use-attribute-sets
     77    * attribute on xsl:element, xsl:copy (see [7.5 Copying]) or
     78    * xsl:attribute-set elements. The value of the use-attribute-sets
     79    * attribute is a whitespace-separated list of names of attribute
     80    * sets. Each name is specified as a QName, which is expanded as
     81    * described in [2.4 Qualified Names].
     82    *
     83    * @param v The value to set for the "use-attribute-sets" attribute.
     84    */
     85   public void setUseAttributeSets(QName[] v)
     86   {
     87     m_attributeSetsNames = v;
     88   }
     89 
     90   /**
     91    * Get the "use-attribute-sets" attribute.
     92    * Attribute sets are used by specifying a use-attribute-sets
     93    * attribute on xsl:element, xsl:copy (see [7.5 Copying]) or
     94    * xsl:attribute-set elements, or a xsl:use-attribute-sets attribute on
     95    * Literal Result Elements.
     96    * The value of the use-attribute-sets
     97    * attribute is a whitespace-separated list of names of attribute
     98    * sets. Each name is specified as a QName, which is expanded as
     99    * described in [2.4 Qualified Names].
    100    *
    101    * @return The value of the "use-attribute-sets" attribute.
    102    */
    103   public QName[] getUseAttributeSets()
    104   {
    105     return m_attributeSetsNames;
    106   }
    107 
    108   /**
    109    * Add the attributes from the named attribute sets to the attribute list.
    110    * TODO: Error handling for: "It is an error if there are two attribute sets
    111    * with the same expanded-name and with equal import precedence and that both
    112    * contain the same attribute unless there is a definition of the attribute
    113    * set with higher import precedence that also contains the attribute."
    114    *
    115    * @param transformer non-null reference to the the current transform-time state.
    116    * @param stylesheet The owning root stylesheet
    117    *
    118    * @throws TransformerException
    119    */
    120   public void applyAttrSets(
    121           TransformerImpl transformer, StylesheetRoot stylesheet)
    122             throws TransformerException
    123   {
    124     applyAttrSets(transformer, stylesheet, m_attributeSetsNames);
    125   }
    126 
    127   /**
    128    * Add the attributes from the named attribute sets to the attribute list.
    129    * TODO: Error handling for: "It is an error if there are two attribute sets
    130    * with the same expanded-name and with equal import precedence and that both
    131    * contain the same attribute unless there is a definition of the attribute
    132    * set with higher import precedence that also contains the attribute."
    133    *
    134    * @param transformer non-null reference to the the current transform-time state.
    135    * @param stylesheet The owning root stylesheet
    136    * @param attributeSetsNames List of attribute sets names to apply
    137    *
    138    * @throws TransformerException
    139    */
    140   private void applyAttrSets(
    141           TransformerImpl transformer, StylesheetRoot stylesheet, QName attributeSetsNames[])
    142             throws TransformerException
    143   {
    144 
    145     if (null != attributeSetsNames)
    146     {
    147       int nNames = attributeSetsNames.length;
    148 
    149       for (int i = 0; i < nNames; i++)
    150       {
    151         QName qname = attributeSetsNames[i];
    152         java.util.List attrSets = stylesheet.getAttributeSetComposed(qname);
    153 
    154         if (null != attrSets)
    155         {
    156           int nSets = attrSets.size();
    157 
    158           // Highest priority attribute set will be at the top,
    159           // so process it last.
    160           for (int k = nSets-1; k >= 0 ; k--)
    161           {
    162             ElemAttributeSet attrSet =
    163               (ElemAttributeSet) attrSets.get(k);
    164 
    165             attrSet.execute(transformer);
    166           }
    167         }
    168         else
    169         {
    170           throw new TransformerException(
    171               XSLMessages.createMessage(XSLTErrorResources.ER_NO_ATTRIB_SET,
    172                   new Object[] {qname}),this);
    173         }
    174       }
    175     }
    176   }
    177 
    178   /**
    179    * Copy attributes specified by use-attribute-sets to the result tree.
    180    * Specifying a use-attribute-sets attribute is equivalent to adding
    181    * xsl:attribute elements for each of the attributes in each of the
    182    * named attribute sets to the beginning of the content of the element
    183    * with the use-attribute-sets attribute, in the same order in which
    184    * the names of the attribute sets are specified in the use-attribute-sets
    185    * attribute. It is an error if use of use-attribute-sets attributes
    186    * on xsl:attribute-set elements causes an attribute set to directly
    187    * or indirectly use itself.
    188    *
    189    * @param transformer non-null reference to the the current transform-time state.
    190    *
    191    * @throws TransformerException
    192    */
    193   public void execute(
    194           TransformerImpl transformer)
    195             throws TransformerException
    196   {
    197 
    198     if (null != m_attributeSetsNames)
    199     {
    200       applyAttrSets(transformer, getStylesheetRoot(),
    201                     m_attributeSetsNames);
    202     }
    203 
    204   }
    205 }
    206