/**
* Copyright (C) 2010 Peter Karich <jetwick_@_pannous_._info>
*
* 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 de.jetwick.ui;
import org.odlabs.wiquery.ui.dialog.Dialog;
import de.jetwick.ui.util.FacetHelper;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.AjaxSelfUpdatingTimerBehavior;
import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxFallbackLink;
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.Model;
import org.apache.wicket.util.time.Duration;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.facet.Facet;
import org.elasticsearch.search.facet.query.QueryFacet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static de.jetwick.es.JetwickQuery.*;
/**
*
* @author Peter Karich, peat_hal 'at' users 'dot' sourceforge 'dot' net
*/
public class SavedSearchPanel extends Panel {
private final Logger logger = LoggerFactory.getLogger(getClass());
private Map<String, String> tr = new LinkedHashMap<String, String>();
private List<FacetHelper<Long>> savedSearches = new ArrayList<FacetHelper<Long>>();
private ListView savedSearchesView;
private boolean isInitialized = false;
public SavedSearchPanel(String id) {
super(id);
tr.put(SAVED_SEARCHES, "Saved Searches");
Link saveSearch = new IndicatingAjaxFallbackLink("saveSearch") {
@Override
public void onClick(AjaxRequestTarget target) {
SavedSearchPanel.this.onSave(target, new Date().getTime());
}
};
add(saveSearch);
AjaxFallbackLink link = new IndicatingAjaxFallbackLink("saveInfo") {
@Override
public void onClick(AjaxRequestTarget target) {
SavedSearchPanel.this.onSave(target, new Date().getTime());
}
@Override
public boolean isVisible() {
return isInitialized && savedSearches.isEmpty();
}
};
add(link.setOutputMarkupId(true));
add(new WebMarkupContainer("indicatorImage") {
@Override
public boolean isVisible() {
return !isInitialized;
}
}.setOutputMarkupId(true));
// don't know how to utilize IAjaxIndicatorAware + getAjaxIndicatorMarkupId() { return indicator.getMarkupId();
//add(indicator);
savedSearchesView = new ListView("filterValues", savedSearches) {
@Override
protected void populateItem(ListItem li) {
final FacetHelper<Long> h = (FacetHelper<Long>) li.getModelObject();
long tmp = h.value;
final long ssId = tmp;
Link link = new IndicatingAjaxFallbackLink("filterValueLink") {
@Override
public void onClick(AjaxRequestTarget target) {
SavedSearchPanel.this.onClick(target, ssId);
}
};
String name = h.displayName;
if (name.length() > 20)
name = name.substring(0, 20) + "..";
else if (name.length() < 1)
name = "<empty>";
if (ssId == 0)
name = "last:" + name;
link.add(new Label("filterValue", name));
link.add(new AttributeAppender("title", true, new Model(h.displayName), " "));
Label label4count = new Label("filterCount", " (" + h.count + ")");
if (h.count < 1) {
link.add(new AttributeAppender("class", new Model("gray"), " "));
label4count.add(new AttributeAppender("class", new Model("gray"), " "));
}
li.add(label4count);
li.add(link);
final Dialog dialog = new Dialog("confirmation").setWidth(400).
setTitle("Delete Saved Search " + name + "?");
dialog.add(new AjaxFallbackLink("button") {
@Override
public void onClick(AjaxRequestTarget target) {
dialog.close(target);
SavedSearchPanel.this.onRemove(target, ssId);
}
});
li.add(dialog);
Link removeLink = new AjaxFallbackLink("removeLink") {
@Override
public void onClick(AjaxRequestTarget target) {
if (target != null)
dialog.open(target);
}
};
li.add(removeLink);
}
};
add(savedSearchesView);
// execute one time
add(new AjaxSelfUpdatingTimerBehavior(Duration.seconds(0.1)) {
@Override
protected void onPostProcessTarget(AjaxRequestTarget target) {
updateSSCounts(target);
isInitialized = true;
stop();
}
});
// execute forever
add(new AjaxSelfUpdatingTimerBehavior(Duration.seconds(60)) {
@Override
protected void onPostProcessTarget(AjaxRequestTarget target) {
// update count of all queries
updateSSCounts(target);
}
});
}
/**
* Make sure that the facets appear in the order we defined via filterToIndex
*/
public List<FacetHelper> createFacetsFields(SearchResponse rsp) {
List<FacetHelper> list = new ArrayList<FacetHelper>();
Long count = null;
if (rsp != null && rsp.facets() != null) {
List<Facet> facets = rsp.facets().facets();
if (facets != null)
for (Facet f : facets) {
if (!(f instanceof QueryFacet))
continue;
int firstIndex = f.getName().indexOf(SAVED_SEARCHES + "_");
if (firstIndex < 0)
continue;
long val = -1;
try {
val = Long.parseLong(f.getName().substring(firstIndex + SAVED_SEARCHES.length() + 1));
} catch (Exception ex) {
}
// do not exclude smaller zero
count = ((QueryFacet) f).count();
if (count == null)
count = 0L;
list.add(new FacetHelper<Long>(SAVED_SEARCHES, val, translate(val), count));
}
}
return list;
}
private static Comparator<FacetHelper> comp = new Comparator<FacetHelper>() {
@Override
public int compare(FacetHelper o1, FacetHelper o2) {
long val1 = (Long) o1.value;
long val2 = (Long) o2.value;
if (val1 < val2)
return -1;
else if (val1 > val2)
return 1;
else
return 0;
}
};
public void updateSSCounts(AjaxRequestTarget target) {
}
public void update(SearchResponse rsp) {
// TODO what if updateSaveSearches failed???
savedSearches.clear();
if (rsp != null) {
for (FacetHelper helper : createFacetsFields(rsp)) {
if (helper != null)
savedSearches.add(helper);
}
}
Collections.sort(savedSearches, comp);
}
public void onClick(AjaxRequestTarget target, long ssId) {
}
public void onSave(AjaxRequestTarget target, long ssId) {
}
public void onRemove(AjaxRequestTarget target, long ssId) {
}
public String translate(long val) {
return "" + val;
}
}