1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| |
10 |
| |
11 |
| |
12 |
| |
13 |
| |
14 |
| |
15 |
| package org.apache.tapestry.components; |
16 |
| |
17 |
| import java.io.IOException; |
18 |
| import java.util.ArrayList; |
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.hivemind.ApplicationRuntimeException; |
25 |
| import org.apache.tapestry.IBinding; |
26 |
| import org.apache.tapestry.IForm; |
27 |
| import org.apache.tapestry.IMarkupWriter; |
28 |
| import org.apache.tapestry.IRequestCycle; |
29 |
| import org.apache.tapestry.Tapestry; |
30 |
| import org.apache.tapestry.TapestryUtils; |
31 |
| import org.apache.tapestry.coerce.ValueConverter; |
32 |
| import org.apache.tapestry.form.AbstractFormComponent; |
33 |
| import org.apache.tapestry.services.DataSqueezer; |
34 |
| import org.apache.tapestry.services.ExpressionEvaluator; |
35 |
| |
36 |
| |
37 |
| |
38 |
| |
39 |
| public abstract class ForBean extends AbstractFormComponent { |
40 |
| private static final char DESC_VALUE = 'V'; |
41 |
| private static final char DESC_PRIMARY_KEY = 'P'; |
42 |
| |
43 |
| |
44 |
| public abstract Object getSource(); |
45 |
| public abstract Object getFullSource(); |
46 |
| public abstract String getElement(); |
47 |
| public abstract boolean getVolatile(); |
48 |
| public abstract Object getDefaultValue(); |
49 |
| public abstract String getPrimaryKey(); |
50 |
| public abstract IPrimaryKeyConverter getConverter(); |
51 |
| public abstract String getKeyExpression(); |
52 |
| |
53 |
| |
54 |
| public abstract Map getPrimaryKeyMap(); |
55 |
| public abstract void setPrimaryKeyMap(Map primaryKeys); |
56 |
| |
57 |
| |
58 |
| public abstract DataSqueezer getDataSqueezer(); |
59 |
| public abstract ValueConverter getValueConverter(); |
60 |
| public abstract ExpressionEvaluator getExpressionEvaluator(); |
61 |
| |
62 |
| |
63 |
| private Object _value; |
64 |
| private int _index; |
65 |
| private boolean _rendering; |
66 |
| |
67 |
| |
68 |
| |
69 |
| |
70 |
| |
71 |
| |
72 |
| |
73 |
| |
74 |
| |
75 |
| |
76 |
| |
77 |
| |
78 |
4
| protected Iterator getSourceData()
|
79 |
| { |
80 |
4
| Object source = getSource();
|
81 |
4
| if (source == null)
|
82 |
0
| return null;
|
83 |
| |
84 |
4
| Iterator iteratorSource = (Iterator) getValueConverter().coerceValue(source, Iterator.class);
|
85 |
| |
86 |
4
| return iteratorSource;
|
87 |
| } |
88 |
| |
89 |
3
| protected Iterator storeSourceData(IForm form, String name)
|
90 |
| { |
91 |
3
| Iterator iteratorSource = getSourceData();
|
92 |
3
| if (iteratorSource == null)
|
93 |
0
| return null;
|
94 |
| |
95 |
| |
96 |
3
| StringBuffer pkDesc = new StringBuffer();
|
97 |
3
| List data = new ArrayList();
|
98 |
3
| List pks = new ArrayList();
|
99 |
3
| while (iteratorSource.hasNext()) {
|
100 |
6
| Object value = iteratorSource.next();
|
101 |
6
| data.add(value);
|
102 |
| |
103 |
6
| Object pk = getPrimaryKeyFromValue(value);
|
104 |
6
| if (pk == null) {
|
105 |
2
| pk = value;
|
106 |
2
| pkDesc.append(DESC_VALUE);
|
107 |
| } |
108 |
| else |
109 |
4
| pkDesc.append(DESC_PRIMARY_KEY);
|
110 |
6
| pks.add(pk);
|
111 |
| } |
112 |
| |
113 |
| |
114 |
3
| form.addHiddenValue(name, pkDesc.toString());
|
115 |
3
| for (Iterator it = pks.iterator(); it.hasNext();) {
|
116 |
6
| Object pk = it.next();
|
117 |
6
| try {
|
118 |
6
| String stringRep = getDataSqueezer().squeeze(pk);
|
119 |
6
| form.addHiddenValue(name, stringRep);
|
120 |
| } catch (IOException ex) { |
121 |
0
| throw new ApplicationRuntimeException(
|
122 |
| Tapestry.format("For.unable-to-convert-value", pk), |
123 |
| this, |
124 |
| null, |
125 |
| ex); |
126 |
| } |
127 |
| } |
128 |
| |
129 |
3
| return data.iterator();
|
130 |
| } |
131 |
| |
132 |
0
| protected Iterator getStoredData(IRequestCycle cycle, String name)
|
133 |
| { |
134 |
0
| String[] submittedPrimaryKeys = cycle.getParameters(name);
|
135 |
0
| String pkDesc = submittedPrimaryKeys[0];
|
136 |
| |
137 |
| |
138 |
0
| List data = new ArrayList(submittedPrimaryKeys.length-1);
|
139 |
0
| List pks = new ArrayList(submittedPrimaryKeys.length-1);
|
140 |
0
| for (int i = 1; i < submittedPrimaryKeys.length; i++) {
|
141 |
0
| String stringRep = submittedPrimaryKeys[i];
|
142 |
0
| try {
|
143 |
0
| Object value = getDataSqueezer().unsqueeze(stringRep);
|
144 |
0
| data.add(value);
|
145 |
0
| if (i <= pkDesc.length() && pkDesc.charAt(i-1) == DESC_PRIMARY_KEY)
|
146 |
0
| pks.add(value);
|
147 |
| } catch (IOException ex) { |
148 |
0
| throw new ApplicationRuntimeException(
|
149 |
| Tapestry.format("For.unable-to-convert-string", stringRep), |
150 |
| this, |
151 |
| null, |
152 |
| ex); |
153 |
| } |
154 |
| } |
155 |
| |
156 |
| |
157 |
0
| IBinding primaryKeysBinding = getBinding("primaryKeys");
|
158 |
0
| if (primaryKeysBinding != null)
|
159 |
0
| primaryKeysBinding.setObject(pks);
|
160 |
| |
161 |
| |
162 |
0
| for (int i = 0; i < data.size(); i++) {
|
163 |
0
| if (i <= pkDesc.length() && pkDesc.charAt(i) == DESC_PRIMARY_KEY) {
|
164 |
0
| Object pk = data.get(i);
|
165 |
0
| Object value = getValueFromPrimaryKey(pk);
|
166 |
0
| data.set(i, value);
|
167 |
| } |
168 |
| } |
169 |
| |
170 |
0
| return data.iterator();
|
171 |
| } |
172 |
| |
173 |
| |
174 |
| |
175 |
| |
176 |
| |
177 |
| |
178 |
| |
179 |
4
| protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
|
180 |
| { |
181 |
| |
182 |
4
| IForm form = (IForm) cycle.getAttribute(TapestryUtils.FORM_ATTRIBUTE);
|
183 |
| |
184 |
| |
185 |
| |
186 |
4
| boolean cycleRewinding = cycle.isRewinding();
|
187 |
4
| if (cycleRewinding && form != null && !form.isRewinding())
|
188 |
0
| return;
|
189 |
| |
190 |
4
| boolean bInForm = (form != null && !getVolatile());
|
191 |
| |
192 |
4
| String name = "";
|
193 |
4
| if (form != null)
|
194 |
3
| name = form.getElementId(this);
|
195 |
| |
196 |
| |
197 |
4
| Iterator dataSource;
|
198 |
4
| if (!bInForm)
|
199 |
1
| dataSource = getSourceData();
|
200 |
3
| else if (cycleRewinding)
|
201 |
0
| dataSource = getStoredData(cycle, name);
|
202 |
| else |
203 |
3
| dataSource = storeSourceData(form, name);
|
204 |
| |
205 |
| |
206 |
| |
207 |
| |
208 |
4
| if (dataSource == null)
|
209 |
0
| return;
|
210 |
| |
211 |
4
| String element = getElement();
|
212 |
| |
213 |
| |
214 |
4
| try
|
215 |
| { |
216 |
4
| _index = 0;
|
217 |
4
| _rendering = true;
|
218 |
| |
219 |
4
| while (dataSource.hasNext())
|
220 |
| { |
221 |
| |
222 |
8
| _value = dataSource.next();
|
223 |
| |
224 |
| |
225 |
8
| IBinding indexBinding = getBinding("index");
|
226 |
8
| if (indexBinding != null)
|
227 |
0
| indexBinding.setObject(new Integer(_index));
|
228 |
| |
229 |
8
| IBinding valueBinding = getBinding("value");
|
230 |
8
| if (valueBinding != null)
|
231 |
0
| valueBinding.setObject(_value);
|
232 |
| |
233 |
| |
234 |
8
| if (element != null)
|
235 |
| { |
236 |
0
| writer.begin(element);
|
237 |
0
| renderInformalParameters(writer, cycle);
|
238 |
| } |
239 |
| |
240 |
8
| renderBody(writer, cycle);
|
241 |
| |
242 |
8
| if (element != null)
|
243 |
0
| writer.end();
|
244 |
| |
245 |
8
| _index++;
|
246 |
| } |
247 |
| } |
248 |
| finally |
249 |
| { |
250 |
4
| _rendering = false;
|
251 |
4
| _value = null;
|
252 |
| } |
253 |
| } |
254 |
| |
255 |
0
| private Object restoreValue(IForm form, String name, Object primaryKey)
|
256 |
| { |
257 |
0
| return getValueFromPrimaryKey(primaryKey);
|
258 |
| } |
259 |
| |
260 |
0
| private void storeValue(IForm form, String name, Object value)
|
261 |
| { |
262 |
0
| Object convertedValue = getPrimaryKeyFromValue(value);
|
263 |
| |
264 |
0
| try
|
265 |
| { |
266 |
0
| String externalValue = getDataSqueezer().squeeze(convertedValue);
|
267 |
0
| form.addHiddenValue(name, externalValue);
|
268 |
| } |
269 |
| catch (IOException ex) |
270 |
| { |
271 |
0
| throw new ApplicationRuntimeException(
|
272 |
| Tapestry.format("For.unable-to-convert-value", value), |
273 |
| this, |
274 |
| null, |
275 |
| ex); |
276 |
| } |
277 |
| } |
278 |
| |
279 |
6
| private Object getPrimaryKeyFromValue(Object value) {
|
280 |
6
| Object primaryKey = null;
|
281 |
| |
282 |
6
| String keyExpression = getKeyExpression();
|
283 |
6
| if (keyExpression != null)
|
284 |
4
| primaryKey = getExpressionEvaluator().read(value, keyExpression);
|
285 |
| |
286 |
6
| if (primaryKey == null) {
|
287 |
2
| IPrimaryKeyConverter converter = getConverter();
|
288 |
2
| if (converter != null)
|
289 |
0
| primaryKey = converter.getPrimaryKey(value);
|
290 |
| } |
291 |
| |
292 |
6
| return primaryKey;
|
293 |
| } |
294 |
| |
295 |
0
| private Object getValueFromPrimaryKey(Object primaryKey) {
|
296 |
0
| Object value = null;
|
297 |
| |
298 |
0
| if (value == null && getKeyExpression() != null) {
|
299 |
0
| String keyExpression = getKeyExpression();
|
300 |
0
| if (keyExpression != null) {
|
301 |
0
| Map primaryKeys = getPrimaryKeyMap();
|
302 |
0
| if (primaryKeys == null)
|
303 |
0
| primaryKeys = initializePrimaryKeysFromSource(keyExpression);
|
304 |
0
| value = primaryKeys.get(primaryKeys);
|
305 |
| } |
306 |
| } |
307 |
| |
308 |
0
| if (value == null) {
|
309 |
0
| IPrimaryKeyConverter converter = getConverter();
|
310 |
0
| if (converter != null)
|
311 |
0
| value = converter.getValue(primaryKey);
|
312 |
| } |
313 |
| |
314 |
0
| if (value == null)
|
315 |
0
| value = getDefaultValue();
|
316 |
| |
317 |
0
| return value;
|
318 |
| } |
319 |
| |
320 |
0
| private Map initializePrimaryKeysFromSource(String keyExpression)
|
321 |
| { |
322 |
0
| Map primaryKeys = new HashMap();
|
323 |
| |
324 |
0
| Object fullSource = getFullSource();
|
325 |
0
| if (fullSource == null)
|
326 |
0
| fullSource = getSource();
|
327 |
0
| if (fullSource == null)
|
328 |
0
| return primaryKeys;
|
329 |
| |
330 |
0
| ExpressionEvaluator evaluator = getExpressionEvaluator();
|
331 |
| |
332 |
0
| Iterator iteratorSource = (Iterator) getValueConverter().coerceValue(fullSource, Iterator.class);
|
333 |
0
| while (iteratorSource.hasNext()) {
|
334 |
0
| Object value = iteratorSource.next();
|
335 |
0
| Object primaryKey = evaluator.read(value, keyExpression);
|
336 |
0
| if (primaryKey != null)
|
337 |
0
| primaryKeys.put(primaryKey, value);
|
338 |
| } |
339 |
| |
340 |
0
| setPrimaryKeyMap(primaryKeys);
|
341 |
0
| return primaryKeys;
|
342 |
| } |
343 |
| |
344 |
| |
345 |
| |
346 |
| |
347 |
| |
348 |
| |
349 |
| |
350 |
| |
351 |
8
| public final Object getValue()
|
352 |
| { |
353 |
8
| if (!_rendering)
|
354 |
0
| throw Tapestry.createRenderOnlyPropertyException(this, "value");
|
355 |
| |
356 |
8
| return _value;
|
357 |
| } |
358 |
| |
359 |
| |
360 |
| |
361 |
| |
362 |
| |
363 |
| |
364 |
| |
365 |
| |
366 |
| |
367 |
| |
368 |
| |
369 |
8
| public int getIndex()
|
370 |
| { |
371 |
8
| if (!_rendering)
|
372 |
0
| throw Tapestry.createRenderOnlyPropertyException(this, "index");
|
373 |
| |
374 |
8
| return _index;
|
375 |
| } |
376 |
| |
377 |
0
| public boolean isDisabled()
|
378 |
| { |
379 |
0
| return false;
|
380 |
| } |
381 |
| |
382 |
| |
383 |
0
| protected void renderFormComponent(IMarkupWriter writer, IRequestCycle cycle) { }
|
384 |
0
| protected void rewindFormComponent(IMarkupWriter writer, IRequestCycle cycle) { }
|
385 |
| } |