001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 /*
019 * $Id: TemplateSubPatternAssociation.java 468643 2006-10-28 06:56:03Z minchau $
020 */
021 package org.apache.xalan.templates;
022
023 import java.io.Serializable;
024
025 import javax.xml.transform.TransformerException;
026
027 import org.apache.xml.utils.QName;
028 import org.apache.xpath.XPath;
029 import org.apache.xpath.XPathContext;
030 import org.apache.xpath.patterns.StepPattern;
031
032 /**
033 * A class to contain a match pattern and it's corresponding template.
034 * This class also defines a node in a match pattern linked list.
035 */
036 class TemplateSubPatternAssociation implements Serializable, Cloneable
037 {
038 static final long serialVersionUID = -8902606755229903350L;
039
040 /** Step pattern */
041 StepPattern m_stepPattern;
042
043 /** Template pattern */
044 private String m_pattern;
045
046 /** The template element */
047 private ElemTemplate m_template;
048
049 /** Next pattern */
050 private TemplateSubPatternAssociation m_next = null;
051
052 /** Flag indicating whether this is wild card pattern */
053 private boolean m_wild;
054
055 /** Target string for this match pattern */
056 private String m_targetString;
057
058 /**
059 * Construct a match pattern from a pattern and template.
060 * @param template The node that contains the template for this pattern.
061 * @param pattern An executable XSLT StepPattern.
062 * @param pat For now a Nodelist that contains old-style element patterns.
063 */
064 TemplateSubPatternAssociation(ElemTemplate template, StepPattern pattern, String pat)
065 {
066
067 m_pattern = pat;
068 m_template = template;
069 m_stepPattern = pattern;
070 m_targetString = m_stepPattern.getTargetString();
071 m_wild = m_targetString.equals("*");
072 }
073
074 /**
075 * Clone this object.
076 *
077 * @return The cloned object.
078 *
079 * @throws CloneNotSupportedException
080 */
081 public Object clone() throws CloneNotSupportedException
082 {
083
084 TemplateSubPatternAssociation tspa =
085 (TemplateSubPatternAssociation) super.clone();
086
087 tspa.m_next = null;
088
089 return tspa;
090 }
091
092 /**
093 * Get the target string of the pattern. For instance, if the pattern is
094 * "foo/baz/boo[@daba]", this string will be "boo".
095 *
096 * @return The "target" string.
097 */
098 public final String getTargetString()
099 {
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 }