KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xerces > dom > DOMNormalizer


1 /*
2  * Copyright 1999-2002,2004, 2005 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.dom;
18
19
20 import java.io.IOException JavaDoc;
21 import java.io.StringReader JavaDoc;
22 import java.util.Vector JavaDoc;
23
24 import org.apache.xerces.impl.Constants;
25 import org.apache.xerces.impl.RevalidationHandler;
26 import org.apache.xerces.impl.dtd.DTDGrammar;
27 import org.apache.xerces.impl.dtd.XMLDTDDescription;
28 import org.apache.xerces.impl.dtd.XMLDTDValidator;
29 import org.apache.xerces.impl.dv.XSSimpleType;
30 import org.apache.xerces.impl.xs.util.SimpleLocator;
31 import org.apache.xerces.parsers.XMLGrammarPreparser;
32 import org.apache.xerces.util.AugmentationsImpl;
33 import org.apache.xerces.util.NamespaceSupport;
34 import org.apache.xerces.util.SymbolTable;
35 import org.apache.xerces.util.XML11Char;
36 import org.apache.xerces.util.XMLChar;
37 import org.apache.xerces.util.XMLGrammarPoolImpl;
38 import org.apache.xerces.util.XMLSymbols;
39 import org.apache.xerces.xni.Augmentations;
40 import org.apache.xerces.xni.NamespaceContext;
41 import org.apache.xerces.xni.QName;
42 import org.apache.xerces.xni.XMLAttributes;
43 import org.apache.xerces.xni.XMLDocumentHandler;
44 import org.apache.xerces.xni.XMLLocator;
45 import org.apache.xerces.xni.XMLResourceIdentifier;
46 import org.apache.xerces.xni.XMLString;
47 import org.apache.xerces.xni.XNIException;
48 import org.apache.xerces.xni.grammars.XMLGrammarDescription;
49 import org.apache.xerces.xni.grammars.XMLGrammarPool;
50 import org.apache.xerces.xni.parser.XMLComponent;
51 import org.apache.xerces.xni.parser.XMLDocumentSource;
52 import org.apache.xerces.xni.parser.XMLInputSource;
53 import org.apache.xerces.xs.AttributePSVI;
54 import org.apache.xerces.xs.ElementPSVI;
55 import org.apache.xerces.xs.XSTypeDefinition;
56 import org.w3c.dom.Attr JavaDoc;
57 import org.w3c.dom.Comment JavaDoc;
58 import org.w3c.dom.DOMError JavaDoc;
59 import org.w3c.dom.DOMErrorHandler JavaDoc;
60 import org.w3c.dom.Document JavaDoc;
61 import org.w3c.dom.DocumentType JavaDoc;
62 import org.w3c.dom.Element JavaDoc;
63 import org.w3c.dom.Entity JavaDoc;
64 import org.w3c.dom.NamedNodeMap JavaDoc;
65 import org.w3c.dom.Node JavaDoc;
66 import org.w3c.dom.NodeList JavaDoc;
67 import org.w3c.dom.ProcessingInstruction JavaDoc;
68 import org.w3c.dom.Text JavaDoc;
69 /**
70  * This class adds implementation for normalizeDocument method.
71  * It acts as if the document was going through a save and load cycle, putting
72  * the document in a "normal" form. The actual result depends on the features being set
73  * and governing what operations actually take place. See setNormalizationFeature for details.
74  * Noticeably this method normalizes Text nodes, makes the document "namespace wellformed",
75  * according to the algorithm described below in pseudo code, by adding missing namespace
76  * declaration attributes and adding or changing namespace prefixes, updates the replacement
77  * tree of EntityReference nodes, normalizes attribute values, etc.
78  * Mutation events, when supported, are generated to reflect the changes occuring on the
79  * document.
80  * See Namespace normalization for details on how namespace declaration attributes and prefixes
81  * are normalized.
82  *
83  * NOTE: There is an initial support for DOM revalidation with XML Schema as a grammar.
84  * The tree might not be validated correctly if entityReferences, CDATA sections are
85  * present in the tree. The PSVI information is not exposed, normalized data (including element
86  * default content is not available).
87  *
88  * @xerces.experimental
89  *
90  * @author Elena Litani, IBM
91  * @author Neeraj Bajaj, Sun Microsystems, inc.
92  * @version $Id: DOMNormalizer.java,v 1.61 2005/05/10 15:36:42 ankitp Exp $
93  */

94 public class DOMNormalizer implements XMLDocumentHandler {
95
96     //
97
// constants
98
//
99
/** Debug normalize document*/
100     protected final static boolean DEBUG_ND = false;
101     /** Debug namespace fix up algorithm*/
102     protected final static boolean DEBUG = false;
103     /** Debug document handler events */
104     protected final static boolean DEBUG_EVENTS = false;
105
106     /** prefix added by namespace fixup algorithm should follow a pattern "NS" + index*/
107     protected final static String JavaDoc PREFIX = "NS";
108
109     //
110
// Data
111
//
112
protected DOMConfigurationImpl fConfiguration = null;
113     protected CoreDocumentImpl fDocument = null;
114     protected final XMLAttributesProxy fAttrProxy = new XMLAttributesProxy();
115     protected final QName fQName = new QName();
116
117     /** Validation handler represents validator instance. */
118     protected RevalidationHandler fValidationHandler;
119
120     /** symbol table */
121     protected SymbolTable fSymbolTable;
122     /** error handler. may be null. */
123     protected DOMErrorHandler JavaDoc fErrorHandler;
124     
125     /**
126      * Cached {@link DOMError} impl.
127      * The same object is re-used to report multiple errors.
128      */

129     private final DOMErrorImpl fError = new DOMErrorImpl();
130     
131     // Validation against namespace aware grammar
132
protected boolean fNamespaceValidation = false;
133
134     // Update PSVI information in the tree
135
protected boolean fPSVI = false;
136
137     /** The namespace context of this document: stores namespaces in scope */
138     protected final NamespaceContext fNamespaceContext = new NamespaceSupport();
139
140     /** Stores all namespace bindings on the current element */
141     protected final NamespaceContext fLocalNSBinder = new NamespaceSupport();
142
143     /** list of attributes */
144     protected final Vector JavaDoc fAttributeList = new Vector JavaDoc(5,10);
145
146
147     /** DOM Locator - for namespace fixup algorithm */
148     protected final DOMLocatorImpl fLocator = new DOMLocatorImpl();
149
150     /** for setting the PSVI */
151     protected Node JavaDoc fCurrentNode = null;
152     private QName fAttrQName = new QName();
153     
154     // attribute value normalization
155
final XMLString fNormalizedValue = new XMLString(new char[16], 0, 0);
156     
157     /**
158      * If the user stops the process, this exception will be thrown.
159      */

160     public static final RuntimeException JavaDoc abort = new RuntimeException JavaDoc();
161     
162     //DTD validator
163
private XMLDTDValidator fDTDValidator;
164     
165     //Check if element content is all "ignorable whitespace"
166
private boolean allWhitespace = false;
167     
168     // Constructor
169
//
170

171     public DOMNormalizer(){}
172
173
174
175     /**
176      * Normalizes document.
177      * Note: reset() must be called before this method.
178      */

179     protected void normalizeDocument(CoreDocumentImpl document, DOMConfigurationImpl config) {
180
181         fDocument = document;
182         fConfiguration = config;
183
184         // intialize and reset DOMNormalizer component
185
//
186
fSymbolTable = (SymbolTable) fConfiguration.getProperty(DOMConfigurationImpl.SYMBOL_TABLE);
187         // reset namespace context
188
fNamespaceContext.reset();
189         fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING);
190
191         if ((fConfiguration.features & DOMConfigurationImpl.VALIDATE) != 0) {
192             String JavaDoc schemaLang = (String JavaDoc)fConfiguration.getProperty(DOMConfigurationImpl.JAXP_SCHEMA_LANGUAGE);
193             
194             if(schemaLang != null && schemaLang.equals(Constants.NS_XMLSCHEMA)) {
195                 fValidationHandler =
196                     CoreDOMImplementationImpl.singleton.getValidator(XMLGrammarDescription.XML_SCHEMA);
197                 fConfiguration.setFeature(DOMConfigurationImpl.SCHEMA, true);
198                 // report fatal error on DOM Level 1 nodes
199
fNamespaceValidation = true;
200                 
201                 // check if we need to fill in PSVI
202
fPSVI = ((fConfiguration.features & DOMConfigurationImpl.PSVI) !=0)?true:false;
203             }
204             
205             fConfiguration.setFeature(DOMConfigurationImpl.XERCES_VALIDATION, true);
206             
207             // reset ID table
208
fDocument.clearIdentifiers();
209             
210             if(fValidationHandler != null)
211             // reset schema validator
212
((XMLComponent) fValidationHandler).reset(fConfiguration);
213             
214         }
215
216         fErrorHandler = (DOMErrorHandler JavaDoc) fConfiguration.getParameter(Constants.DOM_ERROR_HANDLER);
217         if (fValidationHandler != null) {
218             fValidationHandler.setDocumentHandler(this);
219             fValidationHandler.startDocument(
220                     new SimpleLocator(fDocument.fDocumentURI, fDocument.fDocumentURI,
221                         -1, -1 ), fDocument.encoding, fNamespaceContext, null);
222
223         }
224         try {
225             Node JavaDoc kid, next;
226             for (kid = fDocument.getFirstChild(); kid != null; kid = next) {
227                 next = kid.getNextSibling();
228                 kid = normalizeNode(kid);
229                 if (kid != null) { // don't advance
230
next = kid;
231                 }
232             }
233
234             // release resources
235
if (fValidationHandler != null) {
236                 fValidationHandler.endDocument(null);
237                 CoreDOMImplementationImpl.singleton.releaseValidator(
238                     XMLGrammarDescription.XML_SCHEMA, fValidationHandler);
239                 fValidationHandler = null;
240             }
241         }
242         catch (RuntimeException JavaDoc e) {
243             if( e==abort )
244                 return; // processing aborted by the user
245
throw e; // otherwise re-throw.
246
}
247
248     }
249
250
251     /**
252      *
253      * This method acts as if the document was going through a save
254      * and load cycle, putting the document in a "normal" form. The actual result
255      * depends on the features being set and governing what operations actually
256      * take place. See setNormalizationFeature for details. Noticeably this method
257      * normalizes Text nodes, makes the document "namespace wellformed",
258      * according to the algorithm described below in pseudo code, by adding missing
259      * namespace declaration attributes and adding or changing namespace prefixes, updates
260      * the replacement tree of EntityReference nodes,normalizes attribute values, etc.
261      *
262      * @param node Modified node or null. If node is returned, we need
263      * to normalize again starting on the node returned.
264      * @return the normalized Node
265      */

266     protected Node JavaDoc normalizeNode (Node JavaDoc node){
267
268         int type = node.getNodeType();
269         boolean wellformed;
270         fLocator.fRelatedNode=node;
271         
272         switch (type) {
273         case Node.DOCUMENT_TYPE_NODE: {
274                 if (DEBUG_ND) {
275                     System.out.println("==>normalizeNode:{doctype}");
276                 }
277                 DocumentTypeImpl docType = (DocumentTypeImpl)node;
278                 fDTDValidator = (XMLDTDValidator)CoreDOMImplementationImpl.singleton.getValidator(XMLGrammarDescription.XML_DTD);
279                 fDTDValidator.setDocumentHandler(this);
280                 fConfiguration.setProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY, createGrammarPool(docType));
281                 fDTDValidator.reset(fConfiguration);
282                 fDTDValidator.startDocument(
283                         new SimpleLocator(fDocument.fDocumentURI, fDocument.fDocumentURI,
284                             -1, -1 ), fDocument.encoding, fNamespaceContext, null);
285                 fDTDValidator.doctypeDecl(docType.getName(), docType.getPublicId(), docType.getSystemId(), null);
286                 //REVISIT: well-formness encoding info
287
break;
288             }
289
290         case Node.ELEMENT_NODE: {
291                 if (DEBUG_ND) {
292                     System.out.println("==>normalizeNode:{element} "+node.getNodeName());
293                 }
294                 
295                 //do the name check only when version of the document was changed &
296
//application has set the value of well-formed features to true
297
if (fDocument.errorChecking) {
298                     if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) &&
299                             fDocument.isXMLVersionChanged()){
300                         if (fNamespaceValidation){
301                             wellformed = CoreDocumentImpl.isValidQName(node.getPrefix() , node.getLocalName(), fDocument.isXML11Version()) ;
302                         }
303                         else {
304                             wellformed = CoreDocumentImpl.isXMLName(node.getNodeName() , fDocument.isXML11Version());
305                         }
306                         if (!wellformed){
307                             String JavaDoc msg = DOMMessageFormatter.formatMessage(
308                                     DOMMessageFormatter.DOM_DOMAIN,
309                                     "wf-invalid-character-in-node-name",
310                                     new Object JavaDoc[]{"Element", node.getNodeName()});
311                             reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
312                             "wf-invalid-character-in-node-name");
313                         }
314                     }
315                 }
316                 // push namespace context
317
fNamespaceContext.pushContext();
318                 fLocalNSBinder.reset();
319
320                 ElementImpl elem = (ElementImpl)node;
321                 if (elem.needsSyncChildren()) {
322                     elem.synchronizeChildren();
323                 }
324                 AttributeMap attributes = (elem.hasAttributes()) ? (AttributeMap) elem.getAttributes() : null;
325
326                 // fix namespaces and remove default attributes
327
if ((fConfiguration.features & DOMConfigurationImpl.NAMESPACES) !=0) {
328                     // fix namespaces
329
// normalize attribute values
330
// remove default attributes
331
namespaceFixUp(elem, attributes);
332                     
333                     if ((fConfiguration.features & DOMConfigurationImpl.NSDECL) == 0 && attributes != null ) {
334                         for (int i = 0; i < attributes.getLength(); ++i) {
335                             Attr JavaDoc att = (Attr JavaDoc)attributes.getItem(i);
336                             if (XMLSymbols.PREFIX_XMLNS.equals(att.getPrefix()) ||
337                                 XMLSymbols.PREFIX_XMLNS.equals(att.getName())) {
338                                 elem.removeAttributeNode(att);
339                                 --i;
340                             }
341                         }
342                     }
343                     
344                 } else {
345                     if ( attributes!=null ) {
346                         for ( int i=0; i<attributes.getLength(); ++i ) {
347                             Attr JavaDoc attr = (Attr JavaDoc)attributes.item(i);
348                             //removeDefault(attr, attributes);
349
attr.normalize();
350                             if (fDocument.errorChecking && ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0)){
351                                     isAttrValueWF(fErrorHandler, fError, fLocator, attributes, (AttrImpl)attr, attr.getValue(), fDocument.isXML11Version());
352                                 if (fDocument.isXMLVersionChanged()){
353                                     wellformed=CoreDocumentImpl.isXMLName(node.getNodeName() , fDocument.isXML11Version());
354                                     if (!wellformed){
355                                             String JavaDoc msg = DOMMessageFormatter.formatMessage(
356                                               DOMMessageFormatter.DOM_DOMAIN,
357                                               "wf-invalid-character-in-node-name",
358                                                new Object JavaDoc[]{"Attr",node.getNodeName()});
359                                             reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
360                                                 "wf-invalid-character-in-node-name");
361                                     }
362                                 }
363                             }
364                         }
365                     }
366                 }
367                 
368                 
369                 if (fValidationHandler != null) {
370                     // REVISIT: possible solutions to discard default content are:
371
// either we pass some flag to XML Schema validator
372
// or rely on the PSVI information.
373
fAttrProxy.setAttributes(attributes, fDocument, elem);
374                     updateQName(elem, fQName); // updates global qname
375
// set error node in the dom error wrapper
376
// so if error occurs we can report an error node
377
fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
378                     fCurrentNode = node;
379                     // call re-validation handler
380
fValidationHandler.startElement(fQName, fAttrProxy, null);
381                 }
382                 
383                 if (fDTDValidator != null) {
384                     // REVISIT: possible solutions to discard default content are:
385
// either we pass some flag to XML Schema validator
386
// or rely on the PSVI information.
387
fAttrProxy.setAttributes(attributes, fDocument, elem);
388                     updateQName(elem, fQName); // updates global qname
389
// set error node in the dom error wrapper
390
// so if error occurs we can report an error node
391
fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
392                     fCurrentNode = node;
393                     // call re-validation handler
394
fDTDValidator.startElement(fQName, fAttrProxy, null);
395                 }
396
397                 // normalize children
398
Node JavaDoc kid, next;
399                 for (kid = elem.getFirstChild(); kid != null; kid = next) {
400                     next = kid.getNextSibling();
401                     kid = normalizeNode(kid);
402                     if (kid !=null) {
403                         next = kid; // don't advance
404
}
405                 }
406                 if (DEBUG_ND) {
407                     // normalized subtree
408
System.out.println("***The children of {"+node.getNodeName()+"} are normalized");
409                     for (kid = elem.getFirstChild(); kid != null; kid = next) {
410                         next = kid.getNextSibling();
411                         System.out.println(kid.getNodeName() +"["+kid.getNodeValue()+"]");
412                     }
413
414                 }
415
416
417                 if (fValidationHandler != null) {
418                     updateQName(elem, fQName); // updates global qname
419
//
420
// set error node in the dom error wrapper
421
// so if error occurs we can report an error node
422
fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
423                     fCurrentNode = node;
424                     fValidationHandler.endElement(fQName, null);
425                 }
426                 
427                 if (fDTDValidator != null) {
428                     updateQName(elem, fQName); // updates global qname
429
//
430
// set error node in the dom error wrapper
431
// so if error occurs we can report an error node
432
fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
433                     fCurrentNode = node;
434                     fDTDValidator.endElement(fQName, null);
435                 }
436
437                 // pop namespace context
438
fNamespaceContext.popContext();
439
440                 break;
441             }
442
443         case Node.COMMENT_NODE: {
444                 if (DEBUG_ND) {
445                     System.out.println("==>normalizeNode:{comments}");
446                 }
447
448                 if ((fConfiguration.features & DOMConfigurationImpl.COMMENTS) == 0) {
449                     Node JavaDoc prevSibling = node.getPreviousSibling();
450                     Node JavaDoc parent = node.getParentNode();
451                     // remove the comment node
452
parent.removeChild(node);
453                     if (prevSibling != null && prevSibling.getNodeType() == Node.TEXT_NODE) {
454                         Node JavaDoc nextSibling = prevSibling.getNextSibling();
455                         if (nextSibling != null && nextSibling.getNodeType() == Node.TEXT_NODE) {
456                             ((TextImpl)nextSibling).insertData(0, prevSibling.getNodeValue());
457                             parent.removeChild(prevSibling);
458                             return nextSibling;
459                         }
460                     }
461                 }//if comment node need not be removed
462
else {
463                     if (fDocument.errorChecking && ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0)){
464                         String JavaDoc commentdata = ((Comment JavaDoc)node).getData();
465                         // check comments for invalid xml chracter as per the version
466
// of the document
467
isCommentWF(fErrorHandler, fError, fLocator, commentdata, fDocument.isXML11Version());
468                     }
469                 }//end-else if comment node is not to be removed.
470
break;
471             }
472         case Node.ENTITY_REFERENCE_NODE: {
473                 if (DEBUG_ND) {
474                     System.out.println("==>normalizeNode:{entityRef} "+node.getNodeName());
475                 }
476
477                 if ((fConfiguration.features & DOMConfigurationImpl.ENTITIES) == 0) {
478                     Node JavaDoc prevSibling = node.getPreviousSibling();
479                     Node JavaDoc parent = node.getParentNode();
480                     ((EntityReferenceImpl)node).setReadOnly(false, true);
481                     expandEntityRef (parent, node);
482                     parent.removeChild(node);
483                     Node JavaDoc next = (prevSibling != null)?prevSibling.getNextSibling():parent.getFirstChild();
484                     // The list of children #text -> &ent;
485
// and entity has a first child as a text
486
// we should not advance
487
if (prevSibling != null && next != null && prevSibling.getNodeType() == Node.TEXT_NODE &&
488                         next.getNodeType() == Node.TEXT_NODE) {
489                         return prevSibling; // Don't advance
490
}
491                     return next;
492                 } else {
493                     if (fDocument.errorChecking && ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) &&
494                         fDocument.isXMLVersionChanged()){
495                             CoreDocumentImpl.isXMLName(node.getNodeName() , fDocument.isXML11Version());
496                     }
497                     // REVISIT: traverse entity reference and send appropriate calls to the validator
498
// (no normalization should be performed for the children).
499
}
500                 break;
501             }
502
503         case Node.CDATA_SECTION_NODE: {
504                 if (DEBUG_ND) {
505                     System.out.println("==>normalizeNode:{cdata}");
506                 }
507                 
508                 if ((fConfiguration.features & DOMConfigurationImpl.CDATA) == 0) {
509                     // convert CDATA to TEXT nodes
510
Node JavaDoc prevSibling = node.getPreviousSibling();
511                     if (prevSibling != null && prevSibling.getNodeType() == Node.TEXT_NODE){
512                         ((Text JavaDoc)prevSibling).appendData(node.getNodeValue());
513                         node.getParentNode().removeChild(node);
514                         return prevSibling; //don't advance
515
}
516                     else {
517                         Text JavaDoc text = fDocument.createTextNode(node.getNodeValue());
518                         Node JavaDoc parent = node.getParentNode();
519                         node = parent.replaceChild(text, node);
520                         return text; //don't advance
521

522                     }
523                 }
524
525                 // send characters call for CDATA
526
if (fValidationHandler != null) {
527                     // set error node in the dom error wrapper
528
// so if error occurs we can report an error node
529
fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
530                     fCurrentNode = node;
531                     fValidationHandler.startCDATA(null);
532                     fValidationHandler.characterData(node.getNodeValue(), null);
533                     fValidationHandler.endCDATA(null);
534                 }
535                 
536                 if (fDTDValidator != null) {
537                     // set error node in the dom error wrapper
538
// so if error occurs we can report an error node
539
fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
540                     fCurrentNode = node;
541                     fDTDValidator.startCDATA(null);
542                     fDTDValidator.characterData(node.getNodeValue(), null);
543                     fDTDValidator.endCDATA(null);
544                 }
545                 String JavaDoc value = node.getNodeValue();
546                 
547                 if ((fConfiguration.features & DOMConfigurationImpl.SPLITCDATA) != 0) {
548                     int index;
549                     Node JavaDoc parent = node.getParentNode();
550                     if (fDocument.errorChecking) {
551                         isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), fDocument.isXML11Version());
552                     }
553                     while ( (index=value.indexOf("]]>")) >= 0 ) {
554                         node.setNodeValue(value.substring(0, index+2));
555                         value = value.substring(index +2);
556                         
557                         Node JavaDoc firstSplitNode = node;
558                         Node JavaDoc newChild = fDocument.createCDATASection(value);
559                         parent.insertBefore(newChild, node.getNextSibling());
560                         node = newChild;
561                         // issue warning
562
fLocator.fRelatedNode = firstSplitNode;
563                         String JavaDoc msg = DOMMessageFormatter.formatMessage(
564                             DOMMessageFormatter.DOM_DOMAIN,
565                             "cdata-sections-splitted",
566                              null);
567                         reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_WARNING,
568                             "cdata-sections-splitted");
569                     }
570
571                 }
572                 else if (fDocument.errorChecking) {
573                     // check well-formedness
574
isCDataWF(fErrorHandler, fError, fLocator, value, fDocument.isXML11Version());
575                 }
576                 break;
577             }
578
579         case Node.TEXT_NODE: {
580                 if (DEBUG_ND) {
581                     System.out.println("==>normalizeNode(text):{"+node.getNodeValue()+"}");
582                 }
583                 // If node is a text node, we need to check for one of two
584
// conditions:
585
// 1) There is an adjacent text node
586
// 2) There is no adjacent text node, but node is
587
// an empty text node.
588
Node JavaDoc next = node.getNextSibling();
589                 // If an adjacent text node, merge it with this node
590
if ( next!=null && next.getNodeType() == Node.TEXT_NODE ) {
591                     ((Text JavaDoc)node).appendData(next.getNodeValue());
592                     node.getParentNode().removeChild( next );
593                     // We don't need to check well-formness here since we are not yet
594
// done with this node.
595

596                     return node; // Don't advance;
597
} else if (node.getNodeValue().length()==0) {
598                     // If kid is empty, remove it
599
node.getParentNode().removeChild( node );
600                 } else {
601                     // validator.characters() call and well-formness
602
// Don't send characters or check well-formness in the following cases:
603
// 1. entities is false, next child is entity reference: expand tree first
604
// 2. comments is false, and next child is comment
605
// 3. cdata is false, and next child is cdata
606

607                     short nextType = (next != null)?next.getNodeType():-1;
608                     if (nextType == -1 || !(((fConfiguration.features & DOMConfigurationImpl.ENTITIES) == 0 &&
609                            nextType == Node.ENTITY_NODE) ||
610                           ((fConfiguration.features & DOMConfigurationImpl.COMMENTS) == 0 &&
611                            nextType == Node.COMMENT_NODE) ||
612                           ((fConfiguration.features & DOMConfigurationImpl.CDATA) == 0) &&
613                           nextType == Node.CDATA_SECTION_NODE)) {
614                               if (fDocument.errorChecking && ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) ){
615                                   isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), fDocument.isXML11Version());
616                               }
617                               if (fValidationHandler != null) {
618                                      fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
619                                      fCurrentNode = node;
620                                      fValidationHandler.characterData(node.getNodeValue(), null);
621                                      if (DEBUG_ND) {
622                                          System.out.println("=====>characterData(),"+nextType);
623
624                                      }
625                               }
626                               if (fDTDValidator != null) {
627                                   fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
628                                   fCurrentNode = node;
629                                   fDTDValidator.characterData(node.getNodeValue(), null);
630                                   if (DEBUG_ND) {
631                                       System.out.println("=====>characterData(),"+nextType);
632
633                                   }
634                                   if(allWhitespace) {
635                                       allWhitespace = false;
636                                       ((TextImpl)node).setIgnorableWhitespace(true);
637                                   }
638                               }
639                     }
640                     else {
641                             if (DEBUG_ND) {
642                                 System.out.println("=====>don't send characters(),"+nextType);
643
644                             }
645                     }
646                 }
647                 break;
648             }
649         case Node.PROCESSING_INSTRUCTION_NODE: {
650             
651             //do the well-formed valid PI target name , data check when application has set the value of well-formed feature to true
652
if (fDocument.errorChecking && (fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0 ) {
653                 ProcessingInstruction JavaDoc pinode = (ProcessingInstruction JavaDoc)node ;
654
655                 String JavaDoc target = pinode.getTarget();
656                 //1.check PI target name
657
if(fDocument.isXML11Version()){
658                     wellformed = XML11Char.isXML11ValidName(target);
659                 }
660                 else{
661                     wellformed = XMLChar.isValidName(target);
662                 }
663
664                 if (!wellformed) {
665                     String JavaDoc msg = DOMMessageFormatter.formatMessage(
666                         DOMMessageFormatter.DOM_DOMAIN,
667                         "wf-invalid-character-in-node-name",
668                         new Object JavaDoc[]{"Element", node.getNodeName()});
669                     reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
670                         "wf-invalid-character-in-node-name");
671                 }
672                                 
673                 //2. check PI data
674
//processing isntruction data may have certain characters
675
//which may not be valid XML character
676
isXMLCharWF(fErrorHandler, fError, fLocator, pinode.getData(), fDocument.isXML11Version());
677             }
678         }//end case Node.PROCESSING_INSTRUCTION_NODE
679

680         }//end of switch
681
return null;
682     }//normalizeNode
683

684     private XMLGrammarPool createGrammarPool(DocumentTypeImpl docType) {
685
686         XMLGrammarPoolImpl pool = new XMLGrammarPoolImpl();
687         
688         XMLGrammarPreparser preParser = new XMLGrammarPreparser(fSymbolTable);
689         preParser.registerPreparser(XMLGrammarDescription.XML_DTD, null);
690         preParser.setFeature(Constants.XERCES_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE, true);
691         preParser.setFeature(Constants.XERCES_FEATURE_PREFIX + Constants.VALIDATION_FEATURE, true);
692         preParser.setProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY, pool);
693         
694         String JavaDoc internalSubset = docType.getInternalSubset();
695         XMLInputSource is = new XMLInputSource(docType.getPublicId(), docType.getSystemId(), null);
696         
697         if(internalSubset != null)
698             is.setCharacterStream(new StringReader JavaDoc(internalSubset));
699         try {
700             DTDGrammar g = (DTDGrammar)preParser.preparseGrammar(XMLGrammarDescription.XML_DTD, is);
701             ((XMLDTDDescription)g.getGrammarDescription()).setRootName(docType.getName());
702             is.setCharacterStream(null);
703             g = (DTDGrammar)preParser.preparseGrammar(XMLGrammarDescription.XML_DTD, is);
704             ((XMLDTDDescription)g.getGrammarDescription()).setRootName(docType.getName());
705             
706         } catch (XNIException e) {
707         } catch (IOException JavaDoc e) {
708         }
709         
710         return pool;
711     }
712
713
714
715     protected final void expandEntityRef (Node JavaDoc parent, Node JavaDoc reference){
716         Node JavaDoc kid, next;
717         for (kid = reference.getFirstChild(); kid != null; kid = next) {
718             next = kid.getNextSibling();
719             parent.insertBefore(kid, reference);
720         }
721     }
722
723     // fix namespaces
724
// normalize attribute values
725
// remove default attributes
726
// check attribute names if the version of the document changed.
727

728     protected final void namespaceFixUp (ElementImpl element, AttributeMap attributes){
729         if (DEBUG) {
730             System.out.println("[ns-fixup] element:" +element.getNodeName()+
731                                " uri: "+element.getNamespaceURI());
732         }
733
734         // ------------------------------------
735
// pick up local namespace declarations
736
// <xsl:stylesheet xmlns:xsl="http://xslt">
737
// <!-- add the following via DOM
738
// body is bound to http://xslt
739
// -->
740
// <xsl:body xmlns:xsl="http://bound"/>
741
//
742
// ------------------------------------
743

744         String JavaDoc value, name, uri, prefix;
745         if (attributes != null) {
746
747             // Record all valid local declarations
748
for (int k = 0; k < attributes.getLength(); ++k) {
749                 Attr JavaDoc attr = (Attr JavaDoc)attributes.getItem(k);
750                
751                 //do the name check only when version of the document was changed &
752
//application has set the value of well-formed features to true
753
if (fDocument.errorChecking && ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) &&
754                     fDocument.isXMLVersionChanged()) {
755                     //checkQName does checking based on the version of the document
756
fDocument.checkQName(attr.getPrefix() , attr.getLocalName()) ;
757                 }
758                 
759                 uri = attr.getNamespaceURI();
760                 if (uri != null && uri.equals(NamespaceContext.XMLNS_URI)) {
761                     // namespace attribute
762
value = attr.getNodeValue();
763                     if (value == null) {
764                         value=XMLSymbols.EMPTY_STRING;
765                     }
766
767                     // Check for invalid namespace declaration:
768
if (fDocument.errorChecking && value.equals(NamespaceContext.XMLNS_URI)) {
769                         //A null value for locale is passed to formatMessage,
770
//which means that the default locale will be used
771
fLocator.fRelatedNode = attr;
772                         String JavaDoc msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,"CantBindXMLNS",null );
773                         reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR, "CantBindXMLNS");
774                     } else {
775                         // XML 1.0 Attribute value normalization
776
// value = normalizeAttributeValue(value, attr);
777
prefix = attr.getPrefix();
778                         prefix = (prefix == null ||
779                                   prefix.length() == 0) ? XMLSymbols.EMPTY_STRING :fSymbolTable.addSymbol(prefix);
780                         String JavaDoc localpart = fSymbolTable.addSymbol( attr.getLocalName());
781                         if (prefix == XMLSymbols.PREFIX_XMLNS) { //xmlns:prefix
782

783                             value = fSymbolTable.addSymbol(value);
784                             if (value.length() != 0) {
785                                 fNamespaceContext.declarePrefix(localpart, value);
786                             } else {
787                                 // REVISIT: issue error on invalid declarations
788
// xmlns:foo = ""
789

790                             }
791                             //removeDefault (attr, attributes);
792
continue;
793                         } else { // (localpart == fXmlnsSymbol && prefix == fEmptySymbol) -- xmlns
794
// empty prefix is always bound ("" or some string)
795
value = fSymbolTable.addSymbol(value);
796                             fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, value);
797                             //removeDefault (attr, attributes);
798
continue;
799                         }
800                     } // end-else: valid declaration
801
} // end-if: namespace attribute
802
}
803         }
804
805
806
807         // ---------------------------------------------------------
808
// Fix up namespaces for element: per DOM L3
809
// Need to consider the following cases:
810
//
811
// case 1: <xsl:stylesheet xmlns:xsl="http://xsl">
812
// We create another element body bound to the "http://xsl" namespace
813
// as well as namespace attribute rebounding xsl to another namespace.
814
// <xsl:body xmlns:xsl="http://another">
815
// Need to make sure that the new namespace decl value is changed to
816
// "http://xsl"
817
//
818
// ---------------------------------------------------------
819
// check if prefix/namespace is correct for current element
820
// ---------------------------------------------------------
821

822         uri = element.getNamespaceURI();
823         prefix = element.getPrefix();
824         if (uri != null) { // Element has a namespace
825
uri = fSymbolTable.addSymbol(uri);
826             prefix = (prefix == null ||
827                       prefix.length() == 0) ? XMLSymbols.EMPTY_STRING :fSymbolTable.addSymbol(prefix);
828             if (fNamespaceContext.getURI(prefix) == uri) {
829                 // The xmlns:prefix=namespace or xmlns="default" was declared at parent.
830
// The binder always stores mapping of empty prefix to "".
831
} else {
832                 // the prefix is either undeclared
833
// or
834
// conflict: the prefix is bound to another URI
835
addNamespaceDecl(prefix, uri, element);
836                 fLocalNSBinder.declarePrefix(prefix, uri);
837                 fNamespaceContext.declarePrefix(prefix, uri);
838             }
839         } else { // Element has no namespace
840
if (element.getLocalName() == null) {
841                 
842                 // Error: DOM Level 1 node!
843
if (fNamespaceValidation) {
844                     String JavaDoc msg = DOMMessageFormatter.formatMessage(
845                             DOMMessageFormatter.DOM_DOMAIN, "NullLocalElementName",
846                             new Object JavaDoc[]{element.getNodeName()});
847                     reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_FATAL_ERROR,
848                     "NullLocalElementName");
849                 } else {
850                     String JavaDoc msg = DOMMessageFormatter.formatMessage(
851                             DOMMessageFormatter.DOM_DOMAIN, "NullLocalElementName",
852                             new Object JavaDoc[]{element.getNodeName()});
853                     reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
854                     "NullLocalElementName");
855                 }
856                 
857             } else { // uri=null and no colon (DOM L2 node)
858
uri = fNamespaceContext.getURI(XMLSymbols.EMPTY_STRING);
859                 if (uri !=null && uri.length() > 0) {
860                     // undeclare default namespace declaration (before that element
861
// bound to non-zero length uir), but adding xmlns="" decl
862
addNamespaceDecl (XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING, element);
863                     fLocalNSBinder.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING);
864                     fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING);
865                 }
866             }
867         }
868
869         // -----------------------------------------
870
// Fix up namespaces for attributes: per DOM L3
871
// check if prefix/namespace is correct the attributes
872
// -----------------------------------------
873
if (attributes != null) {
874
875             // clone content of the attributes
876
attributes.cloneMap(fAttributeList);
877             for (int i = 0; i < fAttributeList.size(); i++) {
878                 Attr JavaDoc attr = (Attr JavaDoc) fAttributeList.elementAt(i);
879                 fLocator.fRelatedNode = attr;
880
881                 if (DEBUG) {
882                     System.out.println("==>[ns-fixup] process attribute: "+attr.getNodeName());
883                 }
884                 // normalize attribute value
885
attr.normalize();
886                 value = attr.getValue();
887                 name = attr.getNodeName();
888                 uri = attr.getNamespaceURI();
889
890                 // make sure that value is never null.
891
if (value == null) {
892                     value=XMLSymbols.EMPTY_STRING;
893                 }
894
895                 if (uri != null) { // attribute has namespace !=null
896
prefix = attr.getPrefix();
897                     prefix = (prefix == null ||
898                               prefix.length() == 0) ? XMLSymbols.EMPTY_STRING :fSymbolTable.addSymbol(prefix);
899                     /*String localpart =*/ fSymbolTable.addSymbol( attr.getLocalName());
900
901                     // ---------------------------------------
902
// skip namespace declarations
903
// ---------------------------------------
904
// REVISIT: can we assume that "uri" is from some symbol
905
// table, and compare by reference? -SG
906
if (uri != null && uri.equals(NamespaceContext.XMLNS_URI)) {
907                         continue;
908                     }
909                     //---------------------------------------
910
// check if value of the attribute is namespace well-formed
911
//---------------------------------------
912
if (fDocument.errorChecking && ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0)) {
913                             isAttrValueWF(fErrorHandler, fError, fLocator, attributes, (AttrImpl)attr, attr.getValue(), fDocument.isXML11Version());
914                             if (fDocument.isXMLVersionChanged()){
915                                 boolean wellformed=CoreDocumentImpl.isXMLName(attr.getNodeName() , fDocument.isXML11Version());
916                                 if (!wellformed){
917                                         String JavaDoc msg = DOMMessageFormatter.formatMessage(
918                                             DOMMessageFormatter.DOM_DOMAIN,
919                                             "wf-invalid-character-in-node-name",
920                                             new Object JavaDoc[]{"Attribute", attr.getNodeName()});
921                                         reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
922                                             "wf-invalid-character-in-node-name");
923                                 }
924                         }
925                     }
926
927                     // ---------------------------------------
928
// remove default attributes
929
// ---------------------------------------
930
/*
931                     if (removeDefault(attr, attributes)) {
932                         continue;
933                     }
934                     */

935                     // XML 1.0 Attribute value normalization
936
//value = normalizeAttributeValue(value, attr);
937

938                     // reset id-attributes
939
((AttrImpl)attr).setIdAttribute(false);
940
941
942                     uri = fSymbolTable.addSymbol(uri);
943
944                     // find if for this prefix a URI was already declared
945
String JavaDoc declaredURI = fNamespaceContext.getURI(prefix);
946
947                     if (prefix == XMLSymbols.EMPTY_STRING || declaredURI != uri) {
948                         // attribute has no prefix (default namespace decl does not apply to attributes)
949
// OR
950
// attribute prefix is not declared
951
// OR
952
// conflict: attribute has a prefix that conficlicts with a binding
953
// already active in scope
954

955                         name = attr.getNodeName();
956                         // Find if any prefix for attributes namespace URI is available
957
// in the scope
958
String JavaDoc declaredPrefix = fNamespaceContext.getPrefix(uri);
959                         if (declaredPrefix !=null && declaredPrefix !=XMLSymbols.EMPTY_STRING) {
960
961                             // use the prefix that was found (declared previously for this URI
962
prefix = declaredPrefix;
963                         } else {
964                             if (prefix != XMLSymbols.EMPTY_STRING && fLocalNSBinder.getURI(prefix) == null) {
965                                 // the current prefix is not null and it has no in scope declaration
966

967                                 // use this prefix
968
} else {
969
970                                 // find a prefix following the pattern "NS" +index (starting at 1)
971
// make sure this prefix is not declared in the current scope.
972
int counter = 1;
973                                 prefix = fSymbolTable.addSymbol(PREFIX +counter++);
974                                 while (fLocalNSBinder.getURI(prefix)!=null) {
975                                     prefix = fSymbolTable.addSymbol(PREFIX +counter++);
976                                 }
977
978                             }
979                             // add declaration for the new prefix
980
addNamespaceDecl(prefix, uri, element);
981                             value = fSymbolTable.addSymbol(value);
982                             fLocalNSBinder.declarePrefix(prefix, value);
983                             fNamespaceContext.declarePrefix(prefix, uri);
984                         }
985
986                         // change prefix for this attribute
987
attr.setPrefix(prefix);
988                     }
989                 } else { // attribute uri == null
990

991                     // XML 1.0 Attribute value normalization
992
//value = normalizeAttributeValue(value, attr);
993

994                     // reset id-attributes
995
((AttrImpl)attr).setIdAttribute(false);
996
997                     if (attr.getLocalName() == null) {
998                         // It is an error if document has DOM L1 nodes.
999
if (fNamespaceValidation) {
1000                            String JavaDoc msg = DOMMessageFormatter.formatMessage(
1001                                DOMMessageFormatter.DOM_DOMAIN,
1002                                "NullLocalAttrName", new Object JavaDoc[]{attr.getNodeName()});
1003                            reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_FATAL_ERROR,
1004                                "NullLocalAttrName");
1005                        } else {
1006                            String JavaDoc msg = DOMMessageFormatter.formatMessage(
1007                                DOMMessageFormatter.DOM_DOMAIN,
1008                                "NullLocalAttrName", new Object JavaDoc[]{attr.getNodeName()});
1009                            reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
1010                                "NullLocalAttrName");
1011                        }
1012                    } else {
1013                        // uri=null and no colon
1014
// no fix up is needed: default namespace decl does not
1015

1016                        // ---------------------------------------
1017
// remove default attributes
1018
// ---------------------------------------
1019
// removeDefault(attr, attributes);
1020
}
1021                }
1022            }
1023        } // end loop for attributes
1024
}
1025    
1026    /**
1027     * Adds a namespace attribute or replaces the value of existing namespace
1028     * attribute with the given prefix and value for URI.
1029     * In case prefix is empty will add/update default namespace declaration.
1030     *
1031     * @param prefix
1032     * @param uri
1033     * @exception IOException
1034     */

1035
1036    protected final void addNamespaceDecl(String JavaDoc prefix, String JavaDoc uri, ElementImpl element){
1037        if (DEBUG) {
1038            System.out.println("[ns-fixup] addNamespaceDecl ["+prefix+"]");
1039        }
1040        if (prefix == XMLSymbols.EMPTY_STRING) {
1041            if (DEBUG) {
1042                System.out.println("=>add xmlns=\""+uri+"\" declaration");
1043            }
1044            element.setAttributeNS(NamespaceContext.XMLNS_URI, XMLSymbols.PREFIX_XMLNS, uri);
1045        } else {
1046            if (DEBUG) {
1047                System.out.println("=>add xmlns:"+prefix+"=\""+uri+"\" declaration");
1048            }
1049            element.setAttributeNS(NamespaceContext.XMLNS_URI, "xmlns:"+prefix, uri);
1050        }
1051    }
1052    
1053    
1054    //
1055
// Methods for well-formness checking
1056
//
1057

1058    
1059    /**
1060     * Check if CDATA section is well-formed
1061     * @param datavalue
1062     * @param isXML11Version = true if XML 1.1
1063     */

1064    public static final void isCDataWF(DOMErrorHandler JavaDoc errorHandler, DOMErrorImpl error, DOMLocatorImpl locator,
1065        String JavaDoc datavalue, boolean isXML11Version)
1066    {
1067        if (datavalue == null || (datavalue.length() == 0) ) {
1068            return;
1069        }
1070        
1071        char [] dataarray = datavalue.toCharArray();
1072        int datalength = dataarray.length;
1073        
1074        // version of the document is XML 1.1
1075
if (isXML11Version) {
1076            // we need to check all chracters as per production rules of XML11
1077
int i = 0;
1078            while(i < datalength){
1079                char c = dataarray[i++];
1080                if ( XML11Char.isXML11Invalid(c) ) {
1081                    // check if this is a supplemental character
1082
if (XMLChar.isHighSurrogate(c) && i < datalength) {
1083                        char c2 = dataarray[i++];
1084                        if (XMLChar.isLowSurrogate(c2) &&
1085                            XMLChar.isSupplemental(XMLChar.supplemental(c, c2))) {
1086                            continue;
1087                        }
1088                    }
1089                    String JavaDoc msg = DOMMessageFormatter.formatMessage(
1090                        DOMMessageFormatter.XML_DOMAIN,
1091                        "InvalidCharInCDSect",
1092                        new Object JavaDoc[] { Integer.toString(c, 16)});
1093                    reportDOMError(
1094                        errorHandler,
1095                        error,
1096                        locator,
1097                        msg,
1098                        DOMError.SEVERITY_ERROR,
1099                        "wf-invalid-character");
1100                }
1101                else if (c == ']') {
1102                    int count = i;
1103                    if (count < datalength && dataarray[count] == ']') {
1104                        while (++count < datalength && dataarray[count] == ']') {
1105                            // do nothing
1106
}
1107                        if (count < datalength && dataarray[count] == '>') {
1108                            // CDEndInContent
1109
String JavaDoc msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN, "CDEndInContent", null);
1110                            reportDOMError(errorHandler, error, locator,msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
1111                        }
1112                    }
1113                    
1114                }
1115            }
1116        } // version of the document is XML 1.0
1117
else {
1118            // we need to check all chracters as per production rules of XML 1.0
1119
int i = 0;
1120            while (i < datalength) {
1121                char c = dataarray[i++];
1122                if( XMLChar.isInvalid(c) ) {
1123                    // check if this is a supplemental character
1124
if (XMLChar.isHighSurrogate(c) && i < datalength) {
1125                        char c2 = dataarray[i++];
1126                        if (XMLChar.isLowSurrogate(c2) &&
1127                            XMLChar.isSupplemental(XMLChar.supplemental(c, c2))) {
1128                            continue;
1129                        }
1130                    }
1131                    // Note: The key InvalidCharInCDSect from XMLMessages.properties
1132
// is being used to obtain the message and DOM error type
1133
// "wf-invalid-character" is used. Also per DOM it is error but
1134
// as per XML spec. it is fatal error
1135
String JavaDoc msg = DOMMessageFormatter.formatMessage(
1136                        DOMMessageFormatter.XML_DOMAIN,
1137                        "InvalidCharInCDSect",
1138                        new Object JavaDoc[]{Integer.toString(c, 16)});
1139                    reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
1140                }
1141                else if (c==']') {
1142                    int count = i;
1143                    if ( count< datalength && dataarray[count]==']' ) {
1144                        while (++count < datalength && dataarray[count]==']' ) {
1145                            // do nothing
1146
}
1147                        if ( count < datalength && dataarray[count]=='>' ) {
1148                            String JavaDoc msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN, "CDEndInContent", null);
1149                            reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
1150                        }
1151                    }
1152                    
1153                }
1154            }
1155        } // end-else fDocument.isXMLVersion()
1156

1157    } // isCDataWF
1158

1159    /**
1160     * NON-DOM: check for valid XML characters as per the XML version
1161     * @param datavalue
1162     * @param isXML11Version = true if XML 1.1
1163     */

1164    public static final void isXMLCharWF(DOMErrorHandler JavaDoc errorHandler, DOMErrorImpl error, DOMLocatorImpl locator,
1165        String JavaDoc datavalue, boolean isXML11Version)
1166    {
1167        if ( datavalue == null || (datavalue.length() == 0) ) {
1168            return;
1169        }
1170        
1171        char [] dataarray = datavalue.toCharArray();
1172        int datalength = dataarray.length;
1173        
1174        // version of the document is XML 1.1
1175
if(isXML11Version){
1176            //we need to check all characters as per production rules of XML11
1177
int i = 0 ;
1178            while (i < datalength) {
1179                if(XML11Char.isXML11Invalid(dataarray[i++])){
1180                    // check if this is a supplemental character
1181
char ch = dataarray[i-1];
1182                    if (XMLChar.isHighSurrogate(ch) && i < datalength) {
1183                        char ch2 = dataarray[i++];
1184                        if (XMLChar.isLowSurrogate(ch2) &&
1185                            XMLChar.isSupplemental(XMLChar.supplemental(ch, ch2))) {
1186                            continue;
1187                        }
1188                    }
1189                    String JavaDoc msg = DOMMessageFormatter.formatMessage(
1190                        DOMMessageFormatter.DOM_DOMAIN, "InvalidXMLCharInDOM",
1191                        new Object JavaDoc[]{Integer.toString(dataarray[i-1], 16)});
1192                    reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR,
1193                    "wf-invalid-character");
1194                }
1195            }
1196        } // version of the document is XML 1.0
1197
else{
1198            // we need to check all characters as per production rules of XML 1.0
1199
int i = 0 ;
1200            while (i < datalength) {
1201                if( XMLChar.isInvalid(dataarray[i++]) ) {
1202                    // check if this is a supplemental character
1203
char ch = dataarray[i-1];
1204                    if (XMLChar.isHighSurrogate(ch) && i < datalength) {
1205                        char ch2 = dataarray[i++];
1206                        if (XMLChar.isLowSurrogate(ch2) &&
1207                            XMLChar.isSupplemental(XMLChar.supplemental(ch, ch2))) {
1208                            continue;
1209                        }
1210                    }
1211                    String JavaDoc msg = DOMMessageFormatter.formatMessage(
1212                        DOMMessageFormatter.DOM_DOMAIN, "InvalidXMLCharInDOM",
1213                        new Object JavaDoc[]{Integer.toString(dataarray[i-1], 16)});
1214                    reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR,
1215                    "wf-invalid-character");
1216                }
1217            }
1218        } // end-else fDocument.isXMLVersion()
1219

1220    } // isXMLCharWF
1221

1222    /**
1223     * NON-DOM: check if value of the comment is well-formed
1224     * @param datavalue
1225     * @param isXML11Version = true if XML 1.1
1226     */

1227    public static final void isCommentWF(DOMErrorHandler JavaDoc errorHandler, DOMErrorImpl error, DOMLocatorImpl locator,
1228        String JavaDoc datavalue, boolean isXML11Version)
1229    {
1230        if ( datavalue == null || (datavalue.length() == 0) ) {
1231            return;
1232        }
1233        
1234        char [] dataarray = datavalue.toCharArray();
1235        int datalength = dataarray.length ;
1236        
1237        // version of the document is XML 1.1
1238
if (isXML11Version) {
1239            // we need to check all chracters as per production rules of XML11
1240
int i = 0 ;
1241            while (i < datalength){
1242                char c = dataarray[i++];
1243                if ( XML11Char.isXML11Invalid(c) ) {
1244                    // check if this is a supplemental character
1245
if (XMLChar.isHighSurrogate(c) && i < datalength) {
1246                        char c2 = dataarray[i++];
1247                        if (XMLChar.isLowSurrogate(c2) &&
1248                            XMLChar.isSupplemental(XMLChar.supplemental(c, c2))) {
1249                            continue;
1250                        }
1251                    }
1252                    String JavaDoc msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,
1253                        "InvalidCharInComment",
1254                        new Object JavaDoc [] {Integer.toString(dataarray[i-1], 16)});
1255                    reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
1256                }
1257                else if (c == '-' && i < datalength && dataarray[i] == '-') {
1258                    String JavaDoc msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,
1259                        "DashDashInComment", null);
1260                    // invalid: '--' in comment
1261
reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
1262                }
1263            }
1264        } // version of the document is XML 1.0
1265
else {
1266            // we need to check all chracters as per production rules of XML 1.0
1267
int i = 0;
1268            while (i < datalength){
1269                char c = dataarray[i++];
1270                if( XMLChar.isInvalid(c) ){
1271                    // check if this is a supplemental character
1272
if (XMLChar.isHighSurrogate(c) && i < datalength) {
1273                        char c2 = dataarray[i++];
1274                        if (XMLChar.isLowSurrogate(c2) &&
1275                            XMLChar.isSupplemental(XMLChar.supplemental(c, c2))) {
1276                            continue;
1277                        }
1278                    }
1279                    String JavaDoc msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,
1280                        "InvalidCharInComment", new Object JavaDoc [] {Integer.toString(dataarray[i-1], 16)});
1281                    reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
1282                }
1283                else if (c == '-' && i<datalength && dataarray[i]=='-'){
1284                    String JavaDoc msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,
1285                        "DashDashInComment", null);
1286                    // invalid: '--' in comment
1287
reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
1288                }
1289            }
1290            
1291        } // end-else fDocument.isXMLVersion()
1292

1293    } // isCommentWF
1294

1295    /** NON-DOM: check if attribute value is well-formed
1296     * @param attributes
1297     * @param a
1298     * @param value
1299     */

1300    public static final void isAttrValueWF(DOMErrorHandler JavaDoc errorHandler, DOMErrorImpl error,
1301            DOMLocatorImpl locator, NamedNodeMap JavaDoc attributes, Attr JavaDoc a, String JavaDoc value, boolean xml11Version) {
1302        if (a instanceof AttrImpl && ((AttrImpl)a).hasStringValue()) {
1303            isXMLCharWF(errorHandler, error, locator, value, xml11Version);
1304        } else {
1305            NodeList JavaDoc children = a.getChildNodes();
1306            //check each child node of the attribute's value
1307
for (int j = 0; j < children.getLength(); j++) {
1308                Node JavaDoc child = children.item(j);
1309                //If the attribute's child is an entity refernce
1310
if (child.getNodeType() == Node.ENTITY_REFERENCE_NODE) {
1311                    Document JavaDoc owner = a.getOwnerDocument();
1312                    Entity JavaDoc ent = null;
1313                    //search for the entity in the docType
1314
//of the attribute's ownerDocument
1315
if (owner != null) {
1316                        DocumentType JavaDoc docType = owner.getDoctype();
1317                        if (docType != null) {
1318                            NamedNodeMap JavaDoc entities = docType.getEntities();
1319                            ent = (Entity JavaDoc) entities.getNamedItemNS(
1320                                    "*",
1321                                    child.getNodeName());
1322                        }
1323                    }
1324                    //If the entity was not found issue a fatal error
1325
if (ent == null) {
1326                        String JavaDoc msg = DOMMessageFormatter.formatMessage(
1327                            DOMMessageFormatter.DOM_DOMAIN, "UndeclaredEntRefInAttrValue",
1328                            new Object JavaDoc[]{a.getNodeName()});
1329                        reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR,
1330                            "UndeclaredEntRefInAttrValue");
1331                    }
1332                }
1333                else {
1334                    // Text node
1335
isXMLCharWF(errorHandler, error, locator, child.getNodeValue(), xml11Version);
1336                }
1337            }
1338        }
1339    }
1340
1341
1342
1343    /**
1344     * Reports a DOM error to the user handler.
1345     *
1346     * If the error is fatal, the processing will be always aborted.
1347     */

1348    public static final void reportDOMError(DOMErrorHandler JavaDoc errorHandler, DOMErrorImpl error, DOMLocatorImpl locator,
1349                        String JavaDoc message, short severity, String JavaDoc type ) {
1350        if( errorHandler!=null ) {
1351            error.reset();
1352            error.fMessage = message;
1353            error.fSeverity = severity;
1354            error.fLocator = locator;
1355            error.fType = type;
1356            error.fRelatedData = locator.fRelatedNode;
1357    
1358            if(!errorHandler.handleError(error))
1359                throw abort;
1360        }
1361        if( severity==DOMError.SEVERITY_FATAL_ERROR )
1362            throw abort;
1363    }
1364
1365    protected final void updateQName (Node JavaDoc node, QName qname){
1366
1367        String JavaDoc prefix = node.getPrefix();
1368        String JavaDoc namespace = node.getNamespaceURI();
1369        String JavaDoc localName = node.getLocalName();
1370        // REVISIT: the symbols are added too often: start/endElement
1371
// and in the namespaceFixup. Should reduce number of calls to symbol table.
1372
qname.prefix = (prefix!=null && prefix.length()!=0)?fSymbolTable.addSymbol(prefix):null;
1373        qname.localpart = (localName != null)?fSymbolTable.addSymbol(localName):null;
1374        qname.rawname = fSymbolTable.addSymbol(node.getNodeName());
1375        qname.uri = (namespace != null)?fSymbolTable.addSymbol(namespace):null;
1376    }
1377    
1378
1379
1380    /* REVISIT: remove this method if DOM does not change spec.
1381     * Performs partial XML 1.0 attribute value normalization and replaces
1382     * attribute value if the value is changed after the normalization.
1383     * DOM defines that normalizeDocument acts as if the document was going
1384     * through a save and load cycle, given that serializer will not escape
1385     * any '\n' or '\r' characters on load those will be normalized.
1386     * Thus during normalize document we need to do the following:
1387     * - perform "2.11 End-of-Line Handling"
1388     * - replace #xD, #xA, #x9 with #x20 (white space).
1389     * Note: This alg. won't attempt to resolve entity references or character entity
1390     * references, since '&' will be escaped during serialization and during loading
1391     * this won't be recognized as entity reference, i.e. attribute value "&foo;" will
1392     * be serialized as "&amp;foo;" and thus after loading will be "&foo;" again.
1393     * @param value current attribute value
1394     * @param attr current attribute
1395     * @return String the value (could be original if normalization did not change
1396     * the string)
1397     */

1398    final String JavaDoc normalizeAttributeValue(String JavaDoc value, Attr JavaDoc attr) {
1399        if (!attr.getSpecified()){
1400            // specified attributes should already have a normalized form
1401
// since those were added by validator
1402
return value;
1403        }
1404        int end = value.length();
1405        // ensure capacity
1406
if (fNormalizedValue.ch.length < end) {
1407            fNormalizedValue.ch = new char[end];
1408        }
1409        fNormalizedValue.length = 0;
1410        boolean normalized = false;
1411        for (int i = 0; i < end; i++) {
1412            char c = value.charAt(i);
1413            if (c==0x0009 || c==0x000A) {
1414               fNormalizedValue.ch[fNormalizedValue.length++] = ' ';
1415               normalized = true;
1416            }
1417            else if(c==0x000D){
1418               normalized = true;
1419               fNormalizedValue.ch[fNormalizedValue.length++] = ' ';
1420               int next = i+1;
1421               if (next < end && value.charAt(next)==0x000A) i=next; // skip following xA
1422
}
1423            else {
1424                fNormalizedValue.ch[fNormalizedValue.length++] = c;
1425            }
1426        }
1427        if (normalized){
1428           value = fNormalizedValue.toString();
1429           attr.setValue(value);
1430        }
1431        return value;
1432    }
1433  
1434    protected final class XMLAttributesProxy
1435    implements XMLAttributes {
1436        protected AttributeMap fAttributes;
1437        protected CoreDocumentImpl fDocument;
1438        protected ElementImpl fElement;
1439
1440        protected final Vector JavaDoc fAugmentations = new Vector JavaDoc(5);
1441
1442
1443        public void setAttributes(AttributeMap attributes, CoreDocumentImpl doc, ElementImpl elem) {
1444            fDocument = doc;
1445            fAttributes = attributes;
1446            fElement = elem;
1447            if (attributes != null) {
1448                int length = attributes.getLength();
1449
1450                fAugmentations.setSize(length);
1451                // REVISIT: this implementation does not store any value in augmentations
1452
// and basically not keeping augs in parallel to attributes map
1453
// untill all attributes are added (default attributes)
1454
for (int i = 0; i < length; i++) {
1455                    fAugmentations.setElementAt(new AugmentationsImpl(), i);
1456                }
1457            } else {
1458                fAugmentations.setSize(0);
1459            }
1460        }
1461
1462
1463        /**
1464         * This method adds default declarations
1465         * @see org.apache.xerces.xni.XMLAttributes#addAttribute(QName, String, String)
1466         */

1467        public int addAttribute(QName qname, String JavaDoc attrType, String JavaDoc attrValue) {
1468            int index = fElement.getXercesAttribute(qname.uri, qname.localpart);
1469            // add defaults to the tree
1470
if (index < 0) {
1471                // the default attribute was removed by a user and needed to
1472
// be added back
1473
AttrImpl attr = (AttrImpl)
1474                    ((CoreDocumentImpl) fElement.getOwnerDocument()).createAttributeNS(
1475                        qname.uri,
1476                        qname.rawname,
1477                        qname.localpart);
1478                // REVISIT: the following should also update ID table
1479
index = fElement.setXercesAttributeNode(attr);
1480                attr.setNodeValue(attrValue);
1481                fAugmentations.insertElementAt(new AugmentationsImpl(), index);
1482                attr.setSpecified(false);
1483            }
1484            else {
1485                // default attribute is in the tree
1486
// we don't need to do anything since prefix was already fixed
1487
// at the namespace fixup time and value must be same value, otherwise
1488
// attribute will be treated as specified and we will never reach
1489
// this method.
1490

1491            }
1492            return index;
1493        }
1494
1495
1496        public void removeAllAttributes(){
1497            // REVISIT: implement
1498
}
1499
1500
1501        public void removeAttributeAt(int attrIndex){
1502            // REVISIT: implement
1503
}
1504
1505
1506        public int getLength(){
1507            return(fAttributes != null)?fAttributes.getLength():0;
1508        }
1509
1510
1511        public int getIndex(String JavaDoc qName){
1512            // REVISIT: implement
1513
return -1;
1514        }
1515
1516        public int getIndex(String JavaDoc uri, String JavaDoc localPart){
1517            // REVISIT: implement
1518
return -1;
1519        }
1520
1521        public void setName(int attrIndex, QName attrName){
1522            // REVISIT: implement
1523
}
1524
1525        public void getName(int attrIndex, QName attrName){
1526            if (fAttributes !=null) {
1527                updateQName((Node JavaDoc)fAttributes.getItem(attrIndex), attrName);
1528            }
1529        }
1530
1531        public String JavaDoc getPrefix(int index){
1532            // REVISIT: implement
1533
return null;
1534        }
1535
1536
1537        public String JavaDoc getURI(int index){
1538            // REVISIT: implement
1539
return null;
1540        }
1541
1542
1543        public String JavaDoc getLocalName(int index){
1544            // REVISIT: implement
1545
return null;
1546        }
1547
1548
1549        public String JavaDoc getQName(int index){
1550            // REVISIT: implement
1551
return null;
1552        }
1553
1554
1555        public void setType(int attrIndex, String JavaDoc attrType){
1556            // REVISIT: implement
1557
}
1558
1559
1560        public String JavaDoc getType(int index){
1561            return "CDATA";
1562        }
1563
1564
1565        public String JavaDoc getType(String JavaDoc qName){
1566            return "CDATA";
1567        }
1568
1569
1570        public String JavaDoc getType(String JavaDoc uri, String JavaDoc localName){
1571            return "CDATA";
1572        }
1573
1574
1575        public void setValue(int attrIndex, String JavaDoc attrValue){
1576            // REVISIT: is this desired behaviour?
1577
// The values are updated in the case datatype-normalization is turned on
1578
// in this case we need to make sure that specified attributes stay specified
1579

1580            if (fAttributes != null){
1581                AttrImpl attr = (AttrImpl)fAttributes.getItem(attrIndex);
1582                boolean specified = attr.getSpecified();
1583                attr.setValue(attrValue);
1584                attr.setSpecified(specified);
1585            
1586            }
1587        }
1588
1589
1590        public String JavaDoc getValue(int index){
1591            return (fAttributes !=null)?fAttributes.item(index).getNodeValue():"";
1592
1593        }
1594
1595
1596        public String JavaDoc getValue(String JavaDoc qName){
1597            // REVISIT: implement
1598
return null;
1599        }
1600
1601
1602        public String JavaDoc getValue(String JavaDoc uri, String JavaDoc localName){
1603            if (fAttributes != null) {
1604                Node JavaDoc node = fAttributes.getNamedItemNS(uri, localName);
1605                return(node != null)? node.getNodeValue():null;
1606            }
1607            return null;
1608        }
1609
1610
1611        public void setNonNormalizedValue(int attrIndex, String JavaDoc attrValue){
1612            // REVISIT: implement
1613

1614        }
1615
1616
1617        public String JavaDoc getNonNormalizedValue(int attrIndex){
1618            // REVISIT: implement
1619
return null;
1620        }
1621
1622
1623        public void setSpecified(int attrIndex, boolean specified){
1624            AttrImpl attr = (AttrImpl)fAttributes.getItem(attrIndex);
1625            attr.setSpecified(specified);
1626        }
1627
1628        public boolean isSpecified(int attrIndex){
1629            return((Attr JavaDoc)fAttributes.getItem(attrIndex)).getSpecified();
1630        }
1631
1632        public Augmentations getAugmentations (int attributeIndex){
1633            return(Augmentations)fAugmentations.elementAt(attributeIndex);
1634        }
1635
1636        public Augmentations getAugmentations (String JavaDoc uri, String JavaDoc localPart){
1637            // REVISIT: implement
1638
return null;
1639        }
1640
1641        public Augmentations getAugmentations(String JavaDoc qName){
1642            // REVISIT: implement
1643
return null;
1644        }
1645
1646        /**
1647         * Sets the augmentations of the attribute at the specified index.
1648         *
1649         * @param attrIndex The attribute index.
1650         * @param augs The augmentations.
1651         */

1652        public void setAugmentations(int attrIndex, Augmentations augs) {
1653            fAugmentations.setElementAt(augs, attrIndex);
1654        }
1655    }
1656
1657    //
1658
// XMLDocumentHandler methods
1659
//
1660

1661    /**
1662     * The start of the document.
1663     *
1664     * @param locator The document locator, or null if the document
1665     * location cannot be reported during the parsing
1666     * of this document. However, it is <em>strongly</em>
1667     * recommended that a locator be supplied that can
1668     * at least report the system identifier of the
1669     * document.
1670     * @param encoding The auto-detected IANA encoding name of the entity
1671     * stream. This value will be null in those situations
1672     * where the entity encoding is not auto-detected (e.g.
1673     * internal entities or a document entity that is
1674     * parsed from a java.io.Reader).
1675     * @param namespaceContext
1676     * The namespace context in effect at the
1677     * start of this document.
1678     * This object represents the current context.
1679     * Implementors of this class are responsible
1680     * for copying the namespace bindings from the
1681     * the current context (and its parent contexts)
1682     * if that information is important.
1683     *
1684     * @param augs Additional information that may include infoset augmentations
1685     * @exception XNIException
1686     * Thrown by handler to signal an error.
1687     */

1688    public void startDocument(XMLLocator locator, String JavaDoc encoding,
1689                              NamespaceContext namespaceContext,
1690                              Augmentations augs)
1691        throws XNIException{
1692    }
1693
1694    /**
1695     * Notifies of the presence of an XMLDecl line in the document. If
1696     * present, this method will be called immediately following the
1697     * startDocument call.
1698     *
1699     * @param version The XML version.
1700     * @param encoding The IANA encoding name of the document, or null if
1701     * not specified.
1702     * @param standalone The standalone value, or null if not specified.
1703     * @param augs Additional information that may include infoset augmentations
1704     *
1705     * @exception XNIException
1706     * Thrown by handler to signal an error.
1707     */

1708    public void xmlDecl(String JavaDoc version, String JavaDoc encoding, String JavaDoc standalone, Augmentations augs)
1709        throws XNIException{
1710    }
1711
1712    /**
1713     * Notifies of the presence of the DOCTYPE line in the document.
1714     *
1715     * @param rootElement
1716     * The name of the root element.
1717     * @param publicId The public identifier if an external DTD or null
1718     * if the external DTD is specified using SYSTEM.
1719     * @param systemId The system identifier if an external DTD, null
1720     * otherwise.
1721     * @param augs Additional information that may include infoset augmentations
1722     *
1723     * @exception XNIException
1724     * Thrown by handler to signal an error.
1725     */

1726    public void doctypeDecl(String JavaDoc rootElement, String JavaDoc publicId, String JavaDoc systemId, Augmentations augs)
1727        throws XNIException{
1728    }
1729
1730    /**
1731     * A comment.
1732     *
1733     * @param text The text in the comment.
1734     * @param augs Additional information that may include infoset augmentations
1735     *
1736     * @exception XNIException
1737     * Thrown by application to signal an error.
1738     */

1739    public void comment(XMLString text, Augmentations augs) throws XNIException{
1740    }
1741
1742    /**
1743     * A processing instruction. Processing instructions consist of a
1744     * target name and, optionally, text data. The data is only meaningful
1745     * to the application.
1746     * <p>
1747     * Typically, a processing instruction's data will contain a series
1748     * of pseudo-attributes. These pseudo-attributes follow the form of
1749     * element attributes but are <strong>not</strong> parsed or presented
1750     * to the application as anything other than text. The application is
1751     * responsible for parsing the data.
1752     *
1753     * @param target The target.
1754     * @param data The data or null if none specified.
1755     * @param augs Additional information that may include infoset augmentations
1756     *
1757     * @exception XNIException
1758     * Thrown by handler to signal an error.
1759     */

1760    public void processingInstruction(String JavaDoc target, XMLString data, Augmentations augs)
1761        throws XNIException{
1762    }
1763
1764    /**
1765     * The start of an element.
1766     *
1767     * @param element The name of the element.
1768     * @param attributes The element attributes.
1769     * @param augs Additional information that may include infoset augmentations
1770     *
1771     * @exception XNIException
1772     * Thrown by handler to signal an error.
1773     */

1774    public void startElement(QName element, XMLAttributes attributes, Augmentations augs)
1775        throws XNIException {
1776        Element JavaDoc currentElement = (Element JavaDoc) fCurrentNode;
1777        int attrCount = attributes.getLength();
1778        if (DEBUG_EVENTS) {
1779            System.out.println("==>startElement: " +element+
1780            " attrs.length="+attrCount);
1781        }
1782
1783        for (int i = 0; i < attrCount; i++) {
1784            attributes.getName(i, fAttrQName);
1785            Attr JavaDoc attr = null;
1786
1787            attr = currentElement.getAttributeNodeNS(fAttrQName.uri, fAttrQName.localpart);
1788            AttributePSVI attrPSVI =
1789                (AttributePSVI) attributes.getAugmentations(i).getItem(Constants.ATTRIBUTE_PSVI);
1790
1791            if (attrPSVI != null) {
1792                //REVISIT: instead we should be using augmentations:
1793
// to set/retrieve Id attributes
1794
XSTypeDefinition decl = attrPSVI.getMemberTypeDefinition();
1795                boolean id = false;
1796                if (decl != null){
1797                    id = ((XSSimpleType)decl).isIDType();
1798                } else{
1799                    decl = attrPSVI.getTypeDefinition();
1800                    if (decl !=null){
1801                       id = ((XSSimpleType)decl).isIDType();
1802                    }
1803                }
1804                if (id){
1805                    ((ElementImpl)currentElement).setIdAttributeNode(attr, true);
1806                }
1807                
1808                if (fPSVI) {
1809                    ((PSVIAttrNSImpl) attr).setPSVI(attrPSVI);
1810                }
1811                if ((fConfiguration.features & DOMConfigurationImpl.DTNORMALIZATION) != 0) {
1812                    // datatype-normalization
1813
// NOTE: The specified value MUST be set after we set
1814
// the node value because that turns the "specified"
1815
// flag to "true" which may overwrite a "false"
1816
// value from the attribute list.
1817
boolean specified = attr.getSpecified();
1818                    attr.setValue(attrPSVI.getSchemaNormalizedValue());
1819                    if (!specified) {
1820                        ((AttrImpl) attr).setSpecified(specified);
1821                    }
1822                }
1823            }
1824        }
1825    }
1826
1827
1828    /**
1829     * An empty element.
1830     *
1831     * @param element The name of the element.
1832     * @param attributes The element attributes.
1833     * @param augs Additional information that may include infoset augmentations
1834     *
1835     * @exception XNIException
1836     * Thrown by handler to signal an error.
1837     */

1838    public void emptyElement(QName element, XMLAttributes attributes, Augmentations augs)
1839        throws XNIException {
1840        if (DEBUG_EVENTS) {
1841            System.out.println("==>emptyElement: " +element);
1842        }
1843
1844        startElement(element, attributes, augs);
1845        endElement(element, augs);
1846    }
1847
1848    /**
1849     * This method notifies the start of a general entity.
1850     * <p>
1851     * <strong>Note:</strong> This method is not called for entity references
1852     * appearing as part of attribute values.
1853     *
1854     * @param name The name of the general entity.
1855     * @param identifier The resource identifier.
1856     * @param encoding The auto-detected IANA encoding name of the entity
1857     * stream. This value will be null in those situations
1858     * where the entity encoding is not auto-detected (e.g.
1859     * internal entities or a document entity that is
1860     * parsed from a java.io.Reader).
1861     * @param augs Additional information that may include infoset augmentations
1862     *
1863     * @exception XNIException Thrown by handler to signal an error.
1864     */

1865    public void startGeneralEntity(String JavaDoc name,
1866                                   XMLResourceIdentifier identifier,
1867                                   String JavaDoc encoding,
1868                                   Augmentations augs) throws XNIException{
1869    }
1870
1871    /**
1872     * Notifies of the presence of a TextDecl line in an entity. If present,
1873     * this method will be called immediately following the startEntity call.
1874     * <p>
1875     * <strong>Note:</strong> This method will never be called for the
1876     * document entity; it is only called for external general entities
1877     * referenced in document content.
1878     * <p>
1879     * <strong>Note:</strong> This method is not called for entity references
1880     * appearing as part of attribute values.
1881     *
1882     * @param version The XML version, or null if not specified.
1883     * @param encoding The IANA encoding name of the entity.
1884     * @param augs Additional information that may include infoset augmentations
1885     *
1886     * @exception XNIException
1887     * Thrown by handler to signal an error.
1888     */

1889    public void textDecl(String JavaDoc version, String JavaDoc encoding, Augmentations augs) throws XNIException{
1890    }
1891
1892    /**
1893     * This method notifies the end of a general entity.
1894     * <p>
1895     * <strong>Note:</strong> This method is not called for entity references
1896     * appearing as part of attribute values.
1897     *
1898     * @param name The name of the entity.
1899     * @param augs Additional information that may include infoset augmentations
1900     *
1901     * @exception XNIException
1902     * Thrown by handler to signal an error.
1903     */

1904    public void endGeneralEntity(String JavaDoc name, Augmentations augs) throws XNIException{
1905    }
1906
1907    /**
1908     * Character content.
1909     *
1910     * @param text The content.
1911     * @param augs Additional information that may include infoset augmentations
1912     *
1913     * @exception XNIException
1914     * Thrown by handler to signal an error.
1915     */

1916    public void characters(XMLString text, Augmentations augs) throws XNIException{
1917    }
1918
1919    /**
1920     * Ignorable whitespace. For this method to be called, the document
1921     * source must have some way of determining that the text containing
1922     * only whitespace characters should be considered ignorable. For
1923     * example, the validator can determine if a length of whitespace
1924     * characters in the document are ignorable based on the element
1925     * content model.
1926     *
1927     * @param text The ignorable whitespace.
1928     * @param augs Additional information that may include infoset augmentations
1929     *
1930     * @exception XNIException
1931     * Thrown by handler to signal an error.
1932     */

1933    public void ignorableWhitespace(XMLString text, Augmentations augs) throws XNIException{
1934        allWhitespace = true;
1935    }
1936
1937    /**
1938     * The end of an element.
1939     *
1940     * @param element The name of the element.
1941     * @param augs Additional information that may include infoset augmentations
1942     *
1943     * @exception XNIException
1944     * Thrown by handler to signal an error.
1945     */

1946    public void endElement(QName element, Augmentations augs) throws XNIException {
1947        if (DEBUG_EVENTS) {
1948            System.out.println("==>endElement: " + element);
1949        }
1950
1951        if(augs != null) {
1952            ElementPSVI elementPSVI = (ElementPSVI) augs.getItem(Constants.ELEMENT_PSVI);
1953            if (elementPSVI != null) {
1954                ElementImpl elementNode = (ElementImpl) fCurrentNode;
1955                if (fPSVI) {
1956                    ((PSVIElementNSImpl) fCurrentNode).setPSVI(elementPSVI);
1957                }
1958                // include element default content (if one is available)
1959
String JavaDoc normalizedValue = elementPSVI.getSchemaNormalizedValue();
1960                if ((fConfiguration.features & DOMConfigurationImpl.DTNORMALIZATION) != 0) {
1961                    if (normalizedValue !=null)
1962                        elementNode.setTextContent(normalizedValue);
1963                }
1964                else {
1965                    // NOTE: this is a hack: it is possible that DOM had an empty element
1966
// and validator sent default value using characters(), which we don't
1967
// implement. Thus, here we attempt to add the default value.
1968
String JavaDoc text = elementNode.getTextContent();
1969                    if (text.length() == 0) {
1970                        // default content could be provided
1971
if (normalizedValue !=null)
1972                            elementNode.setTextContent(normalizedValue);
1973                    }
1974                }
1975            }
1976        }
1977    }
1978
1979
1980    /**
1981     * The start of a CDATA section.
1982     *
1983     * @param augs Additional information that may include infoset augmentations
1984     *
1985     * @exception XNIException
1986     * Thrown by handler to signal an error.
1987     */

1988    public void startCDATA(Augmentations augs) throws XNIException{
1989    }
1990
1991    /**
1992     * The end of a CDATA section.
1993     *
1994     * @param augs Additional information that may include infoset augmentations
1995     *
1996     * @exception XNIException
1997     * Thrown by handler to signal an error.
1998     */

1999    public void endCDATA(Augmentations augs) throws XNIException{
2000    }
2001
2002    /**
2003     * The end of the document.
2004     *
2005     * @param augs Additional information that may include infoset augmentations
2006     *
2007     * @exception XNIException
2008     * Thrown by handler to signal an error.
2009     */

2010    public void endDocument(Augmentations augs) throws XNIException{
2011    }
2012
2013
2014    /** Sets the document source. */
2015    public void setDocumentSource(XMLDocumentSource source){
2016    }
2017
2018
2019    /** Returns the document source. */
2020    public XMLDocumentSource getDocumentSource(){
2021        return null;
2022    }
2023
2024    
2025} // DOMNormalizer class
2026
Popular Tags