/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id$
 */
package org.apache.xalan.extensions;

import java.util.Vector;

import org.apache.xalan.templates.Constants;

/**
 * Used during assembly of a stylesheet to collect the information for each 
 * extension namespace that is required during the transformation process 
 * to generate an {@link ExtensionHandler}.
 * 
 */
public class ExtensionNamespacesManager
{
  /**
   * Vector of ExtensionNamespaceSupport objects to be used to generate ExtensionHandlers.
   */
  private Vector m_extensions = new Vector();
  /**
   * Vector of ExtensionNamespaceSupport objects for predefined ExtensionNamespaces. Elements
   * from this vector are added to the m_extensions vector when encountered in the stylesheet.
   */
  private Vector m_predefExtensions = new Vector(7);
  /**
   * Vector of extension namespaces for which sufficient information is not yet available to
   * complete the registration process.
   */
  private Vector m_unregisteredExtensions = new Vector();
  
  /**
   * An ExtensionNamespacesManager is instantiated the first time an extension function or
   * element is found in the stylesheet. During initialization, a vector of ExtensionNamespaceSupport
   * objects is created, one for each predefined extension namespace.
   */
  public ExtensionNamespacesManager()
  {
    setPredefinedNamespaces();
  }
  
  /**
   * If necessary, register the extension namespace found compiling a function or 
   * creating an extension element. 
   * 
   * If it is a predefined namespace, create a
   * support object to simplify the instantiate of an appropriate ExtensionHandler
   * during transformation runtime. Otherwise, add the namespace, if necessary,
   * to a vector of undefined extension namespaces, to be defined later.
   * 
   */
  public void registerExtension(String namespace)
  {
    if (namespaceIndex(namespace, m_extensions) == -1)
    {
      int predef = namespaceIndex(namespace, m_predefExtensions);
      if (predef !=-1)
        m_extensions.add(m_predefExtensions.get(predef));
      else if (!(m_unregisteredExtensions.contains(namespace)))
        m_unregisteredExtensions.add(namespace);       
    }
  }
  
  /**
   * Register the extension namespace for an ElemExtensionDecl or ElemFunction,
   * and prepare a support object to launch the appropriate ExtensionHandler at 
   * transformation runtime.
   */  
  public void registerExtension(ExtensionNamespaceSupport extNsSpt)
  {
    String namespace = extNsSpt.getNamespace();
    if (namespaceIndex(namespace, m_extensions) == -1)
    {
      m_extensions.add(extNsSpt);
      if (m_unregisteredExtensions.contains(namespace))
        m_unregisteredExtensions.remove(namespace);
    }
    
  }
  
  /**
   * Get the index for a namespace entry in the extension namespace Vector, -1 if
   * no such entry yet exists.
   */
  public int namespaceIndex(String namespace, Vector extensions)
  {
    for (int i = 0; i < extensions.size(); i++)
    {
      if (((ExtensionNamespaceSupport)extensions.get(i)).getNamespace().equals(namespace))
        return i;
    }
    return -1;
  }
  
    
  /**
   * Get the vector of extension namespaces. Used to provide
   * the extensions table access to a list of extension
   * namespaces encountered during composition of a stylesheet.
   */
  public Vector getExtensions()
  {
    return m_extensions;
  }
  
  /**
   * Attempt to register any unregistered extension namespaces.
   */
  public void registerUnregisteredNamespaces()
  {
    for (int i = 0; i < m_unregisteredExtensions.size(); i++)
    {
      String ns = (String)m_unregisteredExtensions.get(i);
      ExtensionNamespaceSupport extNsSpt = defineJavaNamespace(ns);
      if (extNsSpt != null)
        m_extensions.add(extNsSpt);
    }    
  }
  
    /**
   * For any extension namespace that is not either predefined or defined 
   * by a "component" declaration or exslt function declaration, attempt 
   * to create an ExtensionNamespaceSuport object for the appropriate 
   * Java class or Java package Extension Handler.
   * 
   * Called by StylesheetRoot.recompose(), after all ElemTemplate compose()
   * operations have taken place, in order to set up handlers for
   * the remaining extension namespaces.
   * 
   * @param ns The extension namespace URI.
   * @return   An ExtensionNamespaceSupport object for this namespace
   * (which defines the ExtensionHandler to be used), or null if such 
   * an object cannot be created. 
   *
   * @throws javax.xml.transform.TransformerException
   */
  public ExtensionNamespaceSupport defineJavaNamespace(String ns)
  {
    return defineJavaNamespace(ns, ns);
  }
  public ExtensionNamespaceSupport defineJavaNamespace(String ns, String classOrPackage)
  {
    if(null == ns || ns.trim().length() == 0) // defensive. I don't think it's needed.  -sb
      return null;

    // Prepare the name of the actual class or package, stripping
    // out any leading "class:".  Next, see if there is a /.  If so,
    // only look at the text to the right of the rightmost /.
    String className = classOrPackage;
    if (className.startsWith("class:"))
      className = className.substring(6);

    int lastSlash = className.lastIndexOf("/");
    if (-1 != lastSlash)
      className = className.substring(lastSlash + 1);
      
    // The className can be null here, and can cause an error in getClassForName
    // in JDK 1.8.
    if(null == className || className.trim().length() == 0) 
      return null;
    
    try
    {
      ExtensionHandler.getClassForName(className);
      return new ExtensionNamespaceSupport(
                           ns, 
                           "org.apache.xalan.extensions.ExtensionHandlerJavaClass",                                         
                           new Object[]{ns, "javaclass", className});
    }
    catch (ClassNotFoundException e)
    {
      return new ExtensionNamespaceSupport(
                            ns, 
                            "org.apache.xalan.extensions.ExtensionHandlerJavaPackage",
                            new Object[]{ns, "javapackage", className + "."});
    }
  }
  
/*
  public ExtensionNamespaceSupport getSupport(int index, Vector extensions)
  {
    return (ExtensionNamespaceSupport)extensions.elementAt(index);
  }
*/
  
  
  /**
   * Set up a Vector for predefined extension namespaces.
   */
  private void setPredefinedNamespaces()
  {    
    String uri = Constants.S_EXTENSIONS_JAVA_URL;
    String handlerClassName = "org.apache.xalan.extensions.ExtensionHandlerJavaPackage";
    String lang = "javapackage";
    String lib = "";
    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
                                             new Object[]{uri, lang, lib}));
   
    uri = Constants.S_EXTENSIONS_OLD_JAVA_URL;
    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
                                             new Object[]{uri, lang, lib}));
    
    uri = Constants.S_EXTENSIONS_LOTUSXSL_JAVA_URL;
    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
                                             new Object[]{uri, lang, lib}));
    
    uri = Constants.S_BUILTIN_EXTENSIONS_URL;
    handlerClassName = "org.apache.xalan.extensions.ExtensionHandlerJavaClass";
    lang = "javaclass"; // for remaining predefined extension namespaces.    
    lib = "org.apache.xalan.lib.Extensions";
    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
                                             new Object[]{uri, lang, lib}));
    
    uri = Constants.S_BUILTIN_OLD_EXTENSIONS_URL;
    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
                                             new Object[]{uri, lang, lib}));
    
    // Xalan extension namespaces (redirect, pipe and SQL).
    uri = Constants.S_EXTENSIONS_REDIRECT_URL;
    lib = "org.apache.xalan.lib.Redirect";
    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
                                             new Object[]{uri, lang, lib}));
 
    uri = Constants.S_EXTENSIONS_PIPE_URL;
    lib = "org.apache.xalan.lib.PipeDocument";
    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
                                             new Object[]{uri, lang, lib}));
 
    uri = Constants.S_EXTENSIONS_SQL_URL;
    lib = "org.apache.xalan.lib.sql.XConnection";
    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
                                             new Object[]{uri, lang, lib}));
 
    
    //EXSLT namespaces (not including EXSLT function namespaces which are
    // registered by the associated ElemFunction.
    uri = Constants.S_EXSLT_COMMON_URL;
    lib = "org.apache.xalan.lib.ExsltCommon";
    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
                                             new Object[]{uri, lang, lib}));

    uri = Constants.S_EXSLT_MATH_URL;
    lib = "org.apache.xalan.lib.ExsltMath";
    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
                                             new Object[]{uri, lang, lib}));
    
    uri = Constants.S_EXSLT_SETS_URL;
    lib = "org.apache.xalan.lib.ExsltSets";
    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
                                             new Object[]{uri, lang, lib}));
    
    uri = Constants.S_EXSLT_DATETIME_URL;
    lib = "org.apache.xalan.lib.ExsltDatetime";
    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
                                             new Object[]{uri, lang, lib}));
                                             
    uri = Constants.S_EXSLT_DYNAMIC_URL;
    lib = "org.apache.xalan.lib.ExsltDynamic";
    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
                                             new Object[]{uri, lang, lib}));

    uri = Constants.S_EXSLT_STRINGS_URL;
    lib = "org.apache.xalan.lib.ExsltStrings";
    m_predefExtensions.add(new ExtensionNamespaceSupport(uri, handlerClassName,
                                             new Object[]{uri, lang, lib}));                                             
  }    
  
}
