KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xerces > internal > impl > dtd > XML11NSDTDValidator


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999-2003 The Apache Software Foundation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 2002, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package com.sun.org.apache.xerces.internal.impl.dtd;
59
60 import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
61 import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
62 import com.sun.org.apache.xerces.internal.util.XMLSymbols;
63 import com.sun.org.apache.xerces.internal.xni.Augmentations;
64 import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
65 import com.sun.org.apache.xerces.internal.xni.QName;
66 import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
67 import com.sun.org.apache.xerces.internal.xni.XNIException;
68
69 /**
70  * The DTD validator. The validator implements a document
71  * filter: receiving document events from the scanner; validating
72  * the content and structure; augmenting the InfoSet, if applicable;
73  * and notifying the parser of the information resulting from the
74  * validation process.
75  * <p> Formerly, this component also handled DTD events and grammar construction.
76  * To facilitate the development of a meaningful DTD grammar caching/preparsing
77  * framework, this functionality has been moved into the XMLDTDLoader
78  * class. Therefore, this class no longer implements the DTDFilter
79  * or DTDContentModelFilter interfaces.
80  * <p>
81  * This component requires the following features and properties from the
82  * component manager that uses it:
83  * <ul>
84  * <li>http://xml.org/sax/features/namespaces</li>
85  * <li>http://xml.org/sax/features/validation</li>
86  * <li>http://apache.org/xml/features/validation/dynamic</li>
87  * <li>http://apache.org/xml/properties/internal/symbol-table</li>
88  * <li>http://apache.org/xml/properties/internal/error-reporter</li>
89  * <li>http://apache.org/xml/properties/internal/grammar-pool</li>
90  * <li>http://apache.org/xml/properties/internal/datatype-validator-factory</li>
91  * </ul>
92  *
93  * @author Elena Litani, IBM
94  * @author Michael Glavassevich, IBM
95  *
96  * @version $Id: XML11NSDTDValidator.java,v 1.2 2003/10/10 18:25:40 mrglavas Exp $
97  */

98 public class XML11NSDTDValidator extends XML11DTDValidator {
99
100     /** Attribute QName. */
101     private QName fAttributeQName = new QName();
102
103     /** Bind namespaces */
104     protected final void startNamespaceScope(QName element, XMLAttributes attributes, Augmentations augs)
105         throws XNIException {
106
107         // add new namespace context
108
fNamespaceContext.pushContext();
109
110         if (element.prefix == XMLSymbols.PREFIX_XMLNS) {
111             fErrorReporter.reportError(
112                 XMLMessageFormatter.XMLNS_DOMAIN,
113                 "ElementXMLNSPrefix",
114                 new Object JavaDoc[] { element.rawname },
115                 XMLErrorReporter.SEVERITY_FATAL_ERROR);
116         }
117
118         // search for new namespace bindings
119
int length = attributes.getLength();
120         for (int i = 0; i < length; i++) {
121             String JavaDoc localpart = attributes.getLocalName(i);
122             String JavaDoc prefix = attributes.getPrefix(i);
123             // when it's of form xmlns="..." or xmlns:prefix="...",
124
// it's a namespace declaration. but prefix:xmlns="..." isn't.
125
if (prefix == XMLSymbols.PREFIX_XMLNS || prefix == XMLSymbols.EMPTY_STRING
126                 && localpart == XMLSymbols.PREFIX_XMLNS) {
127
128                 // get the internalized value of this attribute
129
String JavaDoc uri = fSymbolTable.addSymbol(attributes.getValue(i));
130
131                 // 1. "xmlns" can't be bound to any namespace
132
if (prefix == XMLSymbols.PREFIX_XMLNS && localpart == XMLSymbols.PREFIX_XMLNS) {
133                     fErrorReporter.reportError(
134                         XMLMessageFormatter.XMLNS_DOMAIN,
135                         "CantBindXMLNS",
136                         new Object JavaDoc[] { attributes.getQName(i)},
137                         XMLErrorReporter.SEVERITY_FATAL_ERROR);
138                 }
139
140                 // 2. the namespace for "xmlns" can't be bound to any prefix
141
if (uri == NamespaceContext.XMLNS_URI) {
142                     fErrorReporter.reportError(
143                         XMLMessageFormatter.XMLNS_DOMAIN,
144                         "CantBindXMLNS",
145                         new Object JavaDoc[] { attributes.getQName(i)},
146                         XMLErrorReporter.SEVERITY_FATAL_ERROR);
147                 }
148
149                 // 3. "xml" can't be bound to any other namespace than it's own
150
if (localpart == XMLSymbols.PREFIX_XML) {
151                     if (uri != NamespaceContext.XML_URI) {
152                         fErrorReporter.reportError(
153                             XMLMessageFormatter.XMLNS_DOMAIN,
154                             "CantBindXML",
155                             new Object JavaDoc[] { attributes.getQName(i)},
156                             XMLErrorReporter.SEVERITY_FATAL_ERROR);
157                     }
158                 }
159                 // 4. the namespace for "xml" can't be bound to any other prefix
160
else {
161                     if (uri == NamespaceContext.XML_URI) {
162                         fErrorReporter.reportError(
163                             XMLMessageFormatter.XMLNS_DOMAIN,
164                             "CantBindXML",
165                             new Object JavaDoc[] { attributes.getQName(i)},
166                             XMLErrorReporter.SEVERITY_FATAL_ERROR);
167                     }
168                 }
169
170                 prefix = localpart != XMLSymbols.PREFIX_XMLNS ? localpart : XMLSymbols.EMPTY_STRING;
171
172                 // Declare prefix in context. Removing the association between a prefix and a
173
// namespace name is permitted in XML 1.1, so if the uri value is the empty string,
174
// the prefix is being unbound. -- mrglavas
175
fNamespaceContext.declarePrefix(prefix, uri.length() != 0 ? uri : null);
176             }
177         }
178
179         // bind the element
180
String JavaDoc prefix = element.prefix != null ? element.prefix : XMLSymbols.EMPTY_STRING;
181         element.uri = fNamespaceContext.getURI(prefix);
182         if (element.prefix == null && element.uri != null) {
183             element.prefix = XMLSymbols.EMPTY_STRING;
184         }
185         if (element.prefix != null && element.uri == null) {
186             fErrorReporter.reportError(
187                 XMLMessageFormatter.XMLNS_DOMAIN,
188                 "ElementPrefixUnbound",
189                 new Object JavaDoc[] { element.prefix, element.rawname },
190                 XMLErrorReporter.SEVERITY_FATAL_ERROR);
191         }
192
193         // bind the attributes
194
for (int i = 0; i < length; i++) {
195             attributes.getName(i, fAttributeQName);
196             String JavaDoc aprefix = fAttributeQName.prefix != null ? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING;
197             String JavaDoc arawname = fAttributeQName.rawname;
198             if (arawname == XMLSymbols.PREFIX_XMLNS) {
199                 fAttributeQName.uri = fNamespaceContext.getURI(XMLSymbols.PREFIX_XMLNS);
200                 attributes.setName(i, fAttributeQName);
201             } else if (aprefix != XMLSymbols.EMPTY_STRING) {
202                 fAttributeQName.uri = fNamespaceContext.getURI(aprefix);
203                 if (fAttributeQName.uri == null) {
204                     fErrorReporter.reportError(
205                         XMLMessageFormatter.XMLNS_DOMAIN,
206                         "AttributePrefixUnbound",
207                         new Object JavaDoc[] { element.rawname, arawname, aprefix },
208                         XMLErrorReporter.SEVERITY_FATAL_ERROR);
209                 }
210                 attributes.setName(i, fAttributeQName);
211             }
212         }
213
214         // verify that duplicate attributes don't exist
215
// Example: <foo xmlns:a='NS' xmlns:b='NS' a:attr='v1' b:attr='v2'/>
216
int attrCount = attributes.getLength();
217         for (int i = 0; i < attrCount - 1; i++) {
218             String JavaDoc auri = attributes.getURI(i);
219             if (auri == null || auri == NamespaceContext.XMLNS_URI) {
220                 continue;
221             }
222             String JavaDoc alocalpart = attributes.getLocalName(i);
223             for (int j = i + 1; j < attrCount; j++) {
224                 String JavaDoc blocalpart = attributes.getLocalName(j);
225                 String JavaDoc buri = attributes.getURI(j);
226                 if (alocalpart == blocalpart && auri == buri) {
227                     fErrorReporter.reportError(
228                         XMLMessageFormatter.XMLNS_DOMAIN,
229                         "AttributeNSNotUnique",
230                         new Object JavaDoc[] { element.rawname, alocalpart, auri },
231                         XMLErrorReporter.SEVERITY_FATAL_ERROR);
232                 }
233             }
234         }
235
236     } // startNamespaceScope(QName,XMLAttributes)
237

238     /** Handles end element. */
239     protected void endNamespaceScope(QName element, Augmentations augs, boolean isEmpty)
240         throws XNIException {
241
242         // bind element
243
String JavaDoc eprefix = element.prefix != null ? element.prefix : XMLSymbols.EMPTY_STRING;
244         element.uri = fNamespaceContext.getURI(eprefix);
245         if (element.uri != null) {
246             element.prefix = eprefix;
247         }
248
249         // call handlers
250
if (fDocumentHandler != null) {
251             if (!isEmpty) {
252                 fDocumentHandler.endElement(element, augs);
253             }
254         }
255
256         // pop context
257
fNamespaceContext.popContext();
258
259     } // endNamespaceScope(QName,boolean)
260
}
261
Popular Tags