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: ExtensionNamespacesManager.java 469672 2006-10-31 21:56:19Z minchau $
     20  */
     21 package org.apache.xalan.extensions;
     22 
     23 import java.util.Vector;
     24 
     25 import org.apache.xalan.templates.Constants;
     26 
     27 /**
     28  * Used during assembly of a stylesheet to collect the information for each
     29  * extension namespace that is required during the transformation process
     30  * to generate an {@link ExtensionHandler}.
     31  *
     32  */
     33 public class ExtensionNamespacesManager
     34 {
     35   /**
     36    * Vector of ExtensionNamespaceSupport objects to be used to generate ExtensionHandlers.
     37    */
     38   private Vector m_extensions = new Vector();
     39   /**
     40    * Vector of ExtensionNamespaceSupport objects for predefined ExtensionNamespaces. Elements
     41    * from this vector are added to the m_extensions vector when encountered in the stylesheet.
     42    */
     43   private Vector m_predefExtensions = new Vector(7);
     44   /**
     45    * Vector of extension namespaces for which sufficient information is not yet available to
     46    * complete the registration process.
     47    */
     48   private Vector m_unregisteredExtensions = new Vector();
     49 
     50   /**
     51    * An ExtensionNamespacesManager is instantiated the first time an extension function or
     52    * element is found in the stylesheet. During initialization, a vector of ExtensionNamespaceSupport
     53    * objects is created, one for each predefined extension namespace.
     54    */
     55   public ExtensionNamespacesManager()
     56   {
     57     setPredefinedNamespaces();
     58   }
     59 
     60   /**
     61    * If necessary, register the extension namespace found compiling a function or
     62    * creating an extension element.
     63    *
     64    * If it is a predefined namespace, create a
     65    * support object to simplify the instantiate of an appropriate ExtensionHandler
     66    * during transformation runtime. Otherwise, add the namespace, if necessary,
     67    * to a vector of undefined extension namespaces, to be defined later.
     68    *
     69    */
     70   public void registerExtension(String namespace)
     71   {
     72     if (namespaceIndex(namespace, m_extensions) == -1)
     73     {
     74       int predef = namespaceIndex(namespace, m_predefExtensions);
     75       if (predef !=-1)
     76         m_extensions.add(m_predefExtensions.get(predef));
     77       else if (!(m_unregisteredExtensions.contains(namespace)))
     78         m_unregisteredExtensions.add(namespace);
     79     }
     80   }
     81 
     82   /**
     83    * Register the extension namespace for an ElemExtensionDecl or ElemFunction,
     84    * and prepare a support object to launch the appropriate ExtensionHandler at
     85    * transformation runtime.
     86    */
     87   public void registerExtension(ExtensionNamespaceSupport extNsSpt)
     88   {
     89     String namespace = extNsSpt.getNamespace();
     90     if (namespaceIndex(namespace, m_extensions) == -1)
     91     {
     92       m_extensions.add(extNsSpt);
     93       if (m_unregisteredExtensions.contains(namespace))
     94         m_unregisteredExtensions.remove(namespace);
     95     }
     96 
     97   }
     98 
     99   /**
    100    * Get the index for a namespace entry in the extension namespace Vector, -1 if
    101    * no such entry yet exists.
    102    */
    103   public int namespaceIndex(String namespace, Vector extensions)
    104   {
    105     for (int i = 0; i < extensions.size(); i++)
    106     {
    107       if (((ExtensionNamespaceSupport)extensions.get(i)).getNamespace().equals(namespace))
    108         return i;
    109     }
    110     return -1;
    111   }
    112 
    113 
    114   /**
    115    * Get the vector of extension namespaces. Used to provide
    116    * the extensions table access to a list of extension
    117    * namespaces encountered during composition of a stylesheet.
    118    */
    119   public Vector getExtensions()
    120   {
    121     return m_extensions;
    122   }
    123 
    124   /**
    125    * Attempt to register any unregistered extension namespaces.
    126    */
    127   public void registerUnregisteredNamespaces()
    128   {
    129     for (int i = 0; i < m_unregisteredExtensions.size(); i++)
    130     {
    131       String ns = (String)m_unregisteredExtensions.get(i);
    132       ExtensionNamespaceSupport extNsSpt = defineJavaNamespace(ns);
    133       if (extNsSpt != null)
    134         m_extensions.add(extNsSpt);
    135     }
    136   }
    137 
    138     /**
    139    * For any extension namespace that is not either predefined or defined
    140    * by a "component" declaration or exslt function declaration, attempt
    141    * to create an ExtensionNamespaceSuport object for the appropriate
    142    * Java class or Java package Extension Handler.
    143    *
    144    * Called by StylesheetRoot.recompose(), after all ElemTemplate compose()
    145    * operations have taken place, in order to set up handlers for
    146    * the remaining extension namespaces.
    147    *
    148    * @param ns The extension namespace URI.
    149    * @return   An ExtensionNamespaceSupport object for this namespace
    150    * (which defines the ExtensionHandler to be used), or null if such
    151    * an object cannot be created.
    152    *
    153    * @throws javax.xml.transform.TransformerException
    154    */
    155   public ExtensionNamespaceSupport defineJavaNamespace(String ns)
    156   {
    157     return defineJavaNamespace(ns, ns);
    158   }
    159   public ExtensionNamespaceSupport defineJavaNamespace(String ns, String classOrPackage)
    160   {
    161     if(null == ns || ns.trim().length() == 0) // defensive. I don't think it's needed.  -sb
    162       return null;
    163 
    164     // Prepare the name of the actual class or package, stripping
    165     // out any leading "class:".  Next, see if there is a /.  If so,
    166     // only look at the text to the right of the rightmost /.
    167     String className = classOrPackage;
    168     if (className.startsWith("class:"))
    169       className = className.substring(6);
    170 
    171     int lastSlash = className.lastIndexOf("/");
    172     if (-1 != lastSlash)
    173       className = className.substring(lastSlash + 1);
    174 
    175     // The className can be null here, and can cause an error in getClassForName
    176     // in JDK 1.8.
    177     if(null == className || className.trim().length() == 0)
    178       return null;
    179 
    180     try
    181     {
    182       ExtensionHandler.getClassForName(className);
    183       return new ExtensionNamespaceSupport(
    184                            ns,
    185                            "org.apache.xalan.extensions.ExtensionHandlerJavaClass",
    186                            new Object[]{ns, "javaclass", className});
    187     }
    188     catch (ClassNotFoundException e)
    189     {
    190       return new ExtensionNamespaceSupport(
    191                             ns,
    192                             "org.apache.xalan.extensions.ExtensionHandlerJavaPackage",
    193                             new Object[]{ns, "javapackage", className + "."});
    194     }
    195   }
    196 
    197 /*
    198   public ExtensionNamespaceSupport getSupport(int index, Vector extensions)
    199   {
    200     return (ExtensionNamespaceSupport)extensions.elementAt(index);
    201   }
    202 */
    203 
    204 
    205   /**
    206    * Set up a Vector for predefined extension namespaces.
    207    */
    208   private void setPredefinedNamespaces()
    209   {
    210     String uri = Constants.S_EXTENSIONS_JAVA_URL;
    211     String handlerClassName = "org.apache.xalan.extensions.ExtensionHandlerJavaPackage";
    212     String lang = "javapackage";
    213     String lib = "";
    214     m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
    215                                              new Object[]{uri, lang, lib}));
    216 
    217     uri = Constants.S_EXTENSIONS_OLD_JAVA_URL;
    218     m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
    219                                              new Object[]{uri, lang, lib}));
    220 
    221     uri = Constants.S_EXTENSIONS_LOTUSXSL_JAVA_URL;
    222     m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
    223                                              new Object[]{uri, lang, lib}));
    224 
    225     uri = Constants.S_BUILTIN_EXTENSIONS_URL;
    226     handlerClassName = "org.apache.xalan.extensions.ExtensionHandlerJavaClass";
    227     lang = "javaclass"; // for remaining predefined extension namespaces.
    228     lib = "org.apache.xalan.lib.Extensions";
    229     m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
    230                                              new Object[]{uri, lang, lib}));
    231 
    232     uri = Constants.S_BUILTIN_OLD_EXTENSIONS_URL;
    233     m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
    234                                              new Object[]{uri, lang, lib}));
    235 
    236     // Xalan extension namespaces (redirect, pipe and SQL).
    237     uri = Constants.S_EXTENSIONS_REDIRECT_URL;
    238     lib = "org.apache.xalan.lib.Redirect";
    239     m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
    240                                              new Object[]{uri, lang, lib}));
    241 
    242     uri = Constants.S_EXTENSIONS_PIPE_URL;
    243     lib = "org.apache.xalan.lib.PipeDocument";
    244     m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
    245                                              new Object[]{uri, lang, lib}));
    246 
    247     uri = Constants.S_EXTENSIONS_SQL_URL;
    248     lib = "org.apache.xalan.lib.sql.XConnection";
    249     m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
    250                                              new Object[]{uri, lang, lib}));
    251 
    252 
    253     //EXSLT namespaces (not including EXSLT function namespaces which are
    254     // registered by the associated ElemFunction.
    255     uri = Constants.S_EXSLT_COMMON_URL;
    256     lib = "org.apache.xalan.lib.ExsltCommon";
    257     m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
    258                                              new Object[]{uri, lang, lib}));
    259 
    260     uri = Constants.S_EXSLT_MATH_URL;
    261     lib = "org.apache.xalan.lib.ExsltMath";
    262     m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
    263                                              new Object[]{uri, lang, lib}));
    264 
    265     uri = Constants.S_EXSLT_SETS_URL;
    266     lib = "org.apache.xalan.lib.ExsltSets";
    267     m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
    268                                              new Object[]{uri, lang, lib}));
    269 
    270     uri = Constants.S_EXSLT_DATETIME_URL;
    271     lib = "org.apache.xalan.lib.ExsltDatetime";
    272     m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
    273                                              new Object[]{uri, lang, lib}));
    274 
    275     uri = Constants.S_EXSLT_DYNAMIC_URL;
    276     lib = "org.apache.xalan.lib.ExsltDynamic";
    277     m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
    278                                              new Object[]{uri, lang, lib}));
    279 
    280     uri = Constants.S_EXSLT_STRINGS_URL;
    281     lib = "org.apache.xalan.lib.ExsltStrings";
    282     m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
    283                                              new Object[]{uri, lang, lib}));
    284   }
    285 
    286 }
    287