package fr.openwide.core.wicket.more.markup.repeater.table.column; import java.util.List; import org.apache.wicket.MarkupContainer; import org.apache.wicket.behavior.Behavior; import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.model.IModel; import com.google.common.base.Function; import com.google.common.collect.Lists; 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.panel.InvisiblePanel; import fr.openwide.core.wicket.more.link.descriptor.AbstractDynamicBookmarkableLink; import fr.openwide.core.wicket.more.link.descriptor.generator.ILinkGenerator; import fr.openwide.core.wicket.more.link.descriptor.mapper.ILinkDescriptorMapper; import fr.openwide.core.wicket.more.markup.html.bootstrap.label.component.BootstrapBadge; import fr.openwide.core.wicket.more.markup.html.bootstrap.label.renderer.BootstrapRenderer; import fr.openwide.core.wicket.more.markup.html.factory.IDetachableFactory; import fr.openwide.core.wicket.more.model.BindingModel; import fr.openwide.core.wicket.more.model.ReadOnlyModel; public class CoreBootstrapBadgeColumn<T, S extends ISort<?>, C> extends AbstractCoreColumn<T, S> { private static final long serialVersionUID = -5344972073351010752L; private final IDetachableFactory<IModel<T>, ? extends IModel<C>> modelFactory; private final BootstrapRenderer<? super C> renderer; private ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<T>> linkGeneratorMapper; private ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<T>> sideLinkGeneratorMapper; private enum LinkBehaviorIfInvalid { THROW_EXCEPTION, HIDE; } private LinkBehaviorIfInvalid linkBehaviorIfInvalid = null; private List<Behavior> linkBehaviors = Lists.newArrayList(); public CoreBootstrapBadgeColumn(IModel<?> headerLabelModel, final AbstractCoreBinding<? super T, C> binding, final BootstrapRenderer<? super C> renderer) { super(headerLabelModel); this.modelFactory = BindingModel.factory(binding); this.renderer = renderer; } public CoreBootstrapBadgeColumn(IModel<?> headerLabelModel, final Function<? super T, C> function, final BootstrapRenderer<? super C> renderer) { super(headerLabelModel); this.modelFactory = ReadOnlyModel.factory(function); this.renderer = renderer; } @Override public void detach() { super.detach(); if (linkGeneratorMapper != null) { linkGeneratorMapper.detach(); } if (sideLinkGeneratorMapper != null) { sideLinkGeneratorMapper.detach(); } } @Override public void populateItem(Item<ICellPopulator<T>> cellItem, String componentId, IModel<T> rowModel) { cellItem.add( new CoreBootstrapBadgeLinkColumnPanel<T, ISort<?>, C>(componentId, rowModel) { private static final long serialVersionUID = 1L; @Override public BootstrapBadge<C> getBootstrapBadge(String wicketId, IModel<T> rowModel) { return new BootstrapBadge<>(wicketId, modelFactory.create(rowModel), renderer); } @Override public MarkupContainer getLink(String wicketId, IModel<T> rowModel) { if (linkGeneratorMapper != null) { return decorate(linkGeneratorMapper.map(rowModel).link(wicketId)); } return new InvisiblePanel(wicketId); } @Override public MarkupContainer getSideLink(String wicketId, IModel<T> rowModel) { if (sideLinkGeneratorMapper != null) { return decorate(sideLinkGeneratorMapper.map(rowModel).link(wicketId)) .add(new WebMarkupContainer("sideLinkIcon").add(new ClassAttributeAppender("fa fa-share-square-o"))); } return new InvisiblePanel(wicketId); } }.setRenderBodyOnly(true) // Delete useless <div> under <td>. If it could be usefull, give the ability to configure it ); } private AbstractDynamicBookmarkableLink decorate(AbstractDynamicBookmarkableLink link) { if (linkBehaviorIfInvalid != null) { switch (linkBehaviorIfInvalid) { case HIDE: link.hideIfInvalid(); break; case THROW_EXCEPTION: link.throwExceptionIfInvalid(); break; } } for (Behavior linkBehavior : linkBehaviors) { link.add(linkBehavior); } return link; } public ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<T>> getLinkGeneratorMapper() { return linkGeneratorMapper; } public CoreBootstrapBadgeColumn<T, S, C> setLinkGeneratorMapper(ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<T>> linkGeneratorFactory) { if (sideLinkGeneratorMapper != null) { throw new IllegalStateException("link and side link cannot be both set."); } this.linkGeneratorMapper = linkGeneratorFactory; return this; } public ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<T>> getSideLinkGeneratorMapper() { return sideLinkGeneratorMapper; } public CoreBootstrapBadgeColumn<T, S, C> setSideLinkGeneratorMapper(ILinkDescriptorMapper<? extends ILinkGenerator, ? super IModel<T>> sideLinkGeneratorFactory) { if (linkGeneratorMapper != null) { throw new IllegalStateException("link and side link cannot be both set."); } this.sideLinkGeneratorMapper = sideLinkGeneratorFactory; return this; } public CoreBootstrapBadgeColumn<T, S, C> throwExceptionIfInvalid() { this.linkBehaviorIfInvalid = LinkBehaviorIfInvalid.THROW_EXCEPTION; return this; } public CoreBootstrapBadgeColumn<T, S, C> hideIfInvalid() { this.linkBehaviorIfInvalid = LinkBehaviorIfInvalid.HIDE; return this; } public void addLinkBehavior(Behavior behavior) { linkBehaviors.add(behavior); } }