KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xerces > impl > dtd > XML11NSDTDValidator


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.xerces.impl.dtd;
18
19 import org.apache.xerces.impl.XMLErrorReporter;
20 import org.apache.xerces.impl.msg.XMLMessageFormatter;
21 import org.apache.xerces.util.XMLSymbols;
22 import org.apache.xerces.xni.Augmentations;
23 import org.apache.xerces.xni.NamespaceContext;
24 import org.apache.xerces.xni.QName;
25 import org.apache.xerces.xni.XMLAttributes;
26 import org.apache.xerces.xni.XNIException;
27
28 /**
29  * The DTD validator. The validator implements a document
30  * filter: receiving document events from the scanner; validating
31  * the content and structure; augmenting the InfoSet, if applicable;
32  * and notifying the parser of the information resulting from the
33  * validation process.
34  * <p> Formerly, this component also handled DTD events and grammar construction.
35  * To facilitate the development of a meaningful DTD grammar caching/preparsing
36  * framework, this functionality has been moved into the XMLDTDLoader
37  * class. Therefore, this class no longer implements the DTDFilter
38  * or DTDContentModelFilter interfaces.
39  * <p>
40  * This component requires the following features and properties from the
41  * component manager that uses it:
42  * <ul>
43  * <li>http://xml.org/sax/features/namespaces</li>
44  * <li>http://xml.org/sax/features/validation</li>
45  * <li>http://apache.org/xml/features/validation/dynamic</li>
46  * <li>http://apache.org/xml/properties/internal/symbol-table</li>
47  * <li>http://apache.org/xml/properties/internal/error-reporter</li>
48  * <li>http://apache.org/xml/properties/internal/grammar-pool</li>
49  * <li>http://apache.org/xml/properties/internal/datatype-validator-factory</li>
50  * </ul>
51  *
52  * @xerces.internal
53  *
54  * @author Elena Litani, IBM
55  * @author Michael Glavassevich, IBM
56  *
57  * @version $Id: XML11NSDTDValidator.java,v 1.4 2004/10/04 21:57:30 mrglavas Exp $
58  */

59 public class XML11NSDTDValidator extends XML11DTDValidator {
60
61     /** Attribute QName. */
62     private QName fAttributeQName = new QName();
63
64     /** Bind namespaces */
65     protected final void startNamespaceScope(QName element, XMLAttributes attributes, Augmentations augs)
66         throws XNIException {
67
68         // add new namespace context
69
fNamespaceContext.pushContext();
70
71         if (element.prefix == XMLSymbols.PREFIX_XMLNS) {
72             fErrorReporter.reportError(
73                 XMLMessageFormatter.XMLNS_DOMAIN,
74                 "ElementXMLNSPrefix",
75                 new Object JavaDoc[] { element.rawname },
76                 XMLErrorReporter.SEVERITY_FATAL_ERROR);
77         }
78
79         // search for new namespace bindings
80
int length = attributes.getLength();
81         for (int i = 0; i < length; i++) {
82             String JavaDoc localpart = attributes.getLocalName(i);
83             String JavaDoc prefix = attributes.getPrefix(i);
84             // when it's of form xmlns="..." or xmlns:prefix="...",
85
// it's a namespace declaration. but prefix:xmlns="..." isn't.
86
if (prefix == XMLSymbols.PREFIX_XMLNS || prefix == XMLSymbols.EMPTY_STRING
87                 && localpart == XMLSymbols.PREFIX_XMLNS) {
88
89                 // get the internalized value of this attribute
90
String JavaDoc uri = fSymbolTable.addSymbol(attributes.getValue(i));
91
92                 // 1. "xmlns" can't be bound to any namespace
93
if (prefix == XMLSymbols.PREFIX_XMLNS && localpart == XMLSymbols.PREFIX_XMLNS) {
94                     fErrorReporter.reportError(
95                         XMLMessageFormatter.XMLNS_DOMAIN,
96                         "CantBindXMLNS",
97                         new Object JavaDoc[] { attributes.getQName(i)},
98                         XMLErrorReporter.SEVERITY_FATAL_ERROR);
99                 }
100
101                 // 2. the namespace for "xmlns" can't be bound to any prefix
102
if (uri == NamespaceContext.XMLNS_URI) {
103                     fErrorReporter.reportError(
104                         XMLMessageFormatter.XMLNS_DOMAIN,
105                         "CantBindXMLNS",
106                         new Object JavaDoc[] { attributes.getQName(i)},
107                         XMLErrorReporter.SEVERITY_FATAL_ERROR);
108                 }
109
110                 // 3. "xml" can't be bound to any other namespace than it's own
111
if (localpart == XMLSymbols.PREFIX_XML) {
112                     if (uri != NamespaceContext.XML_URI) {
113                         fErrorReporter.reportError(
114                             XMLMessageFormatter.XMLNS_DOMAIN,
115                             "CantBindXML",
116                             new Object JavaDoc[] { attributes.getQName(i)},
117                             XMLErrorReporter.SEVERITY_FATAL_ERROR);
118                     }
119                 }
120                 // 4. the namespace for "xml" can't be bound to any other prefix
121
else {
122                     if (uri == NamespaceContext.XML_URI) {
123                         fErrorReporter.reportError(
124                             XMLMessageFormatter.XMLNS_DOMAIN,
125                             "CantBindXML",
126                             new Object JavaDoc[] { attributes.getQName(i)},
127                             XMLErrorReporter.SEVERITY_FATAL_ERROR);
128                     }
129                 }
130
131                 prefix = localpart != XMLSymbols.PREFIX_XMLNS ? localpart : XMLSymbols.EMPTY_STRING;
132
133                 // Declare prefix in context. Removing the association between a prefix and a
134
// namespace name is permitted in XML 1.1, so if the uri value is the empty string,
135
// the prefix is being unbound. -- mrglavas
136
fNamespaceContext.declarePrefix(prefix, uri.length() != 0 ? uri : null);
137             }
138         }
139
140         // bind the element
141
String JavaDoc prefix = element.prefix != null ? element.prefix : XMLSymbols.EMPTY_STRING;
142         element.uri = fNamespaceContext.getURI(prefix);
143         if (element.prefix == null && element.uri != null) {
144             element.prefix = XMLSymbols.EMPTY_STRING;
145         }
146         if (element.prefix != null && element.uri == null) {
147             fErrorReporter.reportError(
148                 XMLMessageFormatter.XMLNS_DOMAIN,
149                 "ElementPrefixUnbound",
150                 new Object JavaDoc[] { element.prefix, element.rawname },
151                 XMLErrorReporter.SEVERITY_FATAL_ERROR);
152         }
153
154         // bind the attributes
155
for (int i = 0; i < length; i++) {
156             attributes.getName(i, fAttributeQName);
157             String JavaDoc aprefix = fAttributeQName.prefix != null ? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING;
158             String JavaDoc arawname = fAttributeQName.rawname;
159             if (arawname == XMLSymbols.PREFIX_XMLNS) {
160                 fAttributeQName.uri = fNamespaceContext.getURI(XMLSymbols.PREFIX_XMLNS);
161                 attributes.setName(i, fAttributeQName);
162             } else if (aprefix != XMLSymbols.EMPTY_STRING) {
163                 fAttributeQName.uri = fNamespaceContext.getURI(aprefix);
164                 if (fAttributeQName.uri == null) {
165                     fErrorReporter.reportError(
166                         XMLMessageFormatter.XMLNS_DOMAIN,
167                         "AttributePrefixUnbound",
168                         new Object JavaDoc[] { element.rawname, arawname, aprefix },
169                         XMLErrorReporter.SEVERITY_FATAL_ERROR);
170                 }
171                 attributes.setName(i, fAttributeQName);
172             }
173         }
174
175         // verify that duplicate attributes don't exist
176
// Example: <foo xmlns:a='NS' xmlns:b='NS' a:attr='v1' b:attr='v2'/>
177
int attrCount = attributes.getLength();
178         for (int i = 0; i < attrCount - 1; i++) {
179             String JavaDoc auri = attributes.getURI(i);
180             if (auri == null || auri == NamespaceContext.XMLNS_URI) {
181                 continue;
182             }
183             String JavaDoc alocalpart = attributes.getLocalName(i);
184             for (int j = i + 1; j < attrCount; j++) {
185                 String JavaDoc blocalpart = attributes.getLocalName(j);
186                 String JavaDoc buri = attributes.getURI(j);
187                 if (alocalpart == blocalpart && auri == buri) {
188                     fErrorReporter.reportError(
189                         XMLMessageFormatter.XMLNS_DOMAIN,
190                         "AttributeNSNotUnique",
191                         new Object JavaDoc[] { element.rawname, alocalpart, auri },
192                         XMLErrorReporter.SEVERITY_FATAL_ERROR);
193                 }
194             }
195         }
196
197     } // startNamespaceScope(QName,XMLAttributes)
198

199     /** Handles end element. */
200     protected void endNamespaceScope(QName element, Augmentations augs, boolean isEmpty)
201         throws XNIException {
202
203         // bind element
204
String JavaDoc eprefix = element.prefix != null ? element.prefix : XMLSymbols.EMPTY_STRING;
205         element.uri = fNamespaceContext.getURI(eprefix);
206         if (element.uri != null) {
207             element.prefix = eprefix;
208         }
209
210         // call handlers
211
if (fDocumentHandler != null) {
212             if (!isEmpty) {
213                 fDocumentHandler.endElement(element, augs);
214             }
215         }
216
217         // pop context
218
fNamespaceContext.popContext();
219
220     } // endNamespaceScope(QName,boolean)
221
}
222
Popular Tags