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: ElemExtensionDecl.java 468643 2006-10-28 06:56:03Z minchau $ 020 */ 021 package org.apache.xalan.templates; 022 023 import javax.xml.transform.TransformerException; 024 025 import org.apache.xalan.extensions.ExtensionNamespaceSupport; 026 import org.apache.xalan.extensions.ExtensionNamespacesManager; 027 import org.apache.xalan.res.XSLMessages; 028 import org.apache.xalan.res.XSLTErrorResources; 029 import org.apache.xalan.transformer.TransformerImpl; 030 import org.apache.xml.utils.StringVector; 031 032 /** 033 * Implement the declaration of an extension element 034 * @xsl.usage internal 035 */ 036 public class ElemExtensionDecl extends ElemTemplateElement 037 { 038 static final long serialVersionUID = -4692738885172766789L; 039 040 /** 041 * Constructor ElemExtensionDecl 042 * 043 */ 044 public ElemExtensionDecl() 045 { 046 047 // System.out.println("ElemExtensionDecl ctor"); 048 } 049 050 /** Prefix string for this extension element. 051 * @serial */ 052 private String m_prefix = null; 053 054 /** 055 * Set the prefix for this extension element 056 * 057 * 058 * @param v Prefix to set for this extension element 059 */ 060 public void setPrefix(String v) 061 { 062 m_prefix = v; 063 } 064 065 /** 066 * Get the prefix for this extension element 067 * 068 * 069 * @return Prefix for this extension element 070 */ 071 public String getPrefix() 072 { 073 return m_prefix; 074 } 075 076 /** StringVector holding the names of functions defined in this extension. 077 * @serial */ 078 private StringVector m_functions = new StringVector(); 079 080 /** 081 * Set the names of functions defined in this extension 082 * 083 * 084 * @param v StringVector holding the names of functions defined in this extension 085 */ 086 public void setFunctions(StringVector v) 087 { 088 m_functions = v; 089 } 090 091 /** 092 * Get the names of functions defined in this extension 093 * 094 * 095 * @return StringVector holding the names of functions defined in this extension 096 */ 097 public StringVector getFunctions() 098 { 099 return m_functions; 100 } 101 102 /** 103 * Get a function at a given index in this extension element 104 * 105 * 106 * @param i Index of function to get 107 * 108 * @return Name of Function at given index 109 * 110 * @throws ArrayIndexOutOfBoundsException 111 */ 112 public String getFunction(int i) throws ArrayIndexOutOfBoundsException 113 { 114 115 if (null == m_functions) 116 throw new ArrayIndexOutOfBoundsException(); 117 118 return (String) m_functions.elementAt(i); 119 } 120 121 /** 122 * Get count of functions defined in this extension element 123 * 124 * 125 * @return count of functions defined in this extension element 126 */ 127 public int getFunctionCount() 128 { 129 return (null != m_functions) ? m_functions.size() : 0; 130 } 131 132 /** StringVector of elements defined in this extension. 133 * @serial */ 134 private StringVector m_elements = null; 135 136 /** 137 * Set StringVector of elements for this extension 138 * 139 * 140 * @param v StringVector of elements to set 141 */ 142 public void setElements(StringVector v) 143 { 144 m_elements = v; 145 } 146 147 /** 148 * Get StringVector of elements defined for this extension 149 * 150 * 151 * @return StringVector of elements defined for this extension 152 */ 153 public StringVector getElements() 154 { 155 return m_elements; 156 } 157 158 /** 159 * Get the element at the given index 160 * 161 * 162 * @param i Index of element to get 163 * 164 * @return The element at the given index 165 * 166 * @throws ArrayIndexOutOfBoundsException 167 */ 168 public String getElement(int i) throws ArrayIndexOutOfBoundsException 169 { 170 171 if (null == m_elements) 172 throw new ArrayIndexOutOfBoundsException(); 173 174 return (String) m_elements.elementAt(i); 175 } 176 177 /** 178 * Return the count of elements defined for this extension element 179 * 180 * 181 * @return the count of elements defined for this extension element 182 */ 183 public int getElementCount() 184 { 185 return (null != m_elements) ? m_elements.size() : 0; 186 } 187 188 /** 189 * Get an int constant identifying the type of element. 190 * @see org.apache.xalan.templates.Constants 191 * 192 * @return The token ID for this element 193 */ 194 public int getXSLToken() 195 { 196 return Constants.ELEMNAME_EXTENSIONDECL; 197 } 198 199 public void compose(StylesheetRoot sroot) throws TransformerException 200 { 201 super.compose(sroot); 202 String prefix = getPrefix(); 203 String declNamespace = getNamespaceForPrefix(prefix); 204 String lang = null; 205 String srcURL = null; 206 String scriptSrc = null; 207 if (null == declNamespace) 208 throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_NAMESPACE_DECL, new Object[]{prefix})); 209 //"Prefix " + prefix does not have a corresponding namespace declaration"); 210 for (ElemTemplateElement child = getFirstChildElem(); child != null; 211 child = child.getNextSiblingElem()) 212 { 213 if (Constants.ELEMNAME_EXTENSIONSCRIPT == child.getXSLToken()) 214 { 215 ElemExtensionScript sdecl = (ElemExtensionScript) child; 216 lang = sdecl.getLang(); 217 srcURL = sdecl.getSrc(); 218 ElemTemplateElement childOfSDecl = sdecl.getFirstChildElem(); 219 if (null != childOfSDecl) 220 { 221 if (Constants.ELEMNAME_TEXTLITERALRESULT 222 == childOfSDecl.getXSLToken()) 223 { 224 ElemTextLiteral tl = (ElemTextLiteral) childOfSDecl; 225 char[] chars = tl.getChars(); 226 scriptSrc = new String(chars); 227 if (scriptSrc.trim().length() == 0) 228 scriptSrc = null; 229 } 230 } 231 } 232 } 233 if (null == lang) 234 lang = "javaclass"; 235 if (lang.equals("javaclass") && (scriptSrc != null)) 236 throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_ELEM_CONTENT_NOT_ALLOWED, new Object[]{scriptSrc})); 237 //"Element content not allowed for lang=javaclass " + scriptSrc); 238 239 // Register the extension namespace if it has not already been registered. 240 ExtensionNamespaceSupport extNsSpt = null; 241 ExtensionNamespacesManager extNsMgr = sroot.getExtensionNamespacesManager(); 242 if (extNsMgr.namespaceIndex(declNamespace, 243 extNsMgr.getExtensions()) == -1) 244 { 245 if (lang.equals("javaclass")) 246 { 247 if (null == srcURL) 248 { 249 extNsSpt = extNsMgr.defineJavaNamespace(declNamespace); 250 } 251 else if (extNsMgr.namespaceIndex(srcURL, 252 extNsMgr.getExtensions()) == -1) 253 { 254 extNsSpt = extNsMgr.defineJavaNamespace(declNamespace, srcURL); 255 } 256 } 257 else // not java 258 { 259 String handler = "org.apache.xalan.extensions.ExtensionHandlerGeneral"; 260 Object [] args = {declNamespace, this.m_elements, this.m_functions, 261 lang, srcURL, scriptSrc, getSystemId()}; 262 extNsSpt = new ExtensionNamespaceSupport(declNamespace, handler, args); 263 } 264 } 265 if (extNsSpt != null) 266 extNsMgr.registerExtension(extNsSpt); 267 } 268 269 270 /** 271 * This function will be called on top-level elements 272 * only, just before the transform begins. 273 * 274 * @param transformer The XSLT TransformerFactory. 275 * 276 * @throws TransformerException 277 */ 278 public void runtimeInit(TransformerImpl transformer) throws TransformerException 279 { 280 /* //System.out.println("ElemExtensionDecl.runtimeInit()"); 281 String lang = null; 282 String srcURL = null; 283 String scriptSrc = null; 284 String prefix = getPrefix(); 285 String declNamespace = getNamespaceForPrefix(prefix); 286 287 if (null == declNamespace) 288 throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_NAMESPACE_DECL, new Object[]{prefix})); 289 //"Prefix " + prefix does not have a corresponding namespace declaration"); 290 291 for (ElemTemplateElement child = getFirstChildElem(); child != null; 292 child = child.getNextSiblingElem()) 293 { 294 if (Constants.ELEMNAME_EXTENSIONSCRIPT == child.getXSLToken()) 295 { 296 ElemExtensionScript sdecl = (ElemExtensionScript) child; 297 298 lang = sdecl.getLang(); 299 srcURL = sdecl.getSrc(); 300 301 ElemTemplateElement childOfSDecl = sdecl.getFirstChildElem(); 302 303 if (null != childOfSDecl) 304 { 305 if (Constants.ELEMNAME_TEXTLITERALRESULT 306 == childOfSDecl.getXSLToken()) 307 { 308 ElemTextLiteral tl = (ElemTextLiteral) childOfSDecl; 309 char[] chars = tl.getChars(); 310 311 scriptSrc = new String(chars); 312 313 if (scriptSrc.trim().length() == 0) 314 scriptSrc = null; 315 } 316 } 317 } 318 } 319 320 if (null == lang) 321 lang = "javaclass"; 322 323 if (lang.equals("javaclass") && (scriptSrc != null)) 324 throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_ELEM_CONTENT_NOT_ALLOWED, new Object[]{scriptSrc})); 325 //"Element content not allowed for lang=javaclass " + scriptSrc); 326 327 // Instantiate a handler for this extension namespace. 328 ExtensionsTable etable = transformer.getExtensionsTable(); 329 ExtensionHandler nsh = etable.get(declNamespace); 330 331 // If we have no prior ExtensionHandler for this namespace, we need to 332 // create one. 333 // If the script element is for javaclass, this is our special compiled java. 334 // Element content is not supported for this so we throw an exception if 335 // it is provided. Otherwise, we look up the srcURL to see if we already have 336 // an ExtensionHandler. 337 if (null == nsh) 338 { 339 if (lang.equals("javaclass")) 340 { 341 if (null == srcURL) 342 { 343 nsh = etable.makeJavaNamespace(declNamespace); 344 } 345 else 346 { 347 nsh = etable.get(srcURL); 348 349 if (null == nsh) 350 { 351 nsh = etable.makeJavaNamespace(srcURL); 352 } 353 } 354 } 355 else // not java 356 { 357 nsh = new ExtensionHandlerGeneral(declNamespace, this.m_elements, 358 this.m_functions, lang, srcURL, 359 scriptSrc, getSystemId()); 360 361 // System.out.println("Adding NS Handler: declNamespace = "+ 362 // declNamespace+", lang = "+lang+", srcURL = "+ 363 // srcURL+", scriptSrc="+scriptSrc); 364 } 365 366 etable.addExtensionNamespace(declNamespace, nsh); 367 }*/ 368 } 369 }