package fr.openwide.core.wicket.more.markup.repeater.table.builder.toolbar; import java.util.List; import org.apache.wicket.Component; import org.apache.wicket.model.IModel; import com.google.common.collect.FluentIterable; import com.google.common.collect.Lists; import fr.openwide.core.jpa.more.business.sort.ISort; 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.factory.AbstractParameterizedComponentFactory; import fr.openwide.core.wicket.more.markup.html.factory.IOneParameterComponentFactory; import fr.openwide.core.wicket.more.markup.repeater.table.CoreDataTable; import fr.openwide.core.wicket.more.markup.repeater.table.builder.DataTableBuilder; import fr.openwide.core.wicket.more.markup.repeater.table.builder.toolbar.state.IAddedToolbarCoreElementState; import fr.openwide.core.wicket.more.markup.repeater.table.builder.toolbar.state.IAddedToolbarElementState; import fr.openwide.core.wicket.more.markup.repeater.table.builder.toolbar.state.IAddedToolbarLabelElementState; import fr.openwide.core.wicket.more.markup.repeater.table.builder.toolbar.state.IToolbarElementState; import fr.openwide.core.wicket.more.markup.repeater.table.toolbar.CoreCustomizableToolbar; import fr.openwide.core.wicket.more.util.model.Detachables; public class CustomizableToolbarBuilder<T, S extends ISort<?>> implements IToolbarElementState<T, S> { private final DataTableBuilder<T, S> dataTableBuilder; private final List<CustomizableToolbarElementBuilder<T, S>> builders = Lists.newArrayList(); private boolean hideIfEmpty = false; public CustomizableToolbarBuilder(DataTableBuilder<T, S> dataTableBuilder) { super(); this.dataTableBuilder = dataTableBuilder; } private abstract class CustomizableToolbarBuilderWrapper implements IToolbarElementState<T, S> { @Override public IAddedToolbarLabelElementState<T, S> addLabel(IModel<String> model) { return CustomizableToolbarBuilder.this.addLabel(model); } @Override public IAddedToolbarCoreElementState<T, S> addComponent(IOneParameterComponentFactory<Component, CoreDataTable<T, S>> delegateFactory) { return CustomizableToolbarBuilder.this.addComponent(delegateFactory); } @Override public IToolbarElementState<T, S> hideIfEmpty() { return CustomizableToolbarBuilder.this.hideIfEmpty(); } @Override public DataTableBuilder<T, S> end() { return CustomizableToolbarBuilder.this.end(); } } private abstract class AddedToolbarElementState<NextState extends IAddedToolbarElementState<T, S>> extends CustomizableToolbarBuilderWrapper implements IAddedToolbarElementState<T, S> { protected abstract CustomizableToolbarElementBuilder<T, S> getFactory(); protected abstract NextState getNextState(); @Override public NextState when(Condition condition) { getFactory().when(condition); return getNextState(); } @Override public NextState withClass(String cssClass) { getFactory().withClass(cssClass); return getNextState(); } @Override public NextState colspan(Integer colspan) { getFactory().colspan(colspan); return getNextState(); } @Override public NextState full() { getFactory().full(); return getNextState(); } } private class AddedToolbarLabelElementState extends AddedToolbarElementState<IAddedToolbarLabelElementState<T, S>> implements IAddedToolbarLabelElementState<T, S> { private final CustomizableToolbarElementBuilder<T, S> factory; public AddedToolbarLabelElementState(CustomizableToolbarElementBuilder<T, S> factory) { super(); this.factory = factory; } @Override protected CustomizableToolbarElementBuilder<T, S> getFactory() { return factory; } @Override protected IAddedToolbarLabelElementState<T, S> getNextState() { return this; } } private class AddedToolbarLabelCoreElementState extends AddedToolbarElementState<IAddedToolbarCoreElementState<T, S>> implements IAddedToolbarCoreElementState<T, S> { private final CustomizableToolbarElementBuilder<T, S> elementBuilder; public AddedToolbarLabelCoreElementState(CustomizableToolbarElementBuilder<T, S> elementBuilder) { super(); this.elementBuilder = elementBuilder; } @Override protected CustomizableToolbarElementBuilder<T, S> getFactory() { return elementBuilder; } @Override protected IAddedToolbarCoreElementState<T, S> getNextState() { return this; } } @Override public IAddedToolbarLabelElementState<T, S> addLabel(final IModel<String> model) { CustomizableToolbarElementBuilder<T, S> elementBuilder = new CustomizableToolbarElementBuilder<T, S>( getPreviousColspan(builders.size()), new CustomizableToolbarLabelElementDelegateFactory<T, S>(model) ); builders.add(elementBuilder); return new AddedToolbarLabelElementState(elementBuilder); } public static class CustomizableToolbarLabelElementDelegateFactory<T, S extends ISort<?>> extends AbstractParameterizedComponentFactory<Component, CoreDataTable<T, S>> { private static final long serialVersionUID = 1L; private final IModel<String> model; public CustomizableToolbarLabelElementDelegateFactory(IModel<String> model) { super(); this.model = model; } @Override public Component create(String wicketId, CoreDataTable<T, S> parameter) { return new CoreLabel(wicketId, model); } @Override public void detach() { super.detach(); Detachables.detach(model); } } @Override public IAddedToolbarCoreElementState<T, S> addComponent(IOneParameterComponentFactory<Component, CoreDataTable<T, S>> delegateFactory) { CustomizableToolbarElementBuilder<T, S> elementBuilder = new CustomizableToolbarElementBuilder<T, S>( getPreviousColspan(builders.size()), delegateFactory ); builders.add(elementBuilder); return new AddedToolbarLabelCoreElementState(elementBuilder); } @Override public IToolbarElementState<T, S> hideIfEmpty() { this.hideIfEmpty = true; return this; } @Override public DataTableBuilder<T, S> end() { return dataTableBuilder; } public CoreCustomizableToolbar<T, S> build(final CoreDataTable<T, S> table) { CoreCustomizableToolbar<T, S> component = new CoreCustomizableToolbar<T, S>(table, builders); if (hideIfEmpty) { component.add( Condition.isNotEmpty(table.getSequenceProvider()).thenShow() ); } return component; } private Integer getPreviousColspan(final int currentIndex) { Integer previousColspan = 0; if (builders.isEmpty()) { return previousColspan; } for (CustomizableToolbarElementBuilder<T, S> builder : FluentIterable.from(builders).limit(currentIndex)) { if (builder.getColspan() == null) { previousColspan = null; break; } previousColspan = previousColspan + builder.getColspan(); } return previousColspan; } }