1:
37:
38: package ;
39:
40: import ;
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50:
51:
56: public class Bindings
57: implements XPathVariableResolver, Cloneable
58: {
59:
60: static final int VARIABLE = 0;
61: static final int PARAM = 1;
62: static final int WITH_PARAM = 2;
63:
64: final Stylesheet stylesheet;
65:
66:
69: final LinkedList variables;
70:
71:
74: final LinkedList parameters;
75:
76:
79: final LinkedList withParameters;
80:
81:
84: boolean global;
85:
86: Bindings(Stylesheet stylesheet)
87: {
88: this.stylesheet = stylesheet;
89: variables = new LinkedList();
90: parameters = new LinkedList();
91: withParameters = new LinkedList();
92: for (int i = 0; i < 3; i++)
93: {
94: push(i);
95: }
96: }
97:
98: public Object clone()
99: {
100: try
101: {
102: return (Bindings) super.clone();
103: }
104: catch (CloneNotSupportedException e)
105: {
106: throw new Error(e.getMessage());
107: }
108: }
109:
110: void push(int type)
111: {
112: switch (type)
113: {
114: case VARIABLE:
115: variables.addFirst(new HashMap());
116: break;
117: case PARAM:
118: parameters.addFirst(new HashMap());
119: break;
120: case WITH_PARAM:
121: withParameters.addFirst(new HashMap());
122: break;
123: }
124: }
125:
126: void pop(int type)
127: {
128: switch (type)
129: {
130: case VARIABLE:
131: variables.removeFirst();
132: break;
133: case PARAM:
134: parameters.removeFirst();
135: break;
136: case WITH_PARAM:
137: withParameters.removeFirst();
138: break;
139: }
140: }
141:
142: public boolean containsKey(QName name, int type)
143: {
144: if (global)
145: {
146: Map ctx1 = (Map) variables.getLast();
147: Map ctx2 = (Map) parameters.getLast();
148: return (ctx1.containsKey(name) || ctx2.containsKey(name));
149: }
150: Iterator i = null;
151: switch (type)
152: {
153: case VARIABLE:
154: i = variables.iterator();
155: break;
156: case PARAM:
157: i = parameters.iterator();
158: break;
159: case WITH_PARAM:
160: Map ctx = (Map) withParameters.getFirst();
161: return ctx.containsKey(name);
162: }
163: if (i != null)
164: {
165: while (i.hasNext())
166: {
167: Map ctx = (Map) i.next();
168: if (ctx.containsKey(name))
169: {
170: return true;
171: }
172: }
173: }
174: return false;
175: }
176:
177: public Object get(QName name, Node context, int pos, int len)
178: {
179: if (global)
180: {
181: Map ctx = (Map) variables.getLast();
182: Object ret = ctx.get(name);
183: if (ret == null)
184: {
185: ctx = (Map) parameters.getLast();
186: ret = ctx.get(name);
187: }
188: return ret;
189: }
190:
191:
192: Object ret = null;
193:
194:
195: {
196: Map cwp = (Map) withParameters.getFirst();
197: ret = cwp.get(name);
198:
199: }
200: if (ret == null)
201: {
202: for (Iterator i = variables.iterator(); i.hasNext() && ret == null; )
203: {
204: Map vctx = (Map) i.next();
205: ret = vctx.get(name);
206: }
207:
208: }
209: if (ret == null)
210: {
211: for (Iterator i = parameters.iterator(); i.hasNext() && ret == null; )
212: {
213: Map pctx = (Map) i.next();
214: ret = pctx.get(name);
215: }
216:
217: }
218:
223: if (ret instanceof Node)
224: {
225: ret = Collections.singleton(ret);
226: }
227: if (ret == null)
228: {
229: ret = "";
230: }
231:
232: return ret;
233: }
234:
235: void set(QName name, Object value, int type)
236: {
237: switch (type)
238: {
239: case VARIABLE:
240: Map vctx = (Map) variables.getFirst();
241: vctx.put(name, value);
242: break;
243: case PARAM:
244: Map pctx = (Map) parameters.getFirst();
245: pctx.put(name, value);
246: break;
247: case WITH_PARAM:
248: Map wctx = (Map) withParameters.getFirst();
249: wctx.put(name, value);
250: break;
251: }
252:
253: }
254:
255: public Object resolveVariable(QName qName)
256: {
257: return get(qName, null, 1, 1);
258: }
259:
260: public String toString()
261: {
262: StringBuffer buf = new StringBuffer();
263: boolean next = false;
264: Collection seen = new HashSet();
265: Map wctx = (Map) withParameters.getFirst();
266: buf.append('(');
267: for (Iterator i = wctx.entrySet().iterator(); i.hasNext(); )
268: {
269: if (next)
270: {
271: buf.append(',');
272: }
273: else
274: {
275: next = true;
276: }
277: Map.Entry entry = (Map.Entry) i.next();
278: Object key = entry.getKey();
279: if (!seen.contains(key))
280: {
281: buf.append(key);
282: buf.append('=');
283: buf.append(entry.getValue());
284: seen.add(key);
285: }
286: }
287: buf.append(')');
288: next = false;
289: seen.clear();
290: buf.append('{');
291: for (Iterator i = variables.iterator(); i.hasNext(); )
292: {
293: Map ctx = (Map) i.next();
294: for (Iterator j = ctx.entrySet().iterator(); j.hasNext(); )
295: {
296: if (next)
297: {
298: buf.append(',');
299: }
300: else
301: {
302: next = true;
303: }
304: Map.Entry entry = (Map.Entry) j.next();
305: Object key = entry.getKey();
306: if (!seen.contains(key))
307: {
308: buf.append(key);
309: buf.append('=');
310: buf.append(entry.getValue());
311: seen.add(key);
312: }
313: }
314: }
315: buf.append('}');
316: next = false;
317: seen.clear();
318: buf.append('[');
319: for (Iterator i = parameters.iterator(); i.hasNext(); )
320: {
321: Map ctx = (Map) i.next();
322: for (Iterator j = ctx.entrySet().iterator(); j.hasNext(); )
323: {
324: if (next)
325: {
326: buf.append(',');
327: }
328: else
329: {
330: next = true;
331: }
332: Map.Entry entry = (Map.Entry) j.next();
333: Object key = entry.getKey();
334: if (!seen.contains(key))
335: {
336: buf.append(key);
337: buf.append('=');
338: buf.append(entry.getValue());
339: seen.add(key);
340: }
341: }
342: }
343: buf.append(']');
344: return buf.toString();
345: }
346:
347: }