/** * License Agreement for OpenSearchServer * * Copyright (C) 2008-2014 Emmanuel Keller / Jaeksoft * * http://www.open-search-server.com * * This file is part of OpenSearchServer. * * OpenSearchServer is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenSearchServer is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenSearchServer. * If not, see <http://www.gnu.org/licenses/>. **/ package com.jaeksoft.searchlib.web.controller.query; import java.util.ArrayList; import java.util.List; import org.zkoss.bind.BindContext; import org.zkoss.bind.Converter; import org.zkoss.bind.annotation.AfterCompose; import org.zkoss.bind.annotation.BindingParam; import org.zkoss.bind.annotation.Command; import org.zkoss.bind.annotation.GlobalCommand; import org.zkoss.bind.annotation.NotifyChange; import org.zkoss.zk.ui.Component; import com.jaeksoft.searchlib.Client; import com.jaeksoft.searchlib.ClientCatalog; import com.jaeksoft.searchlib.SearchLibException; import com.jaeksoft.searchlib.join.JoinItem; import com.jaeksoft.searchlib.join.JoinList; import com.jaeksoft.searchlib.request.AbstractSearchRequest; import com.jaeksoft.searchlib.schema.Indexed; import com.jaeksoft.searchlib.schema.SchemaField; import com.jaeksoft.searchlib.sort.SortField; import com.jaeksoft.searchlib.util.StringUtils; @AfterCompose(superclass = true) public class SortedController extends AbstractQueryController { private transient int selectedJoinNumber; private transient String selectedSort; private transient String selectedDirection; private transient String selectedNull; private transient SortField selectedSortField; public SortedController() throws SearchLibException { super(); } @Override protected void reset() throws SearchLibException { selectedSort = null; selectedJoinNumber = 0; selectedDirection = null; selectedSortField = null; } public boolean isSelected() { return selectedSortField != null; } @NotifyChange({ "selectedJoinSelect", "selectedDirection", "selectedSort", "selectedNull" }) public void setSelectedSortField(SortField sortField) throws SearchLibException { this.selectedSortField = sortField; this.selectedSort = sortField.getName(); this.selectedJoinNumber = sortField.getJoinNumber(); this.selectedDirection = sortField.getDirection(); this.selectedNull = NULLS_ARRAY[sortField.isNullFirst() ? 1 : 0]; reload(); } public SortField getSelectedSortField() { return selectedSortField; } public void setSelectedSort(String value) { selectedSort = value; } public String getSelectedSort() { return selectedSort; } public void setSelectedDirection(String value) { selectedDirection = value; } public String getSelectedDirection() { return selectedDirection; } public void setSelectedNull(String value) { selectedNull = value; } public String getSelectedNull() { return selectedNull; } @NotifyChange("sortFieldList") public void setSelectedJoinNumber(int joinNumber) { selectedJoinNumber = joinNumber; resize(); } public int getSelectedJoinNumber() { return selectedJoinNumber; } public List<Integer> getJoinNumberList() throws SearchLibException { AbstractSearchRequest searchRequest = (AbstractSearchRequest) getRequest(); if (searchRequest == null) return null; List<Integer> joinNumberList = new ArrayList<Integer>(1); joinNumberList.add(0); JoinList joinList = searchRequest.getJoinList(); if (joinList == null) return joinNumberList; for (JoinItem joinItem : joinList) joinNumberList.add(joinItem.getPosition()); return joinNumberList; } @Command public void onSortAdd() throws SearchLibException { if (selectedSort == null) return; AbstractSearchRequest request = (AbstractSearchRequest) getRequest(); if (request == null) return; request.getSortFieldList() .put(new SortField( selectedJoinNumber, selectedSort, DIRECTIONS_ARRAY[1].equalsIgnoreCase(selectedDirection), NULLS_ARRAY[1].equalsIgnoreCase(selectedNull))); onSortCancel(); } @Command public void onSortSave() throws SearchLibException { if (selectedSortField == null) return; AbstractSearchRequest request = (AbstractSearchRequest) getRequest(); if (request == null) return; selectedSortField.setJoinNumber(selectedJoinNumber); selectedSortField.setName(selectedSort); selectedSortField.setDirection(selectedDirection); selectedSortField.setNullFirst(NULLS_ARRAY[1].equals(selectedNull)); request.getSortFieldList().rebuildCacheKey(); onSortCancel(); } @Command public void onSortCancel() throws SearchLibException { reset(); reload(); } @Command public void onSortRemove(@BindingParam("sortfield") SortField sortField) throws SearchLibException { AbstractSearchRequest request = (AbstractSearchRequest) getRequest(); if (request == null) return; request.getSortFieldList().remove(sortField.getName()); onSortCancel(); } @Command public void onSortUp(@BindingParam("sortfield") SortField sortField) throws SearchLibException { AbstractSearchRequest request = (AbstractSearchRequest) getRequest(); if (request == null) return; request.getSortFieldList().moveUp(sortField); reload(); } @Command public void onSortDown(@BindingParam("sortfield") SortField sortField) throws SearchLibException { AbstractSearchRequest request = (AbstractSearchRequest) getRequest(); if (request == null) return; request.getSortFieldList().moveDown(sortField); reload(); } private List<String> getFieldList(Client client) { if (client == null) return null; List<String> sortFieldList = new ArrayList<String>(); for (SchemaField field : client.getSchema().getFieldList()) if (field.checkIndexed(Indexed.YES)) sortFieldList.add(field.getName()); sortFieldList.add("score"); sortFieldList.add("__distance__"); return sortFieldList; } private JoinItem getJoinItem(int joinNumber) throws SearchLibException { AbstractSearchRequest searchRequest = (AbstractSearchRequest) getRequest(); if (searchRequest == null) return null; JoinList joinList = searchRequest.getJoinList(); if (joinList == null) return null; JoinItem[] joinItems = joinList.getArray(); if (joinItems == null) return null; if (joinNumber >= joinItems.length) return null; return joinItems[joinNumber]; } public List<String> getSortFieldList() throws SearchLibException { Client client = null; if (selectedJoinNumber == 0) client = getClient(); else { JoinItem joinItem = getJoinItem(selectedJoinNumber - 1); if (joinItem == null) return null; client = ClientCatalog.getClient(joinItem.getIndexName()); } return getFieldList(client); } final static public String[] DIRECTIONS_ARRAY = { "ascending", "descending" }; public String[] getDirectionList() { return DIRECTIONS_ARRAY; } final static public String[] NULLS_ARRAY = { "empty last", "empty first" }; public String[] getNullList() { return NULLS_ARRAY; } @Override @Command public void reload() throws SearchLibException { super.reload(); } @Override @GlobalCommand public void eventSchemaChange(Client client) throws SearchLibException { reload(); } private final NullFirstConverter nullFirstConverter = new NullFirstConverter(); public NullFirstConverter getNullFirstConverter() { return nullFirstConverter; } private final JoinLabelConverter joinLabelConverter = new JoinLabelConverter(); public JoinLabelConverter getJoinLabelConverter() { return joinLabelConverter; } public class NullFirstConverter implements Converter<Object, Object, Component> { @Override public Object coerceToBean(Object value, Component component, BindContext ctx) { return IGNORED_VALUE; } @Override public Object coerceToUi(Object value, Component component, BindContext ctx) { if (value == null) return IGNORED_VALUE; return ((Boolean) value) ? "First" : "Last"; } } public class JoinLabelConverter implements Converter<Object, Object, Component> { @Override public Object coerceToBean(Object value, Component component, BindContext ctx) { return IGNORED_VALUE; } @Override public Object coerceToUi(Object value, Component component, BindContext ctx) { if (value == null) return IGNORED_VALUE; Integer joinNumber = (Integer) value; try { if (joinNumber == 0) return getIndexName(); JoinItem joinItem = getJoinItem(joinNumber - 1); if (joinItem == null) return IGNORED_VALUE; return StringUtils.fastConcat(joinItem.getIndexName(), " - ", joinItem.getParamPosition()); } catch (SearchLibException e) { return IGNORED_VALUE; } } } }