home *** CD-ROM | disk | FTP | other *** search
Java Source | 1998-03-18 | 23.8 KB | 757 lines |
- /*
- * Copyright (c) 1997 Krumel & Associates, Inc. All Rights Reserved.
- *
- * www.krumel.com - controls@krumel.com
- *
- * Permission is given to the buyer of this package for one software
- * developer to use this software on one CPU (one workstation) and to make
- * one backup copy. You may uitilize and/or modify this class for use in your
- * projects. You may distribute or sell any executable which results from
- * using this code in yur application, except a utility or class of similar
- * nature to this product. You may distribute this product in compiled
- * form only, but soley to be used with your cmpiled executable product
- * for the puposes of dynamic loading. You may NOT redistribute the source
- * code in any form or make it accessible through a network or other
- * distribution media to others. Please refer to the file "copyright.html"
- * for further important copyright and licensing information.
- *
- * The source code is the confidential and proprietary information
- * of Krumel & Associates, 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 Krumel & Associates, Inc..
-
- * KRUMEL & ASSOCIATES 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. KRUMEL & ASSOCIATES SHALL NOT
- * BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
- * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
- */
-
- package symantec.itools.db.awt;
-
- import java.awt.Point;
- import java.awt.Image;
- import symantec.itools.db.awt.event.*;
- import symantec.itools.db.awt.genutil.Matrix;
-
- /**
- * A data source designed to support running on top of database APIs like JDBC or dbAnywhere.
- * For APIs that do not provide scrollable cursors, the data source provides the ability to
- * cache result set rows. If caching is provided, the state of each row is maintained by a
- * DataState object. The state of a row can be inspected using the return value of rowState()
- * in conjunction with the DataState class.
- */
- public class DbDataSource implements DataSource {
- Matrix rowCache = new Matrix();
-
- TableView view;
- DbDataStore store;
- DbDataUpdater updater;
- MetaTable meta;
- boolean caching = false;
- Data currData;
- int currDataRow, currDataCol;
-
- /**
- * Creates a data source for the specified view and database information.
- * @param v THe view that will display the data.
- * @param s The data store responsible for retrieving the information from the
- * database.
- * @param u The udpater responsible for updating the database information upon
- *
- */
- public DbDataSource(DbDataStore s, DbDataUpdater u, MetaTable m) {
- this(null, s, u, m);
- }
-
- /**
- * Creates a data source for the specified view and database information.
- * @param v THe view that will display the data.
- * @param s The data store responsible for retrieving the information from the
- * database.
- * @param u The udpater responsible for updating the database information upon
- *
- */
- public DbDataSource(TableView v, DbDataStore s, DbDataUpdater u, MetaTable m) {
- view = v;
- setupSource(s, u, m);
- }
-
- /**
- * Gets teh TableView dsplaying the data for the data source.
- */
- public TableView getView() {
- return view;
- }
-
- /**
- * Sets the data store, updater and meta information classes for the data source.
- */
- public void setupSource(DbDataStore s, DbDataUpdater u, MetaTable m) {
- store = s;
- store.setDbDataSource(this);
- updater = u;
- meta = m;
-
- if (meta != null) {
- meta.setDbDataSource(this);
- }
-
- //cache if store doesn't
- caching = !store.supportsCaching();
- }
-
- /**
- * Sets the TableView displaying the data.
- */
- public void setTableView(TableView v) {
- view = v;
- }
-
- /**
- * Informs the data source whether the TableView will be requesting successive data
- * for read only purposes.
- * @param manual true if the data source should expect read only data requests
- */
- public void fetchMode(boolean manual) {
- store.fetchMode(manual);
- }
-
- /**
- * Sets the Data type for cell data when no data value has been set.
- */
- public void setDefaultData(Data defaultValue) {}
-
- /**
- * Requests the DataSource set an appropriate default data type
- */
- public void setDefaultData() {}
-
- /**
- * Gets whether the DataSource has the ability to configure a TableView.
- * @return True if MetaTable class is set, false otherwise.
- */
- public boolean supportsMeta() {
- return meta != null;
- }
-
- /**
- * Gets the cache used to store data retrieved from database and added rows.
- */
- public Matrix getCache() { return rowCache; }
-
- /**
- * Gets the number of rows currently stored in the cache.
- */
- public int lastCachedRow() {
- return rowCache.rows() - 1;
- }
-
- /**
- * Gets the object that provides meta information.
- */
- public MetaTable getMetaTable() { return meta; }
-
- /**
- * Sets the TableView displaying the data.
- * @exception TypeNotSupported if the data source does not support the type of
- * action requested or is not successful
- */
- public void setupTableView(TableView v) throws TypeNotSupported {
- if (meta == null) {
- throw new TypeNotSupported("MetaTable not set");
- }
-
- meta.setupTableView(view);
- }
-
- /**
- * Commits the current data.
- * @exception TypeNotSupported If the data source does not support the type of
- * action requested or is not successful
- */
- public void commitData() throws TypeNotSupported {
- if (currData != null && currData.changed()) {
- setData(currDataRow, currDataCol-1, currData);
- currData.commit();
- currData = null;
- currDataRow = -1;
- }
- }
-
- /**
- * Informs the data source of the current row of the TableView.
- * @exception TypeNotSupported if the data source does not support the type of
- * action requested or is not successful
- */
- public void setCurrentRow(int row) throws TypeNotSupported {
- store.setCurrentRow(row);
- }
-
- /**
- * Gets the data for a cell that should only be used for reading. It does
- * not change the cell data being currently edited.
- * @param row the cells row
- * @exception DataNotAvailable if the requested data is not set in the data source
- */
- public Data readData(int row, int col) throws DataNotAvailable {
- col++;
-
- if (currDataRow == row && currDataCol == col) {
- return currData;
- }
-
- //if caching and it is cached then return it
- if (caching && rowCache.contains(row, col)) {
- return (Data)rowCache.elementAt(row, col);
- }
-
- //if not then go get it and then return it
- //cache if store isn't caching for us
- Data d = store.getData(row, col);
-
- if (caching) {
- rowCache.addElement(row, col, d);
- markClean(row);
- }
-
- return d;
- }
-
- /**
- * Gets the data for a cell. <p>
- * Call this method when going to be doing edits. <p>
- * Call commitData() when done with it (usually when lose focus).
- * @exception DataNotAvailable if the requested data is not set in the data source
- */
- public Data getData(Coordinate coords) throws DataNotAvailable {
- return getData(coords.row, coords.col);
- }
-
- /**
- * Gets the data for a cell. <p>
- * Call this method when going to be doing edits. <p>
- * Call commitData() when done with it (usually when lose focus).
- * @exception DataNotAvailable if the requested data is not set in the data source
- */
- public Data getData(int row, int col) throws DataNotAvailable {
- col++; //we maintain state information in col = 0 so it is all 1 based
-
- if (currDataRow == row && currDataCol == col) {
- return currData;
- }
- currData = readData(row, col-1);
- currDataRow = row;
- currDataCol = col;
-
- return currData;
- }
-
- /**
- * Called by DbDataStore or DbUpdater to insert a new row to the result set.
- * This method will mark the row as new.
- */
- public void insertResultSetRow(int row, Data data[]) {
- synchronized(rowCache) {
- //remember - row state stored in col 0
- for (int col=1; col<=data.length; col++) {
- rowCache.updateElement(row, col, data[col-1]);
- }
-
- markNew(row);
- }
- }
-
- /**
- * Called by DbDataStore or DbUpdater to append a new row to the end of the
- * result set. This method will mark the row as new.
- */
- public int appendResultSetRow(Data data[]) {
- synchronized(rowCache) {
- int rows = rowCache.rows();
-
- //remember - row state stored in col 0
- for (int col=1; col<=data.length; col++) {
- rowCache.addElement(rows, col, data[col-1]);
- }
-
- markNew(rows);
-
- return rows;
- }
- }
-
- /**
- * Called by DbDataStore or DbUpdater to add a new row to the result set.
- * This method will mark the row as clean.
- */
- public void addResultSetRow(int row, Data data[]) {
- //row should already be zero relative by DbDataStore
- //store has obtained a new row of information so store in matrix
- //and mark row as clean
-
- //remember - row state stored in col 0
- for (int col=1; col<=data.length; col++) {
- rowCache.updateElement(row, col, data[col-1]);
- }
-
- markClean(row);
- }
-
- //It is assumed that data has been verified already by data object, but...
- /**
- * Sets the data value for a cell.
- * @param r the row of the cell
- * @param c the column of the cell
- * @param data the data value for the cell
- * @exception TypeNotSupported If the data source does not support the type of
- * action requested or is not successful
- */
- public void setData(int row, int col, Data data) throws TypeNotSupported {
- col++; //we maintain state information in col = 0
- //if cached then mark row for update and change data
- if (caching) {
- rowCache.updateElement(row, col, data);
- markModified(row);
- return;
- }
-
- //not caching so tell source to update
- store.update(row, col, data);
- }
-
- /**
- * Sets the data value for a cell.
- * @param coord the cooridates of the cell
- * @param data the data value for the cell
- * @exception TypeNotSupported If the data source does not support the type of
- * action requested or is not successful
- */
- public void setData(Coordinate coord, Data data) throws TypeNotSupported {
- setData(coord.row, coord.col, data);
- }
-
- /**
- * Gets the textual representation of a cell's data
- * @exception DataNotAvailable if the requested data is not set in the data source
- */
- public String getText(Coordinate coords) throws DataNotAvailable {
- return getData(coords).toString();
- }
-
- /**
- * Undeletes a row in the data source
- * @exception TypeNotSupported If the data source does not support the type of
- * action requested or is not successful
- */
- public void undeleteRow(int row) throws TypeNotSupported {
- //vj: Added to reset current data before undelete
- currData=null;
- currDataRow=-1;
- if (caching) {
- //for now just assume it was previously changed
- //need to add ability to remember previous state through XOR
- markModified(row);
- }
-
- updater.undeleteRow(row);
- }
-
- /**
- * Deletes or marks a row for deletion from the data source
- * @exception TypeNotSupported If the data source does not support the type of
- * action requested or is not successful
- */
- public void deleteRow(int row) throws TypeNotSupported {
- //vj: Added to reset current data before delete
- currData=null;
- currDataRow=-1;
- if (caching) {
- markDeleted(row);
- }
-
- updater.deleteRow(row);
- }
-
- /**
- * Inserts a new row in the data source above the specified row
- * @exception TypeNotSupported if the data source does not support the type of
- * action requested or is not successful
- */
- public void insertRow(int row) throws TypeNotSupported {
- //vj: Added to reset current data before insert
- currData=null;
- currDataRow=-1;
- updater.insertRow(row);
- }
-
- /**
- * Appends a new row at the end of the data source's data.
- * @exception TypeNotSupported if the data source does not support the type of
- * action requested or is not successful
- */
- public int appendRow() throws TypeNotSupported {
- return updater.appendRow();
- }
-
- /**
- * Gets whether the data source supports a specified type of data
- */
- public boolean supports(Coordinate coords, int type) {
- if (type == Data.STRING) return true;
-
- return false;
- }
-
- /**
- * Gets an image representation of a cell's data
- * @exception DataNotAvailable if the requested data is not set in the data source
- */
- public Image getImage(Coordinate coords) throws DataNotAvailable {
- return getData(coords).toImage();
- }
-
- /**
- * Gives a data source a chance to perform any actions in response to a table
- * level event.
- */
- public void handleTableEvent(TableEvent e) {
- }
-
- /**
- * Called in response to circulating an event caused by an invocation of
- * TableView.routeEvent(). The event IDs are specified in the CellEvent class
- */
- public void handleCellEvent(CellEvent e) {
- switch(e.getID()) {
- case CellEvent.UNDO_CELL_EVENT:
- rollback();
- break;
- case CellEvent.LOST_FOCUS:
- break;
- }
- }
-
- /**
- * Routes any exceptions generated to the TableView for proper handling which may
- * include putting a message on status bar or logging to a file.
- */
- public void handleException(int row, int col, Exception ex) {
- view.handleException(row, col, ex);
- }
-
- /**
- * Gets the state of the row.
- * @return the state of the row's data as defined by DataState.
- */
- public int rowState(int row) {
- return store.rowState(row);
- }
-
- /**
- * Requests the data source remove all data.
- */
- public void clear() {
- rowCache.removeAllElements();
- currData = null;
- currDataRow = -1;
- store.clear();
- }
-
- /**
- * Requests the data source reread it data.
- */
- public void refresh() {
- //clear cache, clear view, and re-issue query
- rowCache.removeAllElements();
- currData = null;
- currDataRow = -1;
- store.refresh();
- }
-
- /**
- * Requests that any actions performed on a row be undone. The meaning
- * is left open and is to interpreted as appropriate for the type of
- * data source
- * @exception TypeNotSupported if the data source does not support the type of
- * action requested or is not successful
- */
- public void undoRow(int row) throws TypeNotSupported {
- //vj: Added to reset current data before undo
- currData=null;
- currDataRow=-1;
- store.undoRow(row);
- }
-
- /**
- * Requests the data source save the current state as appopriate.
- * @exception TypeNotSupported if the data source does not support the type of
- * action requested or is not successful
- */
- public void save() throws TypeNotSupported {
- //iterate cache and update all non-clean rows
- //vj: Added to reset current data before undo
- currData=null;
- currDataRow=-1;
- updater.save();
- }
-
- /**
- * Gets whether a cells data is editable or non-editable
- * @return true if the data may be altered by the user.
- */
- public boolean isDataEditable(int row, int col) {
-
- // System.out.println("Into isDataEditable");
-
- if (meta != null) {
- try {
-
- //System.out.println( meta.isDataEditable(row, col+1));
-
- return meta.isDataEditable(row, col+1);
- } catch(DataNotAvailable ex) {
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * Called by DbDataStore and DbUpdater to add a new row of data to the result
- * set.
- */
- public DataState getRowDataState(int row) {
- return (DataState)rowCache.elementAt(row, 0);
- }
-
- /**
- * Marks the row as modified.
- */
- public void markModified(int row) {
- DataState state;
-
- if (rowCache.contains(row, 0)) {
- state = (DataState)rowCache.elementAt(row, 0);
- state.markModified();
- } else {
- //it is really new, not modified
- state = new DataState();
- rowCache.addElement(row, 0, state);
- state.markNew();
- }
- }
-
- /**
- * Marks the row as new.
- */
- public void markNew(int row) {
- DataState state;
-
- if (rowCache.contains(row, 0)) {
- state = (DataState)rowCache.elementAt(row, 0);
- } else {
- state = new DataState();
- rowCache.addElement(row, 0, state);
- }
-
- state.markNew();
- }
-
- /**
- * Marks the row as deleted.
- */
- public void markDeleted(int row) {
- //if something is being deleted it should already be there so
- //let's assume it is there.
- DataState state = (DataState)rowCache.elementAt(row, 0);
- state.markDeleted();
- }
-
- /**
- * Marks the row as clean.
- */
- public void markClean(int row) {
- DataState state;
-
- if (rowCache.contains(row, 0)) {
- state = (DataState)rowCache.elementAt(row, 0);
- } else {
- state = new DataState();
- rowCache.addElement(row, 0, state);
- }
-
- state.markClean();
- }
-
- /**
- * Gets the last row valid in requested range
- * @exception DataNotAvailable if the requested data is not set in the data source
- */
- public int validDataRowRange(int top, int bottom) throws DataNotAvailable {
- //subtract one to make 0 relative
- return store.validDataRowRange(top, bottom)-1;
- }
-
- /**
- * Gets the number of rows of data stored in the data source
- */
- public int rows() {
- return store.rowsRetrieved();
- }
-
- /**
- * Requests the data source get all of the rows from its source of data.
- */
- public int fetchAllRows() {
- return store.fetchAllRows();
- }
-
- //Here are some methods needed to support DefaultData
- /**
- * Method used to support Defaultdata class. Gets the type of data supported
- * by the cell.
- */
- public int type(int row, int col) {
- return Data.STRING;
- }
-
- /**
- * Rolls the current cell to its original value.
- */
- public void rollback(int row, int col) { rollback(); }
-
- /**
- * Rolls the current cell to its original value.
- */
- public void rollbackCurrentData() {
- rollback();
- }
-
- /**
- * Rolls the current cell to its original value.
- */
- public void rollback() {
- currData = null;
- currDataRow = -1;
- }
-
- /**
- * Method used to support Defaultdata class. Commits the data for the
- * specified cell
- */
- public void commit(int row, int col) {}
-
- /**
- * Is never masked.
- * @return <code>false</code>
- */
- public boolean isMasked(int row, int col) {
- return false;
- }
-
- /**
- * Stubbed out function for future expansion.
- * @exception TypeNotSupported if the data source does not support the type of
- * action requested or is not successful
- */
- public String getMask(int row, int col) throws TypeNotSupported {
- throw new TypeNotSupported("stubbed");
- }
-
- /**
- * Method used to support Defaultdata class. Gets whether the data for the
- * specified cell supports choice selection lists.
- */
- public boolean supportsChoice(int row, int col) {
- return false;
- }
-
- /**
- * Method used to support Defaultdata class. Gets the choices for the cell to
- * display.
- * @exception TypeNotSupported if the data source does not support the type of
- * action requested or is not successful
- */
- public Data[] getChoices(int row, int col) throws TypeNotSupported {
- throw new TypeNotSupported("stubbed");
- }
-
- /**
- * Method used to support Defaultdata class. Sets the textual value for a cell.
- */
- public void setText(int row, int col, String t) {}
-
- /**
- * Method used to support Defaultdata class. Inserts a character at the
- * specified location in the data value for a cell.
- * @param row The cell's row
- * @param col The cell's column
- * @param pos The position to insert character
- * @param c The character
- */
- public void insertChar(int row, int col, int pos, char c) {}
-
- /**
- * Method used to support Defaultdata class. Sets the text for a cell to a
- * character
- */
- public void setText(int row, int col, char c) {}
-
- /**
- * Method used to support Defaultdata class. Appends a character to the end
- * of the textual representation of the cell's data.
- */
- public void appendChar(int row, int col, char c) {}
-
- /**
- * Method used to support Defaultdata class. Clears the textual value of a cell.
- */
- public void clearText(int row, int col) {}
-
- /**
- * Method used to support Defaultdata class. Deletes a character from a cell's
- * data.
- * @param row The cell's row
- * @param col The cell's column
- * @param pos The position to delete character
- */
- public void deleteChar(int row, int col, int pos) {}
-
- /**
- * Method used to support Defaultdata class. Gets a substring from a cell's
- * data.
- * @param row The cell's row
- * @param col The cell's column
- * @param spos The starting position of the substring, inclusive
- * @param epos The last position of the substring, exclusive
- */
- public String subString(int row, int col, int spos, int epos) {
- return "stubbed";
- }
-
- /**
- * Method used to support Defaultdata class. Sets the image data for a cell
- */
- public void setImage(int row, int col, Image i) {}
-
- /**
- * Method used to support Defaultdata class. Gets a string representation of
- * a cell's data.
- */
- public String toString(int row, int col) {
- return "stubbed";
- }
-
- /**
- * Method used to support Defaultdata class. Gets an image representationof
- * a cell's data.
- */
- public Image toImage(int row, int col) {
- return null;
- }
- }
-