View Javadoc

1   /*******************************************************************************
2    *   Gisgraphy Project 
3    * 
4    *   This library is free software; you can redistribute it and/or
5    *   modify it under the terms of the GNU Lesser General Public
6    *   License as published by the Free Software Foundation; either
7    *   version 2.1 of the License, or (at your option) any later version.
8    * 
9    *   This library is distributed in the hope that it will be useful,
10   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   *   Lesser General Public License for more details.
13   * 
14   *   You should have received a copy of the GNU Lesser General Public
15   *   License along with this library; if not, write to the Free Software
16   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
17   * 
18   *  Copyright 2008  Gisgraphy project 
19   *  David Masclet <davidmasclet@gisgraphy.com>
20   *  
21   *  
22   *******************************************************************************/
23  /**
24   *
25   */
26  package com.gisgraphy.domain.valueobject;
27  
28  /**
29   * Represent a pagination specification.the design (with DSL and interface) does
30   * not allow to set the 'to' properties before the from e.g :
31   * <code>Paginate().from(1).to(9) will return [1,2,3,4,5,6,7,8,9].
32   * @see <a href="http://www.infoq.com/articles/internal-dsls-java/">DSL</a>
33   * @author <a href="mailto:david.masclet@gisgraphy.com">David Masclet</a>
34   */
35  public class Pagination {
36  
37      /**
38       * If the 'to' parameter is not specified or incorrect, it will be set to a
39       * value to have {@link #DEFAULT_MAX_RESULTS} results this value is NOT the
40       * default to parameters, we prefer to use a startegy to fix number of
41       * results instead of the from
42       */
43      public static final int DEFAULT_MAX_RESULTS = 10;
44      
45      
46      /**
47       * max result the pagination should have
48       */
49      public int maxResult = DEFAULT_MAX_RESULTS;
50  
51      /**
52       * the default 'from' parameters if the one specified is missing or
53       * incorrect
54       */
55      public static final int DEFAULT_FROM = 1;
56  
57      /**
58       * @author <a href="mailto:david.masclet@gisgraphy.com">David Masclet</a>
59       *         To specification
60       */
61      public interface ToSpecification {
62  	Pagination to(int to);
63      }
64  
65      /**
66       * @author <a href="mailto:david.masclet@gisgraphy.com">David Masclet</a>
67       *         From Specification
68       */
69      public interface FromSpecification {
70  	ToSpecification from(int from);
71      }
72  
73      /**
74       * @author <a href="mailto:david.masclet@gisgraphy.com">David Masclet</a> A
75       *         pagination builder
76       */
77      public static class PaginationBuilder implements FromSpecification,
78  	    ToSpecification {
79  
80  	private int from;
81  	private int to;
82  	private int maxResults = DEFAULT_MAX_RESULTS;
83  
84  	private PaginationBuilder() {
85  
86  	}
87  
88  	// builder is private
89  	private Pagination build() {
90  	    Pagination pagination = new Pagination();
91  	    pagination.maxResult=maxResults;
92  	    pagination.from(this.from)
93  		    .to(this.to);
94  	    return pagination;
95  	}
96  
97  	/*
98  	 * (non-Javadoc)
99  	 * 
100 	 * @see com.gisgraphy.domain.valueobject.Pagination.ToSpecification#to(int)
101 	 */
102 	public Pagination to(int to) {
103 	    this.to = to;
104 	    return build();
105 	}
106 
107 	/*
108 	 * (non-Javadoc)
109 	 * 
110 	 * @see com.gisgraphy.domain.valueobject.Pagination.FromSpecification#from(int)
111 	 */
112 	public ToSpecification from(int from) {
113 	    this.from = from;
114 	    return this;
115 	}
116 
117     }
118 
119     /**
120      * Default Pagination
121      */
122     public static final Pagination DEFAULT_PAGINATION = new Pagination();
123 
124     /**
125      * The from attribute (int to force non null value)
126      */
127     private int from = DEFAULT_FROM;
128 
129     /**
130      * The to attribute
131      */
132     private int to = DEFAULT_FROM + DEFAULT_MAX_RESULTS - 1;
133 
134     /**
135      * private contructor
136      */
137     private Pagination() {
138 	super();
139     }
140 
141     /**
142      * Static method to be used to create a pagination object. (tip : use Static
143      * import)
144      * 
145      * @return An instance of {@link FromSpecification} to force the from
146      *         parameter to be set first
147      */
148     public static FromSpecification paginate() {
149 	return new PaginationBuilder();
150     }
151     
152     /**
153      * Static method to be used to create a pagination object and define maxResults. (tip : use Static
154      * import). because The to parameter is calculated with the masResultValue, you need to use this method befor set the to and the from.
155      * 
156      * @param maxResult the max number of results he pagination should have, if max results is incorrect,{@link #DEFAULT_MAX_RESULTS} will be used
157      * @return An instance of {@link FromSpecification} to force the from
158      *         parameter to be set first
159      */
160     public static FromSpecification paginateWithMaxResults(int maxResult) {
161 	PaginationBuilder builder = new PaginationBuilder();
162 	if (maxResult <= 0){
163 	    builder.maxResults = DEFAULT_MAX_RESULTS;
164 	}else {
165 	    builder.maxResults = maxResult;
166 	}
167 	return builder;
168     }
169 
170     /**
171      * @param from
172      *                the from parameter for the current pagination, must be > 0
173      *                (numberd from 1)
174      * @return the current Pagination instance in order to chain setters if the
175      *         parameter is not >0, it will be set to default :
176      *         {@link #DEFAULT_FROM}
177      * @see <a href="http://www.infoq.com/articles/internal-dsls-java/">DSL</a>
178      */
179     private Pagination from(int from) {
180 	this.from = from > 0 ? from : DEFAULT_FROM;
181 	return this;
182     }
183 
184     /**
185      * @param to
186      *                the to parameter for the current pagination,must be > 0
187      *                and > {@link #from(int)}
188      * @return the current Pagination instance in order to chain setters If the
189      *         parameter is < from or <= 0, it will be set at a specific value
190      *         in order to have {@link #DEFAULT_MAX_RESULTS}
191      * @see <a href="http://www.infoq.com/articles/internal-dsls-java/">DSL</a>
192      */
193     private Pagination to(int to) {
194 	this.to = (to > 0 && to >= this.from) ? to : this.from
195 		+ maxResult - 1;
196 	return this;
197     }
198 
199     /**
200      * @return the from
201      */
202     public int getFrom() {
203 	return from;
204     }
205 
206     /**
207      * @return the to
208      */
209     public int getTo() {
210 	return to;
211     }
212 
213     /**
214      * Do a post-treatment on the current pagination to limit number of results.
215      * 'from will be unchanged, only 'to' will be changed if limit is <=0, there
216      * is no effect
217      * 
218      * @param limit
219      *                the max number Of results
220      * @return the current Pagination to chain methods
221      */
222     public Pagination limitNumberOfResults(int limit) {
223 	if (limit > 0) {
224 	    this.to = getMaxNumberOfResults() > limit ? from + limit - 1 : to;
225 	}
226 	return this;
227     }
228 
229     /**
230      * @return how many results will be return according the from and to
231      *         parameters (the max expected numbers of results). it can be less
232      *         than expected if there is less results to return. e.g :
233      *         from(1).to(5) can nly return 2 results if there is only 2
234      *         parameters but this method return the max expected numbers of
235      *         results) it will return 0 if from and to equals 0
236      */
237     public int getMaxNumberOfResults() {
238 	return (to - from) + 1;
239     }
240 
241     /* (non-Javadoc)
242      * @see java.lang.Object#hashCode()
243      */
244     @Override
245     public int hashCode() {
246 	final int prime = 31;
247 	int result = 1;
248 	result = prime * result + from;
249 	result = prime * result + to;
250 	return result;
251     }
252 
253     /* (non-Javadoc)
254      * @see java.lang.Object#equals(java.lang.Object)
255      */
256     @Override
257     public boolean equals(Object obj) {
258 	if (this == obj)
259 	    return true;
260 	if (obj == null)
261 	    return false;
262 	if (getClass() != obj.getClass())
263 	    return false;
264 	final Pagination other = (Pagination) obj;
265 	if (from != other.from)
266 	    return false;
267 	if (to != other.to)
268 	    return false;
269 	return true;
270     }
271 
272     /*
273      * (non-Javadoc)
274      * 
275      * @see java.lang.Object#toString()
276      */
277     @Override
278     public String toString() {
279 	return "paginate from " + from + " to " + to;
280     }
281 
282 }