Source Code Cross Referenced for ElementSchemePointer.java in  » XML » xerces-2_9_1 » org » apache » xerces » xpointer » 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 » XML » xerces 2_9_1 » org.apache.xerces.xpointer 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         * 
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         * 
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:        package org.apache.xerces.xpointer;
018:
019:        import java.util.Hashtable;
020:
021:        import org.apache.xerces.impl.XMLErrorReporter;
022:        import org.apache.xerces.util.SymbolTable;
023:        import org.apache.xerces.util.XMLChar;
024:        import org.apache.xerces.xni.Augmentations;
025:        import org.apache.xerces.xni.QName;
026:        import org.apache.xerces.xni.XMLAttributes;
027:        import org.apache.xerces.xni.XNIException;
028:        import org.apache.xerces.xni.parser.XMLErrorHandler;
029:
030:        /**
031:         * <p>
032:         * Implements the XPointerPart interface for element() scheme specific processing.
033:         * </p>
034:         *
035:         * @xerces.internal
036:         * 
037:         * @version $Id: ElementSchemePointer.java 447248 2006-09-18 05:25:21Z mrglavas $
038:         *
039:         */
040:        class ElementSchemePointer implements  XPointerPart {
041:
042:            // Fields
043:
044:            // The Scheme Name i.e element
045:            private String fSchemeName;
046:
047:            // The scheme Data
048:            private String fSchemeData;
049:
050:            // The scheme Data & child sequence
051:            private String fShortHandPointerName;
052:
053:            // Should we attempt to resolve the ChildSequence from the 
054:            // current element position. If a ShortHand Pointer is present
055:            // attempt to resolve relative to the short hand pointer.
056:            private boolean fIsResolveElement = false;
057:
058:            // Has the element been found
059:            private boolean fIsElementFound = false;
060:
061:            // Was only an empty element found
062:            private boolean fWasOnlyEmptyElementFound = false;
063:
064:            // If a shorthand pointer is present and resolved
065:            boolean fIsShortHand = false;
066:
067:            // The depth at which the element was found
068:            int fFoundDepth = 0;
069:
070:            // The XPointer element child sequence
071:            private int fChildSequence[];
072:
073:            // The current child position
074:            private int fCurrentChildPosition = 1;
075:
076:            // The current child depth
077:            private int fCurrentChildDepth = 0;
078:
079:            // The current element's child sequence
080:            private int fCurrentChildSequence[];;
081:
082:            // Stores if the Fragment was resolved by the pointer
083:            private boolean fIsFragmentResolved = false;
084:
085:            // Stores if the Fragment was resolved by the pointer
086:            private ShortHandPointer fShortHandPointer;
087:
088:            // The XPointer Error reporter
089:            protected XMLErrorReporter fErrorReporter;
090:
091:            // The XPointer Error Handler
092:            protected XMLErrorHandler fErrorHandler;
093:
094:            //
095:            private SymbolTable fSymbolTable;
096:
097:            // ************************************************************************
098:            // Constructors
099:            // ************************************************************************
100:            public ElementSchemePointer() {
101:            }
102:
103:            public ElementSchemePointer(SymbolTable symbolTable) {
104:                fSymbolTable = symbolTable;
105:            }
106:
107:            public ElementSchemePointer(SymbolTable symbolTable,
108:                    XMLErrorReporter errorReporter) {
109:                fSymbolTable = symbolTable;
110:                fErrorReporter = errorReporter;
111:            }
112:
113:            // ************************************************************************
114:            // XPointerPart implementation
115:            // ************************************************************************
116:
117:            /** 
118:             * Parses the XPointer expression and tokenizes it into Strings
119:             * delimited by whitespace.   
120:             *   
121:             * @see org.apache.xerces.xpointer.XPointerProcessor#parseXPointer(java.lang.String)
122:             */
123:            public void parseXPointer(String xpointer) throws XNIException {
124:
125:                //
126:                init();
127:
128:                // tokens
129:                final Tokens tokens = new Tokens(fSymbolTable);
130:
131:                // scanner
132:                Scanner scanner = new Scanner(fSymbolTable) {
133:                    protected void addToken(Tokens tokens, int token)
134:                            throws XNIException {
135:                        if (token == Tokens.XPTRTOKEN_ELEM_CHILD
136:                                || token == Tokens.XPTRTOKEN_ELEM_NCNAME) {
137:                            super .addToken(tokens, token);
138:                            return;
139:                        }
140:                        reportError("InvalidElementSchemeToken",
141:                                new Object[] { tokens.getTokenString(token) });
142:                    }
143:                };
144:
145:                // scan the element() XPointer expression
146:                int length = xpointer.length();
147:                boolean success = scanner.scanExpr(fSymbolTable, tokens,
148:                        xpointer, 0, length);
149:
150:                if (!success) {
151:                    reportError("InvalidElementSchemeXPointer",
152:                            new Object[] { xpointer });
153:                }
154:
155:                // Initialize a temp arrays to the size of token count which should 
156:                // be atleast twice the size of child sequence, to hold the ChildSequence.
157:                int tmpChildSequence[] = new int[tokens.getTokenCount() / 2 + 1];
158:
159:                // the element depth          
160:                int i = 0;
161:
162:                // Traverse the scanned tokens
163:                while (tokens.hasMore()) {
164:                    int token = tokens.nextToken();
165:
166:                    switch (token) {
167:                    case Tokens.XPTRTOKEN_ELEM_NCNAME: {
168:                        // Note:  Only a single ShortHand pointer can be present
169:
170:                        // The shortHand name
171:                        token = tokens.nextToken();
172:                        fShortHandPointerName = tokens.getTokenString(token);
173:
174:                        // Create a new ShortHandPointer
175:                        fShortHandPointer = new ShortHandPointer(fSymbolTable);
176:                        fShortHandPointer.setSchemeName(fShortHandPointerName);
177:
178:                        break;
179:                    }
180:                    case Tokens.XPTRTOKEN_ELEM_CHILD: {
181:                        tmpChildSequence[i] = tokens.nextToken();
182:                        i++;
183:
184:                        break;
185:                    }
186:                    default:
187:                        reportError("InvalidElementSchemeXPointer",
188:                                new Object[] { xpointer });
189:                    }
190:                }
191:
192:                // Initialize the arrays to the number of elements in the ChildSequence.
193:                fChildSequence = new int[i];
194:                fCurrentChildSequence = new int[i];
195:                System.arraycopy(tmpChildSequence, 0, fChildSequence, 0, i);
196:
197:            }
198:
199:            /**
200:             * Returns the scheme name i.e element
201:             * @see org.apache.xerces.xpointer.XPointerPart#getSchemeName()
202:             */
203:            public String getSchemeName() {
204:                return fSchemeName;
205:            }
206:
207:            /**
208:             * Returns the scheme data
209:             * 
210:             * @see org.apache.xerces.xpointer.XPointerPart#getSchemeData()
211:             */
212:            public String getSchemeData() {
213:                return fSchemeData;
214:            }
215:
216:            /**
217:             * Sets the scheme name
218:             * 
219:             * @see org.apache.xerces.xpointer.XPointerPart#setSchemeName(java.lang.String)
220:             */
221:            public void setSchemeName(String schemeName) {
222:                fSchemeName = schemeName;
223:
224:            }
225:
226:            /**
227:             * Sets the scheme data
228:             * 
229:             * @see org.apache.xerces.xpointer.XPointerPart#setSchemeData(java.lang.String)
230:             */
231:            public void setSchemeData(String schemeData) {
232:                fSchemeData = schemeData;
233:            }
234:
235:            /**
236:             * Responsible for resolving the element() scheme XPointer.  If a ShortHand
237:             * Pointer is present and it is successfully resolved and if a child
238:             * sequence is present, the child sequence is resolved relative to it.
239:             *   
240:             * @see org.apache.xerces.xpointer.XPointerProcessor#resolveXPointer(org.apache.xerces.xni.QName, org.apache.xerces.xni.XMLAttributes, org.apache.xerces.xni.Augmentations, int event)
241:             */
242:            public boolean resolveXPointer(QName element,
243:                    XMLAttributes attributes, Augmentations augs, int event)
244:                    throws XNIException {
245:
246:                boolean isShortHandPointerResolved = false;
247:
248:                // if a ChildSequence exisits, resolve child elements
249:
250:                // if an element name exists
251:                if (fShortHandPointerName != null) {
252:                    // resolve ShortHand Pointer
253:                    isShortHandPointerResolved = fShortHandPointer
254:                            .resolveXPointer(element, attributes, augs, event);
255:                    if (isShortHandPointerResolved) {
256:                        fIsResolveElement = true;
257:                        fIsShortHand = true;
258:                    } else {
259:                        fIsResolveElement = false;
260:                    }
261:                } else {
262:                    fIsResolveElement = true;
263:                }
264:
265:                // Added here to skip the ShortHand pointer corresponding to
266:                // an element if one exisits and start searching from its child
267:                if (fChildSequence.length > 0) {
268:                    fIsFragmentResolved = matchChildSequence(element, event);
269:                } else if (isShortHandPointerResolved
270:                        && fChildSequence.length <= 0) {
271:                    // if only a resolved shorthand pointer exists
272:                    fIsFragmentResolved = isShortHandPointerResolved;
273:                } else {
274:                    fIsFragmentResolved = false;
275:                }
276:
277:                return fIsFragmentResolved;
278:            }
279:
280:            /**
281:             * Matches the current element position in the document tree with the
282:             * element position specified in the element XPointer scheme.
283:             *   
284:             * @param event
285:             * @return boolean - true if the current element position in the document 
286:             * tree matches theelement position specified in the element XPointer 
287:             * scheme.
288:             */
289:            protected boolean matchChildSequence(QName element, int event)
290:                    throws XNIException {
291:
292:                // need to resize fCurrentChildSequence
293:                if (fCurrentChildDepth >= fCurrentChildSequence.length) {
294:                    int tmpCurrentChildSequence[] = new int[fCurrentChildSequence.length];
295:                    System.arraycopy(fCurrentChildSequence, 0,
296:                            tmpCurrentChildSequence, 0,
297:                            fCurrentChildSequence.length);
298:
299:                    // Increase the size by a factor of 2 (?)
300:                    fCurrentChildSequence = new int[fCurrentChildDepth * 2];
301:                    System.arraycopy(tmpCurrentChildSequence, 0,
302:                            fCurrentChildSequence, 0,
303:                            tmpCurrentChildSequence.length);
304:                }
305:
306:                //     
307:                if (fIsResolveElement) {
308:                    // start
309:                    if (event == XPointerPart.EVENT_ELEMENT_START) {
310:                        fCurrentChildSequence[fCurrentChildDepth] = fCurrentChildPosition;
311:                        fCurrentChildDepth++;
312:
313:                        // reset the current child position 
314:                        fCurrentChildPosition = 1;
315:
316:                        //if (!fSchemeNameFound) {
317:                        if ((fCurrentChildDepth <= fFoundDepth)
318:                                || (fFoundDepth == 0)) {
319:                            if (checkMatch()) {
320:                                fIsElementFound = true;
321:                                fFoundDepth = fCurrentChildDepth;
322:                            } else {
323:                                fIsElementFound = false;
324:                                fFoundDepth = 0;
325:                            }
326:                        }
327:
328:                    } else if (event == XPointerPart.EVENT_ELEMENT_END) {
329:                        if (fCurrentChildDepth == fFoundDepth) {
330:                            fIsElementFound = true;
331:                        } else if (((fCurrentChildDepth < fFoundDepth) && (fFoundDepth != 0))
332:                                || ((fCurrentChildDepth > fFoundDepth) // or empty element found
333:                                && (fFoundDepth == 0))) {
334:                            fIsElementFound = false;
335:                        }
336:
337:                        // reset array position of last child
338:                        fCurrentChildSequence[fCurrentChildDepth] = 0;
339:
340:                        fCurrentChildDepth--;
341:                        fCurrentChildPosition = fCurrentChildSequence[fCurrentChildDepth] + 1;
342:
343:                    } else if (event == XPointerPart.EVENT_ELEMENT_EMPTY) {
344:
345:                        fCurrentChildSequence[fCurrentChildDepth] = fCurrentChildPosition;
346:                        fCurrentChildPosition++;
347:
348:                        // Donot check for empty elements if the empty element is 
349:                        // a child of a found parent element 
350:                        if (checkMatch()) {
351:                            if (!fIsElementFound) {
352:                                fWasOnlyEmptyElementFound = true;
353:                            } else {
354:                                fWasOnlyEmptyElementFound = false;
355:                            }
356:                            fIsElementFound = true;
357:                        } else {
358:                            fIsElementFound = false;
359:                            fWasOnlyEmptyElementFound = false;
360:                        }
361:                    }
362:                }
363:
364:                return fIsElementFound;
365:            }
366:
367:            /**
368:             * Matches the current position of the element being visited by checking 
369:             * its position and previous elements against the element XPointer expression.  
370:             * If a match is found it return true else false.
371:             *  
372:             * @return boolean 
373:             */
374:            protected boolean checkMatch() {
375:                // If the number of elements in the ChildSequence is greater than the
376:                // current child depth, there is not point in checking further
377:                if (!fIsShortHand) {
378:                    // If a shorthand pointer is not present traverse the children
379:                    // and compare
380:                    if (fChildSequence.length <= fCurrentChildDepth + 1) {
381:
382:                        for (int i = 0; i < fChildSequence.length; i++) {
383:                            if (fChildSequence[i] != fCurrentChildSequence[i]) {
384:                                return false;
385:                            }
386:                        }
387:                    } else {
388:                        return false;
389:                    }
390:                } else {
391:                    // If a shorthand pointer is present traverse the children
392:                    // ignoring the first element of the CurrenChildSequence which
393:                    // contains the ShortHand pointer element and compare            
394:                    if (fChildSequence.length <= fCurrentChildDepth + 1) {
395:
396:                        for (int i = 0; i < fChildSequence.length; i++) {
397:                            // ensure fCurrentChildSequence is large enough
398:                            if (fCurrentChildSequence.length < i + 2) {
399:                                return false;
400:                            }
401:
402:                            // ignore the first element of fCurrentChildSequence
403:                            if (fChildSequence[i] != fCurrentChildSequence[i + 1]) {
404:                                return false;
405:                            }
406:                        }
407:                    } else {
408:                        return false;
409:                    }
410:
411:                }
412:
413:                return true;
414:            }
415:
416:            /**
417:             * Returns true if the node matches or is a child of a matching element()
418:             * scheme XPointer.
419:             *  
420:             * @see org.apache.xerces.xpointer.XPointerProcessor#isFragmentResolved()
421:             */
422:            public boolean isFragmentResolved() throws XNIException {
423:                // Return true if the Fragment was resolved and the current Node depth
424:                // is greater than or equal to the depth at which the element was found
425:                return fIsFragmentResolved;
426:            }
427:
428:            /**
429:             * Returns true if the XPointer expression resolves to a non-element child
430:             * of the current resource fragment.       
431:             * 
432:             * @see org.apache.xerces.xpointer.XPointerPart#isChildFragmentResolved()
433:             *   
434:             */
435:            public boolean isChildFragmentResolved() {
436:                // if only a shorthand pointer was present
437:                if (fIsShortHand && fShortHandPointer != null
438:                        && fChildSequence.length <= 0) {
439:                    return fShortHandPointer.isChildFragmentResolved();
440:                } else {
441:                    return fWasOnlyEmptyElementFound ? !fWasOnlyEmptyElementFound
442:                            : (fIsFragmentResolved && (fCurrentChildDepth >= fFoundDepth));
443:                }
444:            }
445:
446:            /**
447:             * Reports an XPointer error
448:             */
449:            protected void reportError(String key, Object[] arguments)
450:                    throws XNIException {
451:                /*fErrorReporter.reportError(XPointerMessageFormatter.XPOINTER_DOMAIN,
452:                 key, arguments, XMLErrorReporter.SEVERITY_ERROR);
453:                 */
454:                throw new XNIException(
455:                        (fErrorReporter
456:                                .getMessageFormatter(XPointerMessageFormatter.XPOINTER_DOMAIN))
457:                                .formatMessage(fErrorReporter.getLocale(), key,
458:                                        arguments));
459:            }
460:
461:            /**
462:             * Initializes error handling objects
463:             */
464:            protected void initErrorReporter() {
465:                if (fErrorReporter == null) {
466:                    fErrorReporter = new XMLErrorReporter();
467:                }
468:                if (fErrorHandler == null) {
469:                    fErrorHandler = new XPointerErrorHandler();
470:                }
471:                fErrorReporter.putMessageFormatter(
472:                        XPointerMessageFormatter.XPOINTER_DOMAIN,
473:                        new XPointerMessageFormatter());
474:            }
475:
476:            /**
477:             * Initializes the element scheme processor
478:             */
479:            protected void init() {
480:                fSchemeName = null;
481:                fSchemeData = null;
482:                fShortHandPointerName = null;
483:                fIsResolveElement = false;
484:                fIsElementFound = false;
485:                fWasOnlyEmptyElementFound = false;
486:                fFoundDepth = 0;
487:                fCurrentChildPosition = 1;
488:                fCurrentChildDepth = 0;
489:                fIsFragmentResolved = false;
490:                fShortHandPointer = null;
491:
492:                initErrorReporter();
493:            }
494:
495:            // ************************************************************************
496:            // element() Scheme expression scanner
497:            // ************************************************************************
498:
499:            /**
500:             * List of XPointer Framework tokens.
501:             * 
502:             * @xerces.internal
503:             * 
504:             * @author Neil Delima, IBM
505:             * @version $Id: ElementSchemePointer.java 447248 2006-09-18 05:25:21Z mrglavas $
506:             * 
507:             */
508:            private final class Tokens {
509:
510:                /**
511:                 * XPointer element() scheme
512:                 * [1]    ElementSchemeData    ::=    (NCName ChildSequence?) | ChildSequence  
513:                 * [2]    ChildSequence    ::=    ('/' [1-9] [0-9]*)+ 
514:                 */
515:                private static final int XPTRTOKEN_ELEM_NCNAME = 0;
516:
517:                private static final int XPTRTOKEN_ELEM_CHILD = 1;
518:
519:                // Token names
520:                private final String[] fgTokenNames = {
521:                        "XPTRTOKEN_ELEM_NCNAME", "XPTRTOKEN_ELEM_CHILD" };
522:
523:                // Token count
524:                private static final int INITIAL_TOKEN_COUNT = 1 << 8;
525:
526:                private int[] fTokens = new int[INITIAL_TOKEN_COUNT];
527:
528:                private int fTokenCount = 0;
529:
530:                // Current token position
531:                private int fCurrentTokenIndex;
532:
533:                private SymbolTable fSymbolTable;
534:
535:                private Hashtable fTokenNames = new Hashtable();
536:
537:                /**
538:                 * Constructor 
539:                 * 
540:                 * @param symbolTable SymbolTable
541:                 */
542:                private Tokens(SymbolTable symbolTable) {
543:                    fSymbolTable = symbolTable;
544:
545:                    fTokenNames.put(new Integer(XPTRTOKEN_ELEM_NCNAME),
546:                            "XPTRTOKEN_ELEM_NCNAME");
547:                    fTokenNames.put(new Integer(XPTRTOKEN_ELEM_CHILD),
548:                            "XPTRTOKEN_ELEM_CHILD");
549:                }
550:
551:                /*
552:                 * Returns the token String 
553:                 * @param token The index of the token
554:                 * @return String The token string
555:                 */
556:                private String getTokenString(int token) {
557:                    return (String) fTokenNames.get(new Integer(token));
558:                }
559:
560:                /**
561:                 * Returns the token String 
562:                 * @param token The index of the token
563:                 * @return String The token string
564:                 */
565:                private Integer getToken(int token) {
566:                    return (Integer) fTokenNames.get(new Integer(token));
567:                }
568:
569:                /**
570:                 * Add the specified string as a token
571:                 *  
572:                 * @param token The token string
573:                 */
574:                private void addToken(String tokenStr) {
575:                    Integer tokenInt = (Integer) fTokenNames.get(tokenStr);
576:                    if (tokenInt == null) {
577:                        tokenInt = new Integer(fTokenNames.size());
578:                        fTokenNames.put(tokenInt, tokenStr);
579:                    }
580:                    addToken(tokenInt.intValue());
581:                }
582:
583:                /**
584:                 * Add the specified int token
585:                 *  
586:                 * @param token The int specifying the token
587:                 */
588:                private void addToken(int token) {
589:                    try {
590:                        fTokens[fTokenCount] = token;
591:                    } catch (ArrayIndexOutOfBoundsException ex) {
592:                        int[] oldList = fTokens;
593:                        fTokens = new int[fTokenCount << 1];
594:                        System.arraycopy(oldList, 0, fTokens, 0, fTokenCount);
595:                        fTokens[fTokenCount] = token;
596:                    }
597:                    fTokenCount++;
598:                }
599:
600:                /**
601:                 * Resets the current position to the head of the token list.
602:                 */
603:                private void rewind() {
604:                    fCurrentTokenIndex = 0;
605:                }
606:
607:                /**
608:                 * Returns true if the {@link #getNextToken()} method
609:                 * returns a valid token.
610:                 */
611:                private boolean hasMore() {
612:                    return fCurrentTokenIndex < fTokenCount;
613:                }
614:
615:                /**
616:                 * Obtains the token at the current position, then advance
617:                 * the current position by one.
618:                 * 
619:                 * If there's no such next token, this method throws
620:                 * <tt>new XNIException("InvalidXPointerExpression");</tt>.
621:                 */
622:                private int nextToken() throws XNIException {
623:                    if (fCurrentTokenIndex == fTokenCount)
624:                        reportError("XPointerElementSchemeProcessingError",
625:                                null);
626:                    return fTokens[fCurrentTokenIndex++];
627:                }
628:
629:                /**
630:                 * Obtains the token at the current position, without advancing
631:                 * the current position.
632:                 * 
633:                 * If there's no such next token, this method throws
634:                 * <tt>new XNIException("InvalidXPointerExpression");</tt>.
635:                 */
636:                private int peekToken() throws XNIException {
637:                    if (fCurrentTokenIndex == fTokenCount)
638:                        reportError("XPointerElementSchemeProcessingError",
639:                                null);
640:                    return fTokens[fCurrentTokenIndex];
641:                }
642:
643:                /**
644:                 * Obtains the token at the current position as a String.
645:                 * 
646:                 * If there's no current token or if the current token
647:                 * is not a string token, this method throws 
648:                 * If there's no such next token, this method throws
649:                 * <tt>new XNIException("InvalidXPointerExpression");</tt>.
650:                 */
651:                private String nextTokenAsString() throws XNIException {
652:                    String s = getTokenString(nextToken());
653:                    if (s == null)
654:                        reportError("XPointerElementSchemeProcessingError",
655:                                null);
656:                    return s;
657:                }
658:
659:                /**
660:                 * Returns the number of tokens.
661:                 * 
662:                 */
663:                private int getTokenCount() {
664:                    return fTokenCount;
665:                }
666:            }
667:
668:            /**
669:             * 
670:             * The XPointer expression scanner.  Scans the XPointer framework expression.
671:             * 
672:             * @xerces.internal
673:             * 
674:             * @version $Id: ElementSchemePointer.java 447248 2006-09-18 05:25:21Z mrglavas $
675:             */
676:            private class Scanner {
677:
678:                /**
679:                 * 7-bit ASCII subset
680:                 *
681:                 *  0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
682:                 *  0,  0,  0,  0,  0,  0,  0,  0,  0, HT, LF,  0,  0, CR,  0,  0,  // 0
683:                 *  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 1
684:                 * SP,  !,  ",  #,  $,  %,  &,  ',  (,  ),  *,  +,  ,,  -,  .,  /,  // 2
685:                 *  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  :,  ;,  <,  =,  >,  ?,  // 3
686:                 *  @,  A,  B,  C,  D,  E,  F,  G,  H,  I,  J,  K,  L,  M,  N,  O,  // 4
687:                 *  P,  Q,  R,  S,  T,  U,  V,  W,  X,  Y,  Z,  [,  \,  ],  ^,  _,  // 5
688:                 *  `,  a,  b,  c,  d,  e,  f,  g,  h,  i,  j,  k,  l,  m,  n,  o,  // 6
689:                 *  p,  q,  r,  s,  t,  u,  v,  w,  x,  y,  z,  {,  |,  },  ~, DEL  // 7
690:                 */
691:                private static final byte CHARTYPE_INVALID = 0, // invalid XML characters, control characters and 7F
692:                        CHARTYPE_OTHER = 1, // A valid XML character (possibly invalid NCNameChar) that does not fall in one of the other categories
693:                        CHARTYPE_MINUS = 2, // '-' (0x2D)
694:                        CHARTYPE_PERIOD = 3, // '.' (0x2E)
695:                        CHARTYPE_SLASH = 4, // '/' (0x2F)
696:                        CHARTYPE_DIGIT = 5, // '0'-'9' (0x30 to 0x39)
697:                        CHARTYPE_LETTER = 6, // 'A'-'Z' or 'a'-'z' (0x41 to 0x5A and 0x61 to 0x7A)
698:                        CHARTYPE_UNDERSCORE = 7, // '_' (0x5F)
699:                        CHARTYPE_NONASCII = 8; // Non-ASCII Unicode codepoint (>= 0x80)
700:
701:                private final byte[] fASCIICharMap = { 0, 0, 0, 0, 0, 0, 0, 0,
702:                        0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
703:                        0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
704:                        1, 2, 2, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 1, 1,
705:                        1, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
706:                        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 1, 1, 7, 1, 6,
707:                        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
708:                        6, 6, 6, 6, 6, 6, 6, 1, 1, 1, 1, 1 };
709:
710:                /**
711:                 * Symbol literals
712:                 */
713:
714:                //
715:                // Data
716:                //
717:                /** Symbol table. */
718:                private SymbolTable fSymbolTable;
719:
720:                //
721:                // Constructors
722:                //
723:
724:                /** 
725:                 * Constructs an XPath expression scanner. 
726:                 *
727:                 * @param symbolTable SymbolTable  
728:                 */
729:                private Scanner(SymbolTable symbolTable) {
730:                    // save pool and tokens
731:                    fSymbolTable = symbolTable;
732:
733:                } // <init>(SymbolTable)
734:
735:                /**
736:                 * Scans the XPointer Expression
737:                 * 
738:                 */
739:                private boolean scanExpr(SymbolTable symbolTable,
740:                        Tokens tokens, String data, int currentOffset,
741:                        int endOffset) throws XNIException {
742:
743:                    int ch;
744:                    int nameOffset;
745:                    String nameHandle = null;
746:
747:                    while (true) {
748:                        if (currentOffset == endOffset) {
749:                            break;
750:                        }
751:
752:                        ch = data.charAt(currentOffset);
753:                        byte chartype = (ch >= 0x80) ? CHARTYPE_NONASCII
754:                                : fASCIICharMap[ch];
755:
756:                        // 
757:                        // [1]    ElementSchemeData    ::=    (NCName ChildSequence?) | ChildSequence  
758:                        // [2]    ChildSequence    ::=    ('/' [1-9] [0-9]*)+ 
759:                        //  
760:
761:                        switch (chartype) {
762:
763:                        case CHARTYPE_SLASH:
764:                            // if last character is '/', break and report an error
765:                            if (++currentOffset == endOffset) {
766:                                return false;
767:                            }
768:
769:                            addToken(tokens, Tokens.XPTRTOKEN_ELEM_CHILD);
770:                            ch = data.charAt(currentOffset);
771:
772:                            // ChildSequence    ::=    ('/' [1-9] [0-9]*)+                    
773:                            int child = 0;
774:                            while (ch >= '0' && ch <= '9') {
775:                                child = (child * 10) + (ch - '0');
776:                                if (++currentOffset == endOffset) {
777:                                    break;
778:                                }
779:                                ch = data.charAt(currentOffset);
780:                            }
781:
782:                            // An invalid child sequence character
783:                            if (child == 0) {
784:                                reportError(
785:                                        "InvalidChildSequenceCharacter",
786:                                        new Object[] { new Character((char) ch) });
787:                                return false;
788:                            }
789:
790:                            tokens.addToken(child);
791:
792:                            break;
793:
794:                        case CHARTYPE_DIGIT:
795:                        case CHARTYPE_LETTER:
796:                        case CHARTYPE_MINUS:
797:                        case CHARTYPE_NONASCII:
798:                        case CHARTYPE_OTHER:
799:                        case CHARTYPE_PERIOD:
800:                        case CHARTYPE_UNDERSCORE:
801:                            // Scan the ShortHand Pointer NCName 
802:                            nameOffset = currentOffset;
803:                            currentOffset = scanNCName(data, endOffset,
804:                                    currentOffset);
805:
806:                            if (currentOffset == nameOffset) {
807:                                //return false;
808:                                reportError("InvalidNCNameInElementSchemeData",
809:                                        new Object[] { data });
810:                                return false;
811:                            }
812:
813:                            if (currentOffset < endOffset) {
814:                                ch = data.charAt(currentOffset);
815:                            } else {
816:                                ch = -1;
817:                            }
818:
819:                            nameHandle = symbolTable.addSymbol(data.substring(
820:                                    nameOffset, currentOffset));
821:                            addToken(tokens, Tokens.XPTRTOKEN_ELEM_NCNAME);
822:                            tokens.addToken(nameHandle);
823:
824:                            break;
825:                        }
826:                    }
827:                    return true;
828:                }
829:
830:                /** 
831:                 * Scans a NCName.  
832:                 * From Namespaces in XML 
833:                 * [5] NCName ::= (Letter | '_') (NCNameChar)*
834:                 * [6] NCNameChar ::= Letter | Digit | '.' | '-' | '_' | CombiningChar | Extender
835:                 * 
836:                 * @param data A String containing the XPointer expression
837:                 * @param endOffset The int XPointer expression length  
838:                 * @param currentOffset An int representing the current position of the XPointer expression pointer
839:                 */
840:                private int scanNCName(String data, int endOffset,
841:                        int currentOffset) {
842:                    int ch = data.charAt(currentOffset);
843:                    if (ch >= 0x80) {
844:                        if (!XMLChar.isNameStart(ch)) {
845:                            return currentOffset;
846:                        }
847:                    } else {
848:                        byte chartype = fASCIICharMap[ch];
849:                        if (chartype != CHARTYPE_LETTER
850:                                && chartype != CHARTYPE_UNDERSCORE) {
851:                            return currentOffset;
852:                        }
853:                    }
854:                    while (++currentOffset < endOffset) {
855:                        ch = data.charAt(currentOffset);
856:                        if (ch >= 0x80) {
857:                            if (!XMLChar.isName(ch)) {
858:                                break;
859:                            }
860:                        } else {
861:                            byte chartype = fASCIICharMap[ch];
862:                            if (chartype != CHARTYPE_LETTER
863:                                    && chartype != CHARTYPE_DIGIT
864:                                    && chartype != CHARTYPE_PERIOD
865:                                    && chartype != CHARTYPE_MINUS
866:                                    && chartype != CHARTYPE_UNDERSCORE) {
867:                                break;
868:                            }
869:                        }
870:                    }
871:                    return currentOffset;
872:                }
873:
874:                //
875:                // Protected methods
876:                //
877:
878:                /**
879:                 * This method adds the specified token to the token list. By
880:                 * default, this method allows all tokens. However, subclasses
881:                 * of the XPathExprScanner can override this method in order
882:                 * to disallow certain tokens from being used in the scanned
883:                 * XPath expression. This is a convenient way of allowing only
884:                 * a subset of XPath.
885:                 */
886:                protected void addToken(Tokens tokens, int token)
887:                        throws XNIException {
888:                    tokens.addToken(token);
889:                } // addToken(int)
890:
891:            } // class Scanner
892:
893:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.