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