1 package groovy.xml.streamingmarkupsupport;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 import groovy.lang.Closure;
48 import groovy.lang.GroovyInterceptable;
49
50 import java.util.Collections;
51 import java.util.HashMap;
52 import java.util.Map;
53
54 public class BaseMarkupBuilder extends Builder {
55 public BaseMarkupBuilder(final Map namespaceMethodMap) {
56 super(namespaceMethodMap);
57 }
58
59 public Object bind(final Closure root) {
60 return new Document(root, this.namespaceMethodMap);
61 }
62
63 private static class Document extends Built implements GroovyInterceptable {
64 private Object out;
65 private final Map pendingNamespaces = new HashMap();
66 private final Map namespaces = new HashMap();
67 private String prefix = "";
68
69 public Document(final Closure root, final Map namespaceMethodMap) {
70 super(root, namespaceMethodMap);
71
72 this.namespaces.put("xml", "http://www.w3.org/XML/1998/namespace"); // built in namespace
73 this.namespaces.put("mkp", "http://www.codehaus.org/Groovy/markup/keywords"); // pseudo namespace for markup keywords
74 }
75
76
77
78
79 public Object invokeMethod(final String name, final Object args) {
80 final Object[] arguments = (Object[]) args;
81 Map attrs = Collections.EMPTY_MAP;
82 Object body = null;
83
84
85
86
87
88 for (int i = 0; i != arguments.length; i++) {
89 final Object arg = arguments[i];
90
91 if (arg instanceof Map) {
92 attrs = (Map)arg;
93 } else if (arg instanceof Closure) {
94 final Closure c = ((Closure) arg);
95
96 c.setDelegate(this);
97 body = c.asWritable();
98 } else {
99 body = arg;
100 }
101 }
102
103
104
105
106 final Object uri;
107
108 if (this.pendingNamespaces.containsKey(this.prefix)) {
109 uri = this.pendingNamespaces.get(this.prefix);
110 } else if (this.namespaces.containsKey(this.prefix)) {
111 uri = this.namespaces.get(this.prefix);
112 } else {
113 uri = ":";
114 }
115
116 final Object[] info = (Object[])this.namespaceSpecificTags.get(uri);
117 final Map tagMap = (Map)info[2];
118 final Closure defaultTagClosure = (Closure)info[0];
119
120 final String prefix = this.prefix;
121 this.prefix = "";
122
123 if (tagMap.containsKey(name)) {
124 return ((Closure)tagMap.get(name)).call(new Object[]{this, this.pendingNamespaces, this.namespaces, this.namespaceSpecificTags, prefix, attrs, body, this.out});
125 } else {
126 return defaultTagClosure.call(new Object[]{name, this, this.pendingNamespaces, this.namespaces, this.namespaceSpecificTags, prefix, attrs, body, this.out});
127 }
128 }
129
130
131
132
133 public Object getProperty(final String property) {
134 this.prefix = property;
135 return this;
136 }
137
138
139
140
141 public void setProperty(String property, Object newValue) {
142 if ("trigger".equals(property)) {
143 this.out = newValue;
144 this.root.call(this);
145 } else {
146 super.setProperty(property, newValue);
147 }
148 }
149 }
150 }