001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 /* 019 * $Id: ExtensionNamespacesManager.java 1225575 2011-12-29 15:50:25Z mrglavas $ 020 */ 021 package org.apache.xalan.extensions; 022 023 import java.util.Vector; 024 025 import org.apache.xalan.templates.Constants; 026 027 /** 028 * Used during assembly of a stylesheet to collect the information for each 029 * extension namespace that is required during the transformation process 030 * to generate an {@link ExtensionHandler}. 031 * 032 */ 033 public class ExtensionNamespacesManager 034 { 035 /** 036 * Vector of ExtensionNamespaceSupport objects to be used to generate ExtensionHandlers. 037 */ 038 private Vector m_extensions = new Vector(); 039 /** 040 * Vector of ExtensionNamespaceSupport objects for predefined ExtensionNamespaces. Elements 041 * from this vector are added to the m_extensions vector when encountered in the stylesheet. 042 */ 043 private Vector m_predefExtensions = new Vector(7); 044 /** 045 * Vector of extension namespaces for which sufficient information is not yet available to 046 * complete the registration process. 047 */ 048 private Vector m_unregisteredExtensions = new Vector(); 049 050 /** 051 * An ExtensionNamespacesManager is instantiated the first time an extension function or 052 * element is found in the stylesheet. During initialization, a vector of ExtensionNamespaceSupport 053 * objects is created, one for each predefined extension namespace. 054 */ 055 public ExtensionNamespacesManager() 056 { 057 setPredefinedNamespaces(); 058 } 059 060 /** 061 * If necessary, register the extension namespace found compiling a function or 062 * creating an extension element. 063 * 064 * If it is a predefined namespace, create a 065 * support object to simplify the instantiate of an appropriate ExtensionHandler 066 * during transformation runtime. Otherwise, add the namespace, if necessary, 067 * to a vector of undefined extension namespaces, to be defined later. 068 * 069 */ 070 public void registerExtension(String namespace) 071 { 072 if (namespaceIndex(namespace, m_extensions) == -1) 073 { 074 int predef = namespaceIndex(namespace, m_predefExtensions); 075 if (predef !=-1) 076 m_extensions.add(m_predefExtensions.get(predef)); 077 else if (!(m_unregisteredExtensions.contains(namespace))) 078 m_unregisteredExtensions.add(namespace); 079 } 080 } 081 082 /** 083 * Register the extension namespace for an ElemExtensionDecl or ElemFunction, 084 * and prepare a support object to launch the appropriate ExtensionHandler at 085 * transformation runtime. 086 */ 087 public void registerExtension(ExtensionNamespaceSupport extNsSpt) 088 { 089 String namespace = extNsSpt.getNamespace(); 090 if (namespaceIndex(namespace, m_extensions) == -1) 091 { 092 m_extensions.add(extNsSpt); 093 if (m_unregisteredExtensions.contains(namespace)) 094 m_unregisteredExtensions.remove(namespace); 095 } 096 097 } 098 099 /** 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 }