KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icesoft > faces > component > panelseries > UISeries


1 /*
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * "The contents of this file are subject to the Mozilla Public License
5  * Version 1.1 (the "License"); you may not use this file except in
6  * compliance with the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
11  * License for the specific language governing rights and limitations under
12  * the License.
13  *
14  * The Original Code is ICEfaces 1.5 open source software code, released
15  * November 5, 2006. The Initial Developer of the Original Code is ICEsoft
16  * Technologies Canada, Corp. Portions created by ICEsoft are Copyright (C)
17  * 2004-2006 ICEsoft Technologies Canada, Corp. All Rights Reserved.
18  *
19  * Contributor(s): _____________________.
20  *
21  * Alternatively, the contents of this file may be used under the terms of
22  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"
23  * License), in which case the provisions of the LGPL License are
24  * applicable instead of those above. If you wish to allow use of your
25  * version of this file only under the terms of the LGPL License and not to
26  * allow others to use your version of this file under the MPL, indicate
27  * your decision by deleting the provisions above and replace them with
28  * the notice and other provisions required by the LGPL License. If you do
29  * not delete the provisions above, a recipient may use your version of
30  * this file under either the MPL or the LGPL License."
31  *
32  */

33
34 package com.icesoft.faces.component.panelseries;
35
36 import com.icesoft.faces.component.tree.TreeDataModel;
37
38 import javax.faces.application.FacesMessage;
39 import javax.faces.component.EditableValueHolder;
40 import javax.faces.component.NamingContainer;
41 import javax.faces.component.UIComponent;
42 import javax.faces.component.UIData;
43 import javax.faces.component.html.HtmlDataTable;
44 import javax.faces.component.html.HtmlForm;
45 import javax.faces.context.FacesContext;
46 import javax.faces.el.ValueBinding;
47 import javax.faces.event.AbortProcessingException;
48 import javax.faces.event.FacesEvent;
49 import javax.faces.event.FacesListener;
50 import javax.faces.event.PhaseId;
51 import javax.faces.model.ArrayDataModel;
52 import javax.faces.model.DataModel;
53 import javax.faces.model.ListDataModel;
54 import javax.faces.model.ResultDataModel;
55 import javax.faces.model.ResultSetDataModel;
56 import javax.faces.model.ScalarDataModel;
57 import javax.servlet.jsp.jstl.sql.Result;
58 import javax.swing.tree.TreeModel JavaDoc;
59 import java.io.IOException JavaDoc;
60 import java.io.Serializable JavaDoc;
61 import java.sql.ResultSet JavaDoc;
62 import java.util.Collections JavaDoc;
63 import java.util.HashMap JavaDoc;
64 import java.util.Iterator JavaDoc;
65 import java.util.List JavaDoc;
66 import java.util.Map JavaDoc;
67
68
69 /**
70  * This is an extended version of UIData, which allows any UISeries type of
71  * component to have any type of children, it is not restricted to use the
72  * column component as a first child.
73  */

74 public class UISeries extends HtmlDataTable {
75     public static final String JavaDoc COMPONENT_TYPE = "com.icesoft.faces.series";
76     public static final String JavaDoc RENDERER_TYPE = "com.icesoft.faces.seriesRenderer";
77     protected transient DataModel dataModel = null;
78     private int rowIndex = -1;
79     protected Map JavaDoc savedChildren = new HashMap JavaDoc();
80     private String JavaDoc var = null;
81
82
83     public UISeries() {
84         super();
85         setRendererType(RENDERER_TYPE);
86     }
87
88     /**
89      * @see javax.faces.component.UIData#isRowAvailable()
90      */

91     public boolean isRowAvailable() {
92         return (getDataModel().isRowAvailable());
93     }
94
95
96     /**
97      * @see javax.faces.component.UIData#getRowCount()
98      */

99     public int getRowCount() {
100         return (getDataModel().getRowCount());
101     }
102
103
104     /**
105      * @see javax.faces.component.UIData#getRowData()
106      */

107     public Object JavaDoc getRowData() {
108         return (getDataModel().getRowData());
109     }
110
111
112     /**
113      * @see javax.faces.component.UIData#getRowIndex()
114      */

115     public int getRowIndex() {
116         return (this.rowIndex);
117     }
118
119     public void setRowIndex(int rowIndex) {
120         FacesContext facesContext = getFacesContext();
121         // Save current state for the previous row index
122
saveChildrenState(facesContext);
123         // remove or load the current row data as a request scope attribute
124
processCurrentRowData(facesContext, rowIndex);
125         // Reset current state information for the new row index
126
restoreChildrenState(facesContext);
127     }
128
129     private void processCurrentRowData(FacesContext facesContext,
130                                        int rowIndex) {
131         this.rowIndex = rowIndex;
132         DataModel model = getDataModel();
133         model.setRowIndex(rowIndex);
134
135         if (var != null) {
136             Map JavaDoc requestMap = facesContext.getExternalContext().getRequestMap();
137             if (rowIndex == -1) {
138                 loadRowToRequestMap(requestMap, false);
139             } else if (isRowAvailable()) {
140                 loadRowToRequestMap(requestMap, true);
141             } else {
142                 loadRowToRequestMap(requestMap, false);
143             }
144         }
145     }
146
147     private void loadRowToRequestMap(Map JavaDoc requestMap, boolean loadRow) {
148         if (loadRow) {
149             requestMap.put(var, getRowData());
150         } else {
151             requestMap.remove(var);
152         }
153     }
154
155
156     /**
157      * @see javax.faces.component.UIData#getVar()
158      */

159     public String JavaDoc getVar() {
160         return (this.var);
161     }
162
163
164     /**
165      * @see javax.faces.component.UIData#setVar(Stringvar)
166      */

167     public void setVar(String JavaDoc var) {
168         this.var = var;
169     }
170
171     /**
172      * @see javax.faces.component.UIData#setValue(Objectvalue)
173      */

174     public void setValue(Object JavaDoc value) {
175         this.dataModel = null;
176         super.setValue(value);
177     }
178
179
180     public void setValueBinding(String JavaDoc name, ValueBinding binding) {
181         if ("value".equals(name)) {
182             this.dataModel = null;
183         } else if ("var".equals(name) || "rowIndex".equals(name)) {
184             throw new IllegalArgumentException JavaDoc();
185         }
186         super.setValueBinding(name, binding);
187     }
188
189
190     /**
191      * @see javax.faces.component.UIData#getClientId(FacesContextcontext)
192      */

193     public String JavaDoc getClientId(FacesContext context) {
194         if (context == null) {
195             throw new NullPointerException JavaDoc();
196         }
197         String JavaDoc baseClientId = super.getClientId(context);
198         if (getRowIndex() >= 0) {
199             //this extra if is to produce the same ids among myfaces and sunri
200
//myfaces uses the getRowIndex() and SunRI directly using the rowIndex
201
//variable inside its getClientId()
202
if (!baseClientId.endsWith(
203                     "" + NamingContainer.SEPARATOR_CHAR + getRowIndex())) {
204                 return (baseClientId + NamingContainer.SEPARATOR_CHAR +
205                         getRowIndex());
206             }
207             return (baseClientId);
208         } else {
209             return (baseClientId);
210         }
211     }
212
213
214     /**
215      * @see javax.faces.component.UIData#queueEvent(FacesEventevent)
216      */

217     public void queueEvent(FacesEvent event) {
218         super.queueEvent(new RowEvent(this, event, getRowIndex()));
219     }
220
221
222     /**
223      * @see javax.faces.component.UIData#broadcast(FacesEventevent)
224      */

225     public void broadcast(FacesEvent event) throws AbortProcessingException {
226         if (!(event instanceof RowEvent)) {
227             super.broadcast(event);
228             return;
229         }
230
231         // fire row specific event
232
((RowEvent) event).broadcast();
233         return;
234     }
235
236
237     /**
238      * @see javax.faces.component.UIData#encodeBegin(FacesContextcontext)
239      */

240     public void encodeBegin(FacesContext context) throws IOException JavaDoc {
241         dataModel = null;
242         if (!keepSaved(context)) {
243             savedChildren = new HashMap JavaDoc();
244         }
245         super.encodeBegin(context);
246     }
247
248
249     public void processDecodes(FacesContext context) {
250         if (context == null) {
251             throw new NullPointerException JavaDoc();
252         }
253         if (!isRendered()) {
254             return;
255         }
256
257         dataModel = null;
258         if (null == savedChildren || !keepSaved(context)) {
259             savedChildren = new HashMap JavaDoc();
260         }
261
262         iterate(context, PhaseId.APPLY_REQUEST_VALUES);
263         decode(context);
264     }
265
266     public void processValidators(FacesContext context) {
267         if (context == null) {
268             throw new NullPointerException JavaDoc();
269         }
270         if (!isRendered()) {
271             return;
272         }
273         if (isNestedWithinUIData()) {
274             dataModel = null;
275         }
276         iterate(context, PhaseId.PROCESS_VALIDATIONS);
277     }
278
279
280     public void processUpdates(FacesContext context) {
281         if (context == null) {
282             throw new NullPointerException JavaDoc();
283         }
284         if (!isRendered()) {
285             return;
286         }
287         if (isNestedWithinUIData()) {
288             dataModel = null;
289         }
290         iterate(context, PhaseId.UPDATE_MODEL_VALUES);
291     }
292
293     /**
294      * <p>Return the DataModel containing the Objects that will be iterated over
295      * when this component is rendered.</p>
296      *
297      * @return
298      */

299     private DataModel getDataModel() {
300         if (null != this.dataModel) {
301             return (dataModel);
302         }
303
304         Object JavaDoc currentValue = getValue();
305
306         if (null == currentValue) {
307             this.dataModel = new ListDataModel(Collections.EMPTY_LIST);
308         } else if (currentValue instanceof DataModel) {
309             this.dataModel = (DataModel) currentValue;
310         } else if (currentValue instanceof List JavaDoc) {
311             this.dataModel = new ListDataModel((List JavaDoc) currentValue);
312         } else if (Object JavaDoc[].class.isAssignableFrom(currentValue.getClass())) {
313             this.dataModel = new ArrayDataModel((Object JavaDoc[]) currentValue);
314         } else if (currentValue instanceof ResultSet JavaDoc) {
315             this.dataModel = new ResultSetDataModel((ResultSet JavaDoc) currentValue);
316         } else if (currentValue instanceof Result) {
317             this.dataModel = new ResultDataModel((Result) currentValue);
318         } else if (currentValue instanceof TreeModel JavaDoc) {
319             this.dataModel = new TreeDataModel((TreeModel JavaDoc) currentValue);
320         } else {
321             this.dataModel = new ScalarDataModel(currentValue);
322         }
323
324         return (dataModel);
325     }
326
327     protected void iterate(FacesContext facesContext, PhaseId phase) {
328         // clear rowIndex
329
setRowIndex(-1);
330
331         int rowsProcessed = 0;
332         int currentRowIndex = getFirst() - 1;
333         int displayedRows = getRows();
334         // loop over dataModel processing each row once
335
while (1 == 1) {
336             // break if we have processed the number of rows requested
337
if ((displayedRows > 0) && (++rowsProcessed > displayedRows)) {
338                 break;
339             }
340             // process the row at currentRowIndex
341
setRowIndex(++currentRowIndex);
342             // break if we've moved past the last row
343
if (!isRowAvailable()) {
344                 break;
345             }
346             // loop over children and facets
347
Iterator JavaDoc children = getFacetsAndChildren();
348             while (children.hasNext()) {
349                 UIComponent child = (UIComponent) children.next();
350                 if (phase == PhaseId.APPLY_REQUEST_VALUES) {
351                     child.processDecodes(facesContext);
352                 } else if (phase == PhaseId.PROCESS_VALIDATIONS) {
353                     child.processValidators(facesContext);
354                 } else if (phase == PhaseId.UPDATE_MODEL_VALUES) {
355                     child.processUpdates(facesContext);
356                 } else {
357                     throw new IllegalArgumentException JavaDoc();
358                 }
359             }
360         }
361
362         // clear rowIndex
363
setRowIndex(-1);
364     }
365
366     /**
367      * <p>Return true when we need to keep the child state to display error
368      * messages.</p>
369      *
370      * @param facesContext
371      * @return
372      */

373     private boolean keepSaved(FacesContext facesContext) {
374         Iterator JavaDoc childIds = savedChildren.keySet().iterator();
375         while (childIds.hasNext()) {
376             String JavaDoc childId = (String JavaDoc) childIds.next();
377             Iterator JavaDoc childMessages = facesContext.getMessages(childId);
378             while (childMessages.hasNext()) {
379                 FacesMessage childMessage = (FacesMessage) childMessages.next();
380                 if (childMessage.getSeverity()
381                         .compareTo(FacesMessage.SEVERITY_ERROR) >= 0) {
382                     return (true);
383                 }
384             }
385         }
386         // return true if this component is nested inside a UIData
387
return (isNestedWithinUIData());
388     }
389
390     private boolean isNestedWithinUIData() {
391         UIComponent parent = this;
392         while (null != (parent = parent.getParent())) {
393             if (parent instanceof UIData) {
394                 return true;
395             }
396         }
397         return (false);
398     }
399
400
401     protected void restoreChildrenState(FacesContext facesContext) {
402         Iterator JavaDoc children = getFacetsAndChildren();
403         while (children.hasNext()) {
404             UIComponent child = (UIComponent) children.next();
405             restoreChildState(facesContext, child);
406         }
407     }
408
409
410     protected void restoreChildState(FacesContext facesContext,
411                                      UIComponent component) {
412         String JavaDoc id = component.getId();
413         if (!isValid(id)) {
414             return;
415         }
416         component.setId(id);
417         restoreChild(facesContext, component);
418         Iterator JavaDoc children = component.getFacetsAndChildren();
419         while (children.hasNext()) {
420             restoreChildState(facesContext, (UIComponent) children.next());
421         }
422     }
423
424     protected void saveChild(FacesContext facesContext, UIComponent component) {
425         if (component instanceof EditableValueHolder) {
426             EditableValueHolder input = (EditableValueHolder) component;
427             String JavaDoc clientId = component.getClientId(facesContext);
428             ChildState state = (ChildState) savedChildren.get(clientId);
429             if (state == null) {
430                 state = new ChildState();
431                 savedChildren.put(clientId, state);
432             }
433             state.setValue(input.getLocalValue());
434             state.setValid(input.isValid());
435             state.setSubmittedValue(input.getSubmittedValue());
436             state.setLocalValueSet(input.isLocalValueSet());
437         } else if (component instanceof HtmlForm) {
438             String JavaDoc clientId = component.getClientId(facesContext);
439             Boolean JavaDoc isThisFormSubmitted = (Boolean JavaDoc) savedChildren.get(clientId);
440             if (isThisFormSubmitted == null) {
441                 isThisFormSubmitted =
442                         new Boolean JavaDoc(((HtmlForm) component).isSubmitted());
443                 savedChildren.put(clientId, isThisFormSubmitted);
444             }
445         }
446     }
447
448     protected void restoreChild(FacesContext facesContext,
449                                 UIComponent component) {
450         if (component instanceof EditableValueHolder) {
451             EditableValueHolder input = (EditableValueHolder) component;
452             String JavaDoc clientId = component.getClientId(facesContext);
453             ChildState state = (ChildState) savedChildren.get(clientId);
454             if (state == null) {
455                 state = new ChildState();
456             }
457             input.setValue(state.getValue());
458             input.setValid(state.isValid());
459             input.setSubmittedValue(state.getSubmittedValue());
460             input.setLocalValueSet(state.isLocalValueSet());
461         } else if (component instanceof HtmlForm) {
462             String JavaDoc clientId = component.getClientId(facesContext);
463             Boolean JavaDoc isThisFormSubmitted = (Boolean JavaDoc) savedChildren.get(clientId);
464             if (isThisFormSubmitted == null) {
465                 isThisFormSubmitted = Boolean.FALSE;
466             }
467             ((HtmlForm) component)
468                     .setSubmitted(isThisFormSubmitted.booleanValue());
469         }
470     }
471
472     protected void saveChildrenState(FacesContext facesContext) {
473         Iterator JavaDoc children = getFacetsAndChildren();
474         while (children.hasNext()) {
475             UIComponent child = (UIComponent) children.next();
476             saveChildState(facesContext, child);
477         }
478     }
479
480     protected void saveChildState(FacesContext facesContext,
481                                   UIComponent component) {
482         saveChild(facesContext, component);
483         Iterator JavaDoc children = component.getFacetsAndChildren();
484         while (children.hasNext()) {
485             saveChildState(facesContext, (UIComponent) children.next());
486         }
487     }
488
489     // Event associated with the specific rowindex
490
class RowEvent extends FacesEvent {
491         private FacesEvent event = null;
492         private int eventRowIndex = -1;
493
494         public RowEvent(UIComponent component, FacesEvent event,
495                         int eventRowIndex) {
496             super(component);
497             this.event = event;
498             this.eventRowIndex = eventRowIndex;
499         }
500
501         public FacesEvent getFacesEvent() {
502             return (this.event);
503         }
504
505         public boolean isAppropriateListener(FacesListener listener) {
506             return false;
507         }
508
509         public void processListener(FacesListener listener) {
510             throw new IllegalStateException JavaDoc();
511         }
512
513         public PhaseId getPhaseId() {
514             return (this.event.getPhaseId());
515         }
516
517         public void setPhaseId(PhaseId phaseId) {
518             this.event.setPhaseId(phaseId);
519         }
520
521         public void broadcast() {
522             int oldRowIndex = getRowIndex();
523             setRowIndex(eventRowIndex);
524             event.getComponent().broadcast(event);
525             setRowIndex(oldRowIndex);
526         }
527     }
528
529     public Object JavaDoc saveState(FacesContext context) {
530         Object JavaDoc values[] = new Object JavaDoc[4];
531         values[0] = super.saveState(context);
532         values[1] = new Integer JavaDoc(rowIndex);
533         values[2] = savedChildren;
534         values[3] = var;
535         return (values);
536     }
537
538
539     public void restoreState(FacesContext context, Object JavaDoc state) {
540         Object JavaDoc values[] = (Object JavaDoc[]) state;
541         super.restoreState(context, values[0]);
542         rowIndex = ((Integer JavaDoc) values[1]).intValue();
543         savedChildren = (Map JavaDoc) values[2];
544         var = (String JavaDoc) values[3];
545     }
546
547     private boolean isValid(String JavaDoc id) {
548         if (id == null) {
549             return false;
550         }
551         if (!Character.isLetter(id.charAt(0)) && (id.charAt(0) != '_')) {
552             return false;
553         }
554         return true;
555     }
556
557 }
558
559 class ChildState implements Serializable JavaDoc {
560
561     private Object JavaDoc submittedValue;
562     private boolean valid = true;
563     private Object JavaDoc value;
564     private boolean localValueSet;
565
566     Object JavaDoc getSubmittedValue() {
567         return submittedValue;
568     }
569
570     void setSubmittedValue(Object JavaDoc submittedValue) {
571         this.submittedValue = submittedValue;
572     }
573
574     boolean isValid() {
575         return valid;
576     }
577
578     void setValid(boolean valid) {
579         this.valid = valid;
580     }
581
582     Object JavaDoc getValue() {
583         return value;
584     }
585
586     public void setValue(Object JavaDoc value) {
587         this.value = value;
588     }
589
590     boolean isLocalValueSet() {
591         return localValueSet;
592     }
593
594     public void setLocalValueSet(boolean localValueSet) {
595         this.localValueSet = localValueSet;
596     }
597 }
598
599
600
Popular Tags