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: ProcessorExsltFunction.java 468640 2006-10-28 06:53:53Z minchau $ 209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xalan.processor; 229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemApplyImport; 249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemApplyTemplates; 259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemAttribute; 269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemCallTemplate; 279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemComment; 289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemCopy; 299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemCopyOf; 309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemElement; 319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemExsltFuncResult; 329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemExsltFunction; 339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemFallback; 349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemLiteralResult; 359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemMessage; 369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemNumber; 379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemPI; 389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemParam; 399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemTemplate; 409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemTemplateElement; 419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemText; 429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemTextLiteral; 439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemValueOf; 449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.ElemVariable; 459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.templates.Stylesheet; 469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.Attributes; 479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.SAXException; 489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/** 519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * This class processes parse events for an exslt func:function element. 529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @xsl.usage internal 539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic class ProcessorExsltFunction extends ProcessorTemplateElem 559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{ 569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static final long serialVersionUID = 2411427965578315332L; 579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Start an ElemExsltFunction. Verify that it is top level and that it has a name attribute with a 599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * namespace. 609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void startElement( 629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson StylesheetHandler handler, String uri, String localName, String rawName, Attributes attributes) 639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws SAXException 649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson //System.out.println("ProcessorFunction.startElement()"); 669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String msg = ""; 679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (!(handler.getElemTemplateElement() instanceof Stylesheet)) 689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson msg = "func:function element must be top level."; 709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson handler.error(msg, new SAXException(msg)); 719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson super.startElement(handler, uri, localName, rawName, attributes); 739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String val = attributes.getValue("name"); 759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int indexOfColon = val.indexOf(":"); 769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (indexOfColon > 0) 779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson //String prefix = val.substring(0, indexOfColon); 799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson //String localVal = val.substring(indexOfColon + 1); 809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson //String ns = handler.getNamespaceSupport().getURI(prefix); 819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson //if (ns.length() > 0) 829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // System.out.println("fullfuncname " + ns + localVal); 839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else 859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson msg = "func:function name must have namespace"; 879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson handler.error(msg, new SAXException(msg)); 889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Must include; super doesn't suffice! 939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson protected void appendAndPush( 959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson StylesheetHandler handler, ElemTemplateElement elem) 969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws SAXException 979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson //System.out.println("ProcessorFunction appendAndPush()" + elem); 999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson super.appendAndPush(handler, elem); 1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson //System.out.println("originating node " + handler.getOriginatingNode()); 1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson elem.setDOMBackPointer(handler.getOriginatingNode()); 1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson handler.getStylesheet().setTemplate((ElemTemplate) elem); 1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * End an ElemExsltFunction, and verify its validity. 1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void endElement( 1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson StylesheetHandler handler, String uri, String localName, String rawName) 1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws SAXException 1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ElemTemplateElement function = handler.getElemTemplateElement(); 1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson validate(function, handler); // may throw exception 1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson super.endElement(handler, uri, localName, rawName); 1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Non-recursive traversal of FunctionElement tree based on TreeWalker to verify that 1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * there are no literal result elements except within a func:result element and that 1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * the func:result element does not contain any following siblings except xsl:fallback. 1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void validate(ElemTemplateElement elem, StylesheetHandler handler) 1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws SAXException 1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String msg = ""; 1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson while (elem != null) 1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson //System.out.println("elem " + elem); 1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (elem instanceof ElemExsltFuncResult 1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson && elem.getNextSiblingElem() != null 1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson && !(elem.getNextSiblingElem() instanceof ElemFallback)) 1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson msg = "func:result has an illegal following sibling (only xsl:fallback allowed)"; 1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson handler.error(msg, new SAXException(msg)); 1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if((elem instanceof ElemApplyImport 1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson || elem instanceof ElemApplyTemplates 1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson || elem instanceof ElemAttribute 1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson || elem instanceof ElemCallTemplate 1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson || elem instanceof ElemComment 1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson || elem instanceof ElemCopy 1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson || elem instanceof ElemCopyOf 1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson || elem instanceof ElemElement 1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson || elem instanceof ElemLiteralResult 1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson || elem instanceof ElemNumber 1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson || elem instanceof ElemPI 1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson || elem instanceof ElemText 1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson || elem instanceof ElemTextLiteral 1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson || elem instanceof ElemValueOf) 1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson && !(ancestorIsOk(elem))) 1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson msg ="misplaced literal result in a func:function container."; 1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson handler.error(msg, new SAXException(msg)); 1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ElemTemplateElement nextElem = elem.getFirstChildElem(); 1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson while (nextElem == null) 1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson nextElem = elem.getNextSiblingElem(); 1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (nextElem == null) 1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson elem = elem.getParentElem(); 1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (elem == null || elem instanceof ElemExsltFunction) 1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return; // ok 1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson elem = nextElem; 1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Verify that a literal result belongs to a result element, a variable, 1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or a parameter. 1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson boolean ancestorIsOk(ElemTemplateElement child) 1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson while (child.getParentElem() != null && !(child.getParentElem() instanceof ElemExsltFunction)) 1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ElemTemplateElement parent = child.getParentElem(); 1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (parent instanceof ElemExsltFuncResult 1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson || parent instanceof ElemVariable 1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson || parent instanceof ElemParam 1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson || parent instanceof ElemMessage) 1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return true; 1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson child = parent; 1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return false; 1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson} 190