package org.brixcms.plugin.jpa.web.admin; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.apache.wicket.Component; import org.apache.wicket.MetaDataKey; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.event.IEvent; import org.apache.wicket.markup.ComponentTag; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.LoadableDetachableModel; import org.brixcms.auth.Action.Context; import org.brixcms.plugin.jpa.JpaPluginLocator; import org.brixcms.plugin.jpa.Persistable; import org.brixcms.plugin.jpa.web.admin.GridPanel.SelectionChangedEvent; import org.brixcms.plugin.jpa.web.admin.filter.FilterPanel; import org.brixcms.plugin.site.SimpleCallback; import org.brixcms.web.generic.BrixGenericPanel; /** * @author dan.simko@gmail.com */ @SuppressWarnings("serial") public class EntityManagerPanel<T extends Persistable<ID>, ID extends Serializable, F extends Serializable> extends BrixGenericPanel<T> { private static final String EDITOR_ID = "editor"; private static MetaDataKey<String> EDITOR_NODE_TYPE = new MetaDataKey<String>() { }; private final JpaPluginLocator<T, ID, F> pluginLocator; private Component lastEditor; private Component editor; public EntityManagerPanel(String id, IModel<T> model, JpaPluginLocator<T, ID, F> pluginLocator) { super(id, model); this.pluginLocator = pluginLocator; setOutputMarkupId(true); add(new FilterPanel<T, ID, F>("filterPanel", pluginLocator)); add(new GridPanel<T, ID, F>("gridPanel", pluginLocator)); WebMarkupContainer createContainer = new WebMarkupContainer("createContainer") { @Override public boolean isVisible() { return pluginLocator.getPlugin().canCreateEntity(Context.ADMINISTRATION); } }; add(createContainer); final JpaEntityPluginEntriesModel<T, ID, F> createEntitiesModel = new JpaEntityPluginEntriesModel<T, ID, F>(pluginLocator); createContainer.add(new ListView<PluginEntry<T, ID, F>>("create", createEntitiesModel) { @Override protected void populateItem(final ListItem<PluginEntry<T, ID, F>> item) { Link<Void> link; item.add(link = new Link<Void>("link") { @Override public void onClick() { EntityPlugin<T, ID> plugin = item.getModelObject().getPlugin(); final Component currentEditor = getEditor(); if (lastEditor == null || currentEditor.getMetaData(EDITOR_NODE_TYPE) == null) { lastEditor = currentEditor; } SimpleCallback goBack = new SimpleCallback() { @Override public void execute() { setupEditor(lastEditor); } }; Panel panel = plugin.newCreateEntityPanel(EDITOR_ID, goBack); panel.setMetaData(EDITOR_NODE_TYPE, plugin.getPluginId()); setupEditor(panel); } @Override protected void onComponentTag(ComponentTag tag) { super.onComponentTag(tag); EntityPlugin<T, ID> plugin = item.getModelObject().getPlugin(); String pluginId = getEditor().getMetaData(EDITOR_NODE_TYPE); if (plugin.getPluginId().equals(pluginId)) { CharSequence klass = tag.getAttribute("class"); if (klass == null) { klass = "active"; } else { klass = klass + " active"; } tag.put("class", klass); } } }); EntityPlugin<T, ID> plugin = item.getModelObject().getPlugin(); link.add(new Label("label", plugin.newCreateCaptionModel())); } }.setReuseItems(false)); editor = new WebMarkupContainer(EDITOR_ID); add(editor); setupDefaultEditor(); } private void setupEditor(Component newEditor) { editor.replaceWith(newEditor); editor = newEditor; } private void setupDefaultEditor() { setupEditor(new EntityManagerEditorPanel<T, ID, F>(EDITOR_ID, getModel(), pluginLocator)); } private Component getEditor() { return get(EDITOR_ID); }; @Override public void onEvent(IEvent<?> event) { super.onEvent(event); if (event.getPayload() instanceof SelectionChangedEvent) { @SuppressWarnings("unchecked") SelectionChangedEvent<T> e = (SelectionChangedEvent<T>) event.getPayload(); setModelObject(e.getSelected().getObject()); setupDefaultEditor(); getRequestCycle().find(AjaxRequestTarget.class).ifPresent(t -> t.add(this)); } } private static class PluginEntry<T extends Persistable<ID>, ID extends Serializable, F extends Serializable> implements Serializable { private final JpaPluginLocator<T, ID, F> pluginLocator; private final String pluginId; public PluginEntry(JpaPluginLocator<T, ID, F> pluginLocator, EntityPlugin<T, ID> plugin) { this.pluginLocator = pluginLocator; this.pluginId = plugin.getPluginId(); } public EntityPlugin<T, ID> getPlugin() { return pluginLocator.getPlugin().getEntityPluginById(pluginId); } } private static class JpaEntityPluginEntriesModel<T extends Persistable<ID>, ID extends Serializable, F extends Serializable> extends LoadableDetachableModel<List<PluginEntry<T, ID, F>>> { private final JpaPluginLocator<T, ID, F> pluginLocator; public JpaEntityPluginEntriesModel(JpaPluginLocator<T, ID, F> pluginLocator) { this.pluginLocator = pluginLocator; } @Override protected List<PluginEntry<T, ID, F>> load() { return convert(pluginLocator.getPlugin().getEntityPlugins()); } private List<PluginEntry<T, ID, F>> convert(Collection<? extends EntityPlugin<T, ID>> editorPlugins) { List<PluginEntry<T, ID, F>> list = new ArrayList<PluginEntry<T, ID, F>>(); for (EntityPlugin<T, ID> plugin : editorPlugins) { if (pluginLocator.getPlugin().getEntityClass().equals(plugin.getEntityClass())) { list.add(new PluginEntry<T, ID, F>(pluginLocator, plugin)); } } return list; } } }