/** * 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.tags; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink; import org.apache.wicket.markup.head.CssHeaderItem; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.html.form.CheckBoxMultipleChoice; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.HiddenField; import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.model.AbstractReadOnlyModel; import org.apache.wicket.model.CompoundPropertyModel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.request.resource.CssResourceReference; import org.apache.wicket.util.resource.IResourceStream; import org.apache.wicket.util.resource.StringResourceStream; import org.onexus.website.api.events.EventCloseModal; import org.onexus.website.api.events.EventFiltersUpdate; import org.onexus.website.api.events.EventViewChange; import org.onexus.website.api.pages.browser.BrowserPage; import org.onexus.website.api.pages.browser.BrowserPageStatus; import org.onexus.website.api.widgets.Widget; import org.onexus.website.api.widgets.tags.tagstore.ITagStoreManager; import org.onexus.website.api.widgets.tags.tagstore.TagStore; import javax.inject.Inject; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; public class TagWidget extends Widget<TagWidgetConfig, TagWidgetStatus> { public static final CssResourceReference CSS = new CssResourceReference(TagWidget.class, "TagWidget.css"); @Inject private ITagStoreManager tagStoreManager; public TagWidget(String componentId, IModel<TagWidgetStatus> statusModel) { super(componentId, statusModel); Form<TagWidgetStatus> form = new Form<TagWidgetStatus>("form", new CompoundPropertyModel<TagWidgetStatus>(statusModel)); form.add(new HiddenField<String>("selection").setMarkupId("modal-selection-container")); form.add(new AjaxSubmitLink("apply") { @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { TagWidget.this.getStatus().setFilter(false); TagStore tagStore = getTagStore(); for (String tagKey : getSelectedTags()) { for (String tagValue : getSelectedValues()) { tagStore.putTagValue(tagKey, tagValue); } } // Clear selected values getStatus().setSelection(""); target.appendJavaScript("clearSelected();"); // Clear selected tags TagWidget.this.getStatus().getSelectedTags().clear(); sendEvent(EventCloseModal.EVENT); sendEvent(EventViewChange.EVENT); target.add(TagWidget.this); } @Override protected void onError(AjaxRequestTarget target, Form<?> form) { target.add(TagWidget.this); } }); form.add(new AjaxSubmitLink("filter") { @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { TagWidget.this.getStatus().setFilter(!getSelectedTags().isEmpty()); sendEvent(EventCloseModal.EVENT); sendEvent(EventFiltersUpdate.EVENT); target.add(TagWidget.this); } @Override protected void onError(AjaxRequestTarget target, Form<?> form) { target.add(TagWidget.this); } }); final IModel<String> newLabel = Model.of(""); form.add(new TextField<String>("newlabel", newLabel)); form.add(new AjaxSubmitLink("newbutton") { @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { TagStore tagStore = getTagStore(); String label = newLabel.getObject(); if (label != null && !label.isEmpty()) { label = label.trim().replaceAll("[^a-zA-Z0-9\\-_]", "_"); tagStore.putTagKey(label); newLabel.setObject(""); } target.add(TagWidget.this); } @Override protected void onError(AjaxRequestTarget target, Form<?> form) { target.add(TagWidget.this); } }); form.add(new AjaxSubmitLink("remove") { @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { TagStore tagStore = getTagStore(); for (String tagKey : getSelectedTags()) { tagStore.removeTag(tagKey); } sendEvent(EventCloseModal.EVENT); sendEvent(EventViewChange.EVENT); target.add(TagWidget.this); } @Override protected void onError(AjaxRequestTarget target, Form<?> form) { target.add(TagWidget.this); } }); form.add(new CheckBoxMultipleChoice<String>("tags", new PropertyModel<List<String>>(this, "selectedTags"), new TagsModel()).setPrefix("")); final TagsDownload download = new TagsDownload() { @Override protected IResourceStream getResourceStream() { return new StringResourceStream(createDownload(), "text/csv"); } @Override protected String getFileName() { return getDownloadFileName(); } }; form.add(download); form.add(new AjaxSubmitLink("download") { @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { target.add(TagWidget.this); download.initiate(target); } @Override protected void onError(AjaxRequestTarget target, Form<?> form) { target.add(TagWidget.this); } }); add(form); } public List<String> getSelectedTags() { return getStatus().getSelectedTags(); } public void setSelectedTags(List<String> selectedTags) { getStatus().setSelectedTags(selectedTags); } @SuppressWarnings("unchecked") private List<String> getSelectedValues() { TagWidgetStatus status = getStatus(); String selection = status.getSelection(); return selection == null ? Collections.EMPTY_LIST : Arrays.asList(selection.split(":::")); } private CharSequence createDownload() { StringBuilder output = new StringBuilder(); TagStore tagStore = getTagStore(); for (String tagKey : getSelectedTags()) { for (String value : tagStore.getTagValues(tagKey)) { output.append(value).append("\n"); } } return output; } private String getDownloadFileName() { StringBuilder fileName = new StringBuilder(); Iterator<String> it = getSelectedTags().iterator(); while (it.hasNext()) { fileName.append(it.next()); if (it.hasNext()) { fileName.append("-"); } } fileName.append(".tsv"); return fileName.toString(); } private TagStore getTagStore() { BrowserPageStatus status = findParent(BrowserPage.class).getStatus(); String tagId = status.getCurrentTabId(); String baseURI = status.getBase(); String namespace = baseURI + "#" + tagId; TagStore store = tagStoreManager.getUserStore(namespace); // Check that the default tags are present Collection<String> keys = store.getTagKeys(); List<String> defaultTags = getConfig().getTags(); if (defaultTags != null) { for (String defaultTag : defaultTags) { if (!keys.contains(defaultTag)) { store.putTagKey(defaultTag); } } } return store; } @Override public void renderHead(IHeaderResponse response) { super.renderHead(response); response.render(CssHeaderItem.forReference(CSS)); } private class TagsModel extends AbstractReadOnlyModel<List<String>> { @Override public List<String> getObject() { return new ArrayList<String>(getTagStore().getTagKeys()); } } }