io.devbench.uibuilder.components.multivalue.UIBuilderMultiValueParseInterceptor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of uibuilder-multi-value Show documentation
Show all versions of uibuilder-multi-value Show documentation
A multi value component for the UIBuilder Framework
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<>();
}
}