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


001:        /**********************************************************************
002:        Copyright (c) 2006 Erik Bengtson 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:            ...
018:         **********************************************************************/package org.jpox.plugin;
019:
020:        import java.io.InputStreamReader;
021:        import java.math.BigInteger;
022:        import java.net.URL;
023:        import java.text.CharacterIterator;
024:        import java.text.StringCharacterIterator;
025:        import java.util.ArrayList;
026:        import java.util.Collections;
027:        import java.util.HashMap;
028:        import java.util.List;
029:        import java.util.Map;
030:        import java.util.StringTokenizer;
031:        import java.util.jar.Manifest;
032:
033:        import javax.xml.parsers.DocumentBuilder;
034:        import javax.xml.parsers.DocumentBuilderFactory;
035:        import javax.xml.parsers.ParserConfigurationException;
036:
037:        import org.jpox.ClassLoaderResolver;
038:        import org.jpox.exceptions.JPOXException;
039:        import org.jpox.exceptions.JPOXUserException;
040:        import org.jpox.util.JPOXLogger;
041:        import org.jpox.util.Localiser;
042:        import org.w3c.dom.Element;
043:        import org.w3c.dom.NamedNodeMap;
044:        import org.w3c.dom.Node;
045:        import org.w3c.dom.NodeList;
046:        import org.w3c.dom.Text;
047:        import org.xml.sax.InputSource;
048:
049:        /**
050:         * Parser for manifest.mf and plugin.xml files
051:         */
052:        class PluginParser {
053:            protected static final Localiser LOCALISER = Localiser
054:                    .getInstance("org.jpox.Localisation");
055:
056:            public static Bundle parseManifest(Manifest mf, URL fileUrl) {
057:                String symbolicName = getBundleSymbolicName(mf, null);
058:                String bundleVersion = getBundleVersion(mf, null);
059:                String bundleName = getBundleName(mf, null);
060:                String bundleVendor = getBundleVendor(mf, null);
061:                Bundle bundle = new Bundle(symbolicName, bundleName,
062:                        bundleVendor, bundleVersion, fileUrl);
063:                bundle.setRequireBundle(getRequireBundle(mf));
064:                return bundle;
065:            }
066:
067:            /**
068:             * Accessor for the Bundle-Name from the manifest.mf file
069:             * @param mf the manifest
070:             * @return the Set with BundleDescription
071:             */
072:            private static List getRequireBundle(Manifest mf) {
073:                String str = mf.getMainAttributes().getValue("Require-Bundle");
074:                if (str == null || str.length() < 1) {
075:                    return Collections.EMPTY_LIST;
076:                }
077:                Parser p = new Parser(str);
078:                List requiredBundle = new ArrayList();
079:                String bundleSymbolicName = p.parseSymbolicName();
080:                while (bundleSymbolicName != null) {
081:                    Bundle.BundleDescription bd = new Bundle.BundleDescription();
082:                    bd.setBundleSymbolicName(bundleSymbolicName);
083:                    bd.setParameters(p.parseParameters());
084:                    bundleSymbolicName = p.parseSymbolicName();
085:                    requiredBundle.add(bd);
086:                }
087:                return requiredBundle;
088:            }
089:
090:            /**
091:             * Method to parse ExtensionPoints from plug-in file
092:             * @param rootElement the root element of the plugin xml
093:             * @param plugin the plugin bundle
094:             * @param clr the ClassLoaderResolver
095:             * @return a List of extensionPoints, if any
096:             * @throws JPOXException if an error occurs during parsing
097:             */
098:            private static List parseExtensionPoints(Element rootElement,
099:                    Bundle plugin, ClassLoaderResolver clr) {
100:                List extensionPoints = new ArrayList();
101:                try {
102:                    NodeList elements = rootElement
103:                            .getElementsByTagName("extension-point");
104:                    for (int i = 0; i < elements.getLength(); i++) {
105:                        Element element = (Element) elements.item(i);
106:                        String id = element.getAttribute("id").trim();
107:                        String name = element.getAttribute("name");
108:                        String schema = element.getAttribute("schema");
109:                        extensionPoints.add(new ExtensionPoint(id, name, clr
110:                                .getResource(schema, null), plugin));
111:                    }
112:                } catch (JPOXException ex) {
113:                    throw ex;
114:                }
115:                return extensionPoints;
116:            }
117:
118:            /**
119:             * Method to parse Extensions from plug-in file
120:             * @param rootElement the root element of the plugin xml
121:             * @param plugin the plugin bundle
122:             * @param clr the ClassLoaderResolver
123:             * @return a List of extensions, if any
124:             * @throws JPOXException if an error occurs during parsing
125:             */
126:            private static List parseExtensions(Element rootElement,
127:                    Bundle plugin, ClassLoaderResolver clr) {
128:                List extensions = new ArrayList();
129:                try {
130:                    NodeList elements = rootElement
131:                            .getElementsByTagName("extension");
132:                    for (int i = 0; i < elements.getLength(); i++) {
133:                        Element element = (Element) elements.item(i);
134:                        Extension ex = new Extension(element
135:                                .getAttribute("point"), plugin);
136:                        NodeList elms = element.getChildNodes();
137:                        extensions.add(ex);
138:                        for (int e = 0; e < elms.getLength(); e++) {
139:                            if (elms.item(e) instanceof  Element) {
140:                                ex
141:                                        .addConfigurationElement(parseConfigurationElement(
142:                                                ex, (Element) elms.item(e),
143:                                                null));
144:                            }
145:                        }
146:                    }
147:                } catch (JPOXException ex) {
148:                    throw ex;
149:                }
150:                return extensions;
151:            }
152:
153:            /**
154:             * Accessor for the Bundle-SymbolicName from the manifest.mf file
155:             * @param mf the manifest
156:             * @param defaultValue a default value, in case no symbolic name found in manifest
157:             * @return the bundle symbolic name
158:             */
159:            private static String getBundleSymbolicName(Manifest mf,
160:                    String defaultValue) {
161:                if (mf == null) {
162:                    return defaultValue;
163:                }
164:                String name = mf.getMainAttributes().getValue(
165:                        "Bundle-SymbolicName");
166:                if (name == null) {
167:                    return defaultValue;
168:                }
169:                StringTokenizer token = new StringTokenizer(name, ";");
170:                return token.nextToken().trim();
171:            }
172:
173:            /**
174:             * Accessor for the Bundle-Name from the manifest.mf file
175:             * @param mf the manifest
176:             * @param defaultValue a default value, in case no name found in manifest
177:             * @return the bundle name
178:             */
179:            private static String getBundleName(Manifest mf, String defaultValue) {
180:                if (mf == null) {
181:                    return defaultValue;
182:                }
183:                String name = mf.getMainAttributes().getValue("Bundle-Name");
184:                if (name == null) {
185:                    return defaultValue;
186:                }
187:                return name;
188:            }
189:
190:            /**
191:             * Accessor for the Bundle-Vendor from the manifest.mf file
192:             * @param mf the manifest
193:             * @param defaultValue a default value, in case no vendor found in manifest
194:             * @return the bundle vendor
195:             */
196:            private static String getBundleVendor(Manifest mf,
197:                    String defaultValue) {
198:                if (mf == null) {
199:                    return defaultValue;
200:                }
201:                String vendor = mf.getMainAttributes()
202:                        .getValue("Bundle-Vendor");
203:                if (vendor == null) {
204:                    return defaultValue;
205:                }
206:                return vendor;
207:            }
208:
209:            /**
210:             * Accessor for the Bundle-Version from the manifest.mf file
211:             * @param mf the manifest
212:             * @param defaultValue a default value, in case no version found in manifest
213:             * @return the bundle version
214:             */
215:            private static String getBundleVersion(Manifest mf,
216:                    String defaultValue) {
217:                if (mf == null) {
218:                    return defaultValue;
219:                }
220:                String version = mf.getMainAttributes().getValue(
221:                        "Bundle-Version");
222:                if (version == null) {
223:                    return defaultValue;
224:                }
225:                return version;
226:            }
227:
228:            /**
229:             * Method to parse Extensions in plug-in file
230:             * @param mgr the PluginManager
231:             * @param fileUrl URL of the plugin.xml file
232:             * @param clr the ClassLoaderResolver
233:             * @return array of 2 elements. first element is a List of extensionPoints, and 2nd element is a List of Extension
234:             * @throws JPOXException if an error occurs during parsing
235:             */
236:            public static List[] parsePluginElements(PluginRegistry mgr,
237:                    URL fileUrl, Bundle plugin, ClassLoaderResolver clr) {
238:                List extensionPoints = Collections.EMPTY_LIST;
239:                List extensions = Collections.EMPTY_LIST;
240:                try {
241:                    final DocumentBuilderFactory factory = DocumentBuilderFactory
242:                            .newInstance();
243:                    final DocumentBuilder db = factory.newDocumentBuilder();
244:                    try {
245:                        Element rootElement = db.parse(
246:                                new InputSource(new InputStreamReader(fileUrl
247:                                        .openStream()))).getDocumentElement();
248:
249:                        if (JPOXLogger.PLUGIN.isDebugEnabled()) {
250:                            JPOXLogger.PLUGIN.debug(LOCALISER.msg("024003",
251:                                    fileUrl.toString()));
252:                        }
253:                        extensionPoints = parseExtensionPoints(rootElement,
254:                                plugin, clr);
255:
256:                        if (JPOXLogger.PLUGIN.isDebugEnabled()) {
257:                            JPOXLogger.PLUGIN.debug(LOCALISER.msg("024004",
258:                                    fileUrl.toString()));
259:                        }
260:                        extensions = parseExtensions(rootElement, plugin, clr);
261:                    } catch (JPOXException ex) {
262:                        throw ex;
263:                    } catch (Exception e) {
264:                        JPOXLogger.PLUGIN.error(LOCALISER.msg("024000", fileUrl
265:                                .getFile()));
266:                    }
267:                } catch (ParserConfigurationException e1) {
268:                    JPOXLogger.PLUGIN.error(LOCALISER.msg("024001", fileUrl
269:                            .getFile(), e1.getMessage()));
270:                }
271:                return new List[] { extensionPoints, extensions };
272:            }
273:
274:            /**
275:             * Parses the current element and children, creating a ConfigurationElement object
276:             * @param ex the {@link Extension}
277:             * @param element the current element
278:             * @param parent the parent. null if the parent is Extension
279:             * @return the ConfigurationElement for the element
280:             */
281:            private static ConfigurationElement parseConfigurationElement(
282:                    Extension ex, Element element, ConfigurationElement parent) {
283:                ConfigurationElement confElm = new ConfigurationElement(ex,
284:                        element.getNodeName(), parent);
285:                NamedNodeMap attributes = element.getAttributes();
286:                for (int i = 0; i < attributes.getLength(); i++) {
287:                    Node attribute = attributes.item(i);
288:                    confElm.putAttribute(attribute.getNodeName(), attribute
289:                            .getNodeValue());
290:                }
291:                NodeList elements = element.getChildNodes();
292:                for (int i = 0; i < elements.getLength(); i++) {
293:                    if (elements.item(i) instanceof  Element) {
294:                        Element elm = (Element) elements.item(i);
295:                        ConfigurationElement child = parseConfigurationElement(
296:                                ex, elm, confElm);
297:                        confElm.addConfigurationElement(child);
298:                    } else if (elements.item(i) instanceof  Text) {
299:                        confElm.setText(elements.item(i).getNodeValue());
300:                    }
301:                }
302:                return confElm;
303:            }
304:
305:            /**
306:             * Parse a Version Range as per OSGi spec 3.0 $3.2.5
307:             * @param interval the interval string
308:             * @return
309:             */
310:            public static Bundle.BundleVersionRange parseVersionRange(
311:                    String interval) {
312:                Parser p = new Parser(interval);
313:                Bundle.BundleVersionRange versionRange = new Bundle.BundleVersionRange();
314:
315:                if (p.parseChar('[')) {
316:                    //inclusive
317:                    versionRange.floor_inclusive = true;
318:                } else if (p.parseChar('(')) {
319:                    //exclusive
320:                    versionRange.floor_inclusive = false;
321:                }
322:                versionRange.floor = new Bundle.BundleVersion();
323:                versionRange.floor.major = p.parseIntegerLiteral().intValue();
324:                if (p.parseChar('.')) {
325:                    versionRange.floor.minor = p.parseIntegerLiteral()
326:                            .intValue();
327:                }
328:                if (p.parseChar('.')) {
329:                    versionRange.floor.micro = p.parseIntegerLiteral()
330:                            .intValue();
331:                }
332:                if (p.parseChar('.')) {
333:                    versionRange.floor.qualifier = p.parseIdentifier();
334:                }
335:                if (p.parseChar(',')) {
336:                    versionRange.ceiling = new Bundle.BundleVersion();
337:                    versionRange.ceiling.major = p.parseIntegerLiteral()
338:                            .intValue();
339:                    if (p.parseChar('.')) {
340:                        versionRange.ceiling.minor = p.parseIntegerLiteral()
341:                                .intValue();
342:                    }
343:                    if (p.parseChar('.')) {
344:                        versionRange.ceiling.micro = p.parseIntegerLiteral()
345:                                .intValue();
346:                    }
347:                    if (p.parseChar('.')) {
348:                        versionRange.ceiling.qualifier = p.parseIdentifier();
349:                    }
350:                    if (p.parseChar(']')) {
351:                        //inclusive
352:                        versionRange.ceiling_inclusive = true;
353:                    } else if (p.parseChar(')')) {
354:                        //exclusive
355:                        versionRange.ceiling_inclusive = false;
356:                    }
357:                }
358:                return versionRange;
359:            }
360:
361:            /**
362:             * Parser for a list of Bundle-Description
363:             *
364:             * @version $Revision: 1.15 $
365:             **/
366:            public static class Parser {
367:                private final String input;
368:                protected final CharacterIterator ci;
369:
370:                /**
371:                 * Constructor
372:                 * @param input The input string
373:                 **/
374:                public Parser(String input) {
375:                    this .input = input;
376:
377:                    ci = new StringCharacterIterator(input);
378:                }
379:
380:                /**
381:                 * Accessor for the input string.
382:                 * @return The input string.
383:                 */
384:                public String getInput() {
385:                    return input;
386:                }
387:
388:                /**
389:                 * Accessor for the current index in the input string.
390:                 * @return The current index.
391:                 */
392:                public int getIndex() {
393:                    return ci.getIndex();
394:                }
395:
396:                /**
397:                 * Skip over any whitespace from the current position.
398:                 * @return The new position
399:                 */
400:                public int skipWS() {
401:                    int startIdx = ci.getIndex();
402:                    char c = ci.current();
403:
404:                    while (Character.isWhitespace(c) || c == '\t' || c == '\f'
405:                            || c == '\n' || c == '\r' || c == '\u0009'
406:                            || c == '\u000c' || c == '\u0020' || c == '\11'
407:                            || c == '\12' || c == '\14' || c == '\15'
408:                            || c == '\40') {
409:                        c = ci.next();
410:                    }
411:
412:                    return startIdx;
413:                }
414:
415:                /**
416:                 * Check if END OF TEXT is reach
417:                 * @return true if END OF TEXT is reach
418:                 */
419:                public boolean parseEOS() {
420:                    skipWS();
421:
422:                    return ci.current() == CharacterIterator.DONE;
423:                }
424:
425:                /**
426:                 * Check if char <code>c</code> is found
427:                 * @param c the Character to find
428:                 * @return true if <code>c</code> is found
429:                 */
430:                public boolean parseChar(char c) {
431:                    skipWS();
432:
433:                    if (ci.current() == c) {
434:                        ci.next();
435:                        return true;
436:                    } else {
437:                        return false;
438:                    }
439:                }
440:
441:                /**
442:                 * Check if char <code>c</code> is found
443:                 * @param c the Character to find
444:                 * @param unlessFollowedBy the character to validate it does not follow <code>c</code>
445:                 * @return true if <code>c</code> is found and not followed by <code>unlessFollowedBy</code>
446:                 */
447:                public boolean parseChar(char c, char unlessFollowedBy) {
448:                    int savedIdx = skipWS();
449:
450:                    if (ci.current() == c && ci.next() != unlessFollowedBy) {
451:                        return true;
452:                    } else {
453:                        ci.setIndex(savedIdx);
454:                        return false;
455:                    }
456:                }
457:
458:                /**
459:                 * Parse an integer number from the current position.
460:                 * @return The integer number parsed (null if not valid).
461:                 */
462:                public BigInteger parseIntegerLiteral() {
463:                    int savedIdx = skipWS();
464:
465:                    StringBuffer digits = new StringBuffer();
466:                    int radix;
467:                    char c = ci.current();
468:
469:                    if (c == '0') {
470:                        c = ci.next();
471:
472:                        if (c == 'x' || c == 'X') {
473:                            radix = 16;
474:                            c = ci.next();
475:
476:                            while (isHexDigit(c)) {
477:                                digits.append(c);
478:                                c = ci.next();
479:                            }
480:                        } else if (isOctDigit(c)) {
481:                            radix = 8;
482:
483:                            do {
484:                                digits.append(c);
485:                                c = ci.next();
486:                            } while (isOctDigit(c));
487:                        } else {
488:                            radix = 10;
489:                            digits.append('0');
490:                        }
491:                    } else {
492:                        radix = 10;
493:
494:                        while (isDecDigit(c)) {
495:                            digits.append(c);
496:                            c = ci.next();
497:                        }
498:                    }
499:
500:                    if (digits.length() == 0) {
501:                        ci.setIndex(savedIdx);
502:                        return null;
503:                    }
504:
505:                    if (c == 'l' || c == 'L') {
506:                        ci.next();
507:                    }
508:
509:                    return new BigInteger(digits.toString(), radix);
510:                }
511:
512:                /**
513:                 * Check if String <code>s</code> is found
514:                 * @param s the String to find
515:                 * @return true if <code>s</code> is found
516:                 */
517:                public boolean parseString(String s) {
518:                    int savedIdx = skipWS();
519:
520:                    int len = s.length();
521:                    char c = ci.current();
522:
523:                    for (int i = 0; i < len; ++i) {
524:                        if (c != s.charAt(i)) {
525:                            ci.setIndex(savedIdx);
526:                            return false;
527:                        }
528:
529:                        c = ci.next();
530:                    }
531:
532:                    return true;
533:                }
534:
535:                /**
536:                 * Check if String <code>s</code> is found ignoring the case
537:                 * @param s the String to find
538:                 * @return true if <code>s</code> is found
539:                 */
540:                public boolean parseStringIgnoreCase(String s) {
541:                    String lowerCasedString = s.toLowerCase();
542:
543:                    int savedIdx = skipWS();
544:
545:                    int len = lowerCasedString.length();
546:                    char c = ci.current();
547:
548:                    for (int i = 0; i < len; ++i) {
549:                        if (Character.toLowerCase(c) != lowerCasedString
550:                                .charAt(i)) {
551:                            ci.setIndex(savedIdx);
552:                            return false;
553:                        }
554:
555:                        c = ci.next();
556:                    }
557:
558:                    return true;
559:                }
560:
561:                /**
562:                 * Parse a java identifier from the current position.
563:                 * @return The identifier
564:                 */
565:                public String parseIdentifier() {
566:                    skipWS();
567:                    char c = ci.current();
568:
569:                    if (!Character.isJavaIdentifierStart(c)) {
570:                        return null;
571:                    }
572:
573:                    StringBuffer id = new StringBuffer();
574:                    id.append(c);
575:                    //- hifen symbol is valid according OSGi specification
576:                    while (Character.isJavaIdentifierPart(c = ci.next())
577:                            || c == '-') {
578:                        id.append(c);
579:                    }
580:
581:                    return id.toString();
582:                }
583:
584:                /**
585:                 * Parse an OSGi interval from the current position.
586:                 * @return The interval
587:                 */
588:                public String parseInterval() {
589:                    skipWS();
590:                    char c = ci.current();
591:
592:                    StringBuffer id = new StringBuffer();
593:
594:                    while ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')
595:                            || (c >= '0' && c <= '9') || c == '.' || c == '_'
596:                            || c == '-' || c == '[' || c == ']' || c == '('
597:                            || c == ')') {
598:                        id.append(c);
599:                        c = ci.next();
600:                    }
601:
602:                    return id.toString();
603:                }
604:
605:                /**
606:                 * Parses the text string (up to the next space) and
607:                 * returns it. The name includes '.' characters.
608:                 * This can be used, for example, when parsing a class name wanting to
609:                 * read in the full name (including package) so that it can then be
610:                 * checked for existence in the CLASSPATH.
611:                 * @return The name
612:                 */
613:                public String parseName() {
614:                    int savedIdx = skipWS();
615:                    String id;
616:
617:                    if ((id = parseIdentifier()) == null) {
618:                        return null;
619:                    }
620:
621:                    StringBuffer qn = new StringBuffer(id);
622:
623:                    while (parseChar('.')) {
624:                        if ((id = parseIdentifier()) == null) {
625:                            ci.setIndex(savedIdx);
626:                            return null;
627:                        }
628:
629:                        qn.append('.').append(id);
630:                    }
631:
632:                    return qn.toString();
633:                }
634:
635:                /**
636:                 * Utility to return if a character is a decimal digit.
637:                 * @param c The character
638:                 * @return Whether it is a decimal digit
639:                 */
640:                private final boolean isDecDigit(char c) {
641:                    return c >= '0' && c <= '9';
642:                }
643:
644:                /**
645:                 * Utility to return if a character is a octal digit.
646:                 * @param c The character
647:                 * @return Whether it is a octal digit
648:                 */
649:                private final boolean isOctDigit(char c) {
650:                    return c >= '0' && c <= '7';
651:                }
652:
653:                /**
654:                 * Utility to return if a character is a hexadecimal digit.
655:                 * @param c The character
656:                 * @return Whether it is a hexadecimal digit
657:                 */
658:                private final boolean isHexDigit(char c) {
659:                    return c >= '0' && c <= '9' || c >= 'a' && c <= 'f'
660:                            || c >= 'A' && c <= 'F';
661:                }
662:
663:                /**
664:                 * Utility to return if the next non-whitespace character is a single quote.
665:                 * @return Whether it is a single quote at the current point (ignoring whitespace)
666:                 */
667:                public boolean nextIsSingleQuote() {
668:                    skipWS();
669:                    return (ci.current() == '\'');
670:                }
671:
672:                /**
673:                 * Utility to return if the next character is a dot.
674:                 * @return Whether it is a dot at the current point
675:                 */
676:                public boolean nextIsDot() {
677:                    return (ci.current() == '.');
678:                }
679:
680:                /**
681:                 * Utility to return if the next character is a comma.
682:                 * @return Whether it is a dot at the current point
683:                 */
684:                public boolean nextIsComma() {
685:                    return (ci.current() == ',');
686:                }
687:
688:                /**
689:                 * Utility to return if the next character is a semi-colon.
690:                 * @return Whether it is a semi-colon at the current point
691:                 */
692:                public boolean nextIsSemiColon() {
693:                    return (ci.current() == ';');
694:                }
695:
696:                /**
697:                 * Parse a String literal
698:                 * @return the String parsed. null if single quotes or double quotes is found
699:                 * @throws JPOXUserException if an invalid character is found or the CharacterIterator is finished
700:                 */
701:                public String parseStringLiteral() {
702:                    skipWS();
703:
704:                    // Strings can be surrounded by single or double quotes
705:                    char quote = ci.current();
706:                    if (quote != '"' && quote != '\'') {
707:                        return null;
708:                    }
709:
710:                    StringBuffer lit = new StringBuffer();
711:                    char c;
712:
713:                    while ((c = ci.next()) != quote) {
714:                        if (c == CharacterIterator.DONE) {
715:                            throw new JPOXUserException(
716:                                    "Invalid string literal: " + input);
717:                        }
718:
719:                        if (c == '\\') {
720:                            c = parseEscapedCharacter();
721:                        }
722:
723:                        lit.append(c);
724:                    }
725:
726:                    ci.next();
727:
728:                    return lit.toString();
729:                }
730:
731:                /**
732:                 * Parse a escaped character
733:                 * @return the escaped char
734:                 * @throws JPOXUserException if a escaped character is not valid
735:                 */
736:                private char parseEscapedCharacter() {
737:                    char c;
738:
739:                    if (isOctDigit(c = ci.next())) {
740:                        int i = (c - '0');
741:
742:                        if (isOctDigit(c = ci.next())) {
743:                            i = i * 8 + (c - '0');
744:
745:                            if (isOctDigit(c = ci.next())) {
746:                                i = i * 8 + (c - '0');
747:                            } else {
748:                                ci.previous();
749:                            }
750:                        } else {
751:                            ci.previous();
752:                        }
753:
754:                        if (i > 0xff) {
755:                            throw new JPOXUserException(
756:                                    "Invalid character escape: '\\"
757:                                            + Integer.toOctalString(i) + "'");
758:                        }
759:
760:                        return (char) i;
761:                    } else {
762:                        switch (c) {
763:                        case 'b':
764:                            return '\b';
765:                        case 't':
766:                            return '\t';
767:                        case 'n':
768:                            return '\n';
769:                        case 'f':
770:                            return '\f';
771:                        case 'r':
772:                            return '\r';
773:                        case '"':
774:                            return '"';
775:                        case '\'':
776:                            return '\'';
777:                        case '\\':
778:                            return '\\';
779:                        default:
780:                            throw new JPOXUserException(
781:                                    "Invalid character escape: '\\" + c + "'");
782:                        }
783:                    }
784:                }
785:
786:                public String remaining() {
787:                    StringBuffer sb = new StringBuffer();
788:                    char c = ci.current();
789:                    while (c != CharacterIterator.DONE) {
790:                        sb.append(c);
791:                        c = ci.next();
792:                    }
793:                    return sb.toString();
794:                }
795:
796:                public String toString() {
797:                    return input;
798:                }
799:
800:                public Map parseParameters() {
801:                    skipWS();
802:                    Map paramaters = new HashMap();
803:                    while (nextIsSemiColon()) {
804:                        parseChar(';');
805:                        skipWS();
806:                        String name = parseName();
807:                        skipWS();
808:                        if (!parseString(":=") && !parseString("=")) {
809:                            throw new JPOXUserException(
810:                                    "Expected := or = symbols but found \""
811:                                            + remaining() + "\" at position "
812:                                            + this .getIndex() + " of text \""
813:                                            + input + "\"");
814:                        }
815:                        String argument = parseStringLiteral();
816:                        if (argument == null) {
817:                            argument = parseIdentifier();
818:                        }
819:                        if (argument == null) {
820:                            argument = parseInterval();
821:                        }
822:                        paramaters.put(name, argument);
823:                        skipWS();
824:                    }
825:                    return paramaters;
826:                }
827:
828:                public String parseSymbolicName() {
829:                    if (nextIsComma()) {
830:                        parseChar(',');
831:                    }
832:                    String name = parseName();
833:                    if (name == null && !parseEOS()) {
834:                        throw new JPOXUserException(
835:                                "Invalid characters found \"" + remaining()
836:                                        + "\" at position " + this .getIndex()
837:                                        + " of text \"" + input + "\"");
838:                    }
839:                    return name;
840:                }
841:            }
842:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.