You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
545 lines
15 KiB
545 lines
15 KiB
// Beispielklasse aus dem JavaTutorial (http://java.sun.com/docs/books/tutorial) für SuperX angepasst |
|
/* |
|
* @(#)JDBCAdapter.java 1.5 97/12/03 |
|
* |
|
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. |
|
* |
|
* This software is the confidential and proprietary information of Sun |
|
* Microsystems, Inc. ("Confidential Information"). You shall not |
|
* disclose such Confidential Information and shall use it only in |
|
* accordance with the terms of the license agreement you entered into |
|
* with Sun. |
|
* |
|
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE |
|
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE |
|
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR |
|
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES |
|
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING |
|
* THIS SOFTWARE OR ITS DERIVATIVES. |
|
* |
|
*/ |
|
|
|
/** |
|
* An adaptor, transforming the JDBC interface to the TableModel interface. |
|
* |
|
* @version 1.20 09/25/97 |
|
* @author Philip Milne |
|
*/ |
|
|
|
package de.superx.applet; |
|
import java.math.BigDecimal; |
|
import java.sql.Connection; |
|
import java.sql.ResultSet; |
|
import java.sql.SQLException; |
|
import java.sql.Statement; |
|
import java.sql.Timestamp; |
|
import java.sql.Types; |
|
import java.text.NumberFormat; |
|
import java.text.ParseException; |
|
import java.util.Properties; |
|
import java.util.Vector; |
|
|
|
import javax.swing.table.AbstractTableModel; |
|
|
|
import de.superx.common.SuperX_el; |
|
|
|
|
|
/** |
|
* Ein Adapter, der das JDBC-Interface an das TableModel-Interface anpasst. |
|
* Angepasst für SuperX |
|
* @autor Philip Milne, erweitert von R. Behr |
|
* @version 1.2 |
|
*/ |
|
|
|
public class SxJDBCAdapter extends AbstractTableModel implements SxTableModel { |
|
Connection connection; |
|
Properties db_props = null; |
|
boolean isClosed = true; |
|
boolean isEditable = false; |
|
Statement statement = null; |
|
ResultSet resultSet = null; |
|
String[] columnNames = {}; |
|
Class[] columnTpyes = {}; |
|
Vector rows = new Vector(); |
|
SxSQLMetaData metaData; |
|
NumberFormat nf = NumberFormat.getInstance(); |
|
//DecimalFormat df=(DecimalFormat) nf; |
|
|
|
/* public SxJDBCAdapter(String url, String driverName, |
|
String user, String passwd) throws Exception { |
|
try |
|
{ |
|
Class.forName(driverName); |
|
System.err.println("Opening db connection"); |
|
|
|
if (!isClosed) |
|
{ |
|
statement.close(); |
|
connection.close (); |
|
isClosed = true; |
|
} |
|
|
|
db_props = new Properties (); |
|
db_props.put ("user", user); |
|
db_props.put ("password", passwd); |
|
|
|
connection = DriverManager.getConnection(url, db_props); |
|
statement = connection.createStatement(); |
|
isClosed = false; |
|
} |
|
catch (Exception ex) |
|
{ |
|
isClosed = true; |
|
throw new SQLException (ex.toString()); |
|
} |
|
}*/ |
|
|
|
public SxJDBCAdapter() {} |
|
|
|
public void executeQuery(String query) throws SQLException |
|
{ |
|
resultSet = statement.executeQuery(query); |
|
// resultSet = statement.getResultSet(); |
|
metaData = new SxSQLMetaData (new SuperX_el()); |
|
//metaData = resultSet.getMetaData(); |
|
|
|
int numberOfColumns = metaData.getColumnCount(); |
|
columnNames = new String[numberOfColumns]; |
|
// Get the column names and cache them. |
|
// Then we can close the connection. |
|
for(int column = 0; column < numberOfColumns; column++) |
|
{ |
|
columnNames[column] = metaData.getColumnLabel(column+1); |
|
// System.err.println ("Column: " + columnNames[column] + ", max width: " + |
|
// metaData.getColumnDisplaySize(column+1)); |
|
} |
|
|
|
// Get all rows. |
|
rows = new Vector(); |
|
while (resultSet.next()) |
|
{ |
|
Vector newRow = new Vector(); |
|
for (int i = 0; i < getColumnCount(); i++) |
|
{ |
|
// newRow.addElement(dbRepresentation(i, resultSet.getObject(i + 1))); |
|
newRow.addElement(resultSet.getObject(i + 1)); |
|
} |
|
rows.addElement(newRow); |
|
} |
|
// close(); // Need to copy the metaData, bug in jdbc:odbc driver. |
|
fireTableChanged(null); // Tell the listeners a new table has arrived. |
|
} |
|
|
|
public void cancel(String url, String user, String passwd) throws Exception |
|
{ |
|
try |
|
{ |
|
System.err.println("Cancel statement"); |
|
statement.cancel(); |
|
} |
|
catch (Exception e) |
|
{ |
|
System.err.println("Error canceling statement: " + e); |
|
} |
|
} |
|
|
|
public void close() throws SQLException |
|
{ |
|
try |
|
{ |
|
System.err.println("Closing db connection"); |
|
if (!isClosed) |
|
{ |
|
if (resultSet != null) |
|
resultSet.close(); |
|
if (statement != null) |
|
statement.close(); |
|
connection.close(); |
|
isClosed = true; |
|
} |
|
} |
|
catch (SQLException e) |
|
{ |
|
System.err.println("Error closing db connection: " + e); |
|
} |
|
} |
|
|
|
protected void finalize() throws Throwable |
|
{ |
|
if (!isClosed) |
|
{ |
|
close(); |
|
isClosed = true; |
|
} |
|
super.finalize(); |
|
} |
|
|
|
////////////////////////////////////////////////////////////////////////// |
|
// |
|
// Implementation des TableModelInterface |
|
// |
|
////////////////////////////////////////////////////////////////////////// |
|
|
|
// MetaData |
|
|
|
public String getColumnName(int column) { |
|
if (columnNames[column] != null) { |
|
return columnNames[column]; |
|
} else { |
|
return ""; |
|
} |
|
} |
|
|
|
public int getColumnSize(int column) |
|
{ |
|
if (metaData == null) |
|
return -1; |
|
|
|
return metaData.getColumnDisplaySize(column+1); |
|
} |
|
|
|
public Class getColumnClass(int column) |
|
{ |
|
int type; |
|
|
|
if (metaData == null) |
|
return Object.class; |
|
|
|
type = metaData.getColumnType(column+1); |
|
|
|
switch(type) |
|
{ |
|
case Types.CHAR: |
|
case Types.VARCHAR: |
|
case Types.LONGVARCHAR: |
|
return String.class; |
|
|
|
case Types.BIT: |
|
return Boolean.class; |
|
|
|
case Types.TINYINT: |
|
case Types.SMALLINT: |
|
return Short.class; |
|
|
|
case Types.INTEGER: |
|
return Integer.class; |
|
|
|
case Types.BIGINT: |
|
return Long.class; |
|
|
|
case Types.FLOAT: |
|
case Types.DOUBLE: |
|
return Double.class; |
|
|
|
case Types.DATE: |
|
return java.sql.Date.class; |
|
|
|
case Types.DECIMAL: |
|
case Types.NUMERIC: |
|
return java.math.BigDecimal.class; |
|
|
|
case Types.TIMESTAMP: |
|
return java.sql.Timestamp.class; |
|
|
|
default: |
|
return Object.class; |
|
} |
|
} |
|
|
|
public void setEditable(boolean editable) |
|
{ |
|
isEditable = editable; |
|
} |
|
|
|
public boolean isCellEditable(int row, int column) |
|
{ |
|
if (isEditable) |
|
return metaData.isWritable(column); |
|
else |
|
return false; |
|
} |
|
|
|
public int getColumnCount() { |
|
return columnNames.length; |
|
} |
|
|
|
// Data methods |
|
|
|
public int getRowCount() { |
|
return rows.size(); |
|
} |
|
|
|
public Object getValueAt(int aRow, int aColumn) |
|
{ |
|
Vector row = (Vector)rows.elementAt(aRow); |
|
Object value = row.elementAt(aColumn); |
|
return dbRepresentation(aColumn, value, true); |
|
} |
|
|
|
public Object getObjectAt(int aRow, int aColumn) |
|
{ |
|
Vector row = (Vector)rows.elementAt(aRow); |
|
return row.elementAt(aColumn); |
|
} |
|
|
|
private String dbRepresentation(int column, Object value, boolean isDecimalParsingWanted) |
|
{ |
|
int type; |
|
int scale; |
|
double db; |
|
String str; |
|
|
|
if (metaData == null) |
|
return value.toString(); |
|
|
|
if (value == null||value.equals("")) |
|
return " "; |
|
|
|
type = metaData.getColumnType(column+1); |
|
scale = metaData.getScale(column+1); |
|
|
|
switch(type) |
|
{ |
|
case Types.SMALLINT: |
|
int int_value = Short.MIN_VALUE; |
|
if (value instanceof Short) |
|
int_value = ((Short) value).shortValue(); |
|
else |
|
if (value instanceof Integer) |
|
int_value = ((Integer) value).intValue(); |
|
if (int_value == Short.MIN_VALUE) |
|
return (" "); |
|
return value.toString(); |
|
case Types.INTEGER: |
|
if (!(value instanceof Integer)) |
|
return value.toString(); |
|
if (((Integer) value).intValue() == Integer.MIN_VALUE) |
|
return (" "); |
|
return value.toString(); |
|
case Types.DOUBLE: |
|
if (isDecimalParsingWanted) |
|
{ |
|
if (((Double) value).isNaN()) |
|
return " "; |
|
nf.setMinimumFractionDigits(scale); // r.b. Nachkommastellen setzen |
|
nf.setGroupingUsed(true); |
|
//df.setDecimalSeparatorAlwaysShown(true); |
|
//df.applyLocalizedPattern("#.#00,0#"); |
|
if (scale > 3) |
|
nf.setMaximumFractionDigits(3); // r.b. Nachkommastellen setzen |
|
return nf.format((Double) value); |
|
} |
|
else |
|
return value.toString(); |
|
case Types.DECIMAL: |
|
case Types.NUMERIC: |
|
if (isDecimalParsingWanted) |
|
{ |
|
db = ((BigDecimal) value).doubleValue(); |
|
nf.setGroupingUsed(true); |
|
if (db == Double.NaN) |
|
return " "; |
|
//MB bigdecimal kann immer >65000 Nachkommastellen haben, wird immer auf 5 gesetzt |
|
//bei Studiabfragen nach Abschlüssen, ist wahrscheinlich ganz gut, dass ,00 verschwindet (wenngleich gewichtete Fälle) |
|
//bei Cob abfragen wäre schön |
|
//if (scale > 5) nf.setMaximumFractionDigits(5); // r.b. Nachkommastellen setzen |
|
//else nf.setMinimumFractionDigits(scale); // r.b. Nachkommastellen setzen |
|
//, einfach mal fest von 2 ausgehen |
|
nf.setMaximumFractionDigits(2); |
|
nf.setMinimumFractionDigits(2); |
|
//df.setDecimalSeparatorAlwaysShown(true); |
|
//df.applyLocalizedPattern("#.#00,0#"); |
|
return nf.format(db); |
|
} |
|
else |
|
return value.toString(); |
|
case Types.BIT: |
|
return ((Boolean)value).booleanValue() ? "1" : "0"; |
|
case Types.DATE: |
|
str = SxDate.toString((java.sql.Date) value); |
|
if (str.length() == 0) |
|
return (" "); |
|
return str; |
|
case Types.TIMESTAMP: |
|
str = ((Timestamp) value).toString(); |
|
if (str.length() == 0) |
|
return (" "); |
|
return str; |
|
default: |
|
if (value.toString().length() == 0) |
|
return (" "); |
|
return value.toString(); |
|
} |
|
} |
|
|
|
private Object tableRepresentation(int column, Object value) |
|
{ |
|
int type; |
|
|
|
if (value == null) |
|
{ |
|
return ""; |
|
} |
|
|
|
if (metaData == null) |
|
return value; |
|
|
|
type = metaData.getColumnType(column+1); |
|
|
|
switch(type) |
|
{ |
|
case Types.SMALLINT: |
|
{ |
|
try |
|
{ |
|
return new Short (value.toString()); |
|
} |
|
catch (NumberFormatException e) |
|
{ |
|
System.err.println ("tableRepresentation: ERROR: " + value.toString()); |
|
return ""; |
|
} |
|
} |
|
case Types.INTEGER: |
|
{ |
|
try |
|
{ |
|
return new Integer (value.toString()); |
|
} |
|
catch (NumberFormatException e) |
|
{ |
|
System.err.println ("tableRepresentation: ERROR: " + value.toString()); |
|
return ""; |
|
} |
|
} |
|
case Types.DOUBLE: |
|
case Types.FLOAT: |
|
{ |
|
try |
|
{ |
|
Number new_number = nf.parse(value.toString()); |
|
Double new_double = new Double(new_number.doubleValue()); |
|
return new_double; |
|
} |
|
catch (ParseException e) |
|
{ |
|
System.err.println ("tableRepresentation: ERROR parse: Double=" + value.toString()); |
|
return ""; |
|
} |
|
} |
|
case Types.DECIMAL: |
|
{ |
|
try |
|
{ |
|
Number new_number = nf.parse(value.toString()); |
|
BigDecimal new_dec = new BigDecimal(new_number.doubleValue()); |
|
return new_dec; |
|
} |
|
catch (ParseException e) |
|
{ |
|
System.err.println ("tableRepresentation: ERROR parse: BigDecimal=" + value.toString()); |
|
return ""; |
|
} |
|
} |
|
case Types.BIT: |
|
return new Boolean (value.toString()); |
|
case Types.DATE: |
|
return SxDate.getDate(value.toString()); |
|
case Types.TIMESTAMP: |
|
return Timestamp.valueOf(value.toString()); |
|
default: |
|
return value; |
|
} |
|
|
|
} |
|
|
|
public void setValueAt(Object value, int row, int column) |
|
{ |
|
try |
|
{ |
|
String tableName = "info_usr"; // r.b. metaData.getTableName(column+1); |
|
// Some of the drivers seem buggy, tableName should not be null. |
|
if (tableName == null) |
|
{ |
|
System.err.println("Table name returned null."); |
|
} |
|
String colName = getColumnName(column); |
|
|
|
Object new_value = tableRepresentation(column, value); |
|
if (new_value == null) |
|
throw new SQLException ("conversion error"); |
|
|
|
System.err.println ("column: " + colName + ", value: " + new_value); |
|
String query = |
|
"update "+tableName+ |
|
" set "+colName+" = " + "'" + dbRepresentation(column, new_value, true) + "'" + |
|
" where "; |
|
// We don't have a model of the schema so we don't know the |
|
// primary keys or which columns to lock on. To demonstrate |
|
// that editing is possible, we'll just lock on everything. |
|
for(int col = 0; col<getColumnCount(); col++) |
|
{ |
|
String columnName = getColumnName(col); |
|
if (columnName.equals("")) |
|
continue; |
|
if (col != 0) |
|
query = query + " and "; |
|
query = query + columnName + " = " + "'" + getValueAt(row, col) + "'"; |
|
} |
|
|
|
System.err.println(query); |
|
System.err.println("Sending update to database"); |
|
int rc = 1; // statement.executeUpdate(query); |
|
if (rc == 1) |
|
{ |
|
System.err.println("Update succeeded"); |
|
} |
|
else |
|
throw new SQLException ("Update failed: " + rc); |
|
|
|
Vector dataRow = (Vector)rows.elementAt(row); |
|
dataRow.setElementAt(new_value, column); |
|
|
|
} |
|
catch (SQLException e) |
|
{ |
|
System.err.println("ERROR: " + e); |
|
} |
|
|
|
} |
|
|
|
public void setDataVector(Vector Rows, Vector Header, Object Meta) |
|
{ |
|
int numberOfColumns = Header.size(); |
|
columnNames = new String[numberOfColumns]; |
|
rows = Rows; |
|
if (Meta instanceof SxSQLMetaData) |
|
{ |
|
metaData = (SxSQLMetaData) Meta; |
|
// Get the column names and cache them. |
|
for(int column = 0; column < numberOfColumns; column++) |
|
columnNames[column] = (String) Header.elementAt (column); |
|
} |
|
else |
|
metaData = null; |
|
fireTableChanged(null); |
|
} |
|
|
|
public void setDataVector(Vector Rows) |
|
{ |
|
rows = Rows; |
|
|
|
fireTableDataChanged(); |
|
} |
|
/** |
|
* MB 04/2010 hinzugefügt, weil felderinfo decimal nicht funktioniert, |
|
* aufruf von TSxDlgManager für col1 darf bei dbrepresenation kein , sondern . enthalten |
|
* |
|
*/ |
|
public Object getValueAt2(int aRow, int aColumn) |
|
{ |
|
Vector row = (Vector)rows.elementAt(aRow); |
|
Object value = row.elementAt(aColumn); |
|
return dbRepresentation(aColumn, value, false); |
|
} |
|
}
|
|
|