1 46 package groovy.util; 47 48 49 import groovy.lang.Closure; 50 import groovy.lang.GroovyObjectSupport; 51 52 import java.util.List ; 53 import java.util.Map ; 54 55 import org.codehaus.groovy.runtime.InvokerHelper; 56 57 64 public abstract class BuilderSupport extends GroovyObjectSupport { 65 66 private Object current; 67 private Closure nameMappingClosure; 68 private BuilderSupport proxyBuilder; 69 70 public BuilderSupport() { 71 this.proxyBuilder = this; 72 } 73 74 public BuilderSupport(BuilderSupport proxyBuilder) { 75 this(null, proxyBuilder); 76 } 77 78 public BuilderSupport(Closure nameMappingClosure, BuilderSupport proxyBuilder) { 79 this.nameMappingClosure = nameMappingClosure; 80 this.proxyBuilder = proxyBuilder; 81 } 82 83 public Object invokeMethod(String methodName, Object args) { 84 Object name = getName(methodName); 85 return doInvokeMethod(methodName, name, args); 86 } 87 88 protected Object doInvokeMethod(String methodName, Object name, Object args) { 89 Object node = null; 90 Closure closure = null; 91 List list = InvokerHelper.asList(args); 92 93 95 switch (list.size()) { 96 case 0: 97 break; 98 case 1: 99 { 100 Object object = list.get(0); 101 if (object instanceof Map ) { 102 node = proxyBuilder.createNode(name, (Map ) object); 103 } else if (object instanceof Closure) { 104 closure = (Closure) object; 105 node = proxyBuilder.createNode(name); 106 } else { 107 node = proxyBuilder.createNode(name, object); 108 } 109 } 110 break; 111 case 2: 112 { 113 Object object1 = list.get(0); 114 Object object2 = list.get(1); 115 if (object1 instanceof Map ) { 116 if (object2 instanceof Closure) { 117 closure = (Closure) object2; 118 node = proxyBuilder.createNode(name, (Map ) object1); 119 } else { 120 node = proxyBuilder.createNode(name, (Map ) object1, object2); 121 } 122 } else { 123 if (object2 instanceof Closure) { 124 closure = (Closure) object2; 125 node = proxyBuilder.createNode(name, object1); 126 } 127 } 128 } 129 break; 130 case 3: 131 { 132 Object attributes = list.get(0); 133 Object value = list.get(1); 134 closure = (Closure) list.get(2); 135 node = proxyBuilder.createNode(name, (Map ) attributes, value); 136 } 137 break; 138 } 139 140 if (node == null) { 141 node = proxyBuilder.createNode(name); 142 } 143 144 if (current != null) { 145 proxyBuilder.setParent(current, node); 146 } 147 148 if (closure != null) { 149 Object oldCurrent = current; 151 current = node; 152 153 setClosureDelegate(closure, node); 155 closure.call(); 156 157 current = oldCurrent; 158 } 159 160 proxyBuilder.nodeCompleted(current, node); 161 return node; 162 } 163 164 175 protected void setClosureDelegate(Closure closure, Object node) { 176 closure.setDelegate(this); 177 } 178 179 protected abstract void setParent(Object parent, Object child); 180 protected abstract Object createNode(Object name); 181 protected abstract Object createNode(Object name, Object value); 182 protected abstract Object createNode(Object name, Map attributes); 183 protected abstract Object createNode(Object name, Map attributes, Object value); 184 185 191 protected Object getName(String methodName) { 192 if (nameMappingClosure != null) { 193 return nameMappingClosure.call(methodName); 194 } 195 return methodName; 196 } 197 198 199 203 protected void nodeCompleted(Object parent, Object node) { 204 } 205 206 protected Object getCurrent() { 207 return current; 208 } 209 210 protected void setCurrent(Object current) { 211 this.current = current; 212 } 213 } 214 | Popular Tags |