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

edu.stanford.protege.webprotege.forms.GridControlValuesBuilder Maven / Gradle / Ivy

The newest version!
package edu.stanford.protege.webprotege.forms;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import edu.stanford.protege.webprotege.forms.data.*;
import edu.stanford.protege.webprotege.forms.field.*;
import edu.stanford.protege.webprotege.common.LangTagFilter;
import edu.stanford.protege.webprotege.common.Page;
import edu.stanford.protege.webprotege.common.PageCollector;
import edu.stanford.protege.webprotege.common.PageRequest;
import org.semanticweb.owlapi.model.*;

import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Provider;
import java.util.Optional;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.ImmutableList.toImmutableList;

@FormDataBuilderSession
public class GridControlValuesBuilder {

    @Nonnull
    private final BindingValuesExtractor bindingValuesExtractor;

    @Nonnull
    private final Provider formDataDtoBuilderProvider;

    @Nonnull
    private final FormDataBuilderSessionRenderer sessionRenderer;

    @Nonnull
    private final FormRegionOrderingIndex formRegionOrderingIndex;

    @Nonnull
    private final LangTagFilter langTagFilter;

    @Nonnull
    private final FormPageRequestIndex formPageRequestIndex;

    @Nonnull
    private final GridRowDataDtoComparatorFactory comparatorFactory;

    @Nonnull
    private final FormControlDataDtoComparator formControlDataDtoComparator;

    @Nonnull
    private final FormRegionFilterPredicateManager filters;

    @Nonnull
    private final OWLDataFactory dataFactory;


    @Inject
    public GridControlValuesBuilder(@Nonnull BindingValuesExtractor bindingValuesExtractor,
                                    @Nonnull Provider formDataDtoBuilderProvider,
                                    @Nonnull FormDataBuilderSessionRenderer sessionRenderer,
                                    @Nonnull FormRegionOrderingIndex formRegionOrderingIndex,
                                    @Nonnull LangTagFilter langTagFilter,
                                    @Nonnull FormPageRequestIndex formPageRequestIndex,
                                    @Nonnull GridRowDataDtoComparatorFactory comparatorFactory,
                                    @Nonnull FormControlDataDtoComparator formControlDataDtoComparator,
                                    @Nonnull FormRegionFilterIndex formRegionFilterIndex,
                                    @Nonnull FormFilterMatcherFactory formFilterMatcherFactory,
                                    @Nonnull FormRegionFilterPredicateManager filters,
                                    @Nonnull OWLDataFactory dataFactory) {
        this.bindingValuesExtractor = checkNotNull(bindingValuesExtractor);
        this.formDataDtoBuilderProvider = checkNotNull(formDataDtoBuilderProvider);
        this.sessionRenderer = checkNotNull(sessionRenderer);
        this.formRegionOrderingIndex = formRegionOrderingIndex;
        this.langTagFilter = langTagFilter;
        this.formPageRequestIndex = formPageRequestIndex;
        this.comparatorFactory = comparatorFactory;
        this.formControlDataDtoComparator = formControlDataDtoComparator;
        this.filters = filters;
        this.dataFactory = dataFactory;
    }

    @Nonnull
    public ImmutableList getGridControlDataDtoValues(@Nonnull GridControlDescriptor gridControlDescriptor,
                                                                         @Nonnull Optional
                                                                                 subject,
                                                                         @Nonnull OwlBinding theBinding,
                                                                         @Nonnull FormRegionId formFieldId,
                                                                         int depth) {
        var values = bindingValuesExtractor.getBindingValues(subject, theBinding);
        return ImmutableList.of(toGridControlData(subject,
                                                  formFieldId,
                                                  values,
                                                  gridControlDescriptor, depth));
    }

    private FilterState getFilterState(@Nonnull GridControlDescriptor gridControlDescriptor) {
        var filtered = gridControlDescriptor.getColumns()
                                            .stream()
                                            .flatMap(GridColumnDescriptor::getLeafColumnIds)
                                            .anyMatch(filters::isFiltered);
        if (filtered) {
            return FilterState.FILTERED;
        }
        else {
            return FilterState.UNFILTERED;
        }
    }


    private GridControlDataDto toGridControlData(Optional rootSubject,
                                                 FormRegionId formFieldId,
                                                 ImmutableList subjects,
                                                 GridControlDescriptor descriptor, int depth) {
        if (subjects.isEmpty()) {
            var filterState = getFilterState(descriptor);
            return GridControlDataDto.get(descriptor,
                                          Page.emptyPage(),
                                          formRegionOrderingIndex.getOrderings(),
                                          depth,
                                          filterState);
        }

        var pageRequest = rootSubject.map(s -> formPageRequestIndex.pageRequest(s,
                                                                               formFieldId,
                                                                               FormPageRequest.SourceType.GRID_CONTROL)).orElseGet(PageRequest::requestFirstPage);
        var comparator = comparatorFactory.get(descriptor, Optional.empty());

        var subjectFactoryDescriptor = descriptor.getSubjectFactoryDescriptor();

        var rowsPage = subjects.stream()
                               .map(s -> toEntityFormSubject(s, subjectFactoryDescriptor.orElseThrow().getEntityType()))
                               .map(s -> toGridRow(s, descriptor, depth))
                               .filter(row -> !row.containsFilteredEmptyCells())
                               .sorted(comparator)
                               .collect(PageCollector.toPage(pageRequest.getPageNumber(),
                                                             pageRequest.getPageSize()))
                               .orElse(Page.emptyPage());
        var orderings = formRegionOrderingIndex.getOrderings();
        if (orderings.isEmpty()) {
            orderings = descriptor.getColumns()
                                  .stream()
                                  .findFirst()
                                  .map(GridColumnDescriptor::getId)
                                  .map(columnId -> FormRegionOrdering.get(columnId, FormRegionOrderingDirection.ASC))
                                  .map(ImmutableSet::of)
                                  .orElse(ImmutableSet.of());
        }
        var filterState = getFilterState(descriptor);
        return GridControlDataDto.get(descriptor,
                                      rowsPage,
                                      orderings,
                                      depth,
                                      filterState);
    }

    /**
     * Generate a row of a grid for the specified row subject
     *
     * @param rowSubject            The row subject
     * @param gridControlDescriptor The grid control descriptor
     * @return null if there is no row for the specified subject (because it is filtered out)
     */
    @Nonnull
    private GridRowDataDto toGridRow(Optional rowSubject,
                                     GridControlDescriptor gridControlDescriptor,
                                     int depth) {
        var columnDescriptors = gridControlDescriptor.getColumns();
        var formSubject = rowSubject.map(s -> FormEntitySubjectDto.get(sessionRenderer.getEntityRendering(s.getEntity())));
        // To Cells
        var cellData = toGridRowCells(rowSubject,
                                      columnDescriptors,
                                      depth);
        return formSubject.map(s -> GridRowDataDto.get(s, cellData)).orElseGet(() -> GridRowDataDto.get(cellData));
    }

    @Nonnull
    private ImmutableList toGridRowCells(Optional rowSubject,
                                                          @Nonnull ImmutableList columnDescriptors,
                                                          int depth) {
        return columnDescriptors.stream()
                                .map(cd -> toGridCellData(rowSubject, depth, cd))
                                .collect(toImmutableList());
    }

    private GridCellDataDto toGridCellData(Optional rowSubject, int depth, GridColumnDescriptor columnDescriptor) {
        var columnId = columnDescriptor.getId();
        var direction = formRegionOrderingIndex.getOrderingDirection(columnId);
        var cellValueComparator = direction.isAscending() ? formControlDataDtoComparator : formControlDataDtoComparator.reversed();
        var filterPredicate = filters.getFilterPredicate(columnId);
        var cellValues = formDataDtoBuilderProvider.get()
                                                   .toFormControlValues(rowSubject,
                                                                        columnId,
                                                                        columnDescriptor,
                                                                        depth + 1)
                                                   .stream()
                                                   .filter(GridControlValuesBuilder::isNotEmptyGrid)
                                                   .filter(filterPredicate)
                                                   .sorted(cellValueComparator)
                                                   .collect(toImmutableList());
        var filterState = getFilterState(columnDescriptor);
        // The combined filter state takes into consideration the fact that global lang tag
        // filtering may be in place
        var combinedFilterState = getCombinedFilterState(filterState);
        if (cellValues.isEmpty()) {
            return GridCellDataDto.get(columnId, Page.emptyPage(), combinedFilterState);
        }
        if (columnDescriptor.isRepeatable()) {
            return GridCellDataDto.get(columnId, Page.of(cellValues), combinedFilterState);
        }
        // There should only be one to return, but we allow for the fact that
        // there could be more than one – after sorting we take the first one
        var firstValue = cellValues.get(0);
        if (isIncluded(firstValue)) {
            return GridCellDataDto.get(columnId,
                                       Page.of(ImmutableList.of(firstValue)),
                                       combinedFilterState);
        }
        return GridCellDataDto.get(columnId, Page.emptyPage(), combinedFilterState);
    }

    private FilterState getCombinedFilterState(FilterState gridFilterState) {
        if(gridFilterState.equals(FilterState.UNFILTERED)) {
            if(langTagFilter.isFilterActive()) {
                return FilterState.FILTERED;
            }
        }
        return gridFilterState;
    }

    private static boolean isNotEmptyGrid(FormControlDataDto value) {
        return !(value instanceof GridControlDataDto) || !((GridControlDataDto) value).isFilteredEmpty();
    }

    /**
     * Get the filter state for the specified column
     *
     * @param descriptor The column descriptor
     * @return The filter state.  If the column is filtered, or it contains a nested grid that
     * has one or more filtered columns then the state is FILTERED, otherwise it is UNFILTERED
     */
    private FilterState getFilterState(@Nonnull GridColumnDescriptor descriptor) {
        boolean filtered = descriptor.getLeafColumnIds().anyMatch(filters::isFiltered);
        if (filtered) {
            return FilterState.FILTERED;
        }
        else {
            return FilterState.UNFILTERED;
        }
    }

    private boolean isIncluded(FormControlDataDto firstValue) {
        if (firstValue instanceof TextControlDataDto) {
            return ((TextControlDataDto) firstValue).getValue()
                                                    .map(v -> langTagFilter.isIncluded(v.getLang()))
                                                    .orElse(false);
        }
        else {
            return true;
        }
    }


    @Nonnull
    private Optional toEntityFormSubject(@Nonnull OWLPrimitive value,
                                                            @Nonnull EntityType rowEntityType) {
        if(value instanceof OWLEntity) {
            return Optional.of(FormEntitySubject.get((OWLEntity) value));
        }
        else if(value instanceof IRI) {
            var entity = dataFactory.getOWLEntity(rowEntityType, (IRI) value);
            return Optional.of(FormEntitySubject.get(entity));
        }
        else {
            return Optional.empty();
        }
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy