/* * Copyright (c) 2009-2016, b3log.org & hacpai.com * * Licensed under the Apache 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.apache.org/licenses/LICENSE-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.b3log.latke.repository; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; /** * Query. * * @author <a href="http://88250.b3log.org">Liang Ding</a> * @version 1.0.1.0, Jun 27, 2012 * @see Projection * @see Filter * @see SortDirection */ public final class Query { /** * Current page number. */ private int currentPageNum = 1; /** * Page count. */ private Integer pageCount; /** * Page size. */ private int pageSize = Integer.MAX_VALUE; /** * Sorts. */ private Map<String, SortDirection> sorts = new LinkedHashMap<String, SortDirection>(); /** * Filter. */ private Filter filter; /** * Projections. */ private Set<Projection> projections = new HashSet<Projection>(); /** * Indices. */ private Set<String[]> indexes = new HashSet<String[]>(); /** * Initialization value for hashing. */ private static final int INIT_HASH = 5; /** * Base for hashing. */ private static final int BASE = 83; /** * Adds a projection with the specified property name and value type. * * @param propertyName the specified property name * @param valueType the specified value type * @return the current query object */ public Query addProjection(final String propertyName, final Class<?> valueType) { projections.add(new Projection(propertyName, valueType)); return this; } /** * Gets the projections. * * @return projections */ public Set<Projection> getProjections() { return Collections.unmodifiableSet(projections); } /** * Indexes the specified properties for future queries. * * @param properties the specified properties * @return the current query object */ public Query index(final String... properties) { if (null == properties || 0 == properties.length) { return this; } indexes.add(properties); return this; } /** * Gets the indices. * * @return indices */ public Set<String[]> getIndexes() { return Collections.unmodifiableSet(indexes); } /** * Adds sort for the specified property with the specified direction. * * @param propertyName the specified property name to sort * @param sortDirection the specified sort * @return the current query object */ public Query addSort(final String propertyName, final SortDirection sortDirection) { sorts.put(propertyName, sortDirection); return this; } /** * Sets the filter with the specified filter. * * @param filter the specified filter * @return the current query object */ public Query setFilter(final Filter filter) { this.filter = filter; return this; } /** * Gets the filter. * * @return filter */ public Filter getFilter() { return filter; } /** * Gets the current page number. * * <p> * <b>Note</b>: The default value of the current page number is * {@code -1}. * </p> * * @return current page number */ public int getCurrentPageNum() { return currentPageNum; } /** * Sets the current page number with the specified current page number. * * @param currentPageNum the specified current page number * @return the current query object */ public Query setCurrentPageNum(final int currentPageNum) { this.currentPageNum = currentPageNum; return this; } /** * Sets the page size. * * <p> * <b>Note</b>: The default value of the page size {@code -1}. * </p> * * @return page size */ public int getPageSize() { return pageSize; } /** * Sets the page size with the specified page size. * * @param pageSize the specified page size * @return the current query object */ public Query setPageSize(final int pageSize) { this.pageSize = pageSize; return this; } /** * Gets the sorts. * * @return sorts */ public Map<String, SortDirection> getSorts() { return Collections.unmodifiableMap(sorts); } /** * Gets the page count. * * @return page count */ public Integer getPageCount() { return pageCount; } /** * Sets the page count with the specified page count. * * @param pageCount the specified page count * @return the current query object */ public Query setPageCount(final int pageCount) { this.pageCount = pageCount; return this; } @Override public boolean equals(final Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final Query other = (Query) obj; if (this.currentPageNum != other.currentPageNum) { return false; } if (this.pageSize != other.pageSize) { return false; } if (this.sorts != other.sorts && (this.sorts == null || !this.sorts.equals(other.sorts))) { return false; } if (this.filter != other.filter && (this.filter == null || !this.filter.equals(other.filter))) { return false; } if (this.projections != other.projections && (this.projections == null || !this.projections.equals(other.projections))) { return false; } return true; } @Override public int hashCode() { int hash = INIT_HASH; hash = BASE * hash + this.currentPageNum; hash = BASE * hash + this.pageSize; hash = BASE * hash + (this.sorts != null ? this.sorts.hashCode() : 0); hash = BASE * hash + (this.filter != null ? this.filter.hashCode() : 0); hash = BASE * hash + (this.projections != null ? this.projections.hashCode() : 0); return hash; } @Override public String toString() { final StringBuilder stringBuilder = new StringBuilder("currentPageNum=").append(currentPageNum).append(", pageSize=").append(pageSize).append(", pageCount=").append(pageCount).append( ", sorts=["); final Set<Entry<String, SortDirection>> entrySet = sorts.entrySet(); final Iterator<Entry<String, SortDirection>> sortsIterator = entrySet.iterator(); while (sortsIterator.hasNext()) { final Entry<String, SortDirection> sort = sortsIterator.next(); stringBuilder.append("[key=").append(sort.getKey()).append(", direction=").append(sort.getValue().name()).append("]"); if (sortsIterator.hasNext()) { stringBuilder.append(", "); } } stringBuilder.append("]"); if (null != filter) { stringBuilder.append(", filter=[").append(filter.toString()).append("]"); } stringBuilder.append(", projections=["); final Iterator<Projection> projectionsIterator = projections.iterator(); while (projectionsIterator.hasNext()) { final Projection projection = projectionsIterator.next(); stringBuilder.append('[').append(projection.toString()).append(']'); if (projectionsIterator.hasNext()) { stringBuilder.append(", "); } } stringBuilder.append("]"); return stringBuilder.toString(); } }