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    */
TemplateSubPatternAssociation(ElemTemplate template, StepPattern pattern, String pat)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    */
clone()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    */
getTargetString()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    */
setTargetString(String key)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    */
matchMode(QName m1)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    */
matchModes(QName m1, QName m2)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    */
matches(XPathContext xctxt, int targetNode, QName mode)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    */
isWild()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    */
getStepPattern()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    */
getPattern()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    */
getDocOrderPos()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    */
getImportLevel()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    */
getTemplate()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    */
getNext()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    */
setNext(TemplateSubPatternAssociation mp)245   public void setNext(TemplateSubPatternAssociation mp)
246   {
247     m_next = mp;
248   }
249 }
250