~ubuntu-branches/ubuntu/lucid/groovy/lucid

« back to all changes in this revision

Viewing changes to src/main/groovy/xml/StreamingDOMBuilder.groovy

  • Committer: Bazaar Package Importer
  • Author(s): Varun Hiremath, Torsten Werner, Varun Hiremath
  • Date: 2009-04-01 19:24:19 UTC
  • mfrom: (3.2.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090401192419-c5mpylqhcdkv3zuv
Tags: 1.6.0-1
[ Torsten Werner ]
* New upstream release (Closes: #521648)
* Remove Build-Depends: libclassworlds-java.
* Switch to source and target version 1.5.

[ Varun Hiremath ]
* Fix build.xml file
* Add ivy to Build-Depends
* Remove unnecessary Depends -- collections3, mx4j and xpp3 
* Add build.diff patch to fix a build error
* Use quilt to manage patches
* Update manpage (Closes: #507862)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 2003-2007 the original author or authors.
3
 
 *
4
 
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 
 * you may not use this file except in compliance with the License.
6
 
 * You may obtain a copy of the License at
7
 
 *
8
 
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 
 *
10
 
 * Unless required by applicable law or agreed to in writing, software
11
 
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 
 * See the License for the specific language governing permissions and
14
 
 * limitations under the License.
15
 
 */
16
 
 
17
 
package groovy.xml
18
 
 
19
 
import javax.xml.parsers.DocumentBuilderFactory
20
 
import org.w3c.dom.Node
21
 
 
22
 
import groovy.xml.streamingmarkupsupport.AbstractStreamingBuilder
23
 
import groovy.xml.streamingmarkupsupport.StreamingMarkupWriter
24
 
import groovy.xml.streamingmarkupsupport.BaseMarkupBuilder
25
 
 
26
 
class StreamingDOMBuilder extends AbstractStreamingBuilder {
27
 
    def pendingStack = []
28
 
    def commentClosure = {doc, pendingNamespaces, namespaces, namespaceSpecificTags, prefix, attrs, body, dom ->
29
 
        def comment = dom.document.createComment(body)
30
 
        if (comment != null) {
31
 
            dom.element.appendChild(comment)
32
 
        }
33
 
    }
34
 
    def piClosure = {doc, pendingNamespaces, namespaces, namespaceSpecificTags, prefix, attrs, body, dom ->
35
 
        attrs.each {target, instruction ->
36
 
            def pi = null
37
 
            if (instruction instanceof Map) {
38
 
                def buf = new StringBuffer()
39
 
                instruction.each { name, value ->
40
 
                    if (value.toString().contains('"')) {
41
 
                        buf.append(" $name='$value'")
42
 
                    } else {
43
 
                        buf.append(" $name=\"$value\"" )
44
 
                    }
45
 
                }
46
 
                pi = dom.document.createProcessingInstruction(target, buf.toString())
47
 
            } else {
48
 
                pi = dom.document.createProcessingInstruction(target, instruction)
49
 
            }
50
 
            if (pi != null) {
51
 
                dom.element.appendChild(pi)
52
 
            }
53
 
        }
54
 
    }
55
 
    def noopClosure = {doc, pendingNamespaces, namespaces, namespaceSpecificTags, prefix, attrs, body, dom ->
56
 
        if (body instanceof Closure) {
57
 
            def body1 = body.clone()
58
 
            body1.delegate = doc
59
 
            body1(doc)
60
 
        } else if (body instanceof Buildable) {
61
 
            body.build(doc)
62
 
        } else if (body != null) {
63
 
            body.each {
64
 
                if (it instanceof Closure) {
65
 
                    def body1 = it.clone()
66
 
                    body1.delegate = doc
67
 
                    body1(doc)
68
 
                } else if (it instanceof Buildable) {
69
 
                    it.build(doc)
70
 
                } else {
71
 
                    dom.element.appendChild(dom.document.createTextNode(it))
72
 
                }
73
 
            }
74
 
        }
75
 
    }
76
 
    def tagClosure = {tag, doc, pendingNamespaces, namespaces, namespaceSpecificTags, prefix, attrs, body, dom ->
77
 
        def attributes = []
78
 
        def nsAttributes = []
79
 
 
80
 
        attrs.each {key, value ->
81
 
            if (key.contains('$')) {
82
 
                def parts = key.tokenize('$')
83
 
                def namespaceUri = null
84
 
 
85
 
                if (namespaces.containsKey(parts[0])) {
86
 
                    namespaceUri = namespaces[parts[0]]
87
 
 
88
 
                    nsAttributes.add([namespaceUri, "${parts[0]}:${parts[1]}", value])
89
 
 
90
 
                } else {
91
 
                    throw new GroovyRuntimeException("bad attribute namespace tag in ${key}")
92
 
                }
93
 
            } else {
94
 
                attributes.add([key, value])
95
 
            }
96
 
        }
97
 
 
98
 
        def hiddenNamespaces = [:]
99
 
 
100
 
        pendingNamespaces.each {key, value ->
101
 
            hiddenNamespaces[key] = namespaces[key]
102
 
            namespaces[key] = value
103
 
            nsAttributes.add(["http://www.w3.org/2000/xmlns/", "xmlns:${key}", value])
104
 
 
105
 
        }
106
 
 
107
 
        // setup the tag info
108
 
 
109
 
        def uri = ""
110
 
        def qualifiedName = tag
111
 
 
112
 
        if (prefix != "") {
113
 
            if (namespaces.containsKey(prefix)) {
114
 
                uri = namespaces[prefix]
115
 
            } else if (pendingNamespaces.containsKey(prefix)) {
116
 
                uri = pendingNamespaces[prefix]
117
 
            } else {
118
 
                throw new GroovyRuntimeException("Namespace prefix: ${prefix} is not bound to a URI")
119
 
            }
120
 
            if (prefix != ":") {
121
 
                qualifiedName = prefix + ":" + tag
122
 
            }
123
 
        }
124
 
 
125
 
        def element = dom.document.createElementNS(uri, qualifiedName)
126
 
 
127
 
        nsAttributes.each {
128
 
            element.setAttributeNS(it[0], it[1], it[2])
129
 
        }
130
 
        attributes.each {
131
 
            element.setAttribute(it[0], it[1])
132
 
        }
133
 
 
134
 
        dom.element.appendChild(element)
135
 
        dom.element = element
136
 
 
137
 
        if (body != null) {
138
 
            pendingStack.add pendingNamespaces.clone()
139
 
            pendingNamespaces.clear()
140
 
 
141
 
            if (body instanceof Closure) {
142
 
                def body1 = body.clone()
143
 
 
144
 
                body1.delegate = doc
145
 
                body1(doc)
146
 
            } else if (body instanceof Buildable) {
147
 
                body.build(doc)
148
 
            } else {
149
 
                body.each {
150
 
                    if (it instanceof Closure) {
151
 
                        def body1 = it.clone()
152
 
 
153
 
                        body1.delegate = doc
154
 
                        body1(doc)
155
 
                    } else if (it instanceof Buildable) {
156
 
                        it.build(doc)
157
 
                    } else {
158
 
                        dom.element.appendChild(dom.document.createTextNode(it))
159
 
                    }
160
 
                }
161
 
            }
162
 
 
163
 
            pendingNamespaces.clear()
164
 
            pendingNamespaces.putAll pendingStack.pop()
165
 
        }
166
 
 
167
 
        dom.element = dom.element.getParentNode()
168
 
 
169
 
        hiddenNamespaces.each { key, value ->
170
 
            if (value == null) namespaces.remove key
171
 
            else namespaces[key] = value
172
 
        }
173
 
    }
174
 
 
175
 
    def builder = null
176
 
 
177
 
    StreamingDOMBuilder() {
178
 
        specialTags.putAll(['yield':noopClosure,
179
 
                            'yieldUnescaped':noopClosure,
180
 
                            'comment':commentClosure,
181
 
                            'pi':piClosure])
182
 
        def nsSpecificTags = [':'                                          : [tagClosure, tagClosure, [:]],    // the default namespace
183
 
                          'http://www.w3.org/XML/1998/namespace'           : [tagClosure, tagClosure, [:]],
184
 
                          'http://www.codehaus.org/Groovy/markup/keywords' : [badTagClosure, tagClosure, specialTags]]
185
 
        this.builder = new BaseMarkupBuilder(nsSpecificTags)
186
 
    }
187
 
 
188
 
    def bind(closure) {
189
 
        def boundClosure = this.builder.bind(closure)
190
 
        return {
191
 
            if (it instanceof Node) {
192
 
                def document = it.getOwnerDocument()
193
 
                boundClosure.trigger = ['document' : document, 'element' : it]
194
 
                return document
195
 
            } else {
196
 
                def newDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()
197
 
                boundClosure.trigger = ['document' : newDocument, 'element' : newDocument]
198
 
                return newDocument
199
 
            }
200
 
        }
201
 
    }
202
 
}
 
1
/*
 
2
 * Copyright 2003-2007 the original author or authors.
 
3
 *
 
4
 * Licensed under the Apache License, Version 2.0 (the "License");
 
5
 * you may not use this file except in compliance with the License.
 
6
 * You may obtain a copy of the License at
 
7
 *
 
8
 *     http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
10
 * Unless required by applicable law or agreed to in writing, software
 
11
 * distributed under the License is distributed on an "AS IS" BASIS,
 
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
13
 * See the License for the specific language governing permissions and
 
14
 * limitations under the License.
 
15
 */
 
16
 
 
17
package groovy.xml
 
18
 
 
19
import javax.xml.parsers.DocumentBuilderFactory
 
20
import org.w3c.dom.Node
 
21
 
 
22
import groovy.xml.streamingmarkupsupport.AbstractStreamingBuilder
 
23
import groovy.xml.streamingmarkupsupport.BaseMarkupBuilder
 
24
 
 
25
class StreamingDOMBuilder extends AbstractStreamingBuilder {
 
26
    def pendingStack = []
 
27
    def defaultNamespaceStack = [""]
 
28
    def commentClosure = {doc, pendingNamespaces, namespaces, namespaceSpecificTags, prefix, attrs, body, dom ->
 
29
        def comment = dom.document.createComment(body)
 
30
        if (comment != null) {
 
31
            dom.element.appendChild(comment)
 
32
        }
 
33
    }
 
34
    def piClosure = {doc, pendingNamespaces, namespaces, namespaceSpecificTags, prefix, attrs, body, dom ->
 
35
        attrs.each {target, instruction ->
 
36
            def pi = null
 
37
            if (instruction instanceof Map) {
 
38
                def buf = new StringBuffer()
 
39
                instruction.each { name, value ->
 
40
                    if (value.toString().contains('"')) {
 
41
                        buf.append(" $name='$value'")
 
42
                    } else {
 
43
                        buf.append(" $name=\"$value\"" )
 
44
                    }
 
45
                }
 
46
                pi = dom.document.createProcessingInstruction(target, buf.toString())
 
47
            } else {
 
48
                pi = dom.document.createProcessingInstruction(target, instruction)
 
49
            }
 
50
            if (pi != null) {
 
51
                dom.element.appendChild(pi)
 
52
            }
 
53
        }
 
54
    }
 
55
    def noopClosure = {doc, pendingNamespaces, namespaces, namespaceSpecificTags, prefix, attrs, body, dom ->
 
56
        if (body instanceof Closure) {
 
57
            def body1 = body.clone()
 
58
            body1.delegate = doc
 
59
            body1(doc)
 
60
        } else if (body instanceof Buildable) {
 
61
            body.build(doc)
 
62
        } else if (body != null) {
 
63
            body.each {
 
64
                if (it instanceof Closure) {
 
65
                    def body1 = it.clone()
 
66
                    body1.delegate = doc
 
67
                    body1(doc)
 
68
                } else if (it instanceof Buildable) {
 
69
                    it.build(doc)
 
70
                } else {
 
71
                    dom.element.appendChild(dom.document.createTextNode(it))
 
72
                }
 
73
            }
 
74
        }
 
75
    }
 
76
    def tagClosure = {tag, doc, pendingNamespaces, namespaces, namespaceSpecificTags, prefix, attrs, body, dom ->
 
77
        def attributes = []
 
78
        def nsAttributes = []
 
79
        def defaultNamespace = defaultNamespaceStack.last()
 
80
 
 
81
        attrs.each {key, value ->
 
82
            if (key.contains('$')) {
 
83
                def parts = key.tokenize('$')
 
84
                def namespaceUri = null
 
85
 
 
86
                if (namespaces.containsKey(parts[0])) {
 
87
                    namespaceUri = namespaces[parts[0]]
 
88
 
 
89
                    nsAttributes.add([namespaceUri, "${parts[0]}:${parts[1]}", "$value"])
 
90
 
 
91
                } else {
 
92
                    throw new GroovyRuntimeException("bad attribute namespace tag in ${key}")
 
93
                }
 
94
            } else {
 
95
                attributes.add([key, value])
 
96
            }
 
97
        }
 
98
 
 
99
        def hiddenNamespaces = [:]
 
100
 
 
101
        pendingNamespaces.each {key, value ->
 
102
                if (key == ':') {
 
103
                defaultNamespace = "$value"
 
104
                    nsAttributes.add(["http://www.w3.org/2000/xmlns/", "xmlns", defaultNamespace])
 
105
            } else {
 
106
                    hiddenNamespaces[key] = namespaces[key]
 
107
                    namespaces[key] = value
 
108
                    nsAttributes.add(["http://www.w3.org/2000/xmlns/", "xmlns:${key}", "$value"])
 
109
            }
 
110
        }
 
111
 
 
112
        // setup the tag info
 
113
 
 
114
        def uri = defaultNamespace
 
115
        def qualifiedName = tag
 
116
 
 
117
        if (prefix != "") {
 
118
            if (namespaces.containsKey(prefix)) {
 
119
                uri = namespaces[prefix]
 
120
            } else if (pendingNamespaces.containsKey(prefix)) {
 
121
                uri = pendingNamespaces[prefix]
 
122
            } else {
 
123
                throw new GroovyRuntimeException("Namespace prefix: ${prefix} is not bound to a URI")
 
124
            }
 
125
            if (prefix != ":") {
 
126
                qualifiedName = prefix + ":" + tag
 
127
            }
 
128
        }
 
129
 
 
130
        def element = dom.document.createElementNS(uri, qualifiedName)
 
131
 
 
132
        nsAttributes.each {
 
133
            element.setAttributeNS(it[0], it[1], it[2])
 
134
        }
 
135
        attributes.each {
 
136
            element.setAttribute(it[0], it[1])
 
137
        }
 
138
 
 
139
        dom.element.appendChild(element)
 
140
        dom.element = element
 
141
 
 
142
        if (body != null) {
 
143
            defaultNamespaceStack.push defaultNamespace
 
144
            pendingStack.add pendingNamespaces.clone()
 
145
            pendingNamespaces.clear()
 
146
 
 
147
            if (body instanceof Closure) {
 
148
                def body1 = body.clone()
 
149
 
 
150
                body1.delegate = doc
 
151
                body1(doc)
 
152
            } else if (body instanceof Buildable) {
 
153
                body.build(doc)
 
154
            } else {
 
155
                body.each {
 
156
                    if (it instanceof Closure) {
 
157
                        def body1 = it.clone()
 
158
 
 
159
                        body1.delegate = doc
 
160
                        body1(doc)
 
161
                    } else if (it instanceof Buildable) {
 
162
                        it.build(doc)
 
163
                    } else {
 
164
                        dom.element.appendChild(dom.document.createTextNode(it))
 
165
                    }
 
166
                }
 
167
            }
 
168
 
 
169
            pendingNamespaces.clear()
 
170
            pendingNamespaces.putAll pendingStack.pop()
 
171
            defaultNamespaceStack.pop()
 
172
        }
 
173
 
 
174
        dom.element = dom.element.getParentNode()
 
175
 
 
176
        hiddenNamespaces.each { key, value ->
 
177
            if (value == null) namespaces.remove key
 
178
            else namespaces[key] = value
 
179
        }
 
180
    }
 
181
 
 
182
    def builder = null
 
183
 
 
184
    StreamingDOMBuilder() {
 
185
        specialTags.putAll(['yield':noopClosure,
 
186
                            'yieldUnescaped':noopClosure,
 
187
                            'comment':commentClosure,
 
188
                            'pi':piClosure])
 
189
        def nsSpecificTags = [':'                                          : [tagClosure, tagClosure, [:]],    // the default namespace
 
190
                          'http://www.w3.org/2000/xmlns/'                  : [tagClosure, tagClosure, [:]],
 
191
                          'http://www.codehaus.org/Groovy/markup/keywords' : [badTagClosure, tagClosure, specialTags]]
 
192
        this.builder = new BaseMarkupBuilder(nsSpecificTags)
 
193
    }
 
194
 
 
195
    def bind(closure) {
 
196
        def boundClosure = this.builder.bind(closure)
 
197
        return {
 
198
            if (it instanceof Node) {
 
199
                def document = it.getOwnerDocument()
 
200
                boundClosure.trigger = ['document' : document, 'element' : it]
 
201
                return document
 
202
            } else {
 
203
                def dBuilder = DocumentBuilderFactory.newInstance()
 
204
                dBuilder.namespaceAware = true
 
205
                def newDocument = dBuilder.newDocumentBuilder().newDocument()
 
206
                boundClosure.trigger = ['document' : newDocument, 'element' : newDocument]
 
207
                return newDocument
 
208
            }
 
209
        }
 
210
    }
 
211
}