1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package org.rcfaces.core.internal.component;
27
28 import java.io.Externalizable;
29 import java.io.IOException;
30 import java.io.ObjectInput;
31 import java.io.ObjectOutput;
32 import java.util.ArrayList;
33 import java.util.HashMap;
34 import java.util.Iterator;
35 import java.util.List;
36 import java.util.Map;
37
38 import javax.el.ValueExpression;
39 import javax.faces.component.StateHolder;
40 import javax.faces.component.UIColumn;
41 import javax.faces.component.UIComponent;
42 import javax.faces.context.FacesContext;
43 import javax.faces.event.PhaseId;
44 import javax.faces.model.DataModel;
45
46 import org.apache.commons.logging.Log;
47 import org.apache.commons.logging.LogFactory;
48 import org.rcfaces.core.component.capability.IAdditionalInformationContainer;
49 import org.rcfaces.core.internal.Constants;
50 import org.rcfaces.core.internal.capability.IComponentEngine;
51 import org.rcfaces.core.internal.capability.IRCFacesComponent;
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 public class UIData2 extends UIData0 {
76
77 private static final Log LOG = LogFactory.getLog(UIData2.class);
78
79 private static boolean DEBUG_ENABLED = LOG.isDebugEnabled();
80
81 private transient List<int[]> decodedIndexes;
82
83 private Map saved = new HashMap();
84
85 private boolean saveCompleteState = true;
86
87 private boolean iterateMode;
88
89 private int iterateModeFirst;
90
91 private int iterateModeIndex;
92
93 private int iterateModeRows;
94
95 public UIData2() {
96
97 DEBUG_ENABLED = LOG.isDebugEnabled();
98 }
99
100 public void encodeBegin(FacesContext context) throws IOException {
101
102 decodedIndexes = null;
103
104 super.encodeBegin(context);
105 }
106
107 protected void iterate(FacesContext context, PhaseId phaseId) {
108 if (decodedIndexes == null || decodedIndexes.isEmpty()) {
109 super.iterate(context, phaseId);
110 return;
111 }
112
113 if (true) {
114 super.iterate(context, phaseId);
115 return;
116 }
117
118 iterateModeFirst = 0;
119 iterateModeRows = 0;
120 iterateModeIndex = 0;
121
122 for (int[] is : decodedIndexes) {
123 iterateModeRows += is[1];
124 }
125
126 iterateMode = true;
127 try {
128
129 super.iterate(context, phaseId);
130
131 } finally {
132 iterateMode = false;
133 }
134 }
135
136 protected boolean renderColumn(UIColumn column, PhaseId phaseId) {
137 if (column instanceof IAdditionalInformationContainer) {
138 return decodeAdditionalInformation((IAdditionalInformationContainer) column);
139 }
140
141 return true;
142 }
143
144 public int getFirst() {
145 if (iterateMode == false) {
146 int first = super.getFirst();
147
148 if (DEBUG_ENABLED) {
149 LOG.debug("getFirst returns " + first);
150 }
151
152 return first;
153 }
154
155 if (DEBUG_ENABLED) {
156 LOG.debug("Iterate translate mode: return first="
157 + iterateModeFirst);
158 }
159
160 return iterateModeFirst;
161 }
162
163 public int getRowCount() {
164 int rowCount = super.getRowCount();
165
166 if (DEBUG_ENABLED) {
167 LOG.debug("getRowCount() returns " + rowCount);
168 }
169
170 return rowCount;
171 }
172
173 public int getRowIndex() {
174 int rowIndex = super.getRowIndex();
175
176 if (DEBUG_ENABLED) {
177 LOG.debug("getRowIndex() returns " + rowIndex);
178 }
179
180 return rowIndex;
181 }
182
183 public boolean isRowAvailable() {
184 boolean rowAvailable = super.isRowAvailable();
185
186 if (DEBUG_ENABLED) {
187 LOG.debug("isRowAvailable() returns " + rowAvailable);
188 }
189
190 return rowAvailable;
191 }
192
193 public void setFirst(int first) {
194
195 if (DEBUG_ENABLED) {
196 LOG.debug("setFirst(" + first + ")");
197 }
198
199 super.setFirst(first);
200 }
201
202 public void setRows(int rows) {
203
204 if (DEBUG_ENABLED) {
205 LOG.debug("setRows(" + rows + ")");
206 }
207
208 super.setRows(rows);
209 }
210
211 public int getRows() {
212 if (iterateMode == false) {
213 int rows = super.getRows();
214
215 if (DEBUG_ENABLED) {
216 LOG.debug("getRows() returns " + rows);
217 }
218
219 return rows;
220 }
221
222 if (DEBUG_ENABLED) {
223 LOG.debug("getRows(): Iterate translate mode returns rows="
224 + iterateModeRows);
225 }
226
227 return iterateModeRows;
228 }
229
230 public void setRowIndex(int rowIndex) {
231 if (iterateMode == false || rowIndex < 0) {
232
233 if (DEBUG_ENABLED) {
234 LOG.debug("setRowIndex(" + rowIndex + ")");
235 }
236
237 super.setRowIndex(rowIndex);
238 return;
239 }
240
241 int translatedRowIndex = 0;
242 for (int[] is : decodedIndexes) {
243 if (rowIndex >= is[1]) {
244 rowIndex -= is[1];
245 continue;
246 }
247
248 translatedRowIndex = is[0] + rowIndex;
249 break;
250 }
251
252 if (DEBUG_ENABLED) {
253 LOG.debug("setRowIndex(" + rowIndex
254 + ") Iterate translate mode => rowIndex="
255 + translatedRowIndex);
256 }
257
258 super.setRowIndex(translatedRowIndex);
259 }
260
261 public void addDecodedIndexes(int first, int rows) {
262
263 if (DEBUG_ENABLED) {
264 LOG.debug("Add decoded indexes first=" + first + " rows=" + rows);
265 }
266
267 if (decodedIndexes == null) {
268 decodedIndexes = new ArrayList<int[]>();
269 }
270
271 if (rows > 0) {
272 decodedIndexes.add(new int[] { first, rows });
273 }
274 }
275
276 public void restoreState(FacesContext context, Object state) {
277 Object states[] = (Object[]) state;
278
279 super.restoreState(context, states[0]);
280
281 Object[] ss = (Object[]) states[1];
282
283 saved = new HashMap(ss.length / 2);
284 if (ss.length > 0) {
285 for (int i = 0; i < ss.length;) {
286 Object key = ss[i++];
287
288 SavedState2 ss2 = new SavedState2();
289 ss2.restoreState(context, ss[i++]);
290
291 saved.put(key, ss2);
292 }
293 }
294
295 }
296
297 public Object saveState(FacesContext context) {
298 Object ret[] = new Object[2];
299
300 ret[0] = super.saveState(context);
301
302 Object ss[] = new Object[saved.size() * 2];
303 ret[1] = ss;
304
305 if (ss.length > 0) {
306 int index = 0;
307 for (Iterator it = saved.entrySet().iterator(); it.hasNext();) {
308 Map.Entry entry = (Map.Entry) it.next();
309
310 ss[index++] = entry.getKey();
311 ss[index++] = ((SavedState2) entry.getValue())
312 .saveState(context);
313 }
314 }
315
316 return ret;
317 }
318
319
320
321
322
323
324
325
326
327
328
329
330
331 protected void restoreDescendantState(UIComponent component,
332 FacesContext context) {
333
334
335 String id = component.getId();
336 component.setId(id);
337
338 if (component instanceof IRCFacesComponent) {
339 String clientId = component.getClientId(context);
340 SavedState2 state = (SavedState2) saved.get(clientId);
341
342 if (state != null) {
343 IComponentEngine componentEngine = state.getComponentEngine(
344 context, component);
345 if (componentEngine != null) {
346 ComponentEngineManager.setComponentEngine(
347 (IRCFacesComponent) component, componentEngine);
348 }
349 } else {
350 ComponentEngineManager
351 .cloneComponentEngine((IRCFacesComponent) component);
352 }
353
354 if (LOG.isDebugEnabled()) {
355 LOG.debug("Restore state of '" + clientId + "' => " + state);
356 }
357 }
358
359 super.restoreDescendantState(component, context);
360 }
361
362
363
364
365
366
367
368
369
370
371
372
373 protected void saveDescendantState(UIComponent component,
374 FacesContext context) {
375
376 super.saveDescendantState(component, context);
377
378 if (isSaveCompleteState()) {
379 if (component instanceof IRCFacesComponent) {
380 IComponentEngine componentEngine = ComponentEngineManager
381 .getComponentEngine((IRCFacesComponent) component);
382
383 String clientId = component.getClientId(context);
384
385 SavedState2 state = (SavedState2) saved.get(clientId);
386 if (state == null) {
387 state = new SavedState2();
388 saved.put(clientId, state);
389 }
390
391 state.setComponentEngine(componentEngine);
392
393 if (LOG.isDebugEnabled()) {
394 LOG.debug("Save state of '" + clientId + "' => " + state);
395 }
396 }
397 }
398 }
399
400 public final boolean isSaveCompleteState() {
401 return saveCompleteState;
402 }
403
404 public final void setSaveCompleteState(boolean saveCompleteState) {
405 this.saveCompleteState = saveCompleteState;
406 }
407
408
409 public static class SavedState2 implements Externalizable, StateHolder {
410
411 private IComponentEngine componentEngine;
412
413 private Object serializedComponentEngine;
414
415 public SavedState2() {
416
417 }
418
419 public final IComponentEngine getComponentEngine(
420 FacesContext facesContext, UIComponent component) {
421 if (serializedComponentEngine == null) {
422 return componentEngine;
423 }
424
425 IFactory factory = Constants.getCameliaFactory();
426
427 IComponentEngine componentEngine = factory.createComponentEngine();
428
429 componentEngine.restoreState(facesContext,
430 serializedComponentEngine);
431
432 serializedComponentEngine = null;
433
434 return componentEngine;
435 }
436
437 public final void setComponentEngine(IComponentEngine componentEngine) {
438 this.componentEngine = componentEngine;
439 this.serializedComponentEngine = null;
440 }
441
442 public String toString() {
443 return "componentEngine=" + componentEngine;
444 }
445
446 public void readExternal(ObjectInput in) throws IOException,
447 ClassNotFoundException {
448
449 serializedComponentEngine = in.readObject();
450 }
451
452 public void writeExternal(ObjectOutput out) throws IOException {
453 if (componentEngine != null) {
454 serializedComponentEngine = componentEngine
455 .saveState(FacesContext.getCurrentInstance());
456 }
457
458 out.writeObject(serializedComponentEngine);
459 }
460
461 public Object saveState(FacesContext context) {
462 if (componentEngine != null) {
463 serializedComponentEngine = componentEngine
464 .saveState(FacesContext.getCurrentInstance());
465 }
466
467 return serializedComponentEngine;
468 }
469
470 public void restoreState(FacesContext context, Object state) {
471 serializedComponentEngine = state;
472 }
473
474 public boolean isTransient() {
475 return false;
476 }
477
478 public void setTransient(boolean newTransientValue) {
479 }
480
481 }
482
483 public boolean decodeAdditionalInformation(
484 IAdditionalInformationContainer additionalInformationComponent) {
485 if (decodedIndexes == null) {
486 if (DEBUG_ENABLED) {
487 int rowIndex = getRowIndex();
488
489 LOG.debug("Decode additional #" + rowIndex + " ("
490 + decodedIndexesToString() + ") => FALSE");
491 }
492 return false;
493 }
494
495 int rowIndex = getRowIndex();
496
497 for (int[] is : decodedIndexes) {
498 if (rowIndex >= is[0] && rowIndex < is[0] + is[1]) {
499 if (DEBUG_ENABLED) {
500 LOG.debug("Decode additional #" + rowIndex + " ("
501 + decodedIndexesToString() + ") => TRUE");
502 }
503 return true;
504 }
505 }
506
507 if (DEBUG_ENABLED) {
508 LOG.debug("Decode additional #" + rowIndex + " ("
509 + decodedIndexesToString() + ") => FALSE");
510 }
511
512 return false;
513 }
514
515 private String decodedIndexesToString() {
516 if (decodedIndexes == null) {
517 return "null";
518 }
519
520 if (decodedIndexes.isEmpty()) {
521 return "[]";
522 }
523
524 StringBuffer sb = new StringBuffer();
525
526 for (int is[] : decodedIndexes) {
527 if (sb.length() > 0) {
528 sb.append(',');
529 }
530 sb.append("[" + is[0] + "->" + (is[0] + is[1] - 1) + "]");
531 }
532
533 return sb.toString();
534 }
535 }