1 18 package org.apache.batik.bridge; 19 20 import java.io.IOException ; 21 import java.io.InputStreamReader ; 22 import java.io.Reader ; 23 import java.io.StringReader ; 24 import java.net.MalformedURLException ; 25 import java.net.URL ; 26 import java.util.HashSet ; 27 import java.util.Iterator ; 28 import java.util.List ; 29 import java.util.Set ; 30 import java.util.jar.Manifest ; 31 32 import org.apache.batik.dom.svg.XMLBaseSupport; 33 import org.apache.batik.dom.util.XLinkSupport; 34 import org.apache.batik.script.Interpreter; 35 import org.apache.batik.script.InterpreterException; 36 import org.apache.batik.script.ScriptHandler; 37 import org.apache.batik.util.ParsedURL; 38 import org.apache.batik.util.SVGConstants; 39 import org.w3c.dom.Document ; 40 import org.w3c.dom.Element ; 41 import org.w3c.dom.Node ; 42 import org.w3c.dom.NodeList ; 43 import org.w3c.dom.events.DocumentEvent ; 44 import org.w3c.dom.events.Event ; 45 import org.w3c.dom.events.EventListener ; 46 import org.w3c.dom.events.EventTarget ; 47 import org.w3c.dom.svg.SVGDocument; 48 import org.w3c.dom.svg.SVGSVGElement; 49 import org.w3c.dom.svg.EventListenerInitializer; 50 51 57 public class BaseScriptingEnvironment { 58 66 public static final String INLINE_SCRIPT_DESCRIPTION 67 = "BaseScriptingEnvironment.constant.inline.script.description"; 68 69 77 public static final String EVENT_SCRIPT_DESCRIPTION 78 = "BaseScriptingEnvironment.constant.event.script.description"; 79 80 83 public static boolean isDynamicDocument(BridgeContext ctx, Document doc) { 84 Element elt = doc.getDocumentElement(); 85 if ((elt != null) && 86 SVGConstants.SVG_NAMESPACE_URI.equals(elt.getNamespaceURI())) { 87 if (elt.getAttributeNS 88 (null, SVGConstants.SVG_ONABORT_ATTRIBUTE).length() > 0) { 89 return true; 90 } 91 if (elt.getAttributeNS 92 (null, SVGConstants.SVG_ONERROR_ATTRIBUTE).length() > 0) { 93 return true; 94 } 95 if (elt.getAttributeNS 96 (null, SVGConstants.SVG_ONRESIZE_ATTRIBUTE).length() > 0) { 97 return true; 98 } 99 if (elt.getAttributeNS 100 (null, SVGConstants.SVG_ONUNLOAD_ATTRIBUTE).length() > 0) { 101 return true; 102 } 103 if (elt.getAttributeNS 104 (null, SVGConstants.SVG_ONSCROLL_ATTRIBUTE).length() > 0) { 105 return true; 106 } 107 if (elt.getAttributeNS 108 (null, SVGConstants.SVG_ONZOOM_ATTRIBUTE).length() > 0) { 109 return true; 110 } 111 return isDynamicElement(ctx, doc.getDocumentElement()); 112 } 113 return false; 114 } 115 116 public static boolean isDynamicElement(BridgeContext ctx, Element elt) { 117 List bridgeExtensions = ctx.getBridgeExtensions(elt.getOwnerDocument()); 118 return isDynamicElement(elt, ctx, bridgeExtensions); 119 } 120 121 124 public static boolean isDynamicElement 125 (Element elt, BridgeContext ctx, List bridgeExtensions) { 126 Iterator i = bridgeExtensions.iterator(); 127 while (i.hasNext()) { 128 BridgeExtension bridgeExtension = (BridgeExtension) i.next(); 129 if (bridgeExtension.isDynamicElement(elt)) { 130 return true; 131 } 132 } 133 if (SVGConstants.SVG_NAMESPACE_URI.equals(elt.getNamespaceURI())) { 134 if (elt.getAttributeNS 135 (null, SVGConstants.SVG_ONKEYUP_ATTRIBUTE).length() > 0) { 136 return true; 137 } 138 if (elt.getAttributeNS 139 (null, SVGConstants.SVG_ONKEYDOWN_ATTRIBUTE).length() > 0) { 140 return true; 141 } 142 if (elt.getAttributeNS 143 (null, SVGConstants.SVG_ONKEYPRESS_ATTRIBUTE).length() > 0) { 144 return true; 145 } 146 if (elt.getAttributeNS 147 (null, SVGConstants.SVG_ONLOAD_ATTRIBUTE).length() > 0) { 148 return true; 149 } 150 if (elt.getAttributeNS 151 (null, SVGConstants.SVG_ONERROR_ATTRIBUTE).length() > 0) { 152 return true; 153 } 154 if (elt.getAttributeNS 155 (null, SVGConstants.SVG_ONACTIVATE_ATTRIBUTE).length() > 0) { 156 return true; 157 } 158 if (elt.getAttributeNS 159 (null, SVGConstants.SVG_ONCLICK_ATTRIBUTE).length() > 0) { 160 return true; 161 } 162 if (elt.getAttributeNS 163 (null, SVGConstants.SVG_ONFOCUSIN_ATTRIBUTE).length() > 0) { 164 return true; 165 } 166 if (elt.getAttributeNS 167 (null, SVGConstants.SVG_ONFOCUSOUT_ATTRIBUTE).length() > 0) { 168 return true; 169 } 170 if (elt.getAttributeNS 171 (null, SVGConstants.SVG_ONMOUSEDOWN_ATTRIBUTE).length() > 0) { 172 return true; 173 } 174 if (elt.getAttributeNS 175 (null, SVGConstants.SVG_ONMOUSEMOVE_ATTRIBUTE).length() > 0) { 176 return true; 177 } 178 if (elt.getAttributeNS 179 (null, SVGConstants.SVG_ONMOUSEOUT_ATTRIBUTE).length() > 0) { 180 return true; 181 } 182 if (elt.getAttributeNS 183 (null, SVGConstants.SVG_ONMOUSEOVER_ATTRIBUTE).length() > 0) { 184 return true; 185 } 186 if (elt.getAttributeNS 187 (null, SVGConstants.SVG_ONMOUSEUP_ATTRIBUTE).length() > 0) { 188 return true; 189 } 190 } 191 192 for (Node n = elt.getFirstChild(); 193 n != null; 194 n = n.getNextSibling()) { 195 if (n.getNodeType() == Node.ELEMENT_NODE) { 196 if (isDynamicElement(ctx, (Element )n)) { 197 return true; 198 } 199 } 200 } 201 return false; 202 } 203 204 205 protected final static String EVENT_NAME = "event"; 206 protected final static String ALTERNATE_EVENT_NAME = "evt"; 207 208 211 protected BridgeContext bridgeContext; 212 213 216 protected UserAgent userAgent; 217 218 221 protected Document document; 222 223 226 protected ParsedURL docPURL; 227 228 protected Set languages = new HashSet (); 229 230 233 protected Interpreter interpreter; 234 235 239 public BaseScriptingEnvironment(BridgeContext ctx) { 240 bridgeContext = ctx; 241 document = ctx.getDocument(); 242 docPURL = new ParsedURL(((SVGDocument)document).getURL()); 243 userAgent = bridgeContext.getUserAgent(); 244 } 245 246 249 public org.apache.batik.script.Window createWindow 250 (Interpreter interp, String lang) { 251 return new Window(interp, lang); 252 } 253 254 257 public org.apache.batik.script.Window createWindow() { 258 return createWindow(null, null); 259 } 260 261 264 public Interpreter getInterpreter() { 265 if (interpreter != null) 266 return interpreter; 267 268 SVGSVGElement root = (SVGSVGElement)document.getDocumentElement(); 269 String lang = root.getContentScriptType(); 270 return getInterpreter(lang); 271 } 272 273 public Interpreter getInterpreter(String lang) { 274 interpreter = bridgeContext.getInterpreter(lang); 275 if (interpreter == null) { 276 if (languages.contains(lang)) { 277 return null; 279 } 280 281 languages.add(lang); 283 return null; 284 } 285 286 if (!languages.contains(lang)) { 287 languages.add(lang); 288 initializeEnvironment(interpreter, lang); 289 } 290 return interpreter; 291 } 292 293 296 public void initializeEnvironment(Interpreter interp, String lang) { 297 interp.bindObject("window", createWindow(interp, lang)); 298 } 299 300 303 public void loadScripts() { 304 org.apache.batik.script.Window window = null; 305 306 NodeList scripts = document.getElementsByTagNameNS 307 (SVGConstants.SVG_NAMESPACE_URI, SVGConstants.SVG_SCRIPT_TAG); 308 int len = scripts.getLength(); 309 310 if (len == 0) { 311 return; 312 } 313 314 for (int i = 0; i < len; i++) { 315 Element script = (Element )scripts.item(i); 316 String type = script.getAttributeNS 317 (null, SVGConstants.SVG_TYPE_ATTRIBUTE); 318 319 if (type.length() == 0) { 320 type = SVGConstants.SVG_SCRIPT_TYPE_DEFAULT_VALUE; 321 } 322 323 if (type.equals(SVGConstants.SVG_SCRIPT_TYPE_JAVA)) { 327 try { 328 String href = XLinkSupport.getXLinkHref(script); 329 ParsedURL purl = new ParsedURL 330 (XMLBaseSupport.getCascadedXMLBase(script), href); 331 332 checkCompatibleScriptURL(type, purl); 333 334 DocumentJarClassLoader cll; 335 URL docURL = null; 336 try { 337 docURL = new URL (docPURL.toString()); 338 } catch (MalformedURLException mue) { 339 340 } 341 cll = new DocumentJarClassLoader 342 (new URL (purl.toString()), docURL); 343 344 URL url = cll.findResource("META-INF/MANIFEST.MF"); 346 if (url == null) { 347 continue; 348 } 349 Manifest man = new Manifest (url.openStream()); 350 351 String sh; 352 353 sh = man.getMainAttributes().getValue("Script-Handler"); 354 if (sh != null) { 355 ScriptHandler h; 357 h = (ScriptHandler)cll.loadClass(sh).newInstance(); 358 359 if (window == null) { 360 window = createWindow(); 361 } 362 363 h.run(document, window); 364 } 365 366 sh = man.getMainAttributes().getValue("SVG-Handler-Class"); 367 if (sh != null) { 368 EventListenerInitializer initializer; 370 initializer = 371 (EventListenerInitializer)cll.loadClass(sh).newInstance(); 372 373 if (window == null) { 374 window = createWindow(); 375 } 376 377 initializer.initializeEventListeners((SVGDocument)document); 378 } 379 } catch (Exception e) { 380 if (userAgent != null) { 381 userAgent.displayError(e); 382 } 383 } 384 continue; 385 } 386 387 Interpreter interpreter = getInterpreter(type); 391 if (interpreter == null) 392 continue; 394 395 try { 396 String href = XLinkSupport.getXLinkHref(script); 397 String desc = null; 398 Reader reader; 399 400 if (href.length() > 0) { 401 desc = href; 402 403 ParsedURL purl = new ParsedURL 405 (XMLBaseSupport.getCascadedXMLBase(script), href); 406 407 checkCompatibleScriptURL(type, purl); 408 reader = new InputStreamReader (purl.openStream()); 409 } else { 410 checkCompatibleScriptURL(type, docPURL); 411 DocumentLoader dl = bridgeContext.getDocumentLoader(); 412 Element e = script; 413 SVGDocument d = (SVGDocument)e.getOwnerDocument(); 414 int line = dl.getLineNumber(script); 415 desc = Messages.formatMessage 416 (INLINE_SCRIPT_DESCRIPTION, 417 new Object [] {d.getURL(), 418 "<"+script.getNodeName()+">", 419 new Integer (line)}); 420 Node n = script.getFirstChild(); 422 if (n != null) { 423 StringBuffer sb = new StringBuffer (); 424 while (n != null) { 425 if (n.getNodeType() == Node.CDATA_SECTION_NODE 426 || n.getNodeType() == Node.TEXT_NODE) 427 sb.append(n.getNodeValue()); 428 n = n.getNextSibling(); 429 } 430 reader = new StringReader (sb.toString()); 431 } else { 432 continue; 433 } 434 } 435 436 interpreter.evaluate(reader, desc); 437 438 } catch (IOException e) { 439 if (userAgent != null) { 440 userAgent.displayError(e); 441 } 442 return; 443 } catch (InterpreterException e) { 444 System.err.println("InterpExcept: " + e); 445 handleInterpreterException(e); 446 return; 447 } catch (SecurityException e) { 448 if (userAgent != null) { 449 userAgent.displayError(e); 450 } 451 } 452 } 453 } 454 455 460 protected void checkCompatibleScriptURL(String scriptType, 461 ParsedURL scriptPURL){ 462 userAgent.checkLoadScript(scriptType, scriptPURL, docPURL); 463 } 464 465 468 public void dispatchSVGLoadEvent() { 469 SVGSVGElement root = (SVGSVGElement)document.getDocumentElement(); 470 String lang = root.getContentScriptType(); 471 dispatchSVGLoad(root, true, lang); 472 } 473 474 477 protected void dispatchSVGLoad(Element elt, 478 boolean checkCanRun, 479 String lang) { 480 for (Node n = elt.getFirstChild(); 481 n != null; 482 n = n.getNextSibling()) { 483 if (n.getNodeType() == Node.ELEMENT_NODE) { 484 dispatchSVGLoad((Element )n, checkCanRun, lang); 485 } 486 } 487 488 Event ev; 489 DocumentEvent de = (DocumentEvent )elt.getOwnerDocument(); 490 ev = de.createEvent("SVGEvents"); 491 ev.initEvent("SVGLoad", false, false); 492 EventTarget t = (EventTarget )elt; 493 494 final String s = 495 elt.getAttributeNS(null, SVGConstants.SVG_ONLOAD_ATTRIBUTE); 496 if (s.length() == 0) { 497 t.dispatchEvent(ev); 500 return; 501 } 502 503 final Interpreter interp = getInterpreter(); 504 if (interp == null) { 505 t.dispatchEvent(ev); 508 return; 509 } 510 511 if (checkCanRun) { 512 checkCompatibleScriptURL(lang, docPURL); 514 checkCanRun = false; } 516 517 DocumentLoader dl = bridgeContext.getDocumentLoader(); 518 SVGDocument d = (SVGDocument)elt.getOwnerDocument(); 519 int line = dl.getLineNumber(elt); 520 final String desc = Messages.formatMessage 521 (EVENT_SCRIPT_DESCRIPTION, 522 new Object [] {d.getURL(), 523 SVGConstants.SVG_ONLOAD_ATTRIBUTE, 524 new Integer (line)}); 525 526 EventListener l = new EventListener () { 527 public void handleEvent(Event evt) { 528 try { 529 interp.bindObject(EVENT_NAME, evt); 530 interp.bindObject(ALTERNATE_EVENT_NAME, evt); 531 interp.evaluate(new StringReader (s), desc); 532 } catch (IOException io) { 533 } catch (InterpreterException e) { 534 handleInterpreterException(e); 535 } 536 } 537 }; 538 t.addEventListener("SVGLoad", l, false); 539 t.dispatchEvent(ev); 540 t.removeEventListener("SVGLoad", l, false); 541 } 542 543 546 protected void dispatchSVGZoomEvent() { 547 dispatchSVGDocEvent("SVGZoom"); 548 } 549 550 553 protected void dispatchSVGScrollEvent() { 554 dispatchSVGDocEvent("SVGScroll"); 555 } 556 557 560 protected void dispatchSVGResizeEvent() { 561 dispatchSVGDocEvent("SVGResize"); 562 } 563 564 protected void dispatchSVGDocEvent(String eventType) { 565 SVGSVGElement root = 566 (SVGSVGElement)document.getDocumentElement(); 567 EventTarget t = root; 569 570 DocumentEvent de = (DocumentEvent )document; 571 Event ev = de.createEvent("SVGEvents"); 572 ev.initEvent(eventType, false, false); 573 t.dispatchEvent(ev); 574 } 575 576 579 protected void handleInterpreterException(InterpreterException ie) { 580 if (userAgent != null) { 581 Exception ex = ie.getException(); 582 userAgent.displayError((ex == null) ? ie : ex); 583 } 584 } 585 586 589 protected void handleSecurityException(SecurityException se) { 590 if (userAgent != null) { 591 userAgent.displayError(se); 592 } 593 } 594 595 598 protected class Window implements org.apache.batik.script.Window { 599 600 603 protected Interpreter interpreter; 604 605 608 protected String language; 609 610 613 public Window(Interpreter interp, String lang) { 614 interpreter = interp; 615 language = lang; 616 } 617 618 622 public Object setInterval(final String script, long interval) { 623 return null; 624 } 625 626 630 public Object setInterval(final Runnable r, long interval) { 631 return null; 632 } 633 634 638 public void clearInterval(Object interval) { 639 } 640 641 645 public Object setTimeout(final String script, long timeout) { 646 return null; 647 } 648 649 653 public Object setTimeout(final Runnable r, long timeout) { 654 return null; 655 } 656 657 661 public void clearTimeout(Object timeout) { 662 } 663 664 670 public Node parseXML(String text, Document doc) { 671 return null; 672 } 673 674 679 public void getURL(String uri, org.apache.batik.script.Window.URLResponseHandler h) { 680 getURL(uri, h, "UTF8"); 681 } 682 683 689 public void getURL(String uri, 690 org.apache.batik.script.Window.URLResponseHandler h, 691 String enc) { 692 } 693 694 public void postURL(String uri, String content, 695 org.apache.batik.script.Window.URLResponseHandler h) { 696 postURL(uri, content, h, "text/plain", null); 697 } 698 699 public void postURL(String uri, String content, 700 org.apache.batik.script.Window.URLResponseHandler h, 701 String mimeType) { 702 postURL(uri, content, h, mimeType, null); 703 } 704 705 public void postURL(String uri, 706 String content, 707 org.apache.batik.script.Window.URLResponseHandler h, 708 String mimeType, 709 String fEnc) { 710 } 711 712 713 714 717 public void alert(String message) { 718 } 719 720 723 public boolean confirm(String message) { 724 return false; 725 } 726 727 730 public String prompt(String message) { 731 return null; 732 } 733 734 737 public String prompt(String message, String defVal) { 738 return null; 739 } 740 741 744 public BridgeContext getBridgeContext() { 745 return bridgeContext; 746 } 747 748 751 public Interpreter getInterpreter() { 752 return interpreter; 753 } 754 755 } 756 } 757 | Popular Tags |