001: // WARNING: This file was automatically generated. Do not edit it directly,
002: // or you will lose your changes.
003:
004: /*
005: * Licensed to the Apache Software Foundation (ASF) under one
006: * or more contributor license agreements. See the NOTICE file
007: * distributed with this work for additional information
008: * regarding copyright ownership. The ASF licenses this file
009: * to you under the Apache License, Version 2.0 (the
010: * "License"); you may not use this file except in compliance
011: * with the License. You may obtain a copy of the License at
012: *
013: * http://www.apache.org/licenses/LICENSE-2.0
014: *
015: * Unless required by applicable law or agreed to in writing,
016: * software distributed under the License is distributed on an
017: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
018: * KIND, either express or implied. See the License for the
019: * specific language governing permissions and limitations
020: * under the License.
021: */
022: package javax.faces.component;
023:
024: import java.io.IOException;
025: import java.sql.ResultSet;
026: import java.util.*;
027: import javax.el.ValueExpression;
028: import javax.faces.FacesException;
029: import javax.faces.application.FacesMessage;
030: import javax.faces.context.FacesContext;
031: import javax.faces.event.AbortProcessingException;
032: import javax.faces.event.FacesEvent;
033: import javax.faces.event.FacesListener;
034: import javax.faces.event.PhaseId;
035: import javax.faces.model.*;
036: import javax.servlet.jsp.jstl.sql.Result;
037:
038: /**
039: */
040: public class UIData extends UIComponentBase implements NamingContainer {
041:
042: static public final String COMPONENT_FAMILY = "javax.faces.Data";
043: static public final String COMPONENT_TYPE = "javax.faces.Data";
044:
045: /**
046: * Construct an instance of the UIData.
047: */
048: public UIData() {
049: setRendererType("javax.faces.Table");
050: }
051:
052: private static final String FOOTER_FACET_NAME = "footer";
053: private static final String HEADER_FACET_NAME = "header";
054: private static final Class OBJECT_ARRAY_CLASS = (new Object[0])
055: .getClass();
056: private static final int PROCESS_DECODES = 1;
057: private static final int PROCESS_VALIDATORS = 2;
058: private static final int PROCESS_UPDATES = 3;
059:
060: private int _rowIndex = -1;
061:
062: // Holds for each row the states of the child components of this UIData.
063: // Note that only "partial" component state is saved: the component fields
064: // that are expected to vary between rows.
065: private Map _rowStates = new HashMap();
066:
067: /**
068: * Handle case where this table is nested inside another table.
069: * See method getDataModel for more details.
070: * <p>
071: * Key: parentClientId (aka rowId when nested within a parent table)
072: * Value: DataModel
073: */
074: private Map _dataModelMap = new HashMap();
075:
076: // will be set to false if the data should not be refreshed at the beginning of the encode phase
077: private boolean _isValidChilds = true;
078:
079: private Object _initialDescendantComponentState = null;
080:
081: @Override
082: public boolean invokeOnComponent(FacesContext context,
083: String clientId, ContextCallback callback)
084: throws FacesException {
085: // not supported yet
086: return false;
087: }
088:
089: public void setFooter(UIComponent footer) {
090: getFacets().put(FOOTER_FACET_NAME, footer);
091: }
092:
093: public UIComponent getFooter() {
094: return (UIComponent) getFacets().get(FOOTER_FACET_NAME);
095: }
096:
097: public void setHeader(UIComponent header) {
098: getFacets().put(HEADER_FACET_NAME, header);
099: }
100:
101: public UIComponent getHeader() {
102: return (UIComponent) getFacets().get(HEADER_FACET_NAME);
103: }
104:
105: public boolean isRowAvailable() {
106: return getDataModel().isRowAvailable();
107: }
108:
109: public int getRowCount() {
110: return getDataModel().getRowCount();
111: }
112:
113: public Object getRowData() {
114: return getDataModel().getRowData();
115: }
116:
117: public int getRowIndex() {
118: return _rowIndex;
119: }
120:
121: /**
122: * Set the current row index that methods like getRowData use.
123: * <p>
124: * Param rowIndex can be -1, meaning "no row".
125: * <p>
126: * @param rowIndex
127: */
128: public void setRowIndex(int rowIndex) {
129: if (rowIndex < -1) {
130: throw new IllegalArgumentException(
131: "rowIndex is less than -1");
132: }
133:
134: if (_rowIndex == rowIndex) {
135: return;
136: }
137:
138: FacesContext facesContext = getFacesContext();
139:
140: if (_rowIndex == -1) {
141: if (_initialDescendantComponentState == null) {
142: // Create a template that can be used to initialise any row
143: // that we haven't visited before, ie a "saved state" that can
144: // be pushed to the "restoreState" method of all the child
145: // components to set them up to represent a clean row.
146: _initialDescendantComponentState = saveDescendantComponentStates(
147: getChildren().iterator(), false);
148: }
149: } else {
150: // We are currently positioned on some row, and are about to
151: // move off it, so save the (partial) state of the components
152: // representing the current row. Later if this row is revisited
153: // then we can restore this state.
154: _rowStates.put(getClientId(facesContext),
155: saveDescendantComponentStates(getChildren()
156: .iterator(), false));
157: }
158:
159: _rowIndex = rowIndex;
160:
161: DataModel dataModel = getDataModel();
162: dataModel.setRowIndex(rowIndex);
163:
164: String var = _var;
165: if (rowIndex == -1) {
166: if (var != null) {
167: facesContext.getExternalContext().getRequestMap()
168: .remove(var);
169: }
170: } else {
171: if (var != null) {
172: if (isRowAvailable()) {
173: Object rowData = dataModel.getRowData();
174: facesContext.getExternalContext().getRequestMap()
175: .put(var, rowData);
176: } else {
177: facesContext.getExternalContext().getRequestMap()
178: .remove(var);
179: }
180: }
181: }
182:
183: if (_rowIndex == -1) {
184: // reset components to initial state
185: restoreDescendantComponentStates(getChildren().iterator(),
186: _initialDescendantComponentState, false);
187: } else {
188: Object rowState = _rowStates.get(getClientId(facesContext));
189: if (rowState == null) {
190: // We haven't been positioned on this row before, so just
191: // configure the child components of this component with
192: // the standard "initial" state
193: restoreDescendantComponentStates(getChildren()
194: .iterator(), _initialDescendantComponentState,
195: false);
196: } else {
197: // We have been positioned on this row before, so configure
198: // the child components of this component with the (partial)
199: // state that was previously saved. Fields not in the
200: // partial saved state are left with their original values.
201: restoreDescendantComponentStates(getChildren()
202: .iterator(), rowState, false);
203: }
204: }
205: }
206:
207: /**
208: * Overwrite the state of the child components of this component
209: * with data previously saved by method saveDescendantComponentStates.
210: * <p>
211: * The saved state info only covers those fields that are expected to
212: * vary between rows of a table. Other fields are not modified.
213: */
214: private void restoreDescendantComponentStates(
215: Iterator childIterator, Object state,
216: boolean restoreChildFacets) {
217: Iterator descendantStateIterator = null;
218: while (childIterator.hasNext()) {
219: if (descendantStateIterator == null && state != null) {
220: descendantStateIterator = ((Collection) state)
221: .iterator();
222: }
223: UIComponent component = (UIComponent) childIterator.next();
224:
225: // reset the client id (see spec 3.1.6)
226: component.setId(component.getId());
227: if (!component.isTransient()) {
228: Object childState = null;
229: Object descendantState = null;
230: if (descendantStateIterator != null
231: && descendantStateIterator.hasNext()) {
232: Object[] object = (Object[]) descendantStateIterator
233: .next();
234: childState = object[0];
235: descendantState = object[1];
236: }
237: if (component instanceof EditableValueHolder) {
238: ((EditableValueHolderState) childState)
239: .restoreState((EditableValueHolder) component);
240: }
241: Iterator childsIterator;
242: if (restoreChildFacets) {
243: childsIterator = component.getFacetsAndChildren();
244: } else {
245: childsIterator = component.getChildren().iterator();
246: }
247: restoreDescendantComponentStates(childsIterator,
248: descendantState, true);
249: }
250: }
251: }
252:
253: /**
254: * Walk the tree of child components of this UIData, saving the parts of
255: * their state that can vary between rows.
256: * <p>
257: * This is very similar to the process that occurs for normal components
258: * when the view is serialized. Transient components are skipped (no
259: * state is saved for them).
260: * <p>
261: * If there are no children then null is returned. If there are one or
262: * more children, and all children are transient then an empty collection
263: * is returned; this will happen whenever a table contains only read-only
264: * components.
265: * <p>
266: * Otherwise a collection is returned which contains an object for every
267: * non-transient child component; that object may itself contain a collection
268: * of the state of that child's child components.
269: */
270: private Object saveDescendantComponentStates(
271: Iterator childIterator, boolean saveChildFacets) {
272: Collection childStates = null;
273: while (childIterator.hasNext()) {
274: if (childStates == null) {
275: childStates = new ArrayList();
276: }
277: UIComponent child = (UIComponent) childIterator.next();
278: if (!child.isTransient()) {
279: // Add an entry to the collection, being an array of two
280: // elements. The first element is the state of the children
281: // of this component; the second is the state of the current
282: // child itself.
283:
284: Iterator childsIterator;
285: if (saveChildFacets) {
286: childsIterator = child.getFacetsAndChildren();
287: } else {
288: childsIterator = child.getChildren().iterator();
289: }
290: Object descendantState = saveDescendantComponentStates(
291: childsIterator, true);
292: Object state = null;
293: if (child instanceof EditableValueHolder) {
294: state = new EditableValueHolderState(
295: (EditableValueHolder) child);
296: }
297: childStates
298: .add(new Object[] { state, descendantState });
299: }
300: }
301: return childStates;
302: }
303:
304: @Override
305: public void setValueExpression(String name, ValueExpression binding) {
306: if (name == null) {
307: throw new NullPointerException("name");
308: } else if (name.equals("value")) {
309: _dataModelMap.clear();
310: } else if (name.equals("rowIndex")) {
311: throw new IllegalArgumentException("name " + name);
312: }
313: super .setValueExpression(name, binding);
314: }
315:
316: @Override
317: public String getClientId(FacesContext context) {
318: String clientId = super .getClientId(context);
319: int rowIndex = getRowIndex();
320: if (rowIndex == -1) {
321: return clientId;
322: }
323: return clientId + NamingContainer.SEPARATOR_CHAR + rowIndex;
324: }
325:
326: /**
327: * Modify events queued for any child components so that the
328: * UIData state will be correctly configured before the event's
329: * listeners are executed.
330: * <p>
331: * Child components or their renderers may register events against
332: * those child components. When the listener for that event is
333: * eventually invoked, it may expect the uidata's rowData and
334: * rowIndex to be referring to the same object that caused the
335: * event to fire.
336: * <p>
337: * The original queueEvent call against the child component has been
338: * forwarded up the chain of ancestors in the standard way, making
339: * it possible here to wrap the event in a new event whose source
340: * is <i>this</i> component, not the original one. When the event
341: * finally is executed, this component's broadcast method is invoked,
342: * which ensures that the UIData is set to be at the correct row
343: * before executing the original event.
344: */
345: @Override
346: public void queueEvent(FacesEvent event) {
347: super .queueEvent(new FacesEventWrapper(event, getRowIndex(),
348: this ));
349: }
350:
351: /**
352: * Ensure that before the event's listeners are invoked this UIData
353: * component's "current row" is set to the row associated with the event.
354: * <p>
355: * See queueEvent for more details.
356: */
357: @Override
358: public void broadcast(FacesEvent event)
359: throws AbortProcessingException {
360: if (event instanceof FacesEventWrapper) {
361: FacesEvent originalEvent = ((FacesEventWrapper) event)
362: .getWrappedFacesEvent();
363: int eventRowIndex = ((FacesEventWrapper) event)
364: .getRowIndex();
365: int currentRowIndex = getRowIndex();
366: setRowIndex(eventRowIndex);
367: try {
368: originalEvent.getComponent().broadcast(originalEvent);
369: } finally {
370: setRowIndex(currentRowIndex);
371: }
372: } else {
373: super .broadcast(event);
374: }
375: }
376:
377: /**
378: * Perform necessary actions when rendering of this component starts,
379: * before delegating to the inherited implementation which calls the
380: * associated renderer's encodeBegin method.
381: */
382: @Override
383: public void encodeBegin(FacesContext context) throws IOException {
384: _initialDescendantComponentState = null;
385: if (_isValidChilds && !hasErrorMessages(context)) {
386: // Clear the data model so that when rendering code calls
387: // getDataModel a fresh model is fetched from the backing
388: // bean via the value-binding.
389: _dataModelMap.clear();
390:
391: // When the data model is cleared it is also necessary to
392: // clear the saved row state, as there is an implicit 1:1
393: // relation between objects in the _rowStates and the
394: // corresponding DataModel element.
395: _rowStates.clear();
396: }
397: super .encodeBegin(context);
398: }
399:
400: private boolean hasErrorMessages(FacesContext context) {
401: for (Iterator iter = context.getMessages(); iter.hasNext();) {
402: FacesMessage message = (FacesMessage) iter.next();
403: if (FacesMessage.SEVERITY_ERROR.compareTo(message
404: .getSeverity()) <= 0) {
405: return true;
406: }
407: }
408: return false;
409: }
410:
411: /**
412: * @see javax.faces.component.UIComponentBase#encodeEnd(javax.faces.context.FacesContext)
413: */
414: @Override
415: public void encodeEnd(FacesContext context) throws IOException {
416: setRowIndex(-1);
417: super .encodeEnd(context);
418: }
419:
420: @Override
421: public void processDecodes(FacesContext context) {
422: if (context == null)
423: throw new NullPointerException("context");
424: if (!isRendered())
425: return;
426: setRowIndex(-1);
427: processFacets(context, PROCESS_DECODES);
428: processColumnFacets(context, PROCESS_DECODES);
429: processColumnChildren(context, PROCESS_DECODES);
430: setRowIndex(-1);
431: try {
432: decode(context);
433: } catch (RuntimeException e) {
434: context.renderResponse();
435: throw e;
436: }
437: }
438:
439: @Override
440: public void processValidators(FacesContext context) {
441: if (context == null)
442: throw new NullPointerException("context");
443: if (!isRendered())
444: return;
445: setRowIndex(-1);
446: processFacets(context, PROCESS_VALIDATORS);
447: processColumnFacets(context, PROCESS_VALIDATORS);
448: processColumnChildren(context, PROCESS_VALIDATORS);
449: setRowIndex(-1);
450:
451: // check if an validation error forces the render response for our data
452: if (context.getRenderResponse()) {
453: _isValidChilds = false;
454: }
455: }
456:
457: @Override
458: public void processUpdates(FacesContext context) {
459: if (context == null)
460: throw new NullPointerException("context");
461: if (!isRendered())
462: return;
463: setRowIndex(-1);
464: processFacets(context, PROCESS_UPDATES);
465: processColumnFacets(context, PROCESS_UPDATES);
466: processColumnChildren(context, PROCESS_UPDATES);
467: setRowIndex(-1);
468:
469: if (context.getRenderResponse()) {
470: _isValidChilds = false;
471: }
472: }
473:
474: private void processFacets(FacesContext context, int processAction) {
475: for (Iterator it = getFacets().values().iterator(); it
476: .hasNext();) {
477: UIComponent facet = (UIComponent) it.next();
478: process(context, facet, processAction);
479: }
480: }
481:
482: /**
483: * Invoke the specified phase on all facets of all UIColumn children
484: * of this component. Note that no methods are called on the UIColumn
485: * child objects themselves.
486: *
487: * @param context is the current faces context.
488: * @param processAction specifies a JSF phase: decode, validate or update.
489: */
490: private void processColumnFacets(FacesContext context,
491: int processAction) {
492: for (Iterator childIter = getChildren().iterator(); childIter
493: .hasNext();) {
494: UIComponent child = (UIComponent) childIter.next();
495: if (child instanceof UIColumn) {
496: if (!child.isRendered()) {
497: //Column is not visible
498: continue;
499: }
500: for (Iterator facetsIter = child.getFacets().values()
501: .iterator(); facetsIter.hasNext();) {
502: UIComponent facet = (UIComponent) facetsIter.next();
503: process(context, facet, processAction);
504: }
505: }
506: }
507: }
508:
509: /**
510: * Invoke the specified phase on all non-facet children of all UIColumn
511: * children of this component. Note that no methods are called on the
512: * UIColumn child objects themselves.
513: *
514: * @param context is the current faces context.
515: * @param processAction specifies a JSF phase: decode, validate or update.
516: */
517: private void processColumnChildren(FacesContext context,
518: int processAction) {
519: int first = _first;
520: int rows = _rows;
521: int last;
522: if (rows == 0) {
523: last = getRowCount();
524: } else {
525: last = first + rows;
526: }
527: for (int rowIndex = first; last == -1 || rowIndex < last; rowIndex++) {
528: setRowIndex(rowIndex);
529:
530: //scrolled past the last row
531: if (!isRowAvailable())
532: break;
533:
534: for (Iterator it = getChildren().iterator(); it.hasNext();) {
535: UIComponent child = (UIComponent) it.next();
536: if (child instanceof UIColumn) {
537: if (!child.isRendered()) {
538: //Column is not visible
539: continue;
540: }
541: for (Iterator columnChildIter = child.getChildren()
542: .iterator(); columnChildIter.hasNext();) {
543: UIComponent columnChild = (UIComponent) columnChildIter
544: .next();
545: process(context, columnChild, processAction);
546: }
547: }
548: }
549: }
550: }
551:
552: private void process(FacesContext context, UIComponent component,
553: int processAction) {
554: switch (processAction) {
555: case PROCESS_DECODES:
556: component.processDecodes(context);
557: break;
558: case PROCESS_VALIDATORS:
559: component.processValidators(context);
560: break;
561: case PROCESS_UPDATES:
562: component.processUpdates(context);
563: break;
564: }
565: }
566:
567: /**
568: * Return the datamodel for this table, potentially fetching the data from
569: * a backing bean via a value-binding if this is the first time this method
570: * has been called.
571: * <p>
572: * This is complicated by the fact that this table may be nested within
573: * another table. In this case a different datamodel should be fetched
574: * for each row. When nested within a parent table, the parent reference
575: * won't change but parent.getClientId() will, as the suffix changes
576: * depending upon the current row index. A map object on this component
577: * is therefore used to cache the datamodel for each row of the table.
578: * In the normal case where this table is not nested inside a component
579: * that changes its id (like a table does) then this map only ever has
580: * one entry.
581: */
582: protected DataModel getDataModel() {
583: DataModel dataModel;
584: String clientID = "";
585:
586: UIComponent parent = getParent();
587: if (parent != null) {
588: clientID = parent.getClientId(getFacesContext());
589: }
590: dataModel = (DataModel) _dataModelMap.get(clientID);
591: if (dataModel == null) {
592: dataModel = createDataModel();
593: _dataModelMap.put(clientID, dataModel);
594: }
595: return dataModel;
596: }
597:
598: protected void setDataModel(DataModel dataModel) {
599: throw new UnsupportedOperationException(
600: "this method is here only to maintain binary compatibility w/ the RI");
601: }
602:
603: /**
604: * Evaluate this object's value property and convert the result into a
605: * DataModel. Normally this object's value property will be a value-binding
606: * which will cause the value to be fetched from some backing bean.
607: * <p>
608: * The result of fetching the value may be a DataModel object, in which
609: * case that object is returned directly. If the value is of type
610: * List, Array, ResultSet, Result, other object or null then an appropriate
611: * wrapper is created and returned.
612: * <p>
613: * Null is never returned by this method.
614: */
615: private DataModel createDataModel() {
616: Object value = getValue();
617:
618: if (value == null) {
619: return EMPTY_DATA_MODEL;
620: } else if (value instanceof DataModel) {
621: return (DataModel) value;
622: } else if (value instanceof List) {
623: return new ListDataModel((List) value);
624: } else if (OBJECT_ARRAY_CLASS
625: .isAssignableFrom(value.getClass())) {
626: return new ArrayDataModel((Object[]) value);
627: } else if (value instanceof ResultSet) {
628: return new ResultSetDataModel((ResultSet) value);
629: } else if (value instanceof Result) {
630: return new ResultDataModel((Result) value);
631: } else {
632: return new ScalarDataModel(value);
633: }
634: }
635:
636: private static class FacesEventWrapper extends FacesEvent {
637: private static final long serialVersionUID = 6648047974065628773L;
638: private FacesEvent _wrappedFacesEvent;
639: private int _rowIndex;
640:
641: public FacesEventWrapper(FacesEvent facesEvent, int rowIndex,
642: UIData redirectComponent) {
643: super (redirectComponent);
644: _wrappedFacesEvent = facesEvent;
645: _rowIndex = rowIndex;
646: }
647:
648: @Override
649: public PhaseId getPhaseId() {
650: return _wrappedFacesEvent.getPhaseId();
651: }
652:
653: @Override
654: public void setPhaseId(PhaseId phaseId) {
655: _wrappedFacesEvent.setPhaseId(phaseId);
656: }
657:
658: @Override
659: public void queue() {
660: _wrappedFacesEvent.queue();
661: }
662:
663: @Override
664: public String toString() {
665: return _wrappedFacesEvent.toString();
666: }
667:
668: @Override
669: public boolean isAppropriateListener(FacesListener faceslistener) {
670: return _wrappedFacesEvent
671: .isAppropriateListener(faceslistener);
672: }
673:
674: @Override
675: public void processListener(FacesListener faceslistener) {
676: _wrappedFacesEvent.processListener(faceslistener);
677: }
678:
679: public FacesEvent getWrappedFacesEvent() {
680: return _wrappedFacesEvent;
681: }
682:
683: public int getRowIndex() {
684: return _rowIndex;
685: }
686: }
687:
688: public void setValue(Object value) {
689: _value = value;
690: _dataModelMap.clear();
691: _rowStates.clear();
692: _isValidChilds = true;
693: }
694:
695: /**
696: * Set the maximum number of rows displayed in the table.
697: */
698: public void setRows(int rows) {
699: if (rows < 0) {
700: throw new IllegalArgumentException("rows: " + rows);
701: }
702: _rows = rows;
703: _rowsSet = true;
704: }
705:
706: /**
707: * Set the index of the first row to be displayed, where 0 is the first row.
708: */
709: public void setFirst(int first) {
710: if (first < 0) {
711: throw new IllegalArgumentException(
712: "Illegal value for first row: " + first);
713: }
714: _first = first;
715: _firstSet = true;
716: }
717:
718: private static final DataModel EMPTY_DATA_MODEL = new DataModel() {
719: @Override
720: public boolean isRowAvailable() {
721: return false;
722: }
723:
724: @Override
725: public int getRowCount() {
726: return 0;
727: }
728:
729: @Override
730: public Object getRowData() {
731: throw new IllegalArgumentException();
732: }
733:
734: @Override
735: public int getRowIndex() {
736: return -1;
737: }
738:
739: @Override
740: public void setRowIndex(int i) {
741: if (i < -1)
742: throw new IllegalArgumentException();
743: }
744:
745: @Override
746: public Object getWrappedData() {
747: return null;
748: }
749:
750: @Override
751: public void setWrappedData(Object obj) {
752: if (obj == null)
753: return; //Clearing is allowed
754: throw new UnsupportedOperationException(this .getClass()
755: .getName()
756: + " UnsupportedOperationException");
757: }
758: };
759:
760: private class EditableValueHolderState {
761: private final Object _value;
762: private final boolean _localValueSet;
763: private final boolean _valid;
764: private final Object _submittedValue;
765:
766: public EditableValueHolderState(EditableValueHolder evh) {
767: _value = evh.getLocalValue();
768: _localValueSet = evh.isLocalValueSet();
769: _valid = evh.isValid();
770: _submittedValue = evh.getSubmittedValue();
771: }
772:
773: public void restoreState(EditableValueHolder evh) {
774: evh.setValue(_value);
775: evh.setLocalValueSet(_localValueSet);
776: evh.setValid(_valid);
777: evh.setSubmittedValue(_submittedValue);
778: }
779: }
780:
781: // Property: value
782: private Object _value;
783:
784: /**
785: * Gets An EL expression that specifies the data model that backs this table. The value can be of any type.
786: *
787: * A value of type DataModel is used directly. Array-like parameters of type java.util.List, array of Object,
788: * java.sql.ResultSet, or javax.servlet.jsp.jstl.sql.Result are wrapped in a DataModel.
789: *
790: * Other values are wrapped in a DataModel as a single row.
791: *
792: * @return the new value value
793: */
794: public Object getValue() {
795: if (_value != null) {
796: return _value;
797: }
798: ValueExpression expression = getValueExpression("value");
799: if (expression != null) {
800: return expression
801: .getValue(getFacesContext().getELContext());
802: }
803: return null;
804: }
805:
806: // Property: var
807: private String _var;
808:
809: /**
810: * Gets Defines the name of the request-scope variable that will hold the current row during iteration. This value must be a static value.
811: *
812: * @return the new var value
813: */
814: public String getVar() {
815: if (_var != null) {
816: return _var;
817: }
818: ValueExpression expression = getValueExpression("var");
819: if (expression != null) {
820: return (String) expression.getValue(getFacesContext()
821: .getELContext());
822: }
823: return null;
824: }
825:
826: /**
827: * Sets Defines the name of the request-scope variable that will hold the current row during iteration. This value must be a static value.
828: *
829: * @param var the new var value
830: */
831: public void setVar(String var) {
832: this ._var = var;
833: }
834:
835: // Property: rows
836: private int _rows;
837: private boolean _rowsSet;
838:
839: /**
840: * Gets The number of rows to be displayed. Specify zero for all remaining rows in the table.
841: *
842: * @return the new rows value
843: */
844: public int getRows() {
845: if (_rowsSet) {
846: return _rows;
847: }
848: ValueExpression expression = getValueExpression("rows");
849: if (expression != null) {
850: return (Integer) expression.getValue(getFacesContext()
851: .getELContext());
852: }
853: return 0;
854: }
855:
856: // Property: first
857: private int _first;
858: private boolean _firstSet;
859:
860: /**
861: * Gets The index of the first row to be displayed, where 0 is the first row.
862: *
863: * @return the new first value
864: */
865: public int getFirst() {
866: if (_firstSet) {
867: return _first;
868: }
869: ValueExpression expression = getValueExpression("first");
870: if (expression != null) {
871: return (Integer) expression.getValue(getFacesContext()
872: .getELContext());
873: }
874: return 0;
875: }
876:
877: @Override
878: public Object saveState(FacesContext facesContext) {
879: Object[] values = new Object[7];
880: values[0] = super .saveState(facesContext);
881: values[1] = _value;
882: values[2] = _var;
883: values[3] = _rows;
884: values[4] = _rowsSet;
885: values[5] = _first;
886: values[6] = _firstSet;
887:
888: return values;
889: }
890:
891: @Override
892: public void restoreState(FacesContext facesContext, Object state) {
893: Object[] values = (Object[]) state;
894: super .restoreState(facesContext, values[0]);
895: _value = values[1];
896: _var = (String) values[2];
897: _rows = (Integer) values[3];
898: _rowsSet = (Boolean) values[4];
899: _first = (Integer) values[5];
900: _firstSet = (Boolean) values[6];
901: }
902:
903: @Override
904: public String getFamily() {
905: return COMPONENT_FAMILY;
906: }
907: }
|