1 package org.codehaus.groovy.sandbox.markup;
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
49 import java.util.Collections;
50 import java.util.HashMap;
51 import java.util.Map;
52
53 public class BaseMarkupBuilder extends Builder {
54 public BaseMarkupBuilder(final Map namespaceMethodMap) {
55 super(namespaceMethodMap);
56 }
57
58 public Object bind(final Closure root) {
59 return new Document(root, this.namespaceMethodMap);
60 }
61
62 private static class Document extends Built {
63 private Object out;
64 private final Map pendingNamespaces = new HashMap();
65 private final Map namespaces = new HashMap();
66 private String prefix = "";
67
68 public Document(final Closure root, final Map namespaceMethodMap) {
69 super(root, namespaceMethodMap);
70
71 this.namespaces.put("xml", "http://www.w3.org/XML/1998/namespace"); // built in namespace
72 this.namespaces.put("mkp", "http://www.codehaus.org/Groovy/markup/keywords"); // pseudo namespace for markup keywords
73 }
74
75
76
77
78 public Object invokeMethod(final String name, final Object args) {
79 final Object[] arguments = (Object[]) args;
80 Map attrs = Collections.EMPTY_MAP;
81 Object body = null;
82
83
84
85
86
87 for (int i = 0; i != arguments.length; i++) {
88 final Object arg = arguments[i];
89
90 if (arg instanceof Map) {
91 attrs = (Map)arg;
92 } else if (arg instanceof Closure) {
93 final Closure c = ((Closure) arg);
94
95 c.setDelegate(this);
96 body = c.asWritable();
97 } else {
98 body = arg;
99 }
100 }
101
102
103
104
105 final Object uri;
106
107 if (this.pendingNamespaces.containsKey(this.prefix)) {
108 uri = this.pendingNamespaces.get(this.prefix);
109 } else if (this.namespaces.containsKey(this.prefix)) {
110 uri = this.namespaces.get(this.prefix);
111 } else {
112 uri = ":";
113 }
114
115 final Object[] info = (Object[])this.namespaceSpecificTags.get(uri);
116 final Map tagMap = (Map)info[2];
117 final Closure defaultTagClosure = (Closure)info[0];
118
119 final String prefix = this.prefix;
120 this.prefix = "";
121
122 if (tagMap.containsKey(name)) {
123 return ((Closure)tagMap.get(name)).call(new Object[]{this, this.pendingNamespaces, this.namespaces, this.namespaceSpecificTags, prefix, attrs, body, this.out});
124 } else {
125 return defaultTagClosure.call(new Object[]{name, this, this.pendingNamespaces, this.namespaces, this.namespaceSpecificTags, prefix, attrs, body, this.out});
126 }
127 }
128
129
130
131
132 public Object getProperty(final String property) {
133 this.prefix = property;
134 return this;
135 }
136
137
138
139
140 public void setProperty(String property, Object newValue) {
141 if ("trigger".equals(property)) {
142 this.out = newValue;
143 this.root.call();
144 } else {
145 super.setProperty(property, newValue);
146 }
147 }
148 }
149 }