Source Code Cross Referenced for Table.java in  » Database-Client » prefuse » prefuse » data » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database Client » prefuse » prefuse.data 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        package prefuse.data;
0002:
0003:        import java.util.ArrayList;
0004:        import java.util.Date;
0005:        import java.util.HashMap;
0006:        import java.util.Iterator;
0007:
0008:        import javax.swing.event.TableModelEvent;
0009:
0010:        import prefuse.data.column.Column;
0011:        import prefuse.data.column.ColumnFactory;
0012:        import prefuse.data.column.ColumnMetadata;
0013:        import prefuse.data.event.ColumnListener;
0014:        import prefuse.data.event.EventConstants;
0015:        import prefuse.data.event.TableListener;
0016:        import prefuse.data.expression.Expression;
0017:        import prefuse.data.expression.Predicate;
0018:        import prefuse.data.expression.parser.ExpressionParser;
0019:        import prefuse.data.tuple.AbstractTupleSet;
0020:        import prefuse.data.tuple.TableTuple;
0021:        import prefuse.data.tuple.TupleManager;
0022:        import prefuse.data.util.FilterIteratorFactory;
0023:        import prefuse.data.util.Index;
0024:        import prefuse.data.util.RowManager;
0025:        import prefuse.data.util.Sort;
0026:        import prefuse.data.util.TableIterator;
0027:        import prefuse.data.util.TreeIndex;
0028:        import prefuse.util.TypeLib;
0029:        import prefuse.util.collections.CopyOnWriteArrayList;
0030:        import prefuse.util.collections.IncompatibleComparatorException;
0031:        import prefuse.util.collections.IntIterator;
0032:
0033:        /**
0034:         * <p>A Table organizes a collection of data into rows and columns, each row 
0035:         * containing a data record, and each column containing data values for a
0036:         * named data field with a specific data type. Table data can be accessed
0037:         * directly using the row number and column name, or rows can be treated
0038:         * in an object-oriented fashion using {@link prefuse.data.Tuple}
0039:         * instances that represent a single row of data in the table. As such,
0040:         * tables implement the {@link prefuse.data.tuple.TupleSet} interface.</p>
0041:         * 
0042:         * <p>Table rows can be inserted or deleted. In any case, none of the other
0043:         * existing table rows are effected by an insertion or deletion. A deleted
0044:         * row simply becomes invalid--any subsequent attempts to access the row
0045:         * either directly or through a pre-existing Tuple instance will result
0046:         * in an exception. However, if news rows are later added to the table,
0047:         * the row number for previously deleted nodes can be reused. In fact, the
0048:         * lower row number currently unused is assigned to the new row. This results
0049:         * in an efficient reuse of the table rows, but carries an important side
0050:         * effect -- rows do not necesarily maintain the order in which they were
0051:         * added once deletions have occurred on the table. If not deletions
0052:         * occur, the ordering of table rows will reflect the order in which
0053:         * rows were added to the table.</p>
0054:         * 
0055:         * <p>Collections of table rows can be accessed using both iterators over
0056:         * the actual row numbers and iterators over the Tuple instances that
0057:         * encapsulate access to that row. Both types of iteration can also be
0058:         * filtered by providing a {@link prefuse.data.expression.Predicate},
0059:         * allowing tables to be queried for specific values.</p>
0060:         * 
0061:         * <p>Columns (alternativele referred to as data fields) can be added to
0062:         * the Table using {@link #addColumn(String, Class)} and a host of
0063:         * similar methods. This method will automatically determine the right
0064:         * kind of backing column instance to use. Furthermore, Table columns
0065:         * can be specified using a {@link Schema} instance, which describes
0066:         * the column names, data types, and default values. The Table class
0067:         * also maintains its own internal Schema, which be accessed (in a
0068:         * read-only way) using the {@link #getSchema()} method.</p>
0069:         * 
0070:         * <p>Tables also support additional structures. The {@link ColumnMetadata}
0071:         * class returned by the {@link #getMetadata(String)} method supports
0072:         * calculation of different statistics for a column, including minimum
0073:         * and maximum values, and the number of unique data values in the column.
0074:         * {@link prefuse.data.util.Index} instances can be created and retrieved
0075:         * using the {@link #index(String)} method and retrieved without triggering
0076:         * creation using {@link #getIndex(String)} method. An index keeps a
0077:         * sorted collection of all data values in a column, accelerating the creation
0078:         * of filtered iterators by optimizing query calculations and also providing
0079:         * faster computation of many of the {@link ColumnMetadata} methods. If
0080:         * you will be issuing a number of queries (i.e., requesting filtered
0081:         * iterators) dependent on the values of a given column, indexing that column
0082:         * may result in a significant performance increase, though at the cost
0083:         * of storing and maintaining the backing index structure.</p>  
0084:         * 
0085:         * @author <a href="http://jheer.org">jeffrey heer</a>
0086:         */
0087:        public class Table extends AbstractTupleSet implements  ColumnListener {
0088:
0089:            /** Listeners for changes to this table */
0090:            protected CopyOnWriteArrayList m_listeners;
0091:
0092:            /** Locally stored data columns */
0093:            protected ArrayList m_columns;
0094:            /** Column names for locally store data columns */
0095:            protected ArrayList m_names;
0096:
0097:            /** Mapping between column names and column entries
0098:             * containing column, metadata, and index references */
0099:            protected HashMap m_entries;
0100:
0101:            /** Manager for valid row indices */
0102:            protected RowManager m_rows;
0103:
0104:            /** manager for tuples, which are object representations for rows */
0105:            protected TupleManager m_tuples;
0106:
0107:            /** Tracks the number of edits of this table */
0108:            protected int m_modCount = 0;
0109:
0110:            /** Memoize the index of the last column operated on,
0111:             * used to expedite handling of column updates. */
0112:            protected int m_lastCol = -1;
0113:
0114:            /** A cached schema instance, loaded lazily */
0115:            protected Schema m_schema;
0116:
0117:            // ------------------------------------------------------------------------
0118:            // Constructors
0119:
0120:            /**
0121:             * Create a new, empty Table. Rows can be added to the table using
0122:             * the {@link #addRow()} method.
0123:             */
0124:            public Table() {
0125:                this (0, 0);
0126:            }
0127:
0128:            /**
0129:             * Create a new Table with a given number of rows, and the starting
0130:             * capacity for a given number of columns.
0131:             * @param nrows the starting number of table rows
0132:             * @param ncols the starting capacity for columns 
0133:             */
0134:            public Table(int nrows, int ncols) {
0135:                this (nrows, ncols, TableTuple.class);
0136:            }
0137:
0138:            /**
0139:             * Create a new Table.
0140:             * @param nrows the starting number of table rows
0141:             * @param ncols the starting capacity for columns 
0142:             * @param tupleType the class of the Tuple instances to use
0143:             */
0144:            protected Table(int nrows, int ncols, Class tupleType) {
0145:                m_listeners = new CopyOnWriteArrayList();
0146:                m_columns = new ArrayList(ncols);
0147:                m_names = new ArrayList(ncols);
0148:                m_rows = new RowManager(this );
0149:                m_entries = new HashMap(ncols + 5);
0150:                m_tuples = new TupleManager(this , null, tupleType);
0151:
0152:                if (nrows > 0)
0153:                    addRows(nrows);
0154:            }
0155:
0156:            // ------------------------------------------------------------------------
0157:            // Table Metadata
0158:
0159:            /**
0160:             * Get the number of columns / data fields in this table.
0161:             * @return the number of columns 
0162:             */
0163:            public int getColumnCount() {
0164:                return m_columns.size();
0165:            }
0166:
0167:            /**
0168:             * Get the data type of the column at the given column index.
0169:             * @param col the column index
0170:             * @return the data type (as a Java Class) of the column
0171:             */
0172:            public Class getColumnType(int col) {
0173:                return getColumn(col).getColumnType();
0174:            }
0175:
0176:            /**
0177:             * Get the data type of the column with the given data field name.
0178:             * @param field the column / data field name
0179:             * @return the data type (as a Java Class) of the column
0180:             */
0181:            public Class getColumnType(String field) {
0182:                Column c = getColumn(field);
0183:                return (c == null ? null : c.getColumnType());
0184:            }
0185:
0186:            /**
0187:             * Get the number of rows in the table.
0188:             * @return the number of rows
0189:             */
0190:            public int getRowCount() {
0191:                return m_rows.getRowCount();
0192:            }
0193:
0194:            /**
0195:             * Get the minimum row index currently in use by this Table.
0196:             * @return the minimum row index
0197:             */
0198:            public int getMinimumRow() {
0199:                return m_rows.getMinimumRow();
0200:            }
0201:
0202:            /**
0203:             * Get the maximum row index currently in use by this Table.
0204:             * @return the maximum row index
0205:             */
0206:            public int getMaximumRow() {
0207:                return m_rows.getMaximumRow();
0208:            }
0209:
0210:            /**
0211:             * Indicates if the value of the given table cell can be changed. 
0212:             * @param row the row number
0213:             * @param col the column number
0214:             * @return true if the value can be edited/changed, false otherwise
0215:             */
0216:            public boolean isCellEditable(int row, int col) {
0217:                if (!m_rows.isValidRow(row)) {
0218:                    return false;
0219:                } else {
0220:                    return getColumn(col).isCellEditable(row);
0221:                }
0222:            }
0223:
0224:            /**
0225:             * Get the number of times this Table has been modified. Adding rows,
0226:             * deleting rows, and updating table cell values all contribute to
0227:             * this count.
0228:             * @return the number of modifications to this table
0229:             */
0230:            public int getModificationCount() {
0231:                return m_modCount;
0232:            }
0233:
0234:            /**
0235:             * Sets the TupleManager used by this Table. Use this method
0236:             * carefully, as it will cause all existing Tuples retrieved
0237:             * from this Table to be invalidated.
0238:             * @param tm the TupleManager to use
0239:             */
0240:            public void setTupleManager(TupleManager tm) {
0241:                m_tuples.invalidateAll();
0242:                m_tuples = tm;
0243:            }
0244:
0245:            /**
0246:             * Returns this Table's schema. The returned schema will be
0247:             * locked, which means that any attempts to edit the returned schema
0248:             * by adding additional columns will result in a runtime exception.
0249:             * 
0250:             * If this Table subsequently has columns added or removed, this will not
0251:             * be reflected in the returned schema. Instead, this method will need to
0252:             * be called again to get a current schema. Accordingly, it is not
0253:             * recommended that Schema instances returned by this method be stored
0254:             * or reused across scopes unless that exact schema snapshot is
0255:             * desired.
0256:             * 
0257:             * @return a copy of this Table's schema
0258:             */
0259:            public Schema getSchema() {
0260:                if (m_schema == null) {
0261:                    Schema s = new Schema();
0262:                    for (int i = 0; i < getColumnCount(); ++i) {
0263:                        s.addColumn(getColumnName(i), getColumnType(i),
0264:                                getColumn(i).getDefaultValue());
0265:                    }
0266:                    s.lockSchema();
0267:                    m_schema = s;
0268:                }
0269:                return m_schema;
0270:            }
0271:
0272:            /**
0273:             * Invalidates this table's cached schema. This method should be called
0274:             * whenever columns are added or removed from this table.
0275:             */
0276:            protected void invalidateSchema() {
0277:                m_schema = null;
0278:            }
0279:
0280:            // ------------------------------------------------------------------------
0281:            // Row Operations
0282:
0283:            /**
0284:             * Get the row value for accessing an underlying Column instance,
0285:             * corresponding to the given table cell. For basic tables this just
0286:             * returns the input row value. However, for tables that inherit
0287:             * data columns from a parent table and present a filtered view on
0288:             * this data, a mapping between the row numbers of the table and
0289:             * the row numbers of the backing data column is needed. In those cases,
0290:             * this method returns the result of that mapping. The method
0291:             * {@link #getTableRow(int, int)} accesses this map in the reverse
0292:             * direction.
0293:             * @param row the table row to lookup
0294:             * @param col the table column to lookup
0295:             * @return the column row number for accessing the desired table cell
0296:             */
0297:            public int getColumnRow(int row, int col) {
0298:                return m_rows.getColumnRow(row, col);
0299:            }
0300:
0301:            /**
0302:             * Get the row number for this table given a row number for a backing
0303:             * data column and the column number for the data column. For basic
0304:             * tables this just returns the column row value. However, for tables that
0305:             * inherit data columns from a parent table and present a filtered view on
0306:             * this data, a mapping between the row numbers of the table and
0307:             * the row numbers of the backing data column is needed. In those cases,
0308:             * this method returns the result of this mapping, in the direction of
0309:             * the backing column rows to the table rows of the cascaded table. The
0310:             * method {@link #getColumnRow(int, int)} accesses this map in the reverse
0311:             * direction.
0312:             * @param colrow the row of the backing data column
0313:             * @param col the table column to lookup.
0314:             * @return the table row number for accessing the desired table cell
0315:             */
0316:            public int getTableRow(int colrow, int col) {
0317:                return m_rows.getTableRow(colrow, col);
0318:            }
0319:
0320:            /**
0321:             * Add a row to this table. All data columns will be notified and will
0322:             * take on the appropriate default values for the added row.
0323:             * @return the row number of the newly added row
0324:             */
0325:            public int addRow() {
0326:                int r = m_rows.addRow();
0327:                updateRowCount();
0328:
0329:                fireTableEvent(r, r, TableModelEvent.ALL_COLUMNS,
0330:                        TableModelEvent.INSERT);
0331:                return r;
0332:            }
0333:
0334:            /**
0335:             * Add a given number of rows to this table. All data columns will be
0336:             * notified and will take on the appropriate default values for the
0337:             * added rows.
0338:             * @param nrows the number of rows to add.
0339:             */
0340:            public void addRows(int nrows) {
0341:                for (int i = 0; i < nrows; ++i) {
0342:                    addRow();
0343:                }
0344:            }
0345:
0346:            /**
0347:             * Internal method that updates the row counts for local data columns.
0348:             */
0349:            protected void updateRowCount() {
0350:                int maxrow = m_rows.getMaximumRow() + 1;
0351:
0352:                // update columns
0353:                Iterator cols = getColumns();
0354:                while (cols.hasNext()) {
0355:                    Column c = (Column) cols.next();
0356:                    c.setMaximumRow(maxrow);
0357:                }
0358:            }
0359:
0360:            /**
0361:             * Removes a row from this table.
0362:             * @param row the row to delete
0363:             * @return true if the row was successfully deleted, false if the
0364:             * row was already invalid
0365:             */
0366:            public boolean removeRow(int row) {
0367:                if (m_rows.isValidRow(row)) {
0368:                    // the order of operations here is extremely important
0369:                    // otherwise listeners may end up with corrupted state.
0370:                    // fire update *BEFORE* clearing values
0371:                    // allow listeners (e.g., indices) to perform clean-up
0372:                    fireTableEvent(row, row, TableModelEvent.ALL_COLUMNS,
0373:                            TableModelEvent.DELETE);
0374:                    // invalidate the tuple
0375:                    m_tuples.invalidate(row);
0376:                    // release row with row manager
0377:                    // do this before clearing column values, so that any
0378:                    // listeners can determine that the row is invalid
0379:                    m_rows.releaseRow(row);
0380:                    // now clear column values
0381:                    for (Iterator cols = getColumns(); cols.hasNext();) {
0382:                        Column c = (Column) cols.next();
0383:                        c.revertToDefault(row);
0384:                    }
0385:                    return true;
0386:                }
0387:                return false;
0388:            }
0389:
0390:            /**
0391:             * Clear this table, removing all rows.
0392:             * @see prefuse.data.tuple.TupleSet#clear()
0393:             */
0394:            public void clear() {
0395:                IntIterator rows = rows(true);
0396:                while (rows.hasNext()) {
0397:                    removeRow(rows.nextInt());
0398:                }
0399:            }
0400:
0401:            /**
0402:             * Indicates if the given row number corresponds to a valid table row.
0403:             * @param row the row number to check for validity
0404:             * @return true if the row is valid, false if it is not
0405:             */
0406:            public boolean isValidRow(int row) {
0407:                return m_rows.isValidRow(row);
0408:            }
0409:
0410:            // ------------------------------------------------------------------------
0411:            // Column Operations
0412:
0413:            /**
0414:             * Internal method indicating if the given data field is included as a
0415:             * data column.
0416:             */
0417:            protected boolean hasColumn(String name) {
0418:                return getColumnNumber(name) != -1;
0419:            }
0420:
0421:            /**
0422:             * Get the data field name of the column at the given column number.
0423:             * @param col the column number
0424:             * @return the data field name of the column
0425:             */
0426:            public String getColumnName(int col) {
0427:                return (String) m_names.get(col);
0428:            }
0429:
0430:            /**
0431:             * Get the column number for a given data field name.
0432:             * @param field the name of the column to lookup
0433:             * @return the column number of the column, or -1 if the name is not found
0434:             */
0435:            public int getColumnNumber(String field) {
0436:                ColumnEntry e = (ColumnEntry) m_entries.get(field);
0437:                return (e == null ? -1 : e.colnum);
0438:            }
0439:
0440:            /**
0441:             * Get the column number for the given Column instance.
0442:             * @param col the Column instance to lookup
0443:             * @return the column number of the column, or -1 if the name is not found
0444:             */
0445:            public int getColumnNumber(Column col) {
0446:                return m_columns.indexOf(col);
0447:            }
0448:
0449:            /**
0450:             * Get the column at the given column number.
0451:             * @param col the column number
0452:             * @return the Column instance
0453:             */
0454:            public Column getColumn(int col) {
0455:                m_lastCol = col;
0456:                return (Column) m_columns.get(col);
0457:            }
0458:
0459:            /**
0460:             * Get the column with the given data field name
0461:             * @param field the data field name of the column
0462:             * @return the Column instance
0463:             */
0464:            public Column getColumn(String field) {
0465:                ColumnEntry e = (ColumnEntry) m_entries.get(field);
0466:                return (e != null ? e.column : null);
0467:            }
0468:
0469:            /**
0470:             * Add a column with the given name and data type to this table.
0471:             * @param name the data field name for the column
0472:             * @param type the data type, as a Java Class, for the column
0473:             * @see prefuse.data.tuple.TupleSet#addColumn(java.lang.String, java.lang.Class)
0474:             */
0475:            public void addColumn(String name, Class type) {
0476:                addColumn(name, type, null);
0477:            }
0478:
0479:            /**
0480:             * Add a column with the given name and data type to this table.
0481:             * @param name the data field name for the column
0482:             * @param type the data type, as a Java Class, for the column
0483:             * @param defaultValue the default value for column data values
0484:             * @see prefuse.data.tuple.TupleSet#addColumn(java.lang.String, java.lang.Class, java.lang.Object)
0485:             */
0486:            public void addColumn(String name, Class type, Object defaultValue) {
0487:                Column col = ColumnFactory.getColumn(type, m_rows
0488:                        .getMaximumRow() + 1, defaultValue);
0489:                addColumn(name, col);
0490:            }
0491:
0492:            /**
0493:             * Add a derived column to this table, using an Expression instance to
0494:             * dynamically calculate the column data values.
0495:             * @param name the data field name for the column
0496:             * @param expr a String expression in the prefuse expression language, to
0497:             * be parsed into an {@link prefuse.data.expression.Expression} instance.
0498:             * The string is parsed by the
0499:             * {@link prefuse.data.expression.parser.ExpressionParser}. If an error
0500:             * occurs during parsing, an exception will be thrown. 
0501:             * @see prefuse.data.tuple.TupleSet#addColumn(java.lang.String, java.lang.String)
0502:             */
0503:            public void addColumn(String name, String expr) {
0504:                Expression ex = ExpressionParser.parse(expr);
0505:                Throwable t = ExpressionParser.getError();
0506:                if (t != null) {
0507:                    throw new RuntimeException(t);
0508:                } else {
0509:                    addColumn(name, ex);
0510:                }
0511:            }
0512:
0513:            /**
0514:             * Add a derived column to this table, using an Expression instance to
0515:             * dynamically calculate the column data values.
0516:             * @param name the data field name for the column
0517:             * @param expr the Expression that will determine the column values
0518:             * @see prefuse.data.tuple.TupleSet#addColumn(java.lang.String, prefuse.data.expression.Expression)
0519:             */
0520:            public void addColumn(String name, Expression expr) {
0521:                addColumn(name, ColumnFactory.getColumn(this , expr));
0522:            }
0523:
0524:            /**
0525:             * Add a constant column to this table, which returns one constant value
0526:             * for all column rows.
0527:             * @param name the data field name for the column
0528:             * @param type the data type, as a Java Class, for the column
0529:             * @param dflt the default value for column data values
0530:             */
0531:            public void addConstantColumn(String name, Class type, Object dflt) {
0532:                addColumn(name, ColumnFactory.getConstantColumn(type, dflt));
0533:            }
0534:
0535:            /**
0536:             * Internal method for adding a column.
0537:             * @param name the name of the column
0538:             * @param col the actual Column instance
0539:             */
0540:            protected void addColumn(String name, Column col) {
0541:                int idx = getColumnNumber(name);
0542:                if (idx >= 0 && idx < m_columns.size()) {
0543:                    throw new IllegalArgumentException(
0544:                            "Table already has column with name \"" + name
0545:                                    + "\"");
0546:                }
0547:
0548:                // add the column
0549:                m_columns.add(col);
0550:                m_names.add(name);
0551:                m_lastCol = m_columns.size() - 1;
0552:                ColumnEntry entry = new ColumnEntry(m_lastCol, col,
0553:                        new ColumnMetadata(this , name));
0554:
0555:                // add entry, dispose of an overridden entry if needed
0556:                ColumnEntry oldEntry = (ColumnEntry) m_entries.put(name, entry);
0557:                if (oldEntry != null)
0558:                    oldEntry.dispose();
0559:
0560:                invalidateSchema();
0561:
0562:                // listen to what the column has to say
0563:                col.addColumnListener(this );
0564:
0565:                // fire notification
0566:                fireTableEvent(m_rows.getMinimumRow(), m_rows.getMaximumRow(),
0567:                        m_lastCol, TableModelEvent.INSERT);
0568:            }
0569:
0570:            /**
0571:             * Internal method for removing a column.
0572:             * @param idx the column number of the column to remove
0573:             * @return the removed Column instance
0574:             */
0575:            protected Column removeColumn(int idx) {
0576:                // make sure index is legal
0577:                if (idx < 0 || idx >= m_columns.size()) {
0578:                    throw new IllegalArgumentException(
0579:                            "Column index is not legal.");
0580:                }
0581:
0582:                String name = (String) m_names.get(idx);
0583:                ((ColumnEntry) m_entries.get(name)).dispose();
0584:                Column col = (Column) m_columns.remove(idx);
0585:                m_entries.remove(name);
0586:                m_names.remove(idx);
0587:                renumberColumns();
0588:
0589:                m_lastCol = -1;
0590:                invalidateSchema();
0591:
0592:                // ignore what the old column has to say
0593:                col.removeColumnListener(this );
0594:
0595:                // fire notification
0596:                fireTableEvent(m_rows.getMinimumRow(), m_rows.getMaximumRow(),
0597:                        idx, TableModelEvent.DELETE);
0598:
0599:                return col;
0600:            }
0601:
0602:            /**
0603:             * Remove a data field from this table
0604:             * @param field the name of the data field / column to remove
0605:             * @return the removed Column instance
0606:             */
0607:            public Column removeColumn(String field) {
0608:                int idx = m_names.indexOf(field);
0609:                if (idx < 0) {
0610:                    throw new IllegalArgumentException("No such column.");
0611:                }
0612:                return removeColumn(idx);
0613:            }
0614:
0615:            /**
0616:             * Remove a column from this table
0617:             * @param c the column instance to remove
0618:             */
0619:            public void removeColumn(Column c) {
0620:                int idx = m_columns.indexOf(c);
0621:                if (idx < 0) {
0622:                    throw new IllegalArgumentException("No such column.");
0623:                }
0624:                removeColumn(idx);
0625:            }
0626:
0627:            /**
0628:             * Internal method that re-numbers columns upon column removal.
0629:             */
0630:            protected void renumberColumns() {
0631:                Iterator iter = m_names.iterator();
0632:                for (int idx = 0; iter.hasNext(); ++idx) {
0633:                    String name = (String) iter.next();
0634:                    ColumnEntry e = (ColumnEntry) m_entries.get(name);
0635:                    e.colnum = idx;
0636:                }
0637:            }
0638:
0639:            /**
0640:             * Internal method that returns an iterator over columns
0641:             * @return an iterator over columns
0642:             */
0643:            protected Iterator getColumns() {
0644:                return m_columns.iterator();
0645:            }
0646:
0647:            /**
0648:             * Internal method that returns an iterator over column names
0649:             * @return an iterator over column name
0650:             */
0651:            protected Iterator getColumnNames() {
0652:                return m_names.iterator();
0653:            }
0654:
0655:            // ------------------------------------------------------------------------
0656:            // Column Metadata
0657:
0658:            /**
0659:             * Return a metadata instance providing summary information about a column.
0660:             * @param field the data field name of the column
0661:             * @return the columns' associated ColumnMetadata instance
0662:             */
0663:            public ColumnMetadata getMetadata(String field) {
0664:                ColumnEntry e = (ColumnEntry) m_entries.get(field);
0665:                if (e == null) {
0666:                    throw new IllegalArgumentException("Unknown column name: "
0667:                            + field);
0668:                }
0669:                return e.metadata;
0670:            }
0671:
0672:            // ------------------------------------------------------------------------
0673:            // Index Methods
0674:
0675:            /**
0676:             * Create (if necessary) and return an index over the given data field.
0677:             * The first call to this method with a given field name will cause the
0678:             * index to be created and stored. Subsequent calls will simply return
0679:             * the stored index. To attempt to retrieve an index without triggering
0680:             * creation of a new index, use the {@link #getIndex(String)} method.
0681:             * @param field the data field name of the column to index
0682:             * @return the index over the specified data column
0683:             */
0684:            public Index index(String field) {
0685:                ColumnEntry e = (ColumnEntry) m_entries.get(field);
0686:                if (e == null) {
0687:                    throw new IllegalArgumentException("Unknown column name: "
0688:                            + field);
0689:                } else if (e.index != null) {
0690:                    return e.index; // already indexed
0691:                }
0692:
0693:                Column col = e.column;
0694:                try {
0695:                    e.index = new TreeIndex(this , m_rows, col, null);
0696:                } catch (IncompatibleComparatorException ice) { /* can't happen */
0697:                }
0698:
0699:                return e.index;
0700:            }
0701:
0702:            /**
0703:             * Retrieve, without creating, an index for the given data field.
0704:             * @param field the data field name of the column
0705:             * @return the stored index for the column, or null if no index has
0706:             * been created
0707:             */
0708:            public Index getIndex(String field) {
0709:                ColumnEntry e = (ColumnEntry) m_entries.get(field);
0710:                if (e == null) {
0711:                    throw new IllegalArgumentException("Unknown column name: "
0712:                            + field);
0713:                }
0714:                return e.index;
0715:            }
0716:
0717:            /**
0718:             * Internal method for index creation and retrieval.
0719:             * @param field the data field name of the column
0720:             * @param expType the expected data type of the index
0721:             * @param create indicates whether or not a new index should be created
0722:             * if none currently exists for the given data field
0723:             * @return the Index for the given data field
0724:             */
0725:            protected Index getIndex(String field, Class expType, boolean create) {
0726:                if (!expType.equals(getColumnType(field))) {
0727:                    // TODO: need more nuanced type checking here?
0728:                    throw new IllegalArgumentException(
0729:                            "Column type does not match.");
0730:                }
0731:                if (getIndex(field) == null && create) {
0732:                    index(field);
0733:                }
0734:                return getIndex(field);
0735:            }
0736:
0737:            /**
0738:             * Remove the Index associated with the given data field / column name.
0739:             * @param field the name of the column for which to remove the index
0740:             * @return true if an index was successfully removed, false if no
0741:             * such index was found
0742:             */
0743:            public boolean removeIndex(String field) {
0744:                ColumnEntry e = (ColumnEntry) m_entries.get(field);
0745:                if (e == null) {
0746:                    throw new IllegalArgumentException("Unknown column name: "
0747:                            + field);
0748:                }
0749:                if (e.index == null) {
0750:                    return false;
0751:                } else {
0752:                    e.index.dispose();
0753:                    e.index = null;
0754:                    return true;
0755:                }
0756:            }
0757:
0758:            // ------------------------------------------------------------------------
0759:            // Tuple Methods
0760:
0761:            /**
0762:             * Get the Tuple instance providing object-oriented access to the given
0763:             * table row.
0764:             * @param row the table row
0765:             * @return the Tuple for the given table row
0766:             */
0767:            public Tuple getTuple(int row) {
0768:                return m_tuples.getTuple(row);
0769:            }
0770:
0771:            /**
0772:             * Add a Tuple to this table. If the Tuple is already a member of this
0773:             * table, nothing is done and null is returned. If the Tuple is not
0774:             * a member of this Table but has a compatible data schema, as
0775:             * determined by {@link Schema#isAssignableFrom(Schema)}, a new row
0776:             * is created, the Tuple's values are copied, and the new Tuple that
0777:             * is a member of this Table is returned. If the data schemas are not
0778:             * compatible, nothing is done and null is returned.
0779:             * @param t the Tuple to "add" to this table
0780:             * @return the actual Tuple instance added to this table, or null if
0781:             * no new Tuple has been added
0782:             * @see prefuse.data.tuple.TupleSet#addTuple(prefuse.data.Tuple)
0783:             */
0784:            public Tuple addTuple(Tuple t) {
0785:                if (t.getTable() == this ) {
0786:                    return null;
0787:                } else {
0788:                    Schema s = t.getSchema();
0789:                    if (getSchema().isAssignableFrom(s)) {
0790:                        int r = addRow();
0791:                        for (int i = 0; i < s.getColumnCount(); ++i) {
0792:                            String field = s.getColumnName(i);
0793:                            this .set(r, field, t.get(i));
0794:                        }
0795:                        return getTuple(r);
0796:                    } else {
0797:                        return null;
0798:                    }
0799:                }
0800:            }
0801:
0802:            /**
0803:             * Clears the contents of this table and then attempts to add the given
0804:             * Tuple instance.
0805:             * @param t the Tuple to make the sole tuple in thie table
0806:             * @return the actual Tuple instance added to this table, or null if
0807:             * no new Tuple has been added
0808:             * @see prefuse.data.tuple.TupleSet#setTuple(prefuse.data.Tuple)
0809:             */
0810:            public Tuple setTuple(Tuple t) {
0811:                clear();
0812:                return addTuple(t);
0813:            }
0814:
0815:            /**
0816:             * Remove a tuple from this table. If the Tuple is a member of this table,
0817:             * its row is deleted from the table. Otherwise, nothing is done.
0818:             * @param t the Tuple to remove from the table
0819:             * @return true if the Tuple row was successfully deleted, false if the
0820:             * Tuple is invalid or not a member of this table
0821:             * @see prefuse.data.tuple.TupleSet#removeTuple(prefuse.data.Tuple)
0822:             */
0823:            public boolean removeTuple(Tuple t) {
0824:                if (containsTuple(t)) {
0825:                    removeRow(t.getRow());
0826:                    return true;
0827:                } else {
0828:                    return false;
0829:                }
0830:            }
0831:
0832:            /**
0833:             * Indicates if this table contains the given Tuple instance.
0834:             * @param t the Tuple to check for containment
0835:             * @return true if the Tuple represents a row of this table, false if
0836:             * it does not
0837:             * @see prefuse.data.tuple.TupleSet#containsTuple(prefuse.data.Tuple)
0838:             */
0839:            public boolean containsTuple(Tuple t) {
0840:                return (t.getTable() == this  && isValidRow(t.getRow()));
0841:            }
0842:
0843:            /**
0844:             * Get the number of tuples in this table. This is the same as the
0845:             * value returned by {@link #getRowCount()}.
0846:             * @return the number of tuples, which is the same as the number of rows
0847:             * @see prefuse.data.tuple.TupleSet#getTupleCount()
0848:             */
0849:            public int getTupleCount() {
0850:                return getRowCount();
0851:            }
0852:
0853:            /**
0854:             * Returns true, as this table supports the addition of new data fields.
0855:             * @see prefuse.data.tuple.TupleSet#isAddColumnSupported()
0856:             */
0857:            public boolean isAddColumnSupported() {
0858:                return true;
0859:            }
0860:
0861:            // ------------------------------------------------------------------------
0862:            // Data Access Methods
0863:
0864:            /**
0865:             * Check if the <code>get</code> method for the given data field returns
0866:             * values that are compatible with a given target type.
0867:             * @param field the data field to check
0868:             * @param type a Class instance to check for compatibility with the
0869:             * data field values.
0870:             * @return true if the data field is compatible with provided type,
0871:             * false otherwise. If the value is true, objects returned by
0872:             * the {@link #get(int, String)} can be cast to the given type.
0873:             * @see #get(int, String)
0874:             */
0875:            public boolean canGet(String field, Class type) {
0876:                Column c = getColumn(field);
0877:                return (c == null ? false : c.canGet(type));
0878:            }
0879:
0880:            /**
0881:             * Check if the <code>set</code> method for the given data field can
0882:             * accept values of a given target type.
0883:             * @param field the data field to check
0884:             * @param type a Class instance to check for compatibility with the
0885:             * data field values.
0886:             * @return true if the data field is compatible with provided type,
0887:             * false otherwise. If the value is true, objects of the given type
0888:             * can be used as parameters of the {@link #set(int, String, Object)}
0889:             * method.
0890:             * @see #set(int, String, Object)
0891:             */
0892:            public boolean canSet(String field, Class type) {
0893:                Column c = getColumn(field);
0894:                return (c == null ? false : c.canSet(type));
0895:            }
0896:
0897:            /**
0898:             * Get the data value at the given row and field as an Object.
0899:             * @param row the table row to get
0900:             * @param field the data field to retrieve
0901:             * @return the data value as an Object. The concrete type of this
0902:             * Object is dependent on the underlying data column used.
0903:             * @see #canGet(String, Class)
0904:             * @see #getColumnType(String)
0905:             */
0906:            public Object get(int row, String field) {
0907:                int col = getColumnNumber(field);
0908:                row = getColumnRow(row, col);
0909:                return getColumn(col).get(row);
0910:            }
0911:
0912:            /**
0913:             * Set the value of a given row and data field.
0914:             * @param row the table row to set
0915:             * @param field the data field to set
0916:             * @param val the value for the field. If the concrete type of this
0917:             * Object is not compatible with the underlying data model, an
0918:             * Exception will be thrown. Use the {@link #canSet(String, Class)}
0919:             * method to check the type-safety ahead of time.
0920:             * @see #canSet(String, Class)
0921:             * @see #getColumnType(String)
0922:             */
0923:            public void set(int row, String field, Object val) {
0924:                int col = getColumnNumber(field);
0925:                row = getColumnRow(row, col);
0926:                getColumn(col).set(val, row);
0927:
0928:                // we don't fire a notification here, as we catch the
0929:                // notification from the column itself and then dispatch
0930:            }
0931:
0932:            /**
0933:             * Get the data value at the given row and column numbers as an Object.
0934:             * @param row the row number
0935:             * @param col the column number
0936:             * @return the data value as an Object. The concrete type of this
0937:             * Object is dependent on the underlying data column used.
0938:             * @see #canGet(String, Class)
0939:             * @see #getColumnType(int)
0940:             */
0941:            public Object get(int row, int col) {
0942:                row = getColumnRow(row, col);
0943:                return getColumn(col).get(row);
0944:            }
0945:
0946:            /**
0947:             * Set the value of at the given row and column numbers.
0948:             * @param row the row number
0949:             * @param col the column number
0950:             * @param val the value for the field. If the concrete type of this
0951:             * Object is not compatible with the underlying data model, an
0952:             * Exception will be thrown. Use the {@link #canSet(String, Class)}
0953:             * method to check the type-safety ahead of time.
0954:             * @see #canSet(String, Class)
0955:             * @see #getColumnType(String)
0956:             */
0957:            public void set(int row, int col, Object val) {
0958:                row = getColumnRow(row, col);
0959:                getColumn(col).set(val, row);
0960:
0961:                // we don't fire a notification here, as we catch the
0962:                // notification from the column itself and then dispatch
0963:            }
0964:
0965:            /**
0966:             * Get the default value for the given data field.
0967:             * @param field the data field
0968:             * @return the default value, as an Object, used to populate rows
0969:             * of the data field.
0970:             */
0971:            public Object getDefault(String field) {
0972:                int col = getColumnNumber(field);
0973:                return getColumn(col).getDefaultValue();
0974:            }
0975:
0976:            /**
0977:             * Revert this tuple's value for the given field to the default value
0978:             * for the field.
0979:             * @param field the data field
0980:             * @see #getDefault(String)
0981:             */
0982:            public void revertToDefault(int row, String field) {
0983:                int col = getColumnNumber(field);
0984:                row = getColumnRow(row, col);
0985:                getColumn(col).revertToDefault(row);
0986:            }
0987:
0988:            // ------------------------------------------------------------------------
0989:            // Convenience Data Access Methods
0990:
0991:            /**
0992:             * Check if the given data field can return primitive <code>int</code>
0993:             * values.
0994:             * @param field the data field to check
0995:             * @return true if the data field can return primitive <code>int</code>
0996:             * values, false otherwise. If true, the {@link #getInt(int, String)}
0997:             * method can be used safely.
0998:             */
0999:            public final boolean canGetInt(String field) {
1000:                Column col = getColumn(field);
1001:                return (col == null ? false : col.canGetInt());
1002:            }
1003:
1004:            /**
1005:             * Check if the <code>setInt</code> method can safely be used for the
1006:             * given data field.
1007:             * @param field the data field to check
1008:             * @return true if the {@link #setInt(int, String, int)} method can safely
1009:             * be used for the given field, false otherwise.
1010:             */
1011:            public final boolean canSetInt(String field) {
1012:                Column col = getColumn(field);
1013:                return (col == null ? false : col.canSetInt());
1014:            }
1015:
1016:            /**
1017:             * Get the data value at the given row and field as an
1018:             * <code>int</code>.
1019:             * @param row the table row to retrieve
1020:             * @param field the data field to retrieve
1021:             * @see #canGetInt(String)
1022:             */
1023:            public final int getInt(int row, String field) {
1024:                int col = getColumnNumber(field);
1025:                row = getColumnRow(row, col);
1026:                return getColumn(col).getInt(row);
1027:            }
1028:
1029:            /**
1030:             * Set the data value of the given row and field as an
1031:             * <code>int</code>.
1032:             * @param row the table row to set
1033:             * @param field the data field to set
1034:             * @param val the value to set
1035:             * @see #canSetInt(String)
1036:             */
1037:            public final void setInt(int row, String field, int val) {
1038:                int col = getColumnNumber(field);
1039:                row = getColumnRow(row, col);
1040:                getColumn(col).setInt(val, row);
1041:            }
1042:
1043:            /**
1044:             * Get the data value at the given row and field as an
1045:             * <code>int</code>.
1046:             * @param row the table row to retrieve
1047:             * @param col the column number of the data field to retrieve
1048:             * @see #canGetInt(String)
1049:             */
1050:            public final int getInt(int row, int col) {
1051:                row = getColumnRow(row, col);
1052:                return getColumn(col).getInt(row);
1053:            }
1054:
1055:            /**
1056:             * Set the data value of the given row and field as an
1057:             * <code>int</code>.
1058:             * @param row the table row to set
1059:             * @param col the column number of the data field to set
1060:             * @param val the value to set
1061:             * @see #canSetInt(String)
1062:             */
1063:            public final void setInt(int row, int col, int val) {
1064:                row = getColumnRow(row, col);
1065:                getColumn(col).setInt(val, row);
1066:            }
1067:
1068:            // --------------------------------------------------------------
1069:
1070:            /**
1071:             * Check if the given data field can return primitive <code>long</code>
1072:             * values.
1073:             * @param field the data field to check
1074:             * @return true if the data field can return primitive <code>long</code>
1075:             * values, false otherwise. If true, the {@link #getLong(int, String)}
1076:             * method can be used safely.
1077:             */
1078:            public final boolean canGetLong(String field) {
1079:                Column col = getColumn(field);
1080:                return (col == null ? false : col.canGetLong());
1081:            }
1082:
1083:            /**
1084:             * Check if the <code>setLong</code> method can safely be used for the
1085:             * given data field.
1086:             * @param field the data field to check
1087:             * @return true if the {@link #setLong(int, String, long)} method can
1088:             * safely be used for the given field, false otherwise.
1089:             */
1090:            public final boolean canSetLong(String field) {
1091:                Column col = getColumn(field);
1092:                return (col == null ? false : col.canSetLong());
1093:            }
1094:
1095:            /**
1096:             * Get the data value at the given row and field as a
1097:             * <code>long</code>.
1098:             * @param row the table row to retrieve
1099:             * @param field the data field to retrieve
1100:             * @see #canGetLong(String)
1101:             */
1102:            public final long getLong(int row, String field) {
1103:                int col = getColumnNumber(field);
1104:                row = getColumnRow(row, col);
1105:                return getColumn(col).getLong(row);
1106:            }
1107:
1108:            /**
1109:             * Set the data value of the given row and field as a
1110:             * <code>long</code>.
1111:             * @param row the table row to set
1112:             * @param field the data field to set
1113:             * @param val the value to set
1114:             * @see #canSetLong(String)
1115:             */
1116:            public final void setLong(int row, String field, long val) {
1117:                int col = getColumnNumber(field);
1118:                row = getColumnRow(row, col);
1119:                getColumn(col).setLong(val, row);
1120:            }
1121:
1122:            /**
1123:             * Get the data value at the given row and field as an
1124:             * <code>long</code>.
1125:             * @param row the table row to retrieve
1126:             * @param col the column number of the data field to retrieve
1127:             * @see #canGetLong(String)
1128:             */
1129:            public final long getLong(int row, int col) {
1130:                row = getColumnRow(row, col);
1131:                return getColumn(col).getLong(row);
1132:            }
1133:
1134:            /**
1135:             * Set the data value of the given row and field as an
1136:             * <code>long</code>.
1137:             * @param row the table row to set
1138:             * @param col the column number of the data field to set
1139:             * @param val the value to set
1140:             * @see #canSetLong(String)
1141:             */
1142:            public final void setLong(int row, int col, long val) {
1143:                row = getColumnRow(row, col);
1144:                getColumn(col).setLong(val, row);
1145:            }
1146:
1147:            // --------------------------------------------------------------
1148:
1149:            /**
1150:             * Check if the given data field can return primitive <code>float</code>
1151:             * values.
1152:             * @param field the data field to check
1153:             * @return true if the data field can return primitive <code>float</code>
1154:             * values, false otherwise. If true, the {@link #getFloat(int, String)}
1155:             * method can be used safely.
1156:             */
1157:            public final boolean canGetFloat(String field) {
1158:                Column col = getColumn(field);
1159:                return (col == null ? false : col.canGetFloat());
1160:            }
1161:
1162:            /**
1163:             * Check if the <code>setFloat</code> method can safely be used for the
1164:             * given data field.
1165:             * @param field the data field to check
1166:             * @return true if the {@link #setFloat(int, String, float)} method can
1167:             * safely be used for the given field, false otherwise.
1168:             */
1169:            public final boolean canSetFloat(String field) {
1170:                Column col = getColumn(field);
1171:                return (col == null ? false : col.canSetFloat());
1172:            }
1173:
1174:            /**
1175:             * Get the data value at the given row and field as a
1176:             * <code>float</code>.
1177:             * @param row the table row to retrieve
1178:             * @param field the data field to retrieve
1179:             * @see #canGetFloat(String)
1180:             */
1181:            public final float getFloat(int row, String field) {
1182:                int col = getColumnNumber(field);
1183:                row = getColumnRow(row, col);
1184:                return getColumn(col).getFloat(row);
1185:            }
1186:
1187:            /**
1188:             * Set the data value of the given row and field as a
1189:             * <code>float</code>.
1190:             * @param row the table row to set
1191:             * @param field the data field to set
1192:             * @param val the value to set
1193:             * @see #canSetFloat(String)
1194:             */
1195:            public final void setFloat(int row, String field, float val) {
1196:                int col = getColumnNumber(field);
1197:                row = getColumnRow(row, col);
1198:                getColumn(col).setFloat(val, row);
1199:            }
1200:
1201:            /**
1202:             * Get the data value at the given row and field as a
1203:             * <code>float</code>.
1204:             * @param row the table row to retrieve
1205:             * @param col the column number of the data field to get
1206:             * @see #canGetFloat(String)
1207:             */
1208:            public final float getFloat(int row, int col) {
1209:                row = getColumnRow(row, col);
1210:                return getColumn(col).getFloat(row);
1211:            }
1212:
1213:            /**
1214:             * Set the data value of the given row and field as a
1215:             * <code>float</code>.
1216:             * @param row the table row to set
1217:             * @param col the column number of the data field to set
1218:             * @param val the value to set
1219:             * @see #canSetFloat(String)
1220:             */
1221:            public final void setFloat(int row, int col, float val) {
1222:                row = getColumnRow(row, col);
1223:                getColumn(col).setFloat(val, row);
1224:            }
1225:
1226:            // --------------------------------------------------------------
1227:
1228:            /**
1229:             * Check if the given data field can return primitive <code>double</code>
1230:             * values.
1231:             * @param field the data field to check
1232:             * @return true if the data field can return primitive <code>double</code>
1233:             * values, false otherwise. If true, the {@link #getDouble(int, String)}
1234:             * method can be used safely.
1235:             */
1236:            public final boolean canGetDouble(String field) {
1237:                Column col = getColumn(field);
1238:                return (col == null ? false : col.canGetDouble());
1239:            }
1240:
1241:            /**
1242:             * Check if the <code>setDouble</code> method can safely be used for the
1243:             * given data field.
1244:             * @param field the data field to check
1245:             * @return true if the {@link #setDouble(int, String, double)} method can
1246:             * safely be used for the given field, false otherwise.
1247:             */
1248:            public final boolean canSetDouble(String field) {
1249:                Column col = getColumn(field);
1250:                return (col == null ? false : col.canSetDouble());
1251:            }
1252:
1253:            /**
1254:             * Get the data value at the given row and field as a
1255:             * <code>double</code>.
1256:             * @param row the table row to retrieve
1257:             * @param field the data field to retrieve
1258:             * @see #canGetDouble(String)
1259:             */
1260:            public final double getDouble(int row, String field) {
1261:                int col = getColumnNumber(field);
1262:                row = getColumnRow(row, col);
1263:                return getColumn(col).getDouble(row);
1264:            }
1265:
1266:            /**
1267:             * Set the data value of the given row and field as a
1268:             * <code>double</code>.
1269:             * @param row the table row to set
1270:             * @param field the data field to set
1271:             * @param val the value to set
1272:             * @see #canSetDouble(String)
1273:             */
1274:            public final void setDouble(int row, String field, double val) {
1275:                int col = getColumnNumber(field);
1276:                row = getColumnRow(row, col);
1277:                getColumn(col).setDouble(val, row);
1278:            }
1279:
1280:            /**
1281:             * Get the data value at the given row and field as a
1282:             * <code>double</code>.
1283:             * @param row the table row to retrieve
1284:             * @param col the column number of the data field to get
1285:             * @see #canGetDouble(String)
1286:             */
1287:            public final double getDouble(int row, int col) {
1288:                row = getColumnRow(row, col);
1289:                return getColumn(col).getDouble(row);
1290:            }
1291:
1292:            /**
1293:             * Set the data value of the given row and field as a
1294:             * <code>double</code>.
1295:             * @param row the table row to set
1296:             * @param col the column number of the data field to set
1297:             * @param val the value to set
1298:             * @see #canSetDouble(String)
1299:             */
1300:            public final void setDouble(int row, int col, double val) {
1301:                row = getColumnRow(row, col);
1302:                getColumn(col).setDouble(val, row);
1303:            }
1304:
1305:            // --------------------------------------------------------------
1306:
1307:            /**
1308:             * Check if the given data field can return primitive <code>boolean</code>
1309:             * values.
1310:             * @param field the data field to check
1311:             * @return true if the data field can return primitive <code>boolean</code>
1312:             * values, false otherwise. If true, the {@link #getBoolean(int, String)}
1313:             * method can be used safely.
1314:             */
1315:            public final boolean canGetBoolean(String field) {
1316:                Column col = getColumn(field);
1317:                return (col == null ? false : col.canGetBoolean());
1318:            }
1319:
1320:            /**
1321:             * Check if the <code>setBoolean</code> method can safely be used for the
1322:             * given data field.
1323:             * @param field the data field to check
1324:             * @return true if the {@link #setBoolean(int, String, boolean)} method can
1325:             * safely be used for the given field, false otherwise.
1326:             */
1327:            public final boolean canSetBoolean(String field) {
1328:                Column col = getColumn(field);
1329:                return (col == null ? false : col.canSetBoolean());
1330:            }
1331:
1332:            /**
1333:             * Get the data value at the given row and field as a
1334:             * <code>boolean</code>.
1335:             * @param row the table row to retrieve
1336:             * @param field the data field to retrieve
1337:             * @see #canGetBoolean(String)
1338:             */
1339:            public final boolean getBoolean(int row, String field) {
1340:                int col = getColumnNumber(field);
1341:                row = getColumnRow(row, col);
1342:                return getColumn(col).getBoolean(row);
1343:            }
1344:
1345:            /**
1346:             * Set the data value of the given row and field as a
1347:             * <code>boolean</code>.
1348:             * @param row the table row to set
1349:             * @param field the data field to set
1350:             * @param val the value to set
1351:             * @see #canSetBoolean(String)
1352:             */
1353:            public final void setBoolean(int row, String field, boolean val) {
1354:                int col = getColumnNumber(field);
1355:                row = getColumnRow(row, col);
1356:                getColumn(col).setBoolean(val, row);
1357:            }
1358:
1359:            /**
1360:             * Get the data value at the given row and field as a
1361:             * <code>boolean</code>.
1362:             * @param row the table row to retrieve
1363:             * @param col the column number of the data field to get
1364:             * @see #canGetBoolean(String)
1365:             */
1366:            public final boolean getBoolean(int row, int col) {
1367:                row = getColumnRow(row, col);
1368:                return getColumn(col).getBoolean(row);
1369:            }
1370:
1371:            /**
1372:             * Set the data value of the given row and field as a
1373:             * <code>boolean</code>.
1374:             * @param row the table row to set
1375:             * @param col the column number of the data field to set
1376:             * @param val the value to set
1377:             * @see #canSetBoolean(String)
1378:             */
1379:            public final void setBoolean(int row, int col, boolean val) {
1380:                row = getColumnRow(row, col);
1381:                getColumn(col).setBoolean(val, row);
1382:            }
1383:
1384:            // --------------------------------------------------------------
1385:
1386:            /**
1387:             * Check if the given data field can return primitive <code>String</code>
1388:             * values.
1389:             * @param field the data field to check
1390:             * @return true if the data field can return primitive <code>String</code>
1391:             * values, false otherwise. If true, the {@link #getString(int, String)}
1392:             * method can be used safely.
1393:             */
1394:            public final boolean canGetString(String field) {
1395:                Column col = getColumn(field);
1396:                return (col == null ? false : col.canGetString());
1397:            }
1398:
1399:            /**
1400:             * Check if the <code>setString</code> method can safely be used for the
1401:             * given data field.
1402:             * @param field the data field to check
1403:             * @return true if the {@link #setString(int, String, String)} method can
1404:             * safely be used for the given field, false otherwise.
1405:             */
1406:            public final boolean canSetString(String field) {
1407:                Column col = getColumn(field);
1408:                return (col == null ? false : col.canSetString());
1409:            }
1410:
1411:            /**
1412:             * Get the data value at the given row and field as a
1413:             * <code>String</code>.
1414:             * @param row the table row to retrieve
1415:             * @param field the data field to retrieve
1416:             * @see #canGetString(String)
1417:             */
1418:            public final String getString(int row, String field) {
1419:                int col = getColumnNumber(field);
1420:                row = getColumnRow(row, col);
1421:                return getColumn(col).getString(row);
1422:            }
1423:
1424:            /**
1425:             * Set the data value of the given row and field as a
1426:             * <code>String</code>.
1427:             * @param row the table row to set
1428:             * @param field the data field to set
1429:             * @param val the value to set
1430:             * @see #canSetString(String)
1431:             */
1432:            public final void setString(int row, String field, String val) {
1433:                int col = getColumnNumber(field);
1434:                row = getColumnRow(row, col);
1435:                getColumn(col).setString(val, row);
1436:            }
1437:
1438:            /**
1439:             * Get the data value at the given row and field as a
1440:             * <code>String</code>.
1441:             * @param row the table row to retrieve
1442:             * @param col the column number of the data field to retrieve
1443:             * @see #canGetString(String)
1444:             */
1445:            public final String getString(int row, int col) {
1446:                row = getColumnRow(row, col);
1447:                return getColumn(col).getString(row);
1448:            }
1449:
1450:            /**
1451:             * Set the data value of the given row and field as a
1452:             * <code>String</code>.
1453:             * @param row the table row to set
1454:             * @param col the column number of the data field to set
1455:             * @param val the value to set
1456:             * @see #canSetString(String)
1457:             */
1458:            public final void setString(int row, int col, String val) {
1459:                row = getColumnRow(row, col);
1460:                getColumn(col).setString(val, row);
1461:            }
1462:
1463:            // --------------------------------------------------------------
1464:
1465:            /**
1466:             * Check if the given data field can return primitive <code>Date</code>
1467:             * values.
1468:             * @param field the data field to check
1469:             * @return true if the data field can return primitive <code>Date</code>
1470:             * values, false otherwise. If true, the {@link #getDate(int, String)}
1471:             * method can be used safely.
1472:             */
1473:            public final boolean canGetDate(String field) {
1474:                Column col = getColumn(field);
1475:                return (col == null ? false : col.canGetDate());
1476:            }
1477:
1478:            /**
1479:             * Check if the <code>setDate</code> method can safely be used for the
1480:             * given data field.
1481:             * @param field the data field to check
1482:             * @return true if the {@link #setDate(int, String, Date)} method can
1483:             * safely be used for the given field, false otherwise.
1484:             */
1485:            public final boolean canSetDate(String field) {
1486:                Column col = getColumn(field);
1487:                return (col == null ? false : col.canSetDate());
1488:            }
1489:
1490:            /**
1491:             * Get the data value at the given row and field as a
1492:             * <code>Date</code>.
1493:             * @param row the table row to retrieve
1494:             * @param field the data field to retrieve
1495:             * @see #canGetDate(String)
1496:             */
1497:            public final Date getDate(int row, String field) {
1498:                int col = getColumnNumber(field);
1499:                row = getColumnRow(row, col);
1500:                return getColumn(col).getDate(row);
1501:            }
1502:
1503:            /**
1504:             * Set the data value of the given row and field as a
1505:             * <code>Date</code>.
1506:             * @param row the table row to set
1507:             * @param field the data field to set
1508:             * @param val the value to set
1509:             * @see #canSetDate(String)
1510:             */
1511:            public final void setDate(int row, String field, Date val) {
1512:                int col = getColumnNumber(field);
1513:                row = getColumnRow(row, col);
1514:                getColumn(col).setDate(val, row);
1515:            }
1516:
1517:            /**
1518:             * Get the data value at the given row and field as a
1519:             * <code>Date</code>.
1520:             * @param row the table row to retrieve
1521:             * @param col the column number of the data field to retrieve
1522:             * @see #canGetDate(String)
1523:             */
1524:            public final Date getDate(int row, int col) {
1525:                row = getColumnRow(row, col);
1526:                return getColumn(col).getDate(row);
1527:            }
1528:
1529:            /**
1530:             * Set the data value of the given row and field as a
1531:             * <code>Date</code>.
1532:             * @param row the table row to set
1533:             * @param col the column number of the data field to set
1534:             * @param val the value to set
1535:             * @see #canSetDate(String)
1536:             */
1537:            public final void setDate(int row, int col, Date val) {
1538:                row = getColumnRow(row, col);
1539:                getColumn(col).setDate(val, row);
1540:            }
1541:
1542:            // ------------------------------------------------------------------------
1543:            // Query Operations
1544:
1545:            /**
1546:             * Query this table for a filtered, sorted subset of this table. This
1547:             * operation creates an entirely new table independent of this table.
1548:             * If a filtered view of this same table is preferred, use the
1549:             * {@link CascadedTable} class.
1550:             * @param filter the predicate filter determining which rows to include
1551:             * in the new table. If this value is null, all rows will be included.
1552:             * @param sort the sorting criteria determining the order in which
1553:             * rows are added to the new table. If this value is null, the rows
1554:             * will not be sorted.
1555:             * @return a new table meeting the query specification
1556:             */
1557:            public Table select(Predicate filter, Sort sort) {
1558:                Table t = getSchema().instantiate();
1559:                Iterator tuples = tuples(filter, sort);
1560:                while (tuples.hasNext()) {
1561:                    t.addTuple((Tuple) tuples.next());
1562:                }
1563:                return t;
1564:            }
1565:
1566:            /**
1567:             * Removes all table rows that meet the input predicate filter.
1568:             * @param filter a predicate specifying which rows to remove from
1569:             * the table.
1570:             */
1571:            public void remove(Predicate filter) {
1572:                for (IntIterator ii = rows(filter); ii.hasNext();)
1573:                    removeRow(ii.nextInt());
1574:            }
1575:
1576:            // ------------------------------------------------------------------------
1577:            // Iterators
1578:
1579:            /**
1580:             * Return a TableIterator over the rows of this table.
1581:             * @return a TableIterator over this table
1582:             */
1583:            public TableIterator iterator() {
1584:                return iterator(rows());
1585:            }
1586:
1587:            /**
1588:             * Return a TableIterator over the given rows of this table.
1589:             * @param rows an iterator over the table rows to visit
1590:             * @return a TableIterator over this table
1591:             */
1592:            public TableIterator iterator(IntIterator rows) {
1593:                return new TableIterator(this , rows);
1594:            }
1595:
1596:            /**
1597:             * Get an iterator over the tuples in this table.
1598:             * @return an iterator over the table tuples
1599:             * @see prefuse.data.tuple.TupleSet#tuples()
1600:             */
1601:            public Iterator tuples() {
1602:                return m_tuples.iterator(rows());
1603:            }
1604:
1605:            /**
1606:             * Get an iterator over the tuples in this table in reverse order.
1607:             * @return an iterator over the table tuples in reverse order
1608:             */
1609:            public Iterator tuplesReversed() {
1610:                return m_tuples.iterator(rows(true));
1611:            }
1612:
1613:            /**
1614:             * Get an iterator over the tuples for the given rows in this table.
1615:             * @param rows an iterator over the table rows to visit
1616:             * @return an iterator over the selected table tuples
1617:             */
1618:            public Iterator tuples(IntIterator rows) {
1619:                return m_tuples.iterator(rows);
1620:            }
1621:
1622:            /**
1623:             * Get an interator over the row numbers of this table.
1624:             * @return an iterator over the rows of this table
1625:             */
1626:            public IntIterator rows() {
1627:                return m_rows.rows();
1628:            }
1629:
1630:            /**
1631:             * Get a filtered iterator over the row numbers of this table, returning
1632:             * only the rows whose tuples match the given filter predicate.
1633:             * @param filter the filter predicate to apply
1634:             * @return a filtered iterator over the rows of this table
1635:             */
1636:            public IntIterator rows(Predicate filter) {
1637:                return FilterIteratorFactory.rows(this , filter);
1638:            }
1639:
1640:            /**
1641:             * Get an interator over the row numbers of this table.
1642:             * @param reverse true to iterate in rever order, false for normal order
1643:             * @return an iterator over the rows of this table
1644:             */
1645:            public IntIterator rows(boolean reverse) {
1646:                return m_rows.rows(reverse);
1647:            }
1648:
1649:            /**
1650:             * Get an iterator over the rows of this table, sorted by the given data
1651:             * field. This method will create an index over the field if one does
1652:             * not yet exist.
1653:             * @param field the data field to sort by
1654:             * @param ascend true if the iteration should proceed in an ascending
1655:             * (lowest to highest) sort order, false for a descending order
1656:             * @return the sorted iterator over rows of this table
1657:             */
1658:            public IntIterator rowsSortedBy(String field, boolean ascend) {
1659:                Class type = getColumnType(field);
1660:                Index index = getIndex(field, type, true);
1661:                int t = ascend ? Index.TYPE_ASCENDING : Index.TYPE_DESCENDING;
1662:                return index.allRows(t);
1663:            }
1664:
1665:            /**
1666:             * Return an iterator over a range of rwos in this table, determined
1667:             * by a bounded range for a given data field. A new index over the
1668:             * data field will be created if it doesn't already exist.
1669:             * @param field the data field for determining the bounded range
1670:             * @param lo the minimum range value
1671:             * @param hi the maximum range value
1672:             * @param indexType indicate the sort order and inclusivity/exclusivity
1673:             * of the range bounds, using the constants of the
1674:             * {@link prefuse.data.util.Index} class.
1675:             * @return an iterator over a range of table rows, determined by a 
1676:             * sorted bounded range of a data field
1677:             */
1678:            public IntIterator rangeSortedBy(String field, int lo, int hi,
1679:                    int indexType) {
1680:                Index index = getIndex(field, int.class, true);
1681:                return index.rows(lo, hi, indexType);
1682:            }
1683:
1684:            /**
1685:             * Return an iterator over a range of rwos in this table, determined
1686:             * by a bounded range for a given data field. A new index over the
1687:             * data field will be created if it doesn't already exist. 
1688:             * @param field the data field for determining the bounded range
1689:             * @param lo the minimum range value
1690:             * @param hi the maximum range value
1691:             * @param indexType indicate the sort order and inclusivity/exclusivity
1692:             * of the range bounds, using the constants of the
1693:             * {@link prefuse.data.util.Index} class.
1694:             * @return an iterator over a range of table rows, determined by a 
1695:             * sorted bounded range of a data field
1696:             */
1697:            public IntIterator rangeSortedBy(String field, long lo, long hi,
1698:                    int indexType) {
1699:                Index index = getIndex(field, long.class, true);
1700:                return index.rows(lo, hi, indexType);
1701:            }
1702:
1703:            /**
1704:             * Return an iterator over a range of rwos in this table, determined
1705:             * by a bounded range for a given data field. A new index over the
1706:             * data field will be created if it doesn't already exist.
1707:             * @param field the data field for determining the bounded range
1708:             * @param lo the minimum range value
1709:             * @param hi the maximum range value
1710:             * @param indexType indicate the sort order and inclusivity/exclusivity
1711:             * of the range bounds, using the constants of the
1712:             * {@link prefuse.data.util.Index} class.
1713:             * @return an iterator over a range of table rows, determined by a 
1714:             * sorted bounded range of a data field
1715:             */
1716:            public IntIterator rangeSortedBy(String field, float lo, float hi,
1717:                    int indexType) {
1718:                Index index = getIndex(field, float.class, true);
1719:                return index.rows(lo, hi, indexType);
1720:            }
1721:
1722:            /**
1723:             * Return an iterator over a range of rwos in this table, determined
1724:             * by a bounded range for a given data field. A new index over the
1725:             * data field will be created if it doesn't already exist.
1726:             * @param field the data field for determining the bounded range
1727:             * @param lo the minimum range value
1728:             * @param hi the maximum range value
1729:             * @param indexType indicate the sort order and inclusivity/exclusivity
1730:             * of the range bounds, using the constants of the
1731:             * {@link prefuse.data.util.Index} class.
1732:             * @return an iterator over a range of table rows, determined by a 
1733:             * sorted bounded range of a data field
1734:             */
1735:            public IntIterator rangeSortedBy(String field, double lo,
1736:                    double hi, int indexType) {
1737:                Index index = getIndex(field, double.class, true);
1738:                return index.rows(lo, hi, indexType);
1739:            }
1740:
1741:            /**
1742:             * Return an iterator over a range of rwos in this table, determined
1743:             * by a bounded range for a given data field. A new index over the
1744:             * data field will be created if it doesn't already exist.
1745:             * @param field the data field for determining the bounded range
1746:             * @param lo the minimum range value
1747:             * @param hi the maximum range value
1748:             * @param indexType indicate the sort order and inclusivity/exclusivity
1749:             * of the range bounds, using the constants of the
1750:             * {@link prefuse.data.util.Index} class.
1751:             * @return an iterator over a range of table rows, determined by a 
1752:             * sorted bounded range of a data field
1753:             */
1754:            public IntIterator rangeSortedBy(String field, Object lo,
1755:                    Object hi, int indexType) {
1756:                Class type = TypeLib.getSharedType(lo, hi);
1757:                // TODO: check this for correctness
1758:                if (type == null)
1759:                    throw new IllegalArgumentException("Incompatible arguments");
1760:                Index index = getIndex(field, type, true);
1761:                return index.rows(lo, hi, indexType);
1762:            }
1763:
1764:            // ------------------------------------------------------------------------
1765:            // Listener Methods
1766:
1767:            // -- ColumnListeners -----------------------------------------------------
1768:
1769:            /**
1770:             * @see prefuse.data.event.ColumnListener#columnChanged(prefuse.data.column.Column, int, boolean)
1771:             */
1772:            public void columnChanged(Column src, int idx, boolean prev) {
1773:                handleColumnChanged(src, idx, idx);
1774:            }
1775:
1776:            /**
1777:             * @see prefuse.data.event.ColumnListener#columnChanged(prefuse.data.column.Column, int, double)
1778:             */
1779:            public void columnChanged(Column src, int idx, double prev) {
1780:                handleColumnChanged(src, idx, idx);
1781:            }
1782:
1783:            /**
1784:             * @see prefuse.data.event.ColumnListener#columnChanged(prefuse.data.column.Column, int, float)
1785:             */
1786:            public void columnChanged(Column src, int idx, float prev) {
1787:                handleColumnChanged(src, idx, idx);
1788:            }
1789:
1790:            /**
1791:             * @see prefuse.data.event.ColumnListener#columnChanged(prefuse.data.column.Column, int, int)
1792:             */
1793:            public void columnChanged(Column src, int idx, int prev) {
1794:                handleColumnChanged(src, idx, idx);
1795:            }
1796:
1797:            /**
1798:             * @see prefuse.data.event.ColumnListener#columnChanged(prefuse.data.column.Column, int, long)
1799:             */
1800:            public void columnChanged(Column src, int idx, long prev) {
1801:                handleColumnChanged(src, idx, idx);
1802:            }
1803:
1804:            /**
1805:             * @see prefuse.data.event.ColumnListener#columnChanged(prefuse.data.column.Column, int, java.lang.Object)
1806:             */
1807:            public void columnChanged(Column src, int idx, Object prev) {
1808:                handleColumnChanged(src, idx, idx);
1809:            }
1810:
1811:            /**
1812:             * @see prefuse.data.event.ColumnListener#columnChanged(prefuse.data.column.Column, int, int, int)
1813:             */
1814:            public void columnChanged(Column src, int type, int start, int end) {
1815:                handleColumnChanged(src, start, end);
1816:            }
1817:
1818:            /**
1819:             * Handle a column change event.
1820:             * @param c the modified column
1821:             * @param start the starting row of the modified range
1822:             * @param end the ending row (inclusive) of the modified range
1823:             */
1824:            protected void handleColumnChanged(Column c, int start, int end) {
1825:                for (; !isValidRow(start) && start <= end; ++start)
1826:                    ;
1827:                if (start > end)
1828:                    return; // bail if no valid rows
1829:
1830:                // determine the index of the updated column
1831:                int idx;
1832:                if (m_lastCol != -1 && c == getColumn(m_lastCol)) {
1833:                    // constant time
1834:                    idx = m_lastCol;
1835:                } else {
1836:                    // linear time
1837:                    idx = getColumnNumber(c);
1838:                }
1839:
1840:                // if we have a valid index, fire a notification
1841:                if (idx >= 0) {
1842:                    fireTableEvent(start, end, idx, TableModelEvent.UPDATE);
1843:                }
1844:            }
1845:
1846:            // -- TableListeners ------------------------------------------------------
1847:
1848:            /**
1849:             * Add a table listener to this table.
1850:             * @param listnr the listener to add
1851:             */
1852:            public void addTableListener(TableListener listnr) {
1853:                if (!m_listeners.contains(listnr))
1854:                    m_listeners.add(listnr);
1855:            }
1856:
1857:            /**
1858:             * Remove a table listener from this table.
1859:             * @param listnr the listener to remove
1860:             */
1861:            public void removeTableListener(TableListener listnr) {
1862:                m_listeners.remove(listnr);
1863:            }
1864:
1865:            /**
1866:             * Removes all table listeners from this table.
1867:             */
1868:            public void removeAllTableListeners() {
1869:                m_listeners.clear();
1870:            }
1871:
1872:            /**
1873:             * Fire a table event to notify listeners.
1874:             * @param row0 the starting row of the modified range
1875:             * @param row1 the ending row (inclusive) of the modified range
1876:             * @param col the number of the column modified, or
1877:             * {@link prefuse.data.event.EventConstants#ALL_COLUMNS} for operations
1878:             * effecting all columns.
1879:             * @param type the table modification type, one of
1880:             * {@link prefuse.data.event.EventConstants#INSERT},
1881:             * {@link prefuse.data.event.EventConstants#DELETE}, or
1882:             * {@link prefuse.data.event.EventConstants#UPDATE}.
1883:             */
1884:            protected void fireTableEvent(int row0, int row1, int col, int type) {
1885:                // increment the modification count
1886:                ++m_modCount;
1887:
1888:                if (type != EventConstants.UPDATE
1889:                        && col == EventConstants.ALL_COLUMNS) {
1890:                    // fire event to all tuple set listeners
1891:                    fireTupleEvent(this , row0, row1, type);
1892:                }
1893:
1894:                if (!m_listeners.isEmpty()) {
1895:                    // fire event to all table listeners
1896:                    Object[] lstnrs = m_listeners.getArray();
1897:                    for (int i = 0; i < lstnrs.length; ++i) {
1898:                        ((TableListener) lstnrs[i]).tableChanged(this , row0,
1899:                                row1, col, type);
1900:                    }
1901:                }
1902:            }
1903:
1904:            // ------------------------------------------------------------------------
1905:            // String Methods
1906:
1907:            /**
1908:             * @see java.lang.Object#toString()
1909:             */
1910:            public String toString() {
1911:                StringBuffer sbuf = new StringBuffer();
1912:                sbuf.append("Table[");
1913:                sbuf.append("rows=").append(getRowCount());
1914:                sbuf.append(", cols=").append(getColumnCount());
1915:                sbuf.append(", maxrow=").append(m_rows.getMaximumRow());
1916:                sbuf.append("]");
1917:                return sbuf.toString();
1918:            }
1919:
1920:            // ------------------------------------------------------------------------
1921:            // ColumnEntry helper
1922:
1923:            /**
1924:             * Helper class that encapsulates a map entry for a column, including the
1925:             * column itself and its metadata and index.
1926:             * 
1927:             * @author <a href="http://jheer.org">jeffrey heer</a>
1928:             */
1929:            protected static class ColumnEntry {
1930:
1931:                /** The column number. */
1932:                public int colnum;
1933:                /** The Column instance. */
1934:                public Column column;
1935:                /** The column metadata instance. */
1936:                public ColumnMetadata metadata;
1937:                /** The column Index instance. */
1938:                public Index index;
1939:
1940:                /**
1941:                 * Create a new ColumnEntry.
1942:                 * @param col the column number
1943:                 * @param column the Column instance
1944:                 * @param metadata the ColumnMetadata instance
1945:                 */
1946:                public ColumnEntry(int col, Column column,
1947:                        ColumnMetadata metadata) {
1948:                    this .colnum = col;
1949:                    this .column = column;
1950:                    this .metadata = metadata;
1951:                    this .index = null;
1952:                }
1953:
1954:                /**
1955:                 * Dispose of this column entry, disposing of any allocated
1956:                 * metadata or index instances.
1957:                 */
1958:                public void dispose() {
1959:                    if (metadata != null)
1960:                        metadata.dispose();
1961:                    if (index != null)
1962:                        index.dispose();
1963:                }
1964:
1965:            } // end of inner class ColumnEntry
1966:
1967:        } // end of class Table
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.