Source Code Cross Referenced for ExpressionColumn.java in  » Database-Client » prefuse » prefuse » data » column » 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.column 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package prefuse.data.column;
002:
003:        import java.util.BitSet;
004:        import java.util.Iterator;
005:        import java.util.Set;
006:
007:        import prefuse.data.DataTypeException;
008:        import prefuse.data.Table;
009:        import prefuse.data.event.ColumnListener;
010:        import prefuse.data.event.EventConstants;
011:        import prefuse.data.event.ExpressionListener;
012:        import prefuse.data.expression.Expression;
013:        import prefuse.data.expression.ExpressionAnalyzer;
014:
015:        /**
016:         * <p>Column instance that stores values provided by an Expression
017:         * instance. These expressions can reference other column values within the
018:         * same table. Values are evaluated when first requested and then cached to
019:         * increase performance. This column maintains listeners for all referenced
020:         * columns discovered in the expression and for the expression itself,
021:         * invalidating all cached entries when an update to either occurs.</p>
022:         * 
023:         * <p>
024:         * WARNING: Infinite recursion, eventually resulting in a StackOverflowError,
025:         * could occur if an expression refers to its own column, or if two
026:         * ExpressionColumns have expressions referring to each other. The 
027:         * responsibility for avoiding such situations is left with client programmers.
028:         * Note that it is fine for one ExpressionColumn to reference another;
029:         * however, the graph induced by such references must not contain any cycles.
030:         * </p>
031:         * 
032:         * @author <a href="http://jheer.org">jeffrey heer</a>
033:         * @see prefuse.data.expression
034:         */
035:        public class ExpressionColumn extends AbstractColumn {
036:
037:            private Expression m_expr;
038:            private Table m_table;
039:            private Set m_columns;
040:
041:            private BitSet m_valid;
042:            private Column m_cache;
043:            private Listener m_lstnr;
044:
045:            /**
046:             * Create a new ExpressionColumn.
047:             * @param table the table this column is a member of
048:             * @param expr the expression used to provide the column values
049:             */
050:            public ExpressionColumn(Table table, Expression expr) {
051:                super (expr.getType(table.getSchema()));
052:                m_table = table;
053:                m_expr = expr;
054:                m_lstnr = new Listener();
055:
056:                init();
057:
058:                int nrows = m_table.getRowCount();
059:                m_cache = ColumnFactory.getColumn(getColumnType(), nrows);
060:                m_valid = new BitSet(nrows);
061:                m_expr.addExpressionListener(m_lstnr);
062:            }
063:
064:            protected void init() {
065:                // first remove listeners on any current columns
066:                if (m_columns != null && m_columns.size() > 0) {
067:                    Iterator iter = m_columns.iterator();
068:                    while (iter.hasNext()) {
069:                        String field = (String) iter.next();
070:                        Column col = m_table.getColumn(field);
071:                        col.removeColumnListener(m_lstnr);
072:                    }
073:                }
074:                // now get the current set of columns
075:                m_columns = ExpressionAnalyzer.getReferencedColumns(m_expr);
076:
077:                // sanity check table and expression
078:                Iterator iter = m_columns.iterator();
079:                while (iter.hasNext()) {
080:                    String name = (String) iter.next();
081:                    if (m_table.getColumn(name) == null)
082:                        throw new IllegalArgumentException(
083:                                "Table must contain all "
084:                                        + "columns referenced by the expression."
085:                                        + " Bad column name: " + name);
086:
087:                }
088:
089:                // passed check, so now listen to columns
090:                iter = m_columns.iterator();
091:                while (iter.hasNext()) {
092:                    String field = (String) iter.next();
093:                    Column col = m_table.getColumn(field);
094:                    col.addColumnListener(m_lstnr);
095:                }
096:            }
097:
098:            // ------------------------------------------------------------------------
099:            // Column Metadata
100:
101:            /**
102:             * @see prefuse.data.column.Column#getRowCount()
103:             */
104:            public int getRowCount() {
105:                return m_cache.getRowCount();
106:            }
107:
108:            /**
109:             * @see prefuse.data.column.Column#setMaximumRow(int)
110:             */
111:            public void setMaximumRow(int nrows) {
112:                m_cache.setMaximumRow(nrows);
113:            }
114:
115:            // ------------------------------------------------------------------------
116:            // Cache Management
117:
118:            /**
119:             * Check if this ExpressionColumn has a valid cached value at the given
120:             * row.
121:             * @param row the row to check for a valid cache entry
122:             * @return true if the cache row is valid, false otherwise
123:             */
124:            public boolean isCacheValid(int row) {
125:                return m_valid.get(row);
126:            }
127:
128:            /**
129:             * Invalidate a range of the cache.
130:             * @param start the start of the range to invalidate
131:             * @param end the end of the range to invalidate, inclusive
132:             */
133:            public void invalidateCache(int start, int end) {
134:                m_valid.clear(start, end + 1);
135:            }
136:
137:            // ------------------------------------------------------------------------
138:            // Data Access Methods    
139:
140:            /**
141:             * Has no effect, as all values in this column are derived.
142:             * @param row the row to revert
143:             */
144:            public void revertToDefault(int row) {
145:                // do nothing, as we don't have default values.
146:            }
147:
148:            /**
149:             * @see prefuse.data.column.AbstractColumn#canSet(java.lang.Class)
150:             */
151:            public boolean canSet(Class type) {
152:                return false;
153:            }
154:
155:            /**
156:             * @see prefuse.data.column.Column#get(int)
157:             */
158:            public Object get(int row) {
159:                rangeCheck(row);
160:                if (isCacheValid(row)) {
161:                    return m_cache.get(row);
162:                }
163:                Object val = m_expr.get(m_table.getTuple(row));
164:                Class type = val == null ? Object.class : val.getClass();
165:                if (m_cache.canSet(type)) {
166:                    m_cache.set(val, row);
167:                    m_valid.set(row);
168:                }
169:                return val;
170:            }
171:
172:            /**
173:             * @see prefuse.data.column.Column#set(java.lang.Object, int)
174:             */
175:            public void set(Object val, int row) throws DataTypeException {
176:                throw new UnsupportedOperationException();
177:            }
178:
179:            private void rangeCheck(int row) {
180:                if (row < 0 || row >= getRowCount())
181:                    throw new IndexOutOfBoundsException();
182:            }
183:
184:            // ------------------------------------------------------------------------
185:
186:            /**
187:             * @see prefuse.data.column.Column#getBoolean(int)
188:             */
189:            public boolean getBoolean(int row) throws DataTypeException {
190:                if (!canGetBoolean())
191:                    throw new DataTypeException(boolean.class);
192:                rangeCheck(row);
193:
194:                if (isCacheValid(row)) {
195:                    return m_cache.getBoolean(row);
196:                } else {
197:                    boolean value = m_expr.getBoolean(m_table.getTuple(row));
198:                    m_cache.setBoolean(value, row);
199:                    m_valid.set(row);
200:                    return value;
201:                }
202:            }
203:
204:            private void computeNumber(int row) {
205:                if (m_columnType == int.class || m_columnType == byte.class) {
206:                    m_cache.setInt(m_expr.getInt(m_table.getTuple(row)), row);
207:                } else if (m_columnType == long.class) {
208:                    m_cache.setLong(m_expr.getLong(m_table.getTuple(row)), row);
209:                } else if (m_columnType == float.class) {
210:                    m_cache.setFloat(m_expr.getFloat(m_table.getTuple(row)),
211:                            row);
212:                } else {
213:                    m_cache.setDouble(m_expr.getDouble(m_table.getTuple(row)),
214:                            row);
215:                }
216:                m_valid.set(row);
217:            }
218:
219:            /**
220:             * @see prefuse.data.column.Column#getInt(int)
221:             */
222:            public int getInt(int row) throws DataTypeException {
223:                if (!canGetInt())
224:                    throw new DataTypeException(int.class);
225:                rangeCheck(row);
226:
227:                if (!isCacheValid(row))
228:                    computeNumber(row);
229:                return m_cache.getInt(row);
230:            }
231:
232:            /**
233:             * @see prefuse.data.column.Column#getDouble(int)
234:             */
235:            public double getDouble(int row) throws DataTypeException {
236:                if (!canGetDouble())
237:                    throw new DataTypeException(double.class);
238:                rangeCheck(row);
239:
240:                if (!isCacheValid(row))
241:                    computeNumber(row);
242:                return m_cache.getDouble(row);
243:            }
244:
245:            /**
246:             * @see prefuse.data.column.Column#getFloat(int)
247:             */
248:            public float getFloat(int row) throws DataTypeException {
249:                if (!canGetFloat())
250:                    throw new DataTypeException(float.class);
251:                rangeCheck(row);
252:
253:                if (!isCacheValid(row))
254:                    computeNumber(row);
255:                return m_cache.getFloat(row);
256:            }
257:
258:            /**
259:             * @see prefuse.data.column.Column#getLong(int)
260:             */
261:            public long getLong(int row) throws DataTypeException {
262:                if (!canGetLong())
263:                    throw new DataTypeException(long.class);
264:                rangeCheck(row);
265:
266:                if (!isCacheValid(row))
267:                    computeNumber(row);
268:                return m_cache.getLong(row);
269:            }
270:
271:            // ------------------------------------------------------------------------
272:            // Listener Methods
273:
274:            private class Listener implements  ColumnListener,
275:                    ExpressionListener {
276:
277:                public void columnChanged(int start, int end) {
278:                    // for a single index change with a valid cache value,
279:                    // propagate a change event with the previous value
280:                    if (start == end && isCacheValid(start)) {
281:                        if (!m_table.isValidRow(start))
282:                            return;
283:
284:                        // invalidate the cache index
285:                        invalidateCache(start, end);
286:                        // fire change event including previous value
287:                        Class type = getColumnType();
288:                        if (int.class == type) {
289:                            fireColumnEvent(start, m_cache.getInt(start));
290:                        } else if (long.class == type) {
291:                            fireColumnEvent(start, m_cache.getLong(start));
292:                        } else if (float.class == type) {
293:                            fireColumnEvent(start, m_cache.getFloat(start));
294:                        } else if (double.class == type) {
295:                            fireColumnEvent(start, m_cache.getDouble(start));
296:                        } else if (boolean.class == type) {
297:                            fireColumnEvent(start, m_cache.getBoolean(start));
298:                        } else {
299:                            fireColumnEvent(start, m_cache.get(start));
300:                        }
301:
302:                        // otherwise send a generic update
303:                    } else {
304:                        // invalidate cache indices
305:                        invalidateCache(start, end);
306:                        // fire change event
307:                        fireColumnEvent(EventConstants.UPDATE, start, end);
308:                    }
309:                }
310:
311:                public void columnChanged(Column src, int idx, boolean prev) {
312:                    columnChanged(idx, idx);
313:                }
314:
315:                public void columnChanged(Column src, int idx, double prev) {
316:                    columnChanged(idx, idx);
317:                }
318:
319:                public void columnChanged(Column src, int idx, float prev) {
320:                    columnChanged(idx, idx);
321:                }
322:
323:                public void columnChanged(Column src, int type, int start,
324:                        int end) {
325:                    columnChanged(start, end);
326:                }
327:
328:                public void columnChanged(Column src, int idx, int prev) {
329:                    columnChanged(idx, idx);
330:                }
331:
332:                public void columnChanged(Column src, int idx, long prev) {
333:                    columnChanged(idx, idx);
334:                }
335:
336:                public void columnChanged(Column src, int idx, Object prev) {
337:                    columnChanged(idx, idx);
338:                }
339:
340:                public void expressionChanged(Expression expr) {
341:                    // mark everything as changed
342:                    columnChanged(0, m_cache.getRowCount() - 1);
343:                    // re-initialize our setup
344:                    init();
345:                }
346:            }
347:
348:        } // end of class DerivedColumn
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.