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: TemplateSubPatternAssociation.java 468643 2006-10-28 06:56:03Z minchau $
     20  */
     21 package org.apache.xalan.templates;
     22 
     23 import java.io.Serializable;
     24 
     25 import javax.xml.transform.TransformerException;
     26 
     27 import org.apache.xml.utils.QName;
     28 import org.apache.xpath.XPath;
     29 import org.apache.xpath.XPathContext;
     30 import org.apache.xpath.patterns.StepPattern;
     31 
     32 /**
     33  * A class to contain a match pattern and it's corresponding template.
     34  * This class also defines a node in a match pattern linked list.
     35  */
     36 class TemplateSubPatternAssociation implements Serializable, Cloneable
     37 {
     38     static final long serialVersionUID = -8902606755229903350L;
     39 
     40   /** Step pattern           */
     41   StepPattern m_stepPattern;
     42 
     43   /** Template pattern          */
     44   private String m_pattern;
     45 
     46   /** The template element         */
     47   private ElemTemplate m_template;
     48 
     49   /** Next pattern         */
     50   private TemplateSubPatternAssociation m_next = null;
     51 
     52   /** Flag indicating whether this is wild card pattern          */
     53   private boolean m_wild;
     54 
     55   /** Target string for this match pattern           */
     56   private String m_targetString;
     57 
     58   /**
     59    * Construct a match pattern from a pattern and template.
     60    * @param template The node that contains the template for this pattern.
     61    * @param pattern An executable XSLT StepPattern.
     62    * @param pat For now a Nodelist that contains old-style element patterns.
     63    */
     64   TemplateSubPatternAssociation(ElemTemplate template, StepPattern pattern, String pat)
     65   {
     66 
     67     m_pattern = pat;
     68     m_template = template;
     69     m_stepPattern = pattern;
     70     m_targetString = m_stepPattern.getTargetString();
     71     m_wild = m_targetString.equals("*");
     72   }
     73 
     74   /**
     75    * Clone this object.
     76    *
     77    * @return The cloned object.
     78    *
     79    * @throws CloneNotSupportedException
     80    */
     81   public Object clone() throws CloneNotSupportedException
     82   {
     83 
     84     TemplateSubPatternAssociation tspa =
     85       (TemplateSubPatternAssociation) super.clone();
     86 
     87     tspa.m_next = null;
     88 
     89     return tspa;
     90   }
     91 
     92   /**
     93    * Get the target string of the pattern.  For instance, if the pattern is
     94    * "foo/baz/boo[@daba]", this string will be "boo".
     95    *
     96    * @return The "target" string.
     97    */
     98   public final String getTargetString()
     99   {
    100     return m_targetString;
    101   }
    102 
    103   /**
    104    * Set Target String for this template pattern
    105    *
    106    *
    107    * @param key Target string to set
    108    */
    109   public void setTargetString(String key)
    110   {
    111     m_targetString = key;
    112   }
    113 
    114   /**
    115    * Tell if two modes match according to the rules of XSLT.
    116    *
    117    * @param m1 mode to match
    118    *
    119    * @return True if the given mode matches this template's mode
    120    */
    121   boolean matchMode(QName m1)
    122   {
    123     return matchModes(m1, m_template.getMode());
    124   }
    125 
    126   /**
    127    * Tell if two modes match according to the rules of XSLT.
    128    *
    129    * @param m1 First mode to match
    130    * @param m2 Second mode to match
    131    *
    132    * @return True if the two given modes match
    133    */
    134   private boolean matchModes(QName m1, QName m2)
    135   {
    136     return (((null == m1) && (null == m2))
    137             || ((null != m1) && (null != m2) && m1.equals(m2)));
    138   }
    139 
    140   /**
    141    * Return the mode associated with the template.
    142    *
    143    *
    144    * @param xctxt XPath context to use with this template
    145    * @param targetNode Target node
    146    * @param mode reference, which may be null, to the <a href="http://www.w3.org/TR/xslt#modes">current mode</a>.
    147    * @return The mode associated with the template.
    148    *
    149    * @throws TransformerException
    150    */
    151   public boolean matches(XPathContext xctxt, int targetNode, QName mode)
    152           throws TransformerException
    153   {
    154 
    155     double score = m_stepPattern.getMatchScore(xctxt, targetNode);
    156 
    157     return (XPath.MATCH_SCORE_NONE != score)
    158            && matchModes(mode, m_template.getMode());
    159   }
    160 
    161   /**
    162    * Tell if the pattern for this association is a wildcard.
    163    *
    164    * @return true if this pattern is considered to be a wild match.
    165    */
    166   public final boolean isWild()
    167   {
    168     return m_wild;
    169   }
    170 
    171   /**
    172    * Get associated XSLT StepPattern.
    173    *
    174    * @return An executable StepPattern object, never null.
    175    *
    176    */
    177   public final StepPattern getStepPattern()
    178   {
    179     return m_stepPattern;
    180   }
    181 
    182   /**
    183    * Get the pattern string for diagnostic purposes.
    184    *
    185    * @return The pattern string for diagnostic purposes.
    186    *
    187    */
    188   public final String getPattern()
    189   {
    190     return m_pattern;
    191   }
    192 
    193   /**
    194    * Return the position of the template in document
    195    * order in the stylesheet.
    196    *
    197    * @return The position of the template in the overall template order.
    198    */
    199   public int getDocOrderPos()
    200   {
    201     return m_template.getUid();
    202   }
    203 
    204   /**
    205    * Return the import level associated with the stylesheet into which
    206    * this template is composed.
    207    *
    208    * @return The import level of this template.
    209    */
    210   public final int getImportLevel()
    211   {
    212     return m_template.getStylesheetComposed().getImportCountComposed();
    213   }
    214 
    215   /**
    216    * Get the assocated xsl:template.
    217    *
    218    * @return An ElemTemplate, never null.
    219    *
    220    */
    221   public final ElemTemplate getTemplate()
    222   {
    223     return m_template;
    224   }
    225 
    226   /**
    227    * Get the next association.
    228    *
    229    * @return A valid TemplateSubPatternAssociation, or null.
    230    */
    231   public final TemplateSubPatternAssociation getNext()
    232   {
    233     return m_next;
    234   }
    235 
    236   /**
    237    * Set the next element on this association
    238    * list, which should be equal or less in priority to
    239    * this association, and, if equal priority, should occur
    240    * before this template in document order.
    241    *
    242    * @param mp The next association to score if this one fails.
    243    *
    244    */
    245   public void setNext(TemplateSubPatternAssociation mp)
    246   {
    247     m_next = mp;
    248   }
    249 }
    250