Mon, 17 Apr 2017 11:46:11 -0700
Added tag jdk8u141-b05 for changeset f7fc5fc0e2cb
aoqi@0 | 1 | #// Usage: jjs -scripting jsadapter_dom.js |
aoqi@0 | 2 | |
aoqi@0 | 3 | /* |
aoqi@0 | 4 | * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. |
attila@962 | 5 | * |
aoqi@0 | 6 | * Redistribution and use in source and binary forms, with or without |
aoqi@0 | 7 | * modification, are permitted provided that the following conditions |
aoqi@0 | 8 | * are met: |
attila@962 | 9 | * |
aoqi@0 | 10 | * - Redistributions of source code must retain the above copyright |
aoqi@0 | 11 | * notice, this list of conditions and the following disclaimer. |
attila@962 | 12 | * |
aoqi@0 | 13 | * - Redistributions in binary form must reproduce the above copyright |
aoqi@0 | 14 | * notice, this list of conditions and the following disclaimer in the |
aoqi@0 | 15 | * documentation and/or other materials provided with the distribution. |
attila@962 | 16 | * |
aoqi@0 | 17 | * - Neither the name of Oracle nor the names of its |
aoqi@0 | 18 | * contributors may be used to endorse or promote products derived |
aoqi@0 | 19 | * from this software without specific prior written permission. |
attila@962 | 20 | * |
aoqi@0 | 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS |
aoqi@0 | 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
aoqi@0 | 23 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
aoqi@0 | 24 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
aoqi@0 | 25 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
aoqi@0 | 26 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
aoqi@0 | 27 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
aoqi@0 | 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
aoqi@0 | 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
aoqi@0 | 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
aoqi@0 | 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
aoqi@0 | 32 | */ |
aoqi@0 | 33 | |
aoqi@0 | 34 | // Simple example that demonstrates reading XML Rss feed |
aoqi@0 | 35 | // to generate a HTML file from script and show it by browser |
attila@962 | 36 | // Uses XML DOM parser and DOM element wrapped by script |
aoqi@0 | 37 | // "proxy" (JSAdapter constructor) |
aoqi@0 | 38 | |
aoqi@0 | 39 | // Java classes used |
aoqi@0 | 40 | var DocBuilderFac = Java.type("javax.xml.parsers.DocumentBuilderFactory"); |
aoqi@0 | 41 | var Node = Java.type("org.w3c.dom.Node"); |
aoqi@0 | 42 | var File = Java.type("java.io.File"); |
aoqi@0 | 43 | var FileWriter = Java.type("java.io.FileWriter"); |
aoqi@0 | 44 | var PrintWriter = Java.type("java.io.PrintWriter"); |
aoqi@0 | 45 | |
aoqi@0 | 46 | // constants from Node class |
aoqi@0 | 47 | var ELEMENT_NODE = Node.ELEMENT_NODE; |
aoqi@0 | 48 | var TEXT_NODE = Node.TEXT_NODE; |
aoqi@0 | 49 | |
aoqi@0 | 50 | // parse XML from uri and return Document |
aoqi@0 | 51 | function parseXML(uri) { |
aoqi@0 | 52 | var docBuilder = DocBuilderFac.newInstance().newDocumentBuilder(); |
aoqi@0 | 53 | return docBuilder["parse(java.lang.String)"](uri); |
aoqi@0 | 54 | } |
aoqi@0 | 55 | |
aoqi@0 | 56 | // get child Elements of given name of the parent element given |
aoqi@0 | 57 | function getChildElements(elem, name) { |
aoqi@0 | 58 | var nodeList = elem.childNodes; |
aoqi@0 | 59 | var childElems = []; |
aoqi@0 | 60 | var len = nodeList.length; |
aoqi@0 | 61 | for (var i = 0; i < len; i++) { |
aoqi@0 | 62 | var node = nodeList.item(i); |
aoqi@0 | 63 | if (node.nodeType == ELEMENT_NODE && |
aoqi@0 | 64 | node.tagName == name) { |
aoqi@0 | 65 | childElems.push(wrapElement(node)); |
aoqi@0 | 66 | } |
aoqi@0 | 67 | } |
aoqi@0 | 68 | |
aoqi@0 | 69 | return childElems; |
aoqi@0 | 70 | } |
aoqi@0 | 71 | |
aoqi@0 | 72 | // get concatenated child text content of an Element |
aoqi@0 | 73 | function getElemText(elem) { |
aoqi@0 | 74 | var nodeList = elem.childNodes; |
aoqi@0 | 75 | var len = nodeList.length; |
aoqi@0 | 76 | var text = ''; |
aoqi@0 | 77 | for (var i = 0; i < len; i++) { |
aoqi@0 | 78 | var node = nodeList.item(i); |
aoqi@0 | 79 | if (node.nodeType == TEXT_NODE) { |
aoqi@0 | 80 | text += node.nodeValue; |
attila@962 | 81 | } |
aoqi@0 | 82 | } |
aoqi@0 | 83 | |
aoqi@0 | 84 | return text; |
aoqi@0 | 85 | } |
aoqi@0 | 86 | |
aoqi@0 | 87 | // Wrap DOM Element object as a convenient script object |
aoqi@0 | 88 | // using JSAdapter. JSAdapter is like java.lang.reflect.Proxy |
aoqi@0 | 89 | // in that it allows property access, method calls be trapped |
aoqi@0 | 90 | // by 'magic' methods like __get__, __call__. |
aoqi@0 | 91 | function wrapElement(elem) { |
aoqi@0 | 92 | if (! elem) { |
aoqi@0 | 93 | return elem; |
aoqi@0 | 94 | } |
aoqi@0 | 95 | return new JSAdapter() { |
aoqi@0 | 96 | // getter to expose child elements and attributes by name |
aoqi@0 | 97 | __get__: function(name) { |
aoqi@0 | 98 | if (typeof name == 'string') { |
aoqi@0 | 99 | if (name.startsWith('@')) { |
aoqi@0 | 100 | var attr = elem.getAttributeNode(name.substring(1)); |
aoqi@0 | 101 | return !attr? undefined : attr.value; |
aoqi@0 | 102 | } |
aoqi@0 | 103 | |
aoqi@0 | 104 | var arr = getChildElements(elem, name); |
aoqi@0 | 105 | if (arr.length == 1) { |
aoqi@0 | 106 | // single child element, expose as single element |
aoqi@0 | 107 | return arr[0]; |
aoqi@0 | 108 | } else { |
aoqi@0 | 109 | // multiple children of given name, expose as array |
aoqi@0 | 110 | return arr; |
aoqi@0 | 111 | } |
aoqi@0 | 112 | } |
aoqi@0 | 113 | return undefined; |
aoqi@0 | 114 | }, |
aoqi@0 | 115 | |
aoqi@0 | 116 | __call__: function(name) { |
aoqi@0 | 117 | // toString override to get text content of this Element |
aoqi@0 | 118 | if (name == 'toString' || name == 'valueOf') { |
aoqi@0 | 119 | return getElemText(elem); |
aoqi@0 | 120 | } |
aoqi@0 | 121 | return undefined; |
aoqi@0 | 122 | } |
aoqi@0 | 123 | } |
aoqi@0 | 124 | } |
aoqi@0 | 125 | |
aoqi@0 | 126 | // generate HTML using here-doc and string interpolation |
aoqi@0 | 127 | function getBooksHtml() { |
aoqi@0 | 128 | var doc = parseXML("http://www.gutenberg.org/cache/epub/feeds/today.rss"); |
aoqi@0 | 129 | // wrap document root Element as script convenient object |
aoqi@0 | 130 | var rss = wrapElement(doc.documentElement); |
aoqi@0 | 131 | print("rss file version " + rss['@version']); |
aoqi@0 | 132 | |
aoqi@0 | 133 | var str = <<HEAD |
aoqi@0 | 134 | |
aoqi@0 | 135 | <html> |
aoqi@0 | 136 | <title>${rss.channel.title}</title> |
aoqi@0 | 137 | <body> |
aoqi@0 | 138 | <h1>${rss.channel.description}</h1> |
aoqi@0 | 139 | <p> |
aoqi@0 | 140 | Published on ${rss.channel.pubDate} |
aoqi@0 | 141 | </p> |
aoqi@0 | 142 | |
aoqi@0 | 143 | HEAD |
aoqi@0 | 144 | |
aoqi@0 | 145 | var items = rss.channel.item; |
aoqi@0 | 146 | for each (var i in items) { |
aoqi@0 | 147 | str += <<LIST |
aoqi@0 | 148 | |
aoqi@0 | 149 | <dl> |
aoqi@0 | 150 | <dt><a href="${i.link}">${i.title}</a></dt> |
aoqi@0 | 151 | <dd>${i.description}</dd> |
aoqi@0 | 152 | </dl> |
aoqi@0 | 153 | |
aoqi@0 | 154 | LIST |
aoqi@0 | 155 | } |
aoqi@0 | 156 | str += <<END |
aoqi@0 | 157 | |
aoqi@0 | 158 | </body> |
aoqi@0 | 159 | </html> |
aoqi@0 | 160 | |
aoqi@0 | 161 | END |
aoqi@0 | 162 | return str; |
aoqi@0 | 163 | } |
aoqi@0 | 164 | |
aoqi@0 | 165 | // write the string to the given file |
aoqi@0 | 166 | function writeTo(file, str) { |
aoqi@0 | 167 | var w = new PrintWriter(new FileWriter(file)); |
aoqi@0 | 168 | try { |
aoqi@0 | 169 | w.print(str); |
aoqi@0 | 170 | } finally { |
aoqi@0 | 171 | w.close(); |
aoqi@0 | 172 | } |
aoqi@0 | 173 | } |
aoqi@0 | 174 | |
aoqi@0 | 175 | // generate books HTML |
aoqi@0 | 176 | var str = getBooksHtml(); |
aoqi@0 | 177 | |
aoqi@0 | 178 | // write to file. __DIR__ is directory where |
aoqi@0 | 179 | // this script is stored. |
aoqi@0 | 180 | var file = new File(__DIR__ + "books.html"); |
aoqi@0 | 181 | writeTo(file, str); |
aoqi@0 | 182 | |
aoqi@0 | 183 | // show it by desktop browser |
aoqi@0 | 184 | try { |
aoqi@0 | 185 | var Desktop = Java.type("java.awt.Desktop"); |
aoqi@0 | 186 | Desktop.desktop.browse(file.toURI()); |
aoqi@0 | 187 | } catch (e) { |
aoqi@0 | 188 | print(e); |
aoqi@0 | 189 | } |