package fr.openwide.core.wicket.more.markup.repeater.table.builder.action; import java.util.List; import java.util.Objects; import java.util.Set; import org.apache.wicket.AttributeModifier; import org.apache.wicket.Component; import org.apache.wicket.MarkupContainer; import org.apache.wicket.behavior.Behavior; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.link.AbstractLink; import org.apache.wicket.model.IModel; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import fr.openwide.core.commons.util.functional.Predicates2; import fr.openwide.core.wicket.behavior.ClassAttributeAppender; import fr.openwide.core.wicket.markup.html.basic.CoreLabel; import fr.openwide.core.wicket.more.condition.Condition; import fr.openwide.core.wicket.more.markup.html.basic.PlaceholderContainer; import fr.openwide.core.wicket.more.markup.html.bootstrap.label.behavior.BootstrapColorBehavior; import fr.openwide.core.wicket.more.markup.html.bootstrap.label.renderer.BootstrapRenderer; import fr.openwide.core.wicket.more.markup.html.bootstrap.label.renderer.IBootstrapRendererModel; import fr.openwide.core.wicket.more.markup.html.factory.IDetachableFactory; import fr.openwide.core.wicket.more.markup.html.factory.IOneParameterComponentFactory; import fr.openwide.core.wicket.more.markup.repeater.table.column.CoreActionColumnElementPanel; import fr.openwide.core.wicket.more.util.model.Detachables; import fr.openwide.core.wicket.more.util.model.Models; public abstract class AbstractActionColumnElementBuilder<T, L extends AbstractLink, F extends AbstractActionColumnElementBuilder<T, L, F>> implements IOneParameterComponentFactory<MarkupContainer, IModel<T>> { private static final long serialVersionUID = 8791565179874571105L; private final BootstrapRenderer<? super T> renderer; private final IOneParameterComponentFactory<? extends L, IModel<T>> factory; private Condition showLabelCondition = Condition.alwaysFalse(); private Condition showTooltipCondition = Condition.alwaysTrue(); private Condition showIconCondition = Condition.alwaysTrue(); private Condition showPlaceholderCondition = Condition.alwaysTrue(); private final List<IDetachableFactory<? super IModel<? extends T>, ? extends Condition>> conditionFactories = Lists.newArrayList(); private final StringBuilder cssClasses = new StringBuilder(); private final Set<Behavior> behaviors = Sets.newHashSet(); public AbstractActionColumnElementBuilder(BootstrapRenderer<? super T> renderer, IOneParameterComponentFactory<? extends L, IModel<T>> factory) { this.factory = factory; this.renderer = renderer; } @Override public final MarkupContainer create(String wicketId, IModel<T> rowModel) { return new CoreActionColumnElementPanel<T>(wicketId, rowModel) { private static final long serialVersionUID = 1L; @Override protected Component getLink(String string, IModel<T> rowModel) { L link = factory.create("link", rowModel); decorateLink(link, rowModel); return link; } @Override protected PlaceholderContainer getPlaceholder(String string, IModel<T> rowModel) { PlaceholderContainer placeholder = new PlaceholderContainer("linkPlaceholder"); decoratePlaceholder(placeholder, rowModel); return placeholder; } }; } protected void decorateLink(L link, IModel<T> rowModel) { IBootstrapRendererModel rendererModel = renderer.asModel(rowModel); IModel<String> tooltipModel = rendererModel.getTooltipModel(); Condition actionCondition = Condition.alwaysTrue(); for (IDetachableFactory<? super IModel<? extends T>, ? extends Condition> conditionFactory : conditionFactories) { actionCondition = actionCondition.and(conditionFactory.create(rowModel)); } link .add( getIconComponent("icon", rendererModel), getLabelComponent("label", rendererModel) ) .add( BootstrapColorBehavior.btn(rendererModel.getColorModel()), new AttributeModifier("title", showTooltipCondition.negate() .then(Models.placeholder()) .elseIf(Condition.predicate(tooltipModel, Predicates2.hasText()).negate(), rendererModel) .otherwise(tooltipModel) ), new ClassAttributeAppender(cssClasses.toString()), actionCondition.thenShow() ); for (Behavior behavior : behaviors) { link.add(behavior); } } protected void decoratePlaceholder(PlaceholderContainer placeholder, IModel<T> rowModel) { IBootstrapRendererModel rendererModel = renderer.asModel(rowModel); placeholder.condition(showPlaceholderCondition.negate()) .add( getIconComponent("icon", rendererModel), getLabelComponent("label", rendererModel) ) .add(new ClassAttributeAppender(cssClasses.toString())); } private Component getIconComponent(String id, IBootstrapRendererModel rendererModel) { IModel<String> iconCssClassModel = rendererModel.getIconCssClassModel(); return new WebMarkupContainer(id) .add(new ClassAttributeAppender(iconCssClassModel)) .add( Condition.predicate(iconCssClassModel, Predicates2.hasText()) .and(showIconCondition) .thenShow() ); } private Component getLabelComponent(String id, IBootstrapRendererModel rendererModel) { return new CoreLabel("label", rendererModel) .add( Condition.predicate(rendererModel, Predicates2.hasText()) .and(showLabelCondition) .thenShow() ); } public BootstrapRenderer<? super T> getRenderer() { return renderer; } public F showLabel() { showLabelCondition = Condition.alwaysTrue(); return thisAsF(); } public F showLabel(Condition showLabelCondition) { this.showLabelCondition = Objects.requireNonNull(showLabelCondition); return thisAsF(); } public F hideLabel() { showLabelCondition = Condition.alwaysFalse(); return thisAsF(); } public F hideLabel(Condition hideLabelCondition) { return showLabel(Objects.requireNonNull(hideLabelCondition).negate()); } public F showTooltip() { showTooltipCondition = Condition.alwaysTrue(); return thisAsF(); } public F showTooltip(Condition showTooltipCondition) { this.showTooltipCondition = Objects.requireNonNull(showTooltipCondition); return thisAsF(); } public F hideTooltip() { showTooltipCondition = Condition.alwaysFalse(); return thisAsF(); } public F hideTooltip(Condition hideTooltipCondition) { return showTooltip(Objects.requireNonNull(hideTooltipCondition).negate()); } public F showIcon() { showIconCondition = Condition.alwaysTrue(); return thisAsF(); } public F showIcon(Condition showIconCondition) { this.showIconCondition = Objects.requireNonNull(showIconCondition); return thisAsF(); } public F hideIcon() { showIconCondition = Condition.alwaysFalse(); return thisAsF(); } public F hideIcon(Condition hideIconCondition) { return showIcon(Objects.requireNonNull(hideIconCondition).negate()); } public F showPlaceholder() { showPlaceholderCondition = Condition.alwaysTrue(); return thisAsF(); } public F showPlaceholder(Condition showPlaceholderCondition) { this.showPlaceholderCondition = Objects.requireNonNull(showPlaceholderCondition); return thisAsF(); } public F hidePlaceholder() { showPlaceholderCondition = Condition.alwaysFalse(); return thisAsF(); } public F hidePlaceholder(Condition hidePlaceholderCondition) { return showPlaceholder(Objects.requireNonNull(hidePlaceholderCondition).negate()); } public F addConditionFactory(IDetachableFactory<? super IModel<? extends T>, ? extends Condition> conditionFactory) { conditionFactories.add(Objects.requireNonNull(conditionFactory)); return thisAsF(); } public F addCssClass(String cssClass) { if (cssClasses.length() > 0) { cssClasses.append(' '); } cssClasses.append(cssClass); return thisAsF(); } public F addBehaviors(Behavior...behaviorsToAdd) { behaviors.addAll(Sets.newHashSet(behaviorsToAdd)); return thisAsF(); } @SuppressWarnings("unchecked") public final F thisAsF() { return (F) this; } @Override public void detach() { Detachables.detach(showLabelCondition, showTooltipCondition, showIconCondition, showPlaceholderCondition); Detachables.detach(conditionFactories); } }