Source Code Cross Referenced for CascadedTable.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) 


001:        package prefuse.data;
002:
003:        import java.util.ArrayList;
004:        import java.util.Iterator;
005:
006:        import javax.swing.event.TableModelEvent;
007:
008:        import prefuse.data.column.Column;
009:        import prefuse.data.column.ColumnMetadata;
010:        import prefuse.data.event.EventConstants;
011:        import prefuse.data.event.ExpressionListener;
012:        import prefuse.data.event.ProjectionListener;
013:        import prefuse.data.event.TableListener;
014:        import prefuse.data.expression.BooleanLiteral;
015:        import prefuse.data.expression.Expression;
016:        import prefuse.data.expression.Predicate;
017:        import prefuse.data.tuple.TableTuple;
018:        import prefuse.data.util.AcceptAllColumnProjection;
019:        import prefuse.data.util.CascadedRowManager;
020:        import prefuse.data.util.ColumnProjection;
021:        import prefuse.util.collections.CompositeIterator;
022:        import prefuse.util.collections.IntIterator;
023:
024:        /**
025:         * <p>Table subclass featuring a "cascaded" table design - a CascadedTable can
026:         * have a parent table, from which it inherits a potentially filtered set of
027:         * rows and columns. Child tables may override the columns of the parent by
028:         * having a column of the same name as that of the parent, in which case the
029:         * parent's column will not be accessible.</p>
030:         * 
031:         * <p>Table rows of the parent table can be selectively included by providing
032:         * a {@link prefuse.data.expression.Predicate} that filters the parent rows.
033:         * Columns of the parent table can be selectively included by providing
034:         * a {@link prefuse.data.util.ColumnProjection} indicating the columns to
035:         * include.</p>
036:         * 
037:         * <p>Tuple instances backed by a CascadedTable will be not be equivalent to
038:         * the tuples backed by the parent table. However, setting a value in a
039:         * CascadedTable that is inherited from a parent table <em>will</em> update
040:         * the value in the parent table.</p>
041:         * 
042:         * @author <a href="http://jheer.org">jeffrey heer</a>
043:         */
044:        public class CascadedTable extends Table {
045:
046:            /** Cascaded parent table */
047:            protected Table m_parent;
048:            /** List of included parent column names */
049:            protected ArrayList m_pnames;
050:
051:            /** ColumnProjection determining which columns of the parent table
052:             * are included in this table. */
053:            protected ColumnProjection m_colFilter;
054:            /** Selection Predicate determining which rows of the parent table
055:             * are included in this table. */
056:            protected Predicate m_rowFilter;
057:
058:            /** An internal listener class */
059:            protected Listener m_listener;
060:
061:            // ------------------------------------------------------------------------
062:            // Constructor
063:
064:            /**
065:             * Create a new CascadedTable. By default all rows and columns of the
066:             * parent table are included in this one.
067:             * @param parent the parent Table to use
068:             */
069:            public CascadedTable(Table parent) {
070:                this (parent, null, null);
071:            }
072:
073:            /**
074:             * Create a new CascadedTable. By default all columns of the parent
075:             * table are included in this one.
076:             * @param parent the parent Table to use
077:             * @param rowFilter a Predicate determining which rows of the parent
078:             * table to include in this one.
079:             */
080:            public CascadedTable(Table parent, Predicate rowFilter) {
081:                this (parent, rowFilter, null);
082:            }
083:
084:            /**
085:             * Create a new CascadedTable. By default all rows of the parent
086:             * table are included in this one.
087:             * @param parent the parent Table to use
088:             * @param colFilter a ColumnProjection determining which columns of the
089:             * parent table to include in this one.
090:             */
091:            public CascadedTable(Table parent, ColumnProjection colFilter) {
092:                this (parent, null, colFilter);
093:            }
094:
095:            /**
096:             * Create a new CascadedTable.
097:             * @param parent the parent Table to use
098:             * @param rowFilter a Predicate determining which rows of the parent
099:             * table to include in this one.
100:             * @param colFilter a ColumnProjection determining which columns of the
101:             * parent table to include in this one.
102:             */
103:            public CascadedTable(Table parent, Predicate rowFilter,
104:                    ColumnProjection colFilter) {
105:                this (parent, rowFilter, colFilter, TableTuple.class);
106:            }
107:
108:            /**
109:             * Create a new CascadedTable.
110:             * @param parent the parent Table to use
111:             * @param rowFilter a Predicate determining which rows of the parent
112:             * table to include in this one.
113:             * @param colFilter a ColumnProjection determining which columns of the
114:             * parent table to include in this one.
115:             * @param tupleType the class type of the Tuple instances to use
116:             */
117:            protected CascadedTable(Table parent, Predicate rowFilter,
118:                    ColumnProjection colFilter, Class tupleType) {
119:                super (0, 0, tupleType);
120:                m_parent = parent;
121:                m_pnames = new ArrayList();
122:                m_rows = new CascadedRowManager(this );
123:                m_listener = new Listener();
124:
125:                setColumnProjection(colFilter);
126:                setRowFilter(rowFilter);
127:                m_parent.addTableListener(m_listener);
128:            }
129:
130:            // -- non-cascading version -----------------------------------------------
131:
132:            /**
133:             * Create a CascadedTable without a backing parent table.
134:             */
135:            protected CascadedTable() {
136:                this (TableTuple.class);
137:            }
138:
139:            /**
140:             * Create a CascadedTable without a backing parent table.
141:             * @param tupleType the class type of the Tuple instances to use
142:             */
143:            protected CascadedTable(Class tupleType) {
144:                super (0, 0, tupleType);
145:                m_pnames = new ArrayList();
146:            }
147:
148:            // ------------------------------------------------------------------------
149:            // Filter Methods
150:
151:            /**
152:             * Determines which columns are inherited from the backing parent table.
153:             */
154:            protected void filterColumns() {
155:                if (m_parent == null)
156:                    return;
157:
158:                for (int i = 0; i < m_pnames.size(); ++i) {
159:                    String name = (String) m_pnames.get(i);
160:                    Column col = m_parent.getColumn(i);
161:                    boolean contained = m_names.contains(name);
162:                    if (!m_colFilter.include(col, name) || contained) {
163:                        m_pnames.remove(i--);
164:                        if (!contained) {
165:                            ((ColumnEntry) m_entries.get(name)).dispose();
166:                            m_entries.remove(name);
167:                        }
168:
169:                        // fire notification
170:                        fireTableEvent(m_rows.getMinimumRow(), m_rows
171:                                .getMaximumRow(), i, EventConstants.DELETE);
172:                    }
173:                }
174:
175:                m_pnames.clear();
176:
177:                Iterator pcols = m_parent.getColumnNames();
178:                for (int i = 0, j = m_columns.size(); pcols.hasNext(); ++i) {
179:                    String name = (String) pcols.next();
180:                    Column col = m_parent.getColumn(i);
181:
182:                    if (m_colFilter.include(col, name)
183:                            && !m_names.contains(name)) {
184:                        m_pnames.add(name);
185:                        ColumnEntry entry = (ColumnEntry) m_entries.get(name);
186:                        if (entry == null) {
187:                            entry = new ColumnEntry(j++, col,
188:                                    new ColumnMetadata(this , name));
189:                            m_entries.put(name, entry);
190:                            // fire notification
191:                            fireTableEvent(m_rows.getMinimumRow(), m_rows
192:                                    .getMaximumRow(), i, EventConstants.INSERT);
193:                        } else {
194:                            entry.colnum = j++;
195:                        }
196:                        m_lastCol = m_columns.size() - 1;
197:                    }
198:                }
199:
200:            }
201:
202:            /**
203:             * Manually trigger a re-filtering of the rows of this table. If the
204:             * filtering predicate concerns only items within this table, calling
205:             * this method should be unnecessary. It is only when the filtering
206:             * predicate references data outside of this table that a manual
207:             * re-filtering request may be necessary. For example, filtering
208:             * valid edges of a graph from a pool of candidate edges will depend
209:             * on the available nodes.
210:             * @see prefuse.data.util.ValidEdgePredicate
211:             */
212:            public void filterRows() {
213:                if (m_parent == null)
214:                    return;
215:
216:                CascadedRowManager rowman = (CascadedRowManager) m_rows;
217:                IntIterator crows = m_rows.rows();
218:                while (crows.hasNext()) {
219:                    int crow = crows.nextInt();
220:                    if (!m_rowFilter.getBoolean(m_parent.getTuple(rowman
221:                            .getParentRow(crow)))) {
222:                        removeCascadedRow(crow);
223:                    }
224:                }
225:
226:                Iterator ptuples = m_parent.tuples(m_rowFilter);
227:                while (ptuples.hasNext()) {
228:                    Tuple pt = (Tuple) ptuples.next();
229:                    int prow = pt.getRow();
230:                    if (rowman.getChildRow(prow) == -1)
231:                        addCascadedRow(prow);
232:                }
233:            }
234:
235:            /**
236:             * Get the ColumnProjection determining which columns of the
237:             * parent table are included in this one.
238:             * @return the ColumnProjection of this CascadedTable
239:             */
240:            public ColumnProjection getColumnProjection() {
241:                return m_colFilter;
242:            }
243:
244:            /**
245:             * Sets the ColumnProjection determining which columns of the
246:             * parent table are included in this one.
247:             * @param colFilter a ColumnProjection determining which columns of the
248:             * parent table to include in this one.
249:             */
250:            public void setColumnProjection(ColumnProjection colFilter) {
251:                if (m_colFilter != null) {
252:                    m_colFilter.removeProjectionListener(m_listener);
253:                }
254:                m_colFilter = colFilter == null ? new AcceptAllColumnProjection()
255:                        : colFilter;
256:                m_colFilter.addProjectionListener(m_listener);
257:                filterColumns();
258:            }
259:
260:            /**
261:             * Gets ths Predicate determining which rows of the parent
262:             * table are included in this one.
263:             * @return the row filtering Predicate of this CascadedTable
264:             */
265:            public Predicate getRowFilter() {
266:                return m_rowFilter;
267:            }
268:
269:            /**
270:             * Sets the Predicate determining which rows of the parent
271:             * table are included in this one.
272:             * @param rowFilter a Predicate determining which rows of the parent
273:             * table to include in this one.
274:             */
275:            public void setRowFilter(Predicate rowFilter) {
276:                if (m_rowFilter != null) {
277:                    m_rowFilter.removeExpressionListener(m_listener);
278:                }
279:                m_rowFilter = rowFilter == null ? BooleanLiteral.TRUE
280:                        : rowFilter;
281:                if (m_rowFilter != BooleanLiteral.TRUE)
282:                    m_rowFilter.addExpressionListener(m_listener);
283:                filterRows();
284:            }
285:
286:            // ------------------------------------------------------------------------
287:            // Table Metadata
288:
289:            /**
290:             * @see prefuse.data.Table#getColumnCount()
291:             */
292:            public int getColumnCount() {
293:                return m_columns.size() + m_pnames.size();
294:            }
295:
296:            /**
297:             * Get the number of columns explicitly stored by this table (i.e., all
298:             * columns that are not inherited from the parent table).
299:             * @return the number of locally stored columns
300:             */
301:            public int getLocalColumnCount() {
302:                return m_columns.size();
303:            }
304:
305:            // ------------------------------------------------------------------------
306:            // Parent Table Methods
307:
308:            /**
309:             * Get the parent table from which this cascaded table inherits values.
310:             * @return the parent table
311:             */
312:            public Table getParentTable() {
313:                return m_parent;
314:            }
315:
316:            /**
317:             * Given a row in this table, return the corresponding row in the parent
318:             * table.
319:             * @param row a row in this table
320:             * @return the corresponding row in the parent table
321:             */
322:            public int getParentRow(int row) {
323:                return ((CascadedRowManager) m_rows).getParentRow(row);
324:            }
325:
326:            /**
327:             * Given a row in the parent table, return the corresponding row, if any,
328:             * in this table.
329:             * @param prow a row in the parent table
330:             * @return the corresponding row in this table, or -1 if the given parent
331:             * row is not inherited by this table
332:             */
333:            public int getChildRow(int prow) {
334:                return ((CascadedRowManager) m_rows).getChildRow(prow);
335:            }
336:
337:            // ------------------------------------------------------------------------
338:            // Row Operations
339:
340:            /**
341:             * @see prefuse.data.Table#addRow()
342:             */
343:            public int addRow() {
344:                if (m_parent != null) {
345:                    throw new IllegalStateException(
346:                            "Add row not supported for CascadedTable.");
347:                } else {
348:                    return super .addRow();
349:                }
350:            }
351:
352:            /**
353:             * @see prefuse.data.Table#addRows(int)
354:             */
355:            public void addRows(int nrows) {
356:                if (m_parent != null) {
357:                    throw new IllegalStateException(
358:                            "Add rows not supported for CascadedTable.");
359:                } else {
360:                    super .addRows(nrows);
361:                }
362:            }
363:
364:            /**
365:             * @see prefuse.data.Table#removeRow(int)
366:             */
367:            public boolean removeRow(int row) {
368:                if (m_parent != null) {
369:                    throw new IllegalStateException(
370:                            "Remove row not supported for CascadedTable.");
371:                } else {
372:                    return super .removeRow(row);
373:                }
374:            }
375:
376:            /**
377:             * Internal method for adding a new cascaded row backed by
378:             * the given parent row.
379:             * @param prow the parent row to inherit
380:             * @return the row number ofr the newly added row in this table
381:             */
382:            protected int addCascadedRow(int prow) {
383:                int r = m_rows.addRow();
384:                ((CascadedRowManager) m_rows).put(r, prow);
385:                updateRowCount();
386:
387:                fireTableEvent(r, r, TableModelEvent.ALL_COLUMNS,
388:                        TableModelEvent.INSERT);
389:                return r;
390:            }
391:
392:            /**
393:             * Internal method for removing a cascaded row from this table.
394:             * @param row the row to remove
395:             * @return true if the row was successfully removed, false otherwise
396:             */
397:            protected boolean removeCascadedRow(int row) {
398:                boolean rv = super .removeRow(row);
399:                if (rv)
400:                    ((CascadedRowManager) m_rows).remove(row);
401:                return rv;
402:            }
403:
404:            // ------------------------------------------------------------------------
405:            // Column Operations
406:
407:            /**
408:             * @see prefuse.data.Table#getColumnName(int)
409:             */
410:            public String getColumnName(int col) {
411:                int local = m_names.size();
412:                if (col >= local) {
413:                    return (String) m_pnames.get(col - local);
414:                } else {
415:                    return (String) m_names.get(col);
416:                }
417:            }
418:
419:            /**
420:             * @see prefuse.data.Table#getColumnNumber(prefuse.data.column.Column)
421:             */
422:            public int getColumnNumber(Column col) {
423:                int idx = m_columns.indexOf(col);
424:                if (idx == -1 && m_parent != null) {
425:                    idx = m_parent.getColumnNumber(col);
426:                    if (idx == -1)
427:                        return idx;
428:                    String name = m_parent.getColumnName(idx);
429:                    idx = m_pnames.indexOf(name);
430:                    if (idx != -1)
431:                        idx += m_columns.size();
432:                }
433:                return idx;
434:            }
435:
436:            /**
437:             * @see prefuse.data.Table#getColumn(int)
438:             */
439:            public Column getColumn(int col) {
440:                m_lastCol = col;
441:                int local = m_names.size();
442:                if (col >= local && m_parent != null) {
443:                    return m_parent.getColumn((String) m_pnames
444:                            .get(col - local));
445:                } else {
446:                    return (Column) m_columns.get(col);
447:                }
448:            }
449:
450:            /**
451:             * @see prefuse.data.Table#hasColumn(java.lang.String)
452:             */
453:            protected boolean hasColumn(String name) {
454:                int idx = getColumnNumber(name);
455:                return idx >= 0 && idx < getLocalColumnCount();
456:            }
457:
458:            /**
459:             * @see prefuse.data.Table#getColumnNames()
460:             */
461:            protected Iterator getColumnNames() {
462:                if (m_parent == null) {
463:                    return m_names.iterator();
464:                } else {
465:                    return new CompositeIterator(m_names.iterator(), m_pnames
466:                            .iterator());
467:                }
468:            }
469:
470:            /**
471:             * Invalidates this table's cached schema. This method should be called
472:             * whenever columns are added or removed from this table.
473:             */
474:            protected void invalidateSchema() {
475:                super .invalidateSchema();
476:                this .filterColumns();
477:            }
478:
479:            // ------------------------------------------------------------------------
480:            // Listener Methods
481:
482:            /**
483:             * Internal listener class handling updates from the backing parent table,
484:             * the column projection, or the row selection predicate.
485:             */
486:            private class Listener implements  TableListener,
487:                    ProjectionListener, ExpressionListener {
488:                public void tableChanged(Table t, int start, int end, int col,
489:                        int type) {
490:                    // must come from parent
491:                    if (t != m_parent)
492:                        return;
493:
494:                    CascadedRowManager rowman = (CascadedRowManager) m_rows;
495:
496:                    // switch on the event type
497:                    switch (type) {
498:                    case EventConstants.UPDATE: {
499:                        // do nothing if update on all columns, as this is only
500:                        // used to indicate a non-measurable update.
501:                        if (col == EventConstants.ALL_COLUMNS) {
502:                            break;
503:                        }
504:
505:                        // process each update, check if filtered state changes
506:                        for (int r = start, cr = -1; r <= end; ++r) {
507:                            if ((cr = rowman.getChildRow(r)) != -1) {
508:                                // the parent row has a corresponding row in this table
509:                                if (m_rowFilter
510:                                        .getBoolean(m_parent.getTuple(r))) {
511:                                    // row still passes the filter, check the column
512:                                    int idx = getColumnNumber(m_parent
513:                                            .getColumnName(col));
514:                                    if (idx >= getLocalColumnCount())
515:                                        fireTableEvent(cr, cr, idx,
516:                                                EventConstants.UPDATE);
517:                                } else {
518:                                    // row no longer passes the filter, remove it
519:                                    removeCascadedRow(cr);
520:                                }
521:                            } else {
522:                                // does it now pass the filter due to the update?
523:                                if (m_rowFilter
524:                                        .getBoolean(m_parent.getTuple(r))) {
525:                                    if ((cr = rowman.getChildRow(r)) < 0)
526:                                        addCascadedRow(r);
527:                                }
528:                            }
529:                        }
530:                        break;
531:                    }
532:                    case EventConstants.DELETE: {
533:                        if (col == EventConstants.ALL_COLUMNS) {
534:                            // entire rows deleted
535:                            for (int r = start, cr = -1; r <= end; ++r) {
536:                                if ((cr = rowman.getChildRow(r)) != -1)
537:                                    removeCascadedRow(cr);
538:                            }
539:                        } else {
540:                            // column deleted
541:                            filterColumns();
542:                        }
543:                        break;
544:                    }
545:                    case EventConstants.INSERT:
546:                        if (col == EventConstants.ALL_COLUMNS) {
547:                            // entire rows added
548:                            for (int r = start; r <= end; ++r) {
549:                                if (m_rowFilter
550:                                        .getBoolean(m_parent.getTuple(r))) {
551:                                    if (rowman.getChildRow(r) < 0)
552:                                        addCascadedRow(r);
553:                                }
554:                            }
555:                        } else {
556:                            // column added
557:                            filterColumns();
558:                        }
559:                        break;
560:                    }
561:                }
562:
563:                public void projectionChanged(ColumnProjection projection) {
564:                    if (projection == m_colFilter)
565:                        filterColumns();
566:                }
567:
568:                public void expressionChanged(Expression expr) {
569:                    if (expr == m_rowFilter)
570:                        filterRows();
571:                }
572:            }
573:
574:        } // end of class CascadedTable
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.