public class DataTypeDouble extends FloatingPointBase implements IDataTypeComponent { /** Logger for this class. */ private static ILogger s_log = LoggerController.createLogger(DataTypeBigDecimal.class); /* the whole column definition */ private ColumnDisplayDefinition _colDef; /* whether nulls are allowed or not */ private boolean _isNullable; /* table of which we are part (needed for creating popup dialog) */ private JTable _table; /* The JTextComponent that is being used for editing */ private IRestorableTextComponent _textComponent; /* The CellRenderer used for this data type */ //??? For now, use the same renderer as everyone else. //?? //?? IN FUTURE: change this to use a new instance of renederer //?? for this data type. private DefaultColumnRenderer _renderer = DefaultColumnRenderer.getInstance(); // The NumberFormat object to use for all locale-dependent formatting. private NumberFormat _numberFormat; private boolean _renderExceptionHasBeenLogged; /** * Constructor - save the data needed by this data type. */ public DataTypeDouble(JTable table, ColumnDisplayDefinition colDef) { _table = table; _colDef = colDef; _isNullable = colDef.isNullable(); _numberFormat = NumberFormat.getInstance(); // This is a bit hard coded but if we use _scale here // some number displays go crazy. _numberFormat.setMaximumFractionDigits(5); _numberFormat.setMinimumFractionDigits(0); } /** * Return the name of the java class used to hold this data type. */ public String getClassName() { return "java.lang.Double"; } /** * Determine if two objects of this data type contain the same value. * Neither of the objects is null */ public boolean areEqual(Object obj1, Object obj2) { return obj1.equals(obj2); } /* * First we have the methods for in-cell and Text-table operations */ /** * Render a value into text for this DataType. */ public String renderObject(Object value) { //return (String)_renderer.renderObject(value); if (value == null || useJavaDefaultFormat) { return (String)_renderer.renderObject(value); } else { try { return (String)_renderer.renderObject(_numberFormat.format(value)); } catch (Exception e) { if(false == _renderExceptionHasBeenLogged) { _renderExceptionHasBeenLogged = true; s_log.error("Could not format \"" + value + "\" as number type", e); } return (String) _renderer.renderObject(value); } } } /** * This Data Type can be edited in a table cell. */ public boolean isEditableInCell(Object originalValue) { return true; } /** * See if a value in a column has been limited in some way and * needs to be re-read before being used for editing. * For read-only tables this may actually return true since we want * to be able to view the entire contents of the cell even if it was not * completely loaded during the initial table setup. */ public boolean needToReRead(Object originalValue) { // this DataType does not limit the data read during the initial load of the table, // so there is no need to re-read the complete data later return false; } /** * Return a JTextField usable in a CellEditor. */ public JTextField getJTextField() { _textComponent = new RestorableJTextField(); // special handling of operations while editing this data type ((RestorableJTextField)_textComponent).addKeyListener(new KeyTextHandler()); // // handle mouse events for double-click creation of popup dialog. // This happens only in the JTextField, not the JTextArea, so we can // make this an inner class within this method rather than a separate // inner class as is done with the KeyTextHandler class. // ((RestorableJTextField)_textComponent).addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent evt) { if (evt.getClickCount() == 2) { MouseEvent tableEvt = SwingUtilities.convertMouseEvent( (RestorableJTextField)DataTypeDouble.this._textComponent, evt, DataTypeDouble.this._table); CellDataPopup.showDialog(DataTypeDouble.this._table, DataTypeDouble.this._colDef, tableEvt, true); } } }); // end of mouse listener return (JTextField)_textComponent; } /** * Implement the interface for validating and converting to internal object. * Null is a valid successful return, so errors are indicated only by * existance or not of a message in the messageBuffer. */ public Object validateAndConvert(String value, Object originalValue, StringBuffer messageBuffer) { // handle null, which is shown as the special string "<null>" if (value.equals("<null>") || value.equals("")) return null; // Do the conversion into the object in a safe manner try { Double obj; if(useJavaDefaultFormat) { obj = new Double(value); } else { obj = new Double("" + _numberFormat.parse(value)); } return obj; } catch (Exception e) { messageBuffer.append(e.toString() + "\n"); //?? do we need the message also, or is it automatically part of the toString()? //messageBuffer.append(e.getMessage()); return null; } } /** * If true, this tells the PopupEditableIOPanel to use the * binary editing panel rather than a pure text panel. * The binary editing panel assumes the data is an array of bytes, * converts it into text form, allows the user to change how that * data is displayed (e.g. Hex, Decimal, etc.), and converts * the data back from text to bytes when the user editing is completed. * If this returns false, this DataType class must * convert the internal data into a text string that * can be displayed (and edited, if allowed) in a TextField * or TextArea, and must handle all * user key strokes related to editing of that data. */ public boolean useBinaryEditingPanel() { return false; } /* * Now the functions for the Popup-related operations. */ /** * Returns true if data type may be edited in the popup, * false if not. */ public boolean isEditableInPopup(Object originalValue) { return true; } /* * Return a JTextArea usable in the CellPopupDialog * and fill in the value. */ public JTextArea getJTextArea(Object value) { _textComponent = new RestorableJTextArea(); // value is a simple string representation of the data, // the same one used in Text and in-cell operations. ((RestorableJTextArea)_textComponent).setText(renderObject(value)); // special handling of operations while editing this data type ((RestorableJTextArea)_textComponent).addKeyListener(new KeyTextHandler()); return (RestorableJTextArea)_textComponent; } /** * Validating and converting in Popup is identical to cell-related operation. */ public Object validateAndConvertInPopup(String value, Object originalValue, StringBuffer messageBuffer) { return validateAndConvert(value, originalValue, messageBuffer); } /* * The following is used in both cell and popup operations. */ /* * Internal class for handling key events during editing * of both JTextField and JTextArea. */ private class KeyTextHandler extends BaseKeyTextHandler { public void keyTyped(KeyEvent e) { char c = e.getKeyChar(); // as a coding convenience, create a reference to the text component // that is typecast to JTextComponent. this is not essential, as we // could typecast every reference, but this makes the code cleaner JTextComponent _theComponent = (JTextComponent)DataTypeDouble.this._textComponent; String text = _theComponent.getText(); // tabs and newlines get put into the text before this check, // so remove them // This only applies to Popup editing since these chars are // not passed to this level by the in-cell editor. if (c == KeyEvent.VK_TAB || c == KeyEvent.VK_ENTER) { // remove all instances of the offending char int index = text.indexOf(c); if (index != -1) { if (index == text.length() -1) { text = text.substring(0, text.length()-1); // truncate string } else { text = text.substring(0, index) + text.substring(index+1); } ((IRestorableTextComponent)_theComponent).updateText( text); _beepHelper.beep(_theComponent); } e.consume(); } if ( ! ( Character.isDigit(c) || (c == '-') || (c == '+') || (c == 'e') || (c == 'E') || (c == 'f') || (c == 'F') || (c == 'd') || (c == 'D') || (c == '.') || (c == ',') || // several number formats use '.' as decimal separator, others use ',' (c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE) ) ) { _beepHelper.beep(_theComponent); e.consume(); } // handle cases of null // The processing is different when nulls are allowed and when they are not. // if ( DataTypeDouble.this._isNullable) { // user enters something when field is null if (text.equals("<null>")) { if ((c==KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE)) { // delete when null => original value DataTypeDouble.this._textComponent.restoreText(); e.consume(); } else { // non-delete when null => clear field and add text DataTypeDouble.this._textComponent.updateText(""); // fall through to normal processing of this key stroke } } else { // check for user deletes last thing in field if ((c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE)) { if (text.length() <= 1 ) { // about to delete last thing in field, so replace with null DataTypeDouble.this._textComponent.updateText("<null>"); e.consume(); } } } } else { // field is not nullable // handleNotNullableField(text, c, e, _textComponent); } } } /* * DataBase-related functions */ /** * On input from the DB, read the data from the ResultSet into the appropriate * type of object to be stored in the table cell. */ public Object readResultSet(ResultSet rs, int index, boolean limitDataRead) throws java.sql.SQLException { double data = rs.getDouble(index); if (rs.wasNull()) return null; else return new Double(data); } /** * When updating the database, generate a string form of this object value * that can be used in the WHERE clause to match the value in the database. * A return value of null means that this column cannot be used in the WHERE * clause, while a return of "null" (or "is null", etc) means that the column * can be used in the WHERE clause and the value is actually a null value. * This function must also include the column label so that its output * is of the form: * "columnName = value" * or * "columnName is null" * or whatever is appropriate for this column in the database. */ public String getWhereClauseValue(Object value, ISQLDatabaseMetaData md) { if (value == null || value.toString() == null || value.toString().length() == 0) return _colDef.getLabel() + " IS NULL"; else // since we cannot do exact matches on floating point // numbers, we cannot use this field in the WHERE clause. return null; // return _colDef.getLabel() + "=" + value.toString(); } /** * When updating the database, insert the appropriate datatype into the * prepared statment at the given variable position. */ public void setPreparedStatementValue(PreparedStatement pstmt, Object value, int position) throws java.sql.SQLException { if (value == null) { pstmt.setNull(position, _colDef.getSqlType()); } else { pstmt.setDouble(position, ((Double)value).floatValue()); } } /** * Get a default value for the table used to input data for a new row * to be inserted into the DB. */ public Object getDefaultValue(String dbDefaultValue) { if (dbDefaultValue != null) { // try to use the DB default value StringBuffer mbuf = new StringBuffer(); Object newObject = validateAndConvert(dbDefaultValue, null, mbuf); // if there was a problem with converting, then just fall through // and continue as if there was no default given in the DB. // Otherwise, use the converted object if (mbuf.length() == 0) return newObject; } // no default in DB. If nullable, use null. if (_isNullable) return null; // field is not nullable, so create a reasonable default value return new Double(0); } /* * File IO related functions */ /** * Say whether or not object can be exported to and imported from * a file. We put both export and import together in one test * on the assumption that all conversions can be done both ways. */ public boolean canDoFileIO() { return true; } /** * Read a file and construct a valid object from its contents. * Errors are returned by throwing an IOException containing the * cause of the problem as its message. * <P> * DataType is responsible for validating that the imported * data can be converted to an object, and then must return * a text string that can be used in the Popup window text area. * This object-to-text conversion is the same as is done by * the DataType object internally in the getJTextArea() method. * * <P> * File is assumed to be and ASCII string of digits * representing a value of this data type. */ public String importObject(FileInputStream inStream) throws IOException { InputStreamReader inReader = new InputStreamReader(inStream); int fileSize = inStream.available(); char charBuf[] = new char[fileSize]; int count = inReader.read(charBuf, 0, fileSize); if (count != fileSize) throw new IOException( "Could read only "+ count + " chars from a total file size of " + fileSize + ". Import failed."); // convert file text into a string // Special case: some systems tack a newline at the end of // the text read. Assume that if last char is a newline that // we want everything else in the line. String fileText; if (charBuf[count-1] == KeyEvent.VK_ENTER) fileText = new String(charBuf, 0, count-1); else fileText = new String(charBuf); // test that the string is valid by converting it into an // object of this data type StringBuffer messageBuffer = new StringBuffer(); validateAndConvertInPopup(fileText, null, messageBuffer); if (messageBuffer.length() > 0) { // convert number conversion issue into IO issue for consistancy throw new IOException( "Text does not represent data of type "+getClassName()+ ". Text was:\n"+fileText); } // return the text from the file since it does // represent a valid data value return fileText; } /** * Construct an appropriate external representation of the object * and write it to a file. * Errors are returned by throwing an IOException containing the * cause of the problem as its message. * <P> * DataType is responsible for validating that the given text * text from a Popup JTextArea can be converted to an object. * This text-to-object conversion is the same as validateAndConvertInPopup, * which may be used internally by the object to do the validation. * <P> * The DataType object must flush and close the output stream before returning. * Typically it will create another object (e.g. an OutputWriter), and * that is the object that must be flushed and closed. * * <P> * File is assumed to be and ASCII string of digits * representing a value of this data type. */ public void exportObject(FileOutputStream outStream, String text) throws IOException { OutputStreamWriter outWriter = new OutputStreamWriter(outStream); // check that the text is a valid representation StringBuffer messageBuffer = new StringBuffer(); validateAndConvertInPopup(text, null, messageBuffer); if (messageBuffer.length() > 0) { // there was an error in the conversion throw new IOException(new String(messageBuffer)); } // just send the text to the output file outWriter.write(text); outWriter.flush(); outWriter.close()
public class DataTypeFloat extends FloatingPointBase implements IDataTypeComponent { /** Logger for this class. */ private static ILogger s_log = LoggerController.createLogger(DataTypeFloat.class); /* the whole column definition */ private ColumnDisplayDefinition _colDef; /* whether nulls are allowed or not */ private boolean _isNullable; /* table of which we are part (needed for creating popup dialog) */ private JTable _table; /* The JTextComponent that is being used for editing */ private IRestorableTextComponent _textComponent; /* The CellRenderer used for this data type */ //??? For now, use the same renderer as everyone else. //?? //?? IN FUTURE: change this to use a new instance of renederer //?? for this data type. private DefaultColumnRenderer _renderer = DefaultColumnRenderer.getInstance(); // The NumberFormat object to use for all locale-dependent formatting. private NumberFormat _numberFormat; private boolean _renderExceptionHasBeenLogged; /** * Constructor - save the data needed by this data type. */ public DataTypeFloat(JTable table, ColumnDisplayDefinition colDef) { _table = table; _colDef = colDef; _isNullable = colDef.isNullable(); _numberFormat = NumberFormat.getInstance(); // This is a bit hard coded but if we use _scale here // some number displays go crazy. _numberFormat.setMaximumFractionDigits(5); _numberFormat.setMinimumFractionDigits(0); } /** * Return the name of the java class used to hold this data type. */ public String getClassName() { return "java.lang.Float"; } /** * Determine if two objects of this data type contain the same value. * Neither of the objects is null */ public boolean areEqual(Object obj1, Object obj2) { return obj1.equals(obj2); } /* * First we have the methods for in-cell and Text-table operations */ /** * Render a value into text for this DataType. */ public String renderObject(Object value) { //return (String)_renderer.renderObject(value); if (value == null || useJavaDefaultFormat) { return (String)_renderer.renderObject(value); } else { try { return (String)_renderer.renderObject(_numberFormat.format(value)); } catch (Exception e) { if(false == _renderExceptionHasBeenLogged) { _renderExceptionHasBeenLogged = true; s_log.error("Could not format \"" + value + "\" as number type", e); } return (String) _renderer.renderObject(value); } } } /** * This Data Type can be edited in a table cell. */ public boolean isEditableInCell(Object originalValue) { return true; } /** * See if a value in a column has been limited in some way and * needs to be re-read before being used for editing. * For read-only tables this may actually return true since we want * to be able to view the entire contents of the cell even if it was not * completely loaded during the initial table setup. */ public boolean needToReRead(Object originalValue) { // this DataType does not limit the data read during the initial load of the table, // so there is no need to re-read the complete data later return false; } /** * Return a JTextField usable in a CellEditor. */ public JTextField getJTextField() { _textComponent = new RestorableJTextField(); // special handling of operations while editing this data type ((RestorableJTextField)_textComponent).addKeyListener(new KeyTextHandler()); // // handle mouse events for double-click creation of popup dialog. // This happens only in the JTextField, not the JTextArea, so we can // make this an inner class within this method rather than a separate // inner class as is done with the KeyTextHandler class. // ((RestorableJTextField)_textComponent).addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent evt) { if (evt.getClickCount() == 2) { MouseEvent tableEvt = SwingUtilities.convertMouseEvent( (RestorableJTextField)DataTypeFloat.this._textComponent, evt, DataTypeFloat.this._table); CellDataPopup.showDialog(DataTypeFloat.this._table, DataTypeFloat.this._colDef, tableEvt, true); } } }); // end of mouse listener return (JTextField)_textComponent; } /** * Implement the interface for validating and converting to internal object. * Null is a valid successful return, so errors are indicated only by * existance or not of a message in the messageBuffer. */ public Object validateAndConvert(String value, Object originalValue, StringBuffer messageBuffer) { // handle null, which is shown as the special string "<null>" if (value.equals("<null>") || value.equals("")) return null; // Do the conversion into the object in a safe manner try { Float obj; if(useJavaDefaultFormat) { obj = new Float(value); } else { obj = new Float("" + _numberFormat.parse(value)); } return obj; } catch (Exception e) { messageBuffer.append(e.toString() + "\n"); //?? do we need the message also, or is it automatically part of the toString()? //messageBuffer.append(e.getMessage()); return null; } } /** * If true, this tells the PopupEditableIOPanel to use the * binary editing panel rather than a pure text panel. * The binary editing panel assumes the data is an array of bytes, * converts it into text form, allows the user to change how that * data is displayed (e.g. Hex, Decimal, etc.), and converts * the data back from text to bytes when the user editing is completed. * If this returns false, this DataType class must * convert the internal data into a text string that * can be displayed (and edited, if allowed) in a TextField * or TextArea, and must handle all * user key strokes related to editing of that data. */ public boolean useBinaryEditingPanel() { return false; } /* * Now the functions for the Popup-related operations. */ /** * Returns true if data type may be edited in the popup, * false if not. */ public boolean isEditableInPopup(Object originalValue) { return true; } /* * Return a JTextArea usable in the CellPopupDialog * and fill in the value. */ public JTextArea getJTextArea(Object value) { _textComponent = new RestorableJTextArea(); // value is a simple string representation of the data, // the same one used in Text and in-cell operations. ((RestorableJTextArea)_textComponent).setText(renderObject(value)); // special handling of operations while editing this data type ((RestorableJTextArea)_textComponent).addKeyListener(new KeyTextHandler()); return (RestorableJTextArea)_textComponent; } /** * Validating and converting in Popup is identical to cell-related operation. */ public Object validateAndConvertInPopup(String value, Object originalValue, StringBuffer messageBuffer) { return validateAndConvert(value, originalValue, messageBuffer); } /* * The following is used in both cell and popup operations. */ /* * Internal class for handling key events during editing * of both JTextField and JTextArea. */ private class KeyTextHandler extends BaseKeyTextHandler { public void keyTyped(KeyEvent e) { char c = e.getKeyChar(); // as a coding convenience, create a reference to the text component // that is typecast to JTextComponent. this is not essential, as we // could typecast every reference, but this makes the code cleaner JTextComponent _theComponent = (JTextComponent)DataTypeFloat.this._textComponent; String text = _theComponent.getText(); // tabs and newlines get put into the text before this check, // so remove them // This only applies to Popup editing since these chars are // not passed to this level by the in-cell editor. if (c == KeyEvent.VK_TAB || c == KeyEvent.VK_ENTER) { // remove all instances of the offending char int index = text.indexOf(c); if (index != -1) { if (index == text.length() -1) { text = text.substring(0, text.length()-1); // truncate string } else { text = text.substring(0, index) + text.substring(index+1); } ((IRestorableTextComponent)_theComponent).updateText( text); _beepHelper.beep(_theComponent); } e.consume(); } if ( ! ( Character.isDigit(c) || (c == '-') || (c == '+') || (c == 'e') || (c == 'E') || (c == 'f') || (c == 'F') || (c == '.') || (c == ',') || // several number formats use '.' as decimal separator, others use ',' (c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE) ) ) { _beepHelper.beep(_theComponent); e.consume(); } // handle cases of null // The processing is different when nulls are allowed and when they are not. // if ( DataTypeFloat.this._isNullable) { // user enters something when field is null if (text.equals("<null>")) { if ((c==KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE)) { // delete when null => original value DataTypeFloat.this._textComponent.restoreText(); e.consume(); } else { // non-delete when null => clear field and add text DataTypeFloat.this._textComponent.updateText(""); // fall through to normal processing of this key stroke } } else { // check for user deletes last thing in field if ((c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE)) { if (text.length() <= 1 ) { // about to delete last thing in field, so replace with null DataTypeFloat.this._textComponent.updateText("<null>"); e.consume(); } } } } else { // field is not nullable // handleNotNullableField(text, c, e, _textComponent); } } } /* * DataBase-related functions */ /** * On input from the DB, read the data from the ResultSet into the appropriate * type of object to be stored in the table cell. */ public Object readResultSet(ResultSet rs, int index, boolean limitDataRead) throws java.sql.SQLException { float data = rs.getFloat(index); if (rs.wasNull()) return null; else return new Float(data); } /** * When updating the database, generate a string form of this object value * that can be used in the WHERE clause to match the value in the database. * A return value of null means that this column cannot be used in the WHERE * clause, while a return of "null" (or "is null", etc) means that the column * can be used in the WHERE clause and the value is actually a null value. * This function must also include the column label so that its output * is of the form: * "columnName = value" * or * "columnName is null" * or whatever is appropriate for this column in the database. */ public String getWhereClauseValue(Object value, ISQLDatabaseMetaData md) { if (value == null || value.toString() == null || value.toString().length() == 0) return _colDef.getLabel() + " IS NULL"; else // since we cannot do exact matches on floating point // numbers, we cannot use this field in the WHERE clause. return ""; // return _colDef.getLabel() + "=" + value.toString(); } /** * When updating the database, insert the appropriate datatype into the * prepared statment at the given variable position. */ public void setPreparedStatementValue(PreparedStatement pstmt, Object value, int position) throws java.sql.SQLException { if (value == null) { pstmt.setNull(position, _colDef.getSqlType()); } else { pstmt.setFloat(position, ((Float)value).floatValue()); } } /** * Get a default value for the table used to input data for a new row * to be inserted into the DB. */ public Object getDefaultValue(String dbDefaultValue) { if (dbDefaultValue != null) { // try to use the DB default value StringBuffer mbuf = new StringBuffer(); Object newObject = validateAndConvert(dbDefaultValue, null, mbuf); // if there was a problem with converting, then just fall through // and continue as if there was no default given in the DB. // Otherwise, use the converted object if (mbuf.length() == 0) return newObject; } // no default in DB. If nullable, use null. if (_isNullable) return null; // field is not nullable, so create a reasonable default value return new Float(0); } /* * File IO related functions */ /** * Say whether or not object can be exported to and imported from * a file. We put both export and import together in one test * on the assumption that all conversions can be done both ways. */ public boolean canDoFileIO() { return true; } /** * Read a file and construct a valid object from its contents. * Errors are returned by throwing an IOException containing the * cause of the problem as its message. * <P> * DataType is responsible for validating that the imported * data can be converted to an object, and then must return * a text string that can be used in the Popup window text area. * This object-to-text conversion is the same as is done by * the DataType object internally in the getJTextArea() method. * * <P> * File is assumed to be and ASCII string of digits * representing a value of this data type. */ public String importObject(FileInputStream inStream) throws IOException { InputStreamReader inReader = new InputStreamReader(inStream); int fileSize = inStream.available(); char charBuf[] = new char[fileSize]; int count = inReader.read(charBuf, 0, fileSize); if (count != fileSize) throw new IOException( "Could read only "+ count + " chars from a total file size of " + fileSize + ". Import failed."); // convert file text into a string // Special case: some systems tack a newline at the end of // the text read. Assume that if last char is a newline that // we want everything else in the line. String fileText; if (charBuf[count-1] == KeyEvent.VK_ENTER) fileText = new String(charBuf, 0, count-1); else fileText = new String(charBuf); // test that the string is valid by converting it into an // object of this data type StringBuffer messageBuffer = new StringBuffer(); validateAndConvertInPopup(fileText, null, messageBuffer); if (messageBuffer.length() > 0) { // convert number conversion issue into IO issue for consistancy throw new IOException( "Text does not represent data of type "+getClassName()+ ". Text was:\n"+fileText); } // return the text from the file since it does // represent a valid data value return fileText; } /** * Construct an appropriate external representation of the object * and write it to a file. * Errors are returned by throwing an IOException containing the * cause of the problem as its message. * <P> * DataType is responsible for validating that the given text * text from a Popup JTextArea can be converted to an object. * This text-to-object conversion is the same as validateAndConvertInPopup, * which may be used internally by the object to do the validation. * <P> * The DataType object must flush and close the output stream before returning. * Typically it will create another object (e.g. an OutputWriter), and * that is the object that must be flushed and closed. * * <P> * File is assumed to be and ASCII string of digits * representing a value of this data type. */ public void exportObject(FileOutputStream outStream, String text) throws IOException { OutputStreamWriter outWriter = new OutputStreamWriter(outStream); // check that the text is a valid representation StringBuffer messageBuffer = new StringBuffer(); validateAndConvertInPopup(text, null, messageBuffer); if (messageBuffer.length() > 0) { // there was an error in the conversion throw new IOException(new String(messageBuffer)); } // just send the text to the output file outWriter.write(text); outWriter.flush(); outWriter.close()
Clone fragments detected by clone detection tool
File path: /sql12/fw/src/net/sourceforge/squirrel_sql/fw/datasetviewer/cellcomponent/DataTypeDouble.java File path: /sql12/fw/src/net/sourceforge/squirrel_sql/fw/datasetviewer/cellcomponent/DataTypeFloat.java
Method name: Method name:
Number of AST nodes: 0 Number of AST nodes: 0
1
public class DataTypeDouble extends FloatingPointBase
1
public class DataTypeFloat extends FloatingPointBase
2
   implements IDataTypeComponent
2
   implements IDataTypeComponent
3
{
3
{
4
   /** Logger for this class. */
4
   /** Logger for this class. */
5
   private static ILogger s_log = LoggerController.createLogger(DataTypeBigDecimal.class);
5
   private static ILogger s_log = LoggerController.createLogger(DataTypeFloat.class);
6
   /* the whole column definition */
6
   /* the whole column definition */
7
   private ColumnDisplayDefinition _colDef;
7
   private ColumnDisplayDefinition _colDef;
8
   /* whether nulls are allowed or not */
8
   /* whether nulls are allowed or not */
9
   private boolean _isNullable;
9
   private boolean _isNullable;
10
   /* table of which we are part (needed for creating popup dialog) */
10
   /* table of which we are part (needed for creating popup dialog) */
11
   private JTable _table;
11
   private JTable _table;
12
   /* The JTextComponent that is being used for editing */
12
   /* The JTextComponent that is being used for editing */
13
   private IRestorableTextComponent _textComponent;
13
   private IRestorableTextComponent _textComponent;
14
   /* The CellRenderer used for this data type */
14
   /* The CellRenderer used for this data type */
15
   //??? For now, use the same renderer as everyone else.
15
   //??? For now, use the same renderer as everyone else.
16
   //??
16
   //??
17
   //?? IN FUTURE: change this to use a new instance of renederer
17
   //?? IN FUTURE: change this to use a new instance of renederer
18
   //?? for this data type.
18
   //?? for this data type.
19
   private DefaultColumnRenderer _renderer = DefaultColumnRenderer.getInstance();
19
   private DefaultColumnRenderer _renderer = DefaultColumnRenderer.getInstance();
20
   // The NumberFormat object to use for all locale-dependent formatting.
20
   // The NumberFormat object to use for all locale-dependent formatting.
21
   private NumberFormat _numberFormat;
21
   private NumberFormat _numberFormat;
22
   private boolean _renderExceptionHasBeenLogged;
22
   private boolean _renderExceptionHasBeenLogged;
23
   /**
23
   /**
24
    * Constructor - save the data needed by this data type.
24
    * Constructor - save the data needed by this data type.
25
    */
25
    */
26
   public DataTypeDouble(JTable table, ColumnDisplayDefinition colDef) {
26
   public DataTypeFloat(JTable table, ColumnDisplayDefinition colDef) {
27
      _table = table;
27
      _table = table;
28
      _colDef = colDef;
28
      _colDef = colDef;
29
      _isNullable = colDef.isNullable();
29
      _isNullable = colDef.isNullable();
30
      _numberFormat = NumberFormat.getInstance();
30
      _numberFormat = NumberFormat.getInstance();
31
      // This is a bit hard coded but if we use _scale here
31
      // This is a bit hard coded but if we use _scale here
32
      // some number displays go crazy.
32
      // some number displays go crazy.
33
      _numberFormat.setMaximumFractionDigits(5);
33
      _numberFormat.setMaximumFractionDigits(5);
34
      _numberFormat.setMinimumFractionDigits(0);
34
      _numberFormat.setMinimumFractionDigits(0);
35
   }
35
   }
36
   /**
36
   /**
37
    * Return the name of the java class used to hold this data type.
37
    * Return the name of the java class used to hold this data type.
38
    */
38
    */
39
   public String getClassName() {
39
   public String getClassName() {
40
      return "java.lang.Double";
40
      return "java.lang.Float";
41
   }
41
   }
42
   /**
42
   /**
43
    * Determine if two objects of this data type contain the same value.
43
    * Determine if two objects of this data type contain the same value.
44
    * Neither of the objects is null
44
    * Neither of the objects is null
45
    */
45
    */
46
   public boolean areEqual(Object obj1, Object obj2) {
46
   public boolean areEqual(Object obj1, Object obj2) {
47
      return obj1.equals(obj2);
47
      return obj1.equals(obj2);
48
   }
48
   }
49
   /*
49
   /*
50
     * First we have the methods for in-cell and Text-table operations
50
     * First we have the methods for in-cell and Text-table operations
51
     */
51
     */
52
   /**
52
   /**
53
    * Render a value into text for this DataType.
53
    * Render a value into text for this DataType.
54
    */
54
    */
55
   public String renderObject(Object value) {
55
   public String renderObject(Object value) {
56
      //return (String)_renderer.renderObject(value);
56
      //return (String)_renderer.renderObject(value);
57
      if (value == null || useJavaDefaultFormat)
57
      if (value == null || useJavaDefaultFormat)
58
      {
58
      {
59
         return (String)_renderer.renderObject(value);
59
         return (String)_renderer.renderObject(value);
60
      }
60
      }
61
      else
61
      else
62
      {
62
      {
63
         try
63
         try
64
         {
64
         {
65
            return (String)_renderer.renderObject(_numberFormat.format(value));
65
            return (String)_renderer.renderObject(_numberFormat.format(value));
66
         }
66
         }
67
         catch (Exception e)
67
         catch (Exception e)
68
         {
68
         {
69
            if(false == _renderExceptionHasBeenLogged)
69
            if(false == _renderExceptionHasBeenLogged)
70
            {
70
            {
71
               _renderExceptionHasBeenLogged = true;
71
               _renderExceptionHasBeenLogged = true;
72
               s_log.error("Could not format \"" + value + "\" as number type", e);
72
               s_log.error("Could not format \"" + value + "\" as number type", e);
73
            }
73
            }
74
            return (String) _renderer.renderObject(value);
74
            return (String) _renderer.renderObject(value);
75
         }
75
         }
76
      }
76
      }
77
   }
77
   }
78
   /**
78
   /**
79
    * This Data Type can be edited in a table cell.
79
    * This Data Type can be edited in a table cell.
80
    */
80
    */
81
   public boolean isEditableInCell(Object originalValue) {
81
   public boolean isEditableInCell(Object originalValue) {
82
      return true;
82
      return true;
83
   }
83
   }
84
   /**
84
   /**
85
    * See if a value in a column has been limited in some way and
85
    * See if a value in a column has been limited in some way and
86
    * needs to be re-read before being used for editing.
86
    * needs to be re-read before being used for editing.
87
    * For read-only tables this may actually return true since we want
87
    * For read-only tables this may actually return true since we want
88
    * to be able to view the entire contents of the cell even if it was not
88
    * to be able to view the entire contents of the cell even if it was not
89
    * completely loaded during the initial table setup.
89
    * completely loaded during the initial table setup.
90
    */
90
    */
91
   public boolean needToReRead(Object originalValue) {
91
   public boolean needToReRead(Object originalValue) {
92
      // this DataType does not limit the data read during the initial load of the table,
92
      // this DataType does not limit the data read during the initial load of the table,
93
      // so there is no need to re-read the complete data later
93
      // so there is no need to re-read the complete data later
94
      return false;
94
      return false;
95
   }
95
   }
96
   /**
96
   /**
97
    * Return a JTextField usable in a CellEditor.
97
    * Return a JTextField usable in a CellEditor.
98
    */
98
    */
99
   public JTextField getJTextField() {
99
   public JTextField getJTextField() {
100
      _textComponent = new RestorableJTextField();
100
      _textComponent = new RestorableJTextField();
101
      // special handling of operations while editing this data type
101
      // special handling of operations while editing this data type
102
      ((RestorableJTextField)_textComponent).addKeyListener(new KeyTextHandler());
102
      ((RestorableJTextField)_textComponent).addKeyListener(new KeyTextHandler());
103
      //
103
      //
104
      // handle mouse events for double-click creation of popup dialog.
104
      // handle mouse events for double-click creation of popup dialog.
105
      // This happens only in the JTextField, not the JTextArea, so we can
105
      // This happens only in the JTextField, not the JTextArea, so we can
106
      // make this an inner class within this method rather than a separate
106
      // make this an inner class within this method rather than a separate
107
      // inner class as is done with the KeyTextHandler class.
107
      // inner class as is done with the KeyTextHandler class.
108
      //
108
      //
109
      ((RestorableJTextField)_textComponent).addMouseListener(new MouseAdapter()
109
      ((RestorableJTextField)_textComponent).addMouseListener(new MouseAdapter()
110
      {
110
      {
111
         public void mousePressed(MouseEvent evt)
111
         public void mousePressed(MouseEvent evt)
112
         {
112
         {
113
            if (evt.getClickCount() == 2)
113
            if (evt.getClickCount() == 2)
114
            {
114
            {
115
               MouseEvent tableEvt = SwingUtilities.convertMouseEvent(
115
               MouseEvent tableEvt = SwingUtilities.convertMouseEvent(
116
                  (RestorableJTextField)DataTypeDouble.this._textComponent,
116
                  (RestorableJTextField)DataTypeFloat.this._textComponent,
117
                  evt, DataTypeDouble.this._table);
117
                  evt, DataTypeFloat.this._table);
118
               CellDataPopup.showDialog(DataTypeDouble.this._table,
118
               CellDataPopup.showDialog(DataTypeFloat.this._table,
119
                  DataTypeDouble.this._colDef, tableEvt, true);
119
                  DataTypeFloat.this._colDef, tableEvt, true);
120
            }
120
            }
121
         }
121
         }
122
      });	// end of mouse listener
122
      });	// end of mouse listener
123
      return (JTextField)_textComponent;
123
      return (JTextField)_textComponent;
124
   }
124
   }
125
   /**
125
   /**
126
    * Implement the interface for validating and converting to internal object.
126
    * Implement the interface for validating and converting to internal object.
127
    * Null is a valid successful return, so errors are indicated only by
127
    * Null is a valid successful return, so errors are indicated only by
128
    * existance or not of a message in the messageBuffer.
128
    * existance or not of a message in the messageBuffer.
129
    */
129
    */
130
   public Object validateAndConvert(String value, Object originalValue, StringBuffer messageBuffer) {
130
   public Object validateAndConvert(String value, Object originalValue, StringBuffer messageBuffer) {
131
      // handle null, which is shown as the special string "<null>"
131
      // handle null, which is shown as the special string "<null>"
132
      if (value.equals("<null>") || value.equals(""))
132
      if (value.equals("<null>") || value.equals(""))
133
         return null;
133
         return null;
134
      // Do the conversion into the object in a safe manner
134
      // Do the conversion into the object in a safe manner
135
      try
135
      try
136
      {
136
      {
137
         Double obj;
137
         Float obj;
138
         if(useJavaDefaultFormat)
138
         if(useJavaDefaultFormat)
139
         {
139
         {
140
            obj = new Double(value);
140
            obj = new Float(value);
141
         }
141
         }
142
         else
142
         else
143
         {
143
         {
144
            obj = new Double("" + _numberFormat.parse(value));
144
            obj = new Float("" + _numberFormat.parse(value));
145
         }
145
         }
146
         return obj;
146
         return obj;
147
      }
147
      }
148
      catch (Exception e)
148
      catch (Exception e)
149
      {
149
      {
150
         messageBuffer.append(e.toString() + "\n");
150
         messageBuffer.append(e.toString() + "\n");
151
         //?? do we need the message also, or is it automatically part of the toString()?
151
         //?? do we need the message also, or is it automatically part of the toString()?
152
         //messageBuffer.append(e.getMessage());
152
         //messageBuffer.append(e.getMessage());
153
         return null;
153
         return null;
154
      }
154
      }
155
   }
155
   }
156
   /**
156
   /**
157
    * If true, this tells the PopupEditableIOPanel to use the
157
    * If true, this tells the PopupEditableIOPanel to use the
158
    * binary editing panel rather than a pure text panel.
158
    * binary editing panel rather than a pure text panel.
159
    * The binary editing panel assumes the data is an array of bytes,
159
    * The binary editing panel assumes the data is an array of bytes,
160
    * converts it into text form, allows the user to change how that
160
    * converts it into text form, allows the user to change how that
161
    * data is displayed (e.g. Hex, Decimal, etc.), and converts
161
    * data is displayed (e.g. Hex, Decimal, etc.), and converts
162
    * the data back from text to bytes when the user editing is completed.
162
    * the data back from text to bytes when the user editing is completed.
163
    * If this returns false, this DataType class must
163
    * If this returns false, this DataType class must
164
    * convert the internal data into a text string that
164
    * convert the internal data into a text string that
165
    * can be displayed (and edited, if allowed) in a TextField
165
    * can be displayed (and edited, if allowed) in a TextField
166
    * or TextArea, and must handle all
166
    * or TextArea, and must handle all
167
    * user key strokes related to editing of that data.
167
    * user key strokes related to editing of that data.
168
    */
168
    */
169
   public boolean useBinaryEditingPanel() {
169
   public boolean useBinaryEditingPanel() {
170
      return false;
170
      return false;
171
   }
171
   }
172
   /*
172
   /*
173
     * Now the functions for the Popup-related operations.
173
     * Now the functions for the Popup-related operations.
174
     */
174
     */
175
   /**
175
   /**
176
    * Returns true if data type may be edited in the popup,
176
    * Returns true if data type may be edited in the popup,
177
    * false if not.
177
    * false if not.
178
    */
178
    */
179
   public boolean isEditableInPopup(Object originalValue) {
179
   public boolean isEditableInPopup(Object originalValue) {
180
      return true;
180
      return true;
181
   }
181
   }
182
   /*
182
   /*
183
     * Return a JTextArea usable in the CellPopupDialog
183
     * Return a JTextArea usable in the CellPopupDialog
184
     * and fill in the value.
184
     * and fill in the value.
185
     */
185
     */
186
    public JTextArea getJTextArea(Object value) {
186
    public JTextArea getJTextArea(Object value) {
187
      _textComponent = new RestorableJTextArea();
187
      _textComponent = new RestorableJTextArea();
188
      // value is a simple string representation of the data,
188
      // value is a simple string representation of the data,
189
      // the same one used in Text and in-cell operations.
189
      // the same one used in Text and in-cell operations.
190
      ((RestorableJTextArea)_textComponent).setText(renderObject(value));
190
      ((RestorableJTextArea)_textComponent).setText(renderObject(value));
191
      // special handling of operations while editing this data type
191
      // special handling of operations while editing this data type
192
      ((RestorableJTextArea)_textComponent).addKeyListener(new KeyTextHandler());
192
      ((RestorableJTextArea)_textComponent).addKeyListener(new KeyTextHandler());
193
      return (RestorableJTextArea)_textComponent;
193
      return (RestorableJTextArea)_textComponent;
194
    }
194
    }
195
   /**
195
   /**
196
    * Validating and converting in Popup is identical to cell-related operation.
196
    * Validating and converting in Popup is identical to cell-related operation.
197
    */
197
    */
198
   public Object validateAndConvertInPopup(String value, Object originalValue, StringBuffer messageBuffer) {
198
   public Object validateAndConvertInPopup(String value, Object originalValue, StringBuffer messageBuffer) {
199
      return validateAndConvert(value, originalValue, messageBuffer);
199
      return validateAndConvert(value, originalValue, messageBuffer);
200
   }
200
   }
201
   /*
201
   /*
202
     * The following is used in both cell and popup operations.
202
     * The following is used in both cell and popup operations.
203
     */
203
     */
204
   /*
204
   /*
205
     * Internal class for handling key events during editing
205
     * Internal class for handling key events during editing
206
     * of both JTextField and JTextArea.
206
     * of both JTextField and JTextArea.
207
     */
207
     */
208
    private class KeyTextHandler extends BaseKeyTextHandler {
208
    private class KeyTextHandler extends BaseKeyTextHandler {
209
       public void keyTyped(KeyEvent e) {
209
       public void keyTyped(KeyEvent e) {
210
            char c = e.getKeyChar();
210
            char c = e.getKeyChar();
211
            // as a coding convenience, create a reference to the text component
211
            // as a coding convenience, create a reference to the text component
212
            // that is typecast to JTextComponent.  this is not essential, as we
212
            // that is typecast to JTextComponent.  this is not essential, as we
213
            // could typecast every reference, but this makes the code cleaner
213
            // could typecast every reference, but this makes the code cleaner
214
            JTextComponent _theComponent = (JTextComponent)DataTypeDouble.this._textComponent;
214
            JTextComponent _theComponent = (JTextComponent)DataTypeFloat.this._textComponent;
215
            String text = _theComponent.getText();
215
            String text = _theComponent.getText();
216
            // tabs and newlines get put into the text before this check,
216
            // tabs and newlines get put into the text before this check,
217
            // so remove them
217
            // so remove them
218
            // This only applies to Popup editing since these chars are
218
            // This only applies to Popup editing since these chars are
219
            // not passed to this level by the in-cell editor.
219
            // not passed to this level by the in-cell editor.
220
            if (c == KeyEvent.VK_TAB || c == KeyEvent.VK_ENTER) {
220
            if (c == KeyEvent.VK_TAB || c == KeyEvent.VK_ENTER) {
221
               // remove all instances of the offending char
221
               // remove all instances of the offending char
222
               int index = text.indexOf(c);
222
               int index = text.indexOf(c);
223
               if (index != -1) {
223
               if (index != -1) {
224
	               if (index == text.length() -1) {
224
	               if (index == text.length() -1) {
225
	                  text = text.substring(0, text.length()-1);	// truncate string
225
	                  text = text.substring(0, text.length()-1);	// truncate string
226
	               }
226
	               }
227
	               else {
227
	               else {
228
	                  text = text.substring(0, index) + text.substring(index+1);
228
	                  text = text.substring(0, index) + text.substring(index+1);
229
	               }
229
	               }
230
	               ((IRestorableTextComponent)_theComponent).updateText( text);
230
	               ((IRestorableTextComponent)_theComponent).updateText( text);
231
	               _beepHelper.beep(_theComponent);
231
	               _beepHelper.beep(_theComponent);
232
               }
232
               }
233
               e.consume();
233
               e.consume();
234
            }
234
            }
235
            if ( ! ( Character.isDigit(c) ||
235
            if ( ! ( Character.isDigit(c) ||
236
               (c == '-') || (c == '+') ||
236
               (c == '-') || (c == '+') ||
237
               (c == 'e') || (c == 'E') ||
237
               (c == 'e') || (c == 'E') ||
238
               (c == 'f') || (c == 'F') ||
238
               (c == 'f') || (c == 'F') ||
239
               (c == 'd') || (c == 'D') ||
240
               (c == '.') || (c == ',') ||  // several number formats use '.' as decimal separator, others use ','
239
               (c == '.') || (c == ',') ||  // several number formats use '.' as decimal separator, others use ','
241
               (c == KeyEvent.VK_BACK_SPACE) ||
240
               (c == KeyEvent.VK_BACK_SPACE) ||
242
               (c == KeyEvent.VK_DELETE) ) ) {
241
               (c == KeyEvent.VK_DELETE) ) ) {
243
            	_beepHelper.beep(_theComponent);
242
            	_beepHelper.beep(_theComponent);
244
               e.consume();
243
               e.consume();
245
            }
244
            }
246
            // handle cases of null
245
            // handle cases of null
247
            // The processing is different when nulls are allowed and when they are not.
246
            // The processing is different when nulls are allowed and when they are not.
248
            //
247
            //
249
            if ( DataTypeDouble.this._isNullable) {
248
            if ( DataTypeFloat.this._isNullable) {
250
               // user enters something when field is null
249
               // user enters something when field is null
251
               if (text.equals("<null>")) {
250
               if (text.equals("<null>")) {
252
                  if ((c==KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE)) {
251
                  if ((c==KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE)) {
253
                     // delete when null => original value
252
                     // delete when null => original value
254
                     DataTypeDouble.this._textComponent.restoreText();
253
                     DataTypeFloat.this._textComponent.restoreText();
255
                     e.consume();
254
                     e.consume();
256
                  }
255
                  }
257
                  else {
256
                  else {
258
                     // non-delete when null => clear field and add text
257
                     // non-delete when null => clear field and add text
259
                     DataTypeDouble.this._textComponent.updateText("");
258
                     DataTypeFloat.this._textComponent.updateText("");
260
                     // fall through to normal processing of this key stroke
259
                     // fall through to normal processing of this key stroke
261
                  }
260
                  }
262
               }
261
               }
263
               else {
262
               else {
264
                  // check for user deletes last thing in field
263
                  // check for user deletes last thing in field
265
                  if ((c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE)) {
264
                  if ((c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE)) {
266
                     if (text.length() <= 1 ) {
265
                     if (text.length() <= 1 ) {
267
                        // about to delete last thing in field, so replace with null
266
                        // about to delete last thing in field, so replace with null
268
                        DataTypeDouble.this._textComponent.updateText("<null>");
267
                        DataTypeFloat.this._textComponent.updateText("<null>");
269
                        e.consume();
268
                        e.consume();
270
                     }
269
                     }
271
                  }
270
                  }
272
               }
271
               }
273
            }
272
            }
274
            else {
273
            else {
275
                    // field is not nullable
274
                    // field is not nullable
276
                    //
275
                    //
277
                    handleNotNullableField(text, c, e, _textComponent);
276
                    handleNotNullableField(text, c, e, _textComponent);
278
            }
277
            }
279
         }
278
         }
280
      }
279
      }
281
   /*
280
   /*
282
     * DataBase-related functions
281
     * DataBase-related functions
283
     */
282
     */
284
    /**
283
    /**
285
     * On input from the DB, read the data from the ResultSet into the appropriate
284
     * On input from the DB, read the data from the ResultSet into the appropriate
286
     * type of object to be stored in the table cell.
285
     * type of object to be stored in the table cell.
287
     */
286
     */
288
   public Object readResultSet(ResultSet rs, int index, boolean limitDataRead)
287
   public Object readResultSet(ResultSet rs, int index, boolean limitDataRead)
289
      throws java.sql.SQLException {
288
      throws java.sql.SQLException {
290
      double data = rs.getDouble(index);
289
      float data = rs.getFloat(index);
291
      if (rs.wasNull())
290
      if (rs.wasNull())
292
         return null;
291
         return null;
293
      else return new Double(data);
292
      else return new Float(data);
294
   }
293
   }
295
   /**
294
   /**
296
    * When updating the database, generate a string form of this object value
295
    * When updating the database, generate a string form of this object value
297
    * that can be used in the WHERE clause to match the value in the database.
296
    * that can be used in the WHERE clause to match the value in the database.
298
    * A return value of null means that this column cannot be used in the WHERE
297
    * A return value of null means that this column cannot be used in the WHERE
299
    * clause, while a return of "null" (or "is null", etc) means that the column
298
    * clause, while a return of "null" (or "is null", etc) means that the column
300
    * can be used in the WHERE clause and the value is actually a null value.
299
    * can be used in the WHERE clause and the value is actually a null value.
301
    * This function must also include the column label so that its output
300
    * This function must also include the column label so that its output
302
    * is of the form:
301
    * is of the form:
303
    * 	"columnName = value"
302
    * 	"columnName = value"
304
    * or
303
    * or
305
    * 	"columnName is null"
304
    * 	"columnName is null"
306
    * or whatever is appropriate for this column in the database.
305
    * or whatever is appropriate for this column in the database.
307
    */
306
    */
308
   public String getWhereClauseValue(Object value, ISQLDatabaseMetaData md) {
307
   public String getWhereClauseValue(Object value, ISQLDatabaseMetaData md) {
309
      if (value == null || value.toString() == null || value.toString().length() == 0)
308
      if (value == null || value.toString() == null || value.toString().length() == 0)
310
         return _colDef.getLabel() + " IS NULL";
309
         return _colDef.getLabel() + " IS NULL";
311
      else
310
      else
312
         // since we cannot do exact matches on floating point
311
         // since we cannot do exact matches on floating point
313
         // numbers, we cannot use this field in the WHERE clause.
312
         // numbers, we cannot use this field in the WHERE clause.
314
         return null;
313
         return "";
315
//			return _colDef.getLabel() + "=" + value.toString();
314
//			return _colDef.getLabel() + "=" + value.toString();
316
   }
315
   }
317
   /**
316
   /**
318
    * When updating the database, insert the appropriate datatype into the
317
    * When updating the database, insert the appropriate datatype into the
319
    * prepared statment at the given variable position.
318
    * prepared statment at the given variable position.
320
    */
319
    */
321
   public void setPreparedStatementValue(PreparedStatement pstmt, Object value, int position)
320
   public void setPreparedStatementValue(PreparedStatement pstmt, Object value, int position)
322
      throws java.sql.SQLException {
321
      throws java.sql.SQLException {
323
      if (value == null) {
322
      if (value == null) {
324
         pstmt.setNull(position, _colDef.getSqlType());
323
         pstmt.setNull(position, _colDef.getSqlType());
325
      }
324
      }
326
      else {
325
      else {
327
         pstmt.setDouble(position, ((Double)value).floatValue());
326
         pstmt.setFloat(position, ((Float)value).floatValue());
328
      }
327
      }
329
   }
328
   }
330
   /**
329
   /**
331
    * Get a default value for the table used to input data for a new row
330
    * Get a default value for the table used to input data for a new row
332
    * to be inserted into the DB.
331
    * to be inserted into the DB.
333
    */
332
    */
334
   public Object getDefaultValue(String dbDefaultValue) {
333
   public Object getDefaultValue(String dbDefaultValue) {
335
      if (dbDefaultValue != null) {
334
      if (dbDefaultValue != null) {
336
         // try to use the DB default value
335
         // try to use the DB default value
337
         StringBuffer mbuf = new StringBuffer();
336
         StringBuffer mbuf = new StringBuffer();
338
         Object newObject = validateAndConvert(dbDefaultValue, null, mbuf);
337
         Object newObject = validateAndConvert(dbDefaultValue, null, mbuf);
339
         // if there was a problem with converting, then just fall through
338
         // if there was a problem with converting, then just fall through
340
         // and continue as if there was no default given in the DB.
339
         // and continue as if there was no default given in the DB.
341
         // Otherwise, use the converted object
340
         // Otherwise, use the converted object
342
         if (mbuf.length() == 0)
341
         if (mbuf.length() == 0)
343
            return newObject;
342
            return newObject;
344
      }
343
      }
345
      // no default in DB.  If nullable, use null.
344
      // no default in DB.  If nullable, use null.
346
      if (_isNullable)
345
      if (_isNullable)
347
         return null;
346
         return null;
348
      // field is not nullable, so create a reasonable default value
347
      // field is not nullable, so create a reasonable default value
349
      return new Double(0);
348
      return new Float(0);
350
   }
349
   }
351
   /*
350
   /*
352
     * File IO related functions
351
     * File IO related functions
353
     */
352
     */
354
    /**
353
    /**
355
     * Say whether or not object can be exported to and imported from
354
     * Say whether or not object can be exported to and imported from
356
     * a file.  We put both export and import together in one test
355
     * a file.  We put both export and import together in one test
357
     * on the assumption that all conversions can be done both ways.
356
     * on the assumption that all conversions can be done both ways.
358
     */
357
     */
359
    public boolean canDoFileIO() {
358
    public boolean canDoFileIO() {
360
       return true;
359
       return true;
361
    }
360
    }
362
    /**
361
    /**
363
     * Read a file and construct a valid object from its contents.
362
     * Read a file and construct a valid object from its contents.
364
     * Errors are returned by throwing an IOException containing the
363
     * Errors are returned by throwing an IOException containing the
365
     * cause of the problem as its message.
364
     * cause of the problem as its message.
366
     * <P>
365
     * <P>
367
     * DataType is responsible for validating that the imported
366
     * DataType is responsible for validating that the imported
368
     * data can be converted to an object, and then must return
367
     * data can be converted to an object, and then must return
369
     * a text string that can be used in the Popup window text area.
368
     * a text string that can be used in the Popup window text area.
370
     * This object-to-text conversion is the same as is done by
369
     * This object-to-text conversion is the same as is done by
371
     * the DataType object internally in the getJTextArea() method.
370
     * the DataType object internally in the getJTextArea() method.
372
     *
371
     *
373
     * <P>
372
     * <P>
374
     * File is assumed to be and ASCII string of digits
373
     * File is assumed to be and ASCII string of digits
375
     * representing a value of this data type.
374
     * representing a value of this data type.
376
     */
375
     */
377
   public String importObject(FileInputStream inStream)
376
   public String importObject(FileInputStream inStream)
378
       throws IOException {
377
       throws IOException {
379
       InputStreamReader inReader = new InputStreamReader(inStream);
378
       InputStreamReader inReader = new InputStreamReader(inStream);
380
       int fileSize = inStream.available();
379
       int fileSize = inStream.available();
381
       char charBuf[] = new char[fileSize];
380
       char charBuf[] = new char[fileSize];
382
       int count = inReader.read(charBuf, 0, fileSize);
381
       int count = inReader.read(charBuf, 0, fileSize);
383
       if (count != fileSize)
382
       if (count != fileSize)
384
          throw new IOException(
383
          throw new IOException(
385
             "Could read only "+ count +
384
             "Could read only "+ count +
386
             " chars from a total file size of " + fileSize +
385
             " chars from a total file size of " + fileSize +
387
             ". Import failed.");
386
             ". Import failed.");
388
       // convert file text into a string
387
       // convert file text into a string
389
       // Special case: some systems tack a newline at the end of
388
       // Special case: some systems tack a newline at the end of
390
       // the text read.  Assume that if last char is a newline that
389
       // the text read.  Assume that if last char is a newline that
391
       // we want everything else in the line.
390
       // we want everything else in the line.
392
       String fileText;
391
       String fileText;
393
       if (charBuf[count-1] == KeyEvent.VK_ENTER)
392
       if (charBuf[count-1] == KeyEvent.VK_ENTER)
394
          fileText = new String(charBuf, 0, count-1);
393
          fileText = new String(charBuf, 0, count-1);
395
       else fileText = new String(charBuf);
394
       else fileText = new String(charBuf);
396
       // test that the string is valid by converting it into an
395
       // test that the string is valid by converting it into an
397
       // object of this data type
396
       // object of this data type
398
       StringBuffer messageBuffer = new StringBuffer();
397
       StringBuffer messageBuffer = new StringBuffer();
399
       validateAndConvertInPopup(fileText, null, messageBuffer);
398
       validateAndConvertInPopup(fileText, null, messageBuffer);
400
       if (messageBuffer.length() > 0) {
399
       if (messageBuffer.length() > 0) {
401
          // convert number conversion issue into IO issue for consistancy
400
          // convert number conversion issue into IO issue for consistancy
402
          throw new IOException(
401
          throw new IOException(
403
             "Text does not represent data of type "+getClassName()+
402
             "Text does not represent data of type "+getClassName()+
404
             ".  Text was:\n"+fileText);
403
             ".  Text was:\n"+fileText);
405
       }
404
       }
406
       // return the text from the file since it does
405
       // return the text from the file since it does
407
       // represent a valid data value
406
       // represent a valid data value
408
       return fileText;
407
       return fileText;
409
   }
408
   }
410
    /**
409
    /**
411
     * Construct an appropriate external representation of the object
410
     * Construct an appropriate external representation of the object
412
     * and write it to a file.
411
     * and write it to a file.
413
     * Errors are returned by throwing an IOException containing the
412
     * Errors are returned by throwing an IOException containing the
414
     * cause of the problem as its message.
413
     * cause of the problem as its message.
415
     * <P>
414
     * <P>
416
     * DataType is responsible for validating that the given text
415
     * DataType is responsible for validating that the given text
417
     * text from a Popup JTextArea can be converted to an object.
416
     * text from a Popup JTextArea can be converted to an object.
418
     * This text-to-object conversion is the same as validateAndConvertInPopup,
417
     * This text-to-object conversion is the same as validateAndConvertInPopup,
419
     * which may be used internally by the object to do the validation.
418
     * which may be used internally by the object to do the validation.
420
     * <P>
419
     * <P>
421
     * The DataType object must flush and close the output stream before returning.
420
     * The DataType object must flush and close the output stream before returning.
422
     * Typically it will create another object (e.g. an OutputWriter), and
421
     * Typically it will create another object (e.g. an OutputWriter), and
423
     * that is the object that must be flushed and closed.
422
     * that is the object that must be flushed and closed.
424
     *
423
     *
425
     * <P>
424
     * <P>
426
     * File is assumed to be and ASCII string of digits
425
     * File is assumed to be and ASCII string of digits
427
     * representing a value of this data type.
426
     * representing a value of this data type.
428
     */
427
     */
429
    public void exportObject(FileOutputStream outStream, String text)
428
    public void exportObject(FileOutputStream outStream, String text)
430
       throws IOException {
429
       throws IOException {
431
       OutputStreamWriter outWriter = new OutputStreamWriter(outStream);
430
       OutputStreamWriter outWriter = new OutputStreamWriter(outStream);
432
       // check that the text is a valid representation
431
       // check that the text is a valid representation
433
       StringBuffer messageBuffer = new StringBuffer();
432
       StringBuffer messageBuffer = new StringBuffer();
434
       validateAndConvertInPopup(text, null, messageBuffer);
433
       validateAndConvertInPopup(text, null, messageBuffer);
435
       if (messageBuffer.length() > 0) {
434
       if (messageBuffer.length() > 0) {
436
          // there was an error in the conversion
435
          // there was an error in the conversion
437
          throw new IOException(new String(messageBuffer));
436
          throw new IOException(new String(messageBuffer));
438
       }
437
       }
439
       // just send the text to the output file
438
       // just send the text to the output file
440
      outWriter.write(text);
439
      outWriter.write(text);
441
      outWriter.flush();
440
      outWriter.flush();
442
      outWriter.close()
441
      outWriter.close()
Summary
Number of common nesting structure subtrees0
Number of refactorable cases0
Number of non-refactorable cases0
Time elapsed for finding largest common nesting structure subtrees (ms)0.0
Clones location
Number of node comparisons0