Source Code Cross Referenced for Expression.java in  » Report » datavision-1.1.0 » jimm » datavision » 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 » Report » datavision 1.1.0 » jimm.datavision 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package jimm.datavision;
002:
003:        import jimm.datavision.field.Field;
004:        import jimm.util.XMLWriter;
005:        import jimm.util.StringUtils;
006:        import jimm.util.Replacer;
007:        import jimm.datavision.source.Column;
008:        import jimm.util.I18N;
009:        import java.util.*;
010:
011:        /**
012:         * The abstract superclass of objects that are evaluated, such as formulas
013:         * and user columns. An expression contains text that is evaluated. The
014:         * text may contain database column values, formulas, special values,
015:         * or other types of objects.
016:         * <p>
017:         * Before being evaluated, the following substitutions are made withing
018:         * the evaluation string:
019:         * <ul>
020:         * <li>{<i>table_name.column_name</i>} is replaced by the current value
021:         * of the column <i>table_name.column_name</i>.</li>
022:         * <li>{&#64;<i>id_number</i>} is replaced by the results of evaluating the
023:         * formula whose id is <i>id_number</i>.</li>
024:         * <li> {%<i>special_value_name</i>} is replaced by a special value
025:         * (report title, report run date, page number, or record number).</li>
026:         * <li> {?<i>id_number</i>} is replaced by a parameter value (string,
027:         * number, or date).</li>
028:         * <li> {!<i>id_number</i>} is replaced by a user column's value (string,
029:         * number, or date).</li>
030:         * <ul>
031:         *
032:         * @author Jim Menard, <a href="mailto:jimm@io.com">jimm@io.com</a>
033:         */
034:        public abstract class Expression extends Observable implements 
035:                Identity, Nameable, Writeable, Draggable, Observer {
036:
037:            protected Long id;
038:            protected Report report;
039:            protected String name;
040:            protected String expr;
041:            protected String exceptAfter;
042:            protected ArrayList observedContents;
043:
044:            /**
045:             * Given a string, returns a string with all instances of formula,
046:             * parameter, and user column "formula strings" replaced by "display name"
047:             * strings. If there are no such strings, the original string is returned.
048:             *
049:             * @return a string with all formula strings replaced by display name
050:             * strings
051:             */
052:            public static String expressionToDisplay(Report report, String str) {
053:                if (str == null || str.length() == 0 || str.indexOf("{") == -1)
054:                    return str;
055:
056:                StringBuffer buf = new StringBuffer();
057:                int len = str.length();
058:                for (int i = 0; i < len; ++i) {
059:                    char c = str.charAt(i);
060:                    if (c == '{' && (i + 1) < len) {
061:                        int nameStart, nameEnd;
062:                        switch (str.charAt(i + 1)) {
063:                        case '@': // Formula
064:                            nameStart = i + 2;
065:                            nameEnd = str.indexOf("}", nameStart);
066:                            if (nameEnd != -1) {
067:                                String idAsString = str.substring(nameStart,
068:                                        nameEnd);
069:                                buf.append("{@");
070:                                buf.append(report.findFormula(idAsString)
071:                                        .getName());
072:                                buf.append("}");
073:                                i = nameEnd;
074:                            }
075:                            break;
076:                        case '?': // Parameter
077:                            nameStart = i + 2;
078:                            nameEnd = str.indexOf("}", nameStart);
079:                            if (nameEnd != -1) {
080:                                String idAsString = str.substring(nameStart,
081:                                        nameEnd);
082:                                buf.append("{?");
083:                                buf.append(report.findParameter(idAsString)
084:                                        .getName());
085:                                buf.append("}");
086:                                i = nameEnd;
087:                            }
088:                            break;
089:                        case '!': // User column
090:                            nameStart = i + 2;
091:                            nameEnd = str.indexOf("}", nameStart);
092:                            if (nameEnd != -1) {
093:                                String idAsString = str.substring(nameStart,
094:                                        nameEnd);
095:                                buf.append("{!");
096:                                buf.append(report.findUserColumn(idAsString)
097:                                        .getName());
098:                                buf.append("}");
099:                                i = nameEnd;
100:                            }
101:                            break;
102:                        default:
103:                            buf.append(c);
104:                            break;
105:                        }
106:                    } else {
107:                        buf.append(c);
108:                    }
109:                }
110:                return buf.toString();
111:            }
112:
113:            /**
114:             * Given a string, returns a string with all instances of formula,
115:             * parameter, and user column "display names" replaced by "formula
116:             * strings". If there are no such strings, the original string is returned.
117:             *
118:             * @param report a report
119:             * @param str a string with display names
120:             * @return a string with all display names replaced by formula strings
121:             */
122:            public static String displayToExpression(Report report, String str) {
123:                if (str == null || str.length() == 0 || str.indexOf("{") == -1)
124:                    return str;
125:
126:                StringBuffer buf = new StringBuffer();
127:                int len = str.length();
128:                for (int i = 0; i < len; ++i) {
129:                    char c = str.charAt(i);
130:                    if (c == '{' && (i + 1) < len) {
131:                        int nameStart, nameEnd;
132:                        switch (str.charAt(i + 1)) {
133:                        case '@': // Formula
134:                            nameStart = i + 2;
135:                            nameEnd = str.indexOf("}", nameStart);
136:                            if (nameEnd != -1) {
137:                                String formulaName = str.substring(nameStart,
138:                                        nameEnd);
139:                                buf.append("{@");
140:                                Formula formula = report
141:                                        .findFormulaByName(formulaName);
142:                                if (formula == null) {
143:                                    str = I18N.get("Utils.in") + " \"" + str
144:                                            + "\": "
145:                                            + I18N.get("Utils.no_such_formula")
146:                                            + ' ' + formulaName;
147:                                    throw new IllegalArgumentException(str);
148:                                }
149:                                buf.append(formula.getId());
150:                                buf.append("}");
151:                                i = nameEnd;
152:                            }
153:                            break;
154:                        case '?': // Parameter
155:                            nameStart = i + 2;
156:                            nameEnd = str.indexOf("}", nameStart);
157:                            if (nameEnd != -1) {
158:                                String paramName = str.substring(nameStart,
159:                                        nameEnd);
160:                                buf.append("{?");
161:                                Parameter param = report
162:                                        .findParameterByName(paramName);
163:                                if (param == null) {
164:                                    str = I18N.get("Utils.in") + " \"" + str
165:                                            + "\": "
166:                                            + I18N.get("Utils.no_such_param")
167:                                            + ' ' + paramName;
168:                                    throw new IllegalArgumentException(str);
169:                                }
170:                                buf.append(param.getId());
171:                                buf.append("}");
172:                                i = nameEnd;
173:                            }
174:                            break;
175:                        case '!': // User column
176:                            nameStart = i + 2;
177:                            nameEnd = str.indexOf("}", nameStart);
178:                            if (nameEnd != -1) {
179:                                String ucName = str.substring(nameStart,
180:                                        nameEnd);
181:                                buf.append("{!");
182:                                UserColumn uc = report
183:                                        .findUserColumnByName(ucName);
184:                                if (uc == null) {
185:                                    str = I18N.get("Utils.in") + " \"" + str
186:                                            + "\": "
187:                                            + I18N.get("Utils.no_such_usercol")
188:                                            + ' ' + ucName;
189:                                    throw new IllegalArgumentException(str);
190:                                }
191:                                buf.append(uc.getId());
192:                                buf.append("}");
193:                                i = nameEnd;
194:                            }
195:                            break;
196:                        default:
197:                            buf.append(c);
198:                            break;
199:                        }
200:                    } else {
201:                        buf.append(c);
202:                    }
203:                }
204:
205:                return buf.toString();
206:            }
207:
208:            /**
209:             * Constructor. If <i>id</i> is <code>null</code>, throws an
210:             * <code>IllegalArgumentException</code>. This is because subclasses are
211:             * responsible for generating their id number. For example, formulas call
212:             * <code>Report.generateNewFormulaId</code>.
213:             *
214:             * @param id the unique identifier for the new expression; may not be
215:             * <code>null</code>
216:             * @param report the report containing this expression
217:             * @param name the expression name
218:             * @param expression the string to evaulate at runtime; may be
219:             * <code>null</code>
220:             * @param exceptAfter when looking for things inside "{}" braces, ignore
221:             * braces immediately after this string
222:             */
223:            protected Expression(Long id, Report report, String name,
224:                    String expression, String exceptAfter) {
225:                if (id == null) // Need not use I18N; this is a programmer err
226:                    throw new IllegalArgumentException(
227:                            "Subclasses of Expression must"
228:                                    + " not pass in a null id");
229:
230:                this .report = report;
231:                this .id = id;
232:                this .name = name;
233:                expr = expression;
234:                this .exceptAfter = exceptAfter;
235:
236:                // I'd like to start observing the contents of the eval string here,
237:                // but the other expressions may not yet be defined (for example, when
238:                // reading in expressions from an XML file). That's why we start observing
239:                // contents when someone asks for the eval string.
240:                observedContents = null;
241:            }
242:
243:            protected void finalize() throws Throwable {
244:                stopObservingContents();
245:                super .finalize();
246:            }
247:
248:            public void update(Observable o, Object arg) {
249:                setChanged();
250:                notifyObservers(arg);
251:            }
252:
253:            public Object getId() {
254:                return id;
255:            }
256:
257:            /**
258:             * Returns the name for this expression.
259:             *
260:             * @return the name
261:             */
262:            public String getName() {
263:                return name;
264:            }
265:
266:            /**
267:             * Sets the name.
268:             *
269:             * @param newName the new name
270:             */
271:            public void setName(String newName) {
272:                if (name != newName && (name == null || !name.equals(newName))) {
273:                    name = newName;
274:                    setChanged();
275:                    notifyObservers();
276:                }
277:            }
278:
279:            /**
280:             * Returns the expression string.
281:             *
282:             * @return the eval string
283:             */
284:            public String getExpression() {
285:                // I'd like to start observing the contents of the eval string as soon
286:                // as we are constructed, but the other expressions may not yet be defined
287:                // (for example, when reading in expressions from an XML file). That's why
288:                // we start observing contents when someone asks for the eval string.
289:                if (observedContents == null)
290:                    startObservingContents();
291:
292:                return expr;
293:            }
294:
295:            /**
296:             * Sets the eval string.
297:             *
298:             * @param newExpression the new eval string
299:             */
300:            public void setExpression(String newExpression) {
301:                if (expr != newExpression
302:                        && (expr == null || !expr.equals(newExpression))) {
303:                    stopObservingContents();
304:                    expr = newExpression;
305:
306:                    // Don't start observing contents yet. Wait until someone calls
307:                    // getExpression(). See the comment there.
308:                    //  	startObservingContents();
309:
310:                    setChanged();
311:                    notifyObservers();
312:                }
313:            }
314:
315:            /**
316:             * Starts observing all observables referenced by this expression: formulas,
317:             * parameters, and user columns.
318:             */
319:            protected void startObservingContents() {
320:                observedContents = new ArrayList(); // Even if expr is null
321:
322:                if (expr == null || expr.length() == 0)
323:                    return;
324:
325:                // Here, we are using replacers so we can start observing things.
326:                // Usually, they are used to replace strings.
327:
328:                // Formulas
329:                StringUtils.replaceDelimited(exceptAfter, "{@", "}",
330:                        new Replacer() {
331:                            public Object replace(String str) {
332:                                Formula f = report.findFormula(str);
333:                                observedContents.add(f);
334:                                f.addObserver(Expression.this );
335:                                return ""; // Avoid early bail-out
336:                            }
337:                        }, expr);
338:
339:                // Parameters
340:                StringUtils.replaceDelimited(exceptAfter, "{?", "}",
341:                        new Replacer() {
342:                            public Object replace(String str) {
343:                                Parameter p = report.findParameter(str);
344:                                observedContents.add(p);
345:                                p.addObserver(Expression.this );
346:                                return ""; // Avoid early bail-out
347:                            }
348:                        }, expr);
349:
350:                // User columns
351:                StringUtils.replaceDelimited(exceptAfter, "{!", "}",
352:                        new Replacer() {
353:                            public Object replace(String str) {
354:                                UserColumn uc = report.findUserColumn(str);
355:                                observedContents.add(uc);
356:                                uc.addObserver(Expression.this );
357:                                return ""; // Avoid early bail-out
358:                            }
359:                        }, expr);
360:            }
361:
362:            /**
363:             * Stops observing that which we were observing.
364:             */
365:            protected void stopObservingContents() {
366:                if (observedContents != null) {
367:                    for (Iterator iter = observedContents.iterator(); iter
368:                            .hasNext();)
369:                        ((Observable) iter.next()).deleteObserver(this );
370:                    observedContents = null;
371:                }
372:            }
373:
374:            /**
375:             * Returns the expression string fit for human consumption. This mainly means
376:             * that we substitute formula, parameter, and user column numbers with names.
377:             * Called from any expression editor. This code assumes that curly braces are
378:             * never nested.
379:             *
380:             * @return the eval string with formula, parameter, and user column id numbers
381:             * replaced with names
382:             */
383:            public String getEditableExpression() {
384:                return expressionToDisplay(report, getExpression());
385:            }
386:
387:            /**
388:             * Sets the eval string after replacing formula, parameter, and user column
389:             * names with their id numbers. Called from a editor.
390:             * <p>
391:             * This method will throw an <code>IllegalArgumentException</code> if any
392:             * formula, parameter, or user column name is not the name of some existing
393:             * object.
394:             *
395:             * @param newExpression the new eval string
396:             * @throws IllegalArgumentException
397:             */
398:            public void setEditableExpression(String newExpression) {
399:                setExpression(displayToExpression(report, newExpression));
400:            }
401:
402:            public abstract String dragString();
403:
404:            public abstract String designLabel();
405:
406:            public abstract String formulaString();
407:
408:            /**
409:             * Returns <code>true</code> if this expression contains a reference to the
410:             * specified field.
411:             *
412:             * @param f a field
413:             * @return <code>true</code> if this field contains a reference to the
414:             * specified field
415:             */
416:            public boolean refersTo(Field f) {
417:                String str = getExpression();
418:                if (str != null && str.length() > 0)
419:                    return str.indexOf(f.formulaString()) != -1;
420:                else
421:                    return false;
422:            }
423:
424:            /**
425:             * Returns <code>true</code> if this expression contains a reference to the
426:             * specified expression (formula or user column).
427:             *
428:             * @param expression an expression
429:             * @return <code>true</code> if this field is the same as or contains a
430:             * reference to the specified expression
431:             */
432:            public boolean refersTo(Expression expression) {
433:                String str = getExpression();
434:                if (str != null && str.length() > 0)
435:                    return str.indexOf(expression.formulaString()) != -1;
436:                else
437:                    return false;
438:            }
439:
440:            /**
441:             * Returns <code>true</code> if this expression contains a reference to the
442:             * specified parameter.
443:             *
444:             * @param p a parameter
445:             * @return <code>true</code> if this field contains a reference to the
446:             * specified parameter
447:             */
448:            public boolean refersTo(Parameter p) {
449:                String str = getExpression();
450:                if (str != null && str.length() > 0)
451:                    return str.indexOf(p.formulaString()) != -1;
452:                else
453:                    return false;
454:            }
455:
456:            /**
457:             * Returns a collection of the columns used in the expression. This is used
458:             * by the report's query when it is figuring out what columns and tables
459:             * are used by the report.
460:             *
461:             * @return a possibly empty collection of database columns
462:             * @see jimm.datavision.source.Query#findSelectablesUsed
463:             */
464:            public Collection columnsUsed() {
465:                final ArrayList list = new ArrayList();
466:
467:                // We are using a replacer passively, to look for curly-delimited
468:                // expressions. Nothing in the expression text gets modified.
469:                StringUtils.replaceDelimited(exceptAfter, "{", "}",
470:                        new Replacer() {
471:                            public Object replace(String str) {
472:                                switch (str.charAt(0)) {
473:                                case '!': // User column
474:                                    UserColumn uc = report.findUserColumn(str
475:                                            .substring(1));
476:                                    if (uc != null) // Should never be null
477:                                        list.addAll(uc.columnsUsed());
478:                                    break;
479:                                case '%': // Special field
480:                                case '@': // Formula
481:                                case '?': // Parameter
482:                                    break; // ...all are ignored
483:                                default:
484:                                    Column col = report.findColumn(str);
485:                                    if (col != null) // May be null if language uses braces
486:                                        list.add(col);
487:                                }
488:                                return ""; // So we don't quit early
489:                            }
490:                        }, getExpression());
491:
492:                return list;
493:            }
494:
495:            /**
496:             * Returns a collection of the user columns used in the expression. This
497:             * is used by the report's query when it is figuring out what columns,
498:             * tables, and user columns are used by the report.
499:             *
500:             * @return a possibly empty collection of user columns
501:             * @see jimm.datavision.source.Query#findSelectablesUsed
502:             */
503:            public Collection userColumnsUsed() {
504:                final ArrayList list = new ArrayList();
505:
506:                // We are using a replacer passively, to look for curly-delimited
507:                // expressions. Nothing in the expression text gets modified.
508:                StringUtils.replaceDelimited(exceptAfter, "{!", "}",
509:                        new Replacer() {
510:                            public Object replace(String str) {
511:                                UserColumn uc = report.findUserColumn(str);
512:                                if (uc != null) // Should never be null
513:                                    list.add(uc);
514:                                return ""; // So we don't bail out
515:                            }
516:                        }, getExpression());
517:
518:                return list;
519:            }
520:
521:            /**
522:             * Writes this expression as an XML tag.
523:             *
524:             * @param out a writer that knows how to write XML
525:             */
526:            public abstract void writeXML(XMLWriter out);
527:
528:            protected void writeXML(XMLWriter out, String elementName) {
529:                out.startElement(elementName);
530:                out.attr("id", id);
531:                out.attr("name", name);
532:                writeAdditionalAttributes(out);
533:                out.cdata(getExpression());
534:                out.endElement();
535:            }
536:
537:            /**
538:             * Writes additional attributes. Default behavior is to do nothing.
539:             *
540:             * @param out a writer that knows how to write XML
541:             */
542:            protected void writeAdditionalAttributes(XMLWriter out) {
543:            }
544:
545:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.