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 }