Home | History | Annotate | Download | only in extensions
      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: ExtensionsTable.java 469672 2006-10-31 21:56:19Z minchau $
     20  */
     21 package org.apache.xalan.extensions;
     22 
     23 import java.util.Hashtable;
     24 import java.util.Vector;
     25 
     26 import org.apache.xalan.res.XSLMessages;
     27 import org.apache.xalan.res.XSLTErrorResources;
     28 import org.apache.xalan.templates.StylesheetRoot;
     29 import org.apache.xpath.XPathProcessorException;
     30 import org.apache.xpath.functions.FuncExtFunction;
     31 
     32 /**
     33  * Class holding a table registered extension namespace handlers
     34  * @xsl.usage internal
     35  */
     36 public class ExtensionsTable
     37 {
     38   /**
     39    * Table of extensions that may be called from the expression language
     40    * via the call(name, ...) function.  Objects are keyed on the call
     41    * name.
     42    * @xsl.usage internal
     43    */
     44   public Hashtable m_extensionFunctionNamespaces = new Hashtable();
     45 
     46   /**
     47    * The StylesheetRoot associated with this extensions table.
     48    */
     49   private StylesheetRoot m_sroot;
     50 
     51   /**
     52    * The constructor (called from TransformerImpl) registers the
     53    * StylesheetRoot for the transformation and instantiates an
     54    * ExtensionHandler for each extension namespace.
     55    * @xsl.usage advanced
     56    */
     57   public ExtensionsTable(StylesheetRoot sroot)
     58     throws javax.xml.transform.TransformerException
     59   {
     60     m_sroot = sroot;
     61     Vector extensions = m_sroot.getExtensions();
     62     for (int i = 0; i < extensions.size(); i++)
     63     {
     64       ExtensionNamespaceSupport extNamespaceSpt =
     65                  (ExtensionNamespaceSupport)extensions.get(i);
     66       ExtensionHandler extHandler = extNamespaceSpt.launch();
     67         if (extHandler != null)
     68           addExtensionNamespace(extNamespaceSpt.getNamespace(), extHandler);
     69       }
     70     }
     71 
     72   /**
     73    * Get an ExtensionHandler object that represents the
     74    * given namespace.
     75    * @param extns A valid extension namespace.
     76    *
     77    * @return ExtensionHandler object that represents the
     78    * given namespace.
     79    */
     80   public ExtensionHandler get(String extns)
     81   {
     82     return (ExtensionHandler) m_extensionFunctionNamespaces.get(extns);
     83   }
     84 
     85   /**
     86    * Register an extension namespace handler. This handler provides
     87    * functions for testing whether a function is known within the
     88    * namespace and also for invoking the functions.
     89    *
     90    * @param uri the URI for the extension.
     91    * @param extNS the extension handler.
     92    * @xsl.usage advanced
     93    */
     94   public void addExtensionNamespace(String uri, ExtensionHandler extNS)
     95   {
     96     m_extensionFunctionNamespaces.put(uri, extNS);
     97   }
     98 
     99   /**
    100    * Execute the function-available() function.
    101    * @param ns       the URI of namespace in which the function is needed
    102    * @param funcName the function name being tested
    103    *
    104    * @return whether the given function is available or not.
    105    *
    106    * @throws javax.xml.transform.TransformerException
    107    */
    108   public boolean functionAvailable(String ns, String funcName)
    109           throws javax.xml.transform.TransformerException
    110   {
    111     boolean isAvailable = false;
    112 
    113     if (null != ns)
    114     {
    115       ExtensionHandler extNS =
    116            (ExtensionHandler) m_extensionFunctionNamespaces.get(ns);
    117       if (extNS != null)
    118         isAvailable = extNS.isFunctionAvailable(funcName);
    119     }
    120     return isAvailable;
    121   }
    122 
    123   /**
    124    * Execute the element-available() function.
    125    * @param ns       the URI of namespace in which the function is needed
    126    * @param elemName name of element being tested
    127    *
    128    * @return whether the given element is available or not.
    129    *
    130    * @throws javax.xml.transform.TransformerException
    131    */
    132   public boolean elementAvailable(String ns, String elemName)
    133           throws javax.xml.transform.TransformerException
    134   {
    135     boolean isAvailable = false;
    136     if (null != ns)
    137     {
    138       ExtensionHandler extNS =
    139                (ExtensionHandler) m_extensionFunctionNamespaces.get(ns);
    140       if (extNS != null) // defensive
    141         isAvailable = extNS.isElementAvailable(elemName);
    142     }
    143     return isAvailable;
    144   }
    145 
    146   /**
    147    * Handle an extension function.
    148    * @param ns        the URI of namespace in which the function is needed
    149    * @param funcName  the function name being called
    150    * @param argVec    arguments to the function in a vector
    151    * @param methodKey a unique key identifying this function instance in the
    152    *                  stylesheet
    153    * @param exprContext a context which may be passed to an extension function
    154    *                  and provides callback functions to access various
    155    *                  areas in the environment
    156    *
    157    * @return result of executing the function
    158    *
    159    * @throws javax.xml.transform.TransformerException
    160    */
    161   public Object extFunction(String ns, String funcName,
    162                             Vector argVec, Object methodKey,
    163                             ExpressionContext exprContext)
    164             throws javax.xml.transform.TransformerException
    165   {
    166     Object result = null;
    167     if (null != ns)
    168     {
    169       ExtensionHandler extNS =
    170         (ExtensionHandler) m_extensionFunctionNamespaces.get(ns);
    171       if (null != extNS)
    172       {
    173         try
    174         {
    175           result = extNS.callFunction(funcName, argVec, methodKey,
    176                                       exprContext);
    177         }
    178         catch (javax.xml.transform.TransformerException e)
    179         {
    180           throw e;
    181         }
    182         catch (Exception e)
    183         {
    184           throw new javax.xml.transform.TransformerException(e);
    185         }
    186       }
    187       else
    188       {
    189         throw new XPathProcessorException(XSLMessages.createMessage(XSLTErrorResources.ER_EXTENSION_FUNC_UNKNOWN, new Object[]{ns, funcName }));
    190         //"Extension function '" + ns + ":" + funcName + "' is unknown");
    191       }
    192     }
    193     return result;
    194   }
    195 
    196   /**
    197    * Handle an extension function.
    198    * @param extFunction  the extension function
    199    * @param argVec    arguments to the function in a vector
    200    * @param exprContext a context which may be passed to an extension function
    201    *                  and provides callback functions to access various
    202    *                  areas in the environment
    203    *
    204    * @return result of executing the function
    205    *
    206    * @throws javax.xml.transform.TransformerException
    207    */
    208   public Object extFunction(FuncExtFunction extFunction, Vector argVec,
    209                             ExpressionContext exprContext)
    210          throws javax.xml.transform.TransformerException
    211   {
    212     Object result = null;
    213     String ns = extFunction.getNamespace();
    214     if (null != ns)
    215     {
    216       ExtensionHandler extNS =
    217         (ExtensionHandler) m_extensionFunctionNamespaces.get(ns);
    218       if (null != extNS)
    219       {
    220         try
    221         {
    222           result = extNS.callFunction(extFunction, argVec, exprContext);
    223         }
    224         catch (javax.xml.transform.TransformerException e)
    225         {
    226           throw e;
    227         }
    228         catch (Exception e)
    229         {
    230           throw new javax.xml.transform.TransformerException(e);
    231         }
    232       }
    233       else
    234       {
    235         throw new XPathProcessorException(XSLMessages.createMessage(XSLTErrorResources.ER_EXTENSION_FUNC_UNKNOWN,
    236                                           new Object[]{ns, extFunction.getFunctionName()}));
    237       }
    238     }
    239     return result;
    240   }
    241 }
    242