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. package com.sun.org.apache.xerces.internal.dom;
  58. import java.util.Vector;
  59. //--
  60. import com.sun.org.apache.xerces.internal.parsers.XMLGrammarPreparser;
  61. import com.sun.org.apache.xerces.internal.parsers.IntegratedParserConfiguration;
  62. import com.sun.org.apache.xerces.internal.util.XMLGrammarPoolImpl;
  63. import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
  64. import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
  65. import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
  66. import org.xml.sax.InputSource;
  67. //--
  68. import org.w3c.dom.DOMError;
  69. import org.w3c.dom.DOMErrorHandler;
  70. import com.sun.org.apache.xerces.internal.impl.Constants;
  71. import com.sun.org.apache.xerces.internal.impl.RevalidationHandler;
  72. import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
  73. import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
  74. import com.sun.org.apache.xerces.internal.impl.xs.util.SimpleLocator;
  75. import com.sun.org.apache.xerces.internal.util.AugmentationsImpl;
  76. import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
  77. import com.sun.org.apache.xerces.internal.util.SymbolTable;
  78. import com.sun.org.apache.xerces.internal.util.XMLSymbols;
  79. import com.sun.org.apache.xerces.internal.xni.Augmentations;
  80. import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
  81. import com.sun.org.apache.xerces.internal.xni.QName;
  82. import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
  83. import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
  84. import com.sun.org.apache.xerces.internal.xni.XMLLocator;
  85. import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
  86. import com.sun.org.apache.xerces.internal.xni.XMLString;
  87. import com.sun.org.apache.xerces.internal.xni.XNIException;
  88. import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
  89. import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
  90. import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
  91. import com.sun.org.apache.xerces.internal.xs.AttributePSVI;
  92. import com.sun.org.apache.xerces.internal.xs.ElementPSVI;
  93. import org.w3c.dom.Attr;
  94. import org.w3c.dom.Element;
  95. import org.w3c.dom.Node;
  96. import org.w3c.dom.NodeList;
  97. import org.w3c.dom.Text;
  98. import org.w3c.dom.ProcessingInstruction;
  99. import com.sun.org.apache.xerces.internal.util.XML11Char;
  100. import com.sun.org.apache.xerces.internal.util.XMLChar;
  101. import org.w3c.dom.Document;
  102. import org.w3c.dom.DocumentType;
  103. import org.w3c.dom.Entity;
  104. import org.w3c.dom.NamedNodeMap;
  105. import org.w3c.dom.Comment;
  106. import com.sun.org.apache.xerces.internal.impl.dtd.*;
  107. import java.io.*;
  108. /**
  109. * This class adds implementation for normalizeDocument method.
  110. * It acts as if the document was going through a save and load cycle, putting
  111. * the document in a "normal" form. The actual result depends on the features being set
  112. * and governing what operations actually take place. See setNormalizationFeature for details.
  113. * Noticeably this method normalizes Text nodes, makes the document "namespace wellformed",
  114. * according to the algorithm described below in pseudo code, by adding missing namespace
  115. * declaration attributes and adding or changing namespace prefixes, updates the replacement
  116. * tree of EntityReference nodes, normalizes attribute values, etc.
  117. * Mutation events, when supported, are generated to reflect the changes occuring on the
  118. * document.
  119. * See Namespace normalization for details on how namespace declaration attributes and prefixes
  120. * are normalized.
  121. *
  122. * NOTE: There is an initial support for DOM revalidation with XML Schema as a grammar.
  123. * The tree might not be validated correctly if entityReferences, CDATA sections are
  124. * present in the tree. The PSVI information is not exposed, normalized data (including element
  125. * default content is not available).
  126. *
  127. * NOTE: the implementation is experimental and methods, functionality
  128. * can be modified or removed in the future.
  129. *
  130. * @author Elena Litani, IBM
  131. * @author Neeraj Bajaj, Sun Microsystems, inc.
  132. * @version $Id: DOMNormalizer.java,v 1.54 2004/04/22 20:39:03 mrglavas Exp $
  133. */
  134. public class DOMNormalizer implements XMLDocumentHandler {
  135. //-- Added
  136. // Constants
  137. //
  138. // property IDs:
  139. /** Property identifier: symbol table. */
  140. public static final String SYMBOL_TABLE = Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
  141. /** Property identifier: grammar pool. */
  142. public static final String GRAMMAR_POOL = Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
  143. // feature ids
  144. /** Namespaces feature id (http://xml.org/sax/features/namespaces). */
  145. protected static final String NAMESPACES_FEATURE_ID = "http://xml.org/sax/features/namespaces";
  146. /** Validation feature id (http://xml.org/sax/features/validation). */
  147. protected static final String VALIDATION_FEATURE_ID = "http://xml.org/sax/features/validation";
  148. /** Schema validation feature id (http://apache.org/xml/features/validation/schema). */
  149. protected static final String SCHEMA_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/schema";
  150. /** Schema full checking feature id (http://apache.org/xml/features/validation/schema-full-checking). */
  151. protected static final String SCHEMA_FULL_CHECKING_FEATURE_ID = "http://apache.org/xml/features/validation/schema-full-checking";
  152. //--
  153. //
  154. // constants
  155. //
  156. /** Debug normalize document*/
  157. protected final static boolean DEBUG_ND = false;
  158. /** Debug namespace fix up algorithm*/
  159. protected final static boolean DEBUG = false;
  160. /** Debug document handler events */
  161. protected final static boolean DEBUG_EVENTS = false;
  162. /** prefix added by namespace fixup algorithm should follow a pattern "NS" + index*/
  163. protected final static String PREFIX = "NS";
  164. //
  165. // Data
  166. //
  167. protected DOMConfigurationImpl fConfiguration = null;
  168. protected CoreDocumentImpl fDocument = null;
  169. protected final XMLAttributesProxy fAttrProxy = new XMLAttributesProxy();
  170. protected final QName fQName = new QName();
  171. /** Validation handler represents validator instance. */
  172. protected RevalidationHandler fValidationHandler;
  173. protected XMLDTDValidator fDTDValidator;
  174. /** symbol table */
  175. protected SymbolTable fSymbolTable;
  176. /** error handler. may be null. */
  177. protected DOMErrorHandler fErrorHandler;
  178. /**
  179. * Cached {@link DOMError} impl.
  180. * The same object is re-used to report multiple errors.
  181. */
  182. private final DOMErrorImpl fError = new DOMErrorImpl();
  183. // Validation against namespace aware grammar
  184. protected boolean fNamespaceValidation = false;
  185. // Update PSVI information in the tree
  186. protected boolean fPSVI = false;
  187. /** The namespace context of this document: stores namespaces in scope */
  188. protected final NamespaceContext fNamespaceContext = new NamespaceSupport();
  189. /** Stores all namespace bindings on the current element */
  190. protected final NamespaceContext fLocalNSBinder = new NamespaceSupport();
  191. /** list of attributes */
  192. protected final Vector fAttributeList = new Vector(5,10);
  193. /** DOM Locator - for namespace fixup algorithm */
  194. protected final DOMLocatorImpl fLocator = new DOMLocatorImpl();
  195. /** for setting the PSVI */
  196. protected Node fCurrentNode = null;
  197. private QName fAttrQName = new QName();
  198. // attribute value normalization
  199. final XMLString fNormalizedValue = new XMLString(new char[16], 0, 0);
  200. /**
  201. * If the user stops the process, this exception will be thrown.
  202. */
  203. public static final RuntimeException abort = new RuntimeException();
  204. // Constructor
  205. //
  206. public boolean isWhitespace = false;
  207. public boolean docTypeFound = false;
  208. public DOMNormalizer(){}
  209. /**
  210. * Normalizes document.
  211. * Note: reset() must be called before this method.
  212. */
  213. protected void normalizeDocument(CoreDocumentImpl document, DOMConfigurationImpl config) {
  214. fDocument = document;
  215. fConfiguration = config;
  216. // intialize and reset DOMNormalizer component
  217. //
  218. fSymbolTable = (SymbolTable) fConfiguration.getProperty(DOMConfigurationImpl.SYMBOL_TABLE);
  219. // reset namespace context
  220. fNamespaceContext.reset();
  221. fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING);
  222. docTypeFound = false;
  223. if ((fConfiguration.features & DOMConfigurationImpl.VALIDATE) != 0) {
  224. String type =(String) fConfiguration.getProperty(fConfiguration.JAXP_SCHEMA_LANGUAGE);
  225. if(type != null && type.equals(Constants.NS_XMLSCHEMA))
  226. fValidationHandler = CoreDOMImplementationImpl.singleton.getValidator(XMLGrammarDescription.XML_SCHEMA);
  227. fConfiguration.setFeature(DOMConfigurationImpl.XERCES_VALIDATION, true);
  228. fConfiguration.setFeature(DOMConfigurationImpl.SCHEMA, true);
  229. // report fatal error on DOM Level 1 nodes
  230. fNamespaceValidation = true;
  231. // check if we need to fill in PSVI
  232. fPSVI = ((fConfiguration.features & DOMConfigurationImpl.PSVI) !=0)?true:false;
  233. // reset ID table
  234. fDocument.clearIdentifiers();
  235. // reset schema validator
  236. if(fValidationHandler!=null)
  237. ((XMLComponent) fValidationHandler).reset(fConfiguration);
  238. }
  239. fErrorHandler = (DOMErrorHandler) fConfiguration.getParameter(Constants.DOM_ERROR_HANDLER);
  240. if (fValidationHandler != null) {
  241. fValidationHandler.setDocumentHandler(this);
  242. fValidationHandler.startDocument( new SimpleLocator(fDocument.fDocumentURI, fDocument.fDocumentURI, -1, -1 ), fDocument.encoding, fNamespaceContext, null);
  243. }
  244. try {
  245. Node kid, next;
  246. for (kid = fDocument.getFirstChild(); kid != null; kid = next) {
  247. next = kid.getNextSibling();
  248. kid = normalizeNode(kid);
  249. if (kid != null) { // don't advance
  250. next = kid;
  251. }
  252. }
  253. // release resources
  254. if (fValidationHandler != null) {
  255. fValidationHandler.endDocument(null);
  256. CoreDOMImplementationImpl.singleton.releaseValidator(
  257. XMLGrammarDescription.XML_SCHEMA, fValidationHandler);
  258. fValidationHandler = null;
  259. }
  260. }
  261. catch (RuntimeException e) {
  262. if(DEBUG_ND) e.printStackTrace();
  263. if( e==abort )
  264. return; // processing aborted by the user
  265. throw e; // otherwise re-throw.
  266. }
  267. }
  268. /**
  269. *
  270. * This method acts as if the document was going through a save
  271. * and load cycle, putting the document in a "normal" form. The actual result
  272. * depends on the features being set and governing what operations actually
  273. * take place. See setNormalizationFeature for details. Noticeably this method
  274. * normalizes Text nodes, makes the document "namespace wellformed",
  275. * according to the algorithm described below in pseudo code, by adding missing
  276. * namespace declaration attributes and adding or changing namespace prefixes, updates
  277. * the replacement tree of EntityReference nodes,normalizes attribute values, etc.
  278. *
  279. * @param node Modified node or null. If node is returned, we need
  280. * to normalize again starting on the node returned.
  281. * @return the normalized Node
  282. */
  283. protected Node normalizeNode(Node node){
  284. int type = node.getNodeType();
  285. boolean wellformed;
  286. fLocator.fRelatedNode=node;
  287. switch (type) {
  288. case Node.DOCUMENT_TYPE_NODE: {
  289. if (DEBUG_ND) {
  290. System.out.println("==>normalizeNode:{doctype}");
  291. }
  292. fDTDValidator =(XMLDTDValidator) CoreDOMImplementationImpl.singleton.getDTDValidator();
  293. DocumentTypeImpl docNode = (DocumentTypeImpl)node;
  294. if(fDTDValidator != null){
  295. //fix me :
  296. fConfiguration.setFeature(DOMConfigurationImpl.XERCES_VALIDATION, false);
  297. fDTDValidator.startDocument( new SimpleLocator(fDocument.fDocumentURI, fDocument.fDocumentURI, -1, -1 ), fDocument.encoding, fNamespaceContext, null);
  298. if (DEBUG_ND)
  299. System.out.println("Internal subset is "+docNode.getInternalSubset());
  300. XMLGrammarPoolImpl grammarPool = getGrammarPool(docNode.getSystemId(),docNode.getInternalSubset());
  301. fConfiguration.setProperty(GRAMMAR_POOL, grammarPool);
  302. fDTDValidator.setDocumentHandler(this);
  303. ((XMLComponent) fDTDValidator).reset(fConfiguration);
  304. fDTDValidator.doctypeDecl(docNode.getName(),docNode.getPublicId(),docNode.getSystemId(),null);
  305. docTypeFound = true;
  306. }
  307. //REVISIT: well-formness encoding info
  308. break;
  309. }
  310. case Node.ELEMENT_NODE: {
  311. if (DEBUG_ND) {
  312. System.out.println("==>normalizeNode:{element} "+node.getNodeName());
  313. }
  314. //do the name check only when version of the document was changed &
  315. //application has set the value of well-formed features to true
  316. if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) &&
  317. fDocument.isXMLVersionChanged()){
  318. if(fNamespaceValidation){
  319. wellformed = CoreDocumentImpl.isValidQName(node.getPrefix() , node.getLocalName(), fDocument.isXML11Version()) ;
  320. }
  321. else{
  322. wellformed = CoreDocumentImpl.isXMLName(node.getNodeName() , fDocument.isXML11Version());
  323. }
  324. if (!wellformed){
  325. String msg = DOMMessageFormatter.formatMessage(
  326. DOMMessageFormatter.DOM_DOMAIN,
  327. "wf-invalid-character-in-node-name",
  328. new Object[]{"Element", node.getNodeName()});
  329. reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
  330. "wf-invalid-character-in-node-name");
  331. }
  332. }
  333. // push namespace context
  334. fNamespaceContext.pushContext();
  335. fLocalNSBinder.reset();
  336. ElementImpl elem = (ElementImpl)node;
  337. if (elem.needsSyncChildren()) {
  338. elem.synchronizeChildren();
  339. }
  340. AttributeMap attributes = (elem.hasAttributes()) ? (AttributeMap) elem.getAttributes() : null;
  341. // fix namespaces and remove default attributes
  342. if ((fConfiguration.features & DOMConfigurationImpl.NAMESPACES) !=0) {
  343. // fix namespaces
  344. // normalize attribute values
  345. // remove default attributes
  346. namespaceFixUp(elem, attributes);
  347. } else {
  348. if ( attributes!=null ) {
  349. for ( int i=0; i<attributes.getLength(); ++i ) {
  350. Attr attr = (Attr)attributes.item(i);
  351. //removeDefault(attr, attributes);
  352. attr.normalize();
  353. if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0)){
  354. isAttrValueWF(fErrorHandler, fError, fLocator, attributes, (AttrImpl)attr, attr.getValue(), fDocument.isXML11Version());
  355. if (fDocument.isXMLVersionChanged()){
  356. wellformed=CoreDocumentImpl.isXMLName(node.getNodeName() , fDocument.isXML11Version());
  357. if (!wellformed){
  358. String msg = DOMMessageFormatter.formatMessage(
  359. DOMMessageFormatter.DOM_DOMAIN,
  360. "wf-invalid-character-in-node-name",
  361. new Object[]{"Attr",node.getNodeName()});
  362. reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
  363. "wf-invalid-character-in-node-name");
  364. }
  365. }
  366. }
  367. }
  368. }
  369. }
  370. if (fValidationHandler != null) {
  371. // REVISIT: possible solutions to discard default content are:
  372. // either we pass some flag to XML Schema validator
  373. // or rely on the PSVI information.
  374. fAttrProxy.setAttributes(attributes, fDocument, elem);
  375. updateQName(elem, fQName); // updates global qname
  376. // set error node in the dom error wrapper
  377. // so if error occurs we can report an error node
  378. fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
  379. fCurrentNode = node;
  380. // call re-validation handler
  381. fValidationHandler.startElement(fQName, fAttrProxy, null);
  382. }
  383. if(fDTDValidator != null){
  384. if(attributes!=null)
  385. fAttrProxy.setAttributes(attributes, fDocument, elem);
  386. updateQName(elem, fQName); // updates global qname
  387. fCurrentNode = node;
  388. fDTDValidator.startElement(fQName, fAttrProxy, null);
  389. }
  390. // normalize children
  391. Node kid, next;
  392. for (kid = elem.getFirstChild(); kid != null; kid = next) {
  393. next = kid.getNextSibling();
  394. kid = normalizeNode(kid);
  395. if (kid !=null) {
  396. next = kid; // don't advance
  397. }
  398. }
  399. if (DEBUG_ND) {
  400. // normalized subtree
  401. System.out.println("***The children of {"+node.getNodeName()+"} are normalized");
  402. for (kid = elem.getFirstChild(); kid != null; kid = next) {
  403. next = kid.getNextSibling();
  404. System.out.println(kid.getNodeName() +"["+kid.getNodeValue()+"]");
  405. }
  406. }
  407. if (fValidationHandler != null) {
  408. updateQName(elem, fQName); // updates global qname
  409. //
  410. // set error node in the dom error wrapper
  411. // so if error occurs we can report an error node
  412. fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
  413. fCurrentNode = node;
  414. fValidationHandler.endElement(fQName, null);
  415. }
  416. if(fDTDValidator != null ){
  417. updateQName(elem, fQName); // updates global qname
  418. fCurrentNode = node;
  419. fDTDValidator.endElement(fQName,null);
  420. }
  421. // pop namespace context
  422. fNamespaceContext.popContext();
  423. break;
  424. }
  425. case Node.COMMENT_NODE: {
  426. if (DEBUG_ND) {
  427. System.out.println("==>normalizeNode:{comments}");
  428. }
  429. if ((fConfiguration.features & DOMConfigurationImpl.COMMENTS) == 0) {
  430. Node prevSibling = node.getPreviousSibling();
  431. Node parent = node.getParentNode();
  432. // remove the comment node
  433. parent.removeChild(node);
  434. if (prevSibling != null && prevSibling.getNodeType() == Node.TEXT_NODE) {
  435. Node nextSibling = prevSibling.getNextSibling();
  436. if (nextSibling != null && nextSibling.getNodeType() == Node.TEXT_NODE) {
  437. ((TextImpl)nextSibling).insertData(0, prevSibling.getNodeValue());
  438. parent.removeChild(prevSibling);
  439. return nextSibling;
  440. }
  441. }
  442. }//if comment node need not be removed
  443. else {
  444. if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0)){
  445. String commentdata = ((Comment)node).getData();
  446. // check comments for invalid xml chracter as per the version
  447. // of the document
  448. isCommentWF(fErrorHandler, fError, fLocator, commentdata, fDocument.isXML11Version());
  449. }
  450. }//end-else if comment node is not to be removed.
  451. break;
  452. }
  453. case Node.ENTITY_REFERENCE_NODE: {
  454. if (DEBUG_ND) {
  455. System.out.println("==>normalizeNode:{entityRef} "+node.getNodeName());
  456. }
  457. if ((fConfiguration.features & DOMConfigurationImpl.ENTITIES) == 0) {
  458. Node prevSibling = node.getPreviousSibling();
  459. Node parent = node.getParentNode();
  460. ((EntityReferenceImpl)node).setReadOnly(false, true);
  461. expandEntityRef(parent, node);
  462. parent.removeChild(node);
  463. Node next = (prevSibling != null)?prevSibling.getNextSibling():parent.getFirstChild();
  464. // The list of children #text -> &ent;
  465. // and entity has a first child as a text
  466. // we should not advance
  467. if (prevSibling != null && next != null && prevSibling.getNodeType() == Node.TEXT_NODE && next.getNodeType() == Node.TEXT_NODE) {
  468. return prevSibling; // Don't advance
  469. }
  470. return next;
  471. } else {
  472. if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) &&
  473. fDocument.isXMLVersionChanged()){
  474. CoreDocumentImpl.isXMLName(node.getNodeName() , fDocument.isXML11Version());
  475. }
  476. // REVISIT: traverse entity reference and send appropriate calls to the validator
  477. // (no normalization should be performed for the children).
  478. }
  479. break;
  480. }
  481. case Node.CDATA_SECTION_NODE: {
  482. if (DEBUG_ND) {
  483. System.out.println("==>normalizeNode:{cdata}");
  484. }
  485. if ((fConfiguration.features & DOMConfigurationImpl.CDATA) == 0) {
  486. // convert CDATA to TEXT nodes
  487. Node prevSibling = node.getPreviousSibling();
  488. if (prevSibling != null && prevSibling.getNodeType() == Node.TEXT_NODE){
  489. ((Text)prevSibling).appendData(node.getNodeValue());
  490. node.getParentNode().removeChild(node);
  491. return prevSibling; //don't advance
  492. }
  493. else {
  494. Text text = fDocument.createTextNode(node.getNodeValue());
  495. Node parent = node.getParentNode();
  496. node = parent.replaceChild(text, node);
  497. return text; //don't advance
  498. }
  499. }
  500. // send characters call for CDATA
  501. if (fValidationHandler != null) {
  502. // set error node in the dom error wrapper
  503. // so if error occurs we can report an error node
  504. fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
  505. fCurrentNode = node;
  506. fValidationHandler.startCDATA(null);
  507. fValidationHandler.characterData(node.getNodeValue(),null);
  508. fValidationHandler.endCDATA(null);
  509. }
  510. if(fDTDValidator != null){
  511. fCurrentNode = node;
  512. fDTDValidator.startCDATA(null);
  513. String st = node.getNodeValue();
  514. XMLString str = new XMLString();
  515. if(st!=null)
  516. str.setValues(st.toCharArray(),0,st.length());
  517. fDTDValidator.characters(str, null);
  518. fDTDValidator.endCDATA(null);
  519. }
  520. String value = node.getNodeValue();
  521. if ((fConfiguration.features & DOMConfigurationImpl.SPLITCDATA) != 0) {
  522. int index;
  523. Node parent = node.getParentNode();
  524. isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), fDocument.isXML11Version());
  525. while ( (index=value.indexOf("]]>")) >= 0 ) {
  526. node.setNodeValue(value.substring(0, index+2));
  527. value = value.substring(index +2);
  528. Node firstSplitNode = node;
  529. Node newChild = fDocument.createCDATASection(value);
  530. parent.insertBefore(newChild, node.getNextSibling());
  531. node = newChild;
  532. // issue warning
  533. fLocator.fRelatedNode = firstSplitNode;
  534. String msg = DOMMessageFormatter.formatMessage(
  535. DOMMessageFormatter.DOM_DOMAIN,
  536. "cdata-sections-splitted",
  537. null);
  538. reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_WARNING,
  539. "cdata-sections-splitted");
  540. }
  541. }
  542. else {
  543. // check well-formness
  544. isCDataWF(fErrorHandler, fError, fLocator, value, fDocument.isXML11Version());
  545. }
  546. break;
  547. }
  548. case Node.TEXT_NODE: {
  549. if (DEBUG_ND) {
  550. System.out.println("==>normalizeNode(text):{"+node.getNodeValue()+"}");
  551. }
  552. // If node is a text node, we need to check for one of two
  553. // conditions:
  554. // 1) There is an adjacent text node
  555. // 2) There is no adjacent text node, but node is
  556. // an empty text node.
  557. Node next = node.getNextSibling();
  558. // If an adjacent text node, merge it with this node
  559. if ( next!=null && next.getNodeType() == Node.TEXT_NODE ) {
  560. ((Text)node).appendData(next.getNodeValue());
  561. node.getParentNode().removeChild( next );
  562. // We don't need to check well-formness here since we are not yet
  563. // done with this node.
  564. return node; // Don't advance;
  565. } else if (node.getNodeValue().length()==0) {
  566. // If kid is empty, remove it
  567. node.getParentNode().removeChild( node );
  568. } else {
  569. // validator.characters() call and well-formness
  570. // Don't send characters or check well-formness in the following cases:
  571. // 1. entities is false, next child is entity reference: expand tree first
  572. // 2. comments is false, and next child is comment
  573. // 3. cdata is false, and next child is cdata
  574. short nextType = (next != null)?next.getNodeType():-1;
  575. if (nextType == -1 || !(((fConfiguration.features & DOMConfigurationImpl.ENTITIES) == 0 &&
  576. nextType == Node.ENTITY_NODE) ||
  577. ((fConfiguration.features & DOMConfigurationImpl.COMMENTS) == 0 &&
  578. nextType == Node.COMMENT_NODE) ||
  579. ((fConfiguration.features & DOMConfigurationImpl.CDATA) == 0) &&
  580. nextType == Node.CDATA_SECTION_NODE)) {
  581. if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) ){
  582. isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), fDocument.isXML11Version());
  583. }
  584. if (fValidationHandler != null) {
  585. fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
  586. fCurrentNode = node;
  587. fValidationHandler.characterData(node.getNodeValue(), null);
  588. if (DEBUG_ND) {
  589. System.out.println("=====>characterData(),"+nextType);
  590. }
  591. }
  592. if(fDTDValidator != null){
  593. fCurrentNode = node;
  594. String st = node.getNodeValue();
  595. XMLString str = new XMLString();
  596. if(st!=null)
  597. str.setValues(st.toCharArray(),0,st.length());
  598. fDTDValidator.characters(str, null);
  599. if(isWhitespace)
  600. ((TextImpl)node).setIgnorableWhitespace(true);
  601. }
  602. }
  603. else {
  604. if (DEBUG_ND) {
  605. System.out.println("=====>don't send characters(),"+nextType);
  606. }
  607. }
  608. }
  609. break;
  610. }
  611. case Node.PROCESSING_INSTRUCTION_NODE: {
  612. //do the well-formed valid PI target name , data check when application has set the value of well-formed feature to true
  613. if((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0 ){
  614. ProcessingInstruction pinode = (ProcessingInstruction)node ;
  615. String target = pinode.getTarget();
  616. //1.check PI target name
  617. if(fDocument.isXML11Version()){
  618. wellformed = XML11Char.isXML11ValidName(target);
  619. }
  620. else{
  621. wellformed = XMLChar.isValidName(target);
  622. }
  623. if (!wellformed) {
  624. String msg = DOMMessageFormatter.formatMessage(
  625. DOMMessageFormatter.DOM_DOMAIN,
  626. "wf-invalid-character-in-node-name",
  627. new Object[]{"Element", node.getNodeName()});
  628. reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
  629. "wf-invalid-character-in-node-name");
  630. }
  631. //2. check PI data
  632. //processing isntruction data may have certain characters
  633. //which may not be valid XML character
  634. isXMLCharWF(fErrorHandler, fError, fLocator, pinode.getData(), fDocument.isXML11Version());
  635. }
  636. }//end case Node.PROCESSING_INSTRUCTION_NODE
  637. }//end of switch
  638. return null;
  639. }//normalizeNode
  640. protected final void expandEntityRef(Node parent, Node reference){
  641. Node kid, next;
  642. for (kid = reference.getFirstChild(); kid != null; kid = next) {
  643. next = kid.getNextSibling();
  644. parent.insertBefore(kid, reference);
  645. }
  646. }
  647. // fix namespaces
  648. // normalize attribute values
  649. // remove default attributes
  650. // check attribute names if the version of the document changed.
  651. protected final void namespaceFixUp(ElementImpl element, AttributeMap attributes){
  652. if (DEBUG) {
  653. System.out.println("[ns-fixup] element:" +element.getNodeName()+
  654. " uri: "+element.getNamespaceURI());
  655. }
  656. // ------------------------------------
  657. // pick up local namespace declarations
  658. // <xsl:stylesheet xmlns:xsl="http://xslt">
  659. // <!-- add the following via DOM
  660. // body is bound to http://xslt
  661. // -->
  662. // <xsl:body xmlns:xsl="http://bound"/>
  663. //
  664. // ------------------------------------
  665. String value, name, uri, prefix;
  666. if (attributes != null) {
  667. // Record all valid local declarations
  668. for (int k=0; k < attributes.getLength(); k++) {
  669. Attr attr = (Attr)attributes.getItem(k);
  670. //do the name check only when version of the document was changed &
  671. //application has set the value of well-formed features to true
  672. if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) &&
  673. fDocument.isXMLVersionChanged()){
  674. //checkQName does checking based on the version of the document
  675. fDocument.checkQName(attr.getPrefix() , attr.getLocalName()) ;
  676. }
  677. uri = attr.getNamespaceURI();
  678. if (uri != null && uri.equals(NamespaceContext.XMLNS_URI)) {
  679. // namespace attribute
  680. value = attr.getNodeValue();
  681. if (value == null) {
  682. value=XMLSymbols.EMPTY_STRING;
  683. }
  684. // Check for invalid namespace declaration:
  685. if (value.equals(NamespaceContext.XMLNS_URI)) {
  686. //A null value for locale is passed to formatMessage,
  687. //which means that the default locale will be used
  688. fLocator.fRelatedNode = attr;
  689. String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,"CantBindXMLNS",null );
  690. reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR, "CantBindXMLNS");
  691. } else {
  692. // XML 1.0 Attribute value normalization
  693. // value = normalizeAttributeValue(value, attr);
  694. prefix = attr.getPrefix();
  695. prefix = (prefix == null ||
  696. prefix.length() == 0) ? XMLSymbols.EMPTY_STRING :fSymbolTable.addSymbol(prefix);
  697. String localpart = fSymbolTable.addSymbol( attr.getLocalName());
  698. if (prefix == XMLSymbols.PREFIX_XMLNS) { //xmlns:prefix
  699. value = fSymbolTable.addSymbol(value);
  700. if (value.length() != 0) {
  701. fNamespaceContext.declarePrefix(localpart, value);
  702. } else {
  703. // REVISIT: issue error on invalid declarations
  704. // xmlns:foo = ""
  705. }
  706. //removeDefault (attr, attributes);
  707. continue;
  708. } else { // (localpart == fXmlnsSymbol && prefix == fEmptySymbol) -- xmlns
  709. // empty prefix is always bound ("" or some string)
  710. value = fSymbolTable.addSymbol(value);
  711. fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, value);
  712. //removeDefault (attr, attributes);
  713. continue;
  714. }
  715. } // end-else: valid declaration
  716. } // end-if: namespace attribute
  717. }
  718. }
  719. // ---------------------------------------------------------
  720. // Fix up namespaces for element: per DOM L3
  721. // Need to consider the following cases:
  722. //
  723. // case 1: <xsl:stylesheet xmlns:xsl="http://xsl">
  724. // We create another element body bound to the "http://xsl" namespace
  725. // as well as namespace attribute rebounding xsl to another namespace.
  726. // <xsl:body xmlns:xsl="http://another">
  727. // Need to make sure that the new namespace decl value is changed to
  728. // "http://xsl"
  729. //
  730. // ---------------------------------------------------------
  731. // check if prefix/namespace is correct for current element
  732. // ---------------------------------------------------------
  733. uri = element.getNamespaceURI();
  734. prefix = element.getPrefix();
  735. if (uri != null) { // Element has a namespace
  736. uri = fSymbolTable.addSymbol(uri);
  737. prefix = (prefix == null ||
  738. prefix.length() == 0) ? XMLSymbols.EMPTY_STRING :fSymbolTable.addSymbol(prefix);
  739. if (fNamespaceContext.getURI(prefix) == uri) {
  740. // The xmlns:prefix=namespace or xmlns="default" was declared at parent.
  741. // The binder always stores mapping of empty prefix to "".
  742. } else {
  743. // the prefix is either undeclared
  744. // or
  745. // conflict: the prefix is bound to another URI
  746. addNamespaceDecl(prefix, uri, element);
  747. fLocalNSBinder.declarePrefix(prefix, uri);
  748. fNamespaceContext.declarePrefix(prefix, uri);
  749. }
  750. } else { // Element has no namespace
  751. if (element.getLocalName() == null) {
  752. // Error: DOM Level 1 node!
  753. if (fNamespaceValidation) {
  754. String msg = DOMMessageFormatter.formatMessage(
  755. DOMMessageFormatter.DOM_DOMAIN, "NullLocalElementName",
  756. new Object[]{element.getNodeName()});
  757. reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_FATAL_ERROR,
  758. "NullLocalElementName");
  759. } else {
  760. String msg = DOMMessageFormatter.formatMessage(
  761. DOMMessageFormatter.DOM_DOMAIN, "NullLocalElementName",
  762. new Object[]{element.getNodeName()});
  763. reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
  764. "NullLocalElementName");
  765. }
  766. } else { // uri=null and no colon (DOM L2 node)
  767. uri = fNamespaceContext.getURI(XMLSymbols.EMPTY_STRING);
  768. if (uri !=null && uri.length() > 0) {
  769. // undeclare default namespace declaration (before that element
  770. // bound to non-zero length uir), but adding xmlns="" decl
  771. addNamespaceDecl(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING, element);
  772. fLocalNSBinder.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING);
  773. fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING);
  774. }
  775. }
  776. }
  777. // -----------------------------------------
  778. // Fix up namespaces for attributes: per DOM L3
  779. // check if prefix/namespace is correct the attributes
  780. // -----------------------------------------
  781. if (attributes != null) {
  782. // clone content of the attributes
  783. attributes.cloneMap(fAttributeList);
  784. for (int i = 0; i < fAttributeList.size(); i++) {
  785. Attr attr = (Attr) fAttributeList.elementAt(i);
  786. fLocator.fRelatedNode = attr;
  787. if (DEBUG) {
  788. System.out.println("==>[ns-fixup] process attribute: "+attr.getNodeName());
  789. }
  790. // normalize attribute value
  791. attr.normalize();
  792. value = attr.getValue();
  793. name = attr.getNodeName();
  794. uri = attr.getNamespaceURI();
  795. // make sure that value is never null.
  796. if (value == null) {
  797. value=XMLSymbols.EMPTY_STRING;
  798. }
  799. if (uri != null) { // attribute has namespace !=null
  800. prefix = attr.getPrefix();
  801. prefix = (prefix == null ||
  802. prefix.length() == 0) ? XMLSymbols.EMPTY_STRING :fSymbolTable.addSymbol(prefix);
  803. /*String localpart =*/ fSymbolTable.addSymbol( attr.getLocalName());
  804. // ---------------------------------------
  805. // skip namespace declarations
  806. // ---------------------------------------
  807. // REVISIT: can we assume that "uri" is from some symbol
  808. // table, and compare by reference? -SG
  809. if (uri != null && uri.equals(NamespaceContext.XMLNS_URI)) {
  810. continue;
  811. }
  812. //---------------------------------------
  813. // check if value of the attribute is namespace well-formed
  814. //---------------------------------------
  815. if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0)){
  816. isAttrValueWF(fErrorHandler, fError, fLocator, attributes, (AttrImpl)attr, attr.getValue(), fDocument.isXML11Version());
  817. if (fDocument.isXMLVersionChanged()){
  818. boolean wellformed=CoreDocumentImpl.isXMLName(attr.getNodeName() , fDocument.isXML11Version());
  819. if (!wellformed){
  820. String msg = DOMMessageFormatter.formatMessage(
  821. DOMMessageFormatter.DOM_DOMAIN,
  822. "wf-invalid-character-in-node-name",
  823. new Object[]{"Attribute", attr.getNodeName()});
  824. reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character-in-node-name");
  825. }
  826. }
  827. }
  828. // ---------------------------------------
  829. // remove default attributes
  830. // ---------------------------------------
  831. /*
  832. if (removeDefault(attr, attributes)) {
  833. continue;
  834. }
  835. */
  836. // XML 1.0 Attribute value normalization
  837. //value = normalizeAttributeValue(value, attr);
  838. // reset id-attributes
  839. ((AttrImpl)attr).setIdAttribute(false);
  840. uri = fSymbolTable.addSymbol(uri);
  841. // find if for this prefix a URI was already declared
  842. String declaredURI = fNamespaceContext.getURI(prefix);
  843. if (prefix == XMLSymbols.EMPTY_STRING || declaredURI != uri) {
  844. // attribute has no prefix (default namespace decl does not apply to attributes)
  845. // OR
  846. // attribute prefix is not declared
  847. // OR
  848. // conflict: attribute has a prefix that conficlicts with a binding
  849. // already active in scope
  850. name = attr.getNodeName();
  851. // Find if any prefix for attributes namespace URI is available
  852. // in the scope
  853. String declaredPrefix = fNamespaceContext.getPrefix(uri);
  854. if (declaredPrefix !=null && declaredPrefix !=XMLSymbols.EMPTY_STRING) {
  855. // use the prefix that was found (declared previously for this URI
  856. prefix = declaredPrefix;
  857. } else {
  858. if (prefix != XMLSymbols.EMPTY_STRING && fLocalNSBinder.getURI(prefix) == null) {
  859. // the current prefix is not null and it has no in scope declaration
  860. // use this prefix
  861. } else {
  862. // find a prefix following the pattern "NS" +index (starting at 1)
  863. // make sure this prefix is not declared in the current scope.
  864. int counter = 1;
  865. prefix = fSymbolTable.addSymbol(PREFIX +counter++);
  866. while (fLocalNSBinder.getURI(prefix)!=null) {
  867. prefix = fSymbolTable.addSymbol(PREFIX +counter++);
  868. }
  869. }
  870. // add declaration for the new prefix
  871. addNamespaceDecl(prefix, uri, element);
  872. value = fSymbolTable.addSymbol(value);
  873. fLocalNSBinder.declarePrefix(prefix, value);
  874. fNamespaceContext.declarePrefix(prefix, uri);
  875. }
  876. // change prefix for this attribute
  877. attr.setPrefix(prefix);
  878. }
  879. } else { // attribute uri == null
  880. // XML 1.0 Attribute value normalization
  881. //value = normalizeAttributeValue(value, attr);
  882. // reset id-attributes
  883. ((AttrImpl)attr).setIdAttribute(false);
  884. if (attr.getLocalName() == null) {
  885. // It is an error if document has DOM L1 nodes.
  886. if (fNamespaceValidation) {
  887. String msg = DOMMessageFormatter.formatMessage(
  888. DOMMessageFormatter.DOM_DOMAIN,
  889. "NullLocalAttrName", new Object[]{attr.getNodeName()});
  890. reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_FATAL_ERROR, "NullLocalAttrName");
  891. } else {
  892. String msg = DOMMessageFormatter.formatMessage(
  893. DOMMessageFormatter.DOM_DOMAIN,
  894. "NullLocalAttrName", new Object[]{attr.getNodeName()});
  895. reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
  896. "NullLocalAttrName");
  897. }
  898. } else {
  899. // uri=null and no colon
  900. // no fix up is needed: default namespace decl does not
  901. // ---------------------------------------
  902. // remove default attributes
  903. // ---------------------------------------
  904. // removeDefault(attr, attributes);
  905. }
  906. }
  907. }
  908. } // end loop for attributes
  909. }
  910. /**
  911. * Adds a namespace attribute or replaces the value of existing namespace
  912. * attribute with the given prefix and value for URI.
  913. * In case prefix is empty will add/update default namespace declaration.
  914. *
  915. * @param prefix
  916. * @param uri
  917. * @exception IOException
  918. */
  919. protected final void addNamespaceDecl(String prefix, String uri, ElementImpl element){
  920. if (DEBUG) {
  921. System.out.println("[ns-fixup] addNamespaceDecl ["+prefix+"]");
  922. }
  923. if (prefix == XMLSymbols.EMPTY_STRING) {
  924. if (DEBUG) {
  925. System.out.println("=>add xmlns=\""+uri+"\" declaration");
  926. }
  927. element.setAttributeNS(NamespaceContext.XMLNS_URI, XMLSymbols.PREFIX_XMLNS, uri);
  928. } else {
  929. if (DEBUG) {
  930. System.out.println("=>add xmlns:"+prefix+"=\""+uri+"\" declaration");
  931. }
  932. element.setAttributeNS(NamespaceContext.XMLNS_URI, "xmlns:"+prefix, uri);
  933. }
  934. }
  935. //
  936. // Methods for well-formness checking
  937. //
  938. /**
  939. * Check if CDATA section is well-formed
  940. * @param datavalue
  941. * @param isXML11Version = true if XML 1.1
  942. */
  943. public static final void isCDataWF(DOMErrorHandler errorHandler, DOMErrorImpl error, DOMLocatorImpl locator,
  944. String datavalue, boolean isXML11Version) {
  945. if(datavalue == null || (datavalue.length() == 0) ) return ;
  946. char [] dataarray = datavalue.toCharArray();
  947. int datalength = dataarray.length ;
  948. //version of the document is XML 1.1
  949. if(isXML11Version){
  950. //we need to check all chracters as per production rules of XML11
  951. int i = 0 ;
  952. while(i < datalength){
  953. char c = dataarray[i++];
  954. if(XML11Char.isXML11Invalid(c)){
  955. String msg =
  956. DOMMessageFormatter.formatMessage(
  957. DOMMessageFormatter.XML_DOMAIN,
  958. "InvalidCharInCDSect",
  959. new Object[] { Integer.toString(c, 16)});
  960. reportDOMError(
  961. errorHandler,
  962. error,
  963. locator,
  964. msg,
  965. DOMError.SEVERITY_ERROR,
  966. "wf-invalid-character");
  967. }
  968. else if (c==']'){
  969. int count = i;
  970. if (count<datalength && dataarray[count]==']'){
  971. while (++count <datalength && dataarray[count]==']'){
  972. // do nothing
  973. }
  974. if (count <datalength && dataarray[count]=='>'){
  975. //CDEndInContent
  976. String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,
  977. "CDEndInContent", null);
  978. reportDOMError(errorHandler, error, locator,msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
  979. }
  980. }
  981. }
  982. }
  983. }//version of the document is XML 1.0
  984. else{
  985. //we need to check all chracters as per production rules of XML 1.0
  986. int i = 0 ;
  987. while(i < datalength){
  988. char c = dataarray[i++];
  989. if( XMLChar.isInvalid(c) ){
  990. //Note: The key InvalidCharInCDSect from XMLMessages.properties
  991. //is being used to obtain the message and DOM error type
  992. //"wf-invalid-character" is used. Also per DOM it is error but
  993. //as per XML spec. it is fatal error
  994. String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN, "InvalidCharInCDSect", new Object[]{Integer.toString(c, 16)});
  995. reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR,
  996. "wf-invalid-character");
  997. }
  998. else if (c==']'){
  999. int count = i;
  1000. if (count<datalength && dataarray[count]==']'){
  1001. while (++count <datalength && dataarray[count]==']'){
  1002. // do nothing
  1003. }
  1004. if (count <datalength && dataarray[count]=='>'){
  1005. String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,"CDEndInContent", null);
  1006. reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
  1007. }
  1008. }
  1009. }
  1010. }
  1011. }//end-else fDocument.isXMLVersion()
  1012. }//isCDataWF
  1013. /**
  1014. * NON-DOM: check for valid XML characters as per the XML version
  1015. * @param datavalue
  1016. * @param isXML11Version = true if XML 1.1
  1017. */
  1018. public static final void isXMLCharWF(DOMErrorHandler errorHandler, DOMErrorImpl error, DOMLocatorImpl locator,
  1019. String datavalue, boolean isXML11Version) {
  1020. if(datavalue == null || (datavalue.length() == 0) ) return ;
  1021. char [] dataarray = datavalue.toCharArray();
  1022. int datalength = dataarray.length ;
  1023. //version of the document is XML 1.1
  1024. if(isXML11Version){
  1025. //we need to check all characters as per production rules of XML11
  1026. int i = 0 ;
  1027. while(i < datalength){
  1028. if(XML11Char.isXML11Invalid(dataarray[i++])){
  1029. String msg = DOMMessageFormatter.formatMessage(
  1030. DOMMessageFormatter.DOM_DOMAIN, "InvalidXMLCharInDOM",
  1031. new Object[]{Integer.toString(dataarray[i-1], 16)});
  1032. reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR,
  1033. "wf-invalid-character");
  1034. };
  1035. }
  1036. }//version of the document is XML 1.0
  1037. else{
  1038. //we need to check all characters as per production rules of XML 1.0
  1039. int i = 0 ;
  1040. while(i < datalength){
  1041. if( XMLChar.isInvalid(dataarray[i++]) ){
  1042. String msg = DOMMessageFormatter.formatMessage(
  1043. DOMMessageFormatter.DOM_DOMAIN, "InvalidXMLCharInDOM",
  1044. new Object[]{Integer.toString(dataarray[i-1], 16)});
  1045. reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR,
  1046. "wf-invalid-character");
  1047. };
  1048. }
  1049. }//end-else fDocument.isXMLVersion()
  1050. }//isXMLCharWF
  1051. /**
  1052. * NON-DOM: check if value of the comment is well-formed
  1053. * @param datavalue
  1054. * @param isXML11Version = true if XML 1.1
  1055. */
  1056. public static final void isCommentWF(DOMErrorHandler errorHandler, DOMErrorImpl error, DOMLocatorImpl locator,
  1057. String datavalue, boolean isXML11Version) {
  1058. if(datavalue == null || (datavalue.length() == 0) ) return ;
  1059. char [] dataarray = datavalue.toCharArray();
  1060. int datalength = dataarray.length ;
  1061. //version of the document is XML 1.1
  1062. if(isXML11Version){
  1063. //we need to check all chracters as per production rules of XML11
  1064. int i = 0 ;
  1065. while(i < datalength){
  1066. char c = dataarray[i++];
  1067. if(XML11Char.isXML11Invalid(c)){
  1068. String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,
  1069. "InvalidCharInComment",
  1070. new Object [] {Integer.toString(dataarray[i-1], 16)});
  1071. reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
  1072. }
  1073. else if (c == '-' && i<datalength && dataarray[i]=='-'){
  1074. String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,
  1075. "DashDashInComment", null);
  1076. // invalid: '--' in comment
  1077. reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
  1078. }
  1079. }
  1080. }//version of the document is XML 1.0
  1081. else{
  1082. //we need to check all chracters as per production rules of XML 1.0
  1083. int i = 0 ;
  1084. while(i < datalength){
  1085. char c = dataarray[i++];
  1086. if( XMLChar.isInvalid(c) ){
  1087. String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,
  1088. "InvalidCharInComment", new Object [] {Integer.toString(dataarray[i-1], 16)});
  1089. reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
  1090. }
  1091. else if (c == '-' && i<datalength && dataarray[i]=='-'){
  1092. String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,
  1093. "DashDashInComment", null);
  1094. // invalid: '--' in comment
  1095. reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
  1096. }
  1097. }
  1098. }//end-else fDocument.isXMLVersion()
  1099. }//isCommentWF
  1100. /** NON-DOM: check if attribute value is well-formed
  1101. * @param attributes
  1102. * @param a
  1103. * @param value
  1104. */
  1105. public static final void isAttrValueWF(DOMErrorHandler errorHandler, DOMErrorImpl error,
  1106. DOMLocatorImpl locator, AttributeMap attributes, AttrImpl a, String value, boolean xml11Version) {
  1107. if (a.hasStringValue()) {
  1108. isXMLCharWF(errorHandler, error, locator, value, xml11Version);
  1109. } else {
  1110. NodeList children = a.getChildNodes();
  1111. //check each child node of the attribute's value
  1112. for (int j = 0; j < children.getLength(); j++) {
  1113. Node child = children.item(j);
  1114. //If the attribute's child is an entity refernce
  1115. if (child.getNodeType() == Node.ENTITY_REFERENCE_NODE) {
  1116. Document owner = a.getOwnerDocument();
  1117. Entity ent = null;
  1118. //search for the entity in the docType
  1119. //of the attribute's ownerDocument
  1120. if (owner != null) {
  1121. DocumentType docType = owner.getDoctype();
  1122. if (docType != null) {
  1123. NamedNodeMap entities = docType.getEntities();
  1124. ent = (Entity) entities.getNamedItemNS(
  1125. "*",
  1126. child.getNodeName());
  1127. }
  1128. }
  1129. //If the entity was not found issue a fatal error
  1130. if (ent == null) {
  1131. String msg = DOMMessageFormatter.formatMessage(
  1132. DOMMessageFormatter.DOM_DOMAIN, "UndeclaredEntRefInAttrValue",
  1133. new Object[]{a.getNodeName()});
  1134. reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR,
  1135. "UndeclaredEntRefInAttrValue");
  1136. }
  1137. }
  1138. else {
  1139. // Text node
  1140. isXMLCharWF(errorHandler, error, locator, child.getNodeValue(), xml11Version);
  1141. }
  1142. }
  1143. }
  1144. }
  1145. /**
  1146. * Reports a DOM error to the user handler.
  1147. *
  1148. * If the error is fatal, the processing will be always aborted.
  1149. */
  1150. public static final void reportDOMError(DOMErrorHandler errorHandler, DOMErrorImpl error, DOMLocatorImpl locator, String message, short severity, String type ) {
  1151. if( errorHandler!=null ) {
  1152. error.reset();
  1153. error.fMessage = message;
  1154. error.fSeverity = severity;
  1155. error.fLocator = locator;
  1156. error.fType = type;
  1157. error.fRelatedData = locator.fRelatedNode;
  1158. if(!errorHandler.handleError(error))
  1159. throw abort;
  1160. }
  1161. if( severity==DOMError.SEVERITY_FATAL_ERROR )
  1162. throw abort;
  1163. }
  1164. protected final void updateQName(Node node, QName qname){
  1165. String prefix = node.getPrefix();
  1166. String namespace = node.getNamespaceURI();
  1167. String localName = node.getLocalName();
  1168. // REVISIT: the symbols are added too often: start/endElement
  1169. // and in the namespaceFixup. Should reduce number of calls to symbol table.
  1170. qname.prefix = (prefix!=null && prefix.length()!=0)?fSymbolTable.addSymbol(prefix):null;
  1171. qname.localpart = (localName != null)?fSymbolTable.addSymbol(localName):null;
  1172. qname.rawname = fSymbolTable.addSymbol(node.getNodeName());
  1173. qname.uri = (namespace != null)?fSymbolTable.addSymbol(namespace):null;
  1174. }
  1175. /* REVISIT: remove this method if DOM does not change spec.
  1176. * Performs partial XML 1.0 attribute value normalization and replaces
  1177. * attribute value if the value is changed after the normalization.
  1178. * DOM defines that normalizeDocument acts as if the document was going
  1179. * through a save and load cycle, given that serializer will not escape
  1180. * any '\n' or '\r' characters on load those will be normalized.
  1181. * Thus during normalize document we need to do the following:
  1182. * - perform "2.11 End-of-Line Handling"
  1183. * - replace #xD, #xA, #x9 with #x20 (white space).
  1184. * Note: This alg. won't attempt to resolve entity references or character entity
  1185. * references, since '&' will be escaped during serialization and during loading
  1186. * this won't be recognized as entity reference, i.e. attribute value "&foo;" will
  1187. * be serialized as "&foo;" and thus after loading will be "&foo;" again.
  1188. * @param value current attribute value
  1189. * @param attr current attribute
  1190. * @return String the value (could be original if normalization did not change
  1191. * the string)
  1192. */
  1193. final String normalizeAttributeValue(String value, Attr attr) {
  1194. if (!attr.getSpecified()){
  1195. // specified attributes should already have a normalized form
  1196. // since those were added by validator
  1197. return value;
  1198. }
  1199. int end = value.length();
  1200. // ensure capacity
  1201. if (fNormalizedValue.ch.length < end) {
  1202. fNormalizedValue.ch = new char[end];
  1203. }
  1204. fNormalizedValue.length = 0;
  1205. boolean normalized = false;
  1206. for (int i = 0; i < end; i++) {
  1207. char c = value.charAt(i);
  1208. if (c==0x0009 || c==0x000A) {
  1209. fNormalizedValue.ch[fNormalizedValue.length++] = ' ';
  1210. normalized = true;
  1211. }
  1212. else if(c==0x000D){
  1213. normalized = true;
  1214. fNormalizedValue.ch[fNormalizedValue.length++] = ' ';
  1215. int next = i+1;
  1216. if (next < end && value.charAt(next)==0x000A) i=next; // skip following xA
  1217. }
  1218. else {
  1219. fNormalizedValue.ch[fNormalizedValue.length++] = c;
  1220. }
  1221. }
  1222. if (normalized){
  1223. value = fNormalizedValue.toString();
  1224. attr.setValue(value);
  1225. }
  1226. return value;
  1227. }
  1228. protected final class XMLAttributesProxy
  1229. implements XMLAttributes {
  1230. protected AttributeMap fAttributes;
  1231. protected CoreDocumentImpl fDocument;
  1232. protected ElementImpl fElement;
  1233. protected final Vector fAugmentations = new Vector(5);
  1234. public void setAttributes(AttributeMap attributes, CoreDocumentImpl doc, ElementImpl elem) {
  1235. fDocument = doc;
  1236. fAttributes = attributes;
  1237. fElement = elem;
  1238. if (attributes != null) {
  1239. int length = attributes.getLength();
  1240. fAugmentations.setSize(length);
  1241. // REVISIT: this implementation does not store any value in augmentations
  1242. // and basically not keeping augs in parallel to attributes map
  1243. // untill all attributes are added (default attributes)
  1244. for (int i = 0; i < length; i++) {
  1245. fAugmentations.setElementAt(new AugmentationsImpl(), i);
  1246. }
  1247. } else {
  1248. fAugmentations.setSize(0);
  1249. }
  1250. }
  1251. /**
  1252. * This method adds default declarations
  1253. * @see com.sun.org.apache.xerces.internal.xni.XMLAttributes#addAttribute(QName, String, String)
  1254. */
  1255. public int addAttribute(QName qname, String attrType, String attrValue) {
  1256. int index = fElement.getXercesAttribute(qname.uri, qname.localpart);
  1257. // add defaults to the tree
  1258. if (index < 0) {
  1259. // the default attribute was removed by a user and needed to
  1260. // be added back
  1261. AttrImpl attr = (AttrImpl)
  1262. ((CoreDocumentImpl) fElement.getOwnerDocument()).createAttributeNS(
  1263. qname.uri,
  1264. qname.rawname,
  1265. qname.localpart);
  1266. // REVISIT: the following should also update ID table
  1267. index = fElement.setXercesAttributeNode(attr);
  1268. attr.setNodeValue(attrValue);
  1269. fAugmentations.insertElementAt(new AugmentationsImpl(), index);
  1270. attr.setSpecified(false);
  1271. }
  1272. else {
  1273. // default attribute is in the tree
  1274. // we don't need to do anything since prefix was already fixed
  1275. // at the namespace fixup time and value must be same value, otherwise
  1276. // attribute will be treated as specified and we will never reach
  1277. // this method.
  1278. }
  1279. return index;
  1280. }
  1281. public void removeAllAttributes(){
  1282. // REVISIT: implement
  1283. }
  1284. public void removeAttributeAt(int attrIndex){
  1285. // REVISIT: implement
  1286. }
  1287. public int getLength(){
  1288. return(fAttributes != null)?fAttributes.getLength():0;
  1289. }
  1290. public int getIndex(String qName){
  1291. // REVISIT: implement
  1292. return -1;
  1293. }
  1294. public int getIndex(String uri, String localPart){
  1295. // REVISIT: implement
  1296. return -1;
  1297. }
  1298. public void setName(int attrIndex, QName attrName){
  1299. // REVISIT: implement
  1300. }
  1301. public void getName(int attrIndex, QName attrName){
  1302. if (fAttributes !=null) {
  1303. updateQName((Node)fAttributes.getItem(attrIndex), attrName);
  1304. }
  1305. }
  1306. public String getPrefix(int index){
  1307. // REVISIT: implement
  1308. return null;
  1309. }
  1310. public String getURI(int index){
  1311. // REVISIT: implement
  1312. return null;
  1313. }
  1314. public String getLocalName(int index){
  1315. Object ob = fAttributes.item(index);
  1316. if( ob instanceof AttrNSImpl)
  1317. return ((AttrNSImpl)ob).getLocalName();
  1318. else
  1319. return ((AttrImpl)ob).getNodeName();
  1320. }
  1321. public String getQName(int index){
  1322. return fAttributes.item(index).getNodeName();
  1323. }
  1324. public void setType(int attrIndex, String attrType){
  1325. // REVISIT: implement
  1326. }
  1327. public String getType(int index){
  1328. return "CDATA";
  1329. }
  1330. public String getType(String qName){
  1331. return "CDATA";
  1332. }
  1333. public String getType(String uri, String localName){
  1334. return "CDATA";
  1335. }
  1336. public void setValue(int attrIndex, String attrValue){
  1337. // REVISIT: is this desired behaviour?
  1338. // The values are updated in the case datatype-normalization is turned on
  1339. // in this case we need to make sure that specified attributes stay specified
  1340. if (fAttributes != null){
  1341. AttrImpl attr = (AttrImpl)fAttributes.getItem(attrIndex);
  1342. boolean specified = attr.getSpecified();
  1343. attr.setValue(attrValue);
  1344. attr.setSpecified(specified);
  1345. }
  1346. }
  1347. public String getValue(int index){
  1348. return (fAttributes !=null)?fAttributes.item(index).getNodeValue():"";
  1349. }
  1350. public String getValue(String qName){
  1351. // REVISIT: implement
  1352. return null;
  1353. }
  1354. public String getValue(String uri, String localName){
  1355. if (fAttributes != null) {
  1356. Node node = fAttributes.getNamedItemNS(uri, localName);
  1357. return(node != null)? node.getNodeValue():null;
  1358. }
  1359. return null;
  1360. }
  1361. public void setNonNormalizedValue(int attrIndex, String attrValue){
  1362. // REVISIT: implement
  1363. }
  1364. public String getNonNormalizedValue(int attrIndex){
  1365. // REVISIT: implement
  1366. return null;
  1367. }
  1368. public void setSpecified(int attrIndex, boolean specified){
  1369. AttrImpl attr = (AttrImpl)fAttributes.getItem(attrIndex);
  1370. attr.setSpecified(specified);
  1371. }
  1372. public boolean isSpecified(int attrIndex){
  1373. return((Attr)fAttributes.getItem(attrIndex)).getSpecified();
  1374. }
  1375. public Augmentations getAugmentations(int attributeIndex){
  1376. return(Augmentations)fAugmentations.elementAt(attributeIndex);
  1377. }
  1378. public Augmentations getAugmentations(String uri, String localPart){
  1379. // REVISIT: implement
  1380. return null;
  1381. }
  1382. public Augmentations getAugmentations(String qName){
  1383. // REVISIT: implement
  1384. return null;
  1385. }
  1386. /**
  1387. * Sets the augmentations of the attribute at the specified index.
  1388. *
  1389. * @param attrIndex The attribute index.
  1390. * @param augs The augmentations.
  1391. */
  1392. public void setAugmentations(int attrIndex, Augmentations augs) {
  1393. fAugmentations.setElementAt(augs, attrIndex);
  1394. }
  1395. }
  1396. //
  1397. // XMLDocumentHandler methods
  1398. //
  1399. /**
  1400. * The start of the document.
  1401. *
  1402. * @param locator The document locator, or null if the document
  1403. * location cannot be reported during the parsing
  1404. * of this document. However, it is <em>strongly</em>
  1405. * recommended that a locator be supplied that can
  1406. * at least report the system identifier of the
  1407. * document.
  1408. * @param encoding The auto-detected IANA encoding name of the entity
  1409. * stream. This value will be null in those situations
  1410. * where the entity encoding is not auto-detected (e.g.
  1411. * internal entities or a document entity that is
  1412. * parsed from a java.io.Reader).
  1413. * @param namespaceContext
  1414. * The namespace context in effect at the
  1415. * start of this document.
  1416. * This object represents the current context.
  1417. * Implementors of this class are responsible
  1418. * for copying the namespace bindings from the
  1419. * the current context (and its parent contexts)
  1420. * if that information is important.
  1421. *
  1422. * @param augs Additional information that may include infoset augmentations
  1423. * @exception XNIException
  1424. * Thrown by handler to signal an error.
  1425. */
  1426. public void startDocument(XMLLocator locator, String encoding,
  1427. NamespaceContext namespaceContext,
  1428. Augmentations augs)
  1429. throws XNIException{
  1430. }
  1431. /**
  1432. * Notifies of the presence of an XMLDecl line in the document. If
  1433. * present, this method will be called immediately following the
  1434. * startDocument call.
  1435. *
  1436. * @param version The XML version.
  1437. * @param encoding The IANA encoding name of the document, or null if
  1438. * not specified.
  1439. * @param standalone The standalone value, or null if not specified.
  1440. * @param augs Additional information that may include infoset augmentations
  1441. *
  1442. * @exception XNIException
  1443. * Thrown by handler to signal an error.
  1444. */
  1445. public void xmlDecl(String version, String encoding, String standalone, Augmentations augs)
  1446. throws XNIException{
  1447. }
  1448. /**
  1449. * Notifies of the presence of the DOCTYPE line in the document.
  1450. *
  1451. * @param rootElement
  1452. * The name of the root element.
  1453. * @param publicId The public identifier if an external DTD or null
  1454. * if the external DTD is specified using SYSTEM.
  1455. * @param systemId The system identifier if an external DTD, null
  1456. * otherwise.
  1457. * @param augs Additional information that may include infoset augmentations
  1458. *
  1459. * @exception XNIException
  1460. * Thrown by handler to signal an error.
  1461. */
  1462. public void doctypeDecl(String rootElement, String publicId, String systemId, Augmentations augs)
  1463. throws XNIException{
  1464. }
  1465. /**
  1466. * A comment.
  1467. *
  1468. * @param text The text in the comment.
  1469. * @param augs Additional information that may include infoset augmentations
  1470. *
  1471. * @exception XNIException
  1472. * Thrown by application to signal an error.
  1473. */
  1474. public void comment(XMLString text, Augmentations augs) throws XNIException{
  1475. }
  1476. /**
  1477. * A processing instruction. Processing instructions consist of a
  1478. * target name and, optionally, text data. The data is only meaningful
  1479. * to the application.
  1480. * <p>
  1481. * Typically, a processing instruction's data will contain a series
  1482. * of pseudo-attributes. These pseudo-attributes follow the form of
  1483. * element attributes but are <strong>not</strong> parsed or presented
  1484. * to the application as anything other than text. The application is
  1485. * responsible for parsing the data.
  1486. *
  1487. * @param target The target.
  1488. * @param data The data or null if none specified.
  1489. * @param augs Additional information that may include infoset augmentations
  1490. *
  1491. * @exception XNIException
  1492. * Thrown by handler to signal an error.
  1493. */
  1494. public void processingInstruction(String target, XMLString data, Augmentations augs)
  1495. throws XNIException{
  1496. }
  1497. /**
  1498. * The start of an element.
  1499. *
  1500. * @param element The name of the element.
  1501. * @param attributes The element attributes.
  1502. * @param augs Additional information that may include infoset augmentations
  1503. *
  1504. * @exception XNIException
  1505. * Thrown by handler to signal an error.
  1506. */
  1507. public void startElement(QName element, XMLAttributes attributes, Augmentations augs)
  1508. throws XNIException {
  1509. Element currentElement = (Element) fCurrentNode;
  1510. int attrCount = attributes.getLength();
  1511. if (DEBUG_EVENTS) {
  1512. System.out.println("==>startElement: " +element+
  1513. " attrs.length="+attrCount);
  1514. }
  1515. for (int i = 0; i < attrCount; i++) {
  1516. attributes.getName(i, fAttrQName);
  1517. Attr attr = null;
  1518. attr = currentElement.getAttributeNodeNS(fAttrQName.uri, fAttrQName.localpart);
  1519. AttributePSVI attrPSVI =
  1520. (AttributePSVI) attributes.getAugmentations(i).getItem(Constants.ATTRIBUTE_PSVI);
  1521. if (attrPSVI != null) {
  1522. //REVISIT: instead we should be using augmentations:
  1523. // to set/retrieve Id attributes
  1524. XSTypeDefinition decl = attrPSVI.getMemberTypeDefinition();
  1525. boolean id = false;
  1526. if (decl != null){
  1527. id = ((XSSimpleType)decl).isIDType();
  1528. } else{
  1529. decl = attrPSVI.getTypeDefinition();
  1530. if (decl !=null){
  1531. id = ((XSSimpleType)decl).isIDType();
  1532. }
  1533. }
  1534. if (id){
  1535. ((ElementImpl)currentElement).setIdAttributeNode(attr, true);
  1536. }
  1537. if (fPSVI) {
  1538. ((PSVIAttrNSImpl) attr).setPSVI(attrPSVI);
  1539. }
  1540. if ((fConfiguration.features & DOMConfigurationImpl.DTNORMALIZATION) != 0) {
  1541. // datatype-normalization
  1542. // NOTE: The specified value MUST be set after we set
  1543. // the node value because that turns the "specified"
  1544. // flag to "true" which may overwrite a "false"
  1545. // value from the attribute list.
  1546. boolean specified = attr.getSpecified();
  1547. attr.setValue(attrPSVI.getSchemaNormalizedValue());
  1548. if (!specified) {
  1549. ((AttrImpl) attr).setSpecified(specified);
  1550. }
  1551. }
  1552. }
  1553. }
  1554. }
  1555. /**
  1556. * An empty element.
  1557. *
  1558. * @param element The name of the element.
  1559. * @param attributes The element attributes.
  1560. * @param augs Additional information that may include infoset augmentations
  1561. *
  1562. * @exception XNIException
  1563. * Thrown by handler to signal an error.
  1564. */
  1565. public void emptyElement(QName element, XMLAttributes attributes, Augmentations augs)
  1566. throws XNIException {
  1567. if (DEBUG_EVENTS) {
  1568. System.out.println("==>emptyElement: " +element);
  1569. }
  1570. if(true)
  1571. return;
  1572. startElement(element, attributes, augs);
  1573. endElement(element, augs);
  1574. }
  1575. /**
  1576. * This method notifies the start of a general entity.
  1577. * <p>
  1578. * <strong>Note:</strong> This method is not called for entity references
  1579. * appearing as part of attribute values.
  1580. *
  1581. * @param name The name of the general entity.
  1582. * @param identifier The resource identifier.
  1583. * @param encoding The auto-detected IANA encoding name of the entity
  1584. * stream. This value will be null in those situations
  1585. * where the entity encoding is not auto-detected (e.g.
  1586. * internal entities or a document entity that is
  1587. * parsed from a java.io.Reader).
  1588. * @param augs Additional information that may include infoset augmentations
  1589. *
  1590. * @exception XNIException Thrown by handler to signal an error.
  1591. */
  1592. public void startGeneralEntity(String name,
  1593. XMLResourceIdentifier identifier,
  1594. String encoding,
  1595. Augmentations augs) throws XNIException{
  1596. }
  1597. /**
  1598. * Notifies of the presence of a TextDecl line in an entity. If present,
  1599. * this method will be called immediately following the startEntity call.
  1600. * <p>
  1601. * <strong>Note:</strong> This method will never be called for the
  1602. * document entity; it is only called for external general entities
  1603. * referenced in document content.
  1604. * <p>
  1605. * <strong>Note:</strong> This method is not called for entity references
  1606. * appearing as part of attribute values.
  1607. *
  1608. * @param version The XML version, or null if not specified.
  1609. * @param encoding The IANA encoding name of the entity.
  1610. * @param augs Additional information that may include infoset augmentations
  1611. *
  1612. * @exception XNIException
  1613. * Thrown by handler to signal an error.
  1614. */
  1615. public void textDecl(String version, String encoding, Augmentations augs) throws XNIException{
  1616. }
  1617. /**
  1618. * This method notifies the end of a general entity.
  1619. * <p>
  1620. * <strong>Note:</strong> This method is not called for entity references
  1621. * appearing as part of attribute values.
  1622. *
  1623. * @param name The name of the entity.
  1624. * @param augs Additional information that may include infoset augmentations
  1625. *
  1626. * @exception XNIException
  1627. * Thrown by handler to signal an error.
  1628. */
  1629. public void endGeneralEntity(String name, Augmentations augs) throws XNIException{
  1630. }
  1631. /**
  1632. * Character content.
  1633. *
  1634. * @param text The content.
  1635. * @param augs Additional information that may include infoset augmentations
  1636. *
  1637. * @exception XNIException
  1638. * Thrown by handler to signal an error.
  1639. */
  1640. public void characters(XMLString text, Augmentations augs) throws XNIException{
  1641. }
  1642. /**
  1643. * Ignorable whitespace. For this method to be called, the document
  1644. * source must have some way of determining that the text containing
  1645. * only whitespace characters should be considered ignorable. For
  1646. * example, the validator can determine if a length of whitespace
  1647. * characters in the document are ignorable based on the element
  1648. * content model.
  1649. *
  1650. * @param text The ignorable whitespace.
  1651. * @param augs Additional information that may include infoset augmentations
  1652. *
  1653. * @exception XNIException
  1654. * Thrown by handler to signal an error.
  1655. */
  1656. public void ignorableWhitespace(XMLString text, Augmentations augs) throws XNIException{
  1657. if(docTypeFound){
  1658. isWhitespace = true;
  1659. }
  1660. }
  1661. /**
  1662. * The end of an element.
  1663. *
  1664. * @param element The name of the element.
  1665. * @param augs Additional information that may include infoset augmentations
  1666. *
  1667. * @exception XNIException
  1668. * Thrown by handler to signal an error.
  1669. */
  1670. public void endElement(QName element, Augmentations augs) throws XNIException {
  1671. if (DEBUG_EVENTS) {
  1672. System.out.println("==>endElement: " + element);
  1673. }
  1674. if(augs == null)
  1675. return;
  1676. ElementPSVI elementPSVI = (ElementPSVI) augs.getItem(Constants.ELEMENT_PSVI);
  1677. if (elementPSVI != null) {
  1678. ElementImpl elementNode = (ElementImpl) fCurrentNode;
  1679. if (fPSVI) {
  1680. ((PSVIElementNSImpl) fCurrentNode).setPSVI(elementPSVI);
  1681. }
  1682. // include element default content (if one is available)
  1683. String normalizedValue = elementPSVI.getSchemaNormalizedValue();
  1684. if ((fConfiguration.features & DOMConfigurationImpl.DTNORMALIZATION) != 0) {
  1685. if (normalizedValue !=null)
  1686. elementNode.setTextContent(normalizedValue);
  1687. }
  1688. else {
  1689. // NOTE: this is a hack: it is possible that DOM had an empty element
  1690. // and validator sent default value using characters(), which we don't
  1691. // implement. Thus, here we attempt to add the default value.
  1692. String text = elementNode.getTextContent();
  1693. if (text.length() == 0) {
  1694. // default content could be provided
  1695. if (normalizedValue !=null)
  1696. elementNode.setTextContent(normalizedValue);
  1697. }
  1698. }
  1699. }
  1700. }
  1701. /**
  1702. * The start of a CDATA section.
  1703. *
  1704. * @param augs Additional information that may include infoset augmentations
  1705. *
  1706. * @exception XNIException
  1707. * Thrown by handler to signal an error.
  1708. */
  1709. public void startCDATA(Augmentations augs) throws XNIException{
  1710. }
  1711. /**
  1712. * The end of a CDATA section.
  1713. *
  1714. * @param augs Additional information that may include infoset augmentations
  1715. *
  1716. * @exception XNIException
  1717. * Thrown by handler to signal an error.
  1718. */
  1719. public void endCDATA(Augmentations augs) throws XNIException{
  1720. }
  1721. /**
  1722. * The end of the document.
  1723. *
  1724. * @param augs Additional information that may include infoset augmentations
  1725. *
  1726. * @exception XNIException
  1727. * Thrown by handler to signal an error.
  1728. */
  1729. public void endDocument(Augmentations augs) throws XNIException{
  1730. }
  1731. /** Sets the document source. */
  1732. public void setDocumentSource(XMLDocumentSource source){
  1733. }
  1734. /** Returns the document source. */
  1735. public XMLDocumentSource getDocumentSource(){
  1736. return null;
  1737. }
  1738. public XMLGrammarPoolImpl getGrammarPool(String systemId, String internalSubset){
  1739. try{
  1740. XMLGrammarPreparser preparser = new XMLGrammarPreparser(fSymbolTable);
  1741. XMLGrammarPoolImpl grammarPool = new XMLGrammarPoolImpl();
  1742. preparser.registerPreparser(XMLGrammarDescription.XML_DTD, null);
  1743. preparser.setProperty(GRAMMAR_POOL, grammarPool);
  1744. preparser.setFeature(NAMESPACES_FEATURE_ID, true);
  1745. preparser.setFeature(VALIDATION_FEATURE_ID, true);
  1746. Grammar g = null;
  1747. if(systemId != null){
  1748. g = preparser.preparseGrammar(XMLGrammarDescription.XML_DTD,new XMLInputSource(null, systemId, null));
  1749. }
  1750. if(internalSubset != null && !internalSubset.equals("")){
  1751. XMLInputSource xs = new XMLInputSource(null,systemId,null);
  1752. xs.setCharacterStream(new StringReader(internalSubset));
  1753. g = preparser.preparseGrammar(XMLGrammarDescription.XML_DTD,xs);
  1754. }
  1755. return grammarPool;
  1756. }catch(Exception ex){
  1757. if(DEBUG_ND)
  1758. ex.printStackTrace();
  1759. }
  1760. return null;
  1761. }
  1762. } // DOMNormalizer class