Files
secondo/Javagui/mmdb/gui/query/ExtensionPanel.java

367 lines
12 KiB
Java
Raw Permalink Normal View History

2026-01-23 17:03:45 +08:00
//This file is part of SECONDO.
//Copyright (C) 2014, University in Hagen, Department of Computer Science,
//Database Systems for New Applications.
//SECONDO 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 2 of the License, or
//(at your option) any later version.
//SECONDO 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 SECONDO; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package mmdb.gui.query;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import mmdb.MMDBUserInterfaceController;
import mmdb.data.MemoryRelation;
import mmdb.data.RelationHeaderItem;
import mmdb.data.attributes.MemoryAttribute;
import mmdb.error.memory.MemoryException;
import mmdb.error.query.QueryException;
import mmdb.gui.QueryDialog;
import mmdb.operator.OperationController;
import mmdb.operator.OperationController.EOperator;
import tools.Reporter;
/**
* The panel representing the 'EXTENSION' query.
*
* @author Alexander Castor
*/
public class ExtensionPanel extends AbstractOperationPanel {
private static final long serialVersionUID = -6679479531695801670L;
/**
* The list of relations from which attributes can be selected.
*/
private JList relationList;
/**
* The list of operations that can be selected.
*/
private JComboBox operatorList;
/**
* The name of the new attribute.
*/
private JTextField attributeName;
/**
* The operator's argument types.
*/
private List<JTextField> argumentTypes = new ArrayList<JTextField>();
/**
* The operator's argument values.
*/
private List<JComboBox> argumentValues = new ArrayList<JComboBox>();
/**
* The number of arguments.
*/
private int numberOfArguments = -1;
/*
* (non-Javadoc)
*
* @see mmdb.gui.operation.AbstractOperationPanel#constructPanel()
*/
@Override
public void constructPanel() {
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
addDescriptionPanel("ADD AN ATTRIBUTE TO A RELATION GENERATED THROUGH AN OPERATOR", this);
JPanel selectionArea = new JPanel(new GridLayout(1, 2));
selectionArea.setPreferredSize(new Dimension(QueryDialog.DIALOG_WIDTH, MIDDLE_HEIGHT));
addRelationPanel(selectionArea);
JPanel rightArea = new JPanel(new GridLayout(2, 1));
rightArea.setPreferredSize(new Dimension(QueryDialog.DIALOG_WIDTH / 2, MIDDLE_HEIGHT));
JPanel rightTopArea = new JPanel(new GridLayout(2, 1));
rightTopArea
.setPreferredSize(new Dimension(QueryDialog.DIALOG_WIDTH / 2, MIDDLE_HEIGHT / 2));
createNamePanel(rightTopArea);
createOperatorPanel(rightTopArea);
rightArea.add(rightTopArea);
createArgumentPanel(rightArea);
selectionArea.add(rightArea);
this.add(selectionArea);
addConvertToListPanel(this);
addButtonPanel(this);
}
/*
* (non-Javadoc)
*
* @see mmdb.gui.query.AbstractOperationPanel#createButtonListener()
*/
@Override
protected ActionListener createButtonListener() {
return new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
if (!selectionOk()) {
Reporter.showInfo("Please select relation, operator, arguments and enter a valid identifier.");
return;
}
MemoryRelation resultRelation = null;
String selectedRelation = (String)relationList.getSelectedValue();
EOperator selectedOperator = (EOperator) operatorList.getSelectedItem();
List<String> arguments = new ArrayList<String>();
for (int i = 0; i < numberOfArguments; i++) {
arguments.add((String) argumentValues.get(i).getSelectedItem());
}
try {
resultRelation = queryController.executeQuery(relations.get(selectedRelation),
selectedOperator, attributeName.getText(), arguments);
} catch (QueryException e) {
Throwable unexpected = e.getUnexpectedError();
if (unexpected != null) {
unexpected.printStackTrace();
Reporter.showError("Unexpected error occured during extension operation.\n"
+ "See console for details.");
} else {
Reporter.showWarning(e.getMessage());
}
return;
} catch (MemoryException e) {
dialog.dispose();
MMDBUserInterfaceController.getInstance().processMemoryException(e);
}
answer[0] = resultRelation;
answer[1] = createObjectName("EXTENDED BY", selectedRelation,
selectedOperator.toString() + " [");
answer[2] = convert.isSelected();
dialog.setVisible(false);
dialog.dispose();
}
};
}
/**
* Adds the relation selection panel to the underlying container.
*
* @param area
* the underlying container the components are added to
*/
private void addRelationPanel(JPanel area) {
Vector<String> vector = new Vector<String>(relations.keySet());
relationList = new JList(vector);
relationList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
relationList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
fillAttributeList();
}
});
JScrollPane relationSelectionPane = new JScrollPane(relationList,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
relationSelectionPane.setBorder(BorderFactory.createTitledBorder("1) RELATION"));
relationSelectionPane.setPreferredSize(new Dimension(QueryDialog.DIALOG_WIDTH / 2,
MIDDLE_HEIGHT));
area.add(relationSelectionPane);
}
/**
* Adds the attribute name panel to the underlying container.
*
* @param area
* the underlying container the components are added to
*/
private void createNamePanel(JPanel area) {
JPanel attributePanel = new JPanel(new FlowLayout());
attributePanel.setBorder(BorderFactory.createTitledBorder("2) IDENTIFIER"));
attributeName = new JTextField();
attributeName.setPreferredSize(new Dimension(200, 30));
attributeName.setHorizontalAlignment(JTextField.CENTER);
attributePanel.add(attributeName);
attributePanel.setBackground(Color.WHITE);
area.add(attributePanel);
}
/**
* Adds the operator panel to the underlying container.
*
* @param area
* the underlying container the components are added to
*/
private void createOperatorPanel(JPanel area) {
JPanel operatorPanel = new JPanel(new FlowLayout());
operatorPanel.setBorder(BorderFactory.createTitledBorder("3) OPERATOR"));
operatorList = new JComboBox(EOperator.values());
operatorList.setPreferredSize(new Dimension(200, 30));
((JLabel) operatorList.getRenderer()).setHorizontalAlignment(SwingConstants.CENTER);
operatorList.setSelectedItem(null);
operatorList.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
adjustArgumentSelections((EOperator) operatorList.getSelectedItem());
}
});
operatorPanel.add(operatorList);
operatorPanel.setBackground(Color.WHITE);
area.add(operatorPanel);
}
/**
* Adds the argument selection panel to the underlying container.
*
* @param area
* the underlying container the components are added to
*/
private void createArgumentPanel(JPanel area) {
JPanel argumentPanel = new JPanel(new GridLayout(3, 1));
argumentPanel.setBorder(BorderFactory.createTitledBorder("4) ARGUMENTS"));
for (int i = 0; i < 3; i++) {
JPanel argumentSubPanel = new JPanel(new FlowLayout());
argumentSubPanel.setBackground(Color.WHITE);
JTextField textField = new JTextField();
textField.setEnabled(false);
textField.setPreferredSize(new Dimension(100, 30));
textField.setHorizontalAlignment(JTextField.CENTER);
argumentSubPanel.add(textField);
argumentTypes.add(textField);
JComboBox comboBox = new JComboBox();
comboBox.setPreferredSize(new Dimension(150, 30));
((JLabel) comboBox.getRenderer()).setHorizontalAlignment(SwingConstants.CENTER);
argumentSubPanel.add(comboBox);
argumentValues.add(comboBox);
argumentPanel.add(argumentSubPanel);
}
argumentPanel.setBackground(Color.WHITE);
hideAllArgumentFields();
area.add(argumentPanel);
}
private void adjustArgumentSelections(EOperator operator) {
Class<?>[] signature = OperationController.getExtMethodSignature(operator);
hideAllArgumentFields();
clearArgumentTypes();
int counter = 0;
for (Class<?> argument : signature) {
argumentTypes.get(counter).setVisible(true);
argumentTypes.get(counter).setText(MemoryAttribute.getTypeName(argument));
argumentValues.get(counter).setVisible(true);
counter++;
}
numberOfArguments = counter;
fillAttributeList();
}
/**
* Fills the attribute lists depending on the current relation and operator
* selection.
*/
private void fillAttributeList() {
if (numberOfArguments < 1 || relationList.isSelectionEmpty()) {
return;
}
clearArgumentValues();
MemoryRelation relation = relations.get(relationList.getSelectedValue());
for (int i = 0; i < numberOfArguments; i++) {
DefaultComboBoxModel model = (DefaultComboBoxModel) argumentValues.get(
i).getModel();
String argumentType = argumentTypes.get(i).getText();
for (RelationHeaderItem item : relation.getHeader()) {
if (!item.isProjected()) {
continue;
}
if (item.getTypeName().equals(argumentType)) {
model.addElement(item.getIdentifier());
}
}
}
}
/**
* Hides all argument fields.
*/
private void hideAllArgumentFields() {
for (JTextField field : argumentTypes) {
field.setVisible(false);
}
for (JComboBox box : argumentValues) {
box.setVisible(false);
}
}
/**
* Clears all argument types.
*/
private void clearArgumentTypes() {
for (JTextField field : argumentTypes) {
field.setText("");
}
}
/**
* Clears all argument values.
*/
private void clearArgumentValues() {
for (JComboBox box : argumentValues) {
DefaultComboBoxModel model = (DefaultComboBoxModel) box.getModel();
model.removeAllElements();
}
}
private boolean selectionOk() {
if (operatorList.getSelectedItem() == null || relationList.getSelectedValue() == null
|| attributeName == null) {
return false;
}
Pattern pattern = Pattern.compile("[a-z,A-Z]([a-z,A-Z]|[0-9]|_)*");
Matcher matcher = pattern.matcher(attributeName.getText());
if (!matcher.matches()) {
return false;
}
MemoryRelation relation = relations.get(relationList.getSelectedValue());
for (RelationHeaderItem item : relation.getHeader()) {
if (item.getIdentifier().equals(attributeName.getText())) {
return false;
}
}
for (int i = 0; i < numberOfArguments; i++) {
if (argumentValues.get(i).getSelectedItem() == null) {
return false;
}
}
return true;
}
}