1
2
3
4
5
6
7
8
9
10
11 package org.astrogrid.jes.jobscheduler.impl.groovy;
12
13 import org.apache.commons.logging.Log;
14 import org.apache.commons.logging.LogFactory;
15
16 import groovy.lang.Binding;
17 import groovy.lang.MissingPropertyException;
18
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Map;
24
25 /*** represents set of variable bindings in scope.
26 * allows additional scopes to be added and removed.
27 * scopes introduce new bindings.
28 * asignements to existing bindings in parent scopes update, rather than shadow.
29 * @author Noel Winstanley nw@jb.man.ac.uk 28-Jul-2004
30 *
31 */
32 public class Vars{
33 /***
34 * Commons Logger for this class
35 */
36 private static final Log logger = LogFactory.getLog(Vars.class);
37
38 /*** Construct a new Bindings
39 *
40 */
41 public Vars() {
42 super();
43 l = new ArrayList();
44 l.add(new HashMap());
45 }
46
47 protected List l;
48
49
50
51 public Object get(String name) {
52 Map e = findMapWithKey(name);
53 if (e == null) {
54 return null;
55 }
56 return e.get(name);
57 }
58
59 public void set(String name,Object value) {
60 Map e = findMapWithKey(name);
61 if (e == null) {
62 e = getInnermost();
63 }
64 e.put(name,value);
65 }
66
67 private Map getInnermost() {
68 return (Map)l.get(l.size() -1);
69 }
70 private Map findMapWithKey(String name) {
71 for (int i = l.size() - 1; i >= 0; i--) {
72 Map m = (Map)l.get(i);
73 if (m.containsKey(name)) {
74 return m;
75 }
76 }
77 return null;
78 }
79
80
81 public void unset(String name) {
82 Map e = findMapWithKey(name);
83 if (e !=null) {
84 e.remove(name);
85 }
86 }
87 /*** Branch these vars
88 * this is a very shallow copy. existing scopes are shared between the original and copy.
89 * however, new scopes in the copy do not appear in the original.
90 */
91 public Vars branchVars() {
92 Vars copy = new Vars();
93 copy.l.clear();
94 copy.l.addAll(this.l);
95 return copy;
96 }
97
98 public void newScope() {
99 l.add(new HashMap());
100 }
101
102 public void removeScope() {
103 l.remove(l.size() - 1);
104 }
105
106
107 /*** Add the variables defined in this collection to a binding, plus the 'vars' object itself.
108 * @param bodyBinding
109 */
110 public void addToBinding(Binding bodyBinding) {
111 /*** NWW - 9/12/04 don't like this - not necessary - problematic
112 bodyBinding.setVariable("vars",this);
113 */
114 for (Iterator j = l.iterator(); j.hasNext(); ) {
115 Map e = (Map)j.next();
116 for (Iterator i = e.entrySet().iterator(); i.hasNext(); ) {
117 Map.Entry var = (Map.Entry)i.next();
118 bodyBinding.setVariable(var.getKey().toString(),var.getValue());
119 }
120 }
121 }
122
123 /*** Find the variables defined in this collection in the binding, copy back across again.
124 *<p>
125 *any new variables defined in the script must have been done directly - through accessing this object already. so just need to look for the values of existing vars.
126 * @param bodyBinding
127 */
128
129 public void readFromBinding(Binding bodyBinding) {
130 for (int j = 0; j < l.size(); j++){
131 Map e = (Map)l.get(j);
132 for (Iterator i = e.entrySet().iterator(); i.hasNext(); ) {
133 Map.Entry var = (Map.Entry)i.next();
134 try {
135 Object newValue = bodyBinding.getVariable(var.getKey().toString());
136 var.setValue(newValue);
137 } catch (MissingPropertyException missing) {
138 /*** don't think this is possible */
139 logger.warn(missing);
140 }
141 }
142 }
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160 }
161
162
163 /***
164 * Override hashCode.
165 *
166 * @return the Objects hashcode.
167 */
168 public int hashCode() {
169 int hashCode = 1;
170 hashCode = 31 * hashCode + (l == null ? 0 : l.hashCode());
171 return hashCode;
172 }
173 public String toString() {
174 StringBuffer buffer = new StringBuffer();
175 buffer.append("[Vars:");
176 buffer.append(" l: ");
177 buffer.append(l);
178 buffer.append("]");
179 return buffer.toString();
180 }
181 /***
182 * Returns <code>true</code> if this <code>Vars</code> is the same as the o argument.
183 *
184 * @return <code>true</code> if this <code>Vars</code> is the same as the o argument.
185 */
186 public boolean equals(Object o) {
187 if (this == o) {
188 return true;
189 }
190 if (o == null) {
191 return false;
192 }
193 if (o.getClass() != getClass()) {
194 return false;
195 }
196 Vars castedObj = (Vars) o;
197 return ((this.l == null ? castedObj.l == null : this.l
198 .equals(castedObj.l)));
199 }
200 }
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246