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: ElemTemplate.java 468643 2006-10-28 06:56:03Z minchau $
     20  */
     21 package org.apache.xalan.templates;
     22 
     23 import javax.xml.transform.SourceLocator;
     24 import javax.xml.transform.TransformerException;
     25 
     26 import org.apache.xalan.transformer.TransformerImpl;
     27 import org.apache.xml.utils.QName;
     28 import org.apache.xpath.XPath;
     29 import org.apache.xpath.XPathContext;
     30 
     31 /**
     32  * Implement xsl:template.
     33  * <pre>
     34  * <!ELEMENT xsl:template
     35  *  (#PCDATA
     36  *   %instructions;
     37  *   %result-elements;
     38  *   | xsl:param)
     39  * >
     40  *
     41  * <!ATTLIST xsl:template
     42  *   match %pattern; #IMPLIED
     43  *   name %qname; #IMPLIED
     44  *   priority %priority; #IMPLIED
     45  *   mode %qname; #IMPLIED
     46  *   %space-att;
     47  * >
     48  * </pre>
     49  * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
     50  * @xsl.usage advanced
     51  */
     52 public class ElemTemplate extends ElemTemplateElement
     53 {
     54     static final long serialVersionUID = -5283056789965384058L;
     55   /** The public identifier for the current document event.
     56    *  @serial          */
     57   private String m_publicId;
     58 
     59   /** The system identifier for the current document event.
     60    *  @serial          */
     61   private String m_systemId;
     62 
     63   /**
     64    * Return the public identifier for the current document event.
     65    * <p>This will be the public identifier
     66    * @return A string containing the public identifier, or
     67    *         null if none is available.
     68    * @see #getSystemId
     69    */
     70   public String getPublicId()
     71   {
     72     return m_publicId;
     73   }
     74 
     75   /**
     76    * Return the system identifier for the current document event.
     77    *
     78    * <p>If the system identifier is a URL, the parser must resolve it
     79    * fully before passing it to the application.</p>
     80    *
     81    * @return A string containing the system identifier, or null
     82    *         if none is available.
     83    * @see #getPublicId
     84    */
     85   public String getSystemId()
     86   {
     87     return m_systemId;
     88   }
     89 
     90   /**
     91    * Set the location information for this element.
     92    *
     93    * @param locator SourceLocator holding location information
     94    */
     95   public void setLocaterInfo(SourceLocator locator)
     96   {
     97 
     98     m_publicId = locator.getPublicId();
     99     m_systemId = locator.getSystemId();
    100 
    101     super.setLocaterInfo(locator);
    102   }
    103 
    104   /**
    105    * The owning stylesheet.
    106    * (Should this only be put on the template element, to
    107    * conserve space?)
    108    * @serial
    109    */
    110   private Stylesheet m_stylesheet;
    111 
    112   /**
    113    * Get the stylesheet composed (resolves includes and
    114    * imports and has methods on it that return "composed" properties.
    115    *
    116    * @return The stylesheet composed.
    117    */
    118   public StylesheetComposed getStylesheetComposed()
    119   {
    120     return m_stylesheet.getStylesheetComposed();
    121   }
    122 
    123   /**
    124    * Get the owning stylesheet.
    125    *
    126    * @return The owning stylesheet.
    127    */
    128   public Stylesheet getStylesheet()
    129   {
    130     return m_stylesheet;
    131   }
    132 
    133   /**
    134    * Set the owning stylesheet.
    135    *
    136    * @param sheet The owning stylesheet for this element
    137    */
    138   public void setStylesheet(Stylesheet sheet)
    139   {
    140     m_stylesheet = sheet;
    141   }
    142 
    143   /**
    144    * Get the root stylesheet.
    145    *
    146    * @return The root stylesheet for this element
    147    */
    148   public StylesheetRoot getStylesheetRoot()
    149   {
    150     return m_stylesheet.getStylesheetRoot();
    151   }
    152 
    153   /**
    154    * The match attribute is a Pattern that identifies the source
    155    * node or nodes to which the rule applies.
    156    * @serial
    157    */
    158   private XPath m_matchPattern = null;
    159 
    160   /**
    161    * Set the "match" attribute.
    162    * The match attribute is a Pattern that identifies the source
    163    * node or nodes to which the rule applies. The match attribute
    164    * is required unless the xsl:template element has a name
    165    * attribute (see [6 Named Templates]). It is an error for the
    166    * value of the match attribute to contain a VariableReference.
    167    * @see <a href="http://www.w3.org/TR/xslt#patterns">patterns in XSLT Specification</a>
    168    *
    169    * @param v Value to set for the "match" attribute
    170    */
    171   public void setMatch(XPath v)
    172   {
    173     m_matchPattern = v;
    174   }
    175 
    176   /**
    177    * Get the "match" attribute.
    178    * The match attribute is a Pattern that identifies the source
    179    * node or nodes to which the rule applies. The match attribute
    180    * is required unless the xsl:template element has a name
    181    * attribute (see [6 Named Templates]). It is an error for the
    182    * value of the match attribute to contain a VariableReference.
    183    * @see <a href="http://www.w3.org/TR/xslt#patterns">patterns in XSLT Specification</a>
    184    *
    185    * @return Value of the "match" attribute
    186    */
    187   public XPath getMatch()
    188   {
    189     return m_matchPattern;
    190   }
    191 
    192   /**
    193    * An xsl:template element with a name attribute specifies a named template.
    194    * @serial
    195    */
    196   private QName m_name = null;
    197 
    198   /**
    199    * Set the "name" attribute.
    200    * An xsl:template element with a name attribute specifies a named template.
    201    * If an xsl:template element has a name attribute, it may, but need not,
    202    * also have a match attribute.
    203    * @see <a href="http://www.w3.org/TR/xslt#named-templates">named-templates in XSLT Specification</a>
    204    *
    205    * @param v Value to set the "name" attribute
    206    */
    207   public void setName(QName v)
    208   {
    209     m_name = v;
    210   }
    211 
    212   /**
    213    * Get the "name" attribute.
    214    * An xsl:template element with a name attribute specifies a named template.
    215    * If an xsl:template element has a name attribute, it may, but need not,
    216    * also have a match attribute.
    217    * @see <a href="http://www.w3.org/TR/xslt#named-templates">named-templates in XSLT Specification</a>
    218    *
    219    * @return Value of the "name" attribute
    220    */
    221   public QName getName()
    222   {
    223     return m_name;
    224   }
    225 
    226   /**
    227    * Modes allow an element to be processed multiple times,
    228    * each time producing a different result.
    229    * @serial
    230    */
    231   private QName m_mode;
    232 
    233   /**
    234    * Set the "mode" attribute.
    235    * Modes allow an element to be processed multiple times,
    236    * each time producing a different result.  If xsl:template
    237    * does not have a match attribute, it must not have a mode attribute.
    238    * @see <a href="http://www.w3.org/TR/xslt#modes">modes in XSLT Specification</a>
    239    *
    240    * @param v Value to set the "mode" attribute
    241    */
    242   public void setMode(QName v)
    243   {
    244     m_mode = v;
    245   }
    246 
    247   /**
    248    * Get the "mode" attribute.
    249    * Modes allow an element to be processed multiple times,
    250    * each time producing a different result.  If xsl:template
    251    * does not have a match attribute, it must not have a mode attribute.
    252    * @see <a href="http://www.w3.org/TR/xslt#modes">modes in XSLT Specification</a>
    253    *
    254    * @return Value of the "mode" attribute
    255    */
    256   public QName getMode()
    257   {
    258     return m_mode;
    259   }
    260 
    261   /**
    262    * The priority of a template rule is specified by the priority
    263    * attribute on the template rule.
    264    * @serial
    265    */
    266   private double m_priority = XPath.MATCH_SCORE_NONE;
    267 
    268   /**
    269    * Set the "priority" attribute.
    270    * The priority of a template rule is specified by the priority
    271    * attribute on the template rule. The value of this must be a
    272    * real number (positive or negative), matching the production
    273    * Number with an optional leading minus sign (-).
    274    * @see <a href="http://www.w3.org/TR/xslt#conflict">conflict in XSLT Specification</a>
    275    *
    276    * @param v The value to set for the "priority" attribute
    277    */
    278   public void setPriority(double v)
    279   {
    280     m_priority = v;
    281   }
    282 
    283   /**
    284    * Get the "priority" attribute.
    285    * The priority of a template rule is specified by the priority
    286    * attribute on the template rule. The value of this must be a
    287    * real number (positive or negative), matching the production
    288    * Number with an optional leading minus sign (-).
    289    * @see <a href="http://www.w3.org/TR/xslt#conflict">conflict in XSLT Specification</a>
    290    *
    291    * @return The value of the "priority" attribute
    292    */
    293   public double getPriority()
    294   {
    295     return m_priority;
    296   }
    297 
    298   /**
    299    * Get an int constant identifying the type of element.
    300    * @see org.apache.xalan.templates.Constants
    301    *
    302    * @return The token ID for the element
    303    */
    304   public int getXSLToken()
    305   {
    306     return Constants.ELEMNAME_TEMPLATE;
    307   }
    308 
    309   /**
    310    * Return the node name.
    311    *
    312    * @return The element's name
    313    */
    314   public String getNodeName()
    315   {
    316     return Constants.ELEMNAME_TEMPLATE_STRING;
    317   }
    318 
    319   /**
    320    * The stack frame size for this template, which is equal to the maximum number
    321    * of params and variables that can be declared in the template at one time.
    322    */
    323   public int m_frameSize;
    324 
    325   /**
    326    * The size of the portion of the stack frame that can hold parameter
    327    * arguments.
    328    */
    329   int m_inArgsSize;
    330 
    331   /**
    332    * List of namespace/local-name pairs, DTM style, that are unique
    333    * qname identifiers for the arguments.  The position of a given qname
    334    * in the list is the argument ID, and thus the position in the stack
    335    * frame.
    336    */
    337   private int[] m_argsQNameIDs;
    338 
    339   /**
    340    * This function is called after everything else has been
    341    * recomposed, and allows the template to set remaining
    342    * values that may be based on some other property that
    343    * depends on recomposition.
    344    */
    345   public void compose(StylesheetRoot sroot) throws TransformerException
    346   {
    347     super.compose(sroot);
    348     StylesheetRoot.ComposeState cstate = sroot.getComposeState();
    349     java.util.Vector vnames = cstate.getVariableNames();
    350     if(null != m_matchPattern)
    351       m_matchPattern.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
    352 
    353     cstate.resetStackFrameSize();
    354     m_inArgsSize = 0;
    355   }
    356 
    357   /**
    358    * This after the template's children have been composed.
    359    */
    360   public void endCompose(StylesheetRoot sroot) throws TransformerException
    361   {
    362     StylesheetRoot.ComposeState cstate = sroot.getComposeState();
    363     super.endCompose(sroot);
    364     m_frameSize = cstate.getFrameSize();
    365 
    366     cstate.resetStackFrameSize();
    367   }
    368 
    369   /**
    370    * Copy the template contents into the result tree.
    371    * The content of the xsl:template element is the template
    372    * that is instantiated when the template rule is applied.
    373    *
    374    * @param transformer non-null reference to the the current transform-time state.
    375    *
    376    * @throws TransformerException
    377    */
    378   public void execute(
    379           TransformerImpl transformer)
    380             throws TransformerException
    381   {
    382     XPathContext xctxt = transformer.getXPathContext();
    383 
    384     xctxt.pushRTFContext();
    385 
    386       // %REVIEW% commenting out of the code below.
    387 //    if (null != sourceNode)
    388 //    {
    389       transformer.executeChildTemplates(this, true);
    390 //    }
    391 //    else  // if(null == sourceNode)
    392 //    {
    393 //      transformer.getMsgMgr().error(this,
    394 //        this, sourceNode,
    395 //        XSLTErrorResources.ER_NULL_SOURCENODE_HANDLEAPPLYTEMPLATES);
    396 //
    397 //      //"sourceNode is null in handleApplyTemplatesInstruction!");
    398 //    }
    399 
    400     xctxt.popRTFContext();
    401     }
    402 
    403   /**
    404    * This function is called during recomposition to
    405    * control how this element is composed.
    406    * @param root The root stylesheet for this transformation.
    407    */
    408   public void recompose(StylesheetRoot root)
    409   {
    410     root.recomposeTemplates(this);
    411   }
    412 
    413 }
    414