package com.dodo.blog.ui.component.repeater;
import com.dodo.blog.ui.ajax.AjaxListener;
import com.dodo.blog.ui.ajax.AjaxListenerHelper;
import com.dodo.blog.ui.ajax.IAjaxRequestHandler;
import com.dodo.blog.ui.ajax.RepeaterAjaxRequestHandler;
import com.dodo.blog.ui.component.Component;
import com.dodo.blog.ui.component.container.Container;
import javax.servlet.http.HttpServletRequest;
import java.text.MessageFormat;
import java.util.List;
/**
* @author <a href="mailto:pohorelec@comvai.com">Jozef Pohorelec</a>
*/
public abstract class Repeater<T>
extends AbstractRepeater<T>
implements AjaxListener
{
private static final long serialVersionUID = 1L;
public static final int DEFAULT_MAX_ROWS = 5;
public static final String ATTR_REPEATER_ID = "rid";
public static final String CLASS_REPEATER_LINK = "__repeater-link";
public static final String PARAM_FIRST_ROW = "__p_fr";
public static final String PARAM_MAX_ROWS = "__p_mr";
public static final String PARAM_ORDER_BY = "__p_ob";
public static final String PARAM_ORDER_DIRECTION = "__p_od";
private static final String URL = "{0}?" +
PARAM_ID + "={1}&" +
PARAM_FIRST_ROW + "={2}&" +
PARAM_MAX_ROWS + "={3}&" +
PARAM_ORDER_BY + "={4}&" +
PARAM_ORDER_DIRECTION + "={5}&" +
IAjaxRequestHandler.PARAM_AJAX_HANDLER + "={6}";
private IDataSource<T> dataSource;
private int maxRows = DEFAULT_MAX_ROWS;
private int firstRow = 0;
private String orderBy;
private OrderDirection orderDirection;
private Paginator<T> paginator;
private Tag tag;
protected Container container;
public Repeater( String id, IDataSource<T> dataSource )
{
this( id, dataSource, Tag.DIV );
}
public Repeater( String id, IDataSource<T> dataSource, Tag tag )
{
super( Tag.DIV );
create( id, dataSource, tag );
}
protected void create( String id, IDataSource<T> dataSource, Tag tag )
{
init( id, dataSource, tag );
process();
populateRows();
}
protected void init( String id, IDataSource<T> dataSource, Tag tag )
{
clear();
this.tag = tag;
this.dataSource = dataSource;
setId( id );
paginator = new Paginator<T>( getId() );
super.add( paginator );
container = new Container( tag );
super.add( container );
AjaxListenerHelper.addListener( this );
}
@SuppressWarnings( value = "unchecked" )
protected void process()
{
processRequest();
Repeater<T> repeater = ( Repeater<T> ) AjaxListenerHelper.getListener( this );
firstRow = repeater.getFirstRow();
maxRows = repeater.getMaxRows();
orderBy = repeater.getOrderBy();
orderDirection = repeater.getOrderDirection();
}
protected void populateRows()
{
List<T> rows = getRows();
for ( T row : rows )
{
populate( row );
}
}
@Override
@SuppressWarnings( value = "unchecked" )
public List<T> getRows()
{
List<T> result = dataSource.getRows( firstRow, maxRows + 1, orderBy, orderDirection );
if ( result == null )
{
throw new NullPointerException( "Data source cannot return null value!" );
}
if ( result.size() > 0 )
{
if ( firstRow == 0 )
{
paginator.getFirstPage().setHref( "" );
paginator.getFirstPage().setDisabled();
paginator.getPrevPage().setHref( "" );
paginator.getPrevPage().setDisabled();
}
else
{
paginator.getFirstPage().setHref( createUrl( 0, maxRows, orderBy, orderDirection ) );
paginator.getPrevPage().setHref( createUrl( firstRow - maxRows, maxRows, orderBy, orderDirection ) );
}
if ( result.size() <= maxRows )
{
paginator.getNextPage().setHref( "" );
paginator.getNextPage().setDisabled();
}
else
{
paginator.getNextPage().setHref( createUrl( firstRow + maxRows, maxRows, orderBy, orderDirection ) );
}
paginator.getPageIndicator().set( firstRow + 1, result.size() - 1 == maxRows ? firstRow + maxRows : firstRow + result.size() );
if ( result.size() > maxRows )
{
result = result.subList( 0, result.size() - 1 );
}
}
else if ( firstRow > 0 )
{
firstRow = firstRow - maxRows;
if ( firstRow < 0 )
{
firstRow = 0;
}
AjaxListenerHelper.setListener( this );
return getRows();
}
else
{
paginator.getFirstPage().setHref( "" );
paginator.getFirstPage().setDisabled();
paginator.getPrevPage().setHref( "" );
paginator.getPrevPage().setDisabled();
paginator.getNextPage().setHref( "" );
paginator.getNextPage().setDisabled();
paginator.getPageIndicator().set( 0, 0 );
}
return result;
}
@SuppressWarnings( value = "unchecked" )
protected String createUrl( Integer firstRow, Integer maxRows, String orderBy, OrderDirection orderDirection )
{
return MessageFormat.format( URL, getRequest().getRequestURI(), getUniqueId(), firstRow, maxRows, orderBy != null ? orderBy : "", orderDirection != null ? orderDirection.name() : "", RepeaterAjaxRequestHandler.class.getName() );
}
@SuppressWarnings( value = "unchecked" )
private void processRequest()
{
String repeaterId = getRequest().getParameter( PARAM_ID );
if ( getUniqueId().equals( repeaterId ) )
{
// first row
String pfr = getRequest().getParameter( PARAM_FIRST_ROW );
Integer fr = null;
try
{
fr = Integer.valueOf( pfr );
}
catch ( NumberFormatException e )
{
// ignore
}
// max rows
String pmr = getRequest().getParameter( PARAM_MAX_ROWS );
Integer mr = null;
try
{
mr = Integer.valueOf( pmr );
}
catch ( NumberFormatException e )
{
// ignore
}
// order by
String ob = getRequest().getParameter( PARAM_ORDER_BY );
// order direction
String pod = getRequest().getParameter( PARAM_ORDER_DIRECTION );
OrderDirection od = null;
try
{
od = OrderDirection.valueOf( pod );
}
catch ( IllegalArgumentException e )
{
// ignore
}
// update repeater into session
firstRow = fr != null ? fr : firstRow;
maxRows = mr != null ? mr : maxRows;
orderBy = ob != null || ob.trim().length() > 0 ? ob : orderBy;
orderDirection = od != null ? od : orderDirection;
AjaxListenerHelper.setListener( this );
}
}
@Override
public void add( Component component )
{
container.add( component );
}
public IDataSource<T> getDataSource()
{
return dataSource;
}
public int getMaxRows()
{
return maxRows;
}
public void setMaxRows( int maxRows )
{
this.maxRows = maxRows;
}
public int getFirstRow()
{
return firstRow;
}
public void setFirstRow( int firstRow )
{
this.firstRow = firstRow;
}
public String getOrderBy()
{
return orderBy;
}
public void setOrderBy( String orderBy )
{
this.orderBy = orderBy;
}
public OrderDirection getOrderDirection()
{
return orderDirection;
}
public void setOrderDirection( OrderDirection orderDirection )
{
this.orderDirection = orderDirection;
}
public Paginator<T> getPaginator()
{
return paginator;
}
public void setPaginator( Paginator<T> paginator )
{
this.paginator = paginator;
}
public Tag getTag()
{
return tag;
}
@SuppressWarnings( value = "unchecked" )
public String renderAjax( HttpServletRequest request )
{
Repeater<T> repeater = ( Repeater<T> ) AjaxListenerHelper.getListener( this );
repeater.create( repeater.getId(), repeater.getDataSource(), repeater.getTag() );
return repeater.render().toString();
}
@Override
public String getUniqueId()
{
return getId();
}
}