Source Code Cross Referenced for XML11NSDocumentScannerImpl.java in  » XML » xerces-2_9_1 » org » apache » xerces » impl » 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.impl 
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:
018:        package org.apache.xerces.impl;
019:
020:        import java.io.IOException;
021:
022:        import org.apache.xerces.impl.dtd.XMLDTDValidatorFilter;
023:        import org.apache.xerces.impl.msg.XMLMessageFormatter;
024:        import org.apache.xerces.util.XMLAttributesImpl;
025:        import org.apache.xerces.util.XMLSymbols;
026:        import org.apache.xerces.xni.NamespaceContext;
027:        import org.apache.xerces.xni.QName;
028:        import org.apache.xerces.xni.XMLDocumentHandler;
029:        import org.apache.xerces.xni.XNIException;
030:        import org.apache.xerces.xni.parser.XMLComponentManager;
031:        import org.apache.xerces.xni.parser.XMLConfigurationException;
032:        import org.apache.xerces.xni.parser.XMLDocumentSource;
033:
034:        /**
035:         * The scanner acts as the source for the document
036:         * information which is communicated to the document handler.
037:         *
038:         * This class scans an XML document, checks if document has a DTD, and if
039:         * DTD is not found the scanner will remove the DTD Validator from the pipeline and perform
040:         * namespace binding.
041:         *
042:         * Note: This scanner should only be used when the namespace processing is on!
043:         *
044:         * <p>
045:         * This component requires the following features and properties from the
046:         * component manager that uses it:
047:         * <ul>
048:         *  <li>http://xml.org/sax/features/namespaces {true} -- if the value of this
049:         *      feature is set to false this scanner must not be used.</li>
050:         *  <li>http://xml.org/sax/features/validation</li>
051:         *  <li>http://apache.org/xml/features/nonvalidating/load-external-dtd</li>
052:         *  <li>http://apache.org/xml/features/scanner/notify-char-refs</li>
053:         *  <li>http://apache.org/xml/features/scanner/notify-builtin-refs</li>
054:         *  <li>http://apache.org/xml/properties/internal/symbol-table</li>
055:         *  <li>http://apache.org/xml/properties/internal/error-reporter</li>
056:         *  <li>http://apache.org/xml/properties/internal/entity-manager</li>
057:         *  <li>http://apache.org/xml/properties/internal/dtd-scanner</li>
058:         * </ul>
059:         * 
060:         * @xerces.internal
061:         *
062:         * @author Elena Litani, IBM
063:         * @author Michael Glavassevich, IBM
064:         * 
065:         * @version $Id: XML11NSDocumentScannerImpl.java 495747 2007-01-12 21:48:00Z mrglavas $
066:         */
067:        public class XML11NSDocumentScannerImpl extends
068:                XML11DocumentScannerImpl {
069:
070:            /** 
071:             * If is true, the dtd validator is no longer in the pipeline
072:             * and the scanner should bind namespaces 
073:             */
074:            protected boolean fBindNamespaces;
075:
076:            /** 
077:             * If validating parser, make sure we report an error in the
078:             *  scanner if DTD grammar is missing.
079:             */
080:            protected boolean fPerformValidation;
081:
082:            // private data
083:            //
084:
085:            /** DTD validator */
086:            private XMLDTDValidatorFilter fDTDValidator;
087:
088:            /** 
089:             * Saw spaces after element name or between attributes.
090:             * 
091:             * This is reserved for the case where scanning of a start element spans
092:             * several methods, as is the case when scanning the start of a root element 
093:             * where a DTD external subset may be read after scanning the element name.
094:             */
095:            private boolean fSawSpace;
096:
097:            /**
098:             * The scanner is responsible for removing DTD validator
099:             * from the pipeline if it is not needed.
100:             * 
101:             * @param validator the DTD validator from the pipeline
102:             */
103:            public void setDTDValidator(XMLDTDValidatorFilter validator) {
104:                fDTDValidator = validator;
105:            }
106:
107:            /**
108:             * Scans a start element. This method will handle the binding of
109:             * namespace information and notifying the handler of the start
110:             * of the element.
111:             * <p>
112:             * <pre>
113:             * [44] EmptyElemTag ::= '&lt;' Name (S Attribute)* S? '/>'
114:             * [40] STag ::= '&lt;' Name (S Attribute)* S? '>'
115:             * </pre>
116:             * <p>
117:             * <strong>Note:</strong> This method assumes that the leading
118:             * '&lt;' character has been consumed.
119:             * <p>
120:             * <strong>Note:</strong> This method uses the fElementQName and
121:             * fAttributes variables. The contents of these variables will be
122:             * destroyed. The caller should copy important information out of
123:             * these variables before calling this method.
124:             *
125:             * @return True if element is empty. (i.e. It matches
126:             *          production [44].
127:             */
128:            protected boolean scanStartElement() throws IOException,
129:                    XNIException {
130:                if (DEBUG_CONTENT_SCANNING)
131:                    System.out.println(">>> scanStartElementNS()");
132:
133:                // Note: namespace processing is on by default
134:                fEntityScanner.scanQName(fElementQName);
135:                // REVISIT - [Q] Why do we need this local variable? -- mrglavas
136:                String rawname = fElementQName.rawname;
137:                if (fBindNamespaces) {
138:                    fNamespaceContext.pushContext();
139:                    if (fScannerState == SCANNER_STATE_ROOT_ELEMENT) {
140:                        if (fPerformValidation) {
141:                            fErrorReporter.reportError(
142:                                    XMLMessageFormatter.XML_DOMAIN,
143:                                    "MSG_GRAMMAR_NOT_FOUND",
144:                                    new Object[] { rawname },
145:                                    XMLErrorReporter.SEVERITY_ERROR);
146:
147:                            if (fDoctypeName == null
148:                                    || !fDoctypeName.equals(rawname)) {
149:                                fErrorReporter.reportError(
150:                                        XMLMessageFormatter.XML_DOMAIN,
151:                                        "RootElementTypeMustMatchDoctypedecl",
152:                                        new Object[] { fDoctypeName, rawname },
153:                                        XMLErrorReporter.SEVERITY_ERROR);
154:                            }
155:                        }
156:                    }
157:                }
158:
159:                // push element stack
160:                fCurrentElement = fElementStack.pushElement(fElementQName);
161:
162:                // attributes
163:                boolean empty = false;
164:                fAttributes.removeAllAttributes();
165:                do {
166:                    // spaces
167:                    boolean sawSpace = fEntityScanner.skipSpaces();
168:
169:                    // end tag?
170:                    int c = fEntityScanner.peekChar();
171:                    if (c == '>') {
172:                        fEntityScanner.scanChar();
173:                        break;
174:                    } else if (c == '/') {
175:                        fEntityScanner.scanChar();
176:                        if (!fEntityScanner.skipChar('>')) {
177:                            reportFatalError("ElementUnterminated",
178:                                    new Object[] { rawname });
179:                        }
180:                        empty = true;
181:                        break;
182:                    } else if (!isValidNameStartChar(c) || !sawSpace) {
183:                        // Second chance. Check if this character is a high
184:                        // surrogate of a valid name start character.
185:                        if (!isValidNameStartHighSurrogate(c) || !sawSpace) {
186:                            reportFatalError("ElementUnterminated",
187:                                    new Object[] { rawname });
188:                        }
189:                    }
190:
191:                    // attributes
192:                    scanAttribute(fAttributes);
193:
194:                } while (true);
195:
196:                if (fBindNamespaces) {
197:                    // REVISIT: is it required? forbit xmlns prefix for element
198:                    if (fElementQName.prefix == XMLSymbols.PREFIX_XMLNS) {
199:                        fErrorReporter.reportError(
200:                                XMLMessageFormatter.XMLNS_DOMAIN,
201:                                "ElementXMLNSPrefix",
202:                                new Object[] { fElementQName.rawname },
203:                                XMLErrorReporter.SEVERITY_FATAL_ERROR);
204:                    }
205:
206:                    // bind the element
207:                    String prefix = fElementQName.prefix != null ? fElementQName.prefix
208:                            : XMLSymbols.EMPTY_STRING;
209:                    // assign uri to the element
210:                    fElementQName.uri = fNamespaceContext.getURI(prefix);
211:                    // make sure that object in the element stack is updated as well
212:                    fCurrentElement.uri = fElementQName.uri;
213:
214:                    if (fElementQName.prefix == null
215:                            && fElementQName.uri != null) {
216:                        fElementQName.prefix = XMLSymbols.EMPTY_STRING;
217:                        // making sure that the object in the element stack is updated too.
218:                        fCurrentElement.prefix = XMLSymbols.EMPTY_STRING;
219:                    }
220:                    if (fElementQName.prefix != null
221:                            && fElementQName.uri == null) {
222:                        fErrorReporter.reportError(
223:                                XMLMessageFormatter.XMLNS_DOMAIN,
224:                                "ElementPrefixUnbound", new Object[] {
225:                                        fElementQName.prefix,
226:                                        fElementQName.rawname },
227:                                XMLErrorReporter.SEVERITY_FATAL_ERROR);
228:                    }
229:
230:                    // bind attributes (xmlns are already bound bellow)
231:                    int length = fAttributes.getLength();
232:                    for (int i = 0; i < length; i++) {
233:                        fAttributes.getName(i, fAttributeQName);
234:
235:                        String aprefix = fAttributeQName.prefix != null ? fAttributeQName.prefix
236:                                : XMLSymbols.EMPTY_STRING;
237:                        String uri = fNamespaceContext.getURI(aprefix);
238:                        // REVISIT: try removing the first "if" and see if it is faster.
239:                        //
240:                        if (fAttributeQName.uri != null
241:                                && fAttributeQName.uri == uri) {
242:                            continue;
243:                        }
244:                        if (aprefix != XMLSymbols.EMPTY_STRING) {
245:                            fAttributeQName.uri = uri;
246:                            if (uri == null) {
247:                                fErrorReporter.reportError(
248:                                        XMLMessageFormatter.XMLNS_DOMAIN,
249:                                        "AttributePrefixUnbound", new Object[] {
250:                                                fElementQName.rawname,
251:                                                fAttributeQName.rawname,
252:                                                aprefix },
253:                                        XMLErrorReporter.SEVERITY_FATAL_ERROR);
254:                            }
255:                            fAttributes.setURI(i, uri);
256:                        }
257:                    }
258:
259:                    if (length > 1) {
260:                        QName name = fAttributes.checkDuplicatesNS();
261:                        if (name != null) {
262:                            if (name.uri != null) {
263:                                fErrorReporter.reportError(
264:                                        XMLMessageFormatter.XMLNS_DOMAIN,
265:                                        "AttributeNSNotUnique", new Object[] {
266:                                                fElementQName.rawname,
267:                                                name.localpart, name.uri },
268:                                        XMLErrorReporter.SEVERITY_FATAL_ERROR);
269:                            } else {
270:                                fErrorReporter.reportError(
271:                                        XMLMessageFormatter.XMLNS_DOMAIN,
272:                                        "AttributeNotUnique", new Object[] {
273:                                                fElementQName.rawname,
274:                                                name.rawname },
275:                                        XMLErrorReporter.SEVERITY_FATAL_ERROR);
276:                            }
277:                        }
278:                    }
279:                }
280:
281:                // call handler
282:                if (fDocumentHandler != null) {
283:                    if (empty) {
284:
285:                        //decrease the markup depth..
286:                        fMarkupDepth--;
287:
288:                        // check that this element was opened in the same entity
289:                        if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) {
290:                            reportFatalError("ElementEntityMismatch",
291:                                    new Object[] { fCurrentElement.rawname });
292:                        }
293:
294:                        fDocumentHandler.emptyElement(fElementQName,
295:                                fAttributes, null);
296:
297:                        if (fBindNamespaces) {
298:                            fNamespaceContext.popContext();
299:                        }
300:                        //pop the element off the stack..
301:                        fElementStack.popElement(fElementQName);
302:                    } else {
303:                        fDocumentHandler.startElement(fElementQName,
304:                                fAttributes, null);
305:                    }
306:                }
307:
308:                if (DEBUG_CONTENT_SCANNING)
309:                    System.out.println("<<< scanStartElement(): " + empty);
310:                return empty;
311:
312:            } // scanStartElement():boolean
313:
314:            /**
315:             * Scans the name of an element in a start or empty tag. 
316:             * 
317:             * @see #scanStartElement()
318:             */
319:            protected void scanStartElementName() throws IOException,
320:                    XNIException {
321:                // Note: namespace processing is on by default
322:                fEntityScanner.scanQName(fElementQName);
323:                // Must skip spaces here because the DTD scanner
324:                // would consume them at the end of the external subset.
325:                fSawSpace = fEntityScanner.skipSpaces();
326:            } // scanStartElementName()
327:
328:            /**
329:             * Scans the remainder of a start or empty tag after the element name.
330:             * 
331:             * @see #scanStartElement
332:             * @return True if element is empty.
333:             */
334:            protected boolean scanStartElementAfterName() throws IOException,
335:                    XNIException {
336:
337:                // REVISIT - [Q] Why do we need this local variable? -- mrglavas
338:                String rawname = fElementQName.rawname;
339:                if (fBindNamespaces) {
340:                    fNamespaceContext.pushContext();
341:                    if (fScannerState == SCANNER_STATE_ROOT_ELEMENT) {
342:                        if (fPerformValidation) {
343:                            fErrorReporter.reportError(
344:                                    XMLMessageFormatter.XML_DOMAIN,
345:                                    "MSG_GRAMMAR_NOT_FOUND",
346:                                    new Object[] { rawname },
347:                                    XMLErrorReporter.SEVERITY_ERROR);
348:
349:                            if (fDoctypeName == null
350:                                    || !fDoctypeName.equals(rawname)) {
351:                                fErrorReporter.reportError(
352:                                        XMLMessageFormatter.XML_DOMAIN,
353:                                        "RootElementTypeMustMatchDoctypedecl",
354:                                        new Object[] { fDoctypeName, rawname },
355:                                        XMLErrorReporter.SEVERITY_ERROR);
356:                            }
357:                        }
358:                    }
359:                }
360:
361:                // push element stack
362:                fCurrentElement = fElementStack.pushElement(fElementQName);
363:
364:                // attributes
365:                boolean empty = false;
366:                fAttributes.removeAllAttributes();
367:                do {
368:
369:                    // end tag?
370:                    int c = fEntityScanner.peekChar();
371:                    if (c == '>') {
372:                        fEntityScanner.scanChar();
373:                        break;
374:                    } else if (c == '/') {
375:                        fEntityScanner.scanChar();
376:                        if (!fEntityScanner.skipChar('>')) {
377:                            reportFatalError("ElementUnterminated",
378:                                    new Object[] { rawname });
379:                        }
380:                        empty = true;
381:                        break;
382:                    } else if (!isValidNameStartChar(c) || !fSawSpace) {
383:                        // Second chance. Check if this character is a high
384:                        // surrogate of a valid name start character.
385:                        if (!isValidNameStartHighSurrogate(c) || !fSawSpace) {
386:                            reportFatalError("ElementUnterminated",
387:                                    new Object[] { rawname });
388:                        }
389:                    }
390:
391:                    // attributes
392:                    scanAttribute(fAttributes);
393:
394:                    // spaces
395:                    fSawSpace = fEntityScanner.skipSpaces();
396:
397:                } while (true);
398:
399:                if (fBindNamespaces) {
400:                    // REVISIT: is it required? forbit xmlns prefix for element
401:                    if (fElementQName.prefix == XMLSymbols.PREFIX_XMLNS) {
402:                        fErrorReporter.reportError(
403:                                XMLMessageFormatter.XMLNS_DOMAIN,
404:                                "ElementXMLNSPrefix",
405:                                new Object[] { fElementQName.rawname },
406:                                XMLErrorReporter.SEVERITY_FATAL_ERROR);
407:                    }
408:
409:                    // bind the element
410:                    String prefix = fElementQName.prefix != null ? fElementQName.prefix
411:                            : XMLSymbols.EMPTY_STRING;
412:                    // assign uri to the element
413:                    fElementQName.uri = fNamespaceContext.getURI(prefix);
414:                    // make sure that object in the element stack is updated as well
415:                    fCurrentElement.uri = fElementQName.uri;
416:
417:                    if (fElementQName.prefix == null
418:                            && fElementQName.uri != null) {
419:                        fElementQName.prefix = XMLSymbols.EMPTY_STRING;
420:                        // making sure that the object in the element stack is updated too.
421:                        fCurrentElement.prefix = XMLSymbols.EMPTY_STRING;
422:                    }
423:                    if (fElementQName.prefix != null
424:                            && fElementQName.uri == null) {
425:                        fErrorReporter.reportError(
426:                                XMLMessageFormatter.XMLNS_DOMAIN,
427:                                "ElementPrefixUnbound", new Object[] {
428:                                        fElementQName.prefix,
429:                                        fElementQName.rawname },
430:                                XMLErrorReporter.SEVERITY_FATAL_ERROR);
431:                    }
432:
433:                    // bind attributes (xmlns are already bound bellow)
434:                    int length = fAttributes.getLength();
435:                    for (int i = 0; i < length; i++) {
436:                        fAttributes.getName(i, fAttributeQName);
437:
438:                        String aprefix = fAttributeQName.prefix != null ? fAttributeQName.prefix
439:                                : XMLSymbols.EMPTY_STRING;
440:                        String uri = fNamespaceContext.getURI(aprefix);
441:                        // REVISIT: try removing the first "if" and see if it is faster.
442:                        //
443:                        if (fAttributeQName.uri != null
444:                                && fAttributeQName.uri == uri) {
445:                            continue;
446:                        }
447:                        if (aprefix != XMLSymbols.EMPTY_STRING) {
448:                            fAttributeQName.uri = uri;
449:                            if (uri == null) {
450:                                fErrorReporter.reportError(
451:                                        XMLMessageFormatter.XMLNS_DOMAIN,
452:                                        "AttributePrefixUnbound", new Object[] {
453:                                                fElementQName.rawname,
454:                                                fAttributeQName.rawname,
455:                                                aprefix },
456:                                        XMLErrorReporter.SEVERITY_FATAL_ERROR);
457:                            }
458:                            fAttributes.setURI(i, uri);
459:                        }
460:                    }
461:
462:                    if (length > 1) {
463:                        QName name = fAttributes.checkDuplicatesNS();
464:                        if (name != null) {
465:                            if (name.uri != null) {
466:                                fErrorReporter.reportError(
467:                                        XMLMessageFormatter.XMLNS_DOMAIN,
468:                                        "AttributeNSNotUnique", new Object[] {
469:                                                fElementQName.rawname,
470:                                                name.localpart, name.uri },
471:                                        XMLErrorReporter.SEVERITY_FATAL_ERROR);
472:                            } else {
473:                                fErrorReporter.reportError(
474:                                        XMLMessageFormatter.XMLNS_DOMAIN,
475:                                        "AttributeNotUnique", new Object[] {
476:                                                fElementQName.rawname,
477:                                                name.rawname },
478:                                        XMLErrorReporter.SEVERITY_FATAL_ERROR);
479:                            }
480:                        }
481:                    }
482:                }
483:
484:                // call handler
485:                if (fDocumentHandler != null) {
486:                    if (empty) {
487:
488:                        //decrease the markup depth..
489:                        fMarkupDepth--;
490:
491:                        // check that this element was opened in the same entity
492:                        if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) {
493:                            reportFatalError("ElementEntityMismatch",
494:                                    new Object[] { fCurrentElement.rawname });
495:                        }
496:
497:                        fDocumentHandler.emptyElement(fElementQName,
498:                                fAttributes, null);
499:
500:                        if (fBindNamespaces) {
501:                            fNamespaceContext.popContext();
502:                        }
503:                        //pop the element off the stack..
504:                        fElementStack.popElement(fElementQName);
505:                    } else {
506:                        fDocumentHandler.startElement(fElementQName,
507:                                fAttributes, null);
508:                    }
509:                }
510:
511:                if (DEBUG_CONTENT_SCANNING)
512:                    System.out.println("<<< scanStartElementAfterName(): "
513:                            + empty);
514:                return empty;
515:
516:            } // scanStartElementAfterName()
517:
518:            /**
519:             * Scans an attribute.
520:             * <p>
521:             * <pre>
522:             * [41] Attribute ::= Name Eq AttValue
523:             * </pre>
524:             * <p>
525:             * <strong>Note:</strong> This method assumes that the next
526:             * character on the stream is the first character of the attribute
527:             * name.
528:             * <p>
529:             * <strong>Note:</strong> This method uses the fAttributeQName and
530:             * fQName variables. The contents of these variables will be
531:             * destroyed.
532:             *
533:             * @param attributes The attributes list for the scanned attribute.
534:             */
535:            protected void scanAttribute(XMLAttributesImpl attributes)
536:                    throws IOException, XNIException {
537:                if (DEBUG_CONTENT_SCANNING)
538:                    System.out.println(">>> scanAttribute()");
539:
540:                // name
541:                fEntityScanner.scanQName(fAttributeQName);
542:
543:                // equals
544:                fEntityScanner.skipSpaces();
545:                if (!fEntityScanner.skipChar('=')) {
546:                    reportFatalError("EqRequiredInAttribute", new Object[] {
547:                            fCurrentElement.rawname, fAttributeQName.rawname });
548:                }
549:                fEntityScanner.skipSpaces();
550:
551:                // content
552:                int attrIndex;
553:
554:                if (fBindNamespaces) {
555:                    attrIndex = attributes.getLength();
556:                    attributes.addAttributeNS(fAttributeQName,
557:                            XMLSymbols.fCDATASymbol, null);
558:                } else {
559:                    int oldLen = attributes.getLength();
560:                    attrIndex = attributes.addAttribute(fAttributeQName,
561:                            XMLSymbols.fCDATASymbol, null);
562:
563:                    // WFC: Unique Att Spec
564:                    if (oldLen == attributes.getLength()) {
565:                        reportFatalError("AttributeNotUnique", new Object[] {
566:                                fCurrentElement.rawname,
567:                                fAttributeQName.rawname });
568:                    }
569:                }
570:
571:                // Scan attribute value and return true if the non-normalized and normalized value are the same
572:                boolean isSameNormalizedAttr = scanAttributeValue(
573:                        this .fTempString, fTempString2,
574:                        fAttributeQName.rawname, fIsEntityDeclaredVC,
575:                        fCurrentElement.rawname);
576:
577:                String value = fTempString.toString();
578:                attributes.setValue(attrIndex, value);
579:                // If the non-normalized and normalized value are the same, avoid creating a new string.
580:                if (!isSameNormalizedAttr) {
581:                    attributes.setNonNormalizedValue(attrIndex, fTempString2
582:                            .toString());
583:                }
584:                attributes.setSpecified(attrIndex, true);
585:
586:                // record namespace declarations if any.
587:                if (fBindNamespaces) {
588:
589:                    String localpart = fAttributeQName.localpart;
590:                    String prefix = fAttributeQName.prefix != null ? fAttributeQName.prefix
591:                            : XMLSymbols.EMPTY_STRING;
592:                    // when it's of form xmlns="..." or xmlns:prefix="...",
593:                    // it's a namespace declaration. but prefix:xmlns="..." isn't.
594:                    if (prefix == XMLSymbols.PREFIX_XMLNS
595:                            || prefix == XMLSymbols.EMPTY_STRING
596:                            && localpart == XMLSymbols.PREFIX_XMLNS) {
597:
598:                        // get the internalized value of this attribute
599:                        String uri = fSymbolTable.addSymbol(value);
600:
601:                        // 1. "xmlns" can't be bound to any namespace
602:                        if (prefix == XMLSymbols.PREFIX_XMLNS
603:                                && localpart == XMLSymbols.PREFIX_XMLNS) {
604:                            fErrorReporter.reportError(
605:                                    XMLMessageFormatter.XMLNS_DOMAIN,
606:                                    "CantBindXMLNS",
607:                                    new Object[] { fAttributeQName },
608:                                    XMLErrorReporter.SEVERITY_FATAL_ERROR);
609:                        }
610:
611:                        // 2. the namespace for "xmlns" can't be bound to any prefix
612:                        if (uri == NamespaceContext.XMLNS_URI) {
613:                            fErrorReporter.reportError(
614:                                    XMLMessageFormatter.XMLNS_DOMAIN,
615:                                    "CantBindXMLNS",
616:                                    new Object[] { fAttributeQName },
617:                                    XMLErrorReporter.SEVERITY_FATAL_ERROR);
618:                        }
619:
620:                        // 3. "xml" can't be bound to any other namespace than it's own
621:                        if (localpart == XMLSymbols.PREFIX_XML) {
622:                            if (uri != NamespaceContext.XML_URI) {
623:                                fErrorReporter.reportError(
624:                                        XMLMessageFormatter.XMLNS_DOMAIN,
625:                                        "CantBindXML",
626:                                        new Object[] { fAttributeQName },
627:                                        XMLErrorReporter.SEVERITY_FATAL_ERROR);
628:                            }
629:                        }
630:                        // 4. the namespace for "xml" can't be bound to any other prefix
631:                        else {
632:                            if (uri == NamespaceContext.XML_URI) {
633:                                fErrorReporter.reportError(
634:                                        XMLMessageFormatter.XMLNS_DOMAIN,
635:                                        "CantBindXML",
636:                                        new Object[] { fAttributeQName },
637:                                        XMLErrorReporter.SEVERITY_FATAL_ERROR);
638:                            }
639:                        }
640:
641:                        prefix = localpart != XMLSymbols.PREFIX_XMLNS ? localpart
642:                                : XMLSymbols.EMPTY_STRING;
643:
644:                        // Declare prefix in context. Removing the association between a prefix and a 
645:                        // namespace name is permitted in XML 1.1, so if the uri value is the empty string, 
646:                        // the prefix is being unbound. -- mrglavas
647:                        fNamespaceContext.declarePrefix(prefix,
648:                                uri.length() != 0 ? uri : null);
649:                        // bind namespace attribute to a namespace
650:                        attributes.setURI(attrIndex, fNamespaceContext
651:                                .getURI(XMLSymbols.PREFIX_XMLNS));
652:
653:                    } else {
654:                        // attempt to bind attribute
655:                        if (fAttributeQName.prefix != null) {
656:                            attributes.setURI(attrIndex, fNamespaceContext
657:                                    .getURI(fAttributeQName.prefix));
658:                        }
659:                    }
660:                }
661:
662:                if (DEBUG_CONTENT_SCANNING)
663:                    System.out.println("<<< scanAttribute()");
664:            } // scanAttribute(XMLAttributes)
665:
666:            /**
667:             * Scans an end element.
668:             * <p>
669:             * <pre>
670:             * [42] ETag ::= '&lt;/' Name S? '>'
671:             * </pre>
672:             * <p>
673:             * <strong>Note:</strong> This method uses the fElementQName variable.
674:             * The contents of this variable will be destroyed. The caller should
675:             * copy the needed information out of this variable before calling
676:             * this method.
677:             *
678:             * @return The element depth.
679:             */
680:            protected int scanEndElement() throws IOException, XNIException {
681:                if (DEBUG_CONTENT_SCANNING)
682:                    System.out.println(">>> scanEndElement()");
683:
684:                // pop context
685:                fElementStack.popElement(fElementQName);
686:
687:                // Take advantage of the fact that next string _should_ be "fElementQName.rawName",
688:                //In scanners most of the time is consumed on checks done for XML characters, we can
689:                // optimize on it and avoid the checks done for endElement,
690:                //we will also avoid symbol table lookup - neeraj.bajaj@sun.com
691:
692:                // this should work both for namespace processing true or false...
693:
694:                //REVISIT: if the string is not the same as expected.. we need to do better error handling..
695:                //We can skip this for now... In any case if the string doesn't match -- document is not well formed.
696:                if (!fEntityScanner.skipString(fElementQName.rawname)) {
697:                    reportFatalError("ETagRequired",
698:                            new Object[] { fElementQName.rawname });
699:                }
700:
701:                // end
702:                fEntityScanner.skipSpaces();
703:                if (!fEntityScanner.skipChar('>')) {
704:                    reportFatalError("ETagUnterminated",
705:                            new Object[] { fElementQName.rawname });
706:                }
707:                fMarkupDepth--;
708:
709:                //we have increased the depth for two markup "<" characters
710:                fMarkupDepth--;
711:
712:                // check that this element was opened in the same entity
713:                if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) {
714:                    reportFatalError("ElementEntityMismatch",
715:                            new Object[] { fCurrentElement.rawname });
716:                }
717:
718:                // call handler
719:                if (fDocumentHandler != null) {
720:
721:                    fDocumentHandler.endElement(fElementQName, null);
722:                    if (fBindNamespaces) {
723:                        fNamespaceContext.popContext();
724:                    }
725:
726:                }
727:
728:                return fMarkupDepth;
729:
730:            } // scanEndElement():int
731:
732:            public void reset(XMLComponentManager componentManager)
733:                    throws XMLConfigurationException {
734:
735:                super .reset(componentManager);
736:                fPerformValidation = false;
737:                fBindNamespaces = false;
738:            }
739:
740:            /** Creates a content dispatcher. */
741:            protected Dispatcher createContentDispatcher() {
742:                return new NS11ContentDispatcher();
743:            } // createContentDispatcher():Dispatcher
744:
745:            /**
746:             * Dispatcher to handle content scanning.
747:             */
748:            protected final class NS11ContentDispatcher extends
749:                    ContentDispatcher {
750:                /**
751:                 * Scan for root element hook. This method is a hook for
752:                 * subclasses to add code that handles scanning for the root
753:                 * element. This method will also attempt to remove DTD validator
754:                 * from the pipeline, if there is no DTD grammar. If DTD validator
755:                 * is no longer in the pipeline bind namespaces in the scanner.
756:                 *
757:                 *
758:                 * @return True if the caller should stop and return true which
759:                 *          allows the scanner to switch to a new scanning
760:                 *          dispatcher. A return value of false indicates that
761:                 *          the content dispatcher should continue as normal.
762:                 */
763:                protected boolean scanRootElementHook() throws IOException,
764:                        XNIException {
765:
766:                    if (fExternalSubsetResolver != null && !fSeenDoctypeDecl
767:                            && !fDisallowDoctype
768:                            && (fValidation || fLoadExternalDTD)) {
769:                        scanStartElementName();
770:                        resolveExternalSubsetAndRead();
771:                        reconfigurePipeline();
772:                        if (scanStartElementAfterName()) {
773:                            setScannerState(SCANNER_STATE_TRAILING_MISC);
774:                            setDispatcher(fTrailingMiscDispatcher);
775:                            return true;
776:                        }
777:                    } else {
778:                        reconfigurePipeline();
779:                        if (scanStartElement()) {
780:                            setScannerState(SCANNER_STATE_TRAILING_MISC);
781:                            setDispatcher(fTrailingMiscDispatcher);
782:                            return true;
783:                        }
784:                    }
785:                    return false;
786:
787:                } // scanRootElementHook():boolean
788:
789:                /**
790:                 * Re-configures pipeline by removing the DTD validator 
791:                 * if no DTD grammar exists. If no validator exists in the
792:                 * pipeline or there is no DTD grammar, namespace binding
793:                 * is performed by the scanner in the enclosing class.
794:                 */
795:                private void reconfigurePipeline() {
796:                    if (fDTDValidator == null) {
797:                        fBindNamespaces = true;
798:                    } else if (!fDTDValidator.hasGrammar()) {
799:                        fBindNamespaces = true;
800:                        fPerformValidation = fDTDValidator.validate();
801:                        // re-configure pipeline
802:                        XMLDocumentSource source = fDTDValidator
803:                                .getDocumentSource();
804:                        XMLDocumentHandler handler = fDTDValidator
805:                                .getDocumentHandler();
806:                        source.setDocumentHandler(handler);
807:                        if (handler != null)
808:                            handler.setDocumentSource(source);
809:                        fDTDValidator.setDocumentSource(null);
810:                        fDTDValidator.setDocumentHandler(null);
811:                    }
812:                } // reconfigurePipeline()
813:            }
814:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.