|
Groovy example source code file (StreamingDOMBuilder.groovy)
The Groovy StreamingDOMBuilder.groovy source code/* * Copyright 2003-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package groovy.xml import javax.xml.parsers.DocumentBuilderFactory import org.w3c.dom.Node import groovy.xml.streamingmarkupsupport.AbstractStreamingBuilder import groovy.xml.streamingmarkupsupport.BaseMarkupBuilder class StreamingDOMBuilder extends AbstractStreamingBuilder { def pendingStack = [] def defaultNamespaceStack = [""] def commentClosure = {doc, pendingNamespaces, namespaces, namespaceSpecificTags, prefix, attrs, body, dom -> def comment = dom.document.createComment(body) if (comment != null) { dom.element.appendChild(comment) } } def piClosure = {doc, pendingNamespaces, namespaces, namespaceSpecificTags, prefix, attrs, body, dom -> attrs.each {target, instruction -> def pi = null if (instruction instanceof Map) { def buf = new StringBuffer() instruction.each { name, value -> if (value.toString().contains('"')) { buf.append(" $name='$value'") } else { buf.append(" $name=\"$value\"" ) } } pi = dom.document.createProcessingInstruction(target, buf.toString()) } else { pi = dom.document.createProcessingInstruction(target, instruction) } if (pi != null) { dom.element.appendChild(pi) } } } def noopClosure = {doc, pendingNamespaces, namespaces, namespaceSpecificTags, prefix, attrs, body, dom -> if (body instanceof Closure) { def body1 = body.clone() body1.delegate = doc body1(doc) } else if (body instanceof Buildable) { body.build(doc) } else if (body != null) { body.each { if (it instanceof Closure) { def body1 = it.clone() body1.delegate = doc body1(doc) } else if (it instanceof Buildable) { it.build(doc) } else { dom.element.appendChild(dom.document.createTextNode(it)) } } } } def tagClosure = {tag, doc, pendingNamespaces, namespaces, namespaceSpecificTags, prefix, attrs, body, dom -> def attributes = [] def nsAttributes = [] def defaultNamespace = defaultNamespaceStack.last() attrs.each {key, value -> if (key.contains('$')) { def parts = key.tokenize('$') def namespaceUri = null if (namespaces.containsKey(parts[0])) { namespaceUri = namespaces[parts[0]] nsAttributes.add([namespaceUri, "${parts[0]}:${parts[1]}", "$value"]) } else { throw new GroovyRuntimeException("bad attribute namespace tag in ${key}") } } else { attributes.add([key, value]) } } def hiddenNamespaces = [:] pendingNamespaces.each {key, value -> if (key == ':') { defaultNamespace = "$value" nsAttributes.add(["http://www.w3.org/2000/xmlns/", "xmlns", defaultNamespace]) } else { hiddenNamespaces[key] = namespaces[key] namespaces[key] = value nsAttributes.add(["http://www.w3.org/2000/xmlns/", "xmlns:${key}", "$value"]) } } // setup the tag info def uri = defaultNamespace def qualifiedName = tag if (prefix != "") { if (namespaces.containsKey(prefix)) { uri = namespaces[prefix] } else if (pendingNamespaces.containsKey(prefix)) { uri = pendingNamespaces[prefix] } else { throw new GroovyRuntimeException("Namespace prefix: ${prefix} is not bound to a URI") } if (prefix != ":") { qualifiedName = prefix + ":" + tag } } def element = dom.document.createElementNS(uri, qualifiedName) nsAttributes.each { element.setAttributeNS(it[0], it[1], it[2]) } attributes.each { element.setAttribute(it[0], it[1]) } dom.element.appendChild(element) dom.element = element if (body != null) { defaultNamespaceStack.push defaultNamespace pendingStack.add pendingNamespaces.clone() pendingNamespaces.clear() if (body instanceof Closure) { def body1 = body.clone() body1.delegate = doc body1(doc) } else if (body instanceof Buildable) { body.build(doc) } else { body.each { if (it instanceof Closure) { def body1 = it.clone() body1.delegate = doc body1(doc) } else if (it instanceof Buildable) { it.build(doc) } else { dom.element.appendChild(dom.document.createTextNode(it)) } } } pendingNamespaces.clear() pendingNamespaces.putAll pendingStack.pop() defaultNamespaceStack.pop() } dom.element = dom.element.getParentNode() hiddenNamespaces.each { key, value -> if (value == null) namespaces.remove key else namespaces[key] = value } } def builder = null StreamingDOMBuilder() { specialTags.putAll(['yield':noopClosure, 'yieldUnescaped':noopClosure, 'comment':commentClosure, 'pi':piClosure]) def nsSpecificTags = [':' : [tagClosure, tagClosure, [:]], // the default namespace 'http://www.w3.org/2000/xmlns/' : [tagClosure, tagClosure, [:]], 'http://www.codehaus.org/Groovy/markup/keywords' : [badTagClosure, tagClosure, specialTags]] this.builder = new BaseMarkupBuilder(nsSpecificTags) } def bind(closure) { def boundClosure = this.builder.bind(closure) return { if (it instanceof Node) { def document = it.getOwnerDocument() boundClosure.trigger = ['document' : document, 'element' : it] return document } else { def dBuilder = DocumentBuilderFactory.newInstance() dBuilder.namespaceAware = true def newDocument = dBuilder.newDocumentBuilder().newDocument() boundClosure.trigger = ['document' : newDocument, 'element' : newDocument] return newDocument } } } } Other Groovy examples (source code examples)Here is a short list of links related to this Groovy StreamingDOMBuilder.groovy source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.