/*
* Copyright 2013 GiavaCms.org.
*
* Licensed under the Eclipse Public License version 1.0, available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.giavacms.common.renderer;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.FacesRenderer;
import javax.faces.render.Renderer;
import org.giavacms.common.util.JSFUtils;
import org.jboss.logging.Logger;
@FacesRenderer(componentFamily = "javax.faces.Command", rendererType = "uiRepeatPagerWithParams")
public class UIRepeatPagerWithParams extends Renderer
{
protected static Logger logger = Logger
.getLogger(UIRepeatPagerWithParams.class);
private static String[] computeSymbols(int paginaCorrente,
int elementiPerPagina, int totaleElementi,
int massimoNumeroDiLinkVisibili)
{
return (String[]) compute(paginaCorrente, elementiPerPagina,
totaleElementi, massimoNumeroDiLinkVisibili, true);
}
private static Integer[] computeLinks(int paginaCorrente,
int elementiPerPagina, int totaleElementi,
int massimoNumeroDiLinkVisibili)
{
return (Integer[]) compute(paginaCorrente, elementiPerPagina,
totaleElementi, massimoNumeroDiLinkVisibili, false);
}
// pagina corrente parte da 1
private static Object[] compute(int paginaEtLinkCorrente,
int elementiPerPagina, int totaleElementi,
int massimoNumeroDiLinkVisibili, boolean returnSymbols)
{
List<String> symbols = new ArrayList<String>();
List<Integer> linkedPages = new ArrayList<Integer>();
int numeroPagine = (totaleElementi % elementiPerPagina == 0) ? (totaleElementi / elementiPerPagina)
: (totaleElementi / elementiPerPagina + 1);
int minimoLink = 1;
int massimoLink = numeroPagine;
int correzionePerLinkPari = massimoNumeroDiLinkVisibili % 2 == 0 ? -1
: 0;
int massimoNumeroDiLinkVisibiliAllaSinistra = correzionePerLinkPari
+ massimoNumeroDiLinkVisibili / 2;
int massimoNumeroDiLinkVisibiliAllaDestra = massimoNumeroDiLinkVisibili / 2;
int minimoLinkVisibileAllaSinistra = paginaEtLinkCorrente
- massimoNumeroDiLinkVisibiliAllaSinistra;
int massimoLinkVisibileAllaDestra = paginaEtLinkCorrente
+ massimoNumeroDiLinkVisibiliAllaDestra;
if (minimoLinkVisibileAllaSinistra < minimoLink)
{
int linkAggiuntiviVisibliAllaDestra = minimoLink
- minimoLinkVisibileAllaSinistra;
minimoLinkVisibileAllaSinistra = minimoLink;
massimoLinkVisibileAllaDestra = massimoLinkVisibileAllaDestra
+ linkAggiuntiviVisibliAllaDestra;
}
if (massimoLinkVisibileAllaDestra > massimoLink)
{
int linkAggiuntiviVisibliAllaSinistra = massimoLinkVisibileAllaDestra
- massimoLink;
massimoLinkVisibileAllaDestra = massimoLink;
minimoLinkVisibileAllaSinistra = minimoLinkVisibileAllaSinistra
- linkAggiuntiviVisibliAllaSinistra;
}
if (minimoLinkVisibileAllaSinistra < 1)
{
minimoLinkVisibileAllaSinistra = 1;
}
boolean inizio = false;
boolean precedente = false;
boolean successivo = false;
boolean fine = false;
if (paginaEtLinkCorrente > minimoLink)
{
inizio = precedente = true;
}
if (paginaEtLinkCorrente < massimoLink)
{
successivo = fine = true;
}
if (inizio)
{
symbols.add("<<");
linkedPages.add(minimoLink);
}
if (precedente)
{
symbols.add("<");
linkedPages.add(paginaEtLinkCorrente - 1);
}
for (int link = minimoLinkVisibileAllaSinistra; link < paginaEtLinkCorrente; link++)
{
symbols.add("" + link);
linkedPages.add(link);
}
symbols.add(paginaEtLinkCorrente + "");
linkedPages.add(paginaEtLinkCorrente);
for (int link = paginaEtLinkCorrente + 1; link <= massimoLinkVisibileAllaDestra; link++)
{
symbols.add("" + link);
linkedPages.add(link);
}
if (successivo)
{
symbols.add(">");
linkedPages.add(paginaEtLinkCorrente + 1);
}
if (fine)
{
symbols.add(">>");
linkedPages.add(massimoLink);
}
if (returnSymbols)
{
return symbols.toArray(new String[] {});
}
else
{
return linkedPages.toArray(new Integer[] {});
}
}
public void encodeBegin(FacesContext context, UIComponent component)
throws IOException
{
ResponseWriter writer = context.getResponseWriter();
String styleClass = (String) component.getAttributes()
.get("styleClass");
String selectedStyleClass = (String) component.getAttributes().get(
"selectedStyleClass");
@SuppressWarnings("rawtypes")
UiRepeatInterface handler = (UiRepeatInterface) component
.getAttributes().get("handler");
int currentpage = handler.getCurrentPage();
int pagesize = handler.getPageSize();
int itemcount = handler.totalSize();
int showpages = toInt(component.getAttributes().get("showpages"));
Integer[] linkedPages = computeLinks(currentpage, pagesize, itemcount,
showpages);
String[] symbols = computeSymbols(currentpage, pagesize, itemcount,
showpages);
// Boolean[] currents = computeCurrent(currentpage, pagesize, showpages,
// itemcount);
writeLinks(writer, component, styleClass, selectedStyleClass,
linkedPages, symbols, currentpage,
JSFUtils.getQueryStringParameters(),
handler.getCurrentPageParam());
}
private void writeLinks(ResponseWriter writer, UIComponent component,
String styleClass, String selectedStyleClass,
Integer[] linkedPages, String[] symbols, int currentPage,
Map<String, String[]> params, String currentPageParam)
throws IOException
{
for (int i = 0; i < symbols.length; i++)
{
if (linkedPages[i] == currentPage)
{
writeSpan(writer, component, symbols[i], selectedStyleClass);
}
else
{
writeLink(writer, component, symbols[i], styleClass,
currentPageParam, linkedPages[i], params);
}
}
}
private void writeLink(ResponseWriter writer, UIComponent component,
String value, String styleClass, String currentPageParam,
Integer pageToShow, Map<String, String[]> params)
throws IOException
{
writer.writeText(" ", null);
writer.startElement("a", component);
writer.writeAttribute("href",
makeHref("", currentPageParam, pageToShow, params), null);
if (styleClass != null)
writer.writeAttribute("class", styleClass, null);
writer.writeText(value, null);
writer.endElement("a");
}
private void writeSpan(ResponseWriter writer, UIComponent component,
String value, String styleClass) throws IOException
{
writer.writeText(" ", null);
writer.startElement("span", component);
if (styleClass != null)
writer.writeAttribute("class", styleClass, null);
writer.writeText(value, null);
writer.endElement("span");
}
private String makeHref(String base, String currentPageParam,
Integer pageToShow, Map<String, String[]> params)
{
StringBuffer href = new StringBuffer(base);
href.append("?").append(currentPageParam).append("=")
.append(pageToShow);
for (String n : params.keySet())
{
String vs[] = params.get(n);
if (vs != null && vs.length > 0)
{
for (String v : vs)
{
if (n != null && n.trim().length() > 0 && v != null
&& v.trim().length() > 0
&& !currentPageParam.equalsIgnoreCase(n))
{
href.append("&").append(n).append("=").append(v);
}
}
}
}
return href.toString();
}
private static int toInt(Object value)
{
if (value == null)
return 0;
if (value instanceof Number)
return ((Number) value).intValue();
if (value instanceof String)
return Integer.parseInt((String) value);
throw new IllegalArgumentException("Cannot convert " + value);
}
public static void main(String[] args)
{
int totalElements = 1005;
int linkVisibili = 10;
int pageSize = 10;
for (int i = 1; (i * pageSize) < (totalElements + pageSize); i++)
{
log(i, pageSize, totalElements, linkVisibili);
}
}
private static void log(int currentPage, int pageSize, int totalElements,
int linkVisibili)
{
Object[] x = UIRepeatPagerWithParams.compute(currentPage, pageSize,
totalElements, linkVisibili, true);
logger.info(currentPage + " \t=\t ");
for (Object o : x)
{
logger.info(o.toString() + " ");
}
logger.info("\n");
}
public UIRepeatPagerWithParams()
{
super();
}
}