All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.rbmhtechnology.vind.model.ComplexFieldDescriptorBuilder Maven / Gradle / Ivy

There is a newer version: 3.2.0
Show newest version
package com.rbmhtechnology.vind.model;

import com.rbmhtechnology.vind.SearchServerException;
import com.rbmhtechnology.vind.annotations.language.Language;
import com.rbmhtechnology.vind.model.value.LatLng;

import java.time.ZonedDateTime;
import java.util.*;
import java.util.function.Function;

/**
 * Created by fonso on 22.02.17.
 */
public class ComplexFieldDescriptorBuilder {


    private boolean stored = false;
    private boolean indexed = true;
    private boolean fullText = false;
    private Language language = Language.None;
    private float boost = 1;
    private boolean facet = false;
    private boolean suggest = false;
    private boolean filter;
    private Map metadata = new HashMap<>();
    private Function> fullTextFunction;
    private Function storeFunction;
    private Function> facetFunction;
    private Function> suggestFunction;
    private Function> filterFunction;


    /**
     * Builds a ComplexFieldDescriptor field which facet type should extend CharSequence, configured with the current flags.
     * @param field Name of the new field.
     * @param complexConcept the class of the complex object to be stored.
     * @param facetType the class of the facet values to be indexed.
     * @param storeType the class of the value to be stored.
     * @return A complex Text facet field descriptor.
     */
    public  SingleValuedComplexField.TextComplexField buildTextComplexField(String field, Class complexConcept, Class facetType, Class storeType){
        SingleValuedComplexField.TextComplexField complexFieldDescriptor = new SingleValuedComplexField.TextComplexField<>(field, complexConcept, facetType, storeType);
        complexFieldDescriptor.setStored(stored,storeFunction);
        if(stored) {
            complexFieldDescriptor.sort = true;
            complexFieldDescriptor.setSort(storeFunction);
        }
        complexFieldDescriptor.setIndexed(indexed);
        complexFieldDescriptor.setFullText(fullText, fullTextFunction);
        complexFieldDescriptor.setMultiValue(false);
        complexFieldDescriptor.setLanguage(language);
        complexFieldDescriptor.setBoost(boost);
        complexFieldDescriptor.setFacet(facet, facetFunction);
        complexFieldDescriptor.setSuggest(suggest,suggestFunction);
        complexFieldDescriptor.setAdvanceFilter(filter, filterFunction);
        complexFieldDescriptor.setMetadata(metadata);
        return complexFieldDescriptor;
    }

    /**
     * Builds a sortable ComplexFieldDescriptor field which facet type should extend CharSequence, configured with the current flags.
     * @param field Name of the new field.
     * @param complexConcept the class of the complex object to be stored.
     * @param facetType the class of the facet values to be indexed.
     * @param storeType the class of the value to be stored.
     * @param sortFunction {@link Function} to use to obtain the value to use as stored search for this complex field.
     * @return A complex Text facet field descriptor.
     */
    public  SingleValuedComplexField.TextComplexField buildSortableTextComplexField(String field, Class complexConcept, Class facetType, Class storeType, Function sortFunction){
        SingleValuedComplexField.TextComplexField complexFieldDescriptor = new SingleValuedComplexField.TextComplexField<>(field, complexConcept, facetType, storeType);
        complexFieldDescriptor.setStored(stored,storeFunction);

        complexFieldDescriptor.setIndexed(indexed);
        complexFieldDescriptor.setFullText(fullText, fullTextFunction);
        complexFieldDescriptor.setMultiValue(false);
        complexFieldDescriptor.setLanguage(language);
        complexFieldDescriptor.setBoost(boost);
        complexFieldDescriptor.setFacet(facet, facetFunction);
        complexFieldDescriptor.setSuggest(suggest,suggestFunction);
        complexFieldDescriptor.setAdvanceFilter(filter, filterFunction);
        complexFieldDescriptor.setMetadata(metadata);
        complexFieldDescriptor.setSort(sortFunction);
        return complexFieldDescriptor;
    }

    /**
     * Builds a Multivalued ComplexFieldDescriptor field which facet type should extend CharSequence, configured with the current flags.
     * @param field Name of the new field.
     * @param complexConcept the class of the complex object to be stored.
     * @param facetType the class of the facet values to be indexed.
     * @param storeType the class of the value to be stored.
     * @return A complex Text facet field descriptor.
     */
    public  MultiValuedComplexField.TextComplexField buildMultivaluedTextComplexField(String field, Class complexConcept, Class facetType, Class storeType){
        MultiValuedComplexField.TextComplexField complexFieldDescriptor = new MultiValuedComplexField.TextComplexField<>(field, complexConcept, facetType, storeType);
        complexFieldDescriptor.setIndexed(indexed);
        complexFieldDescriptor.setStored(stored,storeFunction);
        if(stored) {
            complexFieldDescriptor.sort = true;
            complexFieldDescriptor.setSort(c ->{
                if (Collection.class.isAssignableFrom(c.getClass())) {
                    final Iterator iterator = ((Collection)c).iterator();
                    if (iterator.hasNext()) {
                        final Object next = iterator.next();
                        if (complexConcept.isAssignableFrom(next.getClass())) {
                            return storeFunction.apply((T) next);
                        } else throw new SearchServerException(
                                "Invalid argument exception, default sort function does not take type '" + c.getClass().getName() + "' as  valid parameter");
                    } else {
                        return null;
                    }
                } else {
                    if (complexConcept.isAssignableFrom(c.getClass())) {
                        return storeFunction.apply((T) c);
                    } else throw new SearchServerException(
                            "Invalid argument exception, default sort function does not take type '"+c.getClass().getName()+"' as  valid parameter");
                }
            });
        }
        complexFieldDescriptor.setFacet(facet, facetFunction);
        complexFieldDescriptor.setFullText(fullText, fullTextFunction);
        complexFieldDescriptor.setSuggest(suggest,suggestFunction);
        complexFieldDescriptor.setAdvanceFilter(filter,filterFunction);
        complexFieldDescriptor.setMultiValue(true);
        complexFieldDescriptor.setLanguage(language);
        complexFieldDescriptor.setBoost(boost);
        complexFieldDescriptor.setMetadata(metadata);
        return complexFieldDescriptor;
    }

    /**
     * Builds a sortable Multivalued ComplexFieldDescriptor field which facet type should extend CharSequence, configured with the current flags.
     * @param field Name of the new field.
     * @param complexConcept the class of the complex object to be stored.
     * @param facetType the class of the facet values to be indexed.
     * @param storeType the class of the value to be stored.
     * @param sortFunction {@link Function} to use to obtain the value to use as stored search for this complex field.
     * @return A complex Text facet field descriptor.
     */
    public  MultiValuedComplexField.TextComplexField buildSortableMultivaluedTextComplexField(String field, Class complexConcept, Class facetType, Class storeType, Function,F> sortFunction){
        MultiValuedComplexField.TextComplexField complexFieldDescriptor = new MultiValuedComplexField.TextComplexField<>(field, complexConcept, facetType, storeType);
        complexFieldDescriptor.setIndexed(indexed);
        complexFieldDescriptor.setStored(stored,storeFunction);
        complexFieldDescriptor.setFacet(facet, facetFunction);
        complexFieldDescriptor.setFullText(fullText, fullTextFunction);
        complexFieldDescriptor.setSuggest(suggest,suggestFunction);
        complexFieldDescriptor.setAdvanceFilter(filter, filterFunction);
        complexFieldDescriptor.setMultiValue(true);
        complexFieldDescriptor.setLanguage(language);
        complexFieldDescriptor.setBoost(boost);
        complexFieldDescriptor.setMetadata(metadata);
        complexFieldDescriptor.setSort(sortFunction);
        return complexFieldDescriptor;
    }

    /**
     * Builds a ComplexFieldDescriptor field which facet type should extend Number, configured with the current flags.
     * @param field Name of the new field.
     * @param complexConcept the class of the complex object to be stored.
     * @param facetType the class of the facet values to be indexed.
     * @param storeType the class of the value to be stored.
     * @return A complex Number facet field descriptor.
     */
    public  SingleValuedComplexField.NumericComplexField buildNumericComplexField(String field, Class complexConcept, Class facetType, Class storeType){
        SingleValuedComplexField.NumericComplexField complexFieldDescriptor = new SingleValuedComplexField.NumericComplexField<>(field, complexConcept, facetType, storeType);
        complexFieldDescriptor.setStored(stored,storeFunction);
        if(stored) {
            complexFieldDescriptor.sort = true;
            complexFieldDescriptor.setSort(storeFunction);
        }
        complexFieldDescriptor.setIndexed(indexed);
        complexFieldDescriptor.setFullText(fullText, fullTextFunction);
        complexFieldDescriptor.setMultiValue(false);
        complexFieldDescriptor.setLanguage(language);
        complexFieldDescriptor.setBoost(boost);
        complexFieldDescriptor.setFacet(facet, facetFunction);
        complexFieldDescriptor.setSuggest(suggest,suggestFunction);
        complexFieldDescriptor.setAdvanceFilter(filter, filterFunction);
        complexFieldDescriptor.setMetadata(metadata);
        return complexFieldDescriptor;
    }

    /**
     * Builds a sortable ComplexFieldDescriptor field which facet type should extend Number, configured with the current flags.
     * @param field Name of the new field.
     * @param complexConcept the class of the complex object to be stored.
     * @param facetType the class of the facet values to be indexed.
     * @param storeType the class of the value to be stored.
     * @param sortFunction {@link Function} to use to obtain the value to use as stored search for this complex field.
     * @return A complex Number facet field descriptor.
     */
    public  SingleValuedComplexField.NumericComplexField buildSortableNumericComplexField(String field, Class complexConcept, Class facetType, Class storeType, Function sortFunction){
        SingleValuedComplexField.NumericComplexField complexFieldDescriptor = new SingleValuedComplexField.NumericComplexField<>(field, complexConcept, facetType, storeType);
        complexFieldDescriptor.setStored(stored,storeFunction);
        complexFieldDescriptor.setIndexed(indexed);
        complexFieldDescriptor.setFullText(fullText, fullTextFunction);
        complexFieldDescriptor.setMultiValue(false);
        complexFieldDescriptor.setLanguage(language);
        complexFieldDescriptor.setBoost(boost);
        complexFieldDescriptor.setFacet(facet, facetFunction);
        complexFieldDescriptor.setSuggest(suggest,suggestFunction);
        complexFieldDescriptor.setAdvanceFilter(filter, filterFunction);
        complexFieldDescriptor.setMetadata(metadata);
        complexFieldDescriptor.setSort(sortFunction);
        return complexFieldDescriptor;
    }

    /**
     * Builds a Multivalued ComplexFieldDescriptor field which facet type should extend Number, configured with the current flags.
     * @param field Name of the new field.
     * @param complexConcept the class of the complex object to be stored.
     * @param facetType the class of the facet values to be indexed.
     * @param storeType the class of the value to be stored.
     * @return A complex Text facet field descriptor.
     */
    public  MultiValuedComplexField.NumericComplexField buildMultivaluedNumericComplexField(String field, Class complexConcept, Class facetType, Class storeType){
        MultiValuedComplexField.NumericComplexField complexFieldDescriptor = new MultiValuedComplexField.NumericComplexField<>(field, complexConcept, facetType, storeType);
        complexFieldDescriptor.setIndexed(indexed);
        complexFieldDescriptor.setStored(stored,storeFunction);
        if(stored) {
            complexFieldDescriptor.sort = true;
            complexFieldDescriptor.setSort(c ->{
                if (Collection.class.isAssignableFrom(c.getClass())) {
                    final Iterator iterator = ((Collection)c).iterator();
                    if (iterator.hasNext()) {
                        final Object next = iterator.next();
                        if (complexConcept.isAssignableFrom(next.getClass())) {
                            return storeFunction.apply((T) next);
                        } else throw new SearchServerException(
                                "Invalid argument exception, default sort function does not take type '" + c.getClass().getName() + "' as  valid parameter");
                    } else {
                        return null;
                    }
                } else {
                    if (complexConcept.isAssignableFrom(c.getClass())) {
                        return storeFunction.apply((T) c);
                    } else throw new SearchServerException(
                            "Invalid argument exception, default sort function does not take type '"+c.getClass().getName()+"' as  valid parameter");
                }
            });
        }
        complexFieldDescriptor.setFacet(facet, facetFunction);
        complexFieldDescriptor.setFullText(fullText, fullTextFunction);
        complexFieldDescriptor.setSuggest(suggest,suggestFunction);
        complexFieldDescriptor.setAdvanceFilter(filter, filterFunction);
        complexFieldDescriptor.setMultiValue(true);
        complexFieldDescriptor.setLanguage(language);
        complexFieldDescriptor.setBoost(boost);
        complexFieldDescriptor.setMetadata(metadata);
        return complexFieldDescriptor;
    }

    /**
     * Builds a sortable Multivalued ComplexFieldDescriptor field which facet type should extend Number, configured with the current flags.
     * @param field Name of the new field.
     * @param complexConcept the class of the complex object to be stored.
     * @param facetType the class of the facet values to be indexed.
     * @param storeType the class of the value to be stored.
     * @param sortFunction {@link Function} to use to obtain the value to use as stored search for this complex field.
     * @return A complex Text facet field descriptor.
     */
    public  MultiValuedComplexField.NumericComplexField buildSortableMultivaluedNumericComplexField(String field, Class complexConcept, Class facetType, Class storeType, Function,F> sortFunction){
        MultiValuedComplexField.NumericComplexField complexFieldDescriptor = new MultiValuedComplexField.NumericComplexField<>(field, complexConcept, facetType, storeType);
        complexFieldDescriptor.setIndexed(indexed);
        complexFieldDescriptor.setStored(stored,storeFunction);
        complexFieldDescriptor.setFacet(facet, facetFunction);
        complexFieldDescriptor.setFullText(fullText, fullTextFunction);
        complexFieldDescriptor.setSuggest(suggest,suggestFunction);
        complexFieldDescriptor.setAdvanceFilter(filter, filterFunction);
        complexFieldDescriptor.setMultiValue(true);
        complexFieldDescriptor.setLanguage(language);
        complexFieldDescriptor.setBoost(boost);
        complexFieldDescriptor.setMetadata(metadata);
        complexFieldDescriptor.setSort(sortFunction);
        return complexFieldDescriptor;
    }

    /**
     * Builds a ComplexFieldDescriptor field which facet type should extend Date, configured with the current flags.
     * @param field Name of the new field.
     * @param complexConcept the class of the complex object to be stored.
     * @param facetType the class of the facet values to be indexed.
     * @param storeType the class of the value to be stored.
     * @return A complex Date facet field descriptor.
     */
    public  SingleValuedComplexField.UtilDateComplexField buildUtilDateComplexField(String field, Class complexConcept, Class facetType, Class storeType){
        SingleValuedComplexField.UtilDateComplexField complexFieldDescriptor = new SingleValuedComplexField.UtilDateComplexField<>(field, complexConcept, facetType, storeType);
        complexFieldDescriptor.setStored(stored,storeFunction);
        if(stored) {
            complexFieldDescriptor.sort = true;
            complexFieldDescriptor.setSort(storeFunction);
        }
        complexFieldDescriptor.setIndexed(indexed);
        complexFieldDescriptor.setFullText(fullText, fullTextFunction);
        complexFieldDescriptor.setMultiValue(false);
        complexFieldDescriptor.setLanguage(language);
        complexFieldDescriptor.setBoost(boost);
        complexFieldDescriptor.setFacet(facet, facetFunction);
        complexFieldDescriptor.setSuggest(suggest,suggestFunction);
        complexFieldDescriptor.setAdvanceFilter(filter, filterFunction);
        complexFieldDescriptor.setMetadata(metadata);
        return complexFieldDescriptor;
    }

    /**
     * Builds a sortable ComplexFieldDescriptor field which facet type should extend Date, configured with the current flags.
     * @param field Name of the new field.
     * @param complexConcept the class of the complex object to be stored.
     * @param facetType the class of the facet values to be indexed.
     * @param storeType the class of the value to be stored.
     * @param sortFunction {@link Function} to use to obtain the value to use as stored search for this complex field.
     * @return A complex Date facet field descriptor.
     */
    public  SingleValuedComplexField.UtilDateComplexField buildSortableUtilDateComplexField(String field, Class complexConcept, Class facetType, Class storeType, Function sortFunction){
        SingleValuedComplexField.UtilDateComplexField complexFieldDescriptor = new SingleValuedComplexField.UtilDateComplexField<>(field, complexConcept, facetType, storeType);
        complexFieldDescriptor.setStored(stored,storeFunction);
        complexFieldDescriptor.setIndexed(indexed);
        complexFieldDescriptor.setFullText(fullText, fullTextFunction);
        complexFieldDescriptor.setMultiValue(false);
        complexFieldDescriptor.setLanguage(language);
        complexFieldDescriptor.setBoost(boost);
        complexFieldDescriptor.setFacet(facet, facetFunction);
        complexFieldDescriptor.setSuggest(suggest,suggestFunction);
        complexFieldDescriptor.setAdvanceFilter(filter, filterFunction);
        complexFieldDescriptor.setMetadata(metadata);
        complexFieldDescriptor.setSort(sortFunction);
        return complexFieldDescriptor;
    }

    /**
     * Builds a Multivalued ComplexFieldDescriptor field which facet type should extend Number, configured with the current flags.
     * @param field Name of the new field.
     * @param complexConcept the class of the complex object to be stored.
     * @param facetType the class of the facet values to be indexed.
     * @param storeType the class of the value to be stored.
     * @return A complex Text facet field descriptor.
     */
    public  MultiValuedComplexField.UtilDateComplexField buildMultivaluedUtilDateComplexField(String field, Class complexConcept, Class facetType, Class storeType){
        MultiValuedComplexField.UtilDateComplexField complexFieldDescriptor = new MultiValuedComplexField.UtilDateComplexField<>(field, complexConcept, facetType, storeType);
        complexFieldDescriptor.setIndexed(indexed);
        complexFieldDescriptor.setStored(stored,storeFunction);
        if(stored) {
            complexFieldDescriptor.sort = true;
            complexFieldDescriptor.setSort(c ->{
                if (Collection.class.isAssignableFrom(c.getClass())) {
                    final Iterator iterator = ((Collection)c).iterator();
                    if (iterator.hasNext()) {
                        final Object next = iterator.next();
                        if (complexConcept.isAssignableFrom(next.getClass())) {
                            return storeFunction.apply((T) next);
                        } else throw new SearchServerException(
                                "Invalid argument exception, default sort function does not take type '" + c.getClass().getName() + "' as  valid parameter");
                    } else {
                        return null;
                    }
                } else {
                    if (complexConcept.isAssignableFrom(c.getClass())) {
                        return storeFunction.apply((T) c);
                    } else throw new SearchServerException(
                            "Invalid argument exception, default sort function does not take type '"+c.getClass().getName()+"' as  valid parameter");
                }
            });
        }
        complexFieldDescriptor.setFacet(facet, facetFunction);
        complexFieldDescriptor.setFullText(fullText, fullTextFunction);
        complexFieldDescriptor.setSuggest(suggest,suggestFunction);
        complexFieldDescriptor.setAdvanceFilter(filter, filterFunction);
        complexFieldDescriptor.setMultiValue(true);
        complexFieldDescriptor.setLanguage(language);
        complexFieldDescriptor.setBoost(boost);
        complexFieldDescriptor.setMetadata(metadata);
        return complexFieldDescriptor;
    }

    /**
     * Builds a sortable Multivalued ComplexFieldDescriptor field which facet type should extend Number, configured with the current flags.
     * @param field Name of the new field.
     * @param complexConcept the class of the complex object to be stored.
     * @param facetType the class of the facet values to be indexed.
     * @param storeType the class of the value to be stored.
     * @param sortFunction {@link Function} to use to obtain the value to use as stored search for this complex field.
     * @return A complex Text facet field descriptor.
     */
    public  MultiValuedComplexField.UtilDateComplexField buildSortableMultivaluedUtilDateComplexField(String field, Class complexConcept, Class facetType, Class storeType, Function,F> sortFunction){
        MultiValuedComplexField.UtilDateComplexField complexFieldDescriptor = new MultiValuedComplexField.UtilDateComplexField<>(field, complexConcept, facetType, storeType);
        complexFieldDescriptor.setIndexed(indexed);
        complexFieldDescriptor.setStored(stored,storeFunction);
        complexFieldDescriptor.setFacet(facet, facetFunction);
        complexFieldDescriptor.setFullText(fullText, fullTextFunction);
        complexFieldDescriptor.setSuggest(suggest,suggestFunction);
        complexFieldDescriptor.setAdvanceFilter(filter, filterFunction);
        complexFieldDescriptor.setMultiValue(true);
        complexFieldDescriptor.setLanguage(language);
        complexFieldDescriptor.setBoost(boost);
        complexFieldDescriptor.setMetadata(metadata);
        complexFieldDescriptor.setSort(sortFunction);
        return complexFieldDescriptor;
    }

    /**
     * Builds a ComplexFieldDescriptor field which facet type should extend ZonedDateTime, configured with the current flags.
     * @param field Name of the new field.
     * @param complexConcept the class of the complex object to be stored.
     * @param facetType the class of the facet values to be indexed.
     * @param storeType the class of the value to be stored.
     * @return A complex ZonedDateTime facet field descriptor.
     */
    public  SingleValuedComplexField.DateComplexField buildDateComplexField(String field, Class complexConcept, Class facetType, Class storeType){
        SingleValuedComplexField.DateComplexField complexFieldDescriptor = new SingleValuedComplexField.DateComplexField<>(field, complexConcept, facetType, storeType);
        complexFieldDescriptor.setStored(stored,storeFunction);
        if(stored) {
            complexFieldDescriptor.sort = true;
            complexFieldDescriptor.setSort(storeFunction);
        }
        complexFieldDescriptor.setIndexed(indexed);
        complexFieldDescriptor.setFullText(fullText, fullTextFunction);
        complexFieldDescriptor.setMultiValue(false);
        complexFieldDescriptor.setLanguage(language);
        complexFieldDescriptor.setBoost(boost);
        complexFieldDescriptor.setFacet(facet, facetFunction);
        complexFieldDescriptor.setSuggest(suggest,suggestFunction);
        complexFieldDescriptor.setAdvanceFilter(filter, filterFunction);
        complexFieldDescriptor.setMetadata(metadata);
        return complexFieldDescriptor;
    }

    /**
     * Builds a sortable ComplexFieldDescriptor field which facet type should extend ZonedDateTime, configured with the current flags.
     * @param field Name of the new field.
     * @param complexConcept the class of the complex object to be stored.
     * @param facetType the class of the facet values to be indexed.
     * @param storeType the class of the value to be stored.
     * @param sortFunction {@link Function} to use to obtain the value to use as stored search for this complex field.
     * @return A complex ZonedDateTime facet field descriptor.
     */
    public  SingleValuedComplexField.DateComplexField buildSortableDateComplexField(String field, Class complexConcept, Class facetType, Class storeType, Function sortFunction){
        SingleValuedComplexField.DateComplexField complexFieldDescriptor = new SingleValuedComplexField.DateComplexField<>(field, complexConcept, facetType, storeType);
        complexFieldDescriptor.setStored(stored,storeFunction);
        complexFieldDescriptor.setIndexed(indexed);
        complexFieldDescriptor.setFullText(fullText, fullTextFunction);
        complexFieldDescriptor.setMultiValue(false);
        complexFieldDescriptor.setLanguage(language);
        complexFieldDescriptor.setBoost(boost);
        complexFieldDescriptor.setFacet(facet, facetFunction);
        complexFieldDescriptor.setSuggest(suggest,suggestFunction);
        complexFieldDescriptor.setAdvanceFilter(filter, filterFunction);
        complexFieldDescriptor.setMetadata(metadata);
        complexFieldDescriptor.setSort(sortFunction);
        return complexFieldDescriptor;
    }

    /**
     * Builds a Multivalued ComplexFieldDescriptor field which facet type should extend ZoneDateTime, configured with the current flags.
     * @param field Name of the new field.
     * @param complexConcept the class of the complex object to be stored.
     * @param facetType the class of the facet values to be indexed.
     * @param storeType the class of the value to be stored.
     * @return A complex Text facet field descriptor.
     */
    public  MultiValuedComplexField.DateComplexField buildMultivaluedDateComplexField(String field, Class complexConcept, Class facetType, Class storeType){
        MultiValuedComplexField.DateComplexField complexFieldDescriptor = new MultiValuedComplexField.DateComplexField<>(field, complexConcept, facetType, storeType);
        complexFieldDescriptor.setIndexed(indexed);
        complexFieldDescriptor.setStored(stored,storeFunction);
        if(stored) {
            complexFieldDescriptor.sort = true;
            complexFieldDescriptor.setSort(c ->{
                if (Collection.class.isAssignableFrom(c.getClass())) {
                    final Iterator iterator = ((Collection)c).iterator();
                    if (iterator.hasNext()) {
                        final Object next = iterator.next();
                        if (complexConcept.isAssignableFrom(next.getClass())) {
                            return storeFunction.apply((T) next);
                        } else throw new SearchServerException(
                                "Invalid argument exception, default sort function does not take type '" + c.getClass().getName() + "' as  valid parameter");
                    } else {
                        return null;
                    }
                } else {
                    if (complexConcept.isAssignableFrom(c.getClass())) {
                        return storeFunction.apply((T) c);
                    } else throw new SearchServerException(
                            "Invalid argument exception, default sort function does not take type '"+c.getClass().getName()+"' as  valid parameter");
                }
            });
        }
        complexFieldDescriptor.setFacet(facet, facetFunction);
        complexFieldDescriptor.setFullText(fullText, fullTextFunction);
        complexFieldDescriptor.setSuggest(suggest,suggestFunction);
        complexFieldDescriptor.setAdvanceFilter(filter, filterFunction);
        complexFieldDescriptor.setMultiValue(true);
        complexFieldDescriptor.setLanguage(language);
        complexFieldDescriptor.setBoost(boost);
        complexFieldDescriptor.setMetadata(metadata);
        return complexFieldDescriptor;
    }

    /**
     * Builds a sortable Multivalued ComplexFieldDescriptor field which facet type should extend ZoneDateTime, configured with the current flags.
     * @param field Name of the new field.
     * @param complexConcept the class of the complex object to be stored.
     * @param facetType the class of the facet values to be indexed.
     * @param storeType the class of the value to be stored.
     * @param sortFunction {@link Function} to use to obtain the value to use as stored search for this complex field.
     * @return A complex Text facet field descriptor.
     */
    public  MultiValuedComplexField.DateComplexField buildSortableMultivaluedDateComplexField(String field, Class complexConcept, Class facetType, Class storeType, Function,F> sortFunction){
        MultiValuedComplexField.DateComplexField complexFieldDescriptor = new MultiValuedComplexField.DateComplexField<>(field, complexConcept, facetType, storeType);
        complexFieldDescriptor.setIndexed(indexed);
        complexFieldDescriptor.setStored(stored,storeFunction);
        complexFieldDescriptor.setFacet(facet, facetFunction);
        complexFieldDescriptor.setFullText(fullText, fullTextFunction);
        complexFieldDescriptor.setSuggest(suggest,suggestFunction);
        complexFieldDescriptor.setAdvanceFilter(filter, filterFunction);
        complexFieldDescriptor.setMultiValue(true);
        complexFieldDescriptor.setLanguage(language);
        complexFieldDescriptor.setBoost(boost);
        complexFieldDescriptor.setMetadata(metadata);
        complexFieldDescriptor.setSort(sortFunction);
        return complexFieldDescriptor;
    }

    /**
     * Builds a ComplexFieldDescriptor field which facet type should extend LatLng, configured with the current flags.
     * @param field Name of the new field.
     * @param complexConcept the class of the complex object to be stored.
     * @param facetType the class of the facet values to be indexed.
     * @param storeType the class of the value to be stored.
     * @return A complex LatLng facet field descriptor.
     */
    public  SingleValuedComplexField.LocationComplexFieldDescriptor buildLocationComplexField(String field, Class complexConcept, Class facetType, Class storeType){
        SingleValuedComplexField.LocationComplexFieldDescriptor complexFieldDescriptor = new SingleValuedComplexField.LocationComplexFieldDescriptor<>(field, complexConcept, facetType, storeType);
        complexFieldDescriptor.setStored(stored,storeFunction);
        complexFieldDescriptor.setIndexed(indexed);
        complexFieldDescriptor.setFullText(fullText, fullTextFunction);
        complexFieldDescriptor.setMultiValue(false);
        complexFieldDescriptor.setLanguage(language);
        complexFieldDescriptor.setBoost(boost);
        complexFieldDescriptor.setFacet(facet, facetFunction);
        complexFieldDescriptor.setSuggest(suggest,suggestFunction);
        complexFieldDescriptor.setAdvanceFilter(filter, filterFunction);
        complexFieldDescriptor.setMetadata(metadata);
        return complexFieldDescriptor;
    }

    /**
     * Builds a Multivalued ComplexFieldDescriptor field which facet type should extend LatLng, configured with the current flags.
     * @param field Name of the new field.
     * @param complexConcept the class of the complex object to be stored.
     * @param facetType the class of the facet values to be indexed.
     * @param storeType the class of the value to be stored.
     * @return A complex Text facet field descriptor.
     */
    public  MultiValuedComplexField.LocationComplexFieldDescriptor buildMultivaluedLocationComplexField(String field, Class complexConcept, Class facetType, Class storeType){
        MultiValuedComplexField.LocationComplexFieldDescriptor complexFieldDescriptor = new MultiValuedComplexField.LocationComplexFieldDescriptor<>(field, complexConcept, facetType, storeType);
        complexFieldDescriptor.setIndexed(indexed);
        complexFieldDescriptor.setStored(stored,storeFunction);
        complexFieldDescriptor.setFacet(facet, facetFunction);
        complexFieldDescriptor.setFullText(fullText, fullTextFunction);
        complexFieldDescriptor.setSuggest(suggest,suggestFunction);
        complexFieldDescriptor.setAdvanceFilter(filter,filterFunction);
        complexFieldDescriptor.setMultiValue(true);
        complexFieldDescriptor.setLanguage(language);
        complexFieldDescriptor.setBoost(boost);
        complexFieldDescriptor.setMetadata(metadata);
        return complexFieldDescriptor;
    }

    /**
     * Sets the field to be stored or not.
     * @param stored True to configure the field to be stored.
     * @param lambda {@link Function} to use to obtain the value to use as stored search for this complex field.
     * @return the {@link ComplexFieldDescriptorBuilder} with the new configuration.
     */
    public ComplexFieldDescriptorBuilder setStored(boolean stored, Function lambda) {
        this.stored = stored;
        this.storeFunction = lambda;
        return this;
    }

    /**
     * Sets the field to be stored or not.
     * @param advanceFilter True to configure the field to have special filtering.
     * @param lambda {@link Function} to use to obtain the value to use for advance filtering on this complex field.
     * @return the {@link ComplexFieldDescriptorBuilder} with the new configuration.
     */
    public ComplexFieldDescriptorBuilder setAdvanceFilter(boolean advanceFilter, Function> lambda) {
        this.filter = advanceFilter;
        this.filterFunction = lambda;
        return this;
    }

    /**
     * Sets the field to be indexed or not.
     * @param indexed True to configure the field to be indexed.
     * @return the {@link ComplexFieldDescriptorBuilder} with the new configuration.
     */
    public ComplexFieldDescriptorBuilder setIndexed(boolean indexed) {
        this.indexed = indexed;
        return this;
    }

    /**
     * Sets the field to be fullText or not and describes how to obtain for the fulltext value.
     * @param fullText True to configure the field to be fullText.
     * @param lambda {@link Function} to use to obtain the value to use as fulltext search for this complex field.
     * @return the {@link ComplexFieldDescriptorBuilder} with the new configuration.
     */
    public ComplexFieldDescriptorBuilder setFullText(boolean fullText, Function> lambda) {
        this.fullText = fullText;
        this.fullTextFunction = lambda;
        return this;
    }
    /**
     * Sets the field language: German("de"), English("en"), Spanish("es") or None(null).
     * @param language Language value.
     * @return the {@link ComplexFieldDescriptorBuilder} with the new configuration.
     */
    public ComplexFieldDescriptorBuilder setLanguage(Language language) {
        this.language = language;
        return this;
    }
    /**
     * Sets the boost value for the field.
     * @param boost A float value to modify the calculated score for thr field. 1 is the,'no boost value'.
     * @return the {@link ComplexFieldDescriptorBuilder} with the new configuration.
     */
    public ComplexFieldDescriptorBuilder setBoost(float boost) {
        this.boost = boost;
        return this;
    }


    /**
     * Sets the field to be used for faceting or not and describes how to obtain for the facet value.
     * @param facet True to configure the field to be used on faceting.
     * @param lambda {@link Function} to use to obtain the values for facet operations for this complex field.
     * @return the {@link ComplexFieldDescriptorBuilder} with the new configuration.
     */
    public ComplexFieldDescriptorBuilder setFacet(boolean facet, Function> lambda) {
        this.facet = facet;
        this.facetFunction = lambda;
        return this;
    }

    /**
     * Sets the field to be used for suggestion or not
     * @param suggest True to configure the field to be used on suggestion.
     * @param lambda {@link Function} to use to obtain the value to use as suggestion search for this complex field.
     * @return the {@link ComplexFieldDescriptorBuilder} with the new configuration.
     */
    public ComplexFieldDescriptorBuilder setSuggest(boolean suggest, Function> lambda) {
        this.suggest = suggest;
        this.suggestFunction = lambda;
        return this;
    }

    /**
     * Add metadata to the field.
     * @param name metadata property name.
     * @param value metadata value.
     * @return the {@link ComplexFieldDescriptorBuilder} with the new metadata added.
     */
    public ComplexFieldDescriptorBuilder putMetadata(String name, String value) {
        this.metadata.put(name, value);
        return this;
    }
}