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

io.devbench.uibuilder.components.multivalue.UIBuilderMultiValueParseInterceptor 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.components.multivalue;

import com.vaadin.flow.component.Component;
import io.devbench.uibuilder.api.parse.BindingHandlerParseInterceptor;
import io.devbench.uibuilder.api.parse.PageTransformer;
import io.devbench.uibuilder.api.utils.ComponentUtil;
import io.devbench.uibuilder.components.form.UIBuilderFormBase;
import org.jetbrains.annotations.NotNull;
import org.jsoup.nodes.Element;
import java.util.Optional;
import java.util.UUID;
import static io.devbench.uibuilder.core.utils.ElementCollector.*;

public class UIBuilderMultiValueParseInterceptor implements BindingHandlerParseInterceptor, PageTransformer {

    static final String DEFAULT_VALUE_ITEM_PATH = "value";

    private static final String AS_ATTRIBUTE = "as";
    private static final String DEFAULT_TEMPLATE_BEAN_NAME = "item";
    private static final String ITEMS_ITEM_BIND_PREFIX = "items:";
    private static final String VALUE_ITEM_PATH_ATTRIBUTE = "value-item-path";

    @Override
    public boolean appliesToSubElements() {
        return true;
    }

    @Override
    public UIBuilderMultiValueBindingContext createBindingContext(Element element) {
        return new UIBuilderMultiValueBindingContext(findTemplateBeanName(element));
    }

    private String findTemplateBeanName(Element element) {
        String templateBeanName = DEFAULT_TEMPLATE_BEAN_NAME;
        if (element.hasAttr(AS_ATTRIBUTE)) {
            templateBeanName = element.attr(AS_ATTRIBUTE);
        }
        return templateBeanName;
    }

    private String findValueItemPath(Element element) {
        String valueItemPath = DEFAULT_VALUE_ITEM_PATH;
        if (element.hasAttr(VALUE_ITEM_PATH_ATTRIBUTE)) {
            valueItemPath = element.attr(VALUE_ITEM_PATH_ATTRIBUTE);
        }
        return valueItemPath;
    }

    @Override
    public boolean handleBinding(@NotNull String binding,
                                 @NotNull UIBuilderMultiValueBindingContext bindingContext) {

        String templateBeanName = bindingContext.getTemplateBeanName();
        if (binding.startsWith(templateBeanName + ".") || binding.equals(templateBeanName)) {
            bindingContext.getBindings().add(binding);
            return true;
        }
        return false;
    }

    @Override
    public void commitBindingParse(UIBuilderMultiValueBindingContext bindingContext, Component component) {
        if (component instanceof UIBuilderMultiValue) {
            bindingContext.commit();
            UIBuilderMultiValue multiItem = (UIBuilderMultiValue) component;
            multiItem.setBindingContext(bindingContext);
        }
    }

    @Override
    public void transform(Element element) {
        if (element.hasAttr(UIBuilderFormBase.ATTR_ITEM_BIND) && !element.hasAttr(ID)) {
            element.attr(ID, UUID.randomUUID().toString());
        }

        if (element.hasAttr(UIBuilderFormBase.ATTR_ITEM_BIND) && !element.attr(UIBuilderFormBase.ATTR_ITEM_BIND).startsWith(ITEMS_ITEM_BIND_PREFIX)) {
            String templateBeanName = findTemplateBeanName(element);
            String valueItemPath = findValueItemPath(element);

            String html = element.html();
            if (html.contains("{{" + templateBeanName + "}}")) {
                html = html.replace("{{" + templateBeanName + "}}", "{{" + templateBeanName + "." + valueItemPath + "}}");
                element.html(html);
            }
        }
    }

    @Override
    public void intercept(Component component, Element element) {
        if (component instanceof UIBuilderMultiValue
            && element.hasAttr(UIBuilderFormBase.ATTR_ITEM_BIND)
            && element.attr(UIBuilderFormBase.ATTR_ITEM_BIND).startsWith(ITEMS_ITEM_BIND_PREFIX)) {

            UIBuilderMultiValue multiValue = (UIBuilderMultiValue) component;
            String bindingPath = element.attr(UIBuilderFormBase.ATTR_ITEM_BIND).substring(ITEMS_ITEM_BIND_PREFIX.length()).trim();
            multiValue.setParentCrudElementBindingPropertyPath(bindingPath);
            multiValue.setParentCrudElementId(findParentFormId(element)
                .orElseGet(() -> findParentCrudPanelId(element)
                    .orElseGet(() -> findParentMDCId(element)
                        .orElse(null))));
        }
    }

    private Optional findParentFormId(Element element) {
        return element.parents().stream()
            .filter(e -> "uibuilder-form".equalsIgnoreCase(e.tagName()))
            .findFirst()
            .filter(formElement -> formElement.hasAttr(ID))
            .map(formElement -> formElement.attr(ID));
    }

    private Optional findParentCrudPanelId(Element element) {
        return element.parents().stream()
            .filter(e -> "crud-panel".equalsIgnoreCase(e.tagName()))
            .findFirst()
            .filter(e -> e.hasAttr(ID))
            .map(e -> e.attr(ID));
    }

    private Optional findParentMDCId(Element element) {
        return element.parents().stream()
            .filter(e -> "detail-panel".equalsIgnoreCase(e.tagName()) || "uibuilder-editor-window".equalsIgnoreCase(e.tagName()))
            .findFirst()
            .filter(e -> e.hasAttr(ID))
            .map(e -> e.attr(ID))
            .flatMap(detailId ->
                element.ownerDocument()
                    .getElementsByAttributeValue("detail", detailId)
                    .stream()
                    .filter(e -> "master-detail-controller".equalsIgnoreCase(e.tagName()))
                    .findFirst()
                    .filter(e -> e.hasAttr(ID))
                    .map(e -> e.attr(ID)));
    }

    @Override
    public boolean isApplicable(Element element) {
        return ComponentUtil.isComponentTagEquals(UIBuilderMultiValue.class, element.tagName());
    }

    @Override
    public boolean isInstantiator(Element element) {
        return element.hasAttr(UIBuilderFormBase.ATTR_ITEM_BIND);
    }

    @Override
    public Component instantiateComponent() {
        return new UIBuilderMultiValue<>();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy