001: /*
002: * Version: MPL 1.1/GPL 2.0/LGPL 2.1
003: *
004: * "The contents of this file are subject to the Mozilla Public License
005: * Version 1.1 (the "License"); you may not use this file except in
006: * compliance with the License. You may obtain a copy of the License at
007: * http://www.mozilla.org/MPL/
008: *
009: * Software distributed under the License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
011: * License for the specific language governing rights and limitations under
012: * the License.
013: *
014: * The Original Code is ICEfaces 1.5 open source software code, released
015: * November 5, 2006. The Initial Developer of the Original Code is ICEsoft
016: * Technologies Canada, Corp. Portions created by ICEsoft are Copyright (C)
017: * 2004-2006 ICEsoft Technologies Canada, Corp. All Rights Reserved.
018: *
019: * Contributor(s): _____________________.
020: *
021: * Alternatively, the contents of this file may be used under the terms of
022: * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"
023: * License), in which case the provisions of the LGPL License are
024: * applicable instead of those above. If you wish to allow use of your
025: * version of this file only under the terms of the LGPL License and not to
026: * allow others to use your version of this file under the MPL, indicate
027: * your decision by deleting the provisions above and replace them with
028: * the notice and other provisions required by the LGPL License. If you do
029: * not delete the provisions above, a recipient may use your version of
030: * this file under either the MPL or the LGPL License."
031: *
032: */
033:
034: package com.icesoft.faces.component.ext;
035:
036: import com.icesoft.faces.component.CSS_DEFAULT;
037: import com.icesoft.faces.component.ext.taglib.Util;
038: import com.icesoft.faces.component.panelseries.UISeries;
039:
040: import javax.faces.component.UIColumn;
041: import javax.faces.component.UIComponent;
042: import javax.faces.component.UIData;
043: import javax.faces.context.FacesContext;
044: import javax.faces.el.ValueBinding;
045: import javax.faces.event.PhaseId;
046: import java.util.Iterator;
047:
048: /**
049: * This is an extension of javax.faces.component.html.HtmlDataTable, which
050: * provides some additional behavior to this component such as: <ul> <li>changes
051: * the component's rendered state based on the authentication</li> <li>maintain
052: * the sorting order, for a column within the dataTable</li> <ul>
053: */
054: public class HtmlDataTable extends UISeries {
055:
056: public static final String COMPONENT_TYPE = "com.icesoft.faces.HtmlDataTable";
057: public static final String RENDERER_TYPE = "com.icesoft.faces.Table";
058: private String renderedOnUserRole = null;
059: private String sortColumn = null;
060: private Boolean sortAscending = null;
061: private static final boolean DEFAULT_SORTASCENDING = true;
062:
063: private Boolean scrollable = null;
064: private String columnWidths = null;
065: private String scrollHeight = null;
066: private String headerClasses = null;
067:
068: public HtmlDataTable() {
069: super ();
070: setRendererType(RENDERER_TYPE);
071: }
072:
073: /**
074: * <p>Set the value of the <code>renderedOnUserRole</code> property.</p>
075: */
076: public void setRenderedOnUserRole(String renderedOnUserRole) {
077: this .renderedOnUserRole = renderedOnUserRole;
078: }
079:
080: /**
081: * <p>Return the value of the <code>renderedOnUserRole</code> property.</p>
082: */
083: public String getRenderedOnUserRole() {
084: if (renderedOnUserRole != null) {
085: return renderedOnUserRole;
086: }
087: ValueBinding vb = getValueBinding("renderedOnUserRole");
088: return vb != null ? (String) vb.getValue(getFacesContext())
089: : null;
090: }
091:
092: /**
093: * <p>Return the value of the <code>rendered</code> property.</p>
094: */
095: public boolean isRendered() {
096: if (!Util.isRenderedOnUserRole(this )) {
097: return false;
098: }
099: return super .isRendered();
100: }
101:
102: /**
103: * <p>Return the value of the <code>sortColumn</code> property.</p>
104: */
105: public String getSortColumn() {
106: if (sortColumn != null) {
107: return sortColumn;
108: }
109: ValueBinding vb = getValueBinding("sortColumn");
110: return vb != null ? (String) vb.getValue(getFacesContext())
111: : null;
112: }
113:
114: /**
115: * <p>Set the value of the <code>sortAscending</code> property.</p>
116: */
117: public void setSortAscending(boolean sortAscending) {
118: this .sortAscending = new Boolean(sortAscending);
119: ValueBinding vb = getValueBinding("sortAscending");
120: if (vb != null) {
121: vb.setValue(getFacesContext(), this .sortAscending);
122: this .sortAscending = null;
123: }
124: }
125:
126: /**
127: * <p>Set the value of the <code>sortColumn</code> property.</p>
128: */
129: public void setSortColumn(String sortColumn) {
130: this .sortColumn = sortColumn;
131: ValueBinding vb = getValueBinding("sortColumn");
132: if (vb != null) {
133: vb.setValue(getFacesContext(), this .sortColumn);
134: sortColumn = null;
135: }
136: }
137:
138: /**
139: * <p>Return the value of the <code>sortAscending</code> property.</p>
140: */
141: public boolean isSortAscending() {
142: if (sortAscending != null) {
143: return sortAscending.booleanValue();
144: }
145: ValueBinding vb = getValueBinding("sortAscending");
146: Boolean v = vb != null ? (Boolean) vb
147: .getValue(getFacesContext()) : null;
148: return v != null ? v.booleanValue() : DEFAULT_SORTASCENDING;
149: }
150:
151: /**
152: * <p>Gets the state of the instance as a <code>Serializable</code>
153: * Object.</p>
154: */
155: public Object saveState(FacesContext context) {
156: Object values[] = new Object[4];
157: values[0] = super .saveState(context);
158: values[1] = renderedOnUserRole;
159: return ((Object) (values));
160: }
161:
162: /**
163: * <p>Perform any processing required to restore the state from the entries
164: * in the state Object.</p>
165: */
166: public void restoreState(FacesContext context, Object state) {
167: Object values[] = (Object[]) state;
168: super .restoreState(context, values[0]);
169: renderedOnUserRole = (String) values[1];
170: }
171:
172: public String getComponentType() {
173: return COMPONENT_TYPE;
174: }
175:
176: protected void iterate(FacesContext facesContext, PhaseId phase) {
177: // clear row index
178: setRowIndex(-1);
179: // process component facets once
180: Iterator facets = getFacets().keySet().iterator();
181: while (facets.hasNext()) {
182: UIComponent facet = (UIComponent) getFacets().get(
183: facets.next());
184: processKids(facesContext, phase, facet);
185: }
186: // reset row index
187: setRowIndex(-1);
188: // process each child column and it's facets once
189: Iterator columns = getChildren().iterator();
190: while (columns.hasNext()) {
191: UIComponent column = (UIComponent) columns.next();
192: if (!(column instanceof UIColumn)
193: && !(column instanceof UIColumns)) {
194: continue;
195: }
196: if (!column.isRendered()) {
197: continue;
198: }
199: if (column instanceof UIColumn) {
200: Iterator columnFacets = column.getFacets().keySet()
201: .iterator();
202: while (columnFacets.hasNext()) {
203: UIComponent columnFacet = (UIComponent) column
204: .getFacets().get(columnFacets.next());
205: processKids(facesContext, phase, columnFacet);
206: }
207:
208: } else if (column instanceof UIColumns) {
209: processKids(facesContext, phase, column);
210: }
211: }
212:
213: // clear rowIndex
214: setRowIndex(-1);
215:
216: int rowsProcessed = 0;
217: int currentRowIndex = getFirst() - 1;
218: int displayedRows = getRows();
219: // loop over dataModel processing each row once
220: while (1 == 1) {
221: // break if we have processed the number of rows requested
222: if ((++currentRowIndex >= getRowCount())
223: || ((displayedRows > 0) && (++rowsProcessed > displayedRows))) {
224: break;
225: }
226: // process the row at currentRowIndex
227: setRowIndex(currentRowIndex);
228: // break if we've moved past the last row
229: if (!isRowAvailable()) {
230: break;
231: }
232: // loop over children
233: Iterator children = getChildren().iterator();
234: while (children.hasNext()) {
235: UIComponent child = (UIComponent) children.next();
236: if (!(child instanceof UIColumn)
237: && !(child instanceof UIColumns)) {
238: continue;
239: }
240: if (child instanceof UIColumn) {
241: Iterator granchildren = child.getChildren()
242: .iterator();
243: while (granchildren.hasNext()) {
244: UIComponent granchild = (UIComponent) granchildren
245: .next();
246: if (!granchild.isRendered()) {
247: continue;
248: }
249: processKids(facesContext, phase, granchild);
250: }
251: } else if (child instanceof UIColumns) {
252: processKids(facesContext, phase, child);
253: }
254: }
255: }
256:
257: // clear rowIndex
258: setRowIndex(-1);
259: }
260:
261: protected void restoreChildrenState(FacesContext facesContext) {
262: Iterator kids = getChildren().iterator();
263: while (kids.hasNext()) {
264: UIComponent kid = (UIComponent) kids.next();
265: if (kid instanceof UIColumn) {
266: restoreChildState(facesContext, kid);
267: }
268: }
269:
270: }
271:
272: /**
273: * <p>Save state information for all descendant components, as described for
274: * <code>setRowIndex()</code>.</p>
275: */
276: protected void saveChildrenState(FacesContext facesContext) {
277: Iterator kids = getChildren().iterator();
278: while (kids.hasNext()) {
279: UIComponent kid = (UIComponent) kids.next();
280: if (kid instanceof UIColumn) {
281: saveChildState(facesContext, kid);
282: }
283: }
284: }
285:
286: public void processKids(FacesContext context, PhaseId phaseId,
287: UIComponent kid) {
288: if (phaseId == PhaseId.APPLY_REQUEST_VALUES) {
289: kid.processDecodes(context);
290: } else if (phaseId == PhaseId.PROCESS_VALIDATIONS) {
291: kid.processValidators(context);
292: } else if (phaseId == PhaseId.UPDATE_MODEL_VALUES) {
293: kid.processUpdates(context);
294: } else {
295: throw new IllegalArgumentException();
296: }
297: }
298:
299: private int colNumber = 0;
300:
301: public int getColNumber() {
302: return colNumber;
303: }
304:
305: public void setColNumber(int colNumber) {
306: this .colNumber = colNumber;
307: }
308:
309: public Boolean getScrollable() {
310: return isScrollable();
311: }
312:
313: public Boolean isScrollable() {
314: if (scrollable != null) {
315: return scrollable;
316: }
317: ValueBinding vb = getValueBinding("scrollable");
318: Boolean v = vb != null ? (Boolean) vb
319: .getValue(getFacesContext()) : null;
320: return v != null ? v : Boolean.FALSE;
321: }
322:
323: public void setScrollable(Boolean scrollable) {
324: this .scrollable = scrollable;
325:
326: }
327:
328: public String getColumnWidths() {
329: if (columnWidths != null) {
330: return columnWidths;
331: }
332: ValueBinding vb = getValueBinding("columnWidths");
333: return vb != null ? (String) vb.getValue(getFacesContext())
334: : null;
335: }
336:
337: public void setColumnWidths(String columnWidths) {
338: this .columnWidths = columnWidths;
339:
340: }
341:
342: public String getScrollHeight() {
343: if (scrollHeight != null) {
344: return scrollHeight;
345: }
346: ValueBinding vb = getValueBinding("scrollHeight");
347: return vb != null ? (String) vb.getValue(getFacesContext())
348: : null;
349: }
350:
351: public void setScrollHeight(String scrollHeight) {
352: this .scrollHeight = scrollHeight;
353:
354: }
355:
356: /**
357: * <p>Set the value of the <code>headerClasses</code> property.</p>
358: */
359: public void setHeaderClasses(String headerClasses) {
360: this .headerClasses = headerClasses;
361: }
362:
363: /**
364: * <p>Return the value of the <code>headerClasses</code> property.</p>
365: */
366: public String getHeaderClasses() {
367: if (headerClasses != null) {
368: return headerClasses;
369: }
370: ValueBinding vb = getValueBinding("headerClasses");
371: return vb != null ? (String) vb.getValue(getFacesContext())
372: : null;
373: }
374:
375: String[] headerClassesArray = null;
376:
377: public String getHeaderClassAtIndex(int index) {
378: if (headerClassesArray == null) {
379: headerClassesArray = getHeaderClasses().split(",");
380: }
381: if (headerClassesArray.length == 1) {
382: return headerClassesArray[0];
383: }
384: try {
385: return headerClassesArray[index];
386: } catch (ArrayIndexOutOfBoundsException e) {
387: return headerClassesArray[0];
388: }
389: }
390:
391: protected void restoreChild(FacesContext facesContext,
392: UIComponent uiComponent) {
393: super .restoreChild(facesContext, uiComponent);
394: if (uiComponent instanceof UIData) {
395: String clientId = uiComponent.getClientId(facesContext);
396: Object value = savedChildren.get(clientId);
397: ((UIData) uiComponent).setValue(value);
398: }
399: }
400:
401: protected void saveChild(FacesContext facesContext,
402: UIComponent uiComponent) {
403: super .saveChild(facesContext, uiComponent);
404: if (uiComponent instanceof UIData) {
405: String clientId = uiComponent.getClientId(facesContext);
406: savedChildren.put(clientId, ((UIData) uiComponent)
407: .getValue());
408: }
409: }
410:
411: public String getStyleClass() {
412: return Util.getQualifiedStyleClass(this , super .getStyleClass(),
413: CSS_DEFAULT.TABLE_STYLE_CLASS, "styleClass");
414: }
415:
416: public String getHeaderClass() {
417: return Util.getQualifiedStyleClass(this ,
418: super .getHeaderClass(), CSS_DEFAULT.TABLE_HEADER_CLASS,
419: "headerClass");
420: }
421:
422: public String getFooterClass() {
423: return Util.getQualifiedStyleClass(this ,
424: super .getFooterClass(), CSS_DEFAULT.TABLE_FOOTER_CLASS,
425: "footerClass");
426: }
427:
428: }
|