1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| |
10 |
| |
11 |
| |
12 |
| |
13 |
| |
14 |
| |
15 |
| package org.apache.tapestry.components; |
16 |
| |
17 |
| import java.util.ArrayList; |
18 |
| import java.util.Collections; |
19 |
| import java.util.HashMap; |
20 |
| import java.util.Iterator; |
21 |
| import java.util.List; |
22 |
| import java.util.Map; |
23 |
| |
24 |
| import org.apache.tapestry.IBinding; |
25 |
| import org.apache.tapestry.IForm; |
26 |
| import org.apache.tapestry.IMarkupWriter; |
27 |
| import org.apache.tapestry.IRequestCycle; |
28 |
| import org.apache.tapestry.Tapestry; |
29 |
| import org.apache.tapestry.TapestryUtils; |
30 |
| import org.apache.tapestry.coerce.ValueConverter; |
31 |
| import org.apache.tapestry.form.AbstractFormComponent; |
32 |
| import org.apache.tapestry.services.DataSqueezer; |
33 |
| import org.apache.tapestry.services.ExpressionEvaluator; |
34 |
| |
35 |
| |
36 |
| |
37 |
| |
38 |
| public abstract class ForBean extends AbstractFormComponent { |
39 |
| |
40 |
| private static final char DESC_VALUE = 'V'; |
41 |
| private static final char DESC_PRIMARY_KEY = 'P'; |
42 |
| |
43 |
| private final RepSource COMPLETE_REP_SOURCE = new CompleteRepSource(); |
44 |
| private final RepSource KEY_EXPRESSION_REP_SOURCE = new KeyExpressionRepSource(); |
45 |
| |
46 |
| |
47 |
| public abstract String getElement(); |
48 |
| public abstract String getKeyExpression(); |
49 |
| public abstract IPrimaryKeyConverter getConverter(); |
50 |
| public abstract Object getDefaultValue(); |
51 |
| public abstract boolean getMatch(); |
52 |
| public abstract boolean getVolatile(); |
53 |
| |
54 |
| |
55 |
| public abstract DataSqueezer getDataSqueezer(); |
56 |
| public abstract ValueConverter getValueConverter(); |
57 |
| public abstract ExpressionEvaluator getExpressionEvaluator(); |
58 |
| |
59 |
| |
60 |
| private Object _value; |
61 |
| private int _index; |
62 |
| private boolean _rendering; |
63 |
| |
64 |
| |
65 |
| |
66 |
| |
67 |
| |
68 |
| |
69 |
| |
70 |
21
| protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
|
71 |
| { |
72 |
| |
73 |
21
| IForm form = (IForm) cycle.getAttribute(TapestryUtils.FORM_ATTRIBUTE);
|
74 |
| |
75 |
| |
76 |
| |
77 |
21
| boolean cycleRewinding = cycle.isRewinding();
|
78 |
21
| if (cycleRewinding && form != null && !form.isRewinding())
|
79 |
0
| return;
|
80 |
| |
81 |
| |
82 |
21
| Iterator dataSource = getData(cycle, form);
|
83 |
| |
84 |
| |
85 |
| |
86 |
21
| if (dataSource == null)
|
87 |
0
| return;
|
88 |
| |
89 |
21
| String element = getElement();
|
90 |
| |
91 |
| |
92 |
21
| try
|
93 |
| { |
94 |
21
| _index = 0;
|
95 |
21
| _rendering = true;
|
96 |
| |
97 |
21
| while (dataSource.hasNext())
|
98 |
| { |
99 |
| |
100 |
57
| _value = dataSource.next();
|
101 |
| |
102 |
| |
103 |
57
| updateOutputParameters();
|
104 |
| |
105 |
| |
106 |
57
| if (element != null)
|
107 |
| { |
108 |
22
| writer.begin(element);
|
109 |
22
| renderInformalParameters(writer, cycle);
|
110 |
| } |
111 |
| |
112 |
57
| renderBody(writer, cycle);
|
113 |
| |
114 |
57
| if (element != null)
|
115 |
22
| writer.end();
|
116 |
| |
117 |
57
| _index++;
|
118 |
| } |
119 |
| } |
120 |
| finally |
121 |
| { |
122 |
21
| _rendering = false;
|
123 |
21
| _value = null;
|
124 |
| } |
125 |
| } |
126 |
| |
127 |
| |
128 |
| |
129 |
| |
130 |
| |
131 |
| |
132 |
| |
133 |
| |
134 |
| |
135 |
46
| public final Object getValue()
|
136 |
| { |
137 |
46
| if (!_rendering)
|
138 |
0
| throw Tapestry.createRenderOnlyPropertyException(this, "value");
|
139 |
| |
140 |
46
| return _value;
|
141 |
| } |
142 |
| |
143 |
| |
144 |
| |
145 |
| |
146 |
| |
147 |
| |
148 |
| |
149 |
| |
150 |
| |
151 |
46
| public int getIndex()
|
152 |
| { |
153 |
46
| if (!_rendering)
|
154 |
0
| throw Tapestry.createRenderOnlyPropertyException(this, "index");
|
155 |
| |
156 |
46
| return _index;
|
157 |
| } |
158 |
| |
159 |
0
| public boolean isDisabled()
|
160 |
| { |
161 |
0
| return false;
|
162 |
| } |
163 |
| |
164 |
| |
165 |
| |
166 |
| |
167 |
57
| protected void updateOutputParameters()
|
168 |
| { |
169 |
57
| IBinding indexBinding = getBinding("index");
|
170 |
57
| if (indexBinding != null)
|
171 |
31
| indexBinding.setObject(new Integer(_index));
|
172 |
| |
173 |
57
| IBinding valueBinding = getBinding("value");
|
174 |
57
| if (valueBinding != null)
|
175 |
31
| valueBinding.setObject(_value);
|
176 |
| } |
177 |
| |
178 |
| |
179 |
| |
180 |
| |
181 |
5
| protected void updatePrimaryKeysParameter(String[] stringReps)
|
182 |
| { |
183 |
5
| IBinding primaryKeysBinding = getBinding("primaryKeys");
|
184 |
5
| if (primaryKeysBinding == null)
|
185 |
5
| return;
|
186 |
| |
187 |
0
| DataSqueezer squeezer = getDataSqueezer();
|
188 |
| |
189 |
0
| int repsCount = stringReps.length;
|
190 |
0
| List primaryKeys = new ArrayList(repsCount);
|
191 |
0
| for (int i = 0; i < stringReps.length; i++) {
|
192 |
0
| String rep = stringReps[i];
|
193 |
0
| if (rep.length() == 0 || rep.charAt(0) != DESC_PRIMARY_KEY)
|
194 |
0
| continue;
|
195 |
0
| Object primaryKey = squeezer.unsqueeze(rep.substring(1));
|
196 |
0
| primaryKeys.add(primaryKey);
|
197 |
| } |
198 |
| |
199 |
0
| primaryKeysBinding.setObject(primaryKeys);
|
200 |
| } |
201 |
| |
202 |
| |
203 |
0
| protected void renderFormComponent(IMarkupWriter writer, IRequestCycle cycle) { }
|
204 |
0
| protected void rewindFormComponent(IMarkupWriter writer, IRequestCycle cycle) { }
|
205 |
| |
206 |
| |
207 |
| |
208 |
| |
209 |
| |
210 |
| |
211 |
| |
212 |
| |
213 |
| |
214 |
| |
215 |
| |
216 |
| |
217 |
| |
218 |
| |
219 |
| |
220 |
| |
221 |
| |
222 |
| |
223 |
| |
224 |
21
| private Iterator getData(IRequestCycle cycle, IForm form) {
|
225 |
21
| if (form == null || getVolatile())
|
226 |
6
| return evaluateSourceIterator();
|
227 |
| |
228 |
15
| String name = form.getElementId(this);
|
229 |
15
| if (cycle.isRewinding())
|
230 |
5
| return getStoredData(cycle, name);
|
231 |
10
| return storeSourceData(form, name);
|
232 |
| } |
233 |
| |
234 |
| |
235 |
| |
236 |
| |
237 |
| |
238 |
| |
239 |
| |
240 |
| |
241 |
| |
242 |
5
| protected Iterator getStoredData(IRequestCycle cycle, String name)
|
243 |
| { |
244 |
5
| String[] stringReps = cycle.getParameters(name);
|
245 |
5
| if (stringReps == null)
|
246 |
0
| return null;
|
247 |
| |
248 |
5
| updatePrimaryKeysParameter(stringReps);
|
249 |
| |
250 |
5
| Iterator sourceIterator = evaluateSourceIterator();
|
251 |
5
| Iterator fullSourceIterator = evaluateFullSourceIterator();
|
252 |
5
| Map repToValueMap = new HashMap();
|
253 |
| |
254 |
5
| int valueCount = stringReps.length;
|
255 |
5
| List values = new ArrayList(valueCount);
|
256 |
5
| for (int i = 0; i < valueCount; i++) {
|
257 |
11
| String rep = stringReps[i];
|
258 |
11
| Object value = getValueFromStringRep(sourceIterator, fullSourceIterator, repToValueMap, rep);
|
259 |
11
| values.add(value);
|
260 |
| } |
261 |
| |
262 |
5
| return values.iterator();
|
263 |
| } |
264 |
| |
265 |
| |
266 |
| |
267 |
| |
268 |
| |
269 |
| |
270 |
| |
271 |
| |
272 |
| |
273 |
| |
274 |
10
| protected Iterator storeSourceData(IForm form, String name)
|
275 |
| { |
276 |
10
| List values = new ArrayList();
|
277 |
| |
278 |
10
| Iterator it = evaluateSourceIterator();
|
279 |
10
| while (it.hasNext()) {
|
280 |
20
| Object value = it.next();
|
281 |
20
| values.add(value);
|
282 |
| |
283 |
20
| String rep = getStringRepFromValue(value);
|
284 |
20
| form.addHiddenValue(name, rep);
|
285 |
| } |
286 |
| |
287 |
10
| return values.iterator();
|
288 |
| } |
289 |
| |
290 |
| |
291 |
| |
292 |
| |
293 |
| |
294 |
| |
295 |
| |
296 |
| |
297 |
| |
298 |
| |
299 |
| |
300 |
71
| protected String getStringRepFromValue(Object value) {
|
301 |
71
| String rep;
|
302 |
71
| DataSqueezer squeezer = getDataSqueezer();
|
303 |
| |
304 |
| |
305 |
71
| Object pk = getPrimaryKeyFromValue(value);
|
306 |
71
| if (pk != null)
|
307 |
| |
308 |
50
| rep = DESC_PRIMARY_KEY + squeezer.squeeze(pk);
|
309 |
| else |
310 |
| |
311 |
21
| rep = DESC_VALUE + squeezer.squeeze(value);
|
312 |
| |
313 |
71
| return rep;
|
314 |
| } |
315 |
| |
316 |
| |
317 |
| |
318 |
| |
319 |
| |
320 |
| |
321 |
| |
322 |
| |
323 |
71
| protected Object getPrimaryKeyFromValue(Object value) {
|
324 |
71
| if (value == null)
|
325 |
0
| return null;
|
326 |
| |
327 |
71
| Object primaryKey = getKeyExpressionFromValue(value);
|
328 |
71
| if (primaryKey == null)
|
329 |
21
| primaryKey = getConverterFromValue(value);
|
330 |
| |
331 |
71
| return primaryKey;
|
332 |
| } |
333 |
| |
334 |
| |
335 |
| |
336 |
| |
337 |
| |
338 |
| |
339 |
| |
340 |
| |
341 |
71
| protected Object getKeyExpressionFromValue(Object value) {
|
342 |
71
| String keyExpression = getKeyExpression();
|
343 |
71
| if (keyExpression == null)
|
344 |
21
| return null;
|
345 |
| |
346 |
50
| Object primaryKey = getExpressionEvaluator().read(value, keyExpression);
|
347 |
50
| return primaryKey;
|
348 |
| } |
349 |
| |
350 |
| |
351 |
| |
352 |
| |
353 |
| |
354 |
| |
355 |
| |
356 |
| |
357 |
21
| protected Object getConverterFromValue(Object value) {
|
358 |
21
| IPrimaryKeyConverter converter = getConverter();
|
359 |
21
| if (converter == null)
|
360 |
21
| return null;
|
361 |
| |
362 |
0
| Object primaryKey = converter.getPrimaryKey(value);
|
363 |
0
| return primaryKey;
|
364 |
| } |
365 |
| |
366 |
| |
367 |
| |
368 |
| |
369 |
| |
370 |
| |
371 |
| |
372 |
| |
373 |
| |
374 |
| |
375 |
| |
376 |
| |
377 |
11
| protected Object getValueFromStringRep(Iterator sourceIterator, Iterator fullSourceIterator,
|
378 |
| Map repToValueMap, String rep) { |
379 |
11
| Object value = null;
|
380 |
11
| DataSqueezer squeezer = getDataSqueezer();
|
381 |
| |
382 |
| |
383 |
11
| if (rep == null || rep.length() == 0)
|
384 |
0
| return getDefaultValue();
|
385 |
| |
386 |
| |
387 |
11
| boolean match = getMatch();
|
388 |
11
| if (match) {
|
389 |
9
| value = findValueWithStringRep(sourceIterator, fullSourceIterator, repToValueMap, rep, COMPLETE_REP_SOURCE);
|
390 |
9
| if (value != null)
|
391 |
7
| return value;
|
392 |
| } |
393 |
| |
394 |
| |
395 |
| |
396 |
4
| char desc = rep.charAt(0);
|
397 |
4
| String squeezed = rep.substring(1);
|
398 |
4
| switch (desc) {
|
399 |
3
| case DESC_VALUE:
|
400 |
| |
401 |
3
| value = squeezer.unsqueeze(squeezed);
|
402 |
3
| break;
|
403 |
| |
404 |
1
| case DESC_PRIMARY_KEY:
|
405 |
| |
406 |
1
| if (!match && getKeyExpression() != null)
|
407 |
0
| value = findValueWithStringRep(sourceIterator, fullSourceIterator, repToValueMap, rep, KEY_EXPRESSION_REP_SOURCE);
|
408 |
| |
409 |
| |
410 |
1
| if (value == null) {
|
411 |
1
| IPrimaryKeyConverter converter = getConverter();
|
412 |
1
| if (converter != null) {
|
413 |
0
| Object pk = squeezer.unsqueeze(squeezed);
|
414 |
0
| value = converter.getValue(pk);
|
415 |
| } |
416 |
| } |
417 |
1
| break;
|
418 |
| } |
419 |
| |
420 |
4
| if (value == null)
|
421 |
1
| value = getDefaultValue();
|
422 |
| |
423 |
4
| return value;
|
424 |
| } |
425 |
| |
426 |
| |
427 |
| |
428 |
| |
429 |
| |
430 |
| |
431 |
| |
432 |
| |
433 |
| |
434 |
| |
435 |
| |
436 |
| |
437 |
| |
438 |
9
| protected Object findValueWithStringRep(Iterator sourceIterator, Iterator fullSourceIterator,
|
439 |
| Map repToValueMap, String rep, RepSource repSource) { |
440 |
9
| Object value = repToValueMap.get(rep);
|
441 |
9
| if (value != null)
|
442 |
1
| return value;
|
443 |
| |
444 |
8
| value = findValueWithStringRepInIterator(sourceIterator, repToValueMap, rep, repSource);
|
445 |
8
| if (value != null)
|
446 |
4
| return value;
|
447 |
| |
448 |
4
| value = findValueWithStringRepInIterator(fullSourceIterator, repToValueMap, rep, repSource);
|
449 |
4
| return value;
|
450 |
| } |
451 |
| |
452 |
| |
453 |
| |
454 |
| |
455 |
| |
456 |
| |
457 |
| |
458 |
| |
459 |
| |
460 |
| |
461 |
| |
462 |
| |
463 |
| |
464 |
| |
465 |
12
| protected Object findValueWithStringRepInIterator(Iterator it, Map repToValueMap, String rep, RepSource repSource) {
|
466 |
12
| while (it.hasNext()) {
|
467 |
51
| Object sourceValue = it.next();
|
468 |
51
| if (sourceValue == null)
|
469 |
0
| continue;
|
470 |
| |
471 |
51
| String sourceRep = repSource.getStringRep(sourceValue);
|
472 |
51
| repToValueMap.put(sourceRep, sourceValue);
|
473 |
| |
474 |
51
| if (rep.equals(sourceRep))
|
475 |
6
| return sourceValue;
|
476 |
| } |
477 |
| |
478 |
6
| return null;
|
479 |
| } |
480 |
| |
481 |
| |
482 |
| |
483 |
| |
484 |
| |
485 |
| |
486 |
21
| protected Iterator evaluateSourceIterator()
|
487 |
| { |
488 |
21
| Iterator it = null;
|
489 |
21
| Object source = null;
|
490 |
| |
491 |
21
| IBinding sourceBinding = getBinding("source");
|
492 |
21
| if (sourceBinding != null)
|
493 |
21
| source = sourceBinding.getObject();
|
494 |
| |
495 |
21
| if (source != null)
|
496 |
21
| it = (Iterator) getValueConverter().coerceValue(source, Iterator.class);
|
497 |
| |
498 |
21
| if (it == null)
|
499 |
0
| it = Collections.EMPTY_LIST.iterator();
|
500 |
| |
501 |
21
| return it;
|
502 |
| } |
503 |
| |
504 |
| |
505 |
| |
506 |
| |
507 |
| |
508 |
| |
509 |
5
| protected Iterator evaluateFullSourceIterator()
|
510 |
| { |
511 |
5
| Iterator it = null;
|
512 |
5
| Object fullSource = null;
|
513 |
| |
514 |
5
| IBinding fullSourceBinding = getBinding("fullSource");
|
515 |
5
| if (fullSourceBinding != null)
|
516 |
2
| fullSource = fullSourceBinding.getObject();
|
517 |
| |
518 |
5
| if (fullSource != null)
|
519 |
2
| it = (Iterator) getValueConverter().coerceValue(fullSource, Iterator.class);
|
520 |
| |
521 |
5
| if (it == null)
|
522 |
3
| it = Collections.EMPTY_LIST.iterator();
|
523 |
| |
524 |
5
| return it;
|
525 |
| } |
526 |
| |
527 |
| |
528 |
| |
529 |
| |
530 |
| protected interface RepSource { |
531 |
| String getStringRep(Object value); |
532 |
| } |
533 |
| |
534 |
| |
535 |
| |
536 |
| |
537 |
| |
538 |
| protected class CompleteRepSource implements RepSource { |
539 |
51
| public String getStringRep(Object value) {
|
540 |
51
| return getStringRepFromValue(value);
|
541 |
| } |
542 |
| } |
543 |
| |
544 |
| |
545 |
| |
546 |
| |
547 |
| |
548 |
| protected class KeyExpressionRepSource implements RepSource { |
549 |
0
| public String getStringRep(Object value) {
|
550 |
0
| Object pk = getKeyExpressionFromValue(value);
|
551 |
0
| return DESC_PRIMARY_KEY + getDataSqueezer().squeeze(pk);
|
552 |
| } |
553 |
| } |
554 |
| |
555 |
| |
556 |
| |
557 |
| |
558 |
0
| protected boolean getCanTakeFocus() {
|
559 |
0
| return false;
|
560 |
| } |
561 |
| |
562 |
0
| public String getClientId()
|
563 |
| { |
564 |
0
| return null;
|
565 |
| } |
566 |
| |
567 |
0
| public String getDisplayName()
|
568 |
| { |
569 |
0
| return null;
|
570 |
| } |
571 |
| |
572 |
| |
573 |
| } |