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

com.vaadin.data.provider.TreeDataProvider Maven / Gradle / Ivy

There is a newer version: 8.27.3
Show newest version
/*
 * Copyright (C) 2000-2024 Vaadin Ltd
 *
 * This program is available under Vaadin Commercial License and Service Terms.
 *
 * See  for the full
 * license.
 */
package com.vaadin.data.provider;

import java.util.Comparator;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;

import com.vaadin.data.TreeData;
import com.vaadin.server.SerializableComparator;
import com.vaadin.server.SerializableFunction;
import com.vaadin.server.SerializablePredicate;

/**
 * An in-memory data provider for listing components that display hierarchical
 * data. Uses an instance of {@link TreeData} as its source of data.
 *
 * @author Vaadin Ltd
 * @since 8.1
 *
 * @param 
 *            data type
 */
public class TreeDataProvider
        extends AbstractHierarchicalDataProvider>
        implements InMemoryDataProvider {

    private final TreeData treeData;

    private SerializablePredicate filter = null;

    private SerializableComparator sortOrder = null;

    /**
     * Constructs a new TreeDataProvider.
     * 

* This data provider should be refreshed after making changes to the * underlying {@link TreeData} instance. * * @param treeData * the backing {@link TreeData} for this provider, not * {@code null} */ public TreeDataProvider(TreeData treeData) { Objects.requireNonNull(treeData, "treeData cannot be null"); this.treeData = treeData; } /** * Return the underlying hierarchical data of this provider. * * @return the underlying data of this provider */ public TreeData getTreeData() { return treeData; } @Override public boolean hasChildren(T item) { if (!treeData.contains(item)) { // The item might be dropped from the tree already return false; } return !treeData.getChildren(item).isEmpty(); } @Override public int getChildCount( HierarchicalQuery> query) { // ensure speedy closing in case the stream is connected to IO channels try (Stream stream = fetchChildren(query)) { return (int) stream.count(); } } @Override public Stream fetchChildren( HierarchicalQuery> query) { if (!treeData.contains(query.getParent())) { throw new IllegalArgumentException("The queried item " + query.getParent() + " could not be found in the backing TreeData. " + "Did you forget to refresh this data provider after item removal?"); } Stream childStream = getFilteredStream( treeData.getChildren(query.getParent()).stream(), query.getFilter()); Optional> comparing = Stream .of(query.getInMemorySorting(), sortOrder) .filter(c -> c != null) .reduce((c1, c2) -> c1.thenComparing(c2)); if (comparing.isPresent()) { childStream = childStream.sorted(comparing.get()); } return childStream.skip(query.getOffset()).limit(query.getLimit()); } @Override public SerializablePredicate getFilter() { return filter; } @Override public void setFilter(SerializablePredicate filter) { this.filter = filter; refreshAll(); } @Override public SerializableComparator getSortComparator() { return sortOrder; } @Override public void setSortComparator(SerializableComparator comparator) { sortOrder = comparator; refreshAll(); } @Override public DataProvider withConvertedFilter( SerializableFunction> filterConverter) { Objects.requireNonNull(filterConverter, "Filter converter can't be null"); return new DataProviderWrapper>(this) { @Override protected SerializablePredicate getFilter(Query query) { return query.getFilter().map(filterConverter).orElse(null); } @Override public int size(Query t) { if (t instanceof HierarchicalQuery) { return dataProvider.size(new HierarchicalQuery<>( t.getOffset(), t.getLimit(), t.getSortOrders(), t.getInMemorySorting(), getFilter(t), ((HierarchicalQuery) t).getParent())); } throw new IllegalArgumentException( "Hierarchical data provider doesn't support non-hierarchical queries"); } @Override public Stream fetch(Query t) { if (t instanceof HierarchicalQuery) { return dataProvider.fetch(new HierarchicalQuery<>( t.getOffset(), t.getLimit(), t.getSortOrders(), t.getInMemorySorting(), getFilter(t), ((HierarchicalQuery) t).getParent())); } throw new IllegalArgumentException( "Hierarchical data provider doesn't support non-hierarchical queries"); } }; } private Stream getFilteredStream(Stream stream, Optional> queryFilter) { final Optional> combinedFilter; if (filter != null) { combinedFilter = Optional .of(queryFilter.map(filter::and).orElse(filter)); } else { combinedFilter = queryFilter; } return combinedFilter.map( f -> stream.filter(element -> flatten(element).anyMatch(f))) .orElse(stream); } private Stream flatten(T element) { return Stream.concat(Stream.of(element), getTreeData() .getChildren(element).stream().flatMap(this::flatten)); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy