/*
* Hibernate Search, full-text search for your domain model
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.search.query.engine.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.hibernate.search.engine.metadata.impl.SortableFieldMetadata;
/**
* Provides information about the sortable fields configured for given entities.
*
* @author Gunnar Morling
*/
public class SortConfigurations implements Iterable<SortConfigurations.SortConfiguration> {
@Override
public String toString() {
return configurations.toString();
}
private final List<SortConfiguration> configurations;
private SortConfigurations(List<SortConfiguration> configurations) {
this.configurations = Collections.unmodifiableList( configurations );
}
@Override
public Iterator<SortConfiguration> iterator() {
return configurations.iterator();
}
/**
* Provides information about the sortable fields configured for one or more entities mapped to the same index.
*
* @author Gunnar Morling
*/
public static class SortConfiguration {
private final String indexName;
private final Map<Class<?>, List<SortableFieldMetadata>> sortableFieldsByType;
public SortConfiguration(String indexName, Map<Class<?>, List<SortableFieldMetadata>> sortableFieldsByType) {
this.indexName = indexName;
this.sortableFieldsByType = sortableFieldsByType;
}
/**
* @param entityType the targeted entity type
* @param sort the sort to be examined
* @return all those sort fields from the given {@link Sort} that cannot be satisfied by the existing sortable
* fields (doc value fields) declared for the given indexed type.
*/
public List<String> getUncoveredSorts(Class<?> entityType, Sort sort) {
List<String> uncoveredSorts = new ArrayList<>();
for ( SortField sortField : sort.getSort() ) {
// no doc value field needed for these
if ( sortField.getType() == SortField.Type.DOC || sortField.getType() == SortField.Type.SCORE ) {
continue;
}
boolean isConfigured = false;
for ( SortableFieldMetadata sortFieldMetadata : sortableFieldsByType.get( entityType ) ) {
if ( sortFieldMetadata.getAbsoluteName().equals( sortField.getField() ) ) {
isConfigured = true;
break;
}
}
if ( !isConfigured ) {
uncoveredSorts.add( sortField.getField() );
}
}
return uncoveredSorts;
}
public Set<Class<?>> getEntityTypes() {
return sortableFieldsByType.keySet();
}
public String getIndexName() {
return indexName;
}
@Override
public String toString() {
return "SortConfiguration [indexName=" + indexName + ", sortableFieldsByType=" + sortableFieldsByType + "]";
}
}
/**
* Collects the sortable fields configured for given entities.
*
* @author Gunnar Morling
*/
public static class Builder {
private final Map<String, Map<Class<?>, List<SortableFieldMetadata>>> builtConfigurations = new HashMap<>();
private Map<Class<?>, List<SortableFieldMetadata>> currentIndexBucket;
private List<SortableFieldMetadata> currentEntityTypeBucket;
public Builder setIndex(String indexName) {
currentIndexBucket = builtConfigurations.get( indexName );
if ( currentIndexBucket == null ) {
currentIndexBucket = new HashMap<>();
builtConfigurations.put( indexName, currentIndexBucket );
}
return this;
}
public Builder setEntityType(Class<?> entityType) {
currentEntityTypeBucket = currentIndexBucket.get( entityType );
if ( currentEntityTypeBucket == null ) {
currentEntityTypeBucket = new ArrayList<>();
currentIndexBucket.put( entityType, currentEntityTypeBucket );
}
return this;
}
public Builder addSortableField(SortableFieldMetadata sortableFieldMetadata) {
currentEntityTypeBucket.add( sortableFieldMetadata );
return this;
}
public Builder addSortableFields(Collection<SortableFieldMetadata> sortableFieldMetadata) {
currentEntityTypeBucket.addAll( sortableFieldMetadata );
return this;
}
public SortConfigurations build() {
List<SortConfiguration> configurations = new ArrayList<>();
for ( Entry<String, Map<Class<?>, List<SortableFieldMetadata>>> configuration : builtConfigurations.entrySet() ) {
configurations.add( new SortConfiguration( configuration.getKey(), configuration.getValue() ) );
}
return new SortConfigurations( configurations );
}
}
}