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