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 }