/** Auxiliary method for dispatchSVGLoad. */ protected void dispatchSVGLoad(Element elt, boolean checkCanRun, String lang) { for (Node n = elt.getFirstChild(); n != null; n = n.getNextSibling()) { if (n.getNodeType() == Node.ELEMENT_NODE) { dispatchSVGLoad((Element) n, checkCanRun, lang); } } DocumentEvent de = (DocumentEvent) elt.getOwnerDocument(); AbstractEvent ev = (AbstractEvent) de.createEvent("SVGEvents"); String type; if (bridgeContext.isSVG12()) { type = "load"; } else { type = "SVGLoad"; } ev.initEventNS(XMLConstants.XML_EVENTS_NAMESPACE_URI, type, false, false); NodeEventTarget t = (NodeEventTarget) elt; final String s = elt.getAttributeNS(null, SVGConstants.SVG_ONLOAD_ATTRIBUTE); if (s.length() == 0) { // No script to run so just dispatch the event to DOM // (For java presumably). t.dispatchEvent(ev); return; } final Interpreter interp = getInterpreter(); if (interp == null) { // Can't load interpreter so just dispatch normal event // to the DOM (for java presumably). t.dispatchEvent(ev); return; } if (checkCanRun) { // Check that it is ok to run embeded scripts checkCompatibleScriptURL(lang, docPURL); checkCanRun = false; // we only check once for onload handlers } DocumentLoader dl = bridgeContext.getDocumentLoader(); SVGDocument d = (SVGDocument) elt.getOwnerDocument(); int line = dl.getLineNumber(elt); final String desc = Messages.formatMessage( EVENT_SCRIPT_DESCRIPTION, new Object[] {d.getURL(), SVGConstants.SVG_ONLOAD_ATTRIBUTE, new Integer(line)}); EventListener l = new EventListener() { public void handleEvent(Event evt) { try { Object event; if (evt instanceof ScriptEventWrapper) { event = ((ScriptEventWrapper) evt).getEventObject(); } else { event = evt; } interp.bindObject(EVENT_NAME, event); interp.bindObject(ALTERNATE_EVENT_NAME, event); interp.evaluate(new StringReader(s), desc); } catch (IOException io) { } catch (InterpreterException e) { handleInterpreterException(e); } } }; t.addEventListenerNS(XMLConstants.XML_EVENTS_NAMESPACE_URI, type, l, false, null); t.dispatchEvent(ev); t.removeEventListenerNS(XMLConstants.XML_EVENTS_NAMESPACE_URI, type, l, false); }
/** Tries to build a GVTFontFamily from a URL reference */ protected GVTFontFamily getFontFamily(BridgeContext ctx, ParsedURL purl) { String purlStr = purl.toString(); Element e = getBaseElement(ctx); SVGDocument svgDoc = (SVGDocument) e.getOwnerDocument(); String docURL = svgDoc.getURL(); ParsedURL pDocURL = null; if (docURL != null) pDocURL = new ParsedURL(docURL); // try to load an SVG document String baseURI = AbstractNode.getBaseURI(e); purl = new ParsedURL(baseURI, purlStr); UserAgent userAgent = ctx.getUserAgent(); try { userAgent.checkLoadExternalResource(purl, pDocURL); } catch (SecurityException ex) { // Can't load font - Security violation. // We should not throw the error that is for certain, just // move down the font list, but do we display the error or not??? // I'll vote yes just because it is a security exception (other // exceptions like font not available etc I would skip). userAgent.displayError(ex); return null; } if (purl.getRef() != null) { // Reference must be to a SVGFont. Element ref = ctx.getReferencedElement(e, purlStr); if (!ref.getNamespaceURI().equals(SVG_NAMESPACE_URI) || !ref.getLocalName().equals(SVG_FONT_TAG)) { return null; } SVGDocument doc = (SVGDocument) e.getOwnerDocument(); SVGDocument rdoc = (SVGDocument) ref.getOwnerDocument(); Element fontElt = ref; if (doc != rdoc) { fontElt = (Element) doc.importNode(ref, true); String base = AbstractNode.getBaseURI(ref); Element g = doc.createElementNS(SVG_NAMESPACE_URI, SVG_G_TAG); g.appendChild(fontElt); g.setAttributeNS(XMLConstants.XML_NAMESPACE_URI, "xml:base", base); CSSUtilities.computeStyleAndURIs(ref, fontElt, purlStr); } // Search for a font-face element Element fontFaceElt = null; for (Node n = fontElt.getFirstChild(); n != null; n = n.getNextSibling()) { if ((n.getNodeType() == Node.ELEMENT_NODE) && n.getNamespaceURI().equals(SVG_NAMESPACE_URI) && n.getLocalName().equals(SVG_FONT_FACE_TAG)) { fontFaceElt = (Element) n; break; } } // todo : if the above loop fails to find a fontFaceElt, a null is passed to createFontFace() SVGFontFaceElementBridge fontFaceBridge; fontFaceBridge = (SVGFontFaceElementBridge) ctx.getBridge(SVG_NAMESPACE_URI, SVG_FONT_FACE_TAG); GVTFontFace gff = fontFaceBridge.createFontFace(ctx, fontFaceElt); return new SVGFontFamily(gff, fontElt, ctx); } // Must be a reference to a 'Web Font'. try { return ctx.getFontFamilyResolver().loadFont(purl.openStream(), this); } catch (Exception ex) { } return null; }
/** Loads the scripts contained in the <script> elements. */ public void loadScripts() { org.apache.batik.script.Window window = null; NodeList scripts = document.getElementsByTagNameNS( SVGConstants.SVG_NAMESPACE_URI, SVGConstants.SVG_SCRIPT_TAG); int len = scripts.getLength(); if (len == 0) { return; } for (int i = 0; i < len; i++) { AbstractElement script = (AbstractElement) scripts.item(i); String type = script.getAttributeNS(null, SVGConstants.SVG_TYPE_ATTRIBUTE); if (type.length() == 0) { type = SVGConstants.SVG_SCRIPT_TYPE_DEFAULT_VALUE; } // // Java code invocation. // if (type.equals(SVGConstants.SVG_SCRIPT_TYPE_JAVA)) { try { String href = XLinkSupport.getXLinkHref(script); ParsedURL purl = new ParsedURL(script.getBaseURI(), href); checkCompatibleScriptURL(type, purl); DocumentJarClassLoader cll; URL docURL = null; try { docURL = new URL(docPURL.toString()); } catch (MalformedURLException mue) { /* nothing just let docURL be null */ } cll = new DocumentJarClassLoader(new URL(purl.toString()), docURL); // Get the 'Script-Handler' entry in the manifest. URL url = cll.findResource("META-INF/MANIFEST.MF"); if (url == null) { continue; } Manifest man = new Manifest(url.openStream()); String sh; sh = man.getMainAttributes().getValue("Script-Handler"); if (sh != null) { // Run the script handler. ScriptHandler h; h = (ScriptHandler) cll.loadClass(sh).newInstance(); if (window == null) { window = createWindow(); } h.run(document, window); } sh = man.getMainAttributes().getValue("SVG-Handler-Class"); if (sh != null) { // Run the initializer EventListenerInitializer initializer; initializer = (EventListenerInitializer) cll.loadClass(sh).newInstance(); if (window == null) { window = createWindow(); } initializer.initializeEventListeners((SVGDocument) document); } } catch (Exception e) { if (userAgent != null) { userAgent.displayError(e); } } continue; } // // Scripting language invocation. // Interpreter interpreter = getInterpreter(type); if (interpreter == null) // Can't find interpreter so just skip this script block. continue; try { String href = XLinkSupport.getXLinkHref(script); String desc = null; Reader reader = null; if (href.length() > 0) { desc = href; // External script. ParsedURL purl = new ParsedURL(script.getBaseURI(), href); checkCompatibleScriptURL(type, purl); InputStream is = purl.openStream(); String mediaType = purl.getContentTypeMediaType(); String enc = purl.getContentTypeCharset(); if (enc != null) { try { reader = new InputStreamReader(is, enc); } catch (UnsupportedEncodingException uee) { enc = null; } } if (reader == null) { if (APPLICATION_ECMASCRIPT.equals(mediaType)) { // No encoding was specified in the MIME type, so // infer it according to RFC 4329. if (purl.hasContentTypeParameter("version")) { // Future versions of application/ecmascript // are not supported, so skip this script // element if the version parameter is present. continue; } PushbackInputStream pbis = new PushbackInputStream(is, 8); byte[] buf = new byte[4]; int read = pbis.read(buf); if (read > 0) { pbis.unread(buf, 0, read); if (read >= 2) { if (buf[0] == (byte) 0xff && buf[1] == (byte) 0xfe) { if (read >= 4 && buf[2] == 0 && buf[3] == 0) { enc = "UTF32-LE"; pbis.skip(4); } else { enc = "UTF-16LE"; pbis.skip(2); } } else if (buf[0] == (byte) 0xfe && buf[1] == (byte) 0xff) { enc = "UTF-16BE"; pbis.skip(2); } else if (read >= 3 && buf[0] == (byte) 0xef && buf[1] == (byte) 0xbb && buf[2] == (byte) 0xbf) { enc = "UTF-8"; pbis.skip(3); } else if (read >= 4 && buf[0] == 0 && buf[1] == 0 && buf[2] == (byte) 0xfe && buf[3] == (byte) 0xff) { enc = "UTF-32BE"; pbis.skip(4); } } if (enc == null) { enc = "UTF-8"; } } reader = new InputStreamReader(pbis, enc); } else { reader = new InputStreamReader(is); } } } else { checkCompatibleScriptURL(type, docPURL); DocumentLoader dl = bridgeContext.getDocumentLoader(); Element e = script; SVGDocument d = (SVGDocument) e.getOwnerDocument(); int line = dl.getLineNumber(script); desc = Messages.formatMessage( INLINE_SCRIPT_DESCRIPTION, new Object[] {d.getURL(), "<" + script.getNodeName() + ">", new Integer(line)}); // Inline script. Node n = script.getFirstChild(); if (n != null) { StringBuffer sb = new StringBuffer(); while (n != null) { if (n.getNodeType() == Node.CDATA_SECTION_NODE || n.getNodeType() == Node.TEXT_NODE) sb.append(n.getNodeValue()); n = n.getNextSibling(); } reader = new StringReader(sb.toString()); } else { continue; } } interpreter.evaluate(reader, desc); } catch (IOException e) { if (userAgent != null) { userAgent.displayError(e); } return; } catch (InterpreterException e) { System.err.println("InterpExcept: " + e); handleInterpreterException(e); return; } catch (SecurityException e) { if (userAgent != null) { userAgent.displayError(e); } } } }