001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package com.sun.rave.web.ui.event;
042:
043: import com.sun.rave.web.ui.component.TextField;
044: import com.sun.rave.web.ui.component.Table;
045: import com.sun.rave.web.ui.component.TableActions;
046: import com.sun.rave.web.ui.component.TableRowGroup;
047: import com.sun.rave.web.ui.util.ConversionUtilities;
048: import com.sun.rave.web.ui.util.LogUtil;
049:
050: import java.util.Iterator;
051:
052: import java.util.List;
053: import java.util.Map;
054:
055: import javax.faces.component.UIComponent;
056: import javax.faces.event.AbortProcessingException;
057: import javax.faces.event.ActionEvent;
058: import javax.faces.event.ActionListener;
059:
060: /**
061: * A listener for receiving pagination toggle events.
062: * <p>
063: * A class that is interested in receiving such events registers itself with the
064: * source {@link Table} of interest, by calling addActionListener().
065: * </p><p>
066: * Note: To see the messages logged by this class, set the following global
067: * defaults in your JDK's "jre/lib/logging.properties" file.
068: * </p><p><pre>
069: * java.util.logging.ConsoleHandler.level = FINE
070: * com.sun.rave.web.ui.event.TablePaginationActionListener.level = FINE
071: * </pre></p>
072: */
073: public class TablePaginationActionListener implements ActionListener {
074: /**
075: * Invoked when the action described by the specified
076: * {@link ActionEvent} occurs. The source parent is expected to be a
077: * TablePagination object.
078: *
079: * @param event The {@link ActionEvent} that has occurred
080: *
081: * @exception AbortProcessingException Signal the JavaServer Faces
082: * implementation that no further processing on the current event
083: * should be performed
084: */
085: public void processAction(ActionEvent event)
086: throws AbortProcessingException {
087: UIComponent source = (event != null) ? (UIComponent) event
088: .getSource() : null;
089: if (source == null) {
090: log("processAction", //NOI18N
091: "Cannot process action, ActionEvent source is null"); //NOI18N
092: return;
093: }
094: processTable(getTableAncestor(source), source.getId());
095: }
096:
097: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
098: // Process Methods
099: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
100:
101: // Helper method to process Table components.
102: private void processTable(Table component, String id)
103: throws AbortProcessingException {
104: if (component == null) {
105: log("processTable",
106: "Cannot process Table action, Table is null"); //NOI18N
107: return;
108: }
109:
110: // Iterate over every TableRowGroup child and set pagination for each.
111: Iterator kids = component.getTableRowGroupChildren();
112: while (kids.hasNext()) {
113: TableRowGroup group = (TableRowGroup) kids.next();
114:
115: if (id.equals(TableActions.PAGINATION_FIRST_BUTTON_ID)) {
116: setFirst(group);
117: } else if (id
118: .equals(TableActions.PAGINATION_LAST_BUTTON_ID)) {
119: setLast(group);
120: } else if (id
121: .equals(TableActions.PAGINATION_NEXT_BUTTON_ID)) {
122: setNext(group);
123: } else if (id.equals(TableActions.PAGINATE_BUTTON_ID)) {
124: setPaginated(group);
125: } else if (id
126: .equals(TableActions.PAGINATION_PREV_BUTTON_ID)) {
127: setPrev(group);
128: } else if (id
129: .equals(TableActions.PAGINATION_SUBMIT_BUTTON_ID)) {
130: try {
131: setPage(group, getPage(component));
132: } catch (NumberFormatException e) {
133: log("processTable",
134: "Cannot obtain page field value"); //NOI18N
135: return;
136: }
137: }
138: }
139: }
140:
141: /**
142: * Get the closest Table ancestor that encloses this component.
143: *
144: * @param component UIComponent for which to extract children.
145: */
146: private Table getTableAncestor(UIComponent component) {
147: if (component == null) {
148: log("getTableAncestor", //NOI18N
149: "Cannot obtain Table ancestor, UIComponent is null"); //NOI18N
150: return null;
151: } else if (component instanceof Table) {
152: return (Table) component;
153: } else {
154: return getTableAncestor(component.getParent());
155: }
156: }
157:
158: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
159: // Pagination Methods
160: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
161:
162: // Get the value of the page field.
163: private int getPage(Table component) {
164: UIComponent actions = component
165: .getFacet(Table.TABLE_ACTIONS_BOTTOM_ID);
166: UIComponent field = (actions != null) ? (UIComponent) actions
167: .getFacet(TableActions.PAGINATION_PAGE_FIELD_ID) : null;
168: String value = null;
169: if (field instanceof TextField) {
170: value = ConversionUtilities.convertValueToString(field,
171: ((TextField) field).getValue());
172: } else {
173: log("getPage", //NOI18N
174: "Cannot obtain page text field value, not TextField instance"); //NOI18N
175: }
176: return (value != null) ? Integer.parseInt(value) : -1;
177: }
178:
179: // Set current page.
180: private void setPage(TableRowGroup component, int page) {
181: if (component == null) {
182: log("setPage", "Cannot set page, TableRowGroup is null"); //NOI18N
183: return;
184: }
185: // Set the starting row for the current page.
186: int row = (page - 1) * component.getRows();
187: setRow(component, row);
188: }
189:
190: // Set first row.
191: private void setFirst(TableRowGroup component) {
192: if (component == null) {
193: log("setFirst",
194: "Canot set first row, TableRowGroup is null"); //NOI18N
195: return;
196: }
197: // Set the starting row for the first page.
198: setRow(component, 0);
199: }
200:
201: // Set last row.
202: private void setLast(TableRowGroup component) {
203: if (component == null) {
204: log("setLast", "Cannot set last row, TableRowGroup is null"); //NOI18N
205: return;
206: }
207: // Get the row number of the last page to be displayed.
208: setRow(component, component.getLast());
209: }
210:
211: // Set next row.
212: private void setNext(TableRowGroup component) {
213: if (component == null) {
214: log("setNext", "Cannot set next row, TableRowGroup is null"); //NOI18N
215: return;
216: }
217: // Get the starting row index for the next page.
218: int row = component.getFirst() + component.getRows();
219: setRow(component, row);
220: }
221:
222: // Set paginated.
223: private void setPaginated(TableRowGroup component) {
224: if (component == null) {
225: log("setPaginated",
226: "Cannot set paginated, TableRowGroup is null"); //NOI18N
227: return;
228: }
229: // Toggle between paginated and scroll mode.
230: component.setPaginated(!component.isPaginated());
231: }
232:
233: // Set previous row.
234: private void setPrev(TableRowGroup component) {
235: if (component == null) {
236: log("setPrev",
237: "Cannot set previous row, TableRowGroup is null"); //NOI18N
238: return;
239: }
240: // Get the starting row index for the previous page.
241: int row = component.getFirst() - component.getRows();
242: setRow(component, row);
243: }
244:
245: // Set row after validating min and max values.
246: private void setRow(TableRowGroup component, int row) {
247: if (component == null) {
248: log("setRow", "Cannot set row, TableRowGroup is null"); //NOI18N
249: return;
250: }
251: // Result cannot be greater than the row index for the last page.
252: int result = Math.min(row, component.getLast());
253:
254: // Result cannot be greater than total number of rows or less than zero.
255: component.setFirst(Math.min(Math.max(result, 0), component
256: .getRowCount()));
257: }
258:
259: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
260: // Misc methods
261: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
262:
263: /**
264: * Log fine messages.
265: */
266: private void log(String method, String message) {
267: // Get class.
268: Class clazz = this .getClass();
269: if (LogUtil.fineEnabled(clazz)) {
270: // Log method name and message.
271: LogUtil.fine(clazz, clazz.getName() + "." + method + ": "
272: + message); //NOI18N
273: }
274: }
275: }
|