Source Code Cross Referenced for FxStatement.java in  » J2EE » fleXive » com » flexive » sqlParser » 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 » J2EE » fleXive » com.flexive.sqlParser 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /***************************************************************
002:         *  This file is part of the [fleXive](R) project.
003:         *
004:         *  Copyright (c) 1999-2008
005:         *  UCS - unique computing solutions gmbh (http://www.ucs.at)
006:         *  All rights reserved
007:         *
008:         *  The [fleXive](R) project is free software; you can redistribute
009:         *  it and/or modify it under the terms of the GNU General Public
010:         *  License as published by the Free Software Foundation;
011:         *  either version 2 of the License, or (at your option) any
012:         *  later version.
013:         *
014:         *  The GNU General Public License can be found at
015:         *  http://www.gnu.org/copyleft/gpl.html.
016:         *  A copy is found in the textfile GPL.txt and important notices to the
017:         *  license from the author are found in LICENSE.txt distributed with
018:         *  these libraries.
019:         *
020:         *  This library is distributed in the hope that it will be useful,
021:         *  but WITHOUT ANY WARRANTY; without even the implied warranty of
022:         *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
023:         *  GNU General Public License for more details.
024:         *
025:         *  For further information about UCS - unique computing solutions gmbh,
026:         *  please see the company website: http://www.ucs.at
027:         *
028:         *  For further information about [fleXive](R), please see the
029:         *  project website: http://www.flexive.org
030:         *
031:         *
032:         *  This copyright notice MUST APPEAR in all copies of the file!
033:         ***************************************************************/package com.flexive.sqlParser;
034:
035:        import com.flexive.shared.exceptions.FxSqlSearchException;
036:        import com.flexive.shared.search.query.VersionFilter;
037:
038:        import java.io.ByteArrayInputStream;
039:        import java.util.ArrayList;
040:        import java.util.HashMap;
041:        import java.util.List;
042:
043:        import org.apache.commons.lang.StringUtils;
044:        import org.apache.commons.logging.Log;
045:        import org.apache.commons.logging.LogFactory;
046:
047:        /**
048:         * Statement.
049:         *
050:         * @author Gregor Schober (gregor.schober@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
051:         */
052:        public class FxStatement {
053:            private static final Log LOG = LogFactory.getLog(FxStatement.class);
054:
055:            public static enum Type {
056:                /** the statement filter the data */
057:                FILTER,
058:                /** the statement will always return a empty resultset */
059:                EMPTY,
060:                /** The statement will always return the whole data from the DB */
061:                ALL
062:            }
063:
064:            private HashMap<String, Table> tables;
065:            private Brace currentBrace;
066:            private Brace rootBrace;
067:            private HashMap<Filter.TYPE, Filter> filters;
068:            private boolean bDebug = false;
069:            private int iBraceElementIdGenerator = 1;
070:            private Type type = Type.FILTER;
071:            private ArrayList<SelectedValue> selected;
072:            private ArrayList<OrderByValue> order;
073:            private int parserExecutionTime = -1;
074:            private int maxResultRows = -1;
075:            private String cacheKey;
076:            private boolean distinct;
077:            private boolean ignoreCase = true;
078:            private VersionFilter versionFilter = null;
079:            private long[] briefcaseFilter = null;
080:            private String contentType;
081:
082:            protected void setBriefcaseFilter(long[] bf) {
083:                briefcaseFilter = bf;
084:            }
085:
086:            /**
087:             * Returns a empty array if the filter is not set, or the id's of all briefcases to search in.
088:             *
089:             * @return a empty array if the filter is not set, or the id's of all briefcases to search in.
090:             */
091:            public long[] getBriefcaseFilter() {
092:                return briefcaseFilter == null ? new long[0] : briefcaseFilter;
093:            }
094:
095:            public boolean hasVersionFilter() {
096:                return versionFilter != null;
097:            }
098:
099:            public VersionFilter getVersionFilter() {
100:                return versionFilter == null ? VersionFilter.MAX
101:                        : versionFilter;
102:            }
103:
104:            public void setVersionFilter(VersionFilter filter) {
105:                this .versionFilter = filter;
106:            }
107:
108:            public boolean getIgnoreCase() {
109:                return ignoreCase;
110:            }
111:
112:            protected void setIgnoreCase(boolean ignoreCase) {
113:                this .ignoreCase = ignoreCase;
114:            }
115:
116:            /**
117:             * Gets the maximum rows returned by the search.
118:             *
119:             * @return the maximum rows returned by the search
120:             */
121:            public int getMaxResultRows() {
122:                return maxResultRows == -1 ? 2000 : maxResultRows; // TODO
123:            }
124:
125:            /**
126:             * Sets the maximum rows returned by the search.
127:             *
128:             * @param maxResultRows the maximum rows returned by the search
129:             */
130:            protected void setMaxResultRows(int maxResultRows) {
131:                this .maxResultRows = maxResultRows;
132:            }
133:
134:            /**
135:             * Sets the contentname to filter by, may be null to indicate that the filter is not set
136:             *
137:             * @param contentName the content name
138:             */
139:            protected void setContentTypeFilter(String contentName) {
140:                this .contentType = contentName.trim().length() == 0 ? null
141:                        : contentName.trim().toUpperCase();
142:            }
143:
144:            /**
145:             * Returns the contentname to filter by, or null if this filter option is not set.
146:             *
147:             * @return the contentname or null
148:             */
149:            public String getContentTypeFilter() {
150:                return contentType;
151:            }
152:
153:            /**
154:             * Returns true if the content type filter is set.
155:             *
156:             * @return true if the content type filter is set
157:             */
158:            public boolean hasContentTypeFilter() {
159:                return contentType != null;
160:            }
161:
162:            /**
163:             * Generates a new statement scope unique brace id.
164:             *
165:             * @return a new brace id
166:             */
167:            protected int getNewBraceElementId() {
168:                return iBraceElementIdGenerator++;
169:            }
170:
171:            /**
172:             * Add a Value to the selected elements.
173:             *
174:             * @param vi    the element
175:             * @param alias the alias
176:             */
177:            protected void addSelectedValue(final Value vi, String alias) {
178:                if (alias == null) {
179:                    if (vi instanceof  Property) {
180:                        final Property property = (Property) vi;
181:                        alias = property.getValue()
182:                                + (StringUtils.isNotBlank(property.getField()) ? "."
183:                                        + property.getField()
184:                                        : "");
185:                    } else {
186:                        alias = (vi.getValue() instanceof  String) ? (String) vi
187:                                .getValue() : String.valueOf(vi.getValue());
188:                    }
189:                }
190:                selected.add(new SelectedValue(vi, alias));
191:            }
192:
193:            /**
194:             * Returns the selected values in the correct order.
195:             *
196:             * @return the selected values
197:             */
198:            public List<SelectedValue> getSelectedValues() {
199:                return selected;
200:            }
201:
202:            /**
203:             * Returns the selected value matching the given alias, or null if no match can be found.
204:             * <p/>
205:             * If a alias is used more than one time the first match will be returned.
206:             *
207:             * @param alias the alias to look for
208:             * @return the matching selected value, or null
209:             */
210:            public SelectedValue getSelectedValueByAlias(String alias) {
211:                for (SelectedValue sv : selected) {
212:                    if (sv.getAlias().equalsIgnoreCase(alias))
213:                        return sv;
214:                }
215:                return null;
216:            }
217:
218:            /**
219:             * Overrides the selected values in the given order.
220:             *
221:             * @param values the new list
222:             */
223:            public void setSelectedValues(ArrayList<SelectedValue> values) {
224:                this .selected = values;
225:            }
226:
227:            /**
228:             * Adds a new order by condition.
229:             *
230:             * @param vi the order by value (column)
231:             * @throws com.flexive.sqlParser.SqlParserException
232:             *          if the column cannot be used for ordering because it is not selected
233:             */
234:            public void addOrderByValue(final OrderByValue vi)
235:                    throws SqlParserException {
236:                computeOrderByColumn(vi);
237:                order.add(0, vi);
238:            }
239:
240:            /**
241:             * Returns the sort order elements.
242:             *
243:             * @return the sort order values
244:             */
245:            public List<OrderByValue> getOrderByValues() {
246:                return order;
247:            }
248:
249:            /**
250:             * Returns a table used by the statement by its alias.
251:             *
252:             * @param alias the alias to look for
253:             * @return a table used by the statement by its alias
254:             */
255:            public Table getTableByAlias(String alias) {
256:                return this .tables.get(alias.toUpperCase());
257:            }
258:
259:            public Table getTableByType(Table.TYPE type) {
260:                for (Table tbl : getTables()) {
261:                    if (tbl.getType() == type)
262:                        return tbl;
263:                }
264:                return null;
265:            }
266:
267:            /**
268:             * Returns all tables that were specified in the 'from' section of the statement.
269:             *
270:             * @return all tables
271:             */
272:            public Table[] getTables() {
273:                Table[] result = new Table[tables.size()];
274:                int pos = 0;
275:                for (String key : this .tables.keySet()) {
276:                    result[pos++] = this .tables.get(key);
277:                }
278:                return result;
279:            }
280:
281:            /**
282:             * Returns the root brace.
283:             * <p/>
284:             * The root brace will be null if the getType is TYPE.ALL or TYPE.EMPTY
285:             *
286:             * @return the root brace
287:             */
288:            public Brace getRootBrace() {
289:                return this .rootBrace;
290:            }
291:
292:            /**
293:             * Returns the statements type.
294:             * <p/>
295:             * TYPE.FILTER: there are conditions<br>
296:             * TYPE.EMPTY: the statement will not deliver any results<br>
297:             * TYPE.ALL: the statements will deliver all data from the selected sources (no filter set)
298:             *
299:             * @return the statements type
300:             */
301:            public Type getType() {
302:                return this .type;
303:            }
304:
305:            /**
306:             * Parses a statement.
307:             *
308:             * @param query the query to process
309:             * @return the statement
310:             * @throws SqlParserException ifthe function fails
311:             */
312:            public static FxStatement parseSql(String query)
313:                    throws SqlParserException {
314:                try {
315:                    long startTime = System.currentTimeMillis();
316:                    query = cleanupQueryString(query);
317:                    ByteArrayInputStream byis = new ByteArrayInputStream(query
318:                            .getBytes("UTF-8"));
319:                    FxStatement stmt = new SQL(byis, "UTF-8").statement();
320:                    byis.close();
321:                    stmt.setParserExecutionTime((int) (System
322:                            .currentTimeMillis() - startTime));
323:                    return stmt;
324:                } catch (TokenMgrError exc) {
325:                    throw new SqlParserException(exc, query);
326:                } catch (ParseException exc) {
327:                    throw new SqlParserException(exc, query);
328:                } catch (SqlParserException exc) {
329:                    throw exc;
330:                } catch (Exception exc) {
331:                    throw new SqlParserException(exc.getMessage());
332:                }
333:            }
334:
335:            protected void setParserExecutionTime(int ms) {
336:                this .parserExecutionTime = ms;
337:            }
338:
339:            /**
340:             * Returns the execution time needed by the parser in ms.
341:             *
342:             * @return the execution time needed by the parser in ms
343:             */
344:            public int getParserExecutionTime() {
345:                return this .parserExecutionTime;
346:            }
347:
348:            // Protected section
349:            protected FxStatement() {
350:                this .rootBrace = new Brace(this );
351:                this .currentBrace = this .rootBrace;
352:                this .tables = new HashMap<String, Table>(10);
353:                this .filters = new HashMap<Filter.TYPE, Filter>(5);
354:                this .selected = new ArrayList<SelectedValue>(50);
355:                this .order = new ArrayList<OrderByValue>(5);
356:            }
357:
358:            protected void addFilter(Filter f) {
359:                this .filters.put(f.getType(), f);
360:            }
361:
362:            /**
363:             * Returns the desired filter, or null if the filter was not specified and has no
364:             * default value.
365:             *
366:             * @param t the filter to get
367:             * @return the filter
368:             */
369:            public Filter getFilter(Filter.TYPE t) {
370:                return filters.get(t);
371:            }
372:
373:            protected void addTable(Table table) {
374:                if (bDebug)
375:                    System.out.println("Adding table: " + table);
376:                this .tables.put(table.getAlias(), table);
377:            }
378:
379:            protected Brace getCurrentBrace() {
380:                return this .currentBrace;
381:            }
382:
383:            protected Brace startSubBrace() throws SqlParserException {
384:                Brace br = new Brace(this );
385:                currentBrace.addElement(br);
386:                currentBrace = br;
387:                return currentBrace;
388:            }
389:
390:            protected Brace endSubBrace() throws SqlParserException {
391:                Brace parent = currentBrace.getParent();
392:                if (currentBrace.size() == 1) {
393:                    // Brace with only one element, remove it and move its element to the parent
394:                    BraceElement ele = currentBrace.removeLastElement();
395:                    parent.removeElement(currentBrace);
396:                    parent.addElement(ele);
397:                }
398:                currentBrace = parent;
399:                return currentBrace;
400:            }
401:
402:            /**
403:             * Removes empty braces and handles conditions that are always false or true.
404:             * Also checks if all aliases are defined.
405:             *
406:             * @throws SqlParserException if the function fails
407:             */
408:            protected void cleanup() throws SqlParserException {
409:
410:                // Check if all referenced tables are present
411:                for (SelectedValue val : selected) {
412:                    if (!(val.getValue() instanceof  Property))
413:                        continue;
414:                    Property prop = (Property) val.getValue();
415:                    if (this .getTableByAlias(prop.getTableAlias()) == null) {
416:                        String stables = "";
417:                        for (String alias : tables.keySet()) {
418:                            stables += ((stables.length() > 0) ? "," : "")
419:                                    + alias;
420:                        }
421:                        throw new SqlParserException(
422:                                "ex.sqlSearch.filter.unknownTableAlias", prop
423:                                        .getTableAlias(), stables);
424:                    }
425:                }
426:
427:                // Check order by
428:                for (OrderByValue ov : getOrderByValues()) {
429:                    computeOrderByColumn(ov);
430:                }
431:
432:                // If no where clause is set at all
433:                if (this .rootBrace == null || this .rootBrace.size() == 0) {
434:                    rootBrace = null;
435:                    type = Type.ALL;
436:                    return;
437:                }
438:
439:                // Cleanup where clause
440:                cleanup(this .rootBrace);
441:
442:                if (rootBrace != null) {
443:                    // Nothing left and TYPE=FILTER has to be set to TYPE.EMPTY
444:                    if (this .rootBrace.size() == 0
445:                            && this .getType() == Type.FILTER) {
446:                        this .type = Type.EMPTY;
447:                        this .rootBrace = null;
448:                    }
449:                    // Only one condition at top level: type has to be null and not 'or'/'and'
450:                    else if (this .rootBrace.size() == 1) {
451:                        this .rootBrace.setType(null);
452:                    }
453:                }
454:            }
455:
456:            private void computeOrderByColumn(OrderByValue ov)
457:                    throws SqlParserException {
458:                if (StringUtils.isNumeric(ov.getValue())) {
459:                    // column selected by index (1-based)
460:                    final int index = Integer.valueOf(ov.getValue()) - 1;
461:                    if (index >= 0 && selected.size() > index) {
462:                        ov.setSelectedValue(selected.get(index), index);
463:                    } else {
464:                        throw new SqlParserException(
465:                                "ex.sqlSearch.invalidOrderByIndex", ov
466:                                        .getValue(), selected.size());
467:                    }
468:                } else {
469:                    // column selected by alias
470:                    boolean found = false;
471:                    int pos = 0;
472:                    for (SelectedValue sv : selected) {
473:                        if (sv.getAlias().equalsIgnoreCase(ov.getValue())) {
474:                            found = true;
475:                            ov.setSelectedValue(sv, pos);
476:                            break;
477:                        }
478:                        pos++;
479:                    }
480:                    if (!found) {
481:                        throw new SqlParserException(
482:                                "ex.sqlSearch.invalidOrderByValue", ov
483:                                        .getValue());
484:                    }
485:                }
486:            }
487:
488:            /**
489:             * Compute a cache key for the statement.
490:             * <p/>
491:             * Statements with the same cache key will produce the same resultset.
492:             *
493:             * @return the cacheKey.
494:             * @throws SqlParserException if the cache key could not be computed
495:             */
496:            protected String getCacheKey() throws SqlParserException {
497:                try {
498:                    // Only build once
499:                    if (cacheKey != null) {
500:                        return cacheKey;
501:                    }
502:
503:                    StringBuffer key = new StringBuffer(512);
504:
505:                    if (type == Type.FILTER) {
506:                        computeCacheKey(key, this .rootBrace);
507:                    } else {
508:                        key.append(type);
509:                    }
510:
511:                    for (String table : this .tables.keySet()) {
512:                        Table t = this .tables.get(table);
513:                        Filter vf = t.getFilter(Filter.TYPE.VERSION);
514:                        String langs = "";
515:                        for (String lang : t.getSearchLanguages()) {
516:                            langs += "|" + lang;
517:                        }
518:                        key.append("_").append(t.getAlias()).append(";")
519:                                .append(t.getType()).append(";").append(langs)
520:                                .append(";").append(
521:                                        vf == null ? "null" : vf.getValue());
522:                    }
523:                    key.append("_").append("_").append(this .getMaxResultRows())
524:                            .append("_").append(this .isDistinct() ? "D" : "A");
525:
526:                    cacheKey = key.toString();
527:                    return cacheKey;
528:                } catch (Throwable t) {
529:                    System.err.println(t.getMessage());
530:                    t.printStackTrace();
531:                    throw new SqlParserException(
532:                            "ex.sqlSearch.unbableToBuildCachekey", t);
533:                }
534:            }
535:
536:            /**
537:             * Sets the distinct condition of the statement.
538:             *
539:             * @param value the condition
540:             */
541:            protected void setDistinct(boolean value) {
542:                this .distinct = value;
543:            }
544:
545:            /**
546:             * Returns if the statements resultset is distinct.
547:             *
548:             * @return true if the statements resultset is distinct
549:             */
550:            public boolean isDistinct() {
551:                return this .distinct;
552:            }
553:
554:            /**
555:             * Helper function for computeCacheKey (recursion).
556:             *
557:             * @param sb the string buffer to write to
558:             * @param br the current brace
559:             */
560:            private void computeCacheKey(StringBuffer sb, Brace br) {
561:                String brType = (br.getType() == null ? "N" : (br.getType()
562:                        .equalsIgnoreCase("and") ? "A" : "O"));
563:                sb.append("(").append(brType);
564:                for (BraceElement be : br.getElements()) {
565:                    if (be instanceof  Condition) {
566:                        sb.append((" " + be.toString()));
567:                    } else {
568:                        computeCacheKey(sb, (Brace) be);
569:                    }
570:                }
571:                sb.append(")");
572:            }
573:
574:            private void removeWholeBrace(Brace br, boolean alwaysTrue) {
575:                try {
576:                    if (bDebug)
577:                        System.out
578:                                .println("Removing whole brace because of always "
579:                                        + alwaysTrue + " cond");
580:                } catch (Exception exc) {
581:                    System.err.println("###Y" + exc.getMessage());
582:                }
583:
584:                if (br.getParent() == null) {
585:                    br.removeAllElements();
586:                    rootBrace = null;
587:                    type = alwaysTrue ? Type.ALL : Type.EMPTY;
588:                } else {
589:                    Brace parent = br.getParent();
590:                    try {
591:                        Condition cd = new Condition(this , new Constant("1"),
592:                                Condition.Comparator.EQUAL, new Constant(
593:                                        alwaysTrue ? "1" : "0"));
594:                        parent.addElement(cd);
595:                    } catch (Exception exc) {
596:                        System.err.println("###Y" + exc.getMessage());
597:                    }
598:                    parent.removeElement(br);
599:                }
600:            }
601:
602:            /**
603:             * Perform an cleanup on the statement.
604:             *
605:             * @param br the brace to work on
606:             * @throws SqlParserException if the function fails
607:             */
608:            private void cleanup(Brace br) throws SqlParserException {
609:
610:                // Move down the brace tree (recursive) ..
611:                for (BraceElement be : br.getElements()) {
612:                    if (be instanceof  Brace) {
613:                        cleanup((Brace) be);
614:                    }
615:                }
616:
617:                // ... now start cleanup from bottom up
618:                if (br.isOr()) {
619:                    for (BraceElement be : br.getElements()) {
620:                        if (!(be instanceof  Condition))
621:                            continue;
622:                        Condition cond = (Condition) be;
623:                        if (cond.isAlwaysTrue()) {
624:                            // Whole brace will be true, remove it and terminate loop
625:                            removeWholeBrace(br, true);
626:                            break;
627:                        }
628:                        if (cond.isAlwaysFalse()) {
629:                            // Condition always false, so remove it
630:                            br.removeElement(cond);
631:                        }
632:                    }
633:                    // If the whole OR is empty we need to add an ALWAYS false to the parent
634:                    if (br.size() == 0 && br.getParent() != null) {
635:                        removeWholeBrace(br, false);
636:                    }
637:
638:                } else if (br.isAnd()) {
639:                    for (BraceElement be : br.getElements()) {
640:                        if (!(be instanceof  Condition))
641:                            continue;
642:                        Condition cond = (Condition) be;
643:                        if (cond.isAlwaysTrue()) {
644:                            // Condition always true, so remove it
645:                            br.removeElement(cond);
646:                        }
647:                        if (cond.isAlwaysFalse()) {
648:                            // Whole brace will be false, remove it and terminate loop
649:                            removeWholeBrace(br, false);
650:                            break;
651:                        }
652:                    }
653:                    // If the whole AND is empty we need to add an ALWAYS true to the parent
654:                    if (br.size() == 0 && br.getParent() != null) {
655:                        removeWholeBrace(br, true);
656:                    }
657:                } else if (br.getSize() > 0) {
658:                    // Just one single condition is set, examine it!
659:                    BraceElement be = br.getElementAt(0);
660:                    if (be instanceof  Condition) {
661:                        Condition cond = (Condition) be;
662:                        if (cond.isAlwaysTrue()) {
663:                            // Everything is selected!
664:                            br.removeAllElements();
665:                            this .rootBrace = null;
666:                            this .type = Type.ALL;
667:                        } else if (cond.isAlwaysFalse()) {
668:                            // No result at all!
669:                            br.removeAllElements();
670:                            this .rootBrace = null;
671:                            this .type = Type.EMPTY;
672:                        }
673:                    }
674:                }
675:
676:                // Cleanup empty braces, and braces that contain just one element
677:                if (br.size() == 1) {
678:                    Brace parent = br.getParent();
679:                    if (parent != null) {
680:                        BraceElement be = br.removeLastElement();
681:                        if (bDebug)
682:                            System.out
683:                                    .println("Moving element to parent since its the only one left in the brace: "
684:                                            + be);
685:                        parent.removeElement(br);
686:                        parent.addElement(be);
687:                    } else {
688:                        // Only one brace in root brace -> make it the root brace
689:                        if (br.getElementAt(0) instanceof  Brace) {
690:                            rootBrace = (Brace) br.removeLastElement();
691:                        }
692:                    }
693:                } else if (br.size() == 0 && br.getParent() != null) {
694:                    if (bDebug)
695:                        System.out.println("Removing empty brace: " + br);
696:                    br.getParent().removeElement(br);
697:                }
698:            }
699:
700:            /**
701:             * Generates a debug string.
702:             *
703:             * @return a debug string of the statement
704:             * @throws com.flexive.shared.exceptions.FxSqlSearchException
705:             *          if the function failed
706:             */
707:            public String printDebug() throws FxSqlSearchException {
708:                try {
709:                    StringBuffer result = new StringBuffer(1024);
710:                    if (this .rootBrace == null) {
711:                        return String.valueOf(this .getType());
712:                    } else {
713:                        printDebug(result, this .rootBrace);
714:                        result = result.deleteCharAt(0);
715:                    }
716:                    result
717:                            .append(("\n##################################################\n"));
718:                    int pos = 0;
719:                    for (SelectedValue v : getSelectedValues()) {
720:                        result.append(("Selected[" + (pos++) + "]: "
721:                                + v.toString() + "\n"));
722:                    }
723:
724:                    pos = 0;
725:                    result.append("Order by: ");
726:                    for (Value v : getOrderByValues()) {
727:                        if ((pos++) > 0)
728:                            result.append(",");
729:                        result.append(v.toString());
730:                    }
731:                    if (pos == 0) {
732:                        result.append(("Order: n/a\n"));
733:                    }
734:                    result.append("\n");
735:
736:                    result.append("Search Languages: ");
737:                    pos = 0;
738:                    for (String v : getTableByType(Table.TYPE.CONTENT)
739:                            .getSearchLanguages()) {
740:                        if ((pos++) > 0)
741:                            result.append(",");
742:                        result.append(v);
743:                    }
744:                    result.append("\n");
745:                    result.append("Cache Key: ");
746:                    try {
747:                        result.append(getCacheKey());
748:                    } catch (Throwable t) {
749:                        result.append(t.getMessage());
750:                    }
751:                    result.append("\n");
752:                    result.append(("Parser execution time: "
753:                            + this .getParserExecutionTime() + " ms\n"));
754:                    return result.toString();
755:                } catch (Throwable t) {
756:                    throw new FxSqlSearchException(LOG, t,
757:                            "ex.sqlSearch.printDebugFailed");
758:                }
759:            }
760:
761:            /**
762:             * Generates a debug string for the statement.
763:             *
764:             * @param sb the StringBuffer to write to
765:             * @param br the current bracer (recursion)
766:             */
767:            protected void printDebug(StringBuffer sb, Brace br) {
768:                String sPrefix = "\n";
769:                for (int i = 0; i < br.getLevel(); i++) {
770:                    sPrefix += "+";
771:                }
772:                sPrefix += (br.getType() == null ? "N" : (br.getType()
773:                        .equalsIgnoreCase("and") ? "A" : "O"))
774:                        + "  ";
775:                sb.append((sPrefix + "("));
776:                boolean hadSubs = false;
777:                for (BraceElement be : br.getElements()) {
778:                    if (be instanceof  Condition) {
779:                        sb.append((" " + be.toString() + " "));
780:                    } else {
781:                        printDebug(sb, (Brace) be);
782:                        hadSubs = true;
783:                    }
784:                }
785:                if (hadSubs) {
786:                    sb.append((sPrefix + ")"));
787:                } else {
788:                    sb.append(" )");
789:                }
790:            }
791:
792:            // Private section
793:
794:            /**
795:             * Cleanup the query string.
796:             * <p/>
797:             * This function removes comments from the query.
798:             *
799:             * @param query the query to cleanup
800:             * @return the processed query string
801:             * @throws SqlParserException ifthe function fails
802:             */
803:            private static String cleanupQueryString(String query)
804:                    throws SqlParserException {
805:                // Make sure the statement has the EOF charater at the end, also add one
806:                // '\n' to ensure that the last line comment ("--") is closed
807:                query = query.trim();
808:                query += "\n";
809:                if (query.charAt(query.length() - 1) != ';')
810:                    query += ";";
811:                return query;
812:            }
813:
814:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.