package fr.openwide.core.wicket.more.markup.repeater.table.builder;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.wicket.Component;
import org.apache.wicket.behavior.Behavior;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.markup.repeater.data.IDataProvider;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
import com.google.common.base.Function;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import fr.openwide.core.commons.util.binding.AbstractCoreBinding;
import fr.openwide.core.jpa.more.business.sort.ISort;
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.link.descriptor.factory.LinkGeneratorFactory;
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.FunctionOneParameterLinkDescriptorMapper;
import fr.openwide.core.wicket.more.link.descriptor.mapper.ILinkDescriptorMapper;
import fr.openwide.core.wicket.more.link.descriptor.mapper.LinkGeneratorFactoryToOneParameterLinkDescriptorMapperAdapter;
import fr.openwide.core.wicket.more.markup.html.basic.TargetBlankBehavior;
import fr.openwide.core.wicket.more.markup.html.bootstrap.label.renderer.BootstrapRenderer;
import fr.openwide.core.wicket.more.markup.html.factory.AbstractDecoratingParameterizedComponentFactory;
import fr.openwide.core.wicket.more.markup.html.factory.ComponentFactories;
import fr.openwide.core.wicket.more.markup.html.factory.IComponentFactory;
import fr.openwide.core.wicket.more.markup.html.factory.IOneParameterComponentFactory;
import fr.openwide.core.wicket.more.markup.html.sort.ISortIconStyle;
import fr.openwide.core.wicket.more.markup.html.sort.SortIconStyle;
import fr.openwide.core.wicket.more.markup.html.sort.TableSortLink.CycleMode;
import fr.openwide.core.wicket.more.markup.html.sort.model.CompositeSortModel;
import fr.openwide.core.wicket.more.markup.html.sort.model.CompositeSortModel.CompositingStrategy;
import fr.openwide.core.wicket.more.markup.repeater.sequence.ISequenceProvider;
import fr.openwide.core.wicket.more.markup.repeater.table.BootstrapPanelCoreDataTablePanel;
import fr.openwide.core.wicket.more.markup.repeater.table.CoreDataTable;
import fr.openwide.core.wicket.more.markup.repeater.table.DecoratedCoreDataTablePanel;
import fr.openwide.core.wicket.more.markup.repeater.table.DecoratedCoreDataTablePanel.AddInPlacement;
import fr.openwide.core.wicket.more.markup.repeater.table.DecoratedCoreDataTablePanel.AjaxPagerAddInComponentFactory;
import fr.openwide.core.wicket.more.markup.repeater.table.DecoratedCoreDataTablePanel.CountAddInComponentFactory;
import fr.openwide.core.wicket.more.markup.repeater.table.DecoratedCoreDataTablePanel.LabelAddInComponentFactory;
import fr.openwide.core.wicket.more.markup.repeater.table.DecoratedCoreDataTablePanel.PagerAddInComponentFactory;
import fr.openwide.core.wicket.more.markup.repeater.table.builder.action.ActionColumnBuilder;
import fr.openwide.core.wicket.more.markup.repeater.table.builder.state.IAddedBooleanLabelColumnState;
import fr.openwide.core.wicket.more.markup.repeater.table.builder.state.IAddedBootstrapBadgeColumnState;
import fr.openwide.core.wicket.more.markup.repeater.table.builder.state.IAddedColumnState;
import fr.openwide.core.wicket.more.markup.repeater.table.builder.state.IAddedCoreColumnState;
import fr.openwide.core.wicket.more.markup.repeater.table.builder.state.IAddedLabelColumnState;
import fr.openwide.core.wicket.more.markup.repeater.table.builder.state.IBuildState;
import fr.openwide.core.wicket.more.markup.repeater.table.builder.state.IColumnState;
import fr.openwide.core.wicket.more.markup.repeater.table.builder.state.IDecoratedBuildState;
import fr.openwide.core.wicket.more.markup.repeater.table.builder.toolbar.CustomizableToolbarBuilder;
import fr.openwide.core.wicket.more.markup.repeater.table.column.CoreActionColumn;
import fr.openwide.core.wicket.more.markup.repeater.table.column.CoreBooleanLabelColumn;
import fr.openwide.core.wicket.more.markup.repeater.table.column.CoreBootstrapBadgeColumn;
import fr.openwide.core.wicket.more.markup.repeater.table.column.CoreBootstrapLabelColumn;
import fr.openwide.core.wicket.more.markup.repeater.table.column.CoreLabelColumn;
import fr.openwide.core.wicket.more.markup.repeater.table.column.ICoreColumn;
import fr.openwide.core.wicket.more.markup.repeater.table.toolbar.CoreHeadersToolbar;
import fr.openwide.core.wicket.more.markup.repeater.table.toolbar.CoreNoRecordsToolbar;
import fr.openwide.core.wicket.more.model.BindingModel;
import fr.openwide.core.wicket.more.model.ReadOnlyModel;
import fr.openwide.core.wicket.more.rendering.Renderer;
import fr.openwide.core.wicket.more.util.IDatePattern;
import fr.openwide.core.wicket.more.util.model.SequenceProviders;
public final class DataTableBuilder<T, S extends ISort<?>> implements IColumnState<T, S> {
private final ISequenceProvider<T> sequenceProvider;
private final CompositeSortModel<S> sortModel;
private final Map<IColumn<T, S>, Condition> columns = Maps.newLinkedHashMap();
private String noRecordsResourceKey;
private final List<CustomizableToolbarBuilder<T, S>> topToolbarBuilders = Lists.newArrayList();
private final List<CustomizableToolbarBuilder<T, S>> bottomToolbarBuilders = Lists.newArrayList();
private boolean showTopToolbar = true;
private boolean showBottomToolbar = true;
private IDataTableFactory<T, S> factory = new IDataTableFactory<T, S>() {
private static final long serialVersionUID = 1L;
@Override
public CoreDataTable<T, S> create(String id, Map<IColumn<T, S>, Condition> columns, ISequenceProvider<T> sequenceProvider, long rowsPerPage) {
return new CoreDataTable<T, S>(id, columns, sequenceProvider, rowsPerPage);
}
};
private DataTableBuilder(ISequenceProvider<T> sequenceProvider, CompositeSortModel<S> sortModel) {
super();
this.sequenceProvider = sequenceProvider;
this.sortModel = sortModel;
}
public static <T, S extends ISort<?>> DataTableBuilder<T, S> start(IDataProvider<T> dataProvider) {
return start(SequenceProviders.forDataProvider(dataProvider));
}
public static <T, S extends ISort<?>> DataTableBuilder<T, S> start(IDataProvider<T> dataProvider, CompositeSortModel<S> sortModel) {
return start(SequenceProviders.forDataProvider(dataProvider), sortModel);
}
public static <T, S extends ISort<?>> DataTableBuilder<T, S> start(ISequenceProvider<T> sequenceProvider) {
return new DataTableBuilder<T, S>(sequenceProvider, new CompositeSortModel<S>(CompositingStrategy.LAST_ONLY));
}
public static <T, S extends ISort<?>> DataTableBuilder<T, S> start(ISequenceProvider<T> sequenceProvider, CompositeSortModel<S> sortModel) {
return new DataTableBuilder<T, S>(sequenceProvider, sortModel);
}
@Override
public IAddedColumnState<T, S> addColumn(final IColumn<T, S> column) {
columns.put(column, null);
return new AddedColumnState<IAddedColumnState<T, S>>() {
@Override
protected IColumn<T, S> getColumn() {
return column;
}
@Override
protected IAddedColumnState<T, S> getNextState() {
return this;
}
};
}
@Override
public IAddedCoreColumnState<T, S> addColumn(final ICoreColumn<T, S> column) {
columns.put(column, null);
return new AddedCoreColumnState<IAddedCoreColumnState<T, S>>() {
@Override
protected ICoreColumn<T, S> getColumn() {
return column;
}
@Override
protected IAddedCoreColumnState<T, S> getNextState() {
return this;
}
};
}
protected IAddedLabelColumnState<T, S> addLabelColumn(CoreLabelColumn<T, S> column) {
columns.put(column, null);
return new AddedLabelColumnState(column);
}
@Override
public IAddedLabelColumnState<T, S> addLabelColumn(IModel<String> headerModel) {
return addLabelColumn(new SimpleLabelColumn<T, S>(headerModel));
}
private static class SimpleLabelColumn<T, S extends ISort<?>> extends CoreLabelColumn<T, S> {
private static final long serialVersionUID = 1L;
public SimpleLabelColumn(IModel<String> headerLabelModel) {
super(headerLabelModel);
}
@Override
protected CoreLabel newLabel(String componentId, IModel<T> rowModel) {
return new CoreLabel(componentId, rowModel);
}
}
@Override
public IAddedLabelColumnState<T, S> addLabelColumn(IModel<String> headerModel, final Renderer<? super T> renderer) {
return addLabelColumn(new RendererLabelColumn<T, S>(headerModel, renderer));
}
private static class RendererLabelColumn<T, S extends ISort<?>> extends CoreLabelColumn<T, S> {
private static final long serialVersionUID = 1L;
private final Renderer<? super T> renderer;
public RendererLabelColumn(IModel<String> displayModel, Renderer<? super T> renderer) {
super(displayModel);
this.renderer = renderer;
}
@Override
protected CoreLabel newLabel(String componentId, IModel<T> rowModel) {
return new CoreLabel(componentId, renderer.asModel(rowModel));
}
}
@Override
public <C> IAddedLabelColumnState<T, S> addLabelColumn(IModel<String> headerModel, final Function<? super T, C> function) {
return addLabelColumn(new FunctionLabelColumn<T, S, C>(headerModel, function));
}
private static class FunctionLabelColumn<T, S extends ISort<?>, C> extends CoreLabelColumn<T, S> {
private static final long serialVersionUID = 1L;
private final Function<? super T, C> function;
public FunctionLabelColumn(IModel<String> displayModel, Function<? super T, C> function) {
super(displayModel);
this.function = function;
}
@Override
protected CoreLabel newLabel(String componentId, IModel<T> rowModel) {
return new CoreLabel(componentId, ReadOnlyModel.of(rowModel, function));
}
}
@Override
public <C> IAddedLabelColumnState<T, S> addLabelColumn(IModel<String> headerModel,
final Function<? super T, C> function, final Renderer<? super C> renderer) {
return addLabelColumn(new FunctionRendererLabelColumn<T, S, C>(headerModel, function, renderer));
}
private static class FunctionRendererLabelColumn<T, S extends ISort<?>, C> extends CoreLabelColumn<T, S> {
private static final long serialVersionUID = 1L;
private final Function<? super T, C> function;
private final Renderer<? super C> renderer;
public FunctionRendererLabelColumn(IModel<String> displayModel, Function<? super T, C> function, Renderer<? super C> renderer) {
super(displayModel);
this.function = function;
this.renderer = renderer;
}
@Override
protected CoreLabel newLabel(String componentId, IModel<T> rowModel) {
return new CoreLabel(componentId, renderer.asModel(ReadOnlyModel.of(rowModel, function)));
}
}
@Override
public <C> IAddedLabelColumnState<T, S> addLabelColumn(IModel<String> headerModel, final AbstractCoreBinding<? super T, C> binding) {
return addLabelColumn(new BindingLabelColumn<T, S, C>(headerModel, binding));
}
private static class BindingLabelColumn<T, S extends ISort<?>, C> extends CoreLabelColumn<T, S> {
private static final long serialVersionUID = 1L;
private final AbstractCoreBinding<? super T, C> binding;
public BindingLabelColumn(IModel<String> displayModel, AbstractCoreBinding<? super T, C> binding) {
super(displayModel);
this.binding = binding;
}
@Override
protected CoreLabel newLabel(String componentId, IModel<T> rowModel) {
return new CoreLabel(componentId, BindingModel.of(rowModel, binding));
}
}
@Override
public <C> IAddedLabelColumnState<T, S> addLabelColumn(IModel<String> headerModel,
final AbstractCoreBinding<? super T, C> binding, final Renderer<? super C> renderer) {
return addLabelColumn(new BindingRendererLabelColumn<T, S, C>(headerModel, binding, renderer));
}
private static class BindingRendererLabelColumn<T, S extends ISort<?>, C> extends CoreLabelColumn<T, S> {
private static final long serialVersionUID = 1L;
private final AbstractCoreBinding<? super T, C> binding;
private final Renderer<? super C> renderer;
public BindingRendererLabelColumn(IModel<String> displayModel, AbstractCoreBinding<? super T, C> binding, Renderer<? super C> renderer) {
super(displayModel);
this.binding = binding;
this.renderer = renderer;
}
@Override
protected CoreLabel newLabel(String componentId, IModel<T> rowModel) {
return new CoreLabel(componentId, renderer.asModel(BindingModel.of(rowModel, binding)));
}
}
@Override
public IAddedLabelColumnState<T, S> addLabelColumn(IModel<String> headerModel,
AbstractCoreBinding<? super T, ? extends Date> binding, IDatePattern datePattern) {
return addLabelColumn(headerModel, binding, Renderer.fromDatePattern(datePattern));
}
@Override
public <C> IAddedCoreColumnState<T, S> addBootstrapLabelColumn(IModel<String> headerModel,
final AbstractCoreBinding<? super T, C> binding, final BootstrapRenderer<? super C> renderer) {
return addColumn(new CoreBootstrapLabelColumn<T, S, C>(headerModel, binding, renderer));
}
@Override
public <C> IAddedCoreColumnState<T, S> addBootstrapLabelColumn(IModel<String> headerModel,
Function<? super T, C> function, BootstrapRenderer<? super C> renderer) {
return addColumn(new CoreBootstrapLabelColumn<T, S, C>(headerModel, function, renderer));
}
@Override
public <C> IAddedBootstrapBadgeColumnState<T, S, C> addBootstrapBadgeColumn(IModel<String> headerModel,
final AbstractCoreBinding<? super T, C> binding, final BootstrapRenderer<? super C> renderer) {
CoreBootstrapBadgeColumn<T, S, C> column = new CoreBootstrapBadgeColumn<T, S, C>(headerModel, binding, renderer);
columns.put(column, null);
return new AddedBootstrapBadgeColumnState<C>(column);
}
@Override
public <C> IAddedBootstrapBadgeColumnState<T, S, C> addBootstrapBadgeColumn(IModel<String> headerModel,
Function<? super T, C> function, BootstrapRenderer<? super C> renderer) {
CoreBootstrapBadgeColumn<T, S, C> column = new CoreBootstrapBadgeColumn<T, S, C>(headerModel, function, renderer);
columns.put(column, null);
return new AddedBootstrapBadgeColumnState<C>(column);
}
@Override
public <C> IAddedBooleanLabelColumnState<T, S> addBooleanLabelColumn(IModel<String> headerModel,
final AbstractCoreBinding<? super T, Boolean> binding) {
CoreBooleanLabelColumn<T, S> column = new CoreBooleanLabelColumn<T, S>(headerModel, binding);
columns.put(column, null);
return new AddedBooleanLabelColumnState(column);
}
@Override
public CustomizableToolbarBuilder<T, S> addTopToolbar() {
CustomizableToolbarBuilder<T, S> builder = new CustomizableToolbarBuilder<T, S>(this);
topToolbarBuilders.add(builder);
return builder;
}
@Override
public CustomizableToolbarBuilder<T, S> addBottomToolbar() {
CustomizableToolbarBuilder<T, S> builder = new CustomizableToolbarBuilder<T, S>(this);
bottomToolbarBuilders.add(builder);
return builder;
}
@Override
public ActionColumnBuilder<T, S> addActionColumn() {
return addActionColumn(Model.of(""));
}
@Override
public ActionColumnBuilder<T, S> addActionColumn(IModel<String> headerLabelModel) {
ActionColumnBuilder<T, S> builder = new ActionColumnBuilder<T, S>(this, headerLabelModel);
return builder;
}
public IAddedCoreColumnState<T, S> addActionColumn(final CoreActionColumn<T, S> column) {
columns.put(column, null);
return new AddedCoreColumnState<IAddedCoreColumnState<T, S>>() {
@Override
protected ICoreColumn<T, S> getColumn() {
return column;
}
@Override
protected IAddedCoreColumnState<T, S> getNextState() {
return this;
}
};
}
@Override
public DataTableBuilder<T, S> withNoRecordsResourceKey(String noRecordsResourceKey) {
this.noRecordsResourceKey = noRecordsResourceKey;
return this;
}
@Override
public DataTableBuilder<T, S> hideHeadersToolbar() {
showTopToolbar = false;
return this;
}
@Override
@Deprecated
public DataTableBuilder<T, S> hideTopToolbar() {
return hideHeadersToolbar();
}
@Override
public DataTableBuilder<T, S> hideNoRecordsToolbar() {
showBottomToolbar = false;
return this;
}
@Override
@Deprecated
public DataTableBuilder<T, S> hideBottomToolbar() {
return hideNoRecordsToolbar();
}
@Override
public IBuildState<T, S> withFactory(IDataTableFactory<T, S> factory) {
this.factory = factory;
return this;
}
@Override
public CoreDataTable<T, S> build(String id) {
return build(id, Long.MAX_VALUE);
}
@Override
public CoreDataTable<T, S> build(String id, long rowsPerPage) {
CoreDataTable<T, S> dataTable = factory.create(id, columns, sequenceProvider, rowsPerPage);
finalizeBuild(dataTable);
return dataTable;
}
protected void finalizeBuild(CoreDataTable<T, S> dataTable) {
if (showTopToolbar) {
for (CustomizableToolbarBuilder<T, S> builder : topToolbarBuilders) {
dataTable.addTopToolbar(builder.build(dataTable));
}
dataTable.addTopToolbar(new CoreHeadersToolbar<S>(dataTable, sortModel));
}
if (showBottomToolbar) {
dataTable.addBodyBottomToolbar(new CoreNoRecordsToolbar(dataTable, new ResourceModel(noRecordsResourceKey != null ? noRecordsResourceKey : "common.emptyList")));
for (CustomizableToolbarBuilder<T, S> builder : bottomToolbarBuilders) {
dataTable.addBottomToolbar(builder.build(dataTable));
}
}
}
@Override
public IDecoratedBuildState<T, S> decorate() {
return new DecoratedBuildState();
}
@Override
public IDecoratedBuildState<T, S> bootstrapPanel() {
return new BootstrapPanelBuildState();
}
private abstract class DataTableBuilderWrapper implements IColumnState<T, S> {
@Override
public IAddedColumnState<T, S> addColumn(IColumn<T, S> column) {
return DataTableBuilder.this.addColumn(column);
}
@Override
public IAddedCoreColumnState<T, S> addColumn(ICoreColumn<T, S> column) {
return DataTableBuilder.this.addColumn(column);
}
@Override
public IAddedLabelColumnState<T, S> addLabelColumn(IModel<String> headerModel) {
return DataTableBuilder.this.addLabelColumn(headerModel);
}
@Override
public IAddedLabelColumnState<T, S> addLabelColumn(IModel<String> headerModel, Renderer<? super T> renderer) {
return DataTableBuilder.this.addLabelColumn(headerModel, renderer);
}
@Override
public <C> IAddedLabelColumnState<T, S> addLabelColumn(IModel<String> headerModel, AbstractCoreBinding<? super T, C> binding) {
return DataTableBuilder.this.addLabelColumn(headerModel, binding);
}
@Override
public <C> IAddedLabelColumnState<T, S> addLabelColumn(IModel<String> headerModel, AbstractCoreBinding<? super T, C> binding,
Renderer<? super C> renderer) {
return DataTableBuilder.this.addLabelColumn(headerModel, binding, renderer);
}
@Override
public <C> IAddedLabelColumnState<T, S> addLabelColumn(IModel<String> headerModel, Function<? super T, C> function) {
return DataTableBuilder.this.addLabelColumn(headerModel, function);
}
@Override
public <C> IAddedLabelColumnState<T, S> addLabelColumn(IModel<String> headerModel, Function<? super T, C> function,
Renderer<? super C> renderer) {
return DataTableBuilder.this.addLabelColumn(headerModel, function, renderer);
}
@Override
public IAddedLabelColumnState<T, S> addLabelColumn(IModel<String> headerModel, AbstractCoreBinding<? super T, ? extends Date> binding,
IDatePattern datePattern) {
return DataTableBuilder.this.addLabelColumn(headerModel, binding, datePattern);
}
@Override
public <C> IAddedCoreColumnState<T, S> addBootstrapLabelColumn(IModel<String> headerModel, AbstractCoreBinding<? super T, C> binding,
BootstrapRenderer<? super C> renderer) {
return DataTableBuilder.this.addBootstrapLabelColumn(headerModel, binding, renderer);
}
@Override
public <C> IAddedCoreColumnState<T, S> addBootstrapLabelColumn(IModel<String> headerModel,
Function<? super T, C> function, BootstrapRenderer<? super C> renderer) {
return DataTableBuilder.this.addBootstrapLabelColumn(headerModel, function, renderer);
}
@Override
public <C> IAddedBootstrapBadgeColumnState<T, S, C> addBootstrapBadgeColumn(IModel<String> headerModel, AbstractCoreBinding<? super T, C> binding,
BootstrapRenderer<? super C> renderer) {
return DataTableBuilder.this.addBootstrapBadgeColumn(headerModel, binding, renderer);
}
@Override
public <C> IAddedBootstrapBadgeColumnState<T, S, C> addBootstrapBadgeColumn(IModel<String> headerModel,
Function<? super T, C> function, BootstrapRenderer<? super C> renderer) {
return DataTableBuilder.this.addBootstrapBadgeColumn(headerModel, function, renderer);
}
@Override
public <C> IAddedBooleanLabelColumnState<T, S> addBooleanLabelColumn(IModel<String> headerModel,
final AbstractCoreBinding<? super T, Boolean> binding) {
return DataTableBuilder.this.addBooleanLabelColumn(headerModel, binding);
}
@Override
public CustomizableToolbarBuilder<T, S> addTopToolbar() {
return DataTableBuilder.this.addTopToolbar();
}
@Override
public CustomizableToolbarBuilder<T, S> addBottomToolbar() {
return DataTableBuilder.this.addBottomToolbar();
}
@Override
public ActionColumnBuilder<T, S> addActionColumn() {
return DataTableBuilder.this.addActionColumn();
}
@Override
public ActionColumnBuilder<T, S> addActionColumn(IModel<String> headerLabelModel) {
return DataTableBuilder.this.addActionColumn(headerLabelModel);
}
@Override
public IBuildState<T, S> withNoRecordsResourceKey(String noRecordsResourceKey) {
return DataTableBuilder.this.withNoRecordsResourceKey(noRecordsResourceKey);
}
@Override
public IBuildState<T, S> hideHeadersToolbar() {
return DataTableBuilder.this.hideHeadersToolbar();
}
@Override
@Deprecated
public IBuildState<T, S> hideTopToolbar() {
return DataTableBuilder.this.hideTopToolbar();
}
@Override
public IBuildState<T, S> hideNoRecordsToolbar() {
return DataTableBuilder.this.hideNoRecordsToolbar();
}
@Override
@Deprecated
public IBuildState<T, S> hideBottomToolbar() {
return DataTableBuilder.this.hideBottomToolbar();
}
@Override
public IBuildState<T, S> withFactory(IDataTableFactory<T, S> factory) {
return DataTableBuilder.this.withFactory(factory);
}
@Override
public CoreDataTable<T, S> build(String id) {
return DataTableBuilder.this.build(id);
}
@Override
public CoreDataTable<T, S> build(String id, long rowsPerPage) {
return DataTableBuilder.this.build(id, rowsPerPage);
}
@Override
public IDecoratedBuildState<T, S> decorate() {
return DataTableBuilder.this.decorate();
}
@Override
public IDecoratedBuildState<T, S> bootstrapPanel() {
return DataTableBuilder.this.bootstrapPanel();
}
}
private abstract class AddedColumnState<NextState extends IAddedColumnState<T, S>> extends DataTableBuilderWrapper implements IAddedColumnState<T, S> {
protected abstract IColumn<T, S> getColumn();
protected abstract NextState getNextState();
@Override
public NextState when(Condition condition) {
columns.put(getColumn(), condition);
return getNextState();
}
}
private abstract class AddedCoreColumnState<NextState extends IAddedCoreColumnState<T, S>> extends AddedColumnState<NextState>
implements IAddedCoreColumnState<T, S> {
@Override
protected abstract ICoreColumn<T, S> getColumn();
@Override
public NextState withClass(String cssClass) {
getColumn().addCssClass(cssClass);
return getNextState();
}
@Override
public NextState withSort(S sort) {
return withSort(sort, SortIconStyle.DEFAULT, CycleMode.NONE_DEFAULT);
}
@Override
public NextState withSort(S sort, ISortIconStyle sortIconStyle) {
return withSort(sort, sortIconStyle, CycleMode.NONE_DEFAULT);
}
@Override
public NextState withSort(S sort, ISortIconStyle sortIconStyle, CycleMode cycleMode) {
ICoreColumn<T, S> column = getColumn();
column.setSortProperty(sort);
column.setSortCycleMode(cycleMode);
column.setSortIconStyle(sortIconStyle);
return getNextState();
}
}
private class AddedLabelColumnState extends AddedCoreColumnState<IAddedLabelColumnState<T, S>> implements IAddedLabelColumnState<T, S> {
private final CoreLabelColumn<T, S> column;
public AddedLabelColumnState(CoreLabelColumn<T, S> column) {
super();
this.column = column;
}
@Override
protected CoreLabelColumn<T, S> getColumn() {
return column;
}
@Override
public IAddedLabelColumnState<T, S> getNextState() {
return this;
}
@Override
public IAddedLabelColumnState<T, S> multiline() {
getColumn().multiline();
return this;
}
@Override
public IAddedLabelColumnState<T, S> showPlaceholder() {
getColumn().showPlaceholder();
return this;
}
@Override
public IAddedLabelColumnState<T, S> showPlaceholder(IModel<String> placeholderModel) {
getColumn().showPlaceholder(placeholderModel);
return this;
}
@Override
public IAddedLabelColumnState<T, S> withTooltip(Renderer<? super T> tooltipRenderer) {
getColumn().setTooltipRenderer(tooltipRenderer);
return this;
}
@Override
public <C> IAddedLabelColumnState<T, S> withTooltip(Function<? super T, C> function, Renderer<? super C> tooltipRenderer) {
return withTooltip(tooltipRenderer.onResultOf(function));
}
@Deprecated
@Override
public IAddedLabelColumnState<T, S> withLink(LinkGeneratorFactory<T> linkGeneratorFactory) {
return withLink(new LinkGeneratorFactoryToOneParameterLinkDescriptorMapperAdapter<>(linkGeneratorFactory));
}
@Deprecated
@Override
public <C> IAddedLabelColumnState<T, S> withLink(AbstractCoreBinding<? super T, C> binding, LinkGeneratorFactory<C> linkGeneratorFactory) {
return withLink(binding, new LinkGeneratorFactoryToOneParameterLinkDescriptorMapperAdapter<>(linkGeneratorFactory));
}
@Deprecated
@Override
public IAddedLabelColumnState<T, S> withSideLink(LinkGeneratorFactory<T> sideLinkGeneratorFactory) {
return withSideLink(new LinkGeneratorFactoryToOneParameterLinkDescriptorMapperAdapter<>(sideLinkGeneratorFactory));
}
@Deprecated
@Override
public <C> IAddedLabelColumnState<T, S> withSideLink(AbstractCoreBinding<? super T, C> binding, LinkGeneratorFactory<C> linkGeneratorFactory) {
return withSideLink(binding, new LinkGeneratorFactoryToOneParameterLinkDescriptorMapperAdapter<>(linkGeneratorFactory));
}
@Override
public IAddedLabelColumnState<T, S> withLink(
ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<T>> linkGeneratorMapper) {
getColumn().setLinkGeneratorMapper(linkGeneratorMapper);
return this;
}
@Override
public <C> IAddedLabelColumnState<T, S> withLink(Function<? super T, C> function,
ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<C>> linkGeneratorMapper) {
return withLink(new FunctionOneParameterLinkDescriptorMapper<>(function, linkGeneratorMapper));
}
@Override
public <C> IAddedLabelColumnState<T, S> withLink(AbstractCoreBinding<? super T, C> binding,
ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<C>> linkGeneratorMapper) {
return withLink(new BindingOneParameterLinkDescriptorMapper<>(binding, linkGeneratorMapper));
}
@Override
public IAddedLabelColumnState<T, S> withSideLink(
ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<T>> linkGeneratorMapper) {
getColumn().setSideLinkGeneratorMapper(linkGeneratorMapper);
return this;
}
@Override
public <C> IAddedLabelColumnState<T, S> withSideLink(Function<? super T, C> function,
ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<C>> linkGeneratorMapper) {
return withSideLink(new FunctionOneParameterLinkDescriptorMapper<>(function, linkGeneratorMapper));
}
@Override
public <C> IAddedLabelColumnState<T, S> withSideLink(AbstractCoreBinding<? super T, C> binding,
ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<C>> linkGeneratorMapper) {
return withSideLink(new BindingOneParameterLinkDescriptorMapper<>(binding, linkGeneratorMapper));
}
@Override
@Deprecated
public IAddedLabelColumnState<T, S> disableIfInvalid() {
// Does nothing: this is the default behavior.
return this;
}
@Override
public IAddedLabelColumnState<T, S> hideIfInvalid() {
getColumn().hideIfInvalid();
return this;
}
@Override
public IAddedLabelColumnState<T, S> linkBehavior(Behavior linkBehavior) {
getColumn().addLinkBehavior(linkBehavior);
return this;
}
@Override
public IAddedLabelColumnState<T, S> targetBlank() {
return linkBehavior(new TargetBlankBehavior());
}
}
private class AddedBootstrapBadgeColumnState<C> extends AddedCoreColumnState<IAddedBootstrapBadgeColumnState<T, S, C>> implements IAddedBootstrapBadgeColumnState<T, S, C> {
private final CoreBootstrapBadgeColumn<T, S, C> column;
public AddedBootstrapBadgeColumnState(CoreBootstrapBadgeColumn<T, S, C> column) {
super();
this.column = column;
}
@Override
protected CoreBootstrapBadgeColumn<T, S, C> getColumn() {
return column;
}
@Override
public IAddedBootstrapBadgeColumnState<T, S, C> getNextState() {
return this;
}
@Override
public IAddedBootstrapBadgeColumnState<T, S, C> withLink(
ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<T>> linkGeneratorMapper) {
getColumn().setLinkGeneratorMapper(linkGeneratorMapper);
return this;
}
@Override
public <E> IAddedBootstrapBadgeColumnState<T, S, C> withLink(Function<? super T, E> function,
ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<E>> linkGeneratorMapper) {
return withLink(new FunctionOneParameterLinkDescriptorMapper<>(function, linkGeneratorMapper));
}
@Override
public <E> IAddedBootstrapBadgeColumnState<T, S, C> withLink(AbstractCoreBinding<? super T, E> binding,
ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<E>> linkGeneratorMapper) {
return withLink(new BindingOneParameterLinkDescriptorMapper<>(binding, linkGeneratorMapper));
}
@Override
public IAddedBootstrapBadgeColumnState<T, S, C> withSideLink(
ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<T>> linkGeneratorMapper) {
getColumn().setSideLinkGeneratorMapper(linkGeneratorMapper);
return this;
}
@Override
public <E> IAddedBootstrapBadgeColumnState<T, S, C> withSideLink(Function<? super T, E> function,
ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<E>> linkGeneratorMapper) {
return withSideLink(new FunctionOneParameterLinkDescriptorMapper<>(function, linkGeneratorMapper));
}
@Override
public <E> IAddedBootstrapBadgeColumnState<T, S, C> withSideLink(AbstractCoreBinding<? super T, E> binding,
ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<E>> linkGeneratorMapper) {
return withSideLink(new BindingOneParameterLinkDescriptorMapper<>(binding, linkGeneratorMapper));
}
@Override
@Deprecated
public IAddedBootstrapBadgeColumnState<T, S, C> disableIfInvalid() {
// Does nothing: this is the default behavior.
return this;
}
@Override
public IAddedBootstrapBadgeColumnState<T, S, C> hideIfInvalid() {
getColumn().hideIfInvalid();
return this;
}
@Override
public IAddedBootstrapBadgeColumnState<T, S, C> throwExceptionIfInvalid() {
getColumn().throwExceptionIfInvalid();
return this;
}
@Override
public IAddedBootstrapBadgeColumnState<T, S, C> linkBehavior(Behavior linkBehavior) {
getColumn().addLinkBehavior(linkBehavior);
return this;
}
@Override
public IAddedBootstrapBadgeColumnState<T, S, C> targetBlank() {
return linkBehavior(new TargetBlankBehavior());
}
}
private class AddedBooleanLabelColumnState extends AddedCoreColumnState<IAddedBooleanLabelColumnState<T, S>> implements IAddedBooleanLabelColumnState<T, S> {
private final CoreBooleanLabelColumn<T, S> column;
public AddedBooleanLabelColumnState(CoreBooleanLabelColumn<T, S> column) {
super();
this.column = column;
}
@Override
protected CoreBooleanLabelColumn<T, S> getColumn() {
return column;
}
@Override
public IAddedBooleanLabelColumnState<T, S> hideIfNullOrFalse() {
getColumn().hideIfNullOrFalse();
return this;
}
@Override
protected IAddedBooleanLabelColumnState<T, S> getNextState() {
return this;
}
}
private class DecoratedBuildState implements IDecoratedBuildState<T, S> {
private static final int DEFAULT_PAGER_VIEW_SIZE = 11;
protected String countResourceKey = null;
protected Condition responsiveCondition = Condition.alwaysTrue();
protected final Multimap<AddInPlacement, IOneParameterComponentFactory<?, ? super DecoratedCoreDataTablePanel<T, S>>>
addInComponentFactories = ArrayListMultimap.create();
protected String getTitleCssClass() {
return "add-in-emphasize";
}
protected String getPaginationCssClass() {
return "add-in-pagination";
}
@Override
public IDecoratedBuildState<T, S> responsive(Condition responsiveCondition) {
this.responsiveCondition = responsiveCondition;
return this;
}
@Override
public IDecoratedBuildState<T, S> title(String resourceKey) {
return addIn(AddInPlacement.HEADING_LEFT, new LabelAddInComponentFactory(new ResourceModel(resourceKey)), getTitleCssClass());
}
@Override
public IDecoratedBuildState<T, S> title(IModel<?> model) {
return addIn(AddInPlacement.HEADING_LEFT, new LabelAddInComponentFactory(model), getTitleCssClass());
}
@Override
public IDecoratedBuildState<T, S> title(IComponentFactory<?> addInComponentFactory) {
return addIn(AddInPlacement.HEADING_LEFT, ComponentFactories.ignoreParameter(addInComponentFactory), getTitleCssClass());
}
@Override
public IDecoratedBuildState<T, S> count(String countResourceKey) {
return count(AddInPlacement.HEADING_LEFT, countResourceKey);
}
@Override
public IDecoratedBuildState<T, S> count(AddInPlacement placement, String countResourceKey) {
this.countResourceKey = countResourceKey;
return addIn(placement, new CountAddInComponentFactory(sequenceProvider, countResourceKey), getTitleCssClass());
}
@Override
public IDecoratedBuildState<T, S> pagers() {
return pagers(DEFAULT_PAGER_VIEW_SIZE);
}
@Override
public IDecoratedBuildState<T, S> pagers(int viewSize) {
return pager(AddInPlacement.HEADING_RIGHT, viewSize).pager(AddInPlacement.FOOTER_RIGHT, viewSize);
}
@Override
public IDecoratedBuildState<T, S> pager(AddInPlacement placement) {
return pager(placement, DEFAULT_PAGER_VIEW_SIZE);
}
@Override
public IDecoratedBuildState<T, S> pager(AddInPlacement placement, int viewSize) {
return addIn(placement, new PagerAddInComponentFactory(viewSize), getPaginationCssClass());
}
@Override
public IDecoratedBuildState<T, S> ajaxPagers() {
return ajaxPagers(DEFAULT_PAGER_VIEW_SIZE);
}
@Override
public IDecoratedBuildState<T, S> ajaxPagers(int viewSize) {
return ajaxPager(AddInPlacement.HEADING_RIGHT, viewSize).ajaxPager(AddInPlacement.FOOTER_RIGHT, viewSize);
}
@Override
public IDecoratedBuildState<T, S> ajaxPager(AddInPlacement placement) {
return ajaxPager(placement, DEFAULT_PAGER_VIEW_SIZE);
}
@Override
public IDecoratedBuildState<T, S> ajaxPager(AddInPlacement placement, int viewSize) {
return addIn(placement, new AjaxPagerAddInComponentFactory(viewSize), getPaginationCssClass());
}
@Override
public IDecoratedBuildState<T, S> addIn(AddInPlacement placement, IComponentFactory<?> addInComponentFactory) {
return addIn(placement, ComponentFactories.ignoreParameter(addInComponentFactory));
}
@Override
public IDecoratedBuildState<T, S> addIn(AddInPlacement placement, IComponentFactory<?> addInComponentFactory,
String cssClasses) {
return addIn(placement, ComponentFactories.ignoreParameter(addInComponentFactory), cssClasses);
}
@Override
public IDecoratedBuildState<T, S> addIn(AddInPlacement placement,
IOneParameterComponentFactory<?, ? super DecoratedCoreDataTablePanel<T, S>> addInComponentFactory) {
addInComponentFactories.put(placement, addInComponentFactory);
return this;
}
@Override
public IDecoratedBuildState<T, S> addIn(AddInPlacement placement,
IOneParameterComponentFactory<?, ? super DecoratedCoreDataTablePanel<T, S>> addInComponentFactory, String cssClasses) {
return addIn(placement, new ClassAttributeAppenderDecoratingParameterizedComponentFactory<>(addInComponentFactory, cssClasses));
}
@Override
public DecoratedCoreDataTablePanel<T, S> build(String id) {
return build(id, Long.MAX_VALUE);
}
@Override
public DecoratedCoreDataTablePanel<T, S> build(String id, long rowsPerPage) {
DecoratedCoreDataTablePanel<T, S> panel = new DecoratedCoreDataTablePanel<T, S>(
id,
factory,
columns,
sequenceProvider,
rowsPerPage,
addInComponentFactories,
responsiveCondition
);
if (noRecordsResourceKey == null && countResourceKey != null) {
withNoRecordsResourceKey(countResourceKey + ".zero");
}
DataTableBuilder.this.finalizeBuild(panel.getDataTable());
return panel;
}
}
private class BootstrapPanelBuildState extends DecoratedBuildState {
@Override
protected String getTitleCssClass() {
return "panel-title";
}
@Override
protected String getPaginationCssClass() {
return "add-in-pagination add-in-pagination-panel";
}
@Override
public DecoratedCoreDataTablePanel<T, S> build(String id, long rowsPerPage) {
BootstrapPanelCoreDataTablePanel<T, S> panel = new BootstrapPanelCoreDataTablePanel<T, S>(id, factory,
columns, sequenceProvider, rowsPerPage, addInComponentFactories, responsiveCondition);
if (noRecordsResourceKey == null && countResourceKey != null) {
withNoRecordsResourceKey(countResourceKey + ".zero");
}
DataTableBuilder.this.finalizeBuild(panel.getDataTable());
return panel;
}
}
private static class ClassAttributeAppenderDecoratingParameterizedComponentFactory<C extends Component, P>
extends AbstractDecoratingParameterizedComponentFactory<C, P> {
private static final long serialVersionUID = 4455974327179014829L;
private final String cssClass;
public ClassAttributeAppenderDecoratingParameterizedComponentFactory(IOneParameterComponentFactory<? extends C, ? super P> delegate, String cssClass) {
super(delegate);
this.cssClass = cssClass;
}
@Override
protected C decorate(C component, P parameter) {
component.add(new ClassAttributeAppender(cssClass));
return component;
}
}
}