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

nl.vpro.hibernate.search6.CollectionSizeBridge Maven / Gradle / Ivy

/*
 * Copyright (C) 2010 All rights reserved
 * VPRO The Netherlands
 */
package nl.vpro.hibernate.search6;

import lombok.With;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.search.engine.backend.document.DocumentElement;
import org.hibernate.search.engine.backend.types.*;
import org.hibernate.search.mapper.pojo.bridge.PropertyBridge;
import org.hibernate.search.mapper.pojo.bridge.binding.PropertyBindingContext;
import org.hibernate.search.mapper.pojo.bridge.mapping.programmatic.PropertyBinder;
import org.hibernate.search.mapper.pojo.bridge.runtime.PropertyBridgeWriteContext;

import java.util.Collection;
import java.util.function.Function;
import java.util.function.Predicate;

@Slf4j
public class CollectionSizeBridge implements PropertyBridge> {

    private final String field;

    private final Function, Integer> sizeFunction;

    public CollectionSizeBridge(String field, Function, Integer> sizeFunction) {
        this.field = field;
        this.sizeFunction = sizeFunction;
    }

    @Override
    public void write(DocumentElement target, Collection bridgedElement, PropertyBridgeWriteContext context) {
        if (bridgedElement != null) {
            target.addValue(field, this.sizeFunction.apply(bridgedElement));
        } else {
            target.addValue(field, 0);
        }
    }


    public static class Binder implements PropertyBinder {

        @With
        private final String name;

        @With
        private final Predicate collectionFilter;


        private Binder(String name, Predicate collectionFilter) {
            this.name = name;
            this.collectionFilter = collectionFilter;
        }


        public Binder() {
            this.collectionFilter  = null;
            this.name = null;
        }


        @Override
        public void bind(PropertyBindingContext context) {
            context.dependencies().useRootOnly();
            var name = this.name == null ? context.bridgedElement().name() + "Size" : this.name;
            var type = context.typeFactory().asInteger().sortable(Sortable.YES).projectable(Projectable.YES).searchable(Searchable.YES);
            var field = context.indexSchemaElement().field(name , type);
            log.debug("Defining field {} with type {}", name, type);
            field.toReference();
            Function, Integer> size = collectionFilter == null ? Collection::size : c -> (int) (c.stream()
                .filter(e -> {
                    if (e == null) {
                        log.warn("Null element in collection {}", c);
                        return false;
                    }
                    return collectionFilter.test(e);
                })
                .filter(collectionFilter)
                .count());
            context.bridge(Collection.class, new CollectionSizeBridge( name, size));
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy