19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/* 29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one 39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or more contributor license agreements. See the NOTICE file 49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed with this work for additional information 59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * regarding copyright ownership. The ASF licenses this file 69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to you under the Apache License, Version 2.0 (the "License"); 79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * you may not use this file except in compliance with the License. 89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * You may obtain a copy of the License at 99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Unless required by applicable law or agreed to in writing, software 139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * See the License for the specific language governing permissions and 169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitations under the License. 179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/* 199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * $Id: ProcessorKey.java 469688 2006-10-31 22:39:43Z minchau $ 209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xalan.processor; 229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.ArrayList; 249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.List; 259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.res.XSLMessages; 279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.res.XSLTErrorResources; 289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.KeyDeclaration; 299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.Attributes; 309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/** 329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * TransformerFactory for xsl:key markup. 339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <pre> 349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <!ELEMENT xsl:key EMPTY> 359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <!ATTLIST xsl:key 369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * name %qname; #REQUIRED 379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * match %pattern; #REQUIRED 389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * use %expr; #REQUIRED 399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * > 409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * </pre> 419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a> 429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @see <a href="http://www.w3.org/TR/xslt#key">key in XSLT Specification</a> 439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonclass ProcessorKey extends XSLTElementProcessor 459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{ 469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static final long serialVersionUID = 4285205417566822979L; 479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Receive notification of the start of an xsl:key element. 509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param handler The calling StylesheetHandler/TemplatesBuilder. 529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param uri The Namespace URI, or the empty string if the 539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * element has no Namespace URI or if Namespace 549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * processing is not being performed. 559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param localName The local name (without prefix), or the 569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * empty string if Namespace processing is not being 579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * performed. 589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param rawName The raw XML 1.0 name (with prefix), or the 599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * empty string if raw names are not available. 609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param attributes The attributes attached to the element. If 619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * there are no attributes, it shall be an empty 629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Attributes object. 639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void startElement( 659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson StylesheetHandler handler, String uri, String localName, String rawName, Attributes attributes) 669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson KeyDeclaration kd = new KeyDeclaration(handler.getStylesheet(), handler.nextUid()); 709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson kd.setDOMBackPointer(handler.getOriginatingNode()); 729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson kd.setLocaterInfo(handler.getLocator()); 739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson setPropertiesFromAttributes(handler, rawName, attributes, kd); 749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson handler.getStylesheet().setKey(kd); 759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Set the properties of an object from the given attribute list. 799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param handler The stylesheet's Content handler, needed for 809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * error reporting. 819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param rawName The raw name of the owner element, needed for 829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * error reporting. 839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param attributes The list of attributes. 849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param target The target element where the properties will be set. 859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson void setPropertiesFromAttributes( 879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson StylesheetHandler handler, String rawName, Attributes attributes, 889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson org.apache.xalan.templates.ElemTemplateElement target) 899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XSLTElementDef def = getElemDef(); 939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Keep track of which XSLTAttributeDefs have been processed, so 959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // I can see which default values need to be set. 969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson List processedDefs = new ArrayList(); 979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int nAttrs = attributes.getLength(); 989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson for (int i = 0; i < nAttrs; i++) 1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String attrUri = attributes.getURI(i); 1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String attrLocalName = attributes.getLocalName(i); 1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XSLTAttributeDef attrDef = def.getAttributeDef(attrUri, attrLocalName); 1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null == attrDef) 1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Then barf, because this element does not allow this attribute. 1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson handler.error(attributes.getQName(i) 1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson + "attribute is not allowed on the " + rawName 1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson + " element!", null); 1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else 1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String valueString = attributes.getValue(i); 1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (valueString.indexOf(org.apache.xpath.compiler.Keywords.FUNC_KEY_STRING 1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson + "(") >= 0) 1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson handler.error( 1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XSLMessages.createMessage( 1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XSLTErrorResources.ER_INVALID_KEY_CALL, null), null); 1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson processedDefs.add(attrDef); 1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson attrDef.setAttrValue(handler, attrUri, attrLocalName, 1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson attributes.getQName(i), attributes.getValue(i), 1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson target); 1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XSLTAttributeDef[] attrDefs = def.getAttributes(); 1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int nAttrDefs = attrDefs.length; 1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson for (int i = 0; i < nAttrDefs; i++) 1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XSLTAttributeDef attrDef = attrDefs[i]; 1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String defVal = attrDef.getDefault(); 1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null != defVal) 1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (!processedDefs.contains(attrDef)) 1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson attrDef.setDefAttrValue(handler, target); 1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (attrDef.getRequired()) 1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (!processedDefs.contains(attrDef)) 1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson handler.error( 1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XSLMessages.createMessage( 1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XSLTErrorResources.ER_REQUIRES_ATTRIB, new Object[]{ rawName, 1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson attrDef.getName() }), null); 1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson} 157