/** * 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.widgets.selector; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.OnChangeAjaxBehavior; import org.apache.wicket.extensions.ajax.markup.html.AjaxIndicatorAppender; import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.model.IModel; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.util.string.AppendingStringBuffer; import org.apache.wicket.util.string.Strings; import org.onexus.collection.api.ICollectionManager; import org.onexus.collection.api.IEntity; import org.onexus.collection.api.query.Filter; import org.onexus.collection.api.query.IQueryParser; import org.onexus.collection.api.query.OrderBy; import org.onexus.collection.api.query.Query; import org.onexus.collection.api.utils.EntityIterator; import org.onexus.collection.api.utils.QueryUtils; import org.onexus.resource.api.ORI; import org.onexus.website.api.events.EventAddFilter; import org.onexus.website.api.events.EventFiltersUpdate; import org.onexus.website.api.pages.browser.BrowserPageStatus; import org.onexus.website.api.pages.browser.SingleEntitySelection; import org.onexus.website.api.widgets.Widget; import javax.inject.Inject; import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class SelectorWidget extends Widget<SelectorWidgetConfig, SelectorWidgetStatus> { @Inject private ICollectionManager collectionManager; @Inject private IQueryParser queryParser; private transient EntityChoice selection; private transient List<EntityChoice> choices; public SelectorWidget(String componentId, IModel<SelectorWidgetStatus> statusModel) { super(componentId, statusModel); Form form = new Form("form"); DropDownChoice<EntityChoice> dropDown = new DropDownChoice<EntityChoice>( "select", new PropertyModel<EntityChoice>(this, "selection"), getChoices() ) { @Override protected CharSequence getDefaultChoice(String selectedValue) { String option = SelectorWidget.this.getConfig().getTitle(); if (Strings.isEmpty(option)) { option = "Choose one..."; } // The <option> tag buffer final AppendingStringBuffer buffer = new AppendingStringBuffer(64 + option.length()); // Add option tag buffer.append("\n<option"); // If null is selected, indicate that if ("".equals(selectedValue)) { buffer.append(" selected=\"selected\""); } // Add body of option tag buffer.append(" value=\"\">").append(option).append("</option>"); return buffer; } }; dropDown.add(new OnChangeAjaxBehavior() { @Override protected void onUpdate(AjaxRequestTarget target) { Boolean selection = getConfig().getSelection(); if (selection == null || !selection) { sendEvent(EventFiltersUpdate.EVENT); } else { EntityChoice choice = getSelection(); if (choice != null) { BrowserPageStatus pageStatus = findParentStatus(BrowserPageStatus.class); pageStatus.addEntitySelection(new SingleEntitySelection(getConfig().getCollection(), getSelection().getId())); setSelection(null); sendEvent(EventAddFilter.EVENT); } } } }); dropDown.setNullValid(true); add(new AjaxIndicatorAppender()); form.add(dropDown); add(form); } public EntityChoice getSelection() { if (selection == null) { SelectorWidgetStatus status = getStatus(); if (status != null && status.getSelection() != null) { for (EntityChoice choice : getChoices()) { if (choice.getId().equals(status.getSelection())) { this.selection = choice; break; } } } } return selection; } public void setSelection(EntityChoice entityChoice) { selection = entityChoice; String id = entityChoice == null ? null : entityChoice.getId(); getStatus().setSelection(id); } private List<EntityChoice> getChoices() { if (choices == null) { String field = getConfig().getField(); ORI collection = getConfig().getCollection(); Query query = new Query(); query.setOn(getWebsiteOri()); String collectionAlias = QueryUtils.newCollectionAlias(query, collection); query.setFrom(collectionAlias); query.addSelect(collectionAlias, null); query.addOrderBy(new OrderBy(collectionAlias, field)); String oqlWhere = getConfig().getWhere(); if (oqlWhere != null && !oqlWhere.isEmpty()) { Filter where = queryParser.parseWhere(collectionAlias + "." + getConfig().getWhere().trim()); query.setWhere(where); } Iterator<IEntity> choicesIt = new EntityIterator(collectionManager.load(query), collection); choices = new ArrayList<EntityChoice>(); while (choicesIt.hasNext()) { IEntity entity = choicesIt.next(); choices.add(new EntityChoice(entity.getId(), String.valueOf(entity.get(field)))); } } return choices; } public static class EntityChoice implements Serializable { private String id; private String field; public EntityChoice(String id, String field) { this.id = id; this.field = field; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getField() { return field; } public void setField(String field) { this.field = field; } public String toString() { return getField(); } } }