001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/sam/tags/sakai_2-4-1/samigo-app/src/java/org/sakaiproject/tool/assessment/jsf/renderer/PagerRenderer.java $
003: * $Id: PagerRenderer.java 11181 2006-06-26 08:13:58Z lydial@stanford.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2004, 2005, 2006 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the"License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.tool.assessment.jsf.renderer;
021:
022: import java.io.IOException;
023: import java.util.Iterator;
024: import java.util.Map;
025: import javax.faces.component.NamingContainer;
026: import javax.faces.component.UIComponent;
027: import javax.faces.component.UIData;
028: import javax.faces.component.UIForm;
029: import javax.faces.context.FacesContext;
030: import javax.faces.context.ResponseWriter;
031: import javax.faces.el.ValueBinding;
032: import javax.faces.render.Renderer;
033:
034: import org.apache.commons.logging.Log;
035: import org.apache.commons.logging.LogFactory;
036:
037: /**
038: *
039: * <p>Description: modified from an example in the core jsf book</p>
040: * <p>Copyright: Copyright (c) 2004 Sakai</p>
041: * <p>Usage:
042: * <samigo:pager
043: * controlId="controlerIdOfPagerButtonControl" dataTableId="idOfDataTable" showpages="999"
044: * styleClass="aStyle" selectedStyleClass="anotherStyle"/>
045: * </p>
046: * @author Lydia Li
047: * @author Ed Smiley
048: * @version $Id: PagerRenderer.java 11181 2006-06-26 08:13:58Z lydial@stanford.edu $
049: */
050:
051: public class PagerRenderer extends Renderer {
052:
053: private static Log log = LogFactory.getLog(PagerRenderer.class);
054:
055: public void encodeBegin(FacesContext context, UIComponent component)
056: throws IOException {
057: String id = component.getClientId(context);
058: UIComponent parent = component;
059: while (!(parent instanceof UIForm)) {
060: parent = parent.getParent();
061: }
062: String formId = parent.getClientId(context);
063:
064: ResponseWriter writer = context.getResponseWriter();
065:
066: String styleClass = (String) get(context, component,
067: "styleClass");
068: String selectedStyleClass = (String) get(context, component,
069: "selectedStyleClass");
070: String dataTableId = (String) get(context, component,
071: "dataTableId");
072: String controlId = (String) get(context, component, "controlId");
073: Integer a = (Integer) get(context, component, "showpages");
074: int showpages = a == null ? 0 : a.intValue();
075:
076: // find the component with the given ID
077:
078: UIData data = (UIData) findComponent(context.getViewRoot(),
079: getId(dataTableId, id), context);
080:
081: int first = data.getFirst();
082: int itemcount = data.getRowCount();
083: int pagesize = data.getRows();
084: if (pagesize <= 0) {
085: pagesize = itemcount;
086:
087: }
088: int pages;
089: int currentPage;
090: if (pagesize != 0) {
091: pages = itemcount / pagesize;
092: currentPage = first / pagesize;
093: if (itemcount % pagesize != 0) {
094: pages++;
095: }
096: } else {
097: pages = 1;
098: currentPage = 1;
099: }
100:
101: if (first >= itemcount - pagesize) {
102: currentPage = pages - 1;
103: }
104: int startPage = 0;
105: int endPage = pages;
106: if (showpages > 0) {
107: startPage = (currentPage / showpages) * showpages;
108: endPage = Math.min(startPage + showpages, pages);
109: }
110:
111: boolean showLinks = true;
112: Boolean showThem = (Boolean) get(context, component,
113: "showLinks");
114: if (showThem != null) {
115: showLinks = showThem.booleanValue();
116: }
117:
118: // links << < # # # > >>
119: if (showLinks) {
120: if (currentPage > 0) {
121: writeLink(writer, component, formId, controlId, "<",
122: styleClass);
123:
124: }
125: if (startPage > 0) {
126: writeLink(writer, component, formId, controlId, "<<",
127: styleClass);
128:
129: }
130: for (int i = startPage; i < endPage; i++) {
131: writeLink(writer, component, formId, controlId, ""
132: + (i + 1),
133: i == currentPage ? selectedStyleClass
134: : styleClass);
135: }
136:
137: if (endPage < pages) {
138: writeLink(writer, component, formId, controlId, ">>",
139: styleClass);
140:
141: }
142: if (first < itemcount - pagesize) {
143: writeLink(writer, component, formId, controlId, ">",
144: styleClass);
145: }
146: }
147:
148: // hidden field to hold result
149: writeHiddenField(writer, component, controlId, id);
150: }
151:
152: /**
153: *
154: * @param writer ResponseWriter
155: * @param component UIComponent
156: * @param formId String
157: * @param id String
158: * @param value String
159: * @param styleClass String
160: * @throws IOException
161: */
162: private void writeLink(ResponseWriter writer,
163: UIComponent component, String formId, String id,
164: String value, String styleClass) throws IOException {
165: writer.writeText(" ", null);
166: writer.startElement("a", component);
167: writer.writeAttribute("href", "#", null);
168: writer.writeAttribute("onclick",
169: onclickCode(formId, id, value), null);
170: if (styleClass != null) {
171: writer.writeAttribute("class", styleClass, "styleClass");
172: }
173: writer.writeText(value, null);
174: writer.endElement("a");
175: }
176:
177: /**
178: *
179: * @param formId String
180: * @param id String
181: * @param value String
182: * @return String
183: */
184: private String onclickCode(String formId, String id, String value) {
185: StringBuffer buffer = new StringBuffer();
186: buffer.append("document.forms[");
187: buffer.append("'");
188: buffer.append(formId);
189: buffer.append("'");
190: buffer.append("]['");
191: buffer.append(id);
192: buffer.append("'].value='");
193: buffer.append(value);
194: buffer.append("';");
195: buffer.append(" document.forms[");
196: buffer.append("'");
197: buffer.append(formId);
198: buffer.append("'");
199: buffer.append("].submit()");
200: buffer.append("; return false;");
201: return buffer.toString();
202: }
203:
204: /**
205: *
206: * @param writer ResponseWriter
207: * @param component UIComponent
208: * @param controlId String
209: * @param id String
210: * @throws IOException
211: */
212: private void writeHiddenField(ResponseWriter writer,
213: UIComponent component, String controlId, String id)
214: throws IOException {
215: writer.startElement("input", component);
216: writer.writeAttribute("type", "hidden", null);
217: writer.writeAttribute("name", id, null);
218: writer.writeAttribute("id", controlId, null);
219: writer.endElement("input");
220: }
221:
222: public void decode(FacesContext context, UIComponent component) {
223: String id = component.getClientId(context);
224: Map parameters = context.getExternalContext()
225: .getRequestParameterMap();
226: String response = (String) parameters.get(id);
227:
228: String dataTableId = (String) get(context, component,
229: "dataTableId");
230: Integer a = (Integer) get(context, component, "showpages");
231: int showpages = a == null ? 0 : a.intValue();
232:
233: UIData data = (UIData) findComponent(context.getViewRoot(),
234: getId(dataTableId, id), context);
235:
236: int first = data.getFirst();
237: int itemcount = data.getRowCount();
238: int pagesize = data.getRows();
239: if (pagesize <= 0) {
240: pagesize = itemcount;
241: }
242:
243: if (response == null) {
244: first = 0;
245: } else if (response.equals("<")) {
246: first -= pagesize;
247: } else if (response.equals(">")) {
248: first += pagesize;
249: } else if (response.equals("<<")) {
250: first -= pagesize * showpages;
251: } else if (response.equals(">>")) {
252: first += pagesize * showpages;
253: } else {
254: int page = 0; // default if cannot be parsed
255: try {
256: page = Integer.parseInt(response);
257: } catch (NumberFormatException ex) {
258: // do nothing, leave at zero
259: log.debug("do nothing, leave at zero");
260: }
261: first = (page - 1) * pagesize;
262: }
263:
264: if (first + pagesize > itemcount) {
265: first = itemcount - pagesize;
266: }
267:
268: if (first < 0) {
269: first = 0;
270: }
271: data.setFirst(first);
272: }
273:
274: /**
275: *
276: * @param context FacesContext
277: * @param component UIComponent
278: * @param name String
279: * @return Object
280: */
281: private static Object get(FacesContext context,
282: UIComponent component, String name) {
283: ValueBinding binding = component.getValueBinding(name);
284: if (binding != null) {
285: return binding.getValue(context);
286: } else {
287: return component.getAttributes().get(name);
288: }
289: }
290:
291: /**
292: *
293: * @param component UIComponent
294: * @param id String
295: * @param context FacesContext
296: * @return UIComponent
297: */
298: private static UIComponent findComponent(UIComponent component,
299: String id, FacesContext context) {
300: String componentId = component.getClientId(context);
301: if (componentId.equals(id)) {
302: return component;
303: }
304: Iterator kids = component.getChildren().iterator();
305: while (kids.hasNext()) {
306: UIComponent kid = (UIComponent) kids.next();
307: UIComponent found = findComponent(kid, id, context);
308: if (found != null) {
309: return found;
310: }
311: }
312: return null;
313: }
314:
315: /**
316: *
317: * @param id String
318: * @param baseId String
319: * @return String
320: */
321: private static String getId(String id, String baseId) {
322: String separator = "" + NamingContainer.SEPARATOR_CHAR;
323: String[] idSplit = id.split(separator);
324: String[] baseIdSplit = baseId.split(separator);
325: StringBuffer buffer = new StringBuffer();
326: for (int i = 0; i < baseIdSplit.length - idSplit.length; i++) {
327: buffer.append(baseIdSplit[i]);
328: buffer.append(separator);
329: }
330: buffer.append(id);
331: return buffer.toString();
332: }
333: }
|