KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > facelets > component > UIRepeat


1 package com.sun.facelets.component;
2
3 import java.io.IOException JavaDoc;
4 import java.io.Serializable JavaDoc;
5 import java.sql.ResultSet JavaDoc;
6 import java.util.Collections JavaDoc;
7 import java.util.HashMap JavaDoc;
8 import java.util.Iterator JavaDoc;
9 import java.util.List JavaDoc;
10 import java.util.Map JavaDoc;
11
12 import javax.faces.FacesException;
13 import javax.faces.application.FacesMessage;
14 import javax.faces.component.EditableValueHolder;
15 import javax.faces.component.NamingContainer;
16 import javax.faces.component.UIComponent;
17 import javax.faces.component.UIComponentBase;
18 import javax.faces.component.UIData;
19 import javax.faces.context.FacesContext;
20 import javax.faces.el.ValueBinding;
21 import javax.faces.event.AbortProcessingException;
22 import javax.faces.event.FacesEvent;
23 import javax.faces.event.FacesListener;
24 import javax.faces.event.PhaseId;
25 import javax.faces.model.ArrayDataModel;
26 import javax.faces.model.DataModel;
27 import javax.faces.model.ListDataModel;
28 import javax.faces.model.ResultSetDataModel;
29 import javax.faces.model.ScalarDataModel;
30 import javax.faces.render.Renderer;
31
32 import com.sun.facelets.tag.jsf.ComponentSupport;
33 import com.sun.facelets.util.FacesAPI;
34
35 public class UIRepeat extends UIComponentBase implements NamingContainer {
36
37     public static final String JavaDoc COMPONENT_TYPE = "facelets.ui.Repeat";
38
39     public static final String JavaDoc COMPONENT_FAMILY = "facelets";
40
41     private final static DataModel EMPTY_MODEL = new ListDataModel(
42             Collections.EMPTY_LIST);
43
44     // our data
45
private Object JavaDoc value;
46
47     private transient DataModel model;
48
49     // variables
50
private String JavaDoc var;
51
52     private String JavaDoc varStatus;
53
54     private int index = -1;
55
56     // scoping
57
private int offset = -1;
58
59     private int size = -1;
60
61     public UIRepeat() {
62         this.setRendererType("facelets.ui.Repeat");
63     }
64
65     public String JavaDoc getFamily() {
66         return COMPONENT_FAMILY;
67     }
68
69     public int getOffset() {
70         if (this.offset != -1) {
71             return this.offset;
72         }
73         ValueBinding vb = this.getValueBinding("offset");
74         if (vb != null) {
75             return ((Integer JavaDoc) vb.getValue(FacesContext.getCurrentInstance()))
76                     .intValue();
77         }
78         return 0;
79     }
80
81     public void setOffset(int offset) {
82         this.offset = offset;
83     }
84
85     public int getSize() {
86         if (this.size != -1) {
87             return this.size;
88         }
89         ValueBinding vb = this.getValueBinding("size");
90         if (vb != null) {
91             return ((Integer JavaDoc) vb.getValue(FacesContext.getCurrentInstance()))
92                     .intValue();
93         }
94         return -1;
95     }
96
97     public void setSize(int size) {
98         this.size = size;
99     }
100
101     public String JavaDoc getVar() {
102         return this.var;
103     }
104
105     public void setVar(String JavaDoc var) {
106         this.var = var;
107     }
108
109     private void resetDataModel() {
110         if (this.isNestedInIterator()) {
111             this.setDataModel(null);
112         }
113     }
114
115     private void setDataModel(DataModel model) {
116         this.model = model;
117     }
118
119     private DataModel getDataModel() {
120         if (this.model == null) {
121             Object JavaDoc val = this.getValue();
122             if (val == null) {
123                 this.model = EMPTY_MODEL;
124             } else if (val instanceof DataModel) {
125                 this.model = (DataModel) val;
126             } else if (val instanceof List JavaDoc) {
127                 this.model = new ListDataModel((List JavaDoc) val);
128             } else if (Object JavaDoc[].class.isAssignableFrom(val.getClass())) {
129                 this.model = new ArrayDataModel((Object JavaDoc[]) val);
130             } else if (val instanceof ResultSet JavaDoc) {
131                 this.model = new ResultSetDataModel((ResultSet JavaDoc) val);
132             } else {
133                 this.model = new ScalarDataModel(val);
134             }
135         }
136         return this.model;
137     }
138
139     public Object JavaDoc getValue() {
140         if (this.value == null) {
141             ValueBinding vb = this.getValueBinding("value");
142             if (vb != null) {
143                 return vb.getValue(FacesContext.getCurrentInstance());
144             }
145         }
146         return this.value;
147     }
148
149     public void setValue(Object JavaDoc value) {
150         this.value = value;
151     }
152
153     private transient StringBuffer JavaDoc buffer;
154
155     private StringBuffer JavaDoc getBuffer() {
156         if (this.buffer == null) {
157             this.buffer = new StringBuffer JavaDoc();
158         }
159         this.buffer.setLength(0);
160         return this.buffer;
161     }
162
163     public String JavaDoc getClientId(FacesContext faces) {
164         String JavaDoc id = super.getClientId(faces);
165         if (this.index >= 0) {
166             id = this.getBuffer().append(id).append(
167                     NamingContainer.SEPARATOR_CHAR).append(this.index)
168                     .toString();
169         }
170         return id;
171     }
172
173     private transient Object JavaDoc origValue;
174
175     private void captureOrigValue() {
176         if (this.var != null) {
177             FacesContext faces = FacesContext.getCurrentInstance();
178             Map JavaDoc attrs = faces.getExternalContext().getRequestMap();
179             this.origValue = attrs.get(this.var);
180         }
181     }
182
183     private void restoreOrigValue() {
184         if (this.var != null) {
185             FacesContext faces = FacesContext.getCurrentInstance();
186             Map JavaDoc attrs = faces.getExternalContext().getRequestMap();
187             if (this.origValue != null) {
188                 attrs.put(this.var, this.origValue);
189             } else {
190                 attrs.remove(this.var);
191             }
192         }
193     }
194
195     private Map JavaDoc childState;
196
197     private Map JavaDoc getChildState() {
198         if (this.childState == null) {
199             this.childState = new HashMap JavaDoc();
200         }
201         return this.childState;
202     }
203
204     private void saveChildState() {
205         if (this.getChildCount() > 0) {
206
207             FacesContext faces = FacesContext.getCurrentInstance();
208
209             Iterator JavaDoc itr = this.getChildren().iterator();
210             while (itr.hasNext()) {
211                 this.saveChildState(faces, (UIComponent) itr.next());
212             }
213         }
214     }
215
216     private void saveChildState(FacesContext faces, UIComponent c) {
217
218         if (c instanceof EditableValueHolder && !c.isTransient()) {
219             String JavaDoc clientId = c.getClientId(faces);
220             SavedState ss = (SavedState) this.getChildState().get(clientId);
221             if (ss == null) {
222                 ss = new SavedState();
223                 this.getChildState().put(clientId, ss);
224             }
225             ss.populate((EditableValueHolder) c);
226         }
227
228         // continue hack
229
Iterator JavaDoc itr = c.getFacetsAndChildren();
230         while (itr.hasNext()) {
231             saveChildState(faces, (UIComponent) itr.next());
232         }
233     }
234
235     private void restoreChildState() {
236         if (this.getChildCount() > 0) {
237
238             FacesContext faces = FacesContext.getCurrentInstance();
239
240             Iterator JavaDoc itr = this.getChildren().iterator();
241             while (itr.hasNext()) {
242                 this.restoreChildState(faces, (UIComponent) itr.next());
243             }
244         }
245     }
246
247     private void restoreChildState(FacesContext faces, UIComponent c) {
248         // reset id
249
String JavaDoc id = c.getId();
250         c.setId(id);
251
252         // hack
253
if (c instanceof EditableValueHolder) {
254             EditableValueHolder evh = (EditableValueHolder) c;
255             String JavaDoc clientId = c.getClientId(faces);
256             SavedState ss = (SavedState) this.getChildState().get(clientId);
257             if (ss != null) {
258                 ss.apply(evh);
259             } else {
260                 NullState.apply(evh);
261             }
262         }
263
264         // continue hack
265
Iterator JavaDoc itr = c.getFacetsAndChildren();
266         while (itr.hasNext()) {
267             restoreChildState(faces, (UIComponent) itr.next());
268         }
269     }
270
271     private boolean keepSaved(FacesContext context) {
272
273         Iterator JavaDoc clientIds = this.getChildState().keySet().iterator();
274         while (clientIds.hasNext()) {
275             String JavaDoc clientId = (String JavaDoc) clientIds.next();
276             Iterator JavaDoc messages = context.getMessages(clientId);
277             while (messages.hasNext()) {
278                 FacesMessage message = (FacesMessage) messages.next();
279                 if (message.getSeverity()
280                         .compareTo(FacesMessage.SEVERITY_ERROR) >= 0) {
281                     return (true);
282                 }
283             }
284         }
285         return (isNestedInIterator());
286     }
287     
288     private boolean isNestedInIterator() {
289         UIComponent parent = this.getParent();
290         while (parent != null) {
291             if (parent instanceof UIData || parent instanceof UIRepeat) {
292                 return true;
293             }
294             parent = parent.getParent();
295         }
296         return false;
297     }
298
299     private void setIndex(int index) {
300
301         // save child state
302
this.saveChildState();
303
304         this.index = index;
305         DataModel localModel = getDataModel();
306         localModel.setRowIndex(index);
307
308         if (this.index != -1 && this.var != null && localModel.isRowAvailable()) {
309             FacesContext faces = FacesContext.getCurrentInstance();
310             Map JavaDoc attrs = faces.getExternalContext().getRequestMap();
311             attrs.put(var, localModel.getRowData());
312         }
313
314         // restore child state
315
this.restoreChildState();
316     }
317
318     private boolean isIndexAvailable() {
319         return this.getDataModel().isRowAvailable();
320     }
321
322     public void process(FacesContext faces, PhaseId phase) {
323
324         // stop if not rendered
325
if (!this.isRendered())
326             return;
327
328         // clear datamodel
329
this.resetDataModel();
330
331         // reset index
332
this.captureOrigValue();
333         this.setIndex(-1);
334
335         try {
336             // has children
337
if (this.getChildCount() > 0) {
338                 Iterator JavaDoc itr;
339                 UIComponent c;
340
341                 int i = this.getOffset();
342                 int end = this.getSize();
343                 end = (end >= 0) ? i + end : Integer.MAX_VALUE;
344
345                 // grab renderer
346
String JavaDoc rendererType = getRendererType();
347                 Renderer renderer = null;
348                 if (rendererType != null) {
349                     renderer = getRenderer(faces);
350                 }
351
352                 this.setIndex(i);
353                 while (i <= end && this.isIndexAvailable()) {
354
355                     if (PhaseId.RENDER_RESPONSE.equals(phase)
356                             && renderer != null) {
357                         renderer.encodeChildren(faces, this);
358                     } else {
359                         itr = this.getChildren().iterator();
360                         while (itr.hasNext()) {
361                             c = (UIComponent) itr.next();
362                             if (PhaseId.APPLY_REQUEST_VALUES.equals(phase)) {
363                                 c.processDecodes(faces);
364                             } else if (PhaseId.PROCESS_VALIDATIONS
365                                     .equals(phase)) {
366                                 c.processValidators(faces);
367                             } else if (PhaseId.UPDATE_MODEL_VALUES
368                                     .equals(phase)) {
369                                 c.processUpdates(faces);
370                             } else if (PhaseId.RENDER_RESPONSE.equals(phase)) {
371                                 if (FacesAPI.getVersion() >= 12) {
372                                     c.encodeAll(faces);
373                                 } else {
374                                     ComponentSupport.encodeRecursive(faces, c);
375                                 }
376                             }
377                         }
378                     }
379                     i++;
380                     this.setIndex(i);
381                 }
382             }
383         } catch (IOException JavaDoc e) {
384             throw new FacesException(e);
385         } finally {
386             this.setIndex(-1);
387             this.restoreOrigValue();
388         }
389     }
390
391     // public boolean invokeOnComponent(FacesContext faces, String clientId,
392
// ContextCallback callback) throws FacesException {
393
// String id = super.getClientId(faces);
394
// if (clientId.equals(id)) {
395
// callback.invokeContextCallback(faces, this);
396
// return true;
397
// } else if (clientId.startsWith(id)) {
398
// int prevIndex = this.index;
399
// int idxStart = clientId.indexOf(NamingContainer.SEPARATOR_CHAR, id
400
// .length());
401
// if (idxStart != -1
402
// && Character.isDigit(clientId.charAt(idxStart + 1))) {
403
// int idxEnd = clientId.indexOf(NamingContainer.SEPARATOR_CHAR,
404
// idxStart);
405
// if (idxEnd != -1) {
406
// int newIndex = Integer.parseInt(clientId.substring(
407
// idxStart, idxEnd));
408
// boolean found = false;
409
// try {
410
// this.captureOrigValue();
411
// this.setIndex(newIndex);
412
// if (this.isIndexAvailable()) {
413
// found = super.invokeOnComponent(faces, clientId,
414
// callback);
415
// }
416
// } finally {
417
// this.setIndex(prevIndex);
418
// this.restoreOrigValue();
419
// }
420
// return found;
421
// }
422
// } else {
423
// return super.invokeOnComponent(faces, clientId, callback);
424
// }
425
// }
426
// return false;
427
// }
428

429     public void processDecodes(FacesContext faces) {
430         if (!this.isRendered())
431             return;
432         this.setDataModel(null);
433         if (!this.keepSaved(faces)) this.childState = null;
434         this.process(faces, PhaseId.APPLY_REQUEST_VALUES);
435         this.decode(faces);
436     }
437
438     public void processUpdates(FacesContext faces) {
439         if (!this.isRendered()) return;
440         this.resetDataModel();
441         this.process(faces, PhaseId.UPDATE_MODEL_VALUES);
442     }
443
444     public void processValidators(FacesContext faces) {
445         if (!this.isRendered()) return;
446         this.resetDataModel();
447         this.process(faces, PhaseId.PROCESS_VALIDATIONS);
448     }
449
450     private final static SavedState NullState = new SavedState();
451
452     // from RI
453
private final static class SavedState implements Serializable JavaDoc {
454
455         private Object JavaDoc submittedValue;
456
457         private static final long serialVersionUID = 2920252657338389849L;
458
459         Object JavaDoc getSubmittedValue() {
460             return (this.submittedValue);
461         }
462
463         void setSubmittedValue(Object JavaDoc submittedValue) {
464             this.submittedValue = submittedValue;
465         }
466
467         private boolean valid = true;
468
469         boolean isValid() {
470             return (this.valid);
471         }
472
473         void setValid(boolean valid) {
474             this.valid = valid;
475         }
476
477         private Object JavaDoc value;
478
479         Object JavaDoc getValue() {
480             return (this.value);
481         }
482
483         public void setValue(Object JavaDoc value) {
484             this.value = value;
485         }
486
487         private boolean localValueSet;
488
489         boolean isLocalValueSet() {
490             return (this.localValueSet);
491         }
492
493         public void setLocalValueSet(boolean localValueSet) {
494             this.localValueSet = localValueSet;
495         }
496
497         public String JavaDoc toString() {
498             return ("submittedValue: " + submittedValue + " value: " + value
499                     + " localValueSet: " + localValueSet);
500         }
501
502         public void populate(EditableValueHolder evh) {
503             this.value = evh.getValue();
504             this.valid = evh.isValid();
505             this.submittedValue = evh.getSubmittedValue();
506             this.localValueSet = evh.isLocalValueSet();
507         }
508
509         public void apply(EditableValueHolder evh) {
510             evh.setValue(this.value);
511             evh.setValid(this.valid);
512             evh.setSubmittedValue(this.submittedValue);
513             evh.setLocalValueSet(this.localValueSet);
514         }
515
516     }
517
518     private final class IndexedEvent extends FacesEvent {
519
520         private final FacesEvent target;
521
522         private final int index;
523
524         public IndexedEvent(UIRepeat owner, FacesEvent target, int index) {
525             super(owner);
526             this.target = target;
527             this.index = index;
528         }
529
530         public PhaseId getPhaseId() {
531             return (this.target.getPhaseId());
532         }
533
534         public void setPhaseId(PhaseId phaseId) {
535             this.target.setPhaseId(phaseId);
536         }
537
538         public boolean isAppropriateListener(FacesListener listener) {
539             return this.target.isAppropriateListener(listener);
540         }
541
542         public void processListener(FacesListener listener) {
543             UIRepeat owner = (UIRepeat) this.getComponent();
544             int prevIndex = owner.index;
545             try {
546                 owner.setIndex(this.index);
547                 if (owner.isIndexAvailable()) {
548                     this.target.processListener(listener);
549                 }
550             } finally {
551                 owner.setIndex(prevIndex);
552             }
553         }
554
555         public int getIndex() {
556             return index;
557         }
558
559         public FacesEvent getTarget() {
560             return target;
561         }
562
563     }
564
565     public void broadcast(FacesEvent event) throws AbortProcessingException {
566         if (event instanceof IndexedEvent) {
567             IndexedEvent idxEvent = (IndexedEvent) event;
568             this.resetDataModel();
569             int prevIndex = this.index;
570             try {
571                 this.setIndex(idxEvent.getIndex());
572                 if (this.isIndexAvailable()) {
573                     FacesEvent target = idxEvent.getTarget();
574                     target.getComponent().broadcast(target);
575                 }
576             } finally {
577                 this.setIndex(prevIndex);
578             }
579         } else {
580             super.broadcast(event);
581         }
582     }
583
584     public void queueEvent(FacesEvent event) {
585         super.queueEvent(new IndexedEvent(this, event, this.index));
586     }
587
588     public void restoreState(FacesContext faces, Object JavaDoc object) {
589         Object JavaDoc[] state = (Object JavaDoc[]) object;
590         super.restoreState(faces, state[0]);
591         this.childState = (Map JavaDoc) state[1];
592         this.offset = ((Integer JavaDoc) state[2]).intValue();
593         this.size = ((Integer JavaDoc) state[3]).intValue();
594         this.var = (String JavaDoc) state[4];
595         this.value = state[5];
596     }
597
598     public Object JavaDoc saveState(FacesContext faces) {
599         Object JavaDoc[] state = new Object JavaDoc[6];
600         state[0] = super.saveState(faces);
601         state[1] = this.childState;
602         state[2] = new Integer JavaDoc(this.offset);
603         state[3] = new Integer JavaDoc(this.size);
604         state[4] = this.var;
605         state[5] = this.value;
606         return state;
607     }
608
609     public void encodeChildren(FacesContext faces) throws IOException JavaDoc {
610         if (!isRendered()) {
611             return;
612         }
613         this.setDataModel(null);
614         if (!this.keepSaved(faces)) {
615             this.childState = null;
616         }
617         this.process(faces, PhaseId.RENDER_RESPONSE);
618     }
619
620     public boolean getRendersChildren() {
621         Renderer renderer = null;
622         if (getRendererType() != null) {
623             if (null != (renderer = getRenderer(getFacesContext()))) {
624                 return renderer.getRendersChildren();
625             }
626         }
627         return true;
628     }
629 }
630
Popular Tags