KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xerces > internal > dom > DOMNormalizer


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

57
58 package com.sun.org.apache.xerces.internal.dom;
59
60
61 import java.util.Vector JavaDoc;
62 //--
63
import com.sun.org.apache.xerces.internal.parsers.XMLGrammarPreparser;
64 import com.sun.org.apache.xerces.internal.parsers.IntegratedParserConfiguration;
65 import com.sun.org.apache.xerces.internal.util.XMLGrammarPoolImpl;
66 import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
67 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
68 import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
69 import org.xml.sax.InputSource JavaDoc;
70 //--
71

72 import org.w3c.dom.DOMError JavaDoc;
73 import org.w3c.dom.DOMErrorHandler JavaDoc;
74 import com.sun.org.apache.xerces.internal.impl.Constants;
75 import com.sun.org.apache.xerces.internal.impl.RevalidationHandler;
76 import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
77 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
78 import com.sun.org.apache.xerces.internal.impl.xs.util.SimpleLocator;
79 import com.sun.org.apache.xerces.internal.util.AugmentationsImpl;
80 import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
81 import com.sun.org.apache.xerces.internal.util.SymbolTable;
82 import com.sun.org.apache.xerces.internal.util.XMLSymbols;
83 import com.sun.org.apache.xerces.internal.xni.Augmentations;
84 import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
85 import com.sun.org.apache.xerces.internal.xni.QName;
86 import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
87 import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
88 import com.sun.org.apache.xerces.internal.xni.XMLLocator;
89 import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
90 import com.sun.org.apache.xerces.internal.xni.XMLString;
91 import com.sun.org.apache.xerces.internal.xni.XNIException;
92 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
93 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
94 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
95 import com.sun.org.apache.xerces.internal.xs.AttributePSVI;
96 import com.sun.org.apache.xerces.internal.xs.ElementPSVI;
97 import org.w3c.dom.Attr JavaDoc;
98 import org.w3c.dom.Element JavaDoc;
99 import org.w3c.dom.Node JavaDoc;
100 import org.w3c.dom.NodeList JavaDoc;
101 import org.w3c.dom.Text JavaDoc;
102 import org.w3c.dom.ProcessingInstruction JavaDoc;
103 import com.sun.org.apache.xerces.internal.util.XML11Char;
104 import com.sun.org.apache.xerces.internal.util.XMLChar;
105 import org.w3c.dom.Document JavaDoc;
106 import org.w3c.dom.DocumentType JavaDoc;
107 import org.w3c.dom.Entity JavaDoc;
108 import org.w3c.dom.NamedNodeMap JavaDoc;
109 import org.w3c.dom.Comment JavaDoc;
110 import com.sun.org.apache.xerces.internal.impl.dtd.*;
111 import java.io.*;
112
113 /**
114  * This class adds implementation for normalizeDocument method.
115  * It acts as if the document was going through a save and load cycle, putting
116  * the document in a "normal" form. The actual result depends on the features being set
117  * and governing what operations actually take place. See setNormalizationFeature for details.
118  * Noticeably this method normalizes Text nodes, makes the document "namespace wellformed",
119  * according to the algorithm described below in pseudo code, by adding missing namespace
120  * declaration attributes and adding or changing namespace prefixes, updates the replacement
121  * tree of EntityReference nodes, normalizes attribute values, etc.
122  * Mutation events, when supported, are generated to reflect the changes occuring on the
123  * document.
124  * See Namespace normalization for details on how namespace declaration attributes and prefixes
125  * are normalized.
126  *
127  * NOTE: There is an initial support for DOM revalidation with XML Schema as a grammar.
128  * The tree might not be validated correctly if entityReferences, CDATA sections are
129  * present in the tree. The PSVI information is not exposed, normalized data (including element
130  * default content is not available).
131  *
132  * NOTE: the implementation is experimental and methods, functionality
133  * can be modified or removed in the future.
134  *
135  * @author Elena Litani, IBM
136  * @author Neeraj Bajaj, Sun Microsystems, inc.
137  * @version $Id: DOMNormalizer.java,v 1.54 2004/04/22 20:39:03 mrglavas Exp $
138  */

139 public class DOMNormalizer implements XMLDocumentHandler {
140     
141     
142     //-- Added
143
// Constants
144
//
145

146     // property IDs:
147

148     /** Property identifier: symbol table. */
149     public static final String JavaDoc SYMBOL_TABLE = Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
150     
151     /** Property identifier: grammar pool. */
152     public static final String JavaDoc GRAMMAR_POOL = Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
153     
154     // feature ids
155

156     /** Namespaces feature id (http://xml.org/sax/features/namespaces). */
157     protected static final String JavaDoc NAMESPACES_FEATURE_ID = "http://xml.org/sax/features/namespaces";
158     
159     /** Validation feature id (http://xml.org/sax/features/validation). */
160     protected static final String JavaDoc VALIDATION_FEATURE_ID = "http://xml.org/sax/features/validation";
161     
162     /** Schema validation feature id (http://apache.org/xml/features/validation/schema). */
163     protected static final String JavaDoc SCHEMA_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/schema";
164     
165     /** Schema full checking feature id (http://apache.org/xml/features/validation/schema-full-checking). */
166     protected static final String JavaDoc SCHEMA_FULL_CHECKING_FEATURE_ID = "http://apache.org/xml/features/validation/schema-full-checking";
167     
168     //--
169
//
170
// constants
171
//
172
/** Debug normalize document*/
173     protected final static boolean DEBUG_ND = false;
174     /** Debug namespace fix up algorithm*/
175     protected final static boolean DEBUG = false;
176     /** Debug document handler events */
177     protected final static boolean DEBUG_EVENTS = false;
178     
179     /** prefix added by namespace fixup algorithm should follow a pattern "NS" + index*/
180     protected final static String JavaDoc PREFIX = "NS";
181     
182     //
183
// Data
184
//
185
protected DOMConfigurationImpl fConfiguration = null;
186     protected CoreDocumentImpl fDocument = null;
187     protected final XMLAttributesProxy fAttrProxy = new XMLAttributesProxy();
188     protected final QName fQName = new QName();
189     
190     /** Validation handler represents validator instance. */
191     protected RevalidationHandler fValidationHandler;
192     protected XMLDTDValidator fDTDValidator;
193     
194     /** symbol table */
195     protected SymbolTable fSymbolTable;
196     /** error handler. may be null. */
197     protected DOMErrorHandler JavaDoc fErrorHandler;
198     
199     /**
200      * Cached {@link DOMError} impl.
201      * The same object is re-used to report multiple errors.
202      */

203     private final DOMErrorImpl fError = new DOMErrorImpl();
204     
205     // Validation against namespace aware grammar
206
protected boolean fNamespaceValidation = false;
207     
208     // Update PSVI information in the tree
209
protected boolean fPSVI = false;
210     
211     /** The namespace context of this document: stores namespaces in scope */
212     protected final NamespaceContext fNamespaceContext = new NamespaceSupport();
213     
214     /** Stores all namespace bindings on the current element */
215     protected final NamespaceContext fLocalNSBinder = new NamespaceSupport();
216     
217     /** list of attributes */
218     protected final Vector JavaDoc fAttributeList = new Vector JavaDoc(5,10);
219     
220     
221     /** DOM Locator - for namespace fixup algorithm */
222     protected final DOMLocatorImpl fLocator = new DOMLocatorImpl();
223     
224     /** for setting the PSVI */
225     protected Node JavaDoc fCurrentNode = null;
226     private QName fAttrQName = new QName();
227     
228     // attribute value normalization
229
final XMLString fNormalizedValue = new XMLString(new char[16], 0, 0);
230     
231     /**
232      * If the user stops the process, this exception will be thrown.
233      */

234     public static final RuntimeException JavaDoc abort = new RuntimeException JavaDoc();
235     
236     // Constructor
237
//
238

239     public boolean isWhitespace = false;
240     public boolean docTypeFound = false;
241     
242     public DOMNormalizer(){}
243     
244     
245     
246     /**
247      * Normalizes document.
248      * Note: reset() must be called before this method.
249      */

250     protected void normalizeDocument(CoreDocumentImpl document, DOMConfigurationImpl config) {
251         
252         fDocument = document;
253         fConfiguration = config;
254         
255         // intialize and reset DOMNormalizer component
256
//
257
fSymbolTable = (SymbolTable) fConfiguration.getProperty(DOMConfigurationImpl.SYMBOL_TABLE);
258         // reset namespace context
259
fNamespaceContext.reset();
260         fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING);
261         docTypeFound = false;
262         if ((fConfiguration.features & DOMConfigurationImpl.VALIDATE) != 0) {
263             String JavaDoc type =(String JavaDoc) fConfiguration.getProperty(fConfiguration.JAXP_SCHEMA_LANGUAGE);
264             if(type != null && type.equals(Constants.NS_XMLSCHEMA))
265                 fValidationHandler = CoreDOMImplementationImpl.singleton.getValidator(XMLGrammarDescription.XML_SCHEMA);
266             fConfiguration.setFeature(DOMConfigurationImpl.XERCES_VALIDATION, true);
267             fConfiguration.setFeature(DOMConfigurationImpl.SCHEMA, true);
268             // report fatal error on DOM Level 1 nodes
269
fNamespaceValidation = true;
270             
271             // check if we need to fill in PSVI
272
fPSVI = ((fConfiguration.features & DOMConfigurationImpl.PSVI) !=0)?true:false;
273             
274             // reset ID table
275
fDocument.clearIdentifiers();
276             
277             // reset schema validator
278
if(fValidationHandler!=null)
279                 ((XMLComponent) fValidationHandler).reset(fConfiguration);
280             
281         }
282         
283         fErrorHandler = (DOMErrorHandler JavaDoc) fConfiguration.getParameter(Constants.DOM_ERROR_HANDLER);
284         if (fValidationHandler != null) {
285             fValidationHandler.setDocumentHandler(this);
286             fValidationHandler.startDocument( new SimpleLocator(fDocument.fDocumentURI, fDocument.fDocumentURI, -1, -1 ), fDocument.encoding, fNamespaceContext, null);
287             
288         }
289         try {
290             Node JavaDoc kid, next;
291             for (kid = fDocument.getFirstChild(); kid != null; kid = next) {
292                 next = kid.getNextSibling();
293                 kid = normalizeNode(kid);
294                 if (kid != null) { // don't advance
295
next = kid;
296                 }
297             }
298             
299             // release resources
300
if (fValidationHandler != null) {
301                 fValidationHandler.endDocument(null);
302                 CoreDOMImplementationImpl.singleton.releaseValidator(
303                 XMLGrammarDescription.XML_SCHEMA, fValidationHandler);
304                 fValidationHandler = null;
305             }
306         }
307         catch (RuntimeException JavaDoc e) {
308             if(DEBUG_ND) e.printStackTrace();
309             if( e==abort )
310                 return; // processing aborted by the user
311
throw e; // otherwise re-throw.
312
}
313         
314     }
315     
316     
317     /**
318      *
319      * This method acts as if the document was going through a save
320      * and load cycle, putting the document in a "normal" form. The actual result
321      * depends on the features being set and governing what operations actually
322      * take place. See setNormalizationFeature for details. Noticeably this method
323      * normalizes Text nodes, makes the document "namespace wellformed",
324      * according to the algorithm described below in pseudo code, by adding missing
325      * namespace declaration attributes and adding or changing namespace prefixes, updates
326      * the replacement tree of EntityReference nodes,normalizes attribute values, etc.
327      *
328      * @param node Modified node or null. If node is returned, we need
329      * to normalize again starting on the node returned.
330      * @return the normalized Node
331      */

332     protected Node JavaDoc normalizeNode(Node JavaDoc node){
333         
334         int type = node.getNodeType();
335         boolean wellformed;
336         fLocator.fRelatedNode=node;
337         
338         switch (type) {
339             case Node.DOCUMENT_TYPE_NODE: {
340                 if (DEBUG_ND) {
341                     System.out.println("==>normalizeNode:{doctype}");
342                 }
343                 fDTDValidator =(XMLDTDValidator) CoreDOMImplementationImpl.singleton.getDTDValidator();
344                 DocumentTypeImpl docNode = (DocumentTypeImpl)node;
345                 if(fDTDValidator != null){
346                 //fix me :
347
fConfiguration.setFeature(DOMConfigurationImpl.XERCES_VALIDATION, false);
348                 
349                 fDTDValidator.startDocument( new SimpleLocator(fDocument.fDocumentURI, fDocument.fDocumentURI, -1, -1 ), fDocument.encoding, fNamespaceContext, null);
350             
351                 
352                 if (DEBUG_ND)
353                     System.out.println("Internal subset is "+docNode.getInternalSubset());
354                 XMLGrammarPoolImpl grammarPool = getGrammarPool(docNode.getSystemId(),docNode.getInternalSubset());
355                 fConfiguration.setProperty(GRAMMAR_POOL, grammarPool);
356                 fDTDValidator.setDocumentHandler(this);
357                  ((XMLComponent) fDTDValidator).reset(fConfiguration);
358                 fDTDValidator.doctypeDecl(docNode.getName(),docNode.getPublicId(),docNode.getSystemId(),null);
359                  docTypeFound = true;
360                 }
361                 //REVISIT: well-formness encoding info
362
break;
363             }
364             
365             case Node.ELEMENT_NODE: {
366                 if (DEBUG_ND) {
367                     System.out.println("==>normalizeNode:{element} "+node.getNodeName());
368                 }
369                 
370                 //do the name check only when version of the document was changed &
371
//application has set the value of well-formed features to true
372
if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) &&
373                 fDocument.isXMLVersionChanged()){
374                     if(fNamespaceValidation){
375                         wellformed = CoreDocumentImpl.isValidQName(node.getPrefix() , node.getLocalName(), fDocument.isXML11Version()) ;
376                     }
377                     else{
378                         wellformed = CoreDocumentImpl.isXMLName(node.getNodeName() , fDocument.isXML11Version());
379                     }
380                     if (!wellformed){
381                             String JavaDoc msg = DOMMessageFormatter.formatMessage(
382                                 DOMMessageFormatter.DOM_DOMAIN,
383                                 "wf-invalid-character-in-node-name",
384                                 new Object JavaDoc[]{"Element", node.getNodeName()});
385                             reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
386                                 "wf-invalid-character-in-node-name");
387                     }
388                 }
389                 // push namespace context
390
fNamespaceContext.pushContext();
391                 fLocalNSBinder.reset();
392                 
393                 ElementImpl elem = (ElementImpl)node;
394                 if (elem.needsSyncChildren()) {
395                     elem.synchronizeChildren();
396                 }
397                 AttributeMap attributes = (elem.hasAttributes()) ? (AttributeMap) elem.getAttributes() : null;
398                 
399                 // fix namespaces and remove default attributes
400
if ((fConfiguration.features & DOMConfigurationImpl.NAMESPACES) !=0) {
401                     // fix namespaces
402
// normalize attribute values
403
// remove default attributes
404
namespaceFixUp(elem, attributes);
405                 } else {
406                     if ( attributes!=null ) {
407                         for ( int i=0; i<attributes.getLength(); ++i ) {
408                             Attr JavaDoc attr = (Attr JavaDoc)attributes.item(i);
409                             //removeDefault(attr, attributes);
410
attr.normalize();
411                             if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0)){
412                                 isAttrValueWF(fErrorHandler, fError, fLocator, attributes, (AttrImpl)attr, attr.getValue(), fDocument.isXML11Version());
413                                 if (fDocument.isXMLVersionChanged()){
414                                     wellformed=CoreDocumentImpl.isXMLName(node.getNodeName() , fDocument.isXML11Version());
415                                     if (!wellformed){
416                                             String JavaDoc msg = DOMMessageFormatter.formatMessage(
417                                               DOMMessageFormatter.DOM_DOMAIN,
418                                               "wf-invalid-character-in-node-name",
419                                                new Object JavaDoc[]{"Attr",node.getNodeName()});
420                                             reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
421                                                 "wf-invalid-character-in-node-name");
422                                     }
423                                 }
424                             }
425                         }
426                     }
427                 }
428                 
429                 
430                 if (fValidationHandler != null) {
431                     // REVISIT: possible solutions to discard default content are:
432
// either we pass some flag to XML Schema validator
433
// or rely on the PSVI information.
434
fAttrProxy.setAttributes(attributes, fDocument, elem);
435                     updateQName(elem, fQName); // updates global qname
436
// set error node in the dom error wrapper
437
// so if error occurs we can report an error node
438
fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
439                     fCurrentNode = node;
440                     // call re-validation handler
441
fValidationHandler.startElement(fQName, fAttrProxy, null);
442                 }
443                 
444                 if(fDTDValidator != null){
445                     if(attributes!=null)
446                     fAttrProxy.setAttributes(attributes, fDocument, elem);
447                     updateQName(elem, fQName); // updates global qname
448
fCurrentNode = node;
449                     fDTDValidator.startElement(fQName, fAttrProxy, null);
450                 }
451                 
452                 // normalize children
453
Node JavaDoc kid, next;
454                 for (kid = elem.getFirstChild(); kid != null; kid = next) {
455                     next = kid.getNextSibling();
456                     kid = normalizeNode(kid);
457                     if (kid !=null) {
458                         next = kid; // don't advance
459
}
460                 }
461                 if (DEBUG_ND) {
462                     // normalized subtree
463
System.out.println("***The children of {"+node.getNodeName()+"} are normalized");
464                     for (kid = elem.getFirstChild(); kid != null; kid = next) {
465                         next = kid.getNextSibling();
466                         System.out.println(kid.getNodeName() +"["+kid.getNodeValue()+"]");
467                     }
468                     
469                 }
470                 
471                 
472                 if (fValidationHandler != null) {
473                     updateQName(elem, fQName); // updates global qname
474
//
475
// set error node in the dom error wrapper
476
// so if error occurs we can report an error node
477
fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
478                     fCurrentNode = node;
479                     fValidationHandler.endElement(fQName, null);
480                 }
481                 if(fDTDValidator != null ){
482                     updateQName(elem, fQName); // updates global qname
483
fCurrentNode = node;
484                     fDTDValidator.endElement(fQName,null);
485                 }
486                 
487                 // pop namespace context
488
fNamespaceContext.popContext();
489                 
490                 break;
491             }
492             
493             case Node.COMMENT_NODE: {
494                 if (DEBUG_ND) {
495                     System.out.println("==>normalizeNode:{comments}");
496                 }
497                 
498                 if ((fConfiguration.features & DOMConfigurationImpl.COMMENTS) == 0) {
499                     Node JavaDoc prevSibling = node.getPreviousSibling();
500                     Node JavaDoc parent = node.getParentNode();
501                     // remove the comment node
502
parent.removeChild(node);
503                     if (prevSibling != null && prevSibling.getNodeType() == Node.TEXT_NODE) {
504                         Node JavaDoc nextSibling = prevSibling.getNextSibling();
505                         if (nextSibling != null && nextSibling.getNodeType() == Node.TEXT_NODE) {
506                             ((TextImpl)nextSibling).insertData(0, prevSibling.getNodeValue());
507                             parent.removeChild(prevSibling);
508                             return nextSibling;
509                         }
510                     }
511                 }//if comment node need not be removed
512
else {
513                     if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0)){
514                         String JavaDoc commentdata = ((Comment JavaDoc)node).getData();
515                         // check comments for invalid xml chracter as per the version
516
// of the document
517
isCommentWF(fErrorHandler, fError, fLocator, commentdata, fDocument.isXML11Version());
518                     }
519                 }//end-else if comment node is not to be removed.
520
break;
521             }
522             case Node.ENTITY_REFERENCE_NODE: {
523                 if (DEBUG_ND) {
524                     System.out.println("==>normalizeNode:{entityRef} "+node.getNodeName());
525                 }
526                 
527                 if ((fConfiguration.features & DOMConfigurationImpl.ENTITIES) == 0) {
528                     Node JavaDoc prevSibling = node.getPreviousSibling();
529                     Node JavaDoc parent = node.getParentNode();
530                     ((EntityReferenceImpl)node).setReadOnly(false, true);
531                     expandEntityRef(parent, node);
532                     parent.removeChild(node);
533                     Node JavaDoc next = (prevSibling != null)?prevSibling.getNextSibling():parent.getFirstChild();
534                     // The list of children #text -> &ent;
535
// and entity has a first child as a text
536
// we should not advance
537
if (prevSibling != null && next != null && prevSibling.getNodeType() == Node.TEXT_NODE && next.getNodeType() == Node.TEXT_NODE) {
538                         return prevSibling; // Don't advance
539
}
540                     return next;
541                 } else {
542                     if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) &&
543                     fDocument.isXMLVersionChanged()){
544                         CoreDocumentImpl.isXMLName(node.getNodeName() , fDocument.isXML11Version());
545                     }
546                     // REVISIT: traverse entity reference and send appropriate calls to the validator
547
// (no normalization should be performed for the children).
548
}
549                 break;
550             }
551             
552             case Node.CDATA_SECTION_NODE: {
553                 if (DEBUG_ND) {
554                     System.out.println("==>normalizeNode:{cdata}");
555                 }
556                 
557                 if ((fConfiguration.features & DOMConfigurationImpl.CDATA) == 0) {
558                     // convert CDATA to TEXT nodes
559
Node JavaDoc prevSibling = node.getPreviousSibling();
560                     if (prevSibling != null && prevSibling.getNodeType() == Node.TEXT_NODE){
561                         ((Text JavaDoc)prevSibling).appendData(node.getNodeValue());
562                         node.getParentNode().removeChild(node);
563                         return prevSibling; //don't advance
564
}
565                     else {
566                         Text JavaDoc text = fDocument.createTextNode(node.getNodeValue());
567                         Node JavaDoc parent = node.getParentNode();
568                         node = parent.replaceChild(text, node);
569                         return text; //don't advance
570

571                     }
572                 }
573                 
574                 // send characters call for CDATA
575
if (fValidationHandler != null) {
576                     // set error node in the dom error wrapper
577
// so if error occurs we can report an error node
578
fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
579                     fCurrentNode = node;
580                     fValidationHandler.startCDATA(null);
581                     fValidationHandler.characterData(node.getNodeValue(),null);
582                     
583                     fValidationHandler.endCDATA(null);
584                 }
585                 
586                 if(fDTDValidator != null){
587                     fCurrentNode = node;
588                     fDTDValidator.startCDATA(null);
589                     String JavaDoc st = node.getNodeValue();
590                     XMLString str = new XMLString();
591                     if(st!=null)
592                         str.setValues(st.toCharArray(),0,st.length());
593                     fDTDValidator.characters(str, null);
594                     fDTDValidator.endCDATA(null);
595                 }
596                 
597                 String JavaDoc value = node.getNodeValue();
598                 
599                 if ((fConfiguration.features & DOMConfigurationImpl.SPLITCDATA) != 0) {
600                     int index;
601                     Node JavaDoc parent = node.getParentNode();
602                     
603                     isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), fDocument.isXML11Version());
604                     while ( (index=value.indexOf("]]>")) >= 0 ) {
605                         node.setNodeValue(value.substring(0, index+2));
606                         value = value.substring(index +2);
607                         
608                         Node JavaDoc firstSplitNode = node;
609                         Node JavaDoc newChild = fDocument.createCDATASection(value);
610                         parent.insertBefore(newChild, node.getNextSibling());
611                         node = newChild;
612                         // issue warning
613
fLocator.fRelatedNode = firstSplitNode;
614                         String JavaDoc msg = DOMMessageFormatter.formatMessage(
615                             DOMMessageFormatter.DOM_DOMAIN,
616                             "cdata-sections-splitted",
617                              null);
618                         reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_WARNING,
619                             "cdata-sections-splitted");
620                     }
621                     
622                 }
623                 else {
624                     // check well-formness
625
isCDataWF(fErrorHandler, fError, fLocator, value, fDocument.isXML11Version());
626                 }
627                 break;
628             }
629             
630             case Node.TEXT_NODE: {
631                 if (DEBUG_ND) {
632                     System.out.println("==>normalizeNode(text):{"+node.getNodeValue()+"}");
633                 }
634                 // If node is a text node, we need to check for one of two
635
// conditions:
636
// 1) There is an adjacent text node
637
// 2) There is no adjacent text node, but node is
638
// an empty text node.
639
Node JavaDoc next = node.getNextSibling();
640                 // If an adjacent text node, merge it with this node
641
if ( next!=null && next.getNodeType() == Node.TEXT_NODE ) {
642                     ((Text JavaDoc)node).appendData(next.getNodeValue());
643                     node.getParentNode().removeChild( next );
644                     // We don't need to check well-formness here since we are not yet
645
// done with this node.
646

647                     return node; // Don't advance;
648
} else if (node.getNodeValue().length()==0) {
649                     // If kid is empty, remove it
650
node.getParentNode().removeChild( node );
651                 } else {
652                     // validator.characters() call and well-formness
653
// Don't send characters or check well-formness in the following cases:
654
// 1. entities is false, next child is entity reference: expand tree first
655
// 2. comments is false, and next child is comment
656
// 3. cdata is false, and next child is cdata
657

658                     short nextType = (next != null)?next.getNodeType():-1;
659                     if (nextType == -1 || !(((fConfiguration.features & DOMConfigurationImpl.ENTITIES) == 0 &&
660                     nextType == Node.ENTITY_NODE) ||
661                     ((fConfiguration.features & DOMConfigurationImpl.COMMENTS) == 0 &&
662                     nextType == Node.COMMENT_NODE) ||
663                     ((fConfiguration.features & DOMConfigurationImpl.CDATA) == 0) &&
664                     nextType == Node.CDATA_SECTION_NODE)) {
665                         if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) ){
666                             isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), fDocument.isXML11Version());
667                         }
668                         if (fValidationHandler != null) {
669                             fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
670                             fCurrentNode = node;
671                             fValidationHandler.characterData(node.getNodeValue(), null);
672                             if (DEBUG_ND) {
673                                 System.out.println("=====>characterData(),"+nextType);
674                                 
675                             }
676                         }
677                         
678                         if(fDTDValidator != null){
679                             fCurrentNode = node;
680                             String JavaDoc st = node.getNodeValue();
681                             XMLString str = new XMLString();
682                             if(st!=null)
683                                 str.setValues(st.toCharArray(),0,st.length());
684                             fDTDValidator.characters(str, null);
685                             if(isWhitespace)
686                             ((TextImpl)node).setIgnorableWhitespace(true);
687                         }
688                     }
689                     else {
690                         if (DEBUG_ND) {
691                             System.out.println("=====>don't send characters(),"+nextType);
692                             
693                         }
694                     }
695                 }
696                 break;
697             }
698             case Node.PROCESSING_INSTRUCTION_NODE: {
699                 
700                 //do the well-formed valid PI target name , data check when application has set the value of well-formed feature to true
701
if((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0 ){
702                     ProcessingInstruction JavaDoc pinode = (ProcessingInstruction JavaDoc)node ;
703                     
704                     String JavaDoc target = pinode.getTarget();
705                     //1.check PI target name
706
if(fDocument.isXML11Version()){
707                         wellformed = XML11Char.isXML11ValidName(target);
708                     }
709                     else{
710                         wellformed = XMLChar.isValidName(target);
711                     }
712                     
713                     if (!wellformed) {
714                         String JavaDoc msg = DOMMessageFormatter.formatMessage(
715                         DOMMessageFormatter.DOM_DOMAIN,
716                         "wf-invalid-character-in-node-name",
717                         new Object JavaDoc[]{"Element", node.getNodeName()});
718                         reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
719                         "wf-invalid-character-in-node-name");
720                     }
721                     
722                     //2. check PI data
723
//processing isntruction data may have certain characters
724
//which may not be valid XML character
725
isXMLCharWF(fErrorHandler, fError, fLocator, pinode.getData(), fDocument.isXML11Version());
726                 }
727             }//end case Node.PROCESSING_INSTRUCTION_NODE
728

729         }//end of switch
730
return null;
731     }//normalizeNode
732

733     protected final void expandEntityRef(Node JavaDoc parent, Node JavaDoc reference){
734         Node JavaDoc kid, next;
735         for (kid = reference.getFirstChild(); kid != null; kid = next) {
736             next = kid.getNextSibling();
737             parent.insertBefore(kid, reference);
738         }
739     }
740     
741     // fix namespaces
742
// normalize attribute values
743
// remove default attributes
744
// check attribute names if the version of the document changed.
745

746     protected final void namespaceFixUp(ElementImpl element, AttributeMap attributes){
747         if (DEBUG) {
748             System.out.println("[ns-fixup] element:" +element.getNodeName()+
749             " uri: "+element.getNamespaceURI());
750         }
751         
752         // ------------------------------------
753
// pick up local namespace declarations
754
// <xsl:stylesheet xmlns:xsl="http://xslt">
755
// <!-- add the following via DOM
756
// body is bound to http://xslt
757
// -->
758
// <xsl:body xmlns:xsl="http://bound"/>
759
//
760
// ------------------------------------
761

762         String JavaDoc value, name, uri, prefix;
763         if (attributes != null) {
764             
765             // Record all valid local declarations
766
for (int k=0; k < attributes.getLength(); k++) {
767                 Attr JavaDoc attr = (Attr JavaDoc)attributes.getItem(k);
768                 
769                 //do the name check only when version of the document was changed &
770
//application has set the value of well-formed features to true
771
if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) &&
772                 fDocument.isXMLVersionChanged()){
773                     //checkQName does checking based on the version of the document
774
fDocument.checkQName(attr.getPrefix() , attr.getLocalName()) ;
775                 }
776                 
777                 uri = attr.getNamespaceURI();
778                 if (uri != null && uri.equals(NamespaceContext.XMLNS_URI)) {
779                     // namespace attribute
780
value = attr.getNodeValue();
781                     if (value == null) {
782                         value=XMLSymbols.EMPTY_STRING;
783                     }
784                     
785                     // Check for invalid namespace declaration:
786
if (value.equals(NamespaceContext.XMLNS_URI)) {
787                         //A null value for locale is passed to formatMessage,
788
//which means that the default locale will be used
789
fLocator.fRelatedNode = attr;
790                         String JavaDoc msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,"CantBindXMLNS",null );
791                         reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR, "CantBindXMLNS");
792                     } else {
793                         // XML 1.0 Attribute value normalization
794
// value = normalizeAttributeValue(value, attr);
795
prefix = attr.getPrefix();
796                         prefix = (prefix == null ||
797                         prefix.length() == 0) ? XMLSymbols.EMPTY_STRING :fSymbolTable.addSymbol(prefix);
798                         String JavaDoc localpart = fSymbolTable.addSymbol( attr.getLocalName());
799                         if (prefix == XMLSymbols.PREFIX_XMLNS) { //xmlns:prefix
800

801                             value = fSymbolTable.addSymbol(value);
802                             if (value.length() != 0) {
803                                 fNamespaceContext.declarePrefix(localpart, value);
804                             } else {
805                                 // REVISIT: issue error on invalid declarations
806
// xmlns:foo = ""
807

808                             }
809                             //removeDefault (attr, attributes);
810
continue;
811                         } else { // (localpart == fXmlnsSymbol && prefix == fEmptySymbol) -- xmlns
812
// empty prefix is always bound ("" or some string)
813
value = fSymbolTable.addSymbol(value);
814                             fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, value);
815                             //removeDefault (attr, attributes);
816
continue;
817                         }
818                     } // end-else: valid declaration
819
} // end-if: namespace attribute
820
}
821         }
822         
823         
824         
825         // ---------------------------------------------------------
826
// Fix up namespaces for element: per DOM L3
827
// Need to consider the following cases:
828
//
829
// case 1: <xsl:stylesheet xmlns:xsl="http://xsl">
830
// We create another element body bound to the "http://xsl" namespace
831
// as well as namespace attribute rebounding xsl to another namespace.
832
// <xsl:body xmlns:xsl="http://another">
833
// Need to make sure that the new namespace decl value is changed to
834
// "http://xsl"
835
//
836
// ---------------------------------------------------------
837
// check if prefix/namespace is correct for current element
838
// ---------------------------------------------------------
839

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

950                     // XML 1.0 Attribute value normalization
951
//value = normalizeAttributeValue(value, attr);
952

953                     // reset id-attributes
954
((AttrImpl)attr).setIdAttribute(false);
955                     
956                     
957                     uri = fSymbolTable.addSymbol(uri);
958                     
959                     // find if for this prefix a URI was already declared
960
String JavaDoc declaredURI = fNamespaceContext.getURI(prefix);
961                     
962                     if (prefix == XMLSymbols.EMPTY_STRING || declaredURI != uri) {
963                         // attribute has no prefix (default namespace decl does not apply to attributes)
964
// OR
965
// attribute prefix is not declared
966
// OR
967
// conflict: attribute has a prefix that conficlicts with a binding
968
// already active in scope
969

970                         name = attr.getNodeName();
971                         // Find if any prefix for attributes namespace URI is available
972
// in the scope
973
String JavaDoc declaredPrefix = fNamespaceContext.getPrefix(uri);
974                         if (declaredPrefix !=null && declaredPrefix !=XMLSymbols.EMPTY_STRING) {
975                             
976                             // use the prefix that was found (declared previously for this URI
977
prefix = declaredPrefix;
978                         } else {
979                             if (prefix != XMLSymbols.EMPTY_STRING && fLocalNSBinder.getURI(prefix) == null) {
980                                 // the current prefix is not null and it has no in scope declaration
981

982                                 // use this prefix
983
} else {
984                                 
985                                 // find a prefix following the pattern "NS" +index (starting at 1)
986
// make sure this prefix is not declared in the current scope.
987
int counter = 1;
988                                 prefix = fSymbolTable.addSymbol(PREFIX +counter++);
989                                 while (fLocalNSBinder.getURI(prefix)!=null) {
990                                     prefix = fSymbolTable.addSymbol(PREFIX +counter++);
991                                 }
992                                 
993                             }
994                             // add declaration for the new prefix
995
addNamespaceDecl(prefix, uri, element);
996                             value = fSymbolTable.addSymbol(value);
997                             fLocalNSBinder.declarePrefix(prefix, value);
998                             fNamespaceContext.declarePrefix(prefix, uri);
999                         }
1000                        
1001                        // change prefix for this attribute
1002
attr.setPrefix(prefix);
1003                    }
1004                } else { // attribute uri == null
1005

1006                    // XML 1.0 Attribute value normalization
1007
//value = normalizeAttributeValue(value, attr);
1008

1009                    // reset id-attributes
1010
((AttrImpl)attr).setIdAttribute(false);
1011                    
1012                    if (attr.getLocalName() == null) {
1013                        // It is an error if document has DOM L1 nodes.
1014
if (fNamespaceValidation) {
1015                            String JavaDoc msg = DOMMessageFormatter.formatMessage(
1016                                DOMMessageFormatter.DOM_DOMAIN,
1017                                "NullLocalAttrName", new Object JavaDoc[]{attr.getNodeName()});
1018                            reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_FATAL_ERROR, "NullLocalAttrName");
1019                        } else {
1020                            String JavaDoc msg = DOMMessageFormatter.formatMessage(
1021                                DOMMessageFormatter.DOM_DOMAIN,
1022                                "NullLocalAttrName", new Object JavaDoc[]{attr.getNodeName()});
1023                            reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
1024                                "NullLocalAttrName");
1025                        }
1026                    } else {
1027                        // uri=null and no colon
1028
// no fix up is needed: default namespace decl does not
1029

1030                        // ---------------------------------------
1031
// remove default attributes
1032
// ---------------------------------------
1033
// removeDefault(attr, attributes);
1034
}
1035                }
1036            }
1037        } // end loop for attributes
1038
}
1039    
1040    /**
1041     * Adds a namespace attribute or replaces the value of existing namespace
1042     * attribute with the given prefix and value for URI.
1043     * In case prefix is empty will add/update default namespace declaration.
1044     *
1045     * @param prefix
1046     * @param uri
1047     * @exception IOException
1048     */

1049    
1050    protected final void addNamespaceDecl(String JavaDoc prefix, String JavaDoc uri, ElementImpl element){
1051        if (DEBUG) {
1052            System.out.println("[ns-fixup] addNamespaceDecl ["+prefix+"]");
1053        }
1054        if (prefix == XMLSymbols.EMPTY_STRING) {
1055            if (DEBUG) {
1056                System.out.println("=>add xmlns=\""+uri+"\" declaration");
1057            }
1058            element.setAttributeNS(NamespaceContext.XMLNS_URI, XMLSymbols.PREFIX_XMLNS, uri);
1059        } else {
1060            if (DEBUG) {
1061                System.out.println("=>add xmlns:"+prefix+"=\""+uri+"\" declaration");
1062            }
1063            element.setAttributeNS(NamespaceContext.XMLNS_URI, "xmlns:"+prefix, uri);
1064        }
1065    }
1066    
1067    
1068    //
1069
// Methods for well-formness checking
1070
//
1071

1072    
1073    /**
1074     * Check if CDATA section is well-formed
1075     * @param datavalue
1076     * @param isXML11Version = true if XML 1.1
1077     */

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

1152    }//isCDataWF
1153

1154    /**
1155     * NON-DOM: check for valid XML characters as per the XML version
1156     * @param datavalue
1157     * @param isXML11Version = true if XML 1.1
1158     */

1159    public static final void isXMLCharWF(DOMErrorHandler JavaDoc errorHandler, DOMErrorImpl error, DOMLocatorImpl locator,
1160    String JavaDoc datavalue, boolean isXML11Version) {
1161        if(datavalue == null || (datavalue.length() == 0) ) return ;
1162        char [] dataarray = datavalue.toCharArray();
1163        int datalength = dataarray.length ;
1164        
1165        //version of the document is XML 1.1
1166
if(isXML11Version){
1167            //we need to check all characters as per production rules of XML11
1168
int i = 0 ;
1169            while(i < datalength){
1170                if(XML11Char.isXML11Invalid(dataarray[i++])){
1171                    String JavaDoc msg = DOMMessageFormatter.formatMessage(
1172                        DOMMessageFormatter.DOM_DOMAIN, "InvalidXMLCharInDOM",
1173                        new Object JavaDoc[]{Integer.toString(dataarray[i-1], 16)});
1174                    reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR,
1175                        "wf-invalid-character");
1176                };
1177            }
1178        }//version of the document is XML 1.0
1179
else{
1180            //we need to check all characters as per production rules of XML 1.0
1181
int i = 0 ;
1182            while(i < datalength){
1183                if( XMLChar.isInvalid(dataarray[i++]) ){
1184                    String JavaDoc msg = DOMMessageFormatter.formatMessage(
1185                        DOMMessageFormatter.DOM_DOMAIN, "InvalidXMLCharInDOM",
1186                        new Object JavaDoc[]{Integer.toString(dataarray[i-1], 16)});
1187                    reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR,
1188                        "wf-invalid-character");
1189                };
1190            }
1191        }//end-else fDocument.isXMLVersion()
1192

1193    }//isXMLCharWF
1194

1195    /**
1196     * NON-DOM: check if value of the comment is well-formed
1197     * @param datavalue
1198     * @param isXML11Version = true if XML 1.1
1199     */

1200    public static final void isCommentWF(DOMErrorHandler JavaDoc errorHandler, DOMErrorImpl error, DOMLocatorImpl locator,
1201    String JavaDoc datavalue, boolean isXML11Version) {
1202        if(datavalue == null || (datavalue.length() == 0) ) return ;
1203        
1204        char [] dataarray = datavalue.toCharArray();
1205        int datalength = dataarray.length ;
1206        
1207        //version of the document is XML 1.1
1208
if(isXML11Version){
1209            //we need to check all chracters as per production rules of XML11
1210
int i = 0 ;
1211            while(i < datalength){
1212                char c = dataarray[i++];
1213                
1214                if(XML11Char.isXML11Invalid(c)){
1215                    String JavaDoc msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,
1216                        "InvalidCharInComment",
1217                        new Object JavaDoc [] {Integer.toString(dataarray[i-1], 16)});
1218                    reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
1219                }
1220                else if (c == '-' && i<datalength && dataarray[i]=='-'){
1221                    String JavaDoc msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,
1222                        "DashDashInComment", null);
1223                    // invalid: '--' in comment
1224
reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
1225                }
1226            }
1227        }//version of the document is XML 1.0
1228
else{
1229            //we need to check all chracters as per production rules of XML 1.0
1230
int i = 0 ;
1231            while(i < datalength){
1232                char c = dataarray[i++];
1233                if( XMLChar.isInvalid(c) ){
1234                    String JavaDoc msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,
1235                        "InvalidCharInComment", new Object JavaDoc [] {Integer.toString(dataarray[i-1], 16)});
1236                    reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
1237                }
1238                else if (c == '-' && i<datalength && dataarray[i]=='-'){
1239                    String JavaDoc msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,
1240                        "DashDashInComment", null);
1241                    // invalid: '--' in comment
1242
reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
1243                }
1244            }
1245            
1246        }//end-else fDocument.isXMLVersion()
1247

1248    }//isCommentWF
1249

1250    /** NON-DOM: check if attribute value is well-formed
1251     * @param attributes
1252     * @param a
1253     * @param value
1254     */

1255    public static final void isAttrValueWF(DOMErrorHandler JavaDoc errorHandler, DOMErrorImpl error,
1256    DOMLocatorImpl locator, AttributeMap attributes, AttrImpl a, String JavaDoc value, boolean xml11Version) {
1257        if (a.hasStringValue()) {
1258            isXMLCharWF(errorHandler, error, locator, value, xml11Version);
1259        } else {
1260            NodeList JavaDoc children = a.getChildNodes();
1261            //check each child node of the attribute's value
1262
for (int j = 0; j < children.getLength(); j++) {
1263                Node JavaDoc child = children.item(j);
1264                //If the attribute's child is an entity refernce
1265
if (child.getNodeType() == Node.ENTITY_REFERENCE_NODE) {
1266                    Document JavaDoc owner = a.getOwnerDocument();
1267                    Entity JavaDoc ent = null;
1268                    //search for the entity in the docType
1269
//of the attribute's ownerDocument
1270
if (owner != null) {
1271                        DocumentType JavaDoc docType = owner.getDoctype();
1272                        if (docType != null) {
1273                            NamedNodeMap JavaDoc entities = docType.getEntities();
1274                            ent = (Entity JavaDoc) entities.getNamedItemNS(
1275                            "*",
1276                            child.getNodeName());
1277                        }
1278                    }
1279                    //If the entity was not found issue a fatal error
1280
if (ent == null) {
1281                        String JavaDoc msg = DOMMessageFormatter.formatMessage(
1282                            DOMMessageFormatter.DOM_DOMAIN, "UndeclaredEntRefInAttrValue",
1283                            new Object JavaDoc[]{a.getNodeName()});
1284                        reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR,
1285                            "UndeclaredEntRefInAttrValue");
1286                    }
1287                }
1288                else {
1289                    // Text node
1290
isXMLCharWF(errorHandler, error, locator, child.getNodeValue(), xml11Version);
1291                }
1292            }
1293        }
1294    }
1295    
1296    
1297    
1298    /**
1299     * Reports a DOM error to the user handler.
1300     *
1301     * If the error is fatal, the processing will be always aborted.
1302     */

1303    public static final void reportDOMError(DOMErrorHandler JavaDoc errorHandler, DOMErrorImpl error, DOMLocatorImpl locator, String JavaDoc message, short severity, String JavaDoc type ) {
1304        if( errorHandler!=null ) {
1305            error.reset();
1306            error.fMessage = message;
1307            error.fSeverity = severity;
1308            error.fLocator = locator;
1309            error.fType = type;
1310            error.fRelatedData = locator.fRelatedNode;
1311    
1312            if(!errorHandler.handleError(error))
1313                throw abort;
1314        }
1315        if( severity==DOMError.SEVERITY_FATAL_ERROR )
1316            throw abort;
1317    }
1318    
1319    protected final void updateQName(Node JavaDoc node, QName qname){
1320        
1321        String JavaDoc prefix = node.getPrefix();
1322        String JavaDoc namespace = node.getNamespaceURI();
1323        String JavaDoc localName = node.getLocalName();
1324        // REVISIT: the symbols are added too often: start/endElement
1325
// and in the namespaceFixup. Should reduce number of calls to symbol table.
1326
qname.prefix = (prefix!=null && prefix.length()!=0)?fSymbolTable.addSymbol(prefix):null;
1327        qname.localpart = (localName != null)?fSymbolTable.addSymbol(localName):null;
1328        qname.rawname = fSymbolTable.addSymbol(node.getNodeName());
1329        qname.uri = (namespace != null)?fSymbolTable.addSymbol(namespace):null;
1330    }
1331    
1332    
1333    
1334    /* REVISIT: remove this method if DOM does not change spec.
1335     * Performs partial XML 1.0 attribute value normalization and replaces
1336     * attribute value if the value is changed after the normalization.
1337     * DOM defines that normalizeDocument acts as if the document was going
1338     * through a save and load cycle, given that serializer will not escape
1339     * any '\n' or '\r' characters on load those will be normalized.
1340     * Thus during normalize document we need to do the following:
1341     * - perform "2.11 End-of-Line Handling"
1342     * - replace #xD, #xA, #x9 with #x20 (white space).
1343     * Note: This alg. won't attempt to resolve entity references or character entity
1344     * references, since '&' will be escaped during serialization and during loading
1345     * this won't be recognized as entity reference, i.e. attribute value "&foo;" will
1346     * be serialized as "&amp;foo;" and thus after loading will be "&foo;" again.
1347     * @param value current attribute value
1348     * @param attr current attribute
1349     * @return String the value (could be original if normalization did not change
1350     * the string)
1351     */

1352    final String JavaDoc normalizeAttributeValue(String JavaDoc value, Attr JavaDoc attr) {
1353        if (!attr.getSpecified()){
1354            // specified attributes should already have a normalized form
1355
// since those were added by validator
1356
return value;
1357        }
1358        int end = value.length();
1359        // ensure capacity
1360
if (fNormalizedValue.ch.length < end) {
1361            fNormalizedValue.ch = new char[end];
1362        }
1363        fNormalizedValue.length = 0;
1364        boolean normalized = false;
1365        for (int i = 0; i < end; i++) {
1366            char c = value.charAt(i);
1367            if (c==0x0009 || c==0x000A) {
1368                fNormalizedValue.ch[fNormalizedValue.length++] = ' ';
1369                normalized = true;
1370            }
1371            else if(c==0x000D){
1372                normalized = true;
1373                fNormalizedValue.ch[fNormalizedValue.length++] = ' ';
1374                int next = i+1;
1375                if (next < end && value.charAt(next)==0x000A) i=next; // skip following xA
1376
}
1377            else {
1378                fNormalizedValue.ch[fNormalizedValue.length++] = c;
1379            }
1380        }
1381        if (normalized){
1382            value = fNormalizedValue.toString();
1383            attr.setValue(value);
1384        }
1385        return value;
1386    }
1387    
1388    protected final class XMLAttributesProxy
1389    implements XMLAttributes {
1390        protected AttributeMap fAttributes;
1391        protected CoreDocumentImpl fDocument;
1392        protected ElementImpl fElement;
1393        
1394        protected final Vector JavaDoc fAugmentations = new Vector JavaDoc(5);
1395        
1396        
1397        public void setAttributes(AttributeMap attributes, CoreDocumentImpl doc, ElementImpl elem) {
1398            fDocument = doc;
1399            fAttributes = attributes;
1400            fElement = elem;
1401            if (attributes != null) {
1402                int length = attributes.getLength();
1403                
1404                fAugmentations.setSize(length);
1405                // REVISIT: this implementation does not store any value in augmentations
1406
// and basically not keeping augs in parallel to attributes map
1407
// untill all attributes are added (default attributes)
1408
for (int i = 0; i < length; i++) {
1409                    fAugmentations.setElementAt(new AugmentationsImpl(), i);
1410                }
1411            } else {
1412                fAugmentations.setSize(0);
1413            }
1414        }
1415        
1416        
1417        /**
1418         * This method adds default declarations
1419         * @see com.sun.org.apache.xerces.internal.xni.XMLAttributes#addAttribute(QName, String, String)
1420         */

1421        public int addAttribute(QName qname, String JavaDoc attrType, String JavaDoc attrValue) {
1422            int index = fElement.getXercesAttribute(qname.uri, qname.localpart);
1423            // add defaults to the tree
1424
if (index < 0) {
1425                // the default attribute was removed by a user and needed to
1426
// be added back
1427
AttrImpl attr = (AttrImpl)
1428                ((CoreDocumentImpl) fElement.getOwnerDocument()).createAttributeNS(
1429                qname.uri,
1430                qname.rawname,
1431                qname.localpart);
1432                // REVISIT: the following should also update ID table
1433
index = fElement.setXercesAttributeNode(attr);
1434                attr.setNodeValue(attrValue);
1435                fAugmentations.insertElementAt(new AugmentationsImpl(), index);
1436                attr.setSpecified(false);
1437            }
1438            else {
1439                // default attribute is in the tree
1440
// we don't need to do anything since prefix was already fixed
1441
// at the namespace fixup time and value must be same value, otherwise
1442
// attribute will be treated as specified and we will never reach
1443
// this method.
1444

1445            }
1446            return index;
1447        }
1448        
1449        
1450        public void removeAllAttributes(){
1451            // REVISIT: implement
1452
}
1453        
1454        
1455        public void removeAttributeAt(int attrIndex){
1456            // REVISIT: implement
1457
}
1458        
1459        
1460        public int getLength(){
1461            return(fAttributes != null)?fAttributes.getLength():0;
1462        }
1463        
1464        
1465        public int getIndex(String JavaDoc qName){
1466            // REVISIT: implement
1467
return -1;
1468        }
1469        
1470        public int getIndex(String JavaDoc uri, String JavaDoc localPart){
1471            // REVISIT: implement
1472
return -1;
1473        }
1474        
1475        public void setName(int attrIndex, QName attrName){
1476            // REVISIT: implement
1477
}
1478        
1479        public void getName(int attrIndex, QName attrName){
1480            if (fAttributes !=null) {
1481                updateQName((Node JavaDoc)fAttributes.getItem(attrIndex), attrName);
1482            }
1483        }
1484        
1485        public String JavaDoc getPrefix(int index){
1486            // REVISIT: implement
1487
return null;
1488        }
1489        
1490        
1491        public String JavaDoc getURI(int index){
1492            // REVISIT: implement
1493
return null;
1494        }
1495        
1496        
1497        public String JavaDoc getLocalName(int index){
1498            Object JavaDoc ob = fAttributes.item(index);
1499            if( ob instanceof AttrNSImpl)
1500                return ((AttrNSImpl)ob).getLocalName();
1501            else
1502                return ((AttrImpl)ob).getNodeName();
1503        }
1504        
1505        
1506        public String JavaDoc getQName(int index){
1507            return fAttributes.item(index).getNodeName();
1508        }
1509        
1510        
1511        public void setType(int attrIndex, String JavaDoc attrType){
1512            // REVISIT: implement
1513
}
1514        
1515        
1516        public String JavaDoc getType(int index){
1517            return "CDATA";
1518        }
1519        
1520        
1521        public String JavaDoc getType(String JavaDoc qName){
1522            return "CDATA";
1523        }
1524        
1525        
1526        public String JavaDoc getType(String JavaDoc uri, String JavaDoc localName){
1527            return "CDATA";
1528        }
1529        
1530        
1531        public void setValue(int attrIndex, String JavaDoc attrValue){
1532            // REVISIT: is this desired behaviour?
1533
// The values are updated in the case datatype-normalization is turned on
1534
// in this case we need to make sure that specified attributes stay specified
1535

1536            if (fAttributes != null){
1537                AttrImpl attr = (AttrImpl)fAttributes.getItem(attrIndex);
1538                boolean specified = attr.getSpecified();
1539                attr.setValue(attrValue);
1540                attr.setSpecified(specified);
1541                
1542            }
1543        }
1544        
1545        
1546        public String JavaDoc getValue(int index){
1547            return (fAttributes !=null)?fAttributes.item(index).getNodeValue():"";
1548            
1549        }
1550        
1551        
1552        public String JavaDoc getValue(String JavaDoc qName){
1553            // REVISIT: implement
1554
return null;
1555        }
1556        
1557        
1558        public String JavaDoc getValue(String JavaDoc uri, String JavaDoc localName){
1559            if (fAttributes != null) {
1560                Node JavaDoc node = fAttributes.getNamedItemNS(uri, localName);
1561                return(node != null)? node.getNodeValue():null;
1562            }
1563            return null;
1564        }
1565        
1566        
1567        public void setNonNormalizedValue(int attrIndex, String JavaDoc attrValue){
1568            // REVISIT: implement
1569

1570        }
1571        
1572        
1573        public String JavaDoc getNonNormalizedValue(int attrIndex){
1574            // REVISIT: implement
1575
return null;
1576        }
1577        
1578        
1579        public void setSpecified(int attrIndex, boolean specified){
1580            AttrImpl attr = (AttrImpl)fAttributes.getItem(attrIndex);
1581            attr.setSpecified(specified);
1582        }
1583        
1584        public boolean isSpecified(int attrIndex){
1585            return((Attr JavaDoc)fAttributes.getItem(attrIndex)).getSpecified();
1586        }
1587        
1588        public Augmentations getAugmentations(int attributeIndex){
1589            return(Augmentations)fAugmentations.elementAt(attributeIndex);
1590        }
1591        
1592        public Augmentations getAugmentations(String JavaDoc uri, String JavaDoc localPart){
1593            // REVISIT: implement
1594
return null;
1595        }
1596        
1597        public Augmentations getAugmentations(String JavaDoc qName){
1598            // REVISIT: implement
1599
return null;
1600        }
1601        
1602        /**
1603         * Sets the augmentations of the attribute at the specified index.
1604         *
1605         * @param attrIndex The attribute index.
1606         * @param augs The augmentations.
1607         */

1608        public void setAugmentations(int attrIndex, Augmentations augs) {
1609            fAugmentations.setElementAt(augs, attrIndex);
1610        }
1611    }
1612    
1613    //
1614
// XMLDocumentHandler methods
1615
//
1616

1617    /**
1618     * The start of the document.
1619     *
1620     * @param locator The document locator, or null if the document
1621     * location cannot be reported during the parsing
1622     * of this document. However, it is <em>strongly</em>
1623     * recommended that a locator be supplied that can
1624     * at least report the system identifier of the
1625     * document.
1626     * @param encoding The auto-detected IANA encoding name of the entity
1627     * stream. This value will be null in those situations
1628     * where the entity encoding is not auto-detected (e.g.
1629     * internal entities or a document entity that is
1630     * parsed from a java.io.Reader).
1631     * @param namespaceContext
1632     * The namespace context in effect at the
1633     * start of this document.
1634     * This object represents the current context.
1635     * Implementors of this class are responsible
1636     * for copying the namespace bindings from the
1637     * the current context (and its parent contexts)
1638     * if that information is important.
1639     *
1640     * @param augs Additional information that may include infoset augmentations
1641     * @exception XNIException
1642     * Thrown by handler to signal an error.
1643     */

1644    public void startDocument(XMLLocator locator, String JavaDoc encoding,
1645    NamespaceContext namespaceContext,
1646    Augmentations augs)
1647    throws XNIException{
1648    }
1649    
1650    /**
1651     * Notifies of the presence of an XMLDecl line in the document. If
1652     * present, this method will be called immediately following the
1653     * startDocument call.
1654     *
1655     * @param version The XML version.
1656     * @param encoding The IANA encoding name of the document, or null if
1657     * not specified.
1658     * @param standalone The standalone value, or null if not specified.
1659     * @param augs Additional information that may include infoset augmentations
1660     *
1661     * @exception XNIException
1662     * Thrown by handler to signal an error.
1663     */

1664    public void xmlDecl(String JavaDoc version, String JavaDoc encoding, String JavaDoc standalone, Augmentations augs)
1665    throws XNIException{
1666    }
1667    
1668    /**
1669     * Notifies of the presence of the DOCTYPE line in the document.
1670     *
1671     * @param rootElement
1672     * The name of the root element.
1673     * @param publicId The public identifier if an external DTD or null
1674     * if the external DTD is specified using SYSTEM.
1675     * @param systemId The system identifier if an external DTD, null
1676     * otherwise.
1677     * @param augs Additional information that may include infoset augmentations
1678     *
1679     * @exception XNIException
1680     * Thrown by handler to signal an error.
1681     */

1682    public void doctypeDecl(String JavaDoc rootElement, String JavaDoc publicId, String JavaDoc systemId, Augmentations augs)
1683    throws XNIException{
1684    }
1685    
1686    /**
1687     * A comment.
1688     *
1689     * @param text The text in the comment.
1690     * @param augs Additional information that may include infoset augmentations
1691     *
1692     * @exception XNIException
1693     * Thrown by application to signal an error.
1694     */

1695    public void comment(XMLString text, Augmentations augs) throws XNIException{
1696    }
1697    
1698    /**
1699     * A processing instruction. Processing instructions consist of a
1700     * target name and, optionally, text data. The data is only meaningful
1701     * to the application.
1702     * <p>
1703     * Typically, a processing instruction's data will contain a series
1704     * of pseudo-attributes. These pseudo-attributes follow the form of
1705     * element attributes but are <strong>not</strong> parsed or presented
1706     * to the application as anything other than text. The application is
1707     * responsible for parsing the data.
1708     *
1709     * @param target The target.
1710     * @param data The data or null if none specified.
1711     * @param augs Additional information that may include infoset augmentations
1712     *
1713     * @exception XNIException
1714     * Thrown by handler to signal an error.
1715     */

1716    public void processingInstruction(String JavaDoc target, XMLString data, Augmentations augs)
1717    throws XNIException{
1718    }
1719    
1720    /**
1721     * The start of an element.
1722     *
1723     * @param element The name of the element.
1724     * @param attributes The element attributes.
1725     * @param augs Additional information that may include infoset augmentations
1726     *
1727     * @exception XNIException
1728     * Thrown by handler to signal an error.
1729     */

1730    public void startElement(QName element, XMLAttributes attributes, Augmentations augs)
1731    throws XNIException {
1732        Element JavaDoc currentElement = (Element JavaDoc) fCurrentNode;
1733        int attrCount = attributes.getLength();
1734        if (DEBUG_EVENTS) {
1735            System.out.println("==>startElement: " +element+
1736            " attrs.length="+attrCount);
1737        }
1738        
1739        for (int i = 0; i < attrCount; i++) {
1740            attributes.getName(i, fAttrQName);
1741            Attr JavaDoc attr = null;
1742            
1743            attr = currentElement.getAttributeNodeNS(fAttrQName.uri, fAttrQName.localpart);
1744            AttributePSVI attrPSVI =
1745            (AttributePSVI) attributes.getAugmentations(i).getItem(Constants.ATTRIBUTE_PSVI);
1746            
1747            if (attrPSVI != null) {
1748                //REVISIT: instead we should be using augmentations:
1749
// to set/retrieve Id attributes
1750
XSTypeDefinition decl = attrPSVI.getMemberTypeDefinition();
1751                boolean id = false;
1752                if (decl != null){
1753                    id = ((XSSimpleType)decl).isIDType();
1754                } else{
1755                    decl = attrPSVI.getTypeDefinition();
1756                    if (decl !=null){
1757                        id = ((XSSimpleType)decl).isIDType();
1758                    }
1759                }
1760                if (id){
1761                    ((ElementImpl)currentElement).setIdAttributeNode(attr, true);
1762                }
1763                
1764                if (fPSVI) {
1765                    ((PSVIAttrNSImpl) attr).setPSVI(attrPSVI);
1766                }
1767                if ((fConfiguration.features & DOMConfigurationImpl.DTNORMALIZATION) != 0) {
1768                    // datatype-normalization
1769
// NOTE: The specified value MUST be set after we set
1770
// the node value because that turns the "specified"
1771
// flag to "true" which may overwrite a "false"
1772
// value from the attribute list.
1773
boolean specified = attr.getSpecified();
1774                    attr.setValue(attrPSVI.getSchemaNormalizedValue());
1775                    if (!specified) {
1776                        ((AttrImpl) attr).setSpecified(specified);
1777                    }
1778                }
1779            }
1780        }
1781    }
1782    
1783    
1784    /**
1785     * An empty element.
1786     *
1787     * @param element The name of the element.
1788     * @param attributes The element attributes.
1789     * @param augs Additional information that may include infoset augmentations
1790     *
1791     * @exception XNIException
1792     * Thrown by handler to signal an error.
1793     */

1794    public void emptyElement(QName element, XMLAttributes attributes, Augmentations augs)
1795    throws XNIException {
1796        if (DEBUG_EVENTS) {
1797            System.out.println("==>emptyElement: " +element);
1798        }
1799        if(true)
1800            return;
1801        
1802        startElement(element, attributes, augs);
1803        endElement(element, augs);
1804    }
1805    
1806    /**
1807     * This method notifies the start of a general entity.
1808     * <p>
1809     * <strong>Note:</strong> This method is not called for entity references
1810     * appearing as part of attribute values.
1811     *
1812     * @param name The name of the general entity.
1813     * @param identifier The resource identifier.
1814     * @param encoding The auto-detected IANA encoding name of the entity
1815     * stream. This value will be null in those situations
1816     * where the entity encoding is not auto-detected (e.g.
1817     * internal entities or a document entity that is
1818     * parsed from a java.io.Reader).
1819     * @param augs Additional information that may include infoset augmentations
1820     *
1821     * @exception XNIException Thrown by handler to signal an error.
1822     */

1823    public void startGeneralEntity(String JavaDoc name,
1824    XMLResourceIdentifier identifier,
1825    String JavaDoc encoding,
1826    Augmentations augs) throws XNIException{
1827    }
1828    
1829    /**
1830     * Notifies of the presence of a TextDecl line in an entity. If present,
1831     * this method will be called immediately following the startEntity call.
1832     * <p>
1833     * <strong>Note:</strong> This method will never be called for the
1834     * document entity; it is only called for external general entities
1835     * referenced in document content.
1836     * <p>
1837     * <strong>Note:</strong> This method is not called for entity references
1838     * appearing as part of attribute values.
1839     *
1840     * @param version The XML version, or null if not specified.
1841     * @param encoding The IANA encoding name of the entity.
1842     * @param augs Additional information that may include infoset augmentations
1843     *
1844     * @exception XNIException
1845     * Thrown by handler to signal an error.
1846     */

1847    public void textDecl(String JavaDoc version, String JavaDoc encoding, Augmentations augs) throws XNIException{
1848    }
1849    
1850    /**
1851     * This method notifies the end of a general entity.
1852     * <p>
1853     * <strong>Note:</strong> This method is not called for entity references
1854     * appearing as part of attribute values.
1855     *
1856     * @param name The name of the entity.
1857     * @param augs Additional information that may include infoset augmentations
1858     *
1859     * @exception XNIException
1860     * Thrown by handler to signal an error.
1861     */

1862    public void endGeneralEntity(String JavaDoc name, Augmentations augs) throws XNIException{
1863    }
1864    
1865    /**
1866     * Character content.
1867     *
1868     * @param text The content.
1869     * @param augs Additional information that may include infoset augmentations
1870     *
1871     * @exception XNIException
1872     * Thrown by handler to signal an error.
1873     */

1874    public void characters(XMLString text, Augmentations augs) throws XNIException{
1875    }
1876    
1877    /**
1878     * Ignorable whitespace. For this method to be called, the document
1879     * source must have some way of determining that the text containing
1880     * only whitespace characters should be considered ignorable. For
1881     * example, the validator can determine if a length of whitespace
1882     * characters in the document are ignorable based on the element
1883     * content model.
1884     *
1885     * @param text The ignorable whitespace.
1886     * @param augs Additional information that may include infoset augmentations
1887     *
1888     * @exception XNIException
1889     * Thrown by handler to signal an error.
1890     */

1891    public void ignorableWhitespace(XMLString text, Augmentations augs) throws XNIException{
1892        if(docTypeFound){
1893            isWhitespace = true;
1894        }
1895    }
1896    
1897    /**
1898     * The end of an element.
1899     *
1900     * @param element The name of the element.
1901     * @param augs Additional information that may include infoset augmentations
1902     *
1903     * @exception XNIException
1904     * Thrown by handler to signal an error.
1905     */

1906    public void endElement(QName element, Augmentations augs) throws XNIException {
1907        if (DEBUG_EVENTS) {
1908            System.out.println("==>endElement: " + element);
1909        }
1910        if(augs == null)
1911            return;
1912        ElementPSVI elementPSVI = (ElementPSVI) augs.getItem(Constants.ELEMENT_PSVI);
1913        if (elementPSVI != null) {
1914            ElementImpl elementNode = (ElementImpl) fCurrentNode;
1915            if (fPSVI) {
1916                ((PSVIElementNSImpl) fCurrentNode).setPSVI(elementPSVI);
1917            }
1918            // include element default content (if one is available)
1919
String JavaDoc normalizedValue = elementPSVI.getSchemaNormalizedValue();
1920            if ((fConfiguration.features & DOMConfigurationImpl.DTNORMALIZATION) != 0) {
1921                if (normalizedValue !=null)
1922                    elementNode.setTextContent(normalizedValue);
1923            }
1924            else {
1925                // NOTE: this is a hack: it is possible that DOM had an empty element
1926
// and validator sent default value using characters(), which we don't
1927
// implement. Thus, here we attempt to add the default value.
1928
String JavaDoc text = elementNode.getTextContent();
1929                if (text.length() == 0) {
1930                    // default content could be provided
1931
if (normalizedValue !=null)
1932                        elementNode.setTextContent(normalizedValue);
1933                }
1934            }
1935        }
1936    }
1937    
1938    
1939    /**
1940     * The start of a CDATA section.
1941     *
1942     * @param augs Additional information that may include infoset augmentations
1943     *
1944     * @exception XNIException
1945     * Thrown by handler to signal an error.
1946     */

1947    public void startCDATA(Augmentations augs) throws XNIException{
1948    }
1949    
1950    /**
1951     * The end of a CDATA section.
1952     *
1953     * @param augs Additional information that may include infoset augmentations
1954     *
1955     * @exception XNIException
1956     * Thrown by handler to signal an error.
1957     */

1958    public void endCDATA(Augmentations augs) throws XNIException{
1959    }
1960    
1961    /**
1962     * The end of the document.
1963     *
1964     * @param augs Additional information that may include infoset augmentations
1965     *
1966     * @exception XNIException
1967     * Thrown by handler to signal an error.
1968     */

1969    public void endDocument(Augmentations augs) throws XNIException{
1970    }
1971    
1972    
1973    /** Sets the document source. */
1974    public void setDocumentSource(XMLDocumentSource source){
1975    }
1976    
1977    
1978    /** Returns the document source. */
1979    public XMLDocumentSource getDocumentSource(){
1980        return null;
1981    }
1982    
1983    public XMLGrammarPoolImpl getGrammarPool(String JavaDoc systemId, String JavaDoc internalSubset){
1984        try{
1985           
1986            XMLGrammarPreparser preparser = new XMLGrammarPreparser(fSymbolTable);
1987            XMLGrammarPoolImpl grammarPool = new XMLGrammarPoolImpl();
1988            preparser.registerPreparser(XMLGrammarDescription.XML_DTD, null);
1989            preparser.setProperty(GRAMMAR_POOL, grammarPool);
1990            preparser.setFeature(NAMESPACES_FEATURE_ID, true);
1991            preparser.setFeature(VALIDATION_FEATURE_ID, true);
1992        
1993            Grammar g = null;
1994        
1995            if(systemId != null){
1996                g = preparser.preparseGrammar(XMLGrammarDescription.XML_DTD,new XMLInputSource(null, systemId, null));
1997            }
1998        
1999            if(internalSubset != null && !internalSubset.equals("")){
2000                XMLInputSource xs = new XMLInputSource(null,systemId,null);
2001                xs.setCharacterStream(new StringReader(internalSubset));
2002                g = preparser.preparseGrammar(XMLGrammarDescription.XML_DTD,xs);
2003            }
2004            return grammarPool;
2005        }catch(Exception JavaDoc ex){
2006            if(DEBUG_ND)
2007                ex.printStackTrace();
2008        }
2009        return null;
2010    }
2011} // DOMNormalizer class
2012
Popular Tags