KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * Copyright 1999-2002,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 /**
30  * The DTD validator. The validator implements a document
31  * filter: receiving document events from the scanner; validating
32  * the content and structure; augmenting the InfoSet, if applicable;
33  * and notifying the parser of the information resulting from the
34  * validation process.
35  * <p> Formerly, this component also handled DTD events and grammar construction.
36  * To facilitate the development of a meaningful DTD grammar caching/preparsing
37  * framework, this functionality has been moved into the XMLDTDLoader
38  * class. Therefore, this class no longer implements the DTDFilter
39  * or DTDContentModelFilter interfaces.
40  * <p>
41  * This component requires the following features and properties from the
42  * component manager that uses it:
43  * <ul>
44  * <li>http://xml.org/sax/features/namespaces</li>
45  * <li>http://xml.org/sax/features/validation</li>
46  * <li>http://apache.org/xml/features/validation/dynamic</li>
47  * <li>http://apache.org/xml/properties/internal/symbol-table</li>
48  * <li>http://apache.org/xml/properties/internal/error-reporter</li>
49  * <li>http://apache.org/xml/properties/internal/grammar-pool</li>
50  * <li>http://apache.org/xml/properties/internal/datatype-validator-factory</li>
51  * </ul>
52  *
53  * @xerces.internal
54  *
55  * @author Elena Litani, IBM
56  *
57  * @version $Id: XMLNSDTDValidator.java,v 1.9 2004/10/04 21:57:30 mrglavas Exp $
58  */

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

206
207     /** Handles end element. */
208     protected void endNamespaceScope(QName element, Augmentations augs, boolean isEmpty)
209         throws XNIException {
210
211         // bind element
212
String JavaDoc eprefix = element.prefix != null ? element.prefix : XMLSymbols.EMPTY_STRING;
213         element.uri = fNamespaceContext.getURI(eprefix);
214         if (element.uri != null) {
215             element.prefix = eprefix;
216         }
217
218         // call handlers
219
if (fDocumentHandler != null) {
220             if (!isEmpty) {
221                 fDocumentHandler.endElement(element, augs);
222             }
223         }
224
225         // pop context
226
fNamespaceContext.popContext();
227
228     } // endNamespaceScope(QName,boolean)
229

230 }
231
Popular Tags