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.behavior.Behavior; import org.apache.wicket.markup.html.link.AbstractLink; import org.apache.wicket.model.IModel; import org.springframework.security.acls.model.Permission; import com.google.common.base.Joiner; import com.google.common.base.Predicate; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import fr.openwide.core.commons.util.binding.AbstractCoreBinding; import fr.openwide.core.jpa.more.business.sort.ISort; import fr.openwide.core.wicket.more.condition.Condition; import fr.openwide.core.wicket.more.link.descriptor.generator.ILinkGenerator; import fr.openwide.core.wicket.more.link.descriptor.mapper.BindingOneParameterLinkDescriptorMapper; import fr.openwide.core.wicket.more.link.descriptor.mapper.ILinkDescriptorMapper; import fr.openwide.core.wicket.more.markup.html.action.IOneParameterAction; import fr.openwide.core.wicket.more.markup.html.action.IOneParameterAjaxAction; import fr.openwide.core.wicket.more.markup.html.bootstrap.label.renderer.BootstrapRenderer; import fr.openwide.core.wicket.more.markup.html.factory.ConditionFactories; import fr.openwide.core.wicket.more.markup.html.factory.IOneParameterComponentFactory; import fr.openwide.core.wicket.more.markup.html.template.js.jquery.plugins.bootstrap.confirm.component.AjaxConfirmLink; import fr.openwide.core.wicket.more.markup.repeater.table.builder.DataTableBuilder; import fr.openwide.core.wicket.more.markup.repeater.table.builder.action.factory.ActionColumnActionFactory; import fr.openwide.core.wicket.more.markup.repeater.table.builder.action.factory.ActionColumnAjaxActionFactory; import fr.openwide.core.wicket.more.markup.repeater.table.builder.action.state.IActionColumnAddedActionState; import fr.openwide.core.wicket.more.markup.repeater.table.builder.action.state.IActionColumnAddedAjaxActionState; import fr.openwide.core.wicket.more.markup.repeater.table.builder.action.state.IActionColumnAddedConfirmActionState; import fr.openwide.core.wicket.more.markup.repeater.table.builder.action.state.IActionColumnAddedElementState; import fr.openwide.core.wicket.more.markup.repeater.table.builder.action.state.IActionColumnAddedLinkState; import fr.openwide.core.wicket.more.markup.repeater.table.builder.action.state.IActionColumnBuildState; import fr.openwide.core.wicket.more.markup.repeater.table.builder.action.state.IActionColumnConfirmActionBuilderStepStart; import fr.openwide.core.wicket.more.markup.repeater.table.builder.state.IAddedCoreColumnState; import fr.openwide.core.wicket.more.markup.repeater.table.column.CoreActionColumn; public class ActionColumnBuilder<T, S extends ISort<?>> implements IActionColumnBuildState<T, S> { private final DataTableBuilder<T, S> dataTableBuilder; private final IModel<String> headerLabelModel; private final Set<String> cssClassesOnElements = Sets.newHashSet(); private final List<AbstractActionColumnElementBuilder<T, ?, ?>> builders = Lists.newArrayList(); public ActionColumnBuilder(DataTableBuilder<T, S> dataTableBuilder, IModel<String> headerLabelModel) { this.dataTableBuilder = dataTableBuilder; this.headerLabelModel = headerLabelModel; } private abstract class ActionColumnBuilderWrapper implements IActionColumnBuildState<T, S> { @Override public IActionColumnAddedLinkState<T, S> addLink(BootstrapRenderer<? super T> renderer, ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<T>> mapper) { return ActionColumnBuilder.this.addLink(renderer, mapper); } @Override public <C> IActionColumnAddedLinkState<T, S> addLink(BootstrapRenderer<? super T> renderer, AbstractCoreBinding<? super T, C> binding, ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<C>> mapper) { return ActionColumnBuilder.this.addLink(renderer, binding, mapper); } @Override public IActionColumnAddedLinkState<T, S> addLabelledLink(BootstrapRenderer<? super T> renderer, ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<T>> mapper) { return ActionColumnBuilder.this.addLabelledLink(renderer, mapper); } @Override public <C> IActionColumnAddedLinkState<T, S> addLabelledLink(BootstrapRenderer<? super T> renderer, AbstractCoreBinding<? super T, C> binding, ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<C>> mapper) { return ActionColumnBuilder.this.addLabelledLink(renderer, binding, mapper); } @Override public IActionColumnAddedAjaxActionState<T, S> addAction(BootstrapRenderer<? super T> renderer, IOneParameterAjaxAction<? super IModel<T>> action) { return ActionColumnBuilder.this.addAction(renderer, action); } @Override public IActionColumnAddedAjaxActionState<T, S> addLabelledAction(BootstrapRenderer<? super T> renderer, IOneParameterAjaxAction<? super IModel<T>> action) { return ActionColumnBuilder.this.addLabelledAction(renderer, action); } @Override public IActionColumnAddedActionState<T, S> addAction(BootstrapRenderer<? super T> renderer, IOneParameterAction<? super IModel<T>> action) { return ActionColumnBuilder.this.addAction(renderer, action); } @Override public IActionColumnAddedActionState<T, S> addLabelledAction(BootstrapRenderer<? super T> renderer, IOneParameterAction<? super IModel<T>> action) { return ActionColumnBuilder.this.addLabelledAction(renderer, action); } @Override public IActionColumnConfirmActionBuilderStepStart<T, S> addConfirmAction(BootstrapRenderer<? super T> renderer) { return ActionColumnBuilder.this.addConfirmAction(renderer); } @Override public IActionColumnAddedActionState<T, S> addAction(BootstrapRenderer<? super T> renderer, IOneParameterComponentFactory<? extends AbstractLink, IModel<T>> factory) { return ActionColumnBuilder.this.addAction(renderer, factory); } @Override public IActionColumnAddedActionState<T, S> addLabelledAction(BootstrapRenderer<? super T> renderer, IOneParameterComponentFactory<? extends AbstractLink, IModel<T>> factory) { return ActionColumnBuilder.this.addLabelledAction(renderer, factory); } @Override public IActionColumnBuildState<T, S> withClassOnElements(String cssClassOnElements) { return ActionColumnBuilder.this.withClassOnElements(cssClassOnElements); } @Override public IAddedCoreColumnState<T, S> end() { return ActionColumnBuilder.this.end(); } } private abstract class ActionColumnAddedElementState<NextState extends IActionColumnAddedElementState<T, S>> extends ActionColumnBuilderWrapper implements IActionColumnAddedElementState<T, S> { protected abstract NextState getNextState(); protected abstract AbstractActionColumnElementBuilder<T, ?, ?> getElementBuilder(); @Override public NextState showLabel() { getElementBuilder().showLabel(); return getNextState(); } @Override public NextState showLabel(Condition showLabelCondition) { getElementBuilder().showLabel(showLabelCondition); return getNextState(); } @Override public NextState hideLabel() { getElementBuilder().hideLabel(); return getNextState(); } @Override public NextState hideLabel(Condition hideLabelCondition) { getElementBuilder().hideLabel(hideLabelCondition); return getNextState(); } @Override public NextState showTooltip() { getElementBuilder().showTooltip(); return getNextState(); } @Override public NextState showTooltip(Condition showTooltipCondition) { getElementBuilder().showTooltip(showTooltipCondition); return getNextState(); } @Override public NextState hideTooltip() { getElementBuilder().hideTooltip(); return getNextState(); } @Override public NextState hideTooltip(Condition hideTooltipCondition) { getElementBuilder().hideTooltip(hideTooltipCondition); return getNextState(); } @Override public NextState showIcon() { getElementBuilder().showIcon(); return getNextState(); } @Override public NextState showIcon(Condition showIconCondition) { getElementBuilder().showIcon(showIconCondition); return getNextState(); } @Override public NextState hideIcon() { getElementBuilder().hideIcon(); return getNextState(); } @Override public NextState hideIcon(Condition hideIconCondition) { getElementBuilder().hideIcon(hideIconCondition); return getNextState(); } @Override public NextState showPlaceholder() { getElementBuilder().showPlaceholder(); return getNextState(); } @Override public NextState showPlaceholder(Condition showPlaceholderCondition) { getElementBuilder().showPlaceholder(showPlaceholderCondition); return getNextState(); } @Override public NextState hidePlaceholder() { getElementBuilder().hidePlaceholder(); return getNextState(); } @Override public NextState hidePlaceholder(Condition hidePlaceholderCondition) { getElementBuilder().hidePlaceholder(hidePlaceholderCondition); return getNextState(); } @Override public NextState when(final Condition condition) { getElementBuilder().addConditionFactory(ConditionFactories.constant(condition)); return getNextState(); } @Override public NextState when(final Predicate<? super T> predicate) { getElementBuilder().addConditionFactory(ConditionFactories.predicate(predicate)); return getNextState(); } @Override public NextState whenPermission(final String permission) { getElementBuilder().addConditionFactory(ConditionFactories.<T>permission(permission)); return getNextState(); } @Override public NextState whenPermission(final Permission permission) { getElementBuilder().addConditionFactory(ConditionFactories.<T>permission(permission)); return getNextState(); } @Override public NextState withClass(String cssClass) { getElementBuilder().addCssClass(cssClass); return getNextState(); } @Override public NextState add(Behavior...behaviors) { getElementBuilder().addBehaviors(behaviors); return getNextState(); } } private class ActionColumnAddedLinkState extends ActionColumnAddedElementState<IActionColumnAddedLinkState<T, S>> implements IActionColumnAddedLinkState<T, S> { private final ActionColumnLinkBuilder<T> elementBuilder; public ActionColumnAddedLinkState(ActionColumnLinkBuilder<T> elementBuilder) { super(); this.elementBuilder = Objects.requireNonNull(elementBuilder); } @Override public ActionColumnLinkBuilder<T> getElementBuilder() { return elementBuilder; } @Override protected IActionColumnAddedLinkState<T, S> getNextState() { return this; } @Override public IActionColumnAddedLinkState<T, S> hideIfInvalid() { getElementBuilder().hideIfInvalid(); return getNextState(); } } private class ActionColumnAddedAjaxActionState extends ActionColumnAddedElementState<IActionColumnAddedAjaxActionState<T, S>> implements IActionColumnAddedAjaxActionState<T, S> { private final AbstractActionColumnElementBuilder<T, ?, ?> elementBuilder; public ActionColumnAddedAjaxActionState(AbstractActionColumnElementBuilder<T, ?, ?> elementBuilder) { super(); this.elementBuilder = Objects.requireNonNull(elementBuilder); } @Override public AbstractActionColumnElementBuilder<T, ?, ?> getElementBuilder() { return elementBuilder; } @Override protected IActionColumnAddedAjaxActionState<T, S> getNextState() { return this; } } private class ActionColumnAddedActionState extends ActionColumnAddedElementState<IActionColumnAddedActionState<T, S>> implements IActionColumnAddedActionState<T, S> { private final AbstractActionColumnElementBuilder<T, ?, ?> elementBuilder; public ActionColumnAddedActionState(AbstractActionColumnElementBuilder<T, ?, ?> elementBuilder) { super(); this.elementBuilder = Objects.requireNonNull(elementBuilder); } @Override public AbstractActionColumnElementBuilder<T, ?, ?> getElementBuilder() { return elementBuilder; } @Override protected IActionColumnAddedActionState<T, S> getNextState() { return this; } } private class ActionColumnAddedConfirmActionState extends ActionColumnAddedElementState<IActionColumnAddedConfirmActionState<T, S>> implements IActionColumnAddedConfirmActionState<T, S> { private final AbstractActionColumnElementBuilder<T, ?, ?> elementBuilder; public ActionColumnAddedConfirmActionState(AbstractActionColumnElementBuilder<T, ?, ?> elementBuilder) { super(); this.elementBuilder = Objects.requireNonNull(elementBuilder); } @Override public AbstractActionColumnElementBuilder<T, ?, ?> getElementBuilder() { return elementBuilder; } @Override protected IActionColumnAddedConfirmActionState<T, S> getNextState() { return this; } } @Override public IActionColumnAddedLinkState<T, S> addLink(BootstrapRenderer<? super T> renderer, ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<T>> mapper) { ActionColumnLinkBuilder<T> factory = new ActionColumnLinkBuilder<>(renderer, mapper); builders.add(factory); return new ActionColumnAddedLinkState(factory); } @Override public <C> IActionColumnAddedLinkState<T, S> addLink(BootstrapRenderer<? super T> renderer, AbstractCoreBinding<? super T, C> binding, ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<C>> mapper) { return addLink(renderer, new BindingOneParameterLinkDescriptorMapper<>(binding, mapper)); } @Override public IActionColumnAddedLinkState<T, S> addLabelledLink(BootstrapRenderer<? super T> renderer, ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<T>> mapper) { return addLink(renderer, mapper).showLabel(); } @Override public <C> IActionColumnAddedLinkState<T, S> addLabelledLink(BootstrapRenderer<? super T> renderer, AbstractCoreBinding<? super T, C> binding, ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<C>> mapper) { return addLabelledLink(renderer, new BindingOneParameterLinkDescriptorMapper<>(binding, mapper)); } @Override public IActionColumnAddedAjaxActionState<T, S> addAction(BootstrapRenderer<? super T> renderer, IOneParameterAjaxAction<? super IModel<T>> action) { AbstractActionColumnElementBuilder<T, ?, ?> builder = new ActionColumnSimpleElementBuilder<>(renderer, new ActionColumnAjaxActionFactory<T>(action)); builders.add(builder); return new ActionColumnAddedAjaxActionState(builder); } @Override public IActionColumnAddedAjaxActionState<T, S> addLabelledAction(BootstrapRenderer<? super T> renderer, IOneParameterAjaxAction<? super IModel<T>> action) { return addAction(renderer, action).showLabel(); } @Override public IActionColumnAddedActionState<T, S> addAction(BootstrapRenderer<? super T> renderer, IOneParameterAction<? super IModel<T>> action) { return addAction(renderer, new ActionColumnActionFactory<T>(action)); } @Override public IActionColumnAddedActionState<T, S> addLabelledAction(BootstrapRenderer<? super T> renderer, IOneParameterAction<? super IModel<T>> action) { return addAction(renderer, action).showLabel(); } @Override public IActionColumnConfirmActionBuilderStepStart<T, S> addConfirmAction(BootstrapRenderer<? super T> renderer) { return new ActionColumnConfirmActionBuilder<>(this, renderer); } public IActionColumnAddedConfirmActionState<T, S> addConfirmAction(BootstrapRenderer<? super T> renderer, IOneParameterComponentFactory<AjaxConfirmLink<T>, IModel<T>> ajaxConfirmLinkFactory) { AbstractActionColumnElementBuilder<T, ?, ?> builder = new ActionColumnSimpleElementBuilder<>(renderer, ajaxConfirmLinkFactory); builders.add(builder); return new ActionColumnAddedConfirmActionState(builder); } @Override public IActionColumnAddedActionState<T, S> addAction(BootstrapRenderer<? super T> renderer, IOneParameterComponentFactory<? extends AbstractLink, IModel<T>> factory) { AbstractActionColumnElementBuilder<T, ?, ?> builder = new ActionColumnSimpleElementBuilder<>(renderer, factory); builders.add(builder); return new ActionColumnAddedActionState(builder); } @Override public IActionColumnAddedActionState<T, S> addLabelledAction(BootstrapRenderer<? super T> renderer, IOneParameterComponentFactory<? extends AbstractLink, IModel<T>> factory) { return addAction(renderer, factory).showLabel(); } @Override public IActionColumnBuildState<T, S> withClassOnElements(String cssClassOnElements) { cssClassesOnElements.add(cssClassOnElements); return this; } public String getCssClassOnElements() { return Joiner.on(" ").join(cssClassesOnElements); } @Override public IAddedCoreColumnState<T, S> end() { for (AbstractActionColumnElementBuilder<T, ?, ?> builder : builders) { builder.addCssClass(getCssClassOnElements()); } return dataTableBuilder.addActionColumn(new CoreActionColumn<T, S>(headerLabelModel, builders)); } }