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 */
21package org.apache.xalan.templates;
22
23import java.io.Serializable;
24
25import javax.xml.transform.TransformerException;
26
27import org.apache.xml.utils.QName;
28import org.apache.xpath.XPath;
29import org.apache.xpath.XPathContext;
30import 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 */
36class 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