1 /* |
|
2 * reserved comment block |
|
3 * DO NOT REMOVE OR ALTER! |
|
4 */ |
|
5 /* |
|
6 * Copyright 1999-2004 The Apache Software Foundation. |
|
7 * |
|
8 * Licensed under the Apache License, Version 2.0 (the "License"); |
|
9 * you may not use this file except in compliance with the License. |
|
10 * You may obtain a copy of the License at |
|
11 * |
|
12 * http://www.apache.org/licenses/LICENSE-2.0 |
|
13 * |
|
14 * Unless required by applicable law or agreed to in writing, software |
|
15 * distributed under the License is distributed on an "AS IS" BASIS, |
|
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
17 * See the License for the specific language governing permissions and |
|
18 * limitations under the License. |
|
19 */ |
|
20 /* |
|
21 * $Id: XSLTProcessorApplet.java,v 1.2.4.1 2005/09/15 02:20:05 jeffsuttor Exp $ |
|
22 */ |
|
23 package com.sun.org.apache.xalan.internal.client; |
|
24 |
|
25 import java.applet.Applet; |
|
26 import java.awt.Graphics; |
|
27 import java.io.IOException; |
|
28 import java.io.PrintWriter; |
|
29 import java.io.StringReader; |
|
30 import java.io.StringWriter; |
|
31 import java.net.MalformedURLException; |
|
32 import java.net.URL; |
|
33 import java.util.Hashtable; |
|
34 import java.util.Enumeration; |
|
35 |
|
36 import javax.xml.transform.Templates; |
|
37 import javax.xml.transform.Transformer; |
|
38 import javax.xml.transform.TransformerConfigurationException; |
|
39 import javax.xml.transform.TransformerException; |
|
40 import javax.xml.transform.TransformerFactory; |
|
41 import javax.xml.transform.stream.StreamResult; |
|
42 import javax.xml.transform.stream.StreamSource; |
|
43 |
|
44 import com.sun.org.apache.xalan.internal.res.XSLMessages; |
|
45 import com.sun.org.apache.xalan.internal.res.XSLTErrorResources; |
|
46 |
|
47 /** |
|
48 * Provides applet host for the XSLT processor. To perform transformations on an HTML client: |
|
49 * <ol> |
|
50 * <li>Use an <applet> tag to embed this applet in the HTML client.</li> |
|
51 * <li>Use the DocumentURL and StyleURL PARAM tags or the {@link #setDocumentURL} and |
|
52 * {@link #setStyleURL} methods to specify the XML source document and XSL stylesheet.</li> |
|
53 * <li>Call the {@link #getHtmlText} method (or one of the transformToHtml() methods) |
|
54 * to perform the transformation and return the result as a String.</li> |
|
55 * </ol> |
|
56 * |
|
57 * This class extends Applet which ultimately causes this class to implement Serializable. |
|
58 * This is a serious restriction on this class. All fields that are not transient and not |
|
59 * static are written-out/read-in during serialization. So even private fields essentially |
|
60 * become part of the API. Developers need to take care when modifying fields. |
|
61 * @xsl.usage general |
|
62 */ |
|
63 public class XSLTProcessorApplet extends Applet |
|
64 { |
|
65 |
|
66 /** |
|
67 * The stylesheet processor. |
|
68 * This field is now transient because a |
|
69 * javax.xml.transform.TransformerFactory from JAXP |
|
70 * makes no claims to be serializable. |
|
71 */ |
|
72 transient TransformerFactory m_tfactory = null; |
|
73 |
|
74 /** |
|
75 * @serial |
|
76 */ |
|
77 private String m_styleURL; |
|
78 |
|
79 /** |
|
80 * @serial |
|
81 */ |
|
82 private String m_documentURL; |
|
83 |
|
84 // Parameter names. To change a name of a parameter, you need only make |
|
85 // a single change. Simply modify the value of the parameter string below. |
|
86 //-------------------------------------------------------------------------- |
|
87 |
|
88 /** |
|
89 * @serial |
|
90 */ |
|
91 private final String PARAM_styleURL = "styleURL"; |
|
92 |
|
93 /** |
|
94 * @serial |
|
95 */ |
|
96 private final String PARAM_documentURL = "documentURL"; |
|
97 |
|
98 |
|
99 // We'll keep the DOM trees around, so tell which trees |
|
100 // are cached. |
|
101 |
|
102 /** |
|
103 * @serial |
|
104 */ |
|
105 private String m_styleURLOfCached = null; |
|
106 |
|
107 /** |
|
108 * @serial |
|
109 */ |
|
110 private String m_documentURLOfCached = null; |
|
111 |
|
112 /** |
|
113 * Save this for use on the worker thread; may not be necessary. |
|
114 * @serial |
|
115 */ |
|
116 private URL m_codeBase = null; |
|
117 |
|
118 /** |
|
119 * @serial |
|
120 */ |
|
121 private String m_treeURL = null; |
|
122 |
|
123 /** |
|
124 * DocumentBase URL |
|
125 * @serial |
|
126 */ |
|
127 private URL m_documentBase = null; |
|
128 |
|
129 /** |
|
130 * Thread stuff for the trusted worker thread. |
|
131 */ |
|
132 transient private Thread m_callThread = null; |
|
133 |
|
134 /** |
|
135 */ |
|
136 transient private TrustedAgent m_trustedAgent = null; |
|
137 |
|
138 /** |
|
139 * Thread for running TrustedAgent. |
|
140 */ |
|
141 transient private Thread m_trustedWorker = null; |
|
142 |
|
143 /** |
|
144 * Where the worker thread puts the HTML text. |
|
145 */ |
|
146 transient private String m_htmlText = null; |
|
147 |
|
148 /** |
|
149 * Where the worker thread puts the document/stylesheet text. |
|
150 */ |
|
151 transient private String m_sourceText = null; |
|
152 |
|
153 /** |
|
154 * Stylesheet attribute name and value that the caller can set. |
|
155 */ |
|
156 transient private String m_nameOfIDAttrOfElemToModify = null; |
|
157 |
|
158 /** |
|
159 */ |
|
160 transient private String m_elemIdToModify = null; |
|
161 |
|
162 /** |
|
163 */ |
|
164 transient private String m_attrNameToSet = null; |
|
165 |
|
166 /** |
|
167 */ |
|
168 transient private String m_attrValueToSet = null; |
|
169 |
|
170 /** |
|
171 * The XSLTProcessorApplet constructor takes no arguments. |
|
172 */ |
|
173 public XSLTProcessorApplet(){} |
|
174 |
|
175 /** |
|
176 * Get basic information about the applet |
|
177 * @return A String with the applet name and author. |
|
178 */ |
|
179 public String getAppletInfo() |
|
180 { |
|
181 return "Name: XSLTProcessorApplet\r\n" + "Author: Scott Boag"; |
|
182 } |
|
183 |
|
184 /** |
|
185 * Get descriptions of the applet parameters. |
|
186 * @return A two-dimensional array of Strings with Name, Type, and Description |
|
187 * for each parameter. |
|
188 */ |
|
189 public String[][] getParameterInfo() |
|
190 { |
|
191 |
|
192 String[][] info = |
|
193 { |
|
194 { PARAM_styleURL, "String", "URL to an XSL stylesheet" }, |
|
195 { PARAM_documentURL, "String", "URL to an XML document" }, |
|
196 }; |
|
197 |
|
198 return info; |
|
199 } |
|
200 |
|
201 /** |
|
202 * Standard applet initialization. |
|
203 */ |
|
204 public void init() |
|
205 { |
|
206 |
|
207 // PARAMETER SUPPORT |
|
208 // The following code retrieves the value of each parameter |
|
209 // specified with the <PARAM> tag and stores it in a member |
|
210 // variable. |
|
211 //---------------------------------------------------------------------- |
|
212 String param; |
|
213 |
|
214 // styleURL: Parameter description |
|
215 //---------------------------------------------------------------------- |
|
216 param = getParameter(PARAM_styleURL); |
|
217 |
|
218 // stylesheet parameters |
|
219 m_parameters = new Hashtable(); |
|
220 |
|
221 if (param != null) |
|
222 setStyleURL(param); |
|
223 |
|
224 // documentURL: Parameter description |
|
225 //---------------------------------------------------------------------- |
|
226 param = getParameter(PARAM_documentURL); |
|
227 |
|
228 if (param != null) |
|
229 setDocumentURL(param); |
|
230 |
|
231 m_codeBase = this.getCodeBase(); |
|
232 m_documentBase = this.getDocumentBase(); |
|
233 |
|
234 // If you use a ResourceWizard-generated "control creator" class to |
|
235 // arrange controls in your applet, you may want to call its |
|
236 // CreateControls() method from within this method. Remove the following |
|
237 // call to resize() before adding the call to CreateControls(); |
|
238 // CreateControls() does its own resizing. |
|
239 //---------------------------------------------------------------------- |
|
240 resize(320, 240); |
|
241 } |
|
242 |
|
243 /** |
|
244 * Automatically called when the HTML client containing the applet loads. |
|
245 * This method starts execution of the applet thread. |
|
246 */ |
|
247 public void start() |
|
248 { |
|
249 //check if user code's on the stack before invoking the worker thread |
|
250 boolean passed = false; |
|
251 try { |
|
252 java.security.AccessController.checkPermission(new java.security.AllPermission()); |
|
253 } catch (SecurityException se) { |
|
254 //expected |
|
255 passed = true; |
|
256 } |
|
257 if (!passed) { |
|
258 throw new SecurityException("The XSLTProcessorApplet class must be extended and its method start() overridden."); |
|
259 } |
|
260 |
|
261 m_trustedAgent = new TrustedAgent(); |
|
262 Thread currentThread = Thread.currentThread(); |
|
263 m_trustedWorker = new Thread(currentThread.getThreadGroup(), |
|
264 m_trustedAgent); |
|
265 m_trustedWorker.start(); |
|
266 try |
|
267 { |
|
268 m_tfactory = TransformerFactory.newInstance(); |
|
269 this.showStatus("Causing Transformer and Parser to Load and JIT..."); |
|
270 |
|
271 // Prime the pump so that subsequent transforms are faster. |
|
272 StringReader xmlbuf = new StringReader("<?xml version='1.0'?><foo/>"); |
|
273 StringReader xslbuf = new StringReader( |
|
274 "<?xml version='1.0'?><xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'><xsl:template match='foo'><out/></xsl:template></xsl:stylesheet>"); |
|
275 PrintWriter pw = new PrintWriter(new StringWriter()); |
|
276 |
|
277 synchronized (m_tfactory) |
|
278 { |
|
279 Templates templates = m_tfactory.newTemplates(new StreamSource(xslbuf)); |
|
280 Transformer transformer = templates.newTransformer(); |
|
281 transformer.transform(new StreamSource(xmlbuf), new StreamResult(pw)); |
|
282 } |
|
283 System.out.println("Primed the pump!"); |
|
284 this.showStatus("Ready to go!"); |
|
285 } |
|
286 catch (Exception e) |
|
287 { |
|
288 this.showStatus("Could not prime the pump!"); |
|
289 System.out.println("Could not prime the pump!"); |
|
290 e.printStackTrace(); |
|
291 } |
|
292 } |
|
293 |
|
294 /** |
|
295 * Do not call; this applet contains no UI or visual components. |
|
296 * |
|
297 */ |
|
298 public void paint(Graphics g){} |
|
299 |
|
300 /** |
|
301 * Automatically called when the HTML page containing the applet is no longer |
|
302 * on the screen. Stops execution of the applet thread. |
|
303 */ |
|
304 public void stop() |
|
305 { |
|
306 if (null != m_trustedWorker) |
|
307 { |
|
308 m_trustedWorker.stop(); |
|
309 |
|
310 // m_trustedWorker.destroy(); |
|
311 m_trustedWorker = null; |
|
312 } |
|
313 |
|
314 m_styleURLOfCached = null; |
|
315 m_documentURLOfCached = null; |
|
316 } |
|
317 |
|
318 /** |
|
319 * Cleanup; called when applet is terminated and unloaded. |
|
320 */ |
|
321 public void destroy() |
|
322 { |
|
323 if (null != m_trustedWorker) |
|
324 { |
|
325 m_trustedWorker.stop(); |
|
326 |
|
327 // m_trustedWorker.destroy(); |
|
328 m_trustedWorker = null; |
|
329 } |
|
330 m_styleURLOfCached = null; |
|
331 m_documentURLOfCached = null; |
|
332 } |
|
333 |
|
334 /** |
|
335 * Set the URL to the XSL stylesheet that will be used |
|
336 * to transform the input XML. No processing is done yet. |
|
337 * @param urlString valid URL string for XSL stylesheet. |
|
338 */ |
|
339 public void setStyleURL(String urlString) |
|
340 { |
|
341 m_styleURL = urlString; |
|
342 } |
|
343 |
|
344 /** |
|
345 * Set the URL to the XML document that will be transformed |
|
346 * with the XSL stylesheet. No processing is done yet. |
|
347 * @param urlString valid URL string for XML document. |
|
348 */ |
|
349 public void setDocumentURL(String urlString) |
|
350 { |
|
351 m_documentURL = urlString; |
|
352 } |
|
353 |
|
354 /** |
|
355 * The processor keeps a cache of the source and |
|
356 * style trees, so call this method if they have changed |
|
357 * or you want to do garbage collection. |
|
358 */ |
|
359 public void freeCache() |
|
360 { |
|
361 m_styleURLOfCached = null; |
|
362 m_documentURLOfCached = null; |
|
363 } |
|
364 |
|
365 /** |
|
366 * Set an attribute in the stylesheet, which gives the ability |
|
367 * to have some dynamic selection control. |
|
368 * @param nameOfIDAttrOfElemToModify The name of an attribute to search for a unique id. |
|
369 * @param elemId The unique ID to look for. |
|
370 * @param attrName Once the element is found, the name of the attribute to set. |
|
371 * @param value The value to set the attribute to. |
|
372 */ |
|
373 public void setStyleSheetAttribute(String nameOfIDAttrOfElemToModify, |
|
374 String elemId, String attrName, |
|
375 String value) |
|
376 { |
|
377 m_nameOfIDAttrOfElemToModify = nameOfIDAttrOfElemToModify; |
|
378 m_elemIdToModify = elemId; |
|
379 m_attrNameToSet = attrName; |
|
380 m_attrValueToSet = value; |
|
381 } |
|
382 |
|
383 |
|
384 /** |
|
385 * Stylesheet parameter key/value pair stored in a hashtable |
|
386 */ |
|
387 transient Hashtable m_parameters; |
|
388 |
|
389 /** |
|
390 * Submit a stylesheet parameter. |
|
391 * |
|
392 * @param key stylesheet parameter key |
|
393 * @param expr the parameter expression to be submitted. |
|
394 * @see javax.xml.transform.Transformer#setParameter(String,Object) |
|
395 */ |
|
396 public void setStylesheetParam(String key, String expr) |
|
397 { |
|
398 m_parameters.put(key, expr); |
|
399 } |
|
400 |
|
401 /** |
|
402 * Given a String containing markup, escape the markup so it |
|
403 * can be displayed in the browser. |
|
404 * |
|
405 * @param s String to escape |
|
406 * |
|
407 * The escaped string. |
|
408 */ |
|
409 public String escapeString(String s) |
|
410 { |
|
411 StringBuffer sb = new StringBuffer(); |
|
412 int length = s.length(); |
|
413 |
|
414 for (int i = 0; i < length; i++) |
|
415 { |
|
416 char ch = s.charAt(i); |
|
417 |
|
418 if ('<' == ch) |
|
419 { |
|
420 sb.append("<"); |
|
421 } |
|
422 else if ('>' == ch) |
|
423 { |
|
424 sb.append(">"); |
|
425 } |
|
426 else if ('&' == ch) |
|
427 { |
|
428 sb.append("&"); |
|
429 } |
|
430 else if (0xd800 <= ch && ch < 0xdc00) |
|
431 { |
|
432 // UTF-16 surrogate |
|
433 int next; |
|
434 |
|
435 if (i + 1 >= length) |
|
436 { |
|
437 throw new RuntimeException( |
|
438 XSLMessages.createMessage( |
|
439 XSLTErrorResources.ER_INVALID_UTF16_SURROGATE, |
|
440 new Object[]{ Integer.toHexString(ch) })); //"Invalid UTF-16 surrogate detected: " |
|
441 |
|
442 //+Integer.toHexString(ch)+ " ?"); |
|
443 } |
|
444 else |
|
445 { |
|
446 next = s.charAt(++i); |
|
447 |
|
448 if (!(0xdc00 <= next && next < 0xe000)) |
|
449 throw new RuntimeException( |
|
450 XSLMessages.createMessage( |
|
451 XSLTErrorResources.ER_INVALID_UTF16_SURROGATE, |
|
452 new Object[]{ |
|
453 Integer.toHexString(ch) + " " |
|
454 + Integer.toHexString(next) })); //"Invalid UTF-16 surrogate detected: " |
|
455 |
|
456 //+Integer.toHexString(ch)+" "+Integer.toHexString(next)); |
|
457 next = ((ch - 0xd800) << 10) + next - 0xdc00 + 0x00010000; |
|
458 } |
|
459 sb.append("&#x"); |
|
460 sb.append(Integer.toHexString(next)); |
|
461 sb.append(";"); |
|
462 } |
|
463 else |
|
464 { |
|
465 sb.append(ch); |
|
466 } |
|
467 } |
|
468 return sb.toString(); |
|
469 } |
|
470 |
|
471 /** |
|
472 * Assuming the stylesheet URL and the input XML URL have been set, |
|
473 * perform the transformation and return the result as a String. |
|
474 * |
|
475 * @return A string that contains the contents pointed to by the URL. |
|
476 * |
|
477 */ |
|
478 public String getHtmlText() |
|
479 { |
|
480 m_trustedAgent.m_getData = true; |
|
481 m_callThread = Thread.currentThread(); |
|
482 try |
|
483 { |
|
484 synchronized (m_callThread) |
|
485 { |
|
486 m_callThread.wait(); |
|
487 } |
|
488 } |
|
489 catch (InterruptedException ie) |
|
490 { |
|
491 System.out.println(ie.getMessage()); |
|
492 } |
|
493 return m_htmlText; |
|
494 } |
|
495 |
|
496 /** |
|
497 * Get an XML document (or stylesheet) |
|
498 * |
|
499 * @param treeURL valid URL string for the document. |
|
500 * |
|
501 * @return document |
|
502 * |
|
503 * @throws IOException |
|
504 */ |
|
505 public String getTreeAsText(String treeURL) throws IOException |
|
506 { |
|
507 m_treeURL = treeURL; |
|
508 m_trustedAgent.m_getData = true; |
|
509 m_trustedAgent.m_getSource = true; |
|
510 m_callThread = Thread.currentThread(); |
|
511 try |
|
512 { |
|
513 synchronized (m_callThread) |
|
514 { |
|
515 m_callThread.wait(); |
|
516 } |
|
517 } |
|
518 catch (InterruptedException ie) |
|
519 { |
|
520 System.out.println(ie.getMessage()); |
|
521 } |
|
522 return m_sourceText; |
|
523 } |
|
524 |
|
525 /** |
|
526 * Use a Transformer to copy the source document |
|
527 * to a StreamResult. |
|
528 * |
|
529 * @return the document as a string |
|
530 */ |
|
531 private String getSource() throws TransformerException |
|
532 { |
|
533 StringWriter osw = new StringWriter(); |
|
534 PrintWriter pw = new PrintWriter(osw, false); |
|
535 String text = ""; |
|
536 try |
|
537 { |
|
538 URL docURL = new URL(m_documentBase, m_treeURL); |
|
539 synchronized (m_tfactory) |
|
540 { |
|
541 Transformer transformer = m_tfactory.newTransformer(); |
|
542 StreamSource source = new StreamSource(docURL.toString()); |
|
543 StreamResult result = new StreamResult(pw); |
|
544 transformer.transform(source, result); |
|
545 text = osw.toString(); |
|
546 } |
|
547 } |
|
548 catch (MalformedURLException e) |
|
549 { |
|
550 e.printStackTrace(); |
|
551 throw new RuntimeException(e.getMessage()); |
|
552 } |
|
553 catch (Exception any_error) |
|
554 { |
|
555 any_error.printStackTrace(); |
|
556 } |
|
557 return text; |
|
558 } |
|
559 |
|
560 /** |
|
561 * Get the XML source Tree as a text string suitable |
|
562 * for display in a browser. Note that this is for display of the |
|
563 * XML itself, not for rendering of HTML by the browser. |
|
564 * |
|
565 * @return XML source document as a string. |
|
566 * @throws Exception thrown if tree can not be converted. |
|
567 */ |
|
568 public String getSourceTreeAsText() throws Exception |
|
569 { |
|
570 return getTreeAsText(m_documentURL); |
|
571 } |
|
572 |
|
573 /** |
|
574 * Get the XSL style Tree as a text string suitable |
|
575 * for display in a browser. Note that this is for display of the |
|
576 * XML itself, not for rendering of HTML by the browser. |
|
577 * |
|
578 * @return The XSL stylesheet as a string. |
|
579 * @throws Exception thrown if tree can not be converted. |
|
580 */ |
|
581 public String getStyleTreeAsText() throws Exception |
|
582 { |
|
583 return getTreeAsText(m_styleURL); |
|
584 } |
|
585 |
|
586 /** |
|
587 * Get the HTML result Tree as a text string suitable |
|
588 * for display in a browser. Note that this is for display of the |
|
589 * XML itself, not for rendering of HTML by the browser. |
|
590 * |
|
591 * @return Transformation result as unmarked text. |
|
592 * @throws Exception thrown if tree can not be converted. |
|
593 */ |
|
594 public String getResultTreeAsText() throws Exception |
|
595 { |
|
596 return escapeString(getHtmlText()); |
|
597 } |
|
598 |
|
599 /** |
|
600 * Process a document and a stylesheet and return |
|
601 * the transformation result. If one of these is null, the |
|
602 * existing value (of a previous transformation) is not affected. |
|
603 * |
|
604 * @param doc URL string to XML document |
|
605 * @param style URL string to XSL stylesheet |
|
606 * |
|
607 * @return HTML transformation result |
|
608 */ |
|
609 public String transformToHtml(String doc, String style) |
|
610 { |
|
611 |
|
612 if (null != doc) |
|
613 { |
|
614 m_documentURL = doc; |
|
615 } |
|
616 |
|
617 if (null != style) |
|
618 { |
|
619 m_styleURL = style; |
|
620 } |
|
621 |
|
622 return getHtmlText(); |
|
623 } |
|
624 |
|
625 /** |
|
626 * Process a document and a stylesheet and return |
|
627 * the transformation result. Use the xsl:stylesheet PI to find the |
|
628 * document, if one exists. |
|
629 * |
|
630 * @param doc URL string to XML document containing an xsl:stylesheet PI. |
|
631 * |
|
632 * @return HTML transformation result |
|
633 */ |
|
634 public String transformToHtml(String doc) |
|
635 { |
|
636 |
|
637 if (null != doc) |
|
638 { |
|
639 m_documentURL = doc; |
|
640 } |
|
641 |
|
642 m_styleURL = null; |
|
643 |
|
644 return getHtmlText(); |
|
645 } |
|
646 |
|
647 |
|
648 /** |
|
649 * Process the transformation. |
|
650 * |
|
651 * @return The transformation result as a string. |
|
652 * |
|
653 * @throws TransformerException |
|
654 */ |
|
655 private String processTransformation() throws TransformerException |
|
656 { |
|
657 String htmlData = null; |
|
658 this.showStatus("Waiting for Transformer and Parser to finish loading and JITing..."); |
|
659 |
|
660 synchronized (m_tfactory) |
|
661 { |
|
662 URL documentURL = null; |
|
663 URL styleURL = null; |
|
664 StringWriter osw = new StringWriter(); |
|
665 PrintWriter pw = new PrintWriter(osw, false); |
|
666 StreamResult result = new StreamResult(pw); |
|
667 |
|
668 this.showStatus("Begin Transformation..."); |
|
669 try |
|
670 { |
|
671 documentURL = new URL(m_codeBase, m_documentURL); |
|
672 StreamSource xmlSource = new StreamSource(documentURL.toString()); |
|
673 |
|
674 styleURL = new URL(m_codeBase, m_styleURL); |
|
675 StreamSource xslSource = new StreamSource(styleURL.toString()); |
|
676 |
|
677 Transformer transformer = m_tfactory.newTransformer(xslSource); |
|
678 |
|
679 |
|
680 Enumeration m_keys = m_parameters.keys(); |
|
681 while (m_keys.hasMoreElements()){ |
|
682 Object key = m_keys.nextElement(); |
|
683 Object expression = m_parameters.get(key); |
|
684 transformer.setParameter((String) key, expression); |
|
685 } |
|
686 transformer.transform(xmlSource, result); |
|
687 } |
|
688 catch (TransformerConfigurationException tfe) |
|
689 { |
|
690 tfe.printStackTrace(); |
|
691 throw new RuntimeException(tfe.getMessage()); |
|
692 } |
|
693 catch (MalformedURLException e) |
|
694 { |
|
695 e.printStackTrace(); |
|
696 throw new RuntimeException(e.getMessage()); |
|
697 } |
|
698 |
|
699 this.showStatus("Transformation Done!"); |
|
700 htmlData = osw.toString(); |
|
701 } |
|
702 return htmlData; |
|
703 } |
|
704 |
|
705 /** |
|
706 * This class maintains a worker thread that that is |
|
707 * trusted and can do things like access data. You need |
|
708 * this because the thread that is called by the browser |
|
709 * is not trusted and can't access data from the URLs. |
|
710 */ |
|
711 class TrustedAgent implements Runnable |
|
712 { |
|
713 |
|
714 /** |
|
715 * Specifies whether the worker thread should perform a transformation. |
|
716 */ |
|
717 public boolean m_getData = false; |
|
718 |
|
719 /** |
|
720 * Specifies whether the worker thread should get an XML document or XSL stylesheet. |
|
721 */ |
|
722 public boolean m_getSource = false; |
|
723 |
|
724 /** |
|
725 * The real work is done from here. |
|
726 * |
|
727 */ |
|
728 public void run() |
|
729 { |
|
730 while (true) |
|
731 { |
|
732 m_trustedWorker.yield(); |
|
733 |
|
734 if (m_getData) // Perform a transformation or get a document. |
|
735 { |
|
736 try |
|
737 { |
|
738 m_getData = false; |
|
739 m_htmlText = null; |
|
740 m_sourceText = null; |
|
741 if (m_getSource) // Get a document. |
|
742 { |
|
743 m_getSource = false; |
|
744 m_sourceText = getSource(); |
|
745 } |
|
746 else // Perform a transformation. |
|
747 m_htmlText = processTransformation(); |
|
748 } |
|
749 catch (Exception e) |
|
750 { |
|
751 e.printStackTrace(); |
|
752 } |
|
753 finally |
|
754 { |
|
755 synchronized (m_callThread) |
|
756 { |
|
757 m_callThread.notify(); |
|
758 } |
|
759 } |
|
760 } |
|
761 else |
|
762 { |
|
763 try |
|
764 { |
|
765 m_trustedWorker.sleep(50); |
|
766 } |
|
767 catch (InterruptedException ie) |
|
768 { |
|
769 ie.printStackTrace(); |
|
770 } |
|
771 } |
|
772 } |
|
773 } |
|
774 } |
|
775 |
|
776 // For compatiblity with old serialized objects |
|
777 // We will change non-serialized fields and change methods |
|
778 // and not have this break us. |
|
779 private static final long serialVersionUID=4618876841979251422L; |
|
780 |
|
781 // For compatibility when de-serializing old objects |
|
782 private void readObject(java.io.ObjectInputStream inStream) throws IOException, ClassNotFoundException |
|
783 { |
|
784 inStream.defaultReadObject(); |
|
785 |
|
786 // Needed assignment of non-serialized fields |
|
787 |
|
788 // A TransformerFactory is not guaranteed to be serializable, |
|
789 // so we create one here |
|
790 m_tfactory = TransformerFactory.newInstance(); |
|
791 } |
|
792 } |
|