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