KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > faces > component > UIData


1 /*
2  * Copyright 2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package javax.faces.component;
17
18 import java.io.IOException JavaDoc;
19 import java.io.Serializable JavaDoc;
20 import java.sql.ResultSet JavaDoc;
21 import java.util.ArrayList JavaDoc;
22 import java.util.Collection JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.Map JavaDoc;
27
28 import javax.faces.context.FacesContext;
29 import javax.faces.el.ValueBinding;
30 import javax.faces.event.AbortProcessingException;
31 import javax.faces.event.FacesEvent;
32 import javax.faces.event.FacesListener;
33 import javax.faces.event.PhaseId;
34 import javax.faces.model.ArrayDataModel;
35 import javax.faces.model.DataModel;
36 import javax.faces.model.ListDataModel;
37 import javax.faces.model.ResultDataModel;
38 import javax.faces.model.ResultSetDataModel;
39 import javax.faces.model.ScalarDataModel;
40 import javax.servlet.jsp.jstl.sql.Result;
41
42 /**
43  * @author Manfred Geiler (latest modification by $Author: schof $)
44  * @version $Revision: 1.31 $ $Date: 2005/04/13 14:18:24 $
45  * $Log: UIData.java,v $
46  * Revision 1.31 2005/04/13 14:18:24 schof
47  * Fixes MYFACES-174 (Thanks to Mathias Broeklemann for the patch)
48  *
49  * Revision 1.30 2005/03/24 16:46:02 matzew
50  * MYFACES-142
51  *
52  * Revision 1.29 2005/03/16 20:10:59 mmarinschek
53  * fix for MYFACES-38, alien commit for Heath Borders
54  *
55  * Revision 1.28 2004/12/27 04:11:11 mmarinschek
56  * Data Table stores the state of facets of children; script tag is rendered with type attribute instead of language attribute, popup works better as a column in a data table
57  *
58  * Revision 1.27 2004/11/26 22:04:57 svieujot
59  * Make UIData work with Collection and not only List.
60  * This allows component like x:dataList to work with Sets, or any type of collection data model.
61  *
62  * Revision 1.26 2004/09/13 15:59:44 manolito
63  * fixed problems with nested UIData and HtmlDataTable components
64  *
65  * Revision 1.25 2004/07/01 22:00:50 mwessendorf
66  * ASF switch
67  *
68  * Revision 1.24 2004/06/21 12:15:29 manolito
69  * encodeBegin in UIData examines descendants valid flag recursivly now before refreshing DataModel
70  *
71  * Revision 1.23 2004/05/27 12:14:55 manolito
72  * no message
73  *
74  * Revision 1.22 2004/05/21 10:39:27 manolito
75  * new renderedIfEmpty attribute in ext. HtmlDataTable component
76  *
77  * Revision 1.21 2004/05/18 11:21:11 manolito
78  * optimized saving of descendant states: isAllChildrenAndFacetsValid loop no longer needed
79  *
80  */

81 public class UIData extends UIComponentBase implements NamingContainer
82 {
83     private static final int STATE_SIZE = 6;
84     private static final int SUPER_STATE_INDEX = 0;
85     private static final int FIRST_INDEX = 1;
86     private static final int ROWS_INDEX = 2;
87     private static final int VALUE_INDEX = 3;
88     private static final int VAR_INDEX = 4;
89     private static final int ROW_STATE_INDEX = 5;
90
91     private static final String JavaDoc FOOTER_FACET_NAME = "footer";
92     private static final String JavaDoc HEADER_FACET_NAME = "header";
93     private static final Class JavaDoc OBJECT_ARRAY_CLASS = (new Object JavaDoc[0]).getClass();
94     private static final int PROCESS_DECODES = 1;
95     private static final int PROCESS_VALIDATORS = 2;
96     private static final int PROCESS_UPDATES = 3;
97
98     // private static final Integer INTEGER_MINUS1 = new Integer(-1);
99

100     private int _rowIndex = -1;
101     private String JavaDoc _var = null;
102     // private Object[] _descendantStates;
103
// private int _descendantEditableValueHolderCount = -1;
104

105     private UIDataRowState _rowState = new UIDataRowState();
106
107     //init to false, so that no descendant states are saved for a newly created UIData
108
transient private boolean _saveDescendantStates = false;
109
110     //Flag to detect if component is rendered for the first time (restoreState sets it to false)
111
transient private boolean _firstTimeRendered = true;
112
113     private Boolean JavaDoc _isEmbeddedUIData = null;
114     private UIData _embeddingUIData = null;
115     private DataModel _dataModel = null;
116     private HashMap JavaDoc _dataModelMap = null;
117
118     public void setFooter(UIComponent footer)
119     {
120         getFacets().put(FOOTER_FACET_NAME, footer);
121     }
122
123     public UIComponent getFooter()
124     {
125         return (UIComponent) getFacets().get(FOOTER_FACET_NAME);
126     }
127
128     public void setHeader(UIComponent header)
129     {
130         getFacets().put(HEADER_FACET_NAME, header);
131     }
132
133     public UIComponent getHeader()
134     {
135         return (UIComponent) getFacets().get(HEADER_FACET_NAME);
136     }
137
138     public boolean isRowAvailable()
139     {
140         return getDataModel().isRowAvailable();
141     }
142
143     public int getRowCount()
144     {
145         return getDataModel().getRowCount();
146     }
147
148     public Object JavaDoc getRowData()
149     {
150         return getDataModel().getRowData();
151     }
152
153     public int getRowIndex()
154     {
155         return _rowIndex;
156     }
157
158     public void setRowIndex(int rowIndex)
159     {
160         saveDescendantComponentStates(getFacesContext(), this);
161
162         _rowIndex = rowIndex;
163
164         DataModel dataModel = getDataModel();
165         dataModel.setRowIndex(rowIndex);
166
167         String JavaDoc var = getVar();
168         if (rowIndex == -1)
169         {
170             if (var != null)
171             {
172                 getFacesContext().getExternalContext().getRequestMap().remove(var);
173             }
174         }
175         else
176         {
177             if (var != null)
178             {
179                 if (isRowAvailable())
180                 {
181                     Object JavaDoc rowData = dataModel.getRowData();
182                     getFacesContext().getExternalContext().getRequestMap().put(var, rowData);
183                 }
184                 else
185                 {
186                     getFacesContext().getExternalContext().getRequestMap().remove(var);
187                 }
188             }
189         }
190
191         restoreDescendantComponentStates(getFacesContext(), this, true);
192     }
193
194     // private int getDescendantStatesRowIndex()
195
// {
196
// int rowIndex = getRowIndex();
197
// if (rowIndex == -1)
198
// {
199
// return 0;
200
// }
201
// else
202
// {
203
// return rowIndex - getFirst() + 1;
204
// }
205
// }
206

207     private void saveDescendantComponentStates(FacesContext context, UIComponent component)
208     {
209         for (Iterator JavaDoc i = component.getFacetsAndChildren(); i.hasNext();)
210         {
211             //TODO: what if child is an EditableValueHolder AND a UIData?
212

213             UIComponent child = (UIComponent) i.next();
214             if (child instanceof UIData)
215             {
216                 UIData childUIData = (UIData) child;
217                 _rowState._clientIdsToChildUIDataStates.put(
218                     childUIData.getClientId(context),
219                     childUIData._rowState);
220                 continue;
221             }
222
223             if (child instanceof EditableValueHolder)
224             {
225                 EditableValueHolder childEVH = (EditableValueHolder) child;
226                 _rowState._clientIdsToChildEVHStates.put(
227                     child.getClientId(context),
228                     new EditableValueHolderState(childEVH));
229             }
230
231             saveDescendantComponentStates(context, child);
232         }
233     }
234
235     // /**
236
// * The descendant Component states algorithm we implement here is pretty fast
237
// * but does not support modification of the components tree during the lifecycle.
238
// * TODO: should we offer an alternative implementation with a clientId based Map ?
239
// */
240
// private void saveDescendantComponentStates()
241
// {
242
// if (_descendantEditableValueHolderCount == -1)
243
// {
244
// //This is the first time we save the descendant components state
245
// refreshDescendantDataStates();
246
// }
247
// else if (_descendantEditableValueHolderCount == 0)
248
// {
249
// //There are no EditableValueHolder children
250
// return;
251
// }
252
// else
253
// {
254
// int rowIndex = getDescendantStatesRowIndex();
255
// EditableValueHolderState[] rowState = null;
256
// // make sure that the underlying data did not change size
257
// // (i.e. someone added a row to the DataModel)
258
// // BUG: #925693
259
// if(rowIndex < _descendantStates.length) {
260
// rowState = (EditableValueHolderState[])_descendantStates[rowIndex];
261
// } else {
262
// // changed size during the lifecycle - should refresh
263
// refreshDescendantDataStates();
264
// rowState = (EditableValueHolderState[])_descendantStates[rowIndex];
265
// }
266
// if (rowState == null)
267
// {
268
// rowState = new EditableValueHolderState[_descendantEditableValueHolderCount];
269
// _descendantStates[rowIndex] = rowState;
270
// }
271
// saveDescendantComponentStates(this, rowState, 0, 0);
272
// }
273
// }
274

275     // private void refreshDescendantDataStates() {
276
// List list = new ArrayList();
277
// saveDescendantComponentStates(this, list,0);
278
// _descendantEditableValueHolderCount = list.size();
279
// if (_descendantEditableValueHolderCount > 0)
280
// {
281
// EditableValueHolderState[] rowState
282
// = (EditableValueHolderState[])list.toArray(new EditableValueHolderState[list.size()]);
283
// int rows = getRows();
284
// if (rows <= 0)
285
// {
286
// rows = getRowCount() - getFirst();
287
// }
288
// _descendantStates = new Object[rows + 1];
289
// int rowIndex = getDescendantStatesRowIndex();
290
// _descendantStates[rowIndex] = rowState;
291
// }
292
// }
293

294     // private static void saveDescendantComponentStates(UIComponent component, List list, int level)
295
// {
296
// for (Iterator it = getChildrenAndOptionalFacetsIterator(level,component); it.hasNext();)
297
// {
298
// UIComponent child = (UIComponent)it.next();
299
// if (child instanceof EditableValueHolder)
300
// {
301
// list.add(new EditableValueHolderState((EditableValueHolder)child));
302
// }
303
// saveDescendantComponentStates(child, list, level+1);
304
// }
305
// }
306

307     // private static Iterator getChildrenAndOptionalFacetsIterator(int level, UIComponent component)
308
// {
309
// Iterator it = null;
310
//
311
// if(level>1)
312
// {
313
// it = component.getFacetsAndChildren();
314
// }
315
// else
316
// {
317
// it = component.getChildren().iterator();
318
// }
319
// return it;
320
// }
321

322     // private static int saveDescendantComponentStates(UIComponent component,
323
// EditableValueHolderState[] states,
324
// int counter, int level)
325
// {
326
//
327
// for (Iterator it = getChildrenAndOptionalFacetsIterator(level, component); it.hasNext();)
328
// {
329
// UIComponent child = (UIComponent)it.next();
330
// if (child instanceof EditableValueHolder)
331
// {
332
// states[counter++] = new EditableValueHolderState((EditableValueHolder)child);
333
// }
334
// counter = saveDescendantComponentStates(child, states, counter,level+1);
335
// }
336
// return counter;
337
// }
338

339     private static String JavaDoc getInitialClientId(FacesContext context, UIComponent component)
340     {
341         /*
342          * The initialized value of oldRowIndex doesn't matter. If we dont' find a
343          * parentUIData, we'll throw an exception, and the value won't be used.
344          * If we do find it, the value will be set to the parentUIData's rowIndex.
345          * This is just to satisfy the compiler.
346          */

347         int oldRowIndex = 0;
348         UIData parentUIData = null;
349
350         for (UIComponent parent = component.getParent(); parent != null; parent = parent.getParent())
351         {
352             if (parent instanceof UIData)
353             {
354                 parentUIData = (UIData) parent;
355                 oldRowIndex = parentUIData._rowIndex;
356                 parentUIData._rowIndex = -1;
357                 break;
358             }
359         }
360
361         if (parentUIData == null)
362         {
363             throw new IllegalStateException JavaDoc(
364                 "Couldn't find a parent UIData for " + component.getClientId(context));
365         }
366
367         //TODO: Hack? This assumes that the component's internal clientId cache will be flushed.
368
component.setId(component.getId());
369         String JavaDoc clientId = component.getClientId(context);
370
371         parentUIData._rowIndex = oldRowIndex;
372
373         component.setId(component.getId());
374
375         return clientId;
376     }
377
378     private void restoreDescendantComponentStates(
379         FacesContext context,
380         UIComponent component,
381         boolean saveState)
382     {
383         for (Iterator JavaDoc i = component.getFacetsAndChildren(); i.hasNext();)
384         {
385             UIComponent child = (UIComponent) i.next();
386             //clear this descendant's clientId:
387
child.setId(child.getId());
388             //HACK: This assumes that setId always clears the cached clientId. Can we be sure?
389

390             if (saveState)
391             {
392                 //see saveDescendantComponentStates(UIComponent)
393
if (child instanceof UIData)
394                 {
395                     UIData childUIData = (UIData) child;
396                     Object JavaDoc state =
397                         _rowState._clientIdsToChildUIDataStates.get(
398                             childUIData.getClientId(context));
399                     if (state == null)
400                     {
401                         UIDataRowState initialState =
402                             (UIDataRowState) _rowState._clientIdsToChildUIDataStates.get(getInitialClientId(context, child));
403
404                         if (initialState == null)
405                         {
406                             throw new IllegalStateException JavaDoc(
407                                 "No initial state defined for clientId: " + child.getClientId(context));
408                         }
409
410                         state = new UIDataRowState(initialState);
411                     }
412
413
414
415                     childUIData._rowState = (UIDataRowState) state;
416
417                     restoreDescendantComponentStates(context, component, false);
418                     continue;
419                 }
420
421                 if (!_firstTimeRendered && child instanceof EditableValueHolder)
422                 {
423                     EditableValueHolder childEVH = (EditableValueHolder) child;
424                     Object JavaDoc state =
425                         _rowState._clientIdsToChildEVHStates.get(child.getClientId(context));
426                     if (state == null)
427                     {
428                         state =
429                             _rowState._clientIdsToChildEVHStates.get(
430                                 getInitialClientId(context, child));
431                     }
432                     ((EditableValueHolderState) state).restore(childEVH);
433                 }
434             }
435
436             restoreDescendantComponentStates(context, child, saveState);
437         }
438     }
439
440     // private void restoreDescendantComponentStates()
441
// {
442
// if (_descendantEditableValueHolderCount == -1)
443
// {
444
// throw new IllegalStateException("saveDescendantComponentStates not called yet?");
445
// }
446
// else if (_descendantEditableValueHolderCount > 0)
447
// {
448
// // There is at least one descendant component to be restored
449
//
450
// // Get zero-based index (instead of -1 based UIData zeroBasedRowIdx):
451
// int zeroBasedRowIdx = getDescendantStatesRowIndex();
452
//
453
// // Is there a reason to restore the state of a new descendant?
454
// // BUG: 925693
455
// // manolito: Yes, descendants for a row not yet saved, must be
456
// // reset to initial row state!
457
// int stateRowsCount = _descendantStates.length;
458
//
459
// EditableValueHolderState[] initialStates = null;
460
// if (stateRowsCount > 0)
461
// {
462
// // No state saved yet for this row, let's restore initial values:
463
// initialStates = (EditableValueHolderState[]) _descendantStates[0];
464
// }
465
//
466
// if (zeroBasedRowIdx < stateRowsCount)
467
// {
468
// // There is a saved state for this row, so restore these values:
469
// EditableValueHolderState[] rowState =
470
// (EditableValueHolderState[]) _descendantStates[zeroBasedRowIdx];
471
// restoreDescendantComponentStates(this, rowState, initialStates, 0, 0);
472
// }
473
// else
474
// {
475
// // No state saved yet for this row, let's restore initial values:
476
// restoreDescendantComponentStates(this, initialStates, initialStates, 0, 0);
477
// }
478
// }
479
// else
480
// {
481
// // There are no states to restore, so only recurse to set the
482
// // right clientIds for all descendants
483
// restoreDescendantComponentStates(this, null, null, 0, 0);
484
// }
485
// }
486

487     // private static int restoreDescendantComponentStates(UIComponent component,
488
// EditableValueHolderState[] states,
489
// EditableValueHolderState[] initialStates,
490
// int counter, int level)
491
// {
492
//
493
// for (Iterator it = getChildrenAndOptionalFacetsIterator(level, component); it.hasNext();)
494
// {
495
// UIComponent child = (UIComponent)it.next();
496
// //clear this descendant's clientId:
497
// child.setId(child.getId()); //HACK: This assumes that setId always clears the cached clientId. Can we be sure?
498
// if (child instanceof EditableValueHolder)
499
// {
500
// if (states != null)
501
// {
502
// states[counter].restore((EditableValueHolder)child);
503
// }
504
// else if (initialStates != null)
505
// {
506
// initialStates[counter].restore((EditableValueHolder)child);
507
// }
508
// else
509
// {
510
// // No state saved yet and no initial state !?
511
// // Should never be possible, but let's reset the component
512
// // state to null values
513
// ((EditableValueHolder)child).setValue(null);
514
// ((EditableValueHolder)child).setLocalValueSet(false);
515
// ((EditableValueHolder)child).setValid(true);
516
// ((EditableValueHolder)child).setSubmittedValue(null);
517
// }
518
// counter++;
519
// }
520
// counter = restoreDescendantComponentStates(child, states, initialStates, counter, level+1);
521
// }
522
// return counter;
523
// }
524

525     public void setRows(int rows)
526     {
527         _rows = new Integer JavaDoc(rows);
528         if (rows < 0)
529             throw new IllegalArgumentException JavaDoc("rows: " + rows);
530     }
531
532     public void setVar(String JavaDoc var)
533     {
534         _var = var;
535     }
536
537     public String JavaDoc getVar()
538     {
539         return _var;
540     }
541
542     public void setValueBinding(String JavaDoc name, ValueBinding binding)
543     {
544         if (name == null)
545         {
546             throw new NullPointerException JavaDoc("name");
547         }
548         else if (name.equals("value"))
549         {
550             _dataModel = null;
551         }
552         else if (name.equals("var") || name.equals("rowIndex"))
553         {
554             throw new IllegalArgumentException JavaDoc("name " + name);
555         }
556         super.setValueBinding(name, binding);
557     }
558
559     public String JavaDoc getClientId(FacesContext context)
560     {
561         String JavaDoc clientId = super.getClientId(context);
562         int rowIndex = getRowIndex();
563         if (rowIndex == -1)
564         {
565             return clientId;
566         }
567         else
568         {
569             return clientId + "_" + rowIndex;
570         }
571     }
572
573     public void queueEvent(FacesEvent event)
574     {
575         super.queueEvent(new FacesEventWrapper(event, getRowIndex(), this));
576     }
577
578     public void broadcast(FacesEvent event) throws AbortProcessingException
579     {
580         if (event instanceof FacesEventWrapper)
581         {
582             FacesEvent originalEvent = ((FacesEventWrapper) event).getWrappedFacesEvent();
583             int eventRowIndex = ((FacesEventWrapper) event).getRowIndex();
584             int currentRowIndex = getRowIndex();
585             setRowIndex(eventRowIndex);
586             originalEvent.getComponent().broadcast(originalEvent);
587             setRowIndex(currentRowIndex);
588         }
589         else
590         {
591             super.broadcast(event);
592         }
593     }
594
595     public void encodeBegin(FacesContext context) throws IOException JavaDoc
596     {
597         if (_firstTimeRendered || isAllChildrenAndFacetsValid())
598         {
599             _saveDescendantStates = false; // no need to save children states
600
//Refresh DataModel for rendering:
601
_dataModel = null;
602             if (_dataModelMap != null)
603                 _dataModelMap.clear();
604         }
605         else
606         {
607             _saveDescendantStates = true;
608             // save children states (valid flag, submittedValues, etc.)
609
}
610         super.encodeBegin(context);
611     }
612
613     public void encodeEnd(FacesContext context) throws IOException JavaDoc
614     {
615         setRowIndex(-1);
616
617         super.encodeEnd(context);
618     }
619
620     private boolean isAllChildrenAndFacetsValid()
621     {
622         int first = getFirst();
623         int rows = getRows();
624         int last;
625         if (rows == 0)
626         {
627             last = getRowCount();
628         }
629         else
630         {
631             last = first + rows;
632         }
633         int setRowIndex = getRowIndex();
634         try
635         {
636             for (int rowIndex = first; rowIndex < last; rowIndex++)
637             {
638                 setRowIndex(rowIndex);
639                 if (isRowAvailable())
640                 {
641                     if (!isAllEditableValueHoldersValidRecursive(getFacetsAndChildren()))
642                     {
643                         return false;
644                     }
645                 }
646             }
647         }
648         finally
649         {
650             setRowIndex(setRowIndex);
651         }
652         return true;
653     }
654
655     private boolean isAllEditableValueHoldersValidRecursive(Iterator JavaDoc facetsAndChildrenIterator)
656     {
657         while (facetsAndChildrenIterator.hasNext())
658         {
659             UIComponent c = (UIComponent) facetsAndChildrenIterator.next();
660             if (c instanceof EditableValueHolder && !((EditableValueHolder) c).isValid())
661             {
662                 return false;
663             }
664             if (!isAllEditableValueHoldersValidRecursive(c.getFacetsAndChildren()))
665             {
666                 return false;
667             }
668         }
669         return true;
670     }
671
672     public void processDecodes(FacesContext context)
673     {
674         if (context == null)
675             throw new NullPointerException JavaDoc("context");
676         if (!isRendered())
677             return;
678         setRowIndex(-1);
679         processFacets(context, PROCESS_DECODES);
680         processColumnFacets(context, PROCESS_DECODES);
681         processColumnChildren(context, PROCESS_DECODES);
682         setRowIndex(-1);
683         try
684         {
685             decode(context);
686         }
687         catch (RuntimeException JavaDoc e)
688         {
689             context.renderResponse();
690             throw e;
691         }
692     }
693
694     public void processValidators(FacesContext context)
695     {
696         if (context == null)
697             throw new NullPointerException JavaDoc("context");
698         if (!isRendered())
699             return;
700         setRowIndex(-1);
701         processFacets(context, PROCESS_VALIDATORS);
702         processColumnFacets(context, PROCESS_VALIDATORS);
703         processColumnChildren(context, PROCESS_VALIDATORS);
704         setRowIndex(-1);
705     }
706
707     public void processUpdates(FacesContext context)
708     {
709         if (context == null)
710             throw new NullPointerException JavaDoc("context");
711         if (!isRendered())
712             return;
713         setRowIndex(-1);
714         processFacets(context, PROCESS_UPDATES);
715         processColumnFacets(context, PROCESS_UPDATES);
716         processColumnChildren(context, PROCESS_UPDATES);
717         setRowIndex(-1);
718     }
719
720     private void processFacets(FacesContext context, int processAction)
721     {
722         for (Iterator JavaDoc it = getFacets().values().iterator(); it.hasNext();)
723         {
724             UIComponent facet = (UIComponent) it.next();
725             process(context, facet, processAction);
726         }
727     }
728
729     private void processColumnFacets(FacesContext context, int processAction)
730     {
731         for (Iterator JavaDoc childIter = getChildren().iterator(); childIter.hasNext();)
732         {
733             UIComponent child = (UIComponent) childIter.next();
734             if (child instanceof UIColumn)
735             {
736                 if (!child.isRendered())
737                 {
738                     //Column is not visible
739
continue;
740                 }
741                 for (Iterator JavaDoc facetsIter = child.getFacets().values().iterator();
742                     facetsIter.hasNext();
743                     )
744                 {
745                     UIComponent facet = (UIComponent) facetsIter.next();
746                     process(context, facet, processAction);
747                 }
748             }
749         }
750     }
751
752     private void processColumnChildren(FacesContext context, int processAction)
753     {
754         int first = getFirst();
755         int rows = getRows();
756         int last;
757         if (rows == 0)
758         {
759             last = getRowCount();
760         }
761         else
762         {
763             last = first + rows;
764         }
765         for (int rowIndex = first; rowIndex < last; rowIndex++)
766         {
767             setRowIndex(rowIndex);
768             if (isRowAvailable())
769             {
770                 for (Iterator JavaDoc it = getChildren().iterator(); it.hasNext();)
771                 {
772                     UIComponent child = (UIComponent) it.next();
773                     if (child instanceof UIColumn)
774                     {
775                         if (!child.isRendered())
776                         {
777                             //Column is not visible
778
continue;
779                         }
780                         for (Iterator JavaDoc columnChildIter = child.getChildren().iterator();
781                             columnChildIter.hasNext();
782                             )
783                         {
784                             UIComponent columnChild = (UIComponent) columnChildIter.next();
785                             process(context, columnChild, processAction);
786                         }
787                     }
788                 }
789             }
790         }
791     }
792
793     private void process(FacesContext context, UIComponent component, int processAction)
794     {
795         switch (processAction)
796         {
797             case PROCESS_DECODES :
798                 component.processDecodes(context);
799                 break;
800             case PROCESS_VALIDATORS :
801                 component.processValidators(context);
802                 break;
803             case PROCESS_UPDATES :
804                 component.processUpdates(context);
805                 break;
806         }
807     }
808
809     private DataModel getDataModel()
810     {
811         UIData embeddingUIData = getEmbeddingUIData();
812         if (embeddingUIData != null)
813         {
814             //This UIData is nested in another UIData, so we must not
815
//do simple caching of the current DataModel. We must associate
816
//the DataModel that we want to cache with the clientId of the
817
//embedding UIData. This clientId will be different for every
818
//row of the embedding UIData.
819
if (_dataModelMap == null)
820             {
821                 _dataModelMap = new HashMap JavaDoc();
822             }
823             String JavaDoc embeddingClientId =
824                 embeddingUIData.getClientId(FacesContext.getCurrentInstance());
825             DataModel dataModel = (DataModel) _dataModelMap.get(embeddingClientId);
826             if (dataModel == null)
827             {
828                 dataModel = createDataModel();
829                 _dataModelMap.put(embeddingClientId, dataModel);
830             }
831             return dataModel;
832         }
833         else
834         {
835             //This UIData is not nested within another UIData. So there
836
//is no need for the DataModel Map.
837
if (_dataModel == null)
838             {
839                 _dataModel = createDataModel();
840             }
841             return _dataModel;
842         }
843     }
844
845     /**
846      * Creates a new DataModel around the current value.
847      */

848     private DataModel createDataModel()
849     {
850         Object JavaDoc value = getValue();
851         if (value == null)
852         {
853             return EMPTY_DATA_MODEL;
854         }
855         else if (value instanceof DataModel)
856         {
857             return (DataModel) value;
858         }
859         else if (value instanceof List JavaDoc)
860         {
861             return new ListDataModel((List JavaDoc) value);
862         }
863         else if (value instanceof Collection JavaDoc)
864         {
865             return new ListDataModel(new ArrayList JavaDoc((Collection JavaDoc) value));
866         }
867         else if (OBJECT_ARRAY_CLASS.isAssignableFrom(value.getClass()))
868         {
869             return new ArrayDataModel((Object JavaDoc[]) value);
870         }
871         else if (value instanceof ResultSet JavaDoc)
872         {
873             return new ResultSetDataModel((ResultSet JavaDoc) value);
874         }
875         else if (value instanceof Result)
876         {
877             return new ResultDataModel((Result) value);
878         }
879         else
880         {
881             return new ScalarDataModel(value);
882         }
883     }
884
885     /**
886      * Looks for an embedding UIData component
887      * @return the embedding UIData or null
888      */

889     private UIData getEmbeddingUIData()
890     {
891         if (_isEmbeddedUIData == null)
892         {
893             UIComponent findParentUIData = getParent();
894             while (findParentUIData != null && !(findParentUIData instanceof UIData))
895             {
896                 findParentUIData = findParentUIData.getParent();
897             }
898             if (findParentUIData != null)
899             {
900                 _embeddingUIData = (UIData) findParentUIData;
901                 _isEmbeddedUIData = Boolean.TRUE;
902             }
903             else
904             {
905                 _isEmbeddedUIData = Boolean.FALSE;
906             }
907         }
908
909         if (_isEmbeddedUIData.booleanValue())
910         {
911             return _embeddingUIData;
912         }
913         else
914         {
915             return null;
916         }
917     }
918
919     private static class UIDataRowIndexState
920     {
921         private UIData _uiData;
922         private int _rowIndex;
923
924         public UIDataRowIndexState(UIData uiData)
925         {
926             _uiData = uiData;
927             _rowIndex = _uiData._rowIndex;
928         }
929
930         public void restore()
931         {
932             _uiData._rowIndex = _rowIndex;
933         }
934     }
935
936     private static class FacesEventWrapper extends FacesEvent
937     {
938         private FacesEvent _wrappedFacesEvent;
939         private int _rowIndex;
940
941         public FacesEventWrapper(FacesEvent facesEvent, int rowIndex, UIData redirectComponent)
942         {
943             super(redirectComponent);
944             _wrappedFacesEvent = facesEvent;
945             _rowIndex = rowIndex;
946         }
947
948         public PhaseId getPhaseId()
949         {
950             return _wrappedFacesEvent.getPhaseId();
951         }
952
953         public void setPhaseId(PhaseId phaseId)
954         {
955             _wrappedFacesEvent.setPhaseId(phaseId);
956         }
957
958         public void queue()
959         {
960             _wrappedFacesEvent.queue();
961         }
962
963         public String JavaDoc toString()
964         {
965             return _wrappedFacesEvent.toString();
966         }
967
968         public boolean isAppropriateListener(FacesListener faceslistener)
969         {
970             return _wrappedFacesEvent.isAppropriateListener(faceslistener);
971         }
972
973         public void processListener(FacesListener faceslistener)
974         {
975             _wrappedFacesEvent.processListener(faceslistener);
976         }
977
978         public FacesEvent getWrappedFacesEvent()
979         {
980             return _wrappedFacesEvent;
981         }
982
983         public int getRowIndex()
984         {
985             return _rowIndex;
986         }
987     }
988
989     private static final DataModel EMPTY_DATA_MODEL = new DataModel()
990     {
991         public boolean isRowAvailable()
992         {
993             return false;
994         }
995
996         public int getRowCount()
997         {
998             return 0;
999         }
1000
1001        public Object JavaDoc getRowData()
1002        {
1003            throw new IllegalArgumentException JavaDoc();
1004        }
1005
1006        public int getRowIndex()
1007        {
1008            return -1;
1009        }
1010
1011        public void setRowIndex(int i)
1012        {
1013            if (i < -1)
1014                throw new IllegalArgumentException JavaDoc();
1015        }
1016
1017        public Object JavaDoc getWrappedData()
1018        {
1019            return null;
1020        }
1021
1022        public void setWrappedData(Object JavaDoc obj)
1023        {
1024            if (obj == null)
1025                return; //Clearing is allowed
1026
throw new UnsupportedOperationException JavaDoc(
1027                this.getClass().getName() + " UnsupportedOperationException");
1028        }
1029    };
1030
1031    private static class UIDataRowState implements Cloneable JavaDoc, Serializable JavaDoc
1032    {
1033        private HashMap JavaDoc _clientIdsToChildUIDataStates = new HashMap JavaDoc();
1034        private HashMap JavaDoc _clientIdsToChildEVHStates = new HashMap JavaDoc();
1035
1036        public UIDataRowState()
1037        {
1038        }
1039
1040        public UIDataRowState(UIDataRowState initial)
1041        {
1042            for (Iterator JavaDoc i = initial._clientIdsToChildEVHStates.entrySet().iterator(); i.hasNext();)
1043            {
1044                Map.Entry JavaDoc entry = (Map.Entry JavaDoc) i.next();
1045                EditableValueHolderState initialState = (EditableValueHolderState) entry.getValue();
1046                _clientIdsToChildEVHStates.put(entry.getKey(), new EditableValueHolderState(initialState));
1047            }
1048
1049            for (Iterator JavaDoc i = initial._clientIdsToChildUIDataStates.entrySet().iterator(); i.hasNext();)
1050            {
1051                Map.Entry JavaDoc entry = (Map.Entry JavaDoc) i.next();
1052                UIDataRowState initialState = (UIDataRowState) entry.getValue();
1053                _clientIdsToChildEVHStates.put(entry.getKey(), new UIDataRowState(initialState));
1054            }
1055        }
1056    }
1057
1058    private static class EditableValueHolderState implements Serializable JavaDoc
1059    {
1060        private Object JavaDoc _localValue;
1061        private boolean _localValueSet;
1062        private boolean _valid;
1063        private Object JavaDoc _submittedValue;
1064
1065        public EditableValueHolderState(EditableValueHolder vh)
1066        {
1067            _localValue = vh.getLocalValue();
1068            _localValueSet = vh.isLocalValueSet();
1069            _valid = vh.isValid();
1070            _submittedValue = vh.getSubmittedValue();
1071        }
1072
1073        public EditableValueHolderState(EditableValueHolderState state)
1074        {
1075            _localValue = state._localValue;
1076            _localValueSet = state._localValueSet;
1077            _valid = state._valid;
1078            _submittedValue = state._submittedValue;
1079        }
1080
1081        public void restore(EditableValueHolder vh)
1082        {
1083            vh.setValue(_localValue);
1084            vh.setLocalValueSet(_localValueSet);
1085            vh.setValid(_valid);
1086            vh.setSubmittedValue(_submittedValue);
1087        }
1088
1089    }
1090
1091    public void setValue(Object JavaDoc value)
1092    {
1093        _value = value;
1094        _dataModel = null;
1095    }
1096
1097    public Object JavaDoc saveState(FacesContext context)
1098    {
1099        Object JavaDoc[] values = new Object JavaDoc[STATE_SIZE];
1100        values[SUPER_STATE_INDEX] = super.saveState(context);
1101        values[FIRST_INDEX] = _first;
1102        values[ROWS_INDEX] = _rows;
1103        values[VALUE_INDEX] = _value;
1104        values[VAR_INDEX] = _var;
1105        values[ROW_STATE_INDEX] = _rowState;
1106        return ((Object JavaDoc) (values));
1107    }
1108
1109    public void restoreState(FacesContext context, Object JavaDoc state)
1110    {
1111        Object JavaDoc[] values = (Object JavaDoc[]) state;
1112        super.restoreState(context, values[0]);
1113        _first = (Integer JavaDoc) values[FIRST_INDEX];
1114        _rows = (Integer JavaDoc) values[ROWS_INDEX];
1115        _value = (Object JavaDoc) values[VALUE_INDEX];
1116        _var = (String JavaDoc) values[VAR_INDEX];
1117        _rowState = (UIDataRowState) values[ROW_STATE_INDEX];
1118
1119        // restore state means component was already rendered at least once:
1120
_firstTimeRendered = false;
1121    }
1122
1123    //------------------ GENERATED CODE BEGIN (do not modify!) --------------------
1124

1125    public static final String JavaDoc COMPONENT_TYPE = "javax.faces.Data";
1126    public static final String JavaDoc COMPONENT_FAMILY = "javax.faces.Data";
1127    private static final String JavaDoc DEFAULT_RENDERER_TYPE = "javax.faces.Table";
1128    private static final int DEFAULT_FIRST = 0;
1129    private static final int DEFAULT_ROWS = 0;
1130
1131    private Integer JavaDoc _first = null;
1132    private Integer JavaDoc _rows = null;
1133    private Object JavaDoc _value = null;
1134
1135    public UIData()
1136    {
1137        setRendererType(DEFAULT_RENDERER_TYPE);
1138    }
1139
1140    public String JavaDoc getFamily()
1141    {
1142        return COMPONENT_FAMILY;
1143    }
1144
1145    public void setFirst(int first)
1146    {
1147        _first = new Integer JavaDoc(first);
1148    }
1149
1150    public int getFirst()
1151    {
1152        if (_first != null)
1153            return _first.intValue();
1154        ValueBinding vb = getValueBinding("first");
1155        Integer JavaDoc v = vb != null ? (Integer JavaDoc) vb.getValue(getFacesContext()) : null;
1156        return v != null ? v.intValue() : DEFAULT_FIRST;
1157    }
1158
1159    public int getRows()
1160    {
1161        if (_rows != null)
1162            return _rows.intValue();
1163        ValueBinding vb = getValueBinding("rows");
1164        Integer JavaDoc v = vb != null ? (Integer JavaDoc) vb.getValue(getFacesContext()) : null;
1165        return v != null ? v.intValue() : DEFAULT_ROWS;
1166    }
1167
1168    public Object JavaDoc getValue()
1169    {
1170        if (_value != null)
1171            return _value;
1172        ValueBinding vb = getValueBinding("value");
1173        return vb != null ? (Object JavaDoc) vb.getValue(getFacesContext()) : null;
1174    }
1175
1176    //------------------ GENERATED CODE END ---------------------------------------
1177

1178}
1179
Popular Tags