/*
* 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 ro.nextreports.designer.querybuilder;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.InputEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.border.TitledBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.jdesktop.swingx.JXList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import ro.nextreports.designer.Globals;
import ro.nextreports.designer.action.query.DeselectListAction;
import ro.nextreports.designer.datasource.DefaultDataSourceManager;
import ro.nextreports.designer.datasource.DefaultSchemaManager;
import ro.nextreports.designer.dbviewer.DefaultDBViewer;
import ro.nextreports.designer.dbviewer.common.DBColumn;
import ro.nextreports.designer.dbviewer.common.DBInfo;
import ro.nextreports.designer.dbviewer.common.DBTable;
import ro.nextreports.designer.dbviewer.common.DBViewer;
import ro.nextreports.designer.dbviewer.common.MalformedTableNameException;
import ro.nextreports.designer.dbviewer.common.NextSqlException;
import ro.nextreports.designer.util.I18NSupport;
import ro.nextreports.designer.util.ImageUtil;
import ro.nextreports.designer.util.Show;
import ro.nextreports.engine.querybuilder.sql.dialect.Dialect;
/**
* Created by IntelliJ IDEA.
* User: mihai.panaitescu
* Date: Apr 4, 2006
* Time: 2:34:20 PM
*/
public class SelectionColumnPanel extends JPanel {
private JComboBox schemaCombo;
private JXList tableList;
private JXList columnList;
private JXList shownColumnList;
private JScrollPane scrTable;
private JScrollPane scrColumn;
private JScrollPane scrShownColumn;
private DefaultListModel tableModel = new DefaultListModel();
private DefaultListModel columnModel = new DefaultListModel();
private DefaultListModel shownColumnModel = new DefaultListModel();
private Dimension scrDim = new Dimension(200, 200);
private Dimension comboDim = new Dimension(200, 20);
private String schema;
private boolean show = true;
private boolean singleSelection = true;
private static final Log LOG = LogFactory.getLog(SelectionColumnPanel.class);
public SelectionColumnPanel(String schema) {
this.schema = schema;
buildUI();
}
public SelectionColumnPanel(String schema, boolean show, boolean singleSelection) {
this.schema = schema;
this.show = show;
this.singleSelection = singleSelection;
buildUI();
}
private void buildUI() {
setLayout(new GridBagLayout());
final DBViewer viewer = Globals.getDBViewer();
schemaCombo = new JComboBox();
schemaCombo.setPreferredSize(comboDim);
schemaCombo.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
String schema = (String) e.getItem();
shownColumnModel.clear();
columnModel.clear();
tableModel.clear();
try {
DBInfo dbInfo = viewer.getDBInfo(schema, DBInfo.TABLES | DBInfo.VIEWS);
List<DBTable> tables = dbInfo.getTables();
Collections.sort(tables);
for (DBTable table : tables) {
tableModel.addElement(table);
}
} catch (NextSqlException ex) {
LOG.error(ex.getMessage(), ex);
ex.printStackTrace();
}
}
});
try {
List<String> schemas = viewer.getSchemas();
String schemaName = viewer.getUserSchema();
Collections.sort(schemas);
boolean added = false;
for (String schema : schemas) {
if (DefaultSchemaManager.getInstance().isVisible(
DefaultDataSourceManager.getInstance().getConnectedDataSource().getName(), schema)) {
added = true;
schemaCombo.addItem(schema);
}
}
if ((schema == null) || schema.equals(DefaultDBViewer.NO_SCHEMA_NAME)) {
schema = DefaultDBViewer.NO_SCHEMA_NAME;//viewer.getUserSchema();
}
if (!added) {
schemaCombo.addItem(schema);
}
schemaCombo.setSelectedItem(schema);
} catch (NextSqlException e) {
LOG.error(e.getMessage(), e);
e.printStackTrace();
}
// create table list
tableList = new JXList(tableModel);
tableList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
tableList.setCellRenderer(new DBTableCellRenderer());
// create column list
columnList = new JXList(columnModel);
if (singleSelection) {
columnList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
} else {
columnList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
}
columnList.setCellRenderer(new DBColumnCellRenderer());
shownColumnList = new JXList(shownColumnModel);
if (singleSelection) {
shownColumnList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
} else {
columnList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
}
addDoubleClick();
shownColumnList.setCellRenderer(new DBColumnCellRenderer());
shownColumnList.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent mouseEvent) {
if ((mouseEvent.getModifiers() & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK) {
JPopupMenu popupMenu = new JPopupMenu();
JMenuItem menuItem = new JMenuItem(new DeselectListAction(shownColumnList));
popupMenu.add(menuItem);
popupMenu.show((Component) mouseEvent.getSource(), mouseEvent.getX(), mouseEvent.getY());
}
}
});
tableList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting() == false) {
int index = tableList.getSelectedIndex();
if (index == -1) {
return;
}
DBTable table = (DBTable) tableModel.getElementAt(index);
try {
List<DBColumn> columns = null;
try {
columns = viewer.getColumns(table.getSchema(), table.getName());
} catch (MalformedTableNameException e1) {
Show.error("Malformed table name : " + table.getName());
return;
}
Collections.sort(columns);
columnModel.clear();
shownColumnModel.clear();
for (DBColumn column : columns) {
columnModel.addElement(column);
shownColumnModel.addElement(column);
}
} catch (NextSqlException e1) {
LOG.error(e1.getMessage(), e1);
e1.printStackTrace();
Show.error(e1);
}
}
}
});
columnList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
shownColumnList.clearSelection();
}
});
scrTable = new JScrollPane(tableList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrTable.setPreferredSize(scrDim);
scrTable.setMinimumSize(scrDim);
scrTable.setBorder(new TitledBorder(I18NSupport.getString("parameter.source.tables")));
scrColumn = new JScrollPane(columnList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrColumn.setPreferredSize(scrDim);
scrColumn.setMinimumSize(scrDim);
scrColumn.setBorder(new TitledBorder(I18NSupport.getString("parameter.source.columns")));
scrShownColumn = new JScrollPane(shownColumnList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrShownColumn.setPreferredSize(scrDim);
scrShownColumn.setMinimumSize(scrDim);
scrShownColumn.setBorder(new TitledBorder(I18NSupport.getString("parameter.source.shown.columns")));
JPanel schemaPanel = new JPanel();
schemaPanel.setLayout(new BoxLayout(schemaPanel, BoxLayout.X_AXIS));
schemaPanel.add(new JLabel("Schema"));
schemaPanel.add(Box.createHorizontalStrut(5));
schemaPanel.add(schemaCombo);
add(schemaPanel, new GridBagConstraints(0, 0, 3, 1, 0.0, 0.0, GridBagConstraints.WEST,
GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
add(scrTable, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.WEST,
GridBagConstraints.BOTH, new Insets(0, 0, 0, 5), 0, 0));
add(scrColumn, new GridBagConstraints(1, 1, 1, 1, 1.0, 1.0, GridBagConstraints.WEST,
GridBagConstraints.BOTH, new Insets(0, 0, 0, 5), 0, 0));
if (show) {
add(scrShownColumn, new GridBagConstraints(2, 1, 1, 1, 1.0, 1.0, GridBagConstraints.WEST,
GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
}
}
private void addDoubleClick() {
columnList.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
onDoubleClick();
}
}
});
}
protected void onDoubleClick(){
}
class DBTableCellRenderer extends DefaultListCellRenderer {
public Component getListCellRendererComponent(JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
JLabel comp = (JLabel) super.getListCellRendererComponent(list, value, index,
isSelected, cellHasFocus);
if (value != null) {
DBTable table = (DBTable) value;
if (table.getType().equals("VIEW")) {
comp.setIcon(ImageUtil.VIEW_IMAGE_ICON);
comp.setText(table.getName());
} else {
comp.setIcon(ImageUtil.TABLE_IMAGE_ICON);
comp.setText(table.getName());
}
value = table.getName();
list.setToolTipText(value.toString());
}
return comp;
}
}
class DBColumnCellRenderer extends DefaultListCellRenderer {
private final Icon primaryKeyIcon = ImageUtil.getImageIcon("keycolumn");
private final Icon foreignKeyIcon = ImageUtil.getImageIcon("fkeycolumn");
private final Icon indexKeyIcon = ImageUtil.getImageIcon("icolumn");
private final Icon columnIcon = ImageUtil.getImageIcon("column");
public Component getListCellRendererComponent(JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
JLabel comp = (JLabel) super.getListCellRendererComponent(list, value, index,
isSelected, cellHasFocus);
if (value != null) {
DBColumn column = (DBColumn) value;
if (column.isPrimaryKey()) {
comp.setIcon(primaryKeyIcon);
comp.setText(column.getName());
} else if (column.isForeignKey()) {
comp.setIcon(foreignKeyIcon);
comp.setText(column.getName());
} else if (column.isIndex()) {
comp.setIcon(indexKeyIcon);
comp.setText(column.getName());
} else {
comp.setIcon(columnIcon);
comp.setText(column.getName());
}
value = column.getName();
list.setToolTipText(value.toString());
}
return comp;
}
}
public DBColumn getSelectedColumn() {
return (DBColumn) columnList.getSelectedValue();
}
public List<DBColumn> getSelectedColumns() {
Object[] array = columnList.getSelectedValues();
List<DBColumn> result = new ArrayList<DBColumn>();
for (Object obj : array) {
result.add((DBColumn)obj);
}
return result;
}
public List<DBColumn> getAllColumns() {
Object[] array = columnModel.toArray();
List<DBColumn> result = new ArrayList<DBColumn>();
for (Object obj : array) {
result.add((DBColumn) obj);
}
return result;
}
public DBColumn getSelectedShownColumn() {
return (DBColumn) shownColumnList.getSelectedValue();
}
public String getJavaTypeForSelectedColumn() {
DBColumn column = getSelectedColumn();
return getJavaTypeForColumn(column);
}
public String getJavaTypeForSelectedShownColumn() {
DBColumn column = getSelectedShownColumn();
return getJavaTypeForColumn(column);
}
private String getJavaTypeForColumn(DBColumn column) {
// dialect
Dialect dialect = null;
try {
dialect = Globals.getDialect();
// System.out.println("dialect =" + dialect + " columnType=" + column.getType() +
// " precision=" + column.getPrecision() + " scale=" + column.getScale());
return dialect.getJavaType(column.getType(), column.getPrecision(), column.getScale());
} catch (Exception ex) {
LOG.error(ex.getMessage(), ex);
ex.printStackTrace();
return "";
}
}
private DBTable getTable(String tableName) {
for (int i = 0, size = tableModel.size(); i < size; i++) {
DBTable table = (DBTable) tableModel.getElementAt(i);
if (table.getName().equals(tableName)) {
return table;
}
}
return null;
}
private DBColumn getColumn(String tableName, String columnName) {
for (int i = 0, size = columnModel.size(); i < size; i++) {
DBColumn column = (DBColumn) columnModel.getElementAt(i);
if (column.getTable().equals(tableName) && column.getName().equals(columnName)) {
return column;
}
}
return null;
}
private DBColumn getShownColumn(String tableName, String columnName) {
for (int i = 0, size = shownColumnModel.size(); i < size; i++) {
DBColumn column = (DBColumn) shownColumnModel.getElementAt(i);
if (column.getTable().equals(tableName) && column.getName().equals(columnName)) {
return column;
}
}
return null;
}
public void setColumns(String source) {
if ((schema != null) && (!schema.equals("%"))) {
schemaCombo.setSelectedItem(schema);
}
int index = source.indexOf(".");
int index2 = source.lastIndexOf(".");
if (index < 1) {
throw new IllegalArgumentException("Invalid source " + source);
}
String tableName = source.substring(0, index);
String columnName;
String shownColumnName = null;
if (index == index2) {
columnName = source.substring(index + 1);
} else {
columnName = source.substring(index + 1, index2);
shownColumnName = source.substring(index2 + 1);
}
DBTable table = getTable(tableName);
if (table != null) {
tableList.setSelectedValue(table, true);
DBColumn column = getColumn(tableName, columnName);
columnList.setSelectedValue(column, true);
if (shownColumnName != null) {
DBColumn shownColumn = getShownColumn(tableName, shownColumnName);
shownColumnList.setSelectedValue(shownColumn, true);
}
}
}
public String getSchema() {
return (String)schemaCombo.getSelectedItem();
}
}