package com.gisgraphy.domain.valueobject;
/*******************************************************************************
* Gisgraphy Project
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
*
* Copyright 2008 Gisgraphy project
* David Masclet <davidmasclet@gisgraphy.com>
*
*
*******************************************************************************/
/**
* Represent a pagination specification.the design (with DSL and interface) does
* not allow to set the 'to' properties before the from e.g :
* <code>Paginate().from(1).to(9) will return [1,2,3,4,5,6,7,8,9].
* @see <a href="http://www.infoq.com/articles/internal-dsls-java/">DSL</a>
* @author <a href="mailto:david.masclet@gisgraphy.com">David Masclet</a>
*/
public class Pagination {
/**
* If the 'to' parameter is not specified or incorrect, it will be set to a
* value to have {@link #DEFAULT_MAX_RESULTS} results this value is NOT the
* default to parameters, we prefer to use a startegy to fix number of
* results instead of the from
*/
public static final int DEFAULT_MAX_RESULTS = 10;
/**
* max result the pagination should have
*/
public int maxResult = DEFAULT_MAX_RESULTS;
/**
* the default 'from' parameters if the one specified is missing or
* incorrect
*/
public static final int DEFAULT_FROM = 1;
/**
* @author <a href="mailto:david.masclet@gisgraphy.com">David Masclet</a>
* To specification
*/
public interface ToSpecification {
Pagination to(int to);
}
/**
* @author <a href="mailto:david.masclet@gisgraphy.com">David Masclet</a>
* From Specification
*/
public interface FromSpecification {
ToSpecification from(int from);
}
/**
* @author <a href="mailto:david.masclet@gisgraphy.com">David Masclet</a> A
* pagination builder
*/
public static class PaginationBuilder implements FromSpecification,
ToSpecification {
private int from;
private int to;
private int maxResults = DEFAULT_MAX_RESULTS;
private PaginationBuilder() {
}
// builder is private
private Pagination build() {
Pagination pagination = new Pagination();
pagination.maxResult=maxResults;
pagination.from(this.from)
.to(this.to);
return pagination;
}
/*
* (non-Javadoc)
*
* @see com.gisgraphy.domain.valueobject.Pagination.ToSpecification#to(int)
*/
public Pagination to(int to) {
this.to = to;
return build();
}
/*
* (non-Javadoc)
*
* @see com.gisgraphy.domain.valueobject.Pagination.FromSpecification#from(int)
*/
public ToSpecification from(int from) {
this.from = from;
return this;
}
}
/**
* Default Pagination
*/
public static final Pagination DEFAULT_PAGINATION = new Pagination();
/**
* The from attribute (int to force non null value)
*/
private int from = DEFAULT_FROM;
/**
* The to attribute
*/
private int to = DEFAULT_FROM + DEFAULT_MAX_RESULTS - 1;
/**
* private contructor
*/
private Pagination() {
super();
}
/**
* Static method to be used to create a pagination object. (tip : use Static
* import)
*
* @return An instance of {@link FromSpecification} to force the from
* parameter to be set first
*/
public static FromSpecification paginate() {
return new PaginationBuilder();
}
/**
* Static method to be used to create a pagination object and define maxResults. (tip : use Static
* import). because The to parameter is calculated with the masResultValue, you need to use this method befor set the to and the from.
*
* @param maxResult the max number of results he pagination should have, if max results is incorrect,{@link #DEFAULT_MAX_RESULTS} will be used
* @return An instance of {@link FromSpecification} to force the from
* parameter to be set first
*/
public static FromSpecification paginateWithMaxResults(int maxResult) {
PaginationBuilder builder = new PaginationBuilder();
if (maxResult <= 0){
builder.maxResults = DEFAULT_MAX_RESULTS;
}else {
builder.maxResults = maxResult;
}
return builder;
}
/**
* @param from
* the from parameter for the current pagination, must be > 0
* (numberd from 1)
* @return the current Pagination instance in order to chain setters if the
* parameter is not >0, it will be set to default :
* {@link #DEFAULT_FROM}
* @see <a href="http://www.infoq.com/articles/internal-dsls-java/">DSL</a>
*/
private Pagination from(int from) {
this.from = from > 0 ? from : DEFAULT_FROM;
return this;
}
/**
* @param to
* the to parameter for the current pagination,must be > 0
* and > {@link #from(int)}
* @return the current Pagination instance in order to chain setters If the
* parameter is < from or <= 0, it will be set at a specific value
* in order to have {@link #DEFAULT_MAX_RESULTS}
* @see <a href="http://www.infoq.com/articles/internal-dsls-java/">DSL</a>
*/
private Pagination to(int to) {
this.to = (to > 0 && to >= this.from) ? to : this.from
+ maxResult - 1;
return this;
}
/**
* @return the from
*/
public int getFrom() {
return from;
}
/**
* @return the to
*/
public int getTo() {
return to;
}
/**
* Do a post-treatment on the current pagination to limit number of results.
* 'from will be unchanged, only 'to' will be changed if limit is <=0, there
* is no effect
*
* @param limit
* the max number Of results
* @return the current Pagination to chain methods
*/
public Pagination limitNumberOfResults(int limit) {
if (limit > 0) {
this.to = getMaxNumberOfResults() > limit ? from + limit - 1 : to;
}
return this;
}
/**
* @return how many results will be return according the from and to
* parameters (the max expected numbers of results). it can be less
* than expected if there is less results to return. e.g :
* from(1).to(5) can nly return 2 results if there is only 2
* parameters but this method return the max expected numbers of
* results) it will return 0 if from and to equals 0
*/
public int getMaxNumberOfResults() {
return (to - from) + 1;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + from;
result = prime * result + to;
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Pagination other = (Pagination) obj;
if (from != other.from)
return false;
if (to != other.to)
return false;
return true;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "paginate from " + from + " to " + to;
}
}