/** * Copyright 2012 Universitat Pompeu Fabra. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * */ package org.onexus.website.api.pages.browser; import org.apache.wicket.AttributeModifier; import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.AjaxLink; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.panel.EmptyPanel; import org.apache.wicket.markup.repeater.RepeatingView; import org.apache.wicket.model.IModel; import org.apache.wicket.model.IWrapModel; import org.apache.wicket.model.Model; import org.onexus.collection.api.ICollectionManager; import org.onexus.collection.api.IEntity; import org.onexus.collection.api.IEntityTable; import org.onexus.collection.api.query.In; import org.onexus.collection.api.query.Query; import org.onexus.resource.api.IResourceManager; import org.onexus.resource.api.ORI; import org.onexus.website.api.WebsiteConfig; import org.onexus.website.api.WebsiteStatus; import org.onexus.website.api.events.AbstractEvent; import org.onexus.website.api.events.EventAddFilter; import org.onexus.website.api.events.EventFiltersUpdate; import org.onexus.website.api.events.EventPanel; import org.onexus.website.api.events.EventRemoveFilter; import org.onexus.website.api.pages.PageConfig; import org.onexus.website.api.pages.PageStatus; import org.onexus.website.api.pages.search.SearchPage; import org.onexus.website.api.pages.search.SearchPageConfig; import org.onexus.website.api.pages.search.SearchPageStatus; import org.onexus.website.api.pages.search.SearchType; import org.onexus.website.api.pages.search.boxes.BoxesPanel; import org.onexus.website.api.widgets.Widget; import org.onexus.website.api.widgets.selection.FilterConfig; import org.onexus.website.api.widgets.selection.MultipleEntitySelection; import javax.inject.Inject; import java.util.Collection; import java.util.List; public class SelectionPanel extends EventPanel { @Inject private IResourceManager resourceManager; @Inject private ICollectionManager collectionManager; private WebMarkupContainer widgetModal; public SelectionPanel(String id, IModel<BrowserPageStatus> pageModel) { super(id, pageModel); // Update this component if this events are fired. onEventFireUpdate(EventAddFilter.class, EventRemoveFilter.class, EventFiltersUpdate.class); // Create a new selection add(new BrowserPageLink<ORI>("new") { @Override public void onClick(AjaxRequestTarget target) { SearchPageStatus status = new SearchPageStatus(); WebsiteStatus websiteStatus = getWebsiteStatus(); WebsiteConfig websiteConfig = websiteStatus.getConfig(); SearchPageConfig searchPageConfig = null; for (PageConfig config : websiteConfig.getPages()) { if (config instanceof SearchPageConfig) { searchPageConfig = (SearchPageConfig) config; } } status.setConfig(searchPageConfig); widgetModal.addOrReplace(new Label("modalHeader", "New selection")); widgetModal.addOrReplace( new SearchPage("widget", new Model<SearchPageStatus>(status), true, false) { @Override protected void onSubmit(SearchPageStatus status, ORI baseUri, FilterConfig filterConfig) { SelectionPanel.this.onSubmit(status, baseUri, filterConfig); } } ); target.add(widgetModal); target.appendJavaScript("$('#" + widgetModal.getMarkupId() + "').modal('show')"); } }); widgetModal = new WebMarkupContainer("widgetModal"); widgetModal.setOutputMarkupId(true); widgetModal.add(new EmptyPanel("widget")); widgetModal.add(new AjaxLink<String>("close") { @Override public void onClick(AjaxRequestTarget target) { Component widget = widgetModal.get("widget"); if (widget instanceof Widget) { ((Widget) widget).onClose(target); } target.appendJavaScript("$('#" + widgetModal.getMarkupId() + "').modal('hide')"); } }); add(widgetModal); widgetModal.add(new Label("modalHeader", "Selection details")); } protected void onSubmit(SearchPageStatus status, ORI baseUri, FilterConfig filterConfig) { SearchType type = status.getType(); if (status.getSearch() != null) { ORI collectionUri = type.getCollection().toAbsolute(baseUri); if (filterConfig == null && status.getSearch().indexOf(',') == -1) { IEntityTable table = BoxesPanel.getSingleEntityTable(collectionManager, type, collectionUri, baseUri, status.getSearch(), true); if (table.next()) { // Single entity selection IEntity entity = table.getEntity(collectionUri); getBrowserPage().addEntitySelection(new SingleEntitySelection(entity)); } table.close(); } else { // Multiple entities selection if (filterConfig == null) { filterConfig = new FilterConfig(status.getSearch()); filterConfig.setCollection(collectionUri); filterConfig.setDefine("fc='" + collectionUri + "'"); String mainKey = type.getKeysList().get(0); In where = new In("fc", mainKey); String[] values = status.getSearch().split(","); for (String value : values) { where.addValue(value.trim()); } filterConfig.setWhere(where.toString()); } getBrowserPage().addEntitySelection(new MultipleEntitySelection(filterConfig)); } } sendEvent(EventAddFilter.EVENT); } @Override protected void onBeforeRender() { super.onBeforeRender(); WebMarkupContainer filtersContainer = new WebMarkupContainer("container"); filtersContainer.setOutputMarkupId(true); RepeatingView filterRules = new RepeatingView("filter"); filtersContainer.add(filterRules); final List<IEntitySelection> selections = getBrowserPage().getEntitySelections(); if (selections != null && !selections.isEmpty()) { Query query = getQuery(); for (IEntitySelection selection : selections) { WebMarkupContainer container = new WebMarkupContainer(filterRules.newChildId()); final ORI filterORI = selection.getSelectionCollection(); final String filterTitle = selection.getTitle(query); // Abbreviate at the 3th comma String abbreviateFilterTitle = filterTitle; int pos = filterTitle.indexOf(','); if (pos > -1) { pos = filterTitle.indexOf(',', pos+1); if (pos > -1) { pos = filterTitle.indexOf(',', pos+1); if (pos > -1) { abbreviateFilterTitle = filterTitle.substring(0, pos) + "..."; } } } // Edit a selection BrowserPageLink<ORI> editLink = new BrowserPageLink<ORI>("edit") { @Override public void onClick(AjaxRequestTarget target) { SearchPageStatus status = new SearchPageStatus(); WebsiteStatus websiteStatus = getWebsiteStatus(); WebsiteConfig websiteConfig = websiteStatus.getConfig(); SearchPageConfig searchPageConfig = null; for (PageConfig config : websiteConfig.getPages()) { if (config instanceof SearchPageConfig) { searchPageConfig = (SearchPageConfig) config; } } for (SearchType searchType : searchPageConfig.getTypes()) { if (searchType.getCollection().equals(filterORI)) { status.setType(searchType); break; } } status.setSearch(filterTitle); status.setConfig(searchPageConfig); widgetModal.addOrReplace(new Label("modalHeader", "Selection details")); widgetModal.addOrReplace(new SearchPage("widget", new Model<SearchPageStatus>(status), false, false) { @Override protected void onSubmit(SearchPageStatus status, ORI baseUri, FilterConfig filterConfig) { SelectionPanel.this.onSubmit(status, baseUri, filterConfig); } }); target.add(widgetModal); target.appendJavaScript("$('#" + widgetModal.getMarkupId() + "').modal('show')"); } }; Label labelComponent = new Label("title", abbreviateFilterTitle); labelComponent.setEscapeModelStrings(false); editLink.add(labelComponent); container.add(editLink); // Remove link BrowserPageLink<IEntitySelection> removeLink = new BrowserPageLink<IEntitySelection>("remove", Model.of(selection)) { @Override public void onClick(AjaxRequestTarget target) { getBrowserPageStatus().removeEntitySelection(getModelObject()); sendEvent(EventRemoveFilter.EVENT); } }; if (selection.isEnable()) { container.add(new AttributeModifier("class", "btn btn-large")); } else { container.add(new AttributeModifier("class", "btn btn-large disabled")); } container.add(removeLink); filterRules.add(container); } } addOrReplace(filtersContainer); } @Override protected void onRegisteredEvent(AjaxRequestTarget target, AbstractEvent event) { target.add(this.get("container")); } private BrowserPageStatus getBrowserPage() { return (BrowserPageStatus) getDefaultModelObject(); } protected Query getQuery() { PageStatus pageStatus = findParentStatus(getDefaultModel(), PageStatus.class); return pageStatus == null ? null : pageStatus.buildQuery(getBaseUri()); } protected ORI getBaseUri() { WebsiteStatus websiteStatus = getWebsiteStatus(); return websiteStatus == null ? null : websiteStatus.getConfig().getORI().getParent(); } protected WebsiteStatus getWebsiteStatus() { return findParentStatus(getDefaultModel(), WebsiteStatus.class); } private static <T> T findParentStatus(IModel<?> model, Class<T> statusClass) { Object obj = model.getObject(); if (obj != null && statusClass.isAssignableFrom(obj.getClass())) { return (T) obj; } if (model instanceof IWrapModel) { IModel<?> parentModel = ((IWrapModel) model).getWrappedModel(); return findParentStatus(parentModel, statusClass); } return null; } }