KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xalan > extensions > ExtensionHandlerGeneral


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: ExtensionHandlerGeneral.java,v 1.23 2004/02/23 10:29:34 aruny Exp $
18  */

19 package org.apache.xalan.extensions;
20
21 import java.io.IOException JavaDoc;
22 import java.io.InputStream JavaDoc;
23 import java.lang.reflect.Method JavaDoc;
24 import java.net.URL JavaDoc;
25 import java.net.URLConnection JavaDoc;
26 import java.util.Hashtable JavaDoc;
27 import java.util.Vector JavaDoc;
28
29 import javax.xml.transform.TransformerException JavaDoc;
30
31 import org.apache.xalan.res.XSLMessages;
32 import org.apache.xalan.res.XSLTErrorResources;
33 import org.apache.xalan.templates.ElemTemplateElement;
34 import org.apache.xalan.templates.Stylesheet;
35 import org.apache.xalan.transformer.TransformerImpl;
36 import org.apache.xml.dtm.DTMIterator;
37 import org.apache.xml.dtm.ref.DTMNodeList;
38 import org.apache.xml.utils.StringVector;
39 import org.apache.xml.utils.SystemIDResolver;
40 import org.apache.xpath.XPathProcessorException;
41 import org.apache.xpath.functions.FuncExtFunction;
42 import org.apache.xpath.objects.XObject;
43
44 /**
45  * Class handling an extension namespace for XPath. Provides functions
46  * to test a function's existence and call a function
47  *
48  * @author Sanjiva Weerawarana (sanjiva@watson.ibm.com)
49  * @xsl.usage internal
50  */

51 public class ExtensionHandlerGeneral extends ExtensionHandler
52 {
53
54   /** script source to run (if any) */
55   private String JavaDoc m_scriptSrc;
56
57   /** URL of source of script (if any) */
58   private String JavaDoc m_scriptSrcURL;
59
60   /** functions of namespace */
61   private Hashtable JavaDoc m_functions = new Hashtable JavaDoc();
62
63   /** elements of namespace */
64   private Hashtable JavaDoc m_elements = new Hashtable JavaDoc();
65
66   // BSF objects used to invoke BSF by reflection. Do not import the BSF classes
67
// since we don't want a compile dependency on BSF.
68

69   /** BSF manager used to run scripts */
70   private Object JavaDoc m_engine;
71
72   /** Engine call to invoke scripts */
73   private Method JavaDoc m_engineCall = null;
74
75   // static fields
76

77   /** BSFManager package name */
78   private static final String JavaDoc BSF_MANAGER = "com.ibm.bsf.BSFManager";
79
80   /** BSFEngine package name */
81   private static final String JavaDoc BSF_ENGINE = "com.ibm.bsf.BSFEngine";
82
83   /** Negative one integer */
84   private static final Integer JavaDoc NEG1INT = new Integer JavaDoc(-1);
85
86   /**
87    * Construct a new extension namespace handler given all the information
88    * needed.
89    *
90    * @param namespaceUri the extension namespace URI that I'm implementing
91    * @param elemNames Vector of element names
92    * @param funcNames string containing list of functions of extension NS
93    * @param lang language of code implementing the extension
94    * @param srcURL value of src attribute (if any) - treated as a URL
95    * or a classname depending on the value of lang. If
96    * srcURL is not null, then scriptSrc is ignored.
97    * @param scriptLang Scripting language of implementation
98    * @param scriptSrcURL URL of source script
99    * @param scriptSrc the actual script code (if any)
100    *
101    * @throws TransformerException
102    */

103   public ExtensionHandlerGeneral(
104           String JavaDoc namespaceUri, StringVector elemNames, StringVector funcNames, String JavaDoc scriptLang, String JavaDoc scriptSrcURL, String JavaDoc scriptSrc, String JavaDoc systemId)
105             throws TransformerException JavaDoc
106   {
107
108     super(namespaceUri, scriptLang);
109
110     if (elemNames != null)
111     {
112       Object JavaDoc junk = new Object JavaDoc();
113       int n = elemNames.size();
114
115       for (int i = 0; i < n; i++)
116       {
117         String JavaDoc tok = elemNames.elementAt(i);
118
119         m_elements.put(tok, junk); // just stick it in there basically
120
}
121     }
122
123     if (funcNames != null)
124     {
125       Object JavaDoc junk = new Object JavaDoc();
126       int n = funcNames.size();
127
128       for (int i = 0; i < n; i++)
129       {
130         String JavaDoc tok = funcNames.elementAt(i);
131
132         m_functions.put(tok, junk); // just stick it in there basically
133
}
134     }
135
136     m_scriptSrcURL = scriptSrcURL;
137     m_scriptSrc = scriptSrc;
138
139     if (m_scriptSrcURL != null)
140     {
141       URL JavaDoc url = null;
142       try{
143         url = new URL JavaDoc(m_scriptSrcURL);
144       }
145       catch (java.net.MalformedURLException JavaDoc mue)
146       {
147         int indexOfColon = m_scriptSrcURL.indexOf(':');
148         int indexOfSlash = m_scriptSrcURL.indexOf('/');
149
150         if ((indexOfColon != -1) && (indexOfSlash != -1)
151             && (indexOfColon < indexOfSlash))
152         {
153           // The url is absolute.
154
url = null;
155           throw new TransformerException JavaDoc(XSLMessages.createMessage(XSLTErrorResources.ER_COULD_NOT_FIND_EXTERN_SCRIPT, new Object JavaDoc[]{m_scriptSrcURL}), mue); //"src attribute not yet supported for "
156
//+ scriptLang);
157
}
158         else
159         {
160           try{
161             url = new URL JavaDoc(new URL JavaDoc(SystemIDResolver.getAbsoluteURI(systemId)), m_scriptSrcURL);
162           }
163           catch (java.net.MalformedURLException JavaDoc mue2)
164           {
165             throw new TransformerException JavaDoc(XSLMessages.createMessage(XSLTErrorResources.ER_COULD_NOT_FIND_EXTERN_SCRIPT, new Object JavaDoc[]{m_scriptSrcURL}), mue2); //"src attribute not yet supported for "
166
//+ scriptLang);
167
}
168         }
169       }
170       if (url != null)
171       {
172         try
173         {
174           URLConnection JavaDoc uc = url.openConnection();
175           InputStream JavaDoc is = uc.getInputStream();
176           byte []bArray = new byte[uc.getContentLength()];
177           is.read(bArray);
178           m_scriptSrc = new String JavaDoc(bArray);
179           
180         }
181         catch (IOException JavaDoc ioe)
182         {
183           throw new TransformerException JavaDoc(XSLMessages.createMessage(XSLTErrorResources.ER_COULD_NOT_FIND_EXTERN_SCRIPT, new Object JavaDoc[]{m_scriptSrcURL}), ioe); //"src attribute not yet supported for "
184
//+ scriptLang);
185
}
186       }
187       
188     }
189
190     Object JavaDoc manager = null;
191     try
192     {
193       manager = ObjectFactory.newInstance(
194         BSF_MANAGER, ObjectFactory.findClassLoader(), true);
195     }
196     catch (ObjectFactory.ConfigurationError e)
197     {
198       e.printStackTrace();
199     }
200
201     if (manager == null)
202     {
203       throw new TransformerException JavaDoc(XSLMessages.createMessage(XSLTErrorResources.ER_CANNOT_INIT_BSFMGR, null)); //"Could not initialize BSF manager");
204
}
205
206     try
207     {
208       Method JavaDoc loadScriptingEngine = manager.getClass()
209         .getMethod("loadScriptingEngine", new Class JavaDoc[]{ String JavaDoc.class });
210
211       m_engine = loadScriptingEngine.invoke(manager,
212         new Object JavaDoc[]{ scriptLang });
213
214       Method JavaDoc engineExec = m_engine.getClass().getMethod("exec",
215         new Class JavaDoc[]{ String JavaDoc.class, Integer.TYPE, Integer.TYPE, Object JavaDoc.class });
216
217       // "Compile" the program
218
engineExec.invoke(m_engine,
219         new Object JavaDoc[]{ "XalanScript", NEG1INT, NEG1INT, m_scriptSrc });
220     }
221     catch (Exception JavaDoc e)
222     {
223       e.printStackTrace();
224
225       throw new TransformerException JavaDoc(XSLMessages.createMessage(XSLTErrorResources.ER_CANNOT_CMPL_EXTENSN, null), e); //"Could not compile extension", e);
226
}
227   }
228
229   /**
230    * Tests whether a certain function name is known within this namespace.
231    * @param function name of the function being tested
232    * @return true if its known, false if not.
233    */

234   public boolean isFunctionAvailable(String JavaDoc function)
235   {
236     return (m_functions.get(function) != null);
237   }
238
239   /**
240    * Tests whether a certain element name is known within this namespace.
241    * @param function name of the function being tested
242    *
243    * @param element name of the element being tested
244    * @return true if its known, false if not.
245    */

246   public boolean isElementAvailable(String JavaDoc element)
247   {
248     return (m_elements.get(element) != null);
249   }
250
251   /**
252    * Process a call to a function.
253    *
254    * @param funcName Function name.
255    * @param args The arguments of the function call.
256    * @param methodKey A key that uniquely identifies this class and method call.
257    * @param exprContext The context in which this expression is being executed.
258    *
259    * @return the return value of the function evaluation.
260    *
261    * @throws TransformerException if parsing trouble
262    */

263   public Object JavaDoc callFunction(
264           String JavaDoc funcName, Vector JavaDoc args, Object JavaDoc methodKey, ExpressionContext exprContext)
265             throws TransformerException JavaDoc
266   {
267
268     Object JavaDoc[] argArray;
269
270     try
271     {
272       argArray = new Object JavaDoc[args.size()];
273
274       for (int i = 0; i < argArray.length; i++)
275       {
276         Object JavaDoc o = args.elementAt(i);
277
278         argArray[i] = (o instanceof XObject) ? ((XObject) o).object() : o;
279         o = argArray[i];
280         if(null != o && o instanceof DTMIterator)
281         {
282           argArray[i] = new DTMNodeList((DTMIterator)o);
283         }
284       }
285
286       if (m_engineCall == null) {
287         m_engineCall = m_engine.getClass().getMethod("call",
288           new Class JavaDoc[]{ Object JavaDoc.class, String JavaDoc.class, Object JavaDoc[].class });
289       }
290
291       return m_engineCall.invoke(m_engine,
292         new Object JavaDoc[]{ null, funcName, argArray });
293     }
294     catch (Exception JavaDoc e)
295     {
296       e.printStackTrace();
297
298       String JavaDoc msg = e.getMessage();
299
300       if (null != msg)
301       {
302         if (msg.startsWith("Stopping after fatal error:"))
303         {
304           msg = msg.substring("Stopping after fatal error:".length());
305         }
306
307         // System.out.println("Call to extension function failed: "+msg);
308
throw new TransformerException JavaDoc(e);
309       }
310       else
311       {
312
313         // Should probably make a TRaX Extension Exception.
314
throw new TransformerException JavaDoc(XSLMessages.createMessage(XSLTErrorResources.ER_CANNOT_CREATE_EXTENSN, new Object JavaDoc[]{funcName, e })); //"Could not create extension: " + funcName
315
//+ " because of: " + e);
316
}
317     }
318   }
319
320   /**
321    * Process a call to an XPath extension function
322    *
323    * @param extFunction The XPath extension function
324    * @param args The arguments of the function call.
325    * @param exprContext The context in which this expression is being executed.
326    * @return the return value of the function evaluation.
327    * @throws TransformerException
328    */

329   public Object JavaDoc callFunction(FuncExtFunction extFunction,
330                              Vector JavaDoc args,
331                              ExpressionContext exprContext)
332       throws TransformerException JavaDoc
333   {
334     return callFunction(extFunction.getFunctionName(), args,
335                         extFunction.getMethodKey(), exprContext);
336   }
337
338   /**
339    * Process a call to this extension namespace via an element. As a side
340    * effect, the results are sent to the TransformerImpl's result tree.
341    *
342    * @param localPart Element name's local part.
343    * @param element The extension element being processed.
344    * @param transformer Handle to TransformerImpl.
345    * @param stylesheetTree The compiled stylesheet tree.
346    * @param mode The current mode.
347    * @param sourceTree The root of the source tree (but don't assume
348    * it's a Document).
349    * @param sourceNode The current context node.
350    * @param methodKey A key that uniquely identifies this class and method call.
351    *
352    * @throws XSLProcessorException thrown if something goes wrong
353    * while running the extension handler.
354    * @throws MalformedURLException if loading trouble
355    * @throws FileNotFoundException if loading trouble
356    * @throws IOException if loading trouble
357    * @throws TransformerException if parsing trouble
358    */

359   public void processElement(
360           String JavaDoc localPart, ElemTemplateElement element, TransformerImpl transformer,
361           Stylesheet stylesheetTree, Object JavaDoc methodKey)
362             throws TransformerException JavaDoc, IOException JavaDoc
363   {
364
365     Object JavaDoc result = null;
366     XSLProcessorContext xpc = new XSLProcessorContext(transformer, stylesheetTree);
367
368     try
369     {
370       Vector JavaDoc argv = new Vector JavaDoc(2);
371
372       argv.addElement(xpc);
373       argv.addElement(element);
374
375       result = callFunction(localPart, argv, methodKey,
376                             transformer.getXPathContext().getExpressionContext());
377     }
378     catch (XPathProcessorException e)
379     {
380
381       // e.printStackTrace ();
382
throw new TransformerException JavaDoc(e.getMessage(), e);
383     }
384
385     if (result != null)
386     {
387       xpc.outputToResultTree(stylesheetTree, result);
388     }
389   }
390 }
391
Popular Tags