blob: d86215971a76325372001db73b7a1788da859608 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.lucene.luke.app.desktop.components.fragments.search;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.apache.lucene.luke.app.desktop.components.ComponentOperatorRegistry;
import org.apache.lucene.luke.app.desktop.components.SearchTabOperator;
import org.apache.lucene.luke.app.desktop.util.MessageUtils;
import org.apache.lucene.luke.app.desktop.util.StringUtils;
import org.apache.lucene.luke.models.search.Search;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.SortedNumericSortField;
/** Provider of the Sort pane */
public final class SortPaneProvider implements SortTabOperator {
private static final String COMMAND_FIELD_COMBO1 = "fieldCombo1";
private static final String COMMAND_FIELD_COMBO2 = "fieldCombo2";
private final JComboBox<String> fieldCombo1 = new JComboBox<>();
private final JComboBox<String> typeCombo1 = new JComboBox<>();
private final JComboBox<String> orderCombo1 = new JComboBox<>(Order.names());
private final JComboBox<String> fieldCombo2 = new JComboBox<>();
private final JComboBox<String> typeCombo2 = new JComboBox<>();
private final JComboBox<String> orderCombo2 = new JComboBox<>(Order.names());
private final ListenerFunctions listeners = new ListenerFunctions();
private final ComponentOperatorRegistry operatorRegistry;
private Search searchModel;
public SortPaneProvider() {
this.operatorRegistry = ComponentOperatorRegistry.getInstance();
operatorRegistry.register(SortTabOperator.class, this);
}
public JScrollPane get() {
JPanel panel = new JPanel(new GridLayout(1, 1));
panel.setOpaque(false);
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
panel.add(initSortConfigsPanel());
JScrollPane scrollPane = new JScrollPane(panel);
scrollPane.setOpaque(false);
scrollPane.getViewport().setOpaque(false);
return scrollPane;
}
private JPanel initSortConfigsPanel() {
JPanel panel = new JPanel(new GridLayout(5, 1));
panel.setOpaque(false);
panel.setMaximumSize(new Dimension(500, 200));
panel.add(new JLabel(MessageUtils.getLocalizedMessage("search_sort.label.primary")));
JPanel primary = new JPanel(new FlowLayout(FlowLayout.LEADING));
primary.setOpaque(false);
primary.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));
primary.add(new JLabel(MessageUtils.getLocalizedMessage("search_sort.label.field")));
fieldCombo1.setPreferredSize(new Dimension(150, 30));
fieldCombo1.setActionCommand(COMMAND_FIELD_COMBO1);
fieldCombo1.addActionListener(listeners::changeField);
primary.add(fieldCombo1);
primary.add(new JLabel(MessageUtils.getLocalizedMessage("search_sort.label.type")));
typeCombo1.setPreferredSize(new Dimension(130, 30));
typeCombo1.addItem("");
typeCombo1.setEnabled(false);
primary.add(typeCombo1);
primary.add(new JLabel(MessageUtils.getLocalizedMessage("search_sort.label.order")));
orderCombo1.setPreferredSize(new Dimension(100, 30));
orderCombo1.setEnabled(false);
primary.add(orderCombo1);
panel.add(primary);
panel.add(new JLabel(MessageUtils.getLocalizedMessage("search_sort.label.secondary")));
JPanel secondary = new JPanel(new FlowLayout(FlowLayout.LEADING));
secondary.setOpaque(false);
secondary.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));
secondary.add(new JLabel(MessageUtils.getLocalizedMessage("search_sort.label.field")));
fieldCombo2.setPreferredSize(new Dimension(150, 30));
fieldCombo2.setActionCommand(COMMAND_FIELD_COMBO2);
fieldCombo2.addActionListener(listeners::changeField);
secondary.add(fieldCombo2);
secondary.add(new JLabel(MessageUtils.getLocalizedMessage("search_sort.label.type")));
typeCombo2.setPreferredSize(new Dimension(130, 30));
typeCombo2.addItem("");
typeCombo2.setEnabled(false);
secondary.add(typeCombo2);
secondary.add(new JLabel(MessageUtils.getLocalizedMessage("search_sort.label.order")));
orderCombo2.setPreferredSize(new Dimension(100, 30));
orderCombo2.setEnabled(false);
secondary.add(orderCombo2);
panel.add(secondary);
JPanel clear = new JPanel(new FlowLayout(FlowLayout.LEADING));
clear.setOpaque(false);
JButton clearBtn = new JButton(MessageUtils.getLocalizedMessage("button.clear"));
clearBtn.addActionListener(listeners::clear);
clear.add(clearBtn);
panel.add(clear);
return panel;
}
@Override
public void setSearchModel(Search model) {
searchModel = model;
}
@Override
public void setSortableFields(Collection<String> sortableFields) {
fieldCombo1.removeAllItems();
fieldCombo2.removeAllItems();
fieldCombo1.addItem("");
fieldCombo2.addItem("");
for (String field : sortableFields) {
fieldCombo1.addItem(field);
fieldCombo2.addItem(field);
}
}
@Override
public Sort getSort() {
if (StringUtils.isNullOrEmpty((String) fieldCombo1.getSelectedItem())
&& StringUtils.isNullOrEmpty((String) fieldCombo2.getSelectedItem())) {
return null;
}
List<SortField> li = new ArrayList<>();
if (!StringUtils.isNullOrEmpty((String) fieldCombo1.getSelectedItem())) {
searchModel.getSortType((String) fieldCombo1.getSelectedItem(), (String) typeCombo1.getSelectedItem(), isReverse(orderCombo1)).ifPresent(li::add);
}
if (!StringUtils.isNullOrEmpty((String) fieldCombo2.getSelectedItem())) {
searchModel.getSortType((String) fieldCombo2.getSelectedItem(), (String) typeCombo2.getSelectedItem(), isReverse(orderCombo2)).ifPresent(li::add);
}
return new Sort(li.toArray(new SortField[0]));
}
private boolean isReverse(JComboBox<String> order) {
return Order.valueOf((String) order.getSelectedItem()) == Order.DESC;
}
private class ListenerFunctions {
void changeField(ActionEvent e) {
if (e.getActionCommand().equalsIgnoreCase(COMMAND_FIELD_COMBO1)) {
resetField(fieldCombo1, typeCombo1, orderCombo1);
} else if (e.getActionCommand().equalsIgnoreCase(COMMAND_FIELD_COMBO2)) {
resetField(fieldCombo2, typeCombo2, orderCombo2);
}
resetExactHitsCnt();
}
private void resetField(JComboBox<String> fieldCombo, JComboBox<String> typeCombo, JComboBox<String> orderCombo) {
typeCombo.removeAllItems();
if (StringUtils.isNullOrEmpty((String) fieldCombo.getSelectedItem())) {
typeCombo.addItem("");
typeCombo.setEnabled(false);
orderCombo.setEnabled(false);
} else {
List<SortField> sortFields = searchModel.guessSortTypes((String) fieldCombo.getSelectedItem());
sortFields.stream()
.map(sf -> {
if (sf instanceof SortedNumericSortField) {
return ((SortedNumericSortField) sf).getNumericType().name();
} else {
return sf.getType().name();
}
}).forEach(typeCombo::addItem);
typeCombo.setEnabled(true);
orderCombo.setEnabled(true);
}
}
void clear(ActionEvent e) {
fieldCombo1.setSelectedIndex(0);
typeCombo1.removeAllItems();
typeCombo1.setSelectedItem("");
typeCombo1.setEnabled(false);
orderCombo1.setSelectedIndex(0);
orderCombo1.setEnabled(false);
fieldCombo2.setSelectedIndex(0);
typeCombo2.removeAllItems();
typeCombo2.setSelectedItem("");
typeCombo2.setEnabled(false);
orderCombo2.setSelectedIndex(0);
orderCombo2.setEnabled(false);
resetExactHitsCnt();
}
private void resetExactHitsCnt() {
operatorRegistry.get(SearchTabOperator.class).ifPresent(operator -> {
if (StringUtils.isNullOrEmpty((String) fieldCombo1.getSelectedItem()) &&
StringUtils.isNullOrEmpty((String) fieldCombo2.getSelectedItem())) {
operator.enableExactHitsCB(true);
operator.setExactHits(false);
} else {
operator.enableExactHitsCB(false);
operator.setExactHits(true);
}
});
}
}
enum Order {
ASC, DESC;
static String[] names() {
return Arrays.stream(values()).map(Order::name).toArray(String[]::new);
}
}
}