Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
$URL: https://source.sakaiproject.org/svn/jsf/tags/sakai-10.0/jsf-widgets/src/java/org/sakaiproject/jsf/renderer/PagerRenderer.java $ $Id: PagerRenderer.java 116316 2012-11-13 21:31:50Z steve.swinsburg@gmail.com $ Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008 The Sakai Foundation Licensed under the Educational Community License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.opensource.org/licenses/ECL-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
 
 
 package org.sakaiproject.jsf.renderer;
 
 import java.util.Map;
 
 
 
 public class PagerRenderer extends Renderer
 {	
 	private static final Log log = LogFactory.getLog(PagerRenderer.class);
 	private static final String BUNDLE_NAME = "org.sakaiproject.jsf.bundle.pager";
 	
 	public void encodeBegin(FacesContext contextUIComponent componentthrows IOException
 	{
 		if (!component.isRendered()) return;
 		
 		// get state
 		
 		ResponseWriter out = context.getResponseWriter();
 		String clientId = component.getClientId(context);
 		//String formId = getFormId(context, component);
 		
 		int pageSize = getInt(contextcomponent"pageSize", 0);
 		int totalItems = getInt(contextcomponent"totalItems", 0);
 		int firstItem = getInt(contextcomponent"firstItem", 0);
 		int lastItem = getInt(contextcomponent"lastItem", -1);		
 		if (.isDebugEnabled()) .debug("encodeBegin: firstItem=" + firstItem + ", pageSize=" + pageSize + ", value=" + getString(contextcomponent"value"null));
 		
 		// in case we are rendering before decode()ing we need to adjust the states 
 		adjustState(contextcomponentfirstItemlastItempageSizetotalItemsfirstItemlastItempageSize);
 
 		pageSize = getInt(contextcomponent"pageSize", 0);
 		totalItems = getInt(contextcomponent"totalItems", 0);
 		firstItem = getInt(contextcomponent"firstItem", 0);
 		lastItem = getInt(contextcomponent"lastItem", -1);
 		
 		// get stuff for pageing buttons
 		String idFirst = clientId+"_first";
 		String idPrev = clientId+"_prev";
 		String idNext = clientId+"_next";
 		String idLast = clientId+"_last";		
 		String idPastItem = clientId+"_pastItem";
 		boolean renderFirst = getBoolean(contextcomponent"renderFirst"true);
 		boolean renderPrev = getBoolean(contextcomponent"renderPrev"true);
 		boolean renderNext = getBoolean(contextcomponent"renderNext"true);
 		boolean renderLast = getBoolean(contextcomponent"renderLast"true);
 		boolean renderPageSize = getBoolean(contextcomponent"renderPageSize"true);
 		String labelFirst = getString(contextcomponent"textFirst""|<");
 		String labelPrev = getString(contextcomponent"textPrev""<");
 		String labelNext = getString(contextcomponent"textNext"">");
 		String labelLast = getString(contextcomponent"textLast"">|");		
 		String textItem = getString(contextcomponent"textItem""items");
 		String titleFirst = MessageFormat.format(
 				getString(contextcomponent"titleFirst""First {0} {1}"),
 				pageSizetextItem);
 		String titlePrev = MessageFormat.format(
 				getString(contextcomponent"titlePrev""Previous {0} {1}"),
 				pageSizetextItem);
 		String titleNext = MessageFormat.format(
 				getString(contextcomponent"titleNext""Next {0} {1}"),
 				pageSizetextItem);
 		String titleLast = MessageFormat.format(
 				getString(contextcomponent"titleLast""Last {0} {1}"),
 				pageSizetextItem);
 
 		// TODO: Do this elsewhere? (component vs renderer)
 		boolean disabledFirst = (firstItem == 0);
		boolean disabledPrev = (firstItem == 0);
		boolean disabledNext = (pageSize == 0) || (firstItem + pageSize >= totalItems);
		boolean disabledLast = disabledNext;
		boolean accesskeys = getBoolean(contextcomponent"accesskeys"false);
		String accesskeyFirst = (accesskeys) ? "f" : null;
		String accesskeyPrev = (accesskeys) ? "p" : null;
		String accesskeyNext = (accesskeys) ? "n" : null;
		String accesskeyLast = (accesskeys) ? "l" : null;
		// get stuff for page size selection and display
		String textPageSize = getString(contextcomponent"textPageSize""Show {0}");
		String textPageSizeAll = getString(contextcomponent"textPageSizeAll""all");
		String pageSizesStr = getString(contextcomponent"pageSizes""5,10,20,50,100");
		String[] pageSizes = pageSizesStr.split(",");
		String idSelect = clientId+"_pageSize";
		String textStatus;
		if (totalItems > 0)
		{
		    textStatus = getString(contextcomponent"textStatus""Viewing {0} to {1} of {2} {3}");
		}
		else
		{
		    textStatus = getString(contextcomponent"textStatusZeroItems""Viewing 0 {3}");
		}
		Object[] args = new Object[] {String.valueOf(firstItem+1), String.valueOf(lastItem), String.valueOf(totalItems), textItem};
		textStatus = MessageFormat.format(textStatusargs);
		// prepare the dropdown for selecting the 
		// TODO: Probably need to cache this for performance
		String onchangeHandler = "javascript:this.form.submit(); return false;";
		String selectedValue = String.valueOf(pageSize);
		String[] optionTexts = new String[pageSizes.length+1];
		String[] optionValues = new String[pageSizes.length+1];
		for (int i=0; i<pageSizes.lengthi++)
		{
			optionTexts[i] = MessageFormat.format(textPageSizenew Object[] {pageSizes[i]});
			optionValues[i] = pageSizes[i];
		}
		optionTexts[pageSizes.length] = MessageFormat.format(textPageSizenew Object[] {textPageSizeAll});
		optionValues[pageSizes.length] = "0";
		// Output HTML
		out.startElement("div"null);
		out.writeAttribute("class""listNav"null);
		writeStatus(outtextStatus);
		writeButton(outrenderFirstidFirstlabelFirstdisabledFirsttitleFirstaccesskeyFirst);
		writeButton(outrenderPrevidPrevlabelPrevdisabledPrevtitlePrevaccesskeyPrev);
		writeSelect(outrenderPageSizeidSelectoptionTextsoptionValuesselectedValueonchangeHandler);
		writeButton(outrenderNextidNextlabelNextdisabledNexttitleNextaccesskeyNext);
		writeButton(outrenderLastidLastlabelLastdisabledLasttitleLastaccesskeyLast);
		// hidden state that prevents browser reloads from re-performing actions
		// for example, if the user presses the button for the next page of items,
		// and then reloads the browser window.
		out.startElement("input"null);
		out.writeAttribute("type""hidden"null);
		out.writeAttribute("name"idPastItemnull);
		out.writeAttribute("value", String.valueOf(firstItem), null);
		out.endElement("input");
		out.endElement("div");
	}

Output status display
	private static void writeStatus(ResponseWriter outString status)
	{
		out.startElement("div"null);
		out.writeAttribute("class""instruction"null);
		out.writeText(statusnull);
		out.endElement("div");		
	}

Output an HTML button
	private static void writeButton(ResponseWriter outboolean renderString nameString labelboolean disabledString titleString accesskey)
	{
		if (!renderreturn;
		//SAK-22812 wrap each button with a fieldset and legend, for accessibility
		out.startElement("fieldset"null);
		out.startElement("legend"null);
		out.writeText(titlenull);
		out.endElement("legend");
		out.startElement("input"null);
		out.writeAttribute("type""submit"null);
		out.writeAttribute("name"namenull);
		out.writeAttribute("value"labelnull);
		// TODO: i18n
		if (!disabled)
		{
			out.writeAttribute("title"titlenull);
			if (accesskey != nullout.writeAttribute("accesskey"accesskeynull);
			//out.writeAttribute("onclick", "javascript:this.form.submit(); return false;", null);
		}
		else
		{
			out.writeAttribute("disabled""disabled"null);
		}
		out.endElement("input");
		out.endElement("fieldset");
		out.write("\n");
	}

Output an HTML drop-down select
	private static void writeSelect(ResponseWriter outboolean renderString selectIdString[] optionTextsString[] optionValuesString selectedValueString onchangeHandler)
	{
		if (!renderreturn;
		out.startElement("select"null);
		out.writeAttribute("name"selectIdnull);
		out.writeAttribute("id"selectIdnull);
		out.writeAttribute("onchange"onchangeHandlernull);
		out.write("\n");
		for (int i=0; i<optionValues.lengthi++)
		{
			String optionText = optionTexts[i];
			String optionValue = optionValues[i];
			out.startElement("option"null);
			if (optionValue.equals(selectedValue)) out.writeAttribute("selected""selected"null);
			out.writeAttribute("value"optionValuenull);
			out.writeText(optionTextnull);
			out.endElement("option");
			out.write("\n");
		}
		out.endElement("select");
		out.write("\n");
	}
	public void decode(FacesContext contextUIComponent component)
	{
		String clientId = component.getClientId(context);
		String idFirst = clientId+"_first";
		String idPrev = clientId+"_prev";
		String idNext = clientId+"_next";
		String idLast = clientId+"_last";
		String idSelect = clientId+"_pageSize";
		String idPastItem = clientId+"_pastItem";
	    int firstItem = getInt(contextcomponent"firstItem", 0);
	    int lastItem = getInt(contextcomponent"lastItem", 0);
	    int pageSize = getInt(contextcomponent"pageSize", 0);
	    int totalItems = getInt(contextcomponent"totalItems", 0);
		if (.isDebugEnabled()) .debug("decode: firstItem=" + firstItem + ", pageSize=" + pageSize + ", value=" + getString(contextcomponent"value"null));
	    
		int newFirstItem = firstItem;
		int newLastItem = lastItem;
		int newPageSize = pageSize;
		String str = (Stringreq.get(idPastItem);
		// only perform actions if the current firstItem from the 
		// request matches the current firstItem state stored on the server.
		// Prevents browser reloads from performing the same action again.
		if (str != null && firstItem == Integer.valueOf(str).intValue())
		{
			// TODO: Seperate decoding from calculations (renderer vs component)
		    // check which button was pressed
			if (req.containsKey(idFirst))
			{
				newFirstItem = 0;
			}
			else if (req.containsKey(idPrev))
			{
				newFirstItem = Math.max(firstItem - pageSize, 0);
			}
			else if (req.containsKey(idNext))
			{
				newFirstItem = Math.min(firstItem + pageSizetotalItems - 1);
			}
			else if (req.containsKey(idLast))
			{
				int lastPage = (totalItems - 1) / pageSize;
				newFirstItem = lastPage * pageSize;
			}
			else if (req.containsKey(idSelect))
			{
				newPageSize = Integer.parseInt((String)req.get(idSelect));
			}
		}
		adjustState(contextcomponentfirstItemlastItempageSizetotalItemsnewFirstItemnewLastItemnewPageSize);
	}
	private static String formatValue(int firstItemint pageSize) {
		return firstItem + "," + pageSize;
	}

Save the new paging state back to the given component (adjusting firstItem and lastItem first if necessary)
	private static void adjustState(FacesContext contextUIComponent componentint firstItemint lastItemint pageSizeint totalItemsint newFirstItemint newLastItemint newPageSize)
	{
		// recalculate last item
		newLastItem = Math.min(newFirstItem + newPageSizetotalItems);
		if (newPageSize <= 0) 
		{
			// if displaying all items
			newFirstItem = 0;
			newLastItem = totalItems;
		}
		// we don't count lastItem changing as a full state change (value of this component doesn't change)
	    if (newLastItem != lastItem) RendererUtil.setAttribute(contextcomponent"lastItem"new Integer(newLastItem));
	    // send the newly changed values where they need to go
		if (newPageSize != pageSize) RendererUtil.setAttribute(contextcomponent"pageSize"new Integer(newPageSize));
		if (newFirstItem != firstItem) RendererUtil.setAttribute(contextcomponent"firstItem"new Integer(newFirstItem));
	    	
		// Set value, which causes registered valueChangeListener to be called
		String newValue = formatValue(newFirstItemnewPageSize);
		Object oldValue = (String)evh.getValue();
		if (!newValue.equals(oldValue))
		{
			if (oldValue != null) {
				evh.setSubmittedValue(newValue);
				evh.setValid(true);
else {
				// Need to initialize value string based on initial parameters.
				if (.isDebugEnabled()) .debug("initializing value to " + newValue);
				evh.setValue(newValue);
			}
		}
	}

Retrieve an integer value from the component (or widget's resource bundle if not set on the component).
	private static int getInt(FacesContext contextUIComponent componentString attrNameint def)
	{
		Object ret = getFromAttributeOrBundle(contextcomponentattrName);
		if (ret instanceof Integerreturn ((Integer)ret).intValue();
		if (ret instanceof Stringreturn Integer.valueOf((Stringret).intValue();
		return def;
	}

Retrieve an boolean value from the component (or widget's resource bundle if not set on the component).
	private static boolean getBoolean(FacesContext contextUIComponent componentString attrNameboolean def)
	{
		Object ret = getFromAttributeOrBundle(contextcomponentattrName);
		if (ret instanceof Booleanreturn ((Boolean)ret).booleanValue();
		if (ret instanceof Stringreturn Boolean.valueOf((Stringret).booleanValue();
		return def;
	}

Get a named attribute from the component or the widget resource bundle.

Returns:
The attribute value if it exists in the given component, or the attribute value from this widget's resource bundle, or the default if none of those exists.
	private static String getString(FacesContext contextUIComponent componentString attrNameString def)
	{
		String ret = (StringgetFromAttributeOrBundle(contextcomponentattrName);
		if (ret != nullreturn ret;
		// otherwise, return the default
		return def;
	}

Return the attribute value; whether from plain attributes, ValueBinding, or the widget resource bundle.
	private static Object getFromAttributeOrBundle(FacesContext contextUIComponent componentString name)
	{
		// first try the attributes and value bindings
		Object ret = RendererUtil.getAttribute(contextcomponentname);
		if (ret != nullreturn ret;
		// next try the widget resource bundle
		String str = null;
		try {
			str = LocaleUtil.getLocalizedString(context"pager_"+name);
catch (MissingResourceException e) {
			// Returning null is fine here.
			// TODO Distinguish between the dynamic variables we expect to find as an
			// attribute and the static settings we expect to find in a resource bundle,
			// rather than hiding which is which.
		}
		if (str != null && str.length() > 0) return str;
		return null;
	}
New to GrepCode? Check out our FAQ X