Source Code Cross Referenced for Parser.java in  » Database-ORM » JPOX » org » jpox » store » query » 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 ORM » JPOX » org.jpox.store.query 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**********************************************************************
002:        Copyright (c) 2002 Kelly Grizzle (TJDO) and others. All rights reserved. 
003:        Licensed under the Apache License, Version 2.0 (the "License");
004:        you may not use this file except in compliance with the License.
005:        You may obtain a copy of the License at
006:
007:            http://www.apache.org/licenses/LICENSE-2.0
008:
009:        Unless required by applicable law or agreed to in writing, software
010:        distributed under the License is distributed on an "AS IS" BASIS,
011:        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012:        See the License for the specific language governing permissions and
013:        limitations under the License. 
014:         
015:
016:        Contributors:
017:        2003 Andy Jefferson - coding standards
018:        2005 Andy Jefferson - added support for single quoted StringLiteral 
019:                              (including contrib from Tony Lai)
020:            ...
021:         **********************************************************************/package org.jpox.store.query;
022:
023:        import java.math.BigDecimal;
024:        import java.math.BigInteger;
025:        import java.text.CharacterIterator;
026:        import java.text.StringCharacterIterator;
027:
028:        import org.jpox.ClassLoaderResolver;
029:        import org.jpox.exceptions.ClassNotResolvedException;
030:        import org.jpox.exceptions.JPOXUserException;
031:        import org.jpox.util.Imports;
032:        import org.jpox.util.Localiser;
033:
034:        /**
035:         * Parser for a Query. The query can be JDOQL, or JPQL.
036:         * Allows a class to work its way through the parsed string, obtaining relevant
037:         * components with each call, or peeking ahead before deciding what component
038:         * to parse next.
039:         *
040:         * @version $Revision: 1.18 $
041:         **/
042:        public class Parser {
043:            /** Localiser for messages. */
044:            protected static final Localiser LOCALISER = Localiser
045:                    .getInstance("org.jpox.store.Localisation");
046:
047:            protected final String input;
048:            protected final Imports imports;
049:            protected final CharacterIterator ci;
050:
051:            /**
052:             * Constructor
053:             * @param input The input string
054:             * @param imports Necessary imports to use in the parse.
055:             **/
056:            public Parser(String input, Imports imports) {
057:                this .input = input;
058:                this .imports = imports;
059:
060:                ci = new StringCharacterIterator(input);
061:            }
062:
063:            /**
064:             * Accessor for the input string.
065:             * @return The input string.
066:             */
067:            public String getInput() {
068:                return input;
069:            }
070:
071:            /**
072:             * Accessor for the current index in the input string.
073:             * @return The current index.
074:             */
075:            public int getIndex() {
076:                return ci.getIndex();
077:            }
078:
079:            /**
080:             * Skip over any whitespace from the current position.
081:             * @return The new position
082:             */
083:            public int skipWS() {
084:                int startIdx = ci.getIndex();
085:                char c = ci.current();
086:
087:                while (Character.isWhitespace(c) || c == '\t' || c == '\f'
088:                        || c == '\n' || c == '\r' || c == '\u0009'
089:                        || c == '\u000c' || c == '\u0020' || c == '\11'
090:                        || c == '\12' || c == '\14' || c == '\15' || c == '\40') {
091:                    c = ci.next();
092:                }
093:
094:                return startIdx;
095:            }
096:
097:            /**
098:             * Check if END OF TEXT is reach
099:             * @return true if END OF TEXT is reach
100:             */
101:            public boolean parseEOS() {
102:                skipWS();
103:
104:                return ci.current() == CharacterIterator.DONE;
105:            }
106:
107:            /**
108:             * Check if char <code>c</code> is found
109:             * @param c the Character to find
110:             * @return true if <code>c</code> is found
111:             */
112:            public boolean parseChar(char c) {
113:                skipWS();
114:
115:                if (ci.current() == c) {
116:                    ci.next();
117:                    return true;
118:                } else {
119:                    return false;
120:                }
121:            }
122:
123:            /**
124:             * Check if char <code>c</code> is found
125:             * @param c the Character to find
126:             * @param unlessFollowedBy the character to validate it does not follow <code>c</code>
127:             * @return true if <code>c</code> is found and not followed by <code>unlessFollowedBy</code>
128:             */
129:            public boolean parseChar(char c, char unlessFollowedBy) {
130:                int savedIdx = skipWS();
131:
132:                if (ci.current() == c && ci.next() != unlessFollowedBy) {
133:                    return true;
134:                } else {
135:                    ci.setIndex(savedIdx);
136:                    return false;
137:                }
138:            }
139:
140:            /**
141:             * Check if String <code>s</code> is found
142:             * @param s the String to find
143:             * @return true if <code>s</code> is found
144:             */
145:            public boolean parseString(String s) {
146:                int savedIdx = skipWS();
147:
148:                int len = s.length();
149:                char c = ci.current();
150:
151:                for (int i = 0; i < len; ++i) {
152:                    if (c != s.charAt(i)) {
153:                        ci.setIndex(savedIdx);
154:                        return false;
155:                    }
156:
157:                    c = ci.next();
158:                }
159:
160:                return true;
161:            }
162:
163:            /**
164:             * Check if String <code>s</code> is found ignoring the case
165:             * @param s the String to find
166:             * @return true if <code>s</code> is found
167:             */
168:            public boolean parseStringIgnoreCase(String s) {
169:                String lowerCasedString = s.toLowerCase();
170:
171:                int savedIdx = skipWS();
172:
173:                int len = lowerCasedString.length();
174:                char c = ci.current();
175:
176:                for (int i = 0; i < len; ++i) {
177:                    if (Character.toLowerCase(c) != lowerCasedString.charAt(i)) {
178:                        ci.setIndex(savedIdx);
179:                        return false;
180:                    }
181:
182:                    c = ci.next();
183:                }
184:
185:                return true;
186:            }
187:
188:            /**
189:             * Check if String "s" is found ignoring the case, and not moving the cursor position.
190:             * @param s the String to find
191:             * @return true if string is found
192:             */
193:            public boolean peekStringIgnoreCase(String s) {
194:                String lowerCasedString = s.toLowerCase();
195:
196:                int savedIdx = skipWS();
197:
198:                int len = lowerCasedString.length();
199:                char c = ci.current();
200:
201:                for (int i = 0; i < len; ++i) {
202:                    if (Character.toLowerCase(c) != lowerCasedString.charAt(i)) {
203:                        ci.setIndex(savedIdx);
204:                        return false;
205:                    }
206:                    c = ci.next();
207:                }
208:                ci.setIndex(savedIdx);
209:
210:                return true;
211:            }
212:
213:            /**
214:             * Parse a java identifier from the current position.
215:             * @return The identifier
216:             */
217:            public String parseIdentifier() {
218:                skipWS();
219:                char c = ci.current();
220:
221:                if (!Character.isJavaIdentifierStart(c) && !(c == ':')) {
222:                    // Current character is not a valid identifier char, and isn't a
223:                    // valid JDOQL parameter start character
224:                    return null;
225:                }
226:
227:                StringBuffer id = new StringBuffer();
228:                id.append(c);
229:                while (Character.isJavaIdentifierPart(c = ci.next())) {
230:                    id.append(c);
231:                }
232:
233:                return id.toString();
234:            }
235:
236:            /**
237:             * Checks if a java Method is found
238:             * @return true if a Method is found
239:             */
240:            public String parseMethod() {
241:                int savedIdx = ci.getIndex();
242:
243:                String id;
244:
245:                if ((id = parseIdentifier()) == null) {
246:                    ci.setIndex(savedIdx);
247:                    return null;
248:                }
249:
250:                skipWS();
251:
252:                if (!parseChar('(')) {
253:                    ci.setIndex(savedIdx);
254:                    return null;
255:                }
256:                ci.setIndex(ci.getIndex() - 1);
257:                return id;
258:            }
259:
260:            /**
261:             * Parses the text string (up to the next space) and
262:             * returns it. The name includes '.' characters.
263:             * This can be used, for example, when parsing a class name wanting to
264:             * read in the full name (including package) so that it can then be
265:             * checked for existence in the CLASSPATH.
266:             * @return The name
267:             */
268:            public String parseName() {
269:                int savedIdx = skipWS();
270:                String id;
271:
272:                if ((id = parseIdentifier()) == null) {
273:                    return null;
274:                }
275:
276:                StringBuffer qn = new StringBuffer(id);
277:
278:                while (parseChar('.')) {
279:                    if ((id = parseIdentifier()) == null) {
280:                        ci.setIndex(savedIdx);
281:                        return null;
282:                    }
283:
284:                    qn.append('.').append(id);
285:                }
286:
287:                return qn.toString();
288:            }
289:
290:            /**
291:             * Parse a cast in the query from the current position, returning
292:             * the class that is being cast to. Returns null if the current position
293:             * doesnt have a cast.
294:             * @param clr The ClassLoaderResolver
295:             * @param primary The primary class loader to use (if any)
296:             * @return The class to cast to
297:             */
298:            public Class parseCast(ClassLoaderResolver clr, ClassLoader primary) {
299:                int savedIdx = skipWS();
300:                String typeName;
301:
302:                if (!parseChar('(') || (typeName = parseName()) == null
303:                        || !parseChar(')')) {
304:                    ci.setIndex(savedIdx);
305:                    return null;
306:                }
307:
308:                try {
309:                    return imports.resolveClassDeclaration(typeName, clr,
310:                            primary);
311:                } catch (ClassNotResolvedException e) {
312:                    ci.setIndex(savedIdx);
313:                    throw new JPOXUserException(LOCALISER.msg("021053",
314:                            typeName));
315:                }
316:            }
317:
318:            /**
319:             * Utility to return if a character is a decimal digit.
320:             * @param c The character
321:             * @return Whether it is a decimal digit
322:             */
323:            private final static boolean isDecDigit(char c) {
324:                return c >= '0' && c <= '9';
325:            }
326:
327:            /**
328:             * Utility to return if a character is a octal digit.
329:             * @param c The character
330:             * @return Whether it is a octal digit
331:             */
332:            private final static boolean isOctDigit(char c) {
333:                return c >= '0' && c <= '7';
334:            }
335:
336:            /**
337:             * Utility to return if a character is a hexadecimal digit.
338:             * @param c The character
339:             * @return Whether it is a hexadecimal digit
340:             */
341:            private final static boolean isHexDigit(char c) {
342:                return c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A'
343:                        && c <= 'F';
344:            }
345:
346:            /**
347:             * Parse an integer number from the current position.
348:             * @return The integer number parsed (null if not valid).
349:             */
350:            public BigInteger parseIntegerLiteral() {
351:                int savedIdx = skipWS();
352:
353:                StringBuffer digits = new StringBuffer();
354:                int radix;
355:                char c = ci.current();
356:
357:                if (c == '0') {
358:                    c = ci.next();
359:
360:                    if (c == 'x' || c == 'X') {
361:                        radix = 16;
362:                        c = ci.next();
363:
364:                        while (isHexDigit(c)) {
365:                            digits.append(c);
366:                            c = ci.next();
367:                        }
368:                    } else if (isOctDigit(c)) {
369:                        radix = 8;
370:
371:                        do {
372:                            digits.append(c);
373:                            c = ci.next();
374:                        } while (isOctDigit(c));
375:                    } else {
376:                        radix = 10;
377:                        digits.append('0');
378:                    }
379:                } else {
380:                    radix = 10;
381:
382:                    while (isDecDigit(c)) {
383:                        digits.append(c);
384:                        c = ci.next();
385:                    }
386:                }
387:
388:                if (digits.length() == 0) {
389:                    ci.setIndex(savedIdx);
390:                    return null;
391:                }
392:
393:                if (c == 'l' || c == 'L') {
394:                    ci.next();
395:                }
396:
397:                return new BigInteger(digits.toString(), radix);
398:            }
399:
400:            /**
401:             * Parse a floating point number from the current position.
402:             * @return The floating point number parsed (null if not valid).
403:             */
404:            public BigDecimal parseFloatingPointLiteral() {
405:                int savedIdx = skipWS();
406:                StringBuffer val = new StringBuffer();
407:                boolean dotSeen = false;
408:                boolean expSeen = false;
409:                boolean sfxSeen = false;
410:
411:                char c = ci.current();
412:
413:                while (isDecDigit(c)) {
414:                    val.append(c);
415:                    c = ci.next();
416:                }
417:
418:                if (c == '.') {
419:                    dotSeen = true;
420:                    val.append(c);
421:                    c = ci.next();
422:
423:                    while (isDecDigit(c)) {
424:                        val.append(c);
425:                        c = ci.next();
426:                    }
427:                }
428:
429:                if (val.length() < (dotSeen ? 2 : 1)) {
430:                    ci.setIndex(savedIdx);
431:                    return null;
432:                }
433:
434:                if (c == 'e' || c == 'E') {
435:                    expSeen = true;
436:                    val.append(c);
437:                    c = ci.next();
438:
439:                    if (c != '+' && c != '-' && !isDecDigit(c)) {
440:                        ci.setIndex(savedIdx);
441:                        return null;
442:                    }
443:
444:                    do {
445:                        val.append(c);
446:                        c = ci.next();
447:                    } while (isDecDigit(c));
448:                }
449:
450:                if (c == 'f' || c == 'F' || c == 'd' || c == 'D') {
451:                    sfxSeen = true;
452:                    ci.next();
453:                }
454:
455:                if (!dotSeen && !expSeen && !sfxSeen) {
456:                    ci.setIndex(savedIdx);
457:                    return null;
458:                }
459:
460:                return new BigDecimal(val.toString());
461:            }
462:
463:            /**
464:             * Parse a boolean from the current position.
465:             * @return The boolean parsed (null if not valid).
466:             */
467:            public Boolean parseBooleanLiteral() {
468:                int savedIdx = skipWS();
469:                String id;
470:
471:                if ((id = parseIdentifier()) == null) {
472:                    return null;
473:                }
474:
475:                if (id.equals("true")) {
476:                    return Boolean.TRUE;
477:                } else if (id.equals("false")) {
478:                    return Boolean.FALSE;
479:                } else {
480:                    ci.setIndex(savedIdx);
481:                    return null;
482:                }
483:            }
484:
485:            /**
486:             * Utility to return if the next non-whitespace character is a single quote.
487:             * @return Whether it is a single quote at the current point (ignoring whitespace)
488:             */
489:            public boolean nextIsSingleQuote() {
490:                skipWS();
491:                return (ci.current() == '\'');
492:            }
493:
494:            /**
495:             * Utility to return if the next character is a dot.
496:             * @return Whether it is a dot at the current point
497:             */
498:            public boolean nextIsDot() {
499:                return (ci.current() == '.');
500:            }
501:
502:            /**
503:             * Parse a Character literal.
504:             * @return the Character parsed. null if single quotes is found
505:             * @throws JPOXUserException if an invalid character is found or the CharacterIterator is finished
506:             */
507:            public Character parseCharacterLiteral() {
508:                skipWS();
509:
510:                if (ci.current() != '\'') {
511:                    return null;
512:                }
513:
514:                char c = ci.next();
515:
516:                if (c == CharacterIterator.DONE) {
517:                    throw new JPOXUserException("Invalid character literal: "
518:                            + input);
519:                }
520:
521:                if (c == '\\') {
522:                    // Why are we doing this exactly ? If the string is "\\_" then this should be "\_" but doing this
523:                    // we get an Exception thrown for invalid escape expression. See JPQLParser for correct version IMHO
524:                    c = parseEscapedCharacter();
525:                }
526:
527:                if (ci.next() != '\'') {
528:                    throw new JPOXUserException("Invalid character literal: "
529:                            + input);
530:                }
531:
532:                ci.next();
533:
534:                return new Character(c);
535:            }
536:
537:            /**
538:             * Parse a String literal.
539:             * @return the String parsed. null if single quotes or double quotes is found
540:             * @throws JPOXUserException if an invalid character is found or the CharacterIterator is finished
541:             */
542:            public String parseStringLiteral() {
543:                skipWS();
544:
545:                // Strings can be surrounded by single or double quotes
546:                char quote = ci.current();
547:                if (quote != '"' && quote != '\'') {
548:                    return null;
549:                }
550:
551:                StringBuffer lit = new StringBuffer();
552:                char c;
553:
554:                while ((c = ci.next()) != quote) {
555:                    if (c == CharacterIterator.DONE) {
556:                        throw new JPOXUserException("Invalid string literal: "
557:                                + input);
558:                    }
559:
560:                    if (c == '\\') {
561:                        // Why are we doing this exactly ? If the string is "\\_" then this should be "\_" but doing this
562:                        // we get an Exception thrown for invalid escape expression. See JPQLParser for correct version IMHO
563:                        c = parseEscapedCharacter();
564:                    }
565:
566:                    lit.append(c);
567:                }
568:
569:                ci.next();
570:
571:                return lit.toString();
572:            }
573:
574:            /**
575:             * Parse a escaped character.
576:             * @return the escaped char
577:             * @throws JPOXUserException if a escaped character is not valid
578:             */
579:            protected char parseEscapedCharacter() {
580:                char c;
581:
582:                if (isOctDigit(c = ci.next())) {
583:                    int i = (c - '0');
584:
585:                    if (isOctDigit(c = ci.next())) {
586:                        i = i * 8 + (c - '0');
587:
588:                        if (isOctDigit(c = ci.next())) {
589:                            i = i * 8 + (c - '0');
590:                        } else {
591:                            ci.previous();
592:                        }
593:                    } else {
594:                        ci.previous();
595:                    }
596:
597:                    if (i > 0xff) {
598:                        throw new JPOXUserException(
599:                                "Invalid character escape: '\\"
600:                                        + Integer.toOctalString(i) + "'");
601:                    }
602:
603:                    return (char) i;
604:                } else {
605:                    switch (c) {
606:                    case 'b':
607:                        return '\b';
608:                    case 't':
609:                        return '\t';
610:                    case 'n':
611:                        return '\n';
612:                    case 'f':
613:                        return '\f';
614:                    case 'r':
615:                        return '\r';
616:                    case '"':
617:                        return '"';
618:                    case '\'':
619:                        return '\'';
620:                    case '\\':
621:                        return '\\';
622:                    default:
623:                        throw new JPOXUserException(
624:                                "Invalid character escape: '\\" + c + "'");
625:                    }
626:                }
627:            }
628:
629:            /**
630:             * Checks if null literal is parsed
631:             * @return true if null literal is found
632:             */
633:            public boolean parseNullLiteral() {
634:                int savedIdx = skipWS();
635:                String id;
636:
637:                if ((id = parseIdentifier()) == null) {
638:                    return false;
639:                } else if (id.equals("null")) {
640:                    return true;
641:                } else {
642:                    ci.setIndex(savedIdx);
643:                    return false;
644:                }
645:            }
646:
647:            public String remaining() {
648:                StringBuffer sb = new StringBuffer();
649:                char c = ci.current();
650:                while (c != CharacterIterator.DONE) {
651:                    sb.append(c);
652:                    c = ci.next();
653:                }
654:                return sb.toString();
655:            }
656:
657:            public String toString() {
658:                return input;
659:            }
660:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.