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: ElemUse.java 476466 2006-11-18 08:22:31Z minchau $ 020 */ 021 package org.apache.xalan.templates; 022 023 import java.util.Vector; 024 025 import javax.xml.transform.TransformerException; 026 027 import org.apache.xalan.res.XSLMessages; 028 import org.apache.xalan.res.XSLTErrorResources; 029 import org.apache.xalan.transformer.TransformerImpl; 030 import org.apache.xml.utils.QName; 031 032 /** 033 * Implement xsl:use. 034 * This acts as a superclass for ElemCopy, ElemAttributeSet, 035 * ElemElement, and ElemLiteralResult, on order to implement 036 * shared behavior the use-attribute-sets attribute. 037 * @see <a href="http://www.w3.org/TR/xslt#attribute-sets">attribute-sets in XSLT Specification</a> 038 * @xsl.usage advanced 039 */ 040 public class ElemUse extends ElemTemplateElement 041 { 042 static final long serialVersionUID = 5830057200289299736L; 043 044 /** 045 * The value of the "use-attribute-sets" attribute. 046 * @serial 047 */ 048 private QName m_attributeSetsNames[] = null; 049 050 /** 051 * Set the "use-attribute-sets" attribute. 052 * Attribute sets are used by specifying a use-attribute-sets 053 * attribute on xsl:element, xsl:copy (see [7.5 Copying]) or 054 * xsl:attribute-set elements. The value of the use-attribute-sets 055 * attribute is a whitespace-separated list of names of attribute 056 * sets. Each name is specified as a QName, which is expanded as 057 * described in [2.4 Qualified Names]. 058 * 059 * @param v The value to set for the "use-attribute-sets" attribute. 060 */ 061 public void setUseAttributeSets(Vector v) 062 { 063 064 int n = v.size(); 065 066 m_attributeSetsNames = new QName[n]; 067 068 for (int i = 0; i < n; i++) 069 { 070 m_attributeSetsNames[i] = (QName) v.elementAt(i); 071 } 072 } 073 074 /** 075 * Set the "use-attribute-sets" attribute. 076 * Attribute sets are used by specifying a use-attribute-sets 077 * attribute on xsl:element, xsl:copy (see [7.5 Copying]) or 078 * xsl:attribute-set elements. The value of the use-attribute-sets 079 * attribute is a whitespace-separated list of names of attribute 080 * sets. Each name is specified as a QName, which is expanded as 081 * described in [2.4 Qualified Names]. 082 * 083 * @param v The value to set for the "use-attribute-sets" attribute. 084 */ 085 public void setUseAttributeSets(QName[] v) 086 { 087 m_attributeSetsNames = v; 088 } 089 090 /** 091 * Get the "use-attribute-sets" attribute. 092 * Attribute sets are used by specifying a use-attribute-sets 093 * attribute on xsl:element, xsl:copy (see [7.5 Copying]) or 094 * xsl:attribute-set elements, or a xsl:use-attribute-sets attribute on 095 * Literal Result Elements. 096 * The value of the use-attribute-sets 097 * attribute is a whitespace-separated list of names of attribute 098 * sets. Each name is specified as a QName, which is expanded as 099 * 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 }