14c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/* 24c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one 34c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * or more contributor license agreements. See the NOTICE file 44c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * distributed with this work for additional information 54c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * regarding copyright ownership. The ASF licenses this file 64c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * to you under the Apache License, Version 2.0 (the "License"); 74c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * you may not use this file except in compliance with the License. 84c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * You may obtain a copy of the License at 94c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Unless required by applicable law or agreed to in writing, software 134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * See the License for the specific language governing permissions and 164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * limitations under the License. 174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/* 194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * $Id: ElemExsltFunction.java 468643 2006-10-28 06:56:03Z minchau $ 204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpackage org.apache.xalan.templates; 224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.transform.TransformerException; 244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xalan.extensions.ExtensionNamespaceSupport; 264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xalan.transformer.TransformerImpl; 274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.VariableStack; 284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.XPathContext; 294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.objects.XObject; 304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.w3c.dom.Node; 324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.w3c.dom.NodeList; 334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/** 364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Implement func:function. 374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @xsl.usage advanced 384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpublic class ElemExsltFunction extends ElemTemplate 404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson{ 414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson static final long serialVersionUID = 272154954793534771L; 424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get an integer representation of the element type. 444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return An integer representation of the element, defined in the 464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Constants class. 474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xalan.templates.Constants 484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public int getXSLToken() 504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return Constants.EXSLT_ELEMNAME_FUNCTION; 524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Return the node name, defined in the 564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Constants class. 574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xalan.templates.Constants 584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return The node name 594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public String getNodeName() 624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return Constants.EXSLT_ELEMNAME_FUNCTION_STRING; 644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void execute(TransformerImpl transformer, XObject[] args) 674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws TransformerException 684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPathContext xctxt = transformer.getXPathContext(); 704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson VariableStack vars = xctxt.getVarStack(); 714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Increment the frame bottom of the variable stack by the 734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // frame size 744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int thisFrame = vars.getStackFrame(); 754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int nextFrame = vars.link(m_frameSize); 764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (m_inArgsSize < args.length) { 784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new TransformerException ("function called with too many args"); 794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Set parameters, 824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // have to clear the section of the stack frame that has params. 834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (m_inArgsSize > 0) { 844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson vars.clearLocalSlots(0, m_inArgsSize); 854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (args.length > 0) { 874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson vars.setStackFrame(thisFrame); 884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson NodeList children = this.getChildNodes(); 894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson for (int i = 0; i < args.length; i ++) { 914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson Node child = children.item(i); 924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (children.item(i) instanceof ElemParam) { 934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson ElemParam param = (ElemParam)children.item(i); 944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson vars.setLocalVariable(param.getIndex(), args[i], nextFrame); 954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson vars.setStackFrame(nextFrame); 994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Removed ElemTemplate 'push' and 'pop' of RTFContext, in order to avoid losing the RTF context 1034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // before a value can be returned. ElemExsltFunction operates in the scope of the template that called 1044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // the function. 1054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // xctxt.pushRTFContext(); 1064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson vars.setStackFrame(nextFrame); 1084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transformer.executeChildTemplates(this, true); 1094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Reset the stack frame after the function call 1114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson vars.unlink(thisFrame); 1124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Following ElemTemplate 'pop' removed -- see above. 1144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // xctxt.popRTFContext(); 1154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Called after everything else has been 1204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * recomposed, and allows the function to set remaining 1214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * values that may be based on some other property that 1224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * depends on recomposition. 1234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void compose(StylesheetRoot sroot) throws TransformerException 1254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super.compose(sroot); 1274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Register the function namespace (if not already registered). 1294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson String namespace = getName().getNamespace(); 1304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson String handlerClass = sroot.getExtensionHandlerClass(); 1314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson Object[] args ={namespace, sroot}; 1324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson ExtensionNamespaceSupport extNsSpt = 1334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson new ExtensionNamespaceSupport(namespace, handlerClass, args); 1344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson sroot.getExtensionNamespacesManager().registerExtension(extNsSpt); 1354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Make sure there is a handler for the EXSLT functions namespace 1364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // -- for isElementAvailable(). 1374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (!(namespace.equals(Constants.S_EXSLT_FUNCTIONS_URL))) 1384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson namespace = Constants.S_EXSLT_FUNCTIONS_URL; 1404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson args = new Object[]{namespace, sroot}; 1414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson extNsSpt = new ExtensionNamespaceSupport(namespace, handlerClass, args); 1424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson sroot.getExtensionNamespacesManager().registerExtension(extNsSpt); 1434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson} 146