/*
* Copyright 2012 - 2017 the original author or authors.
*
* 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.springframework.data.solr.core.query;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.util.Assert;
/**
* Full implementation of {@link Query} that allows multiple options like pagination, grouping,...
*
* @author Christoph Strobl
* @author Rosty Kerei
* @author Luke Corpe
* @author Andrey Paramonov
* @author Francisco Spaeth
*/
public class SimpleQuery extends AbstractQuery implements Query, FilterQuery {
private List<Field> projectionOnFields = new ArrayList<>(0);
private List<FilterQuery> filterQueries = new ArrayList<>(0);
private Long offset = null;
private Integer rows = null;
private Sort sort;
private Operator defaultOperator;
private Integer timeAllowed;
private String defType;
private GroupOptions groupOptions;
private StatsOptions statsOptions;
private SpellcheckOptions spellcheckOptions;
public SimpleQuery() {}
/**
* @param criteria
*/
public SimpleQuery(Criteria criteria) {
this(criteria, null);
}
/**
* @param queryString
* @since 1.1
*/
public SimpleQuery(String queryString) {
this(new SimpleStringCriteria(queryString));
}
/**
* @param criteria
* @param pageable
*/
public SimpleQuery(Criteria criteria, Pageable pageable) {
super(criteria);
if (pageable != null) {
this.offset = pageable.getOffset();
this.rows = pageable.getPageSize();
this.addSort(pageable.getSort());
}
}
/**
* @param queryString
* @param pageable
* @since 1.1
*/
public SimpleQuery(String queryString, Pageable pageable) {
this(new SimpleStringCriteria(queryString), pageable);
}
public static final Query fromQuery(Query source) {
return fromQuery(source, new SimpleQuery());
}
public static <T extends SimpleQuery> T fromQuery(Query source, T destination) {
if (source == null || destination == null) {
return null;
}
if (source.getCriteria() != null) {
destination.addCriteria(source.getCriteria());
}
if (!source.getFilterQueries().isEmpty()) {
for (FilterQuery fq : source.getFilterQueries()) {
destination.addFilterQuery(fq);
}
}
if (!source.getProjectionOnFields().isEmpty()) {
for (Field projectionField : source.getProjectionOnFields()) {
destination.addProjectionOnField(projectionField);
}
}
if (!source.getGroupByFields().isEmpty()) {
for (Field groupByField : source.getGroupByFields()) {
destination.addGroupByField(groupByField);
}
}
if (source.getSort() != null) {
destination.addSort(source.getSort());
}
if (source.getDefType() != null) {
destination.setDefType(source.getDefType());
}
if (source.getDefaultOperator() != null) {
destination.setDefaultOperator(source.getDefaultOperator());
}
if (source.getTimeAllowed() != null) {
destination.setTimeAllowed(source.getTimeAllowed());
}
if (source.getRequestHandler() != null) {
destination.setRequestHandler(source.getRequestHandler());
}
return destination;
}
@SuppressWarnings("unchecked")
@Override
public final <T extends Query> T addProjectionOnField(Field field) {
Assert.notNull(field, "Field for projection must not be null.");
Assert.hasText(field.getName(), "Field.name for projection must not be null/empty.");
this.projectionOnFields.add(field);
return (T) this;
}
public final <T extends Query> T addProjectionOnField(String fieldname) {
return this.addProjectionOnField(new SimpleField(fieldname));
}
@SuppressWarnings("unchecked")
public final <T extends Query> T addProjectionOnFields(Field... fields) {
Assert.notEmpty(fields, "Cannot add projection on null/empty field list.");
for (Field field : fields) {
addProjectionOnField(field);
}
return (T) this;
}
@SuppressWarnings("unchecked")
public final <T extends Query> T addProjectionOnFields(String... fieldnames) {
Assert.notEmpty(fieldnames, "Cannot add projection on null/empty field list.");
for (String fieldname : fieldnames) {
addProjectionOnField(fieldname);
}
return (T) this;
}
@Override
public final <T extends Query> T setPageRequest(Pageable pageable) {
Assert.notNull(pageable, "Pageable must not be null!");
this.offset = pageable.getOffset();
this.rows = pageable.getPageSize();
return this.addSort(pageable.getSort());
}
@SuppressWarnings("unchecked")
@Override
public <T extends Query> T setOffset(Long offset) {
this.offset = offset;
return (T) this;
}
@SuppressWarnings("unchecked")
@Override
public <T extends Query> T setRows(Integer rows) {
this.rows = rows;
return (T) this;
}
@SuppressWarnings("unchecked")
@Override
@Deprecated
public final <T extends Query> T addGroupByField(Field field) {
Assert.notNull(field, "Field for grouping must not be null.");
Assert.hasText(field.getName(), "Field.name for grouping must not be null/empty.");
if (this.groupOptions == null) {
this.groupOptions = new GroupOptions();
}
this.groupOptions.addGroupByField(field).setGroupMain(true);
return (T) this;
}
/**
* add grouping on field name
*
* @param fieldname must not be null
* @return
* @deprecated in favor of {@link GroupOptions}
* @see GroupOptions
*/
@Deprecated
public final <T extends Query> T addGroupByField(String fieldname) {
return addGroupByField(new SimpleField(fieldname));
}
@SuppressWarnings("unchecked")
@Override
public final <T extends Query> T addSort(Sort sort) {
if (sort == null) {
return (T) this;
}
if (this.sort == null) {
this.sort = sort;
} else {
this.sort = this.sort.and(sort);
}
return (T) this;
}
@Override
public Sort getSort() {
return this.sort;
}
@Override
public Pageable getPageRequest() {
if (this.rows == null && this.offset == null) {
return Pageable.unpaged();
}
int rows = this.rows != null ? this.rows : DEFAULT_PAGE_SIZE;
long offset = this.offset != null ? this.offset : 0;
return new SolrPageRequest(rows != 0 ? (int) (offset / rows) : 0, rows, this.sort);
}
@Override
public Long getOffset() {
return this.offset;
}
@Override
public Integer getRows() {
return this.rows;
}
@Override
@Deprecated
public List<Field> getGroupByFields() {
if (this.groupOptions == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(this.groupOptions.getGroupByFields());
}
@Override
public List<Field> getProjectionOnFields() {
return Collections.unmodifiableList(this.projectionOnFields);
}
@SuppressWarnings("unchecked")
@Override
public <T extends Query> T addFilterQuery(FilterQuery filterQuery) {
this.filterQueries.add(filterQuery);
return (T) this;
}
@SuppressWarnings("unchecked")
@Override
public <T extends Query> T setTimeAllowed(Integer timeAllowed) {
this.timeAllowed = timeAllowed;
return (T) this;
}
@Override
public Integer getTimeAllowed() {
return this.timeAllowed;
}
@SuppressWarnings("unchecked")
@Override
public <T extends Query> T setGroupOptions(GroupOptions groupOptions) {
this.groupOptions = groupOptions;
return (T) this;
}
@Override
public GroupOptions getGroupOptions() {
return groupOptions;
}
/*
* (non-Javadoc)
* @see org.springframework.data.solr.core.query.Query#getStatsOptions()
*/
@Override
public StatsOptions getStatsOptions() {
return statsOptions;
}
/*
* (non-Javadoc)
* @see org.springframework.data.solr.core.query.Query#setStatsOptions(org.springframework.data.solr.core.query.StatsOptions)
*/
@SuppressWarnings("unchecked")
@Override
public <T extends Query> T setStatsOptions(StatsOptions statsOptions) {
this.statsOptions = statsOptions;
return (T) this;
}
@Override
public List<FilterQuery> getFilterQueries() {
return Collections.unmodifiableList(this.filterQueries);
}
@Override
public Operator getDefaultOperator() {
return this.defaultOperator != null ? this.defaultOperator : Operator.NONE;
}
/**
* @return true if current operator does not equal {@link Operator#NONE}
*/
public boolean hasDefaultOperatorDefined() {
return !Operator.NONE.equals(getDefaultOperator());
}
@Override
public void setDefaultOperator(Operator operator) {
this.defaultOperator = operator;
}
@Override
public String getDefType() {
return this.defType != null ? this.defType : "";
}
@Override
public void setDefType(String defType) {
this.defType = defType;
}
/*
* (non-Javadoc)
* @see org.springframework.data.solr.core.query.Query#setSpellcheckOptions(org.springframework.data.solr.core.query.SpellcheckOptions)
*/
@Override
@SuppressWarnings("unchecked")
public <T extends Query> T setSpellcheckOptions(SpellcheckOptions spellcheckOptions) {
this.spellcheckOptions = spellcheckOptions;
return (T) this;
}
/*
* (non-Javadoc)
* @see org.springframework.data.solr.core.query.Query#getSpellcheckOptions()
*/
@Override
public SpellcheckOptions getSpellcheckOptions() {
return this.spellcheckOptions;
}
}