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

io.devbench.uibuilder.data.collectionds.datasource.component.AbstractDataSourceComponent Maven / Gradle / Ivy

The newest version!
/*
 *
 * Copyright © 2018 Webvalto Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.devbench.uibuilder.data.collectionds.datasource.component;

import com.vaadin.flow.component.HasComponents;
import com.vaadin.flow.component.HasElement;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.data.binder.HasItems;
import io.devbench.uibuilder.api.components.HasRawElementComponent;
import io.devbench.uibuilder.api.listeners.BackendAttachListener;
import io.devbench.uibuilder.components.util.datasource.DataSourceReadyEvent;
import io.devbench.uibuilder.data.api.datasource.DataSourceManager;
import io.devbench.uibuilder.data.api.datasource.interfaces.DataSourceRefreshNotifiable;
import io.devbench.uibuilder.data.api.exceptions.DataSourceNotFoundException;
import io.devbench.uibuilder.data.api.filter.FilterExpression;
import io.devbench.uibuilder.data.collectionds.CollectionDataSource;
import io.devbench.uibuilder.data.collectionds.ItemDataSourceCapable;
import io.devbench.uibuilder.data.collectionds.interceptors.ItemDataSourceBindingContext;
import io.devbench.uibuilder.data.common.dataprovidersupport.DataProviderEndpointManager;
import io.devbench.uibuilder.data.common.dataprovidersupport.DataProviderEndpointRegistration;
import io.devbench.uibuilder.data.common.datasource.CommonDataSource;
import io.devbench.uibuilder.data.common.datasource.CommonDataSourceContext;
import io.devbench.uibuilder.data.common.datasource.CommonDataSourceSelector;
import lombok.AccessLevel;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

public abstract class AbstractDataSourceComponent
    extends HasRawElementComponent
    implements HasComponents, HasElement, HasItems, BackendAttachListener, DataSourceRefreshNotifiable, ItemDataSourceCapable {

    private static final String SET_ENDPOINT_URL_FUNCTION_NAME = "_setEndpointInfo";

    @Getter
    @Nullable
    private CommonDataSource dataSource;

    @Getter(AccessLevel.PROTECTED)
    private String dataSourceId;

    @Override
    public void connectItemDataSource(String dataSourceId) {
        this.dataSourceId = dataSourceId;
        this.setItems(Collections.emptyList());
    }

    @Override
    public void onAttached() {
        final DataProviderEndpointManager dataProviderEndpointManager = DataProviderEndpointManager.getInstance();
        addListener(DataSourceReadyEvent.class, event -> {
            connectDataSource(event.getDataSourceId(), event.getDataSourceName(), event.getDefaultQuery(), dataProviderEndpointManager);
        });
    }

    private void connectDataSource(String dataSourceId, String datasourceName, String datasourceDefaultQuery,
                                   DataProviderEndpointManager dataProviderEndpointManager) {
        this.dataSourceId = dataSourceId;
        final DataProviderEndpointRegistration endpoint = dataProviderEndpointManager.register(this, dataSourceId, datasourceName, datasourceDefaultQuery);
        dataSource = endpoint.getDataSource();
        getElement().callJsFunction(SET_ENDPOINT_URL_FUNCTION_NAME, endpoint.getUrl(), UI.getCurrent().getCsrfToken());
        setSelectedItemsIfItemWasSetPreviously();
    }

    public final void setItems(Collection elements) {
        CollectionDataSource collectionDataSource = createCollectionDataSource(elements);
        setDataSource(collectionDataSource);
        onItemsSet();
    }

    @SafeVarargs
    public final void setItems(T... elements) {
        setItems(Arrays.asList(elements));
    }

    public void onItemsSet() {
        // can be overridden
    }

    private CollectionDataSource createCollectionDataSource(Collection items) {
        final ItemDataSourceBindingContext bindingContext = (ItemDataSourceBindingContext)
            Objects.requireNonNull(
                DataSourceManager.getInstance().getDataSourceProvider().getBindingContextForName(this.dataSourceId, null),
                "Datasource bindings by id datasource: " + this.dataSourceId + " not found");
        final List keyPaths = bindingContext.getKeyPaths();
        return new CollectionDataSource<>(bindingContext, keyPaths, items);
    }

    @Override
    public void setDataSource(CommonDataSource, ?> collectionDataSource) {
        @SuppressWarnings("unchecked")
        CommonDataSourceContext> dataSourceContext =
            (CommonDataSourceContext>) CommonDataSourceContext.getInstance();

        DataProviderEndpointManager dataProvider = DataProviderEndpointManager.getInstance();
        DataProviderEndpointRegistration endpoint = dataProvider.register(this, collectionDataSource);

        dataSource = dataSourceContext.replaceDataSource(this.dataSourceId, new CommonDataSourceSelector(null, this), endpoint::getDataSource);

        getElement().callJsFunction(SET_ENDPOINT_URL_FUNCTION_NAME, endpoint.getUrl(), UI.getCurrent().getCsrfToken());
        setSelectedItemsIfItemWasSetPreviously();
    }

    protected abstract void setSelectedItemsIfItemWasSetPreviously();

    @Override
    public void refresh() {
        getElement().callJsFunction("clearCache");
    }

    public void withDataSource(@NotNull Consumer> dataSourceConsumer) {
        withDataSource(dataSourceConsumer, () -> new DataSourceNotFoundException("Trying to access missing datasource in component: " + this));
    }

    public void withDataSource(@NotNull Consumer> dataSourceConsumer,
                               @Nullable Supplier dataSourceNotFoundException) {
        CommonDataSource dataSource = getDataSource();
        if (dataSource != null) {
            dataSourceConsumer.accept(dataSource);
        } else {
            if (dataSourceNotFoundException != null) {
                throw dataSourceNotFoundException.get();
            }
        }
    }

    public  Optional mapDataSource(@NotNull Function, R> dataSourceFunction) {
        return mapDataSource(dataSourceFunction, () -> new DataSourceNotFoundException("Trying to access missing datasource in component: " + this));
    }

    public  Optional mapDataSource(@NotNull Function, R> dataSourceFunction,
                                         @Nullable Supplier dataSourceNotFoundException) {

        CommonDataSource dataSource = getDataSource();
        if (dataSource != null) {
            return Optional.ofNullable(dataSourceFunction.apply(dataSource));
        } else {
            if (dataSourceNotFoundException != null) {
                throw dataSourceNotFoundException.get();
            }
        }

        return Optional.empty();
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy