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 */ ExtensionNamespacesManager()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 */ registerExtension(String namespace)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 */ registerExtension(ExtensionNamespaceSupport extNsSpt)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 */ namespaceIndex(String namespace, Vector extensions)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 */ getExtensions()119 public Vector getExtensions() 120 { 121 return m_extensions; 122 } 123 124 /** 125 * Attempt to register any unregistered extension namespaces. 126 */ registerUnregisteredNamespaces()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 */ defineJavaNamespace(String ns)155 public ExtensionNamespaceSupport defineJavaNamespace(String ns) 156 { 157 return defineJavaNamespace(ns, ns); 158 } defineJavaNamespace(String ns, String classOrPackage)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 */ setPredefinedNamespaces()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