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: ElemUse.java 476466 2006-11-18 08:22:31Z minchau $ 20 */ 21package org.apache.xalan.templates; 22 23import java.util.Vector; 24 25import javax.xml.transform.TransformerException; 26 27import org.apache.xalan.res.XSLMessages; 28import org.apache.xalan.res.XSLTErrorResources; 29import org.apache.xalan.transformer.TransformerImpl; 30import org.apache.xml.utils.QName; 31 32/** 33 * Implement xsl:use. 34 * This acts as a superclass for ElemCopy, ElemAttributeSet, 35 * ElemElement, and ElemLiteralResult, on order to implement 36 * shared behavior the use-attribute-sets attribute. 37 * @see <a href="http://www.w3.org/TR/xslt#attribute-sets">attribute-sets in XSLT Specification</a> 38 * @xsl.usage advanced 39 */ 40public class ElemUse extends ElemTemplateElement 41{ 42 static final long serialVersionUID = 5830057200289299736L; 43 44 /** 45 * The value of the "use-attribute-sets" attribute. 46 * @serial 47 */ 48 private QName m_attributeSetsNames[] = null; 49 50 /** 51 * Set the "use-attribute-sets" attribute. 52 * Attribute sets are used by specifying a use-attribute-sets 53 * attribute on xsl:element, xsl:copy (see [7.5 Copying]) or 54 * xsl:attribute-set elements. The value of the use-attribute-sets 55 * attribute is a whitespace-separated list of names of attribute 56 * sets. Each name is specified as a QName, which is expanded as 57 * described in [2.4 Qualified Names]. 58 * 59 * @param v The value to set for the "use-attribute-sets" attribute. 60 */ 61 public void setUseAttributeSets(Vector v) 62 { 63 64 int n = v.size(); 65 66 m_attributeSetsNames = new QName[n]; 67 68 for (int i = 0; i < n; i++) 69 { 70 m_attributeSetsNames[i] = (QName) v.elementAt(i); 71 } 72 } 73 74 /** 75 * Set the "use-attribute-sets" attribute. 76 * Attribute sets are used by specifying a use-attribute-sets 77 * attribute on xsl:element, xsl:copy (see [7.5 Copying]) or 78 * xsl:attribute-set elements. The value of the use-attribute-sets 79 * attribute is a whitespace-separated list of names of attribute 80 * sets. Each name is specified as a QName, which is expanded as 81 * described in [2.4 Qualified Names]. 82 * 83 * @param v The value to set for the "use-attribute-sets" attribute. 84 */ 85 public void setUseAttributeSets(QName[] v) 86 { 87 m_attributeSetsNames = v; 88 } 89 90 /** 91 * Get the "use-attribute-sets" attribute. 92 * Attribute sets are used by specifying a use-attribute-sets 93 * attribute on xsl:element, xsl:copy (see [7.5 Copying]) or 94 * xsl:attribute-set elements, or a xsl:use-attribute-sets attribute on 95 * Literal Result Elements. 96 * The value of the use-attribute-sets 97 * attribute is a whitespace-separated list of names of attribute 98 * sets. Each name is specified as a QName, which is expanded as 99 * described in [2.4 Qualified Names]. 100 * 101 * @return The value of the "use-attribute-sets" attribute. 102 */ 103 public QName[] getUseAttributeSets() 104 { 105 return m_attributeSetsNames; 106 } 107 108 /** 109 * Add the attributes from the named attribute sets to the attribute list. 110 * TODO: Error handling for: "It is an error if there are two attribute sets 111 * with the same expanded-name and with equal import precedence and that both 112 * contain the same attribute unless there is a definition of the attribute 113 * set with higher import precedence that also contains the attribute." 114 * 115 * @param transformer non-null reference to the the current transform-time state. 116 * @param stylesheet The owning root stylesheet 117 * 118 * @throws TransformerException 119 */ 120 public void applyAttrSets( 121 TransformerImpl transformer, StylesheetRoot stylesheet) 122 throws TransformerException 123 { 124 applyAttrSets(transformer, stylesheet, m_attributeSetsNames); 125 } 126 127 /** 128 * Add the attributes from the named attribute sets to the attribute list. 129 * TODO: Error handling for: "It is an error if there are two attribute sets 130 * with the same expanded-name and with equal import precedence and that both 131 * contain the same attribute unless there is a definition of the attribute 132 * set with higher import precedence that also contains the attribute." 133 * 134 * @param transformer non-null reference to the the current transform-time state. 135 * @param stylesheet The owning root stylesheet 136 * @param attributeSetsNames List of attribute sets names to apply 137 * 138 * @throws TransformerException 139 */ 140 private void applyAttrSets( 141 TransformerImpl transformer, StylesheetRoot stylesheet, QName attributeSetsNames[]) 142 throws TransformerException 143 { 144 145 if (null != attributeSetsNames) 146 { 147 int nNames = attributeSetsNames.length; 148 149 for (int i = 0; i < nNames; i++) 150 { 151 QName qname = attributeSetsNames[i]; 152 java.util.List attrSets = stylesheet.getAttributeSetComposed(qname); 153 154 if (null != attrSets) 155 { 156 int nSets = attrSets.size(); 157 158 // Highest priority attribute set will be at the top, 159 // so process it last. 160 for (int k = nSets-1; k >= 0 ; k--) 161 { 162 ElemAttributeSet attrSet = 163 (ElemAttributeSet) attrSets.get(k); 164 165 attrSet.execute(transformer); 166 } 167 } 168 else 169 { 170 throw new TransformerException( 171 XSLMessages.createMessage(XSLTErrorResources.ER_NO_ATTRIB_SET, 172 new Object[] {qname}),this); 173 } 174 } 175 } 176 } 177 178 /** 179 * Copy attributes specified by use-attribute-sets to the result tree. 180 * Specifying a use-attribute-sets attribute is equivalent to adding 181 * xsl:attribute elements for each of the attributes in each of the 182 * named attribute sets to the beginning of the content of the element 183 * with the use-attribute-sets attribute, in the same order in which 184 * the names of the attribute sets are specified in the use-attribute-sets 185 * attribute. It is an error if use of use-attribute-sets attributes 186 * on xsl:attribute-set elements causes an attribute set to directly 187 * or indirectly use itself. 188 * 189 * @param transformer non-null reference to the the current transform-time state. 190 * 191 * @throws TransformerException 192 */ 193 public void execute( 194 TransformerImpl transformer) 195 throws TransformerException 196 { 197 198 if (null != m_attributeSetsNames) 199 { 200 applyAttrSets(transformer, getStylesheetRoot(), 201 m_attributeSetsNames); 202 } 203 204 } 205} 206