IDOMParser.cpp
上传用户:huihehuasu
上传日期:2007-01-10
资源大小:6948k
文件大小:40k
源码类别:

xml/soap/webservice

开发平台:

C/C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 2001 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 2001, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. /**
  57. *  This file contains code to build the DOM tree. It registers a document
  58. *  handler with the scanner. In these handler methods, appropriate IDOM nodes
  59. *  are created and added to the DOM tree.
  60. *
  61. * $Id: IDOMParser.cpp,v 1.9 2001/11/20 18:51:44 tng Exp $
  62. *
  63. */
  64. // ---------------------------------------------------------------------------
  65. //  Includes
  66. // ---------------------------------------------------------------------------
  67. #include <sax/EntityResolver.hpp>
  68. #include <util/XMLUniDefs.hpp>
  69. #include <sax/ErrorHandler.hpp>
  70. #include <sax/SAXParseException.hpp>
  71. #include <framework/XMLNotationDecl.hpp>
  72. #include <util/IOException.hpp>
  73. #include <internal/XMLScanner.hpp>
  74. #include <validators/DTD/DTDValidator.hpp>
  75. #include <parsers/IDOMParser.hpp>
  76. #include <idom/IDOM_DOMImplementation.hpp>
  77. #include <idom/IDOM_Element.hpp>
  78. #include <idom/IDAttrImpl.hpp>
  79. #include <idom/IDOM_CDATASection.hpp>
  80. #include <idom/IDOM_Comment.hpp>
  81. #include <idom/IDTextImpl.hpp>
  82. #include <idom/IDDocumentImpl.hpp>
  83. #include <idom/IDDocumentTypeImpl.hpp>
  84. #include <idom/IDOM_DocumentType.hpp>
  85. #include <idom/IDElementImpl.hpp>
  86. #include <idom/IDEntityImpl.hpp>
  87. #include <idom/IDEntityReferenceImpl.hpp>
  88. #include <idom/IDNotationImpl.hpp>
  89. #include <idom/IDOM_NamedNodeMap.hpp>
  90. #include <idom/IDOM_ProcessingInstruction.hpp>
  91. #include <idom/IDNodeIDMap.hpp>
  92. #include <validators/common/ContentSpecNode.hpp>
  93. #include <validators/DTD/DTDAttDefList.hpp>
  94. // ---------------------------------------------------------------------------
  95. //  IDOMParser: Constructors and Destructor
  96. // ---------------------------------------------------------------------------
  97. IDOMParser::IDOMParser(XMLValidator* const valToAdopt) :
  98. fErrorHandler(0)
  99. , fEntityResolver(0)
  100. , fCreateEntityReferenceNodes(false)
  101. , fIncludeIgnorableWhitespace(true)
  102. , fNodeStack(0)
  103. , fScanner(0)
  104. , fDocument(0)
  105. , fDocumentVector(0)
  106. {
  107.     //
  108.     //  Create a scanner and tell it what validator to use. Then set us
  109.     //  as the document event handler so we can fill the IDOM document.
  110.     //
  111.     fScanner = new XMLScanner(valToAdopt);
  112.     fScanner->setDocHandler(this);
  113.     fScanner->setDocTypeHandler(this);
  114.     fNodeStack = new ValueStackOf<IDOM_Node*>(64);
  115.     this->reset();
  116. }
  117. IDOMParser::~IDOMParser()
  118. {
  119.     if (fDocumentVector)
  120.         delete fDocumentVector;
  121.     delete fDocument;
  122.     delete fNodeStack;
  123.     delete fScanner;
  124. }
  125. void IDOMParser::reset()
  126. {
  127.     // if fDocument exists already, store the old pointer in the vector for deletion later
  128.     if (fDocument) {
  129.         if (!fDocumentVector) {
  130.             // allocate the vector if not exists yet
  131.             fDocumentVector  = new RefVectorOf<IDDocumentImpl>(10, true) ;
  132.         }
  133.         fDocumentVector->addElement(fDocument);
  134.     }
  135.     fDocument = 0;
  136.     resetDocType();
  137.     fCurrentParent   = 0;
  138.     fCurrentNode     = 0;
  139.     fParseInProgress = false;
  140.     fWithinElement   = false;
  141.     fNodeStack->removeAllElements();
  142. };
  143. // ---------------------------------------------------------------------------
  144. //  IDOMParser: Getter methods
  145. // ---------------------------------------------------------------------------
  146. IDOM_Document* IDOMParser::getDocument()
  147. {
  148.     return fDocument;
  149. }
  150. const XMLValidator& IDOMParser::getValidator() const
  151. {
  152.     return *fScanner->getValidator();
  153. }
  154. bool IDOMParser::getDoNamespaces() const
  155. {
  156.     return fScanner->getDoNamespaces();
  157. }
  158. bool IDOMParser::getExitOnFirstFatalError() const
  159. {
  160.     return fScanner->getExitOnFirstFatal();
  161. }
  162. bool IDOMParser::getValidationConstraintFatal() const
  163. {
  164.     return fScanner->getValidationConstraintFatal();
  165. }
  166. IDOMParser::ValSchemes IDOMParser::getValidationScheme() const
  167. {
  168.     const XMLScanner::ValSchemes scheme = fScanner->getValidationScheme();
  169.     if (scheme == XMLScanner::Val_Always)
  170.         return Val_Always;
  171.     else if (scheme == XMLScanner::Val_Never)
  172.         return Val_Never;
  173.     return Val_Auto;
  174. }
  175. bool IDOMParser::getDoSchema() const
  176. {
  177.     return fScanner->getDoSchema();
  178. }
  179. bool IDOMParser::getValidationSchemaFullChecking() const
  180. {
  181.     return fScanner->getValidationSchemaFullChecking();
  182. }
  183. int IDOMParser::getErrorCount() const
  184. {
  185.     return fScanner->getErrorCount();
  186. }
  187. XMLCh* IDOMParser::getExternalSchemaLocation() const
  188. {
  189.     return fScanner->getExternalSchemaLocation();
  190. }
  191. XMLCh* IDOMParser::getExternalNoNamespaceSchemaLocation() const
  192. {
  193.     return fScanner->getExternalNoNamespaceSchemaLocation();
  194. }
  195. // ---------------------------------------------------------------------------
  196. //  IDOMParser: Setter methods
  197. // ---------------------------------------------------------------------------
  198. void IDOMParser::setDoNamespaces(const bool newState)
  199. {
  200.     fScanner->setDoNamespaces(newState);
  201. }
  202. void IDOMParser::setErrorHandler(ErrorHandler* const handler)
  203. {
  204.     fErrorHandler = handler;
  205.     if (fErrorHandler) {
  206.         fScanner->setErrorReporter(this);
  207.         fScanner->setErrorHandler(fErrorHandler);
  208.     }
  209.     else {
  210.         fScanner->setErrorReporter(0);
  211.         fScanner->setErrorHandler(0);
  212.     }
  213. }
  214. void IDOMParser::setEntityResolver(EntityResolver* const handler)
  215. {
  216.     fEntityResolver = handler;
  217.     if (fEntityResolver) {
  218.         fScanner->setEntityHandler(this);
  219.         fScanner->setEntityResolver(fEntityResolver);
  220.     }
  221.     else {
  222.         fScanner->setEntityHandler(0);
  223.         fScanner->setEntityResolver(0);
  224.     }
  225. }
  226. void IDOMParser::setExitOnFirstFatalError(const bool newState)
  227. {
  228.     fScanner->setExitOnFirstFatal(newState);
  229. }
  230. void IDOMParser::setValidationConstraintFatal(const bool newState)
  231. {
  232.     fScanner->setValidationConstraintFatal(newState);
  233. }
  234. void IDOMParser::setValidationScheme(const ValSchemes newScheme)
  235. {
  236.     if (newScheme == Val_Never)
  237.         fScanner->setValidationScheme(XMLScanner::Val_Never);
  238.     else if (newScheme == Val_Always)
  239.         fScanner->setValidationScheme(XMLScanner::Val_Always);
  240.     else
  241.         fScanner->setValidationScheme(XMLScanner::Val_Auto);
  242. }
  243. void IDOMParser::setDoSchema(const bool newState)
  244. {
  245.     fScanner->setDoSchema(newState);
  246. }
  247. void IDOMParser::setValidationSchemaFullChecking(const bool schemaFullChecking)
  248. {
  249.     fScanner->setValidationSchemaFullChecking(schemaFullChecking);
  250. }
  251. void IDOMParser::setExternalSchemaLocation(const XMLCh* const schemaLocation)
  252. {
  253.     fScanner->setExternalSchemaLocation(schemaLocation);
  254. }
  255. void IDOMParser::setExternalNoNamespaceSchemaLocation(const XMLCh* const noNamespaceSchemaLocation)
  256. {
  257.     fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation);
  258. }
  259. void IDOMParser::setExternalSchemaLocation(const char* const schemaLocation)
  260. {
  261.     fScanner->setExternalSchemaLocation(schemaLocation);
  262. }
  263. void IDOMParser::setExternalNoNamespaceSchemaLocation(const char* const noNamespaceSchemaLocation)
  264. {
  265.     fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation);
  266. }
  267. // ---------------------------------------------------------------------------
  268. //  IDOMParser: Parsing methods
  269. // ---------------------------------------------------------------------------
  270. void IDOMParser::parse(const InputSource& source, const bool reuseGrammar)
  271. {
  272.     // Avoid multiple entrance
  273.     if (fParseInProgress)
  274.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  275.     try
  276.     {
  277.         fParseInProgress = true;
  278.         fScanner->scanDocument(source, reuseGrammar);
  279.         fParseInProgress = false;
  280.     }
  281.     catch(...)
  282.     {
  283.         fParseInProgress = false;
  284.         throw;
  285.     }
  286. }
  287. void IDOMParser::parse(const XMLCh* const systemId, const bool reuseGrammar)
  288. {
  289.     // Avoid multiple entrance
  290.     if (fParseInProgress)
  291.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  292.     try
  293.     {
  294.         fParseInProgress = true;
  295.         fScanner->scanDocument(systemId, reuseGrammar);
  296.         fParseInProgress = false;
  297.     }
  298.     catch(...)
  299.     {
  300.         fParseInProgress = false;
  301.         throw;
  302.     }
  303. }
  304. void IDOMParser::parse(const char* const systemId, const bool reuseGrammar)
  305. {
  306.     // Avoid multiple entrance
  307.     if (fParseInProgress)
  308.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  309.     try
  310.     {
  311.         fParseInProgress = true;
  312.         fScanner->scanDocument(systemId, reuseGrammar);
  313.         fParseInProgress = false;
  314.     }
  315.     catch(...)
  316.     {
  317.         fParseInProgress = false;
  318.         throw;
  319.     }
  320. }
  321. // ---------------------------------------------------------------------------
  322. //  IDOMParser: Progressive parse methods
  323. // ---------------------------------------------------------------------------
  324. bool IDOMParser::parseFirst( const   XMLCh* const    systemId
  325.                            ,       XMLPScanToken&  toFill
  326.                            , const bool            reuseGrammar)
  327. {
  328.     //
  329.     //  Avoid multiple entrance. We cannot enter here while a regular parse
  330.     //  is in progress.
  331.     //
  332.     if (fParseInProgress)
  333.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  334.     return fScanner->scanFirst(systemId, toFill, reuseGrammar);
  335. }
  336. bool IDOMParser::parseFirst( const   char* const         systemId
  337.                            ,       XMLPScanToken&      toFill
  338.                            , const bool                reuseGrammar)
  339. {
  340.     //
  341.     //  Avoid multiple entrance. We cannot enter here while a regular parse
  342.     //  is in progress.
  343.     //
  344.     if (fParseInProgress)
  345.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  346.     return fScanner->scanFirst(systemId, toFill, reuseGrammar);
  347. }
  348. bool IDOMParser::parseFirst( const   InputSource&    source
  349.                            ,       XMLPScanToken&  toFill
  350.                            , const bool            reuseGrammar)
  351. {
  352.     //
  353.     //  Avoid multiple entrance. We cannot enter here while a regular parse
  354.     //  is in progress.
  355.     //
  356.     if (fParseInProgress)
  357.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  358.     return fScanner->scanFirst(source, toFill, reuseGrammar);
  359. }
  360. bool IDOMParser::parseNext(XMLPScanToken& token)
  361. {
  362.     return fScanner->scanNext(token);
  363. }
  364. void IDOMParser::parseReset(XMLPScanToken& token)
  365. {
  366.     // Reset the scanner, and then reset the parser
  367.     fScanner->scanReset(token);
  368.     reset();
  369. }
  370. // ---------------------------------------------------------------------------
  371. //  IDOMParser: Utilities
  372. // ---------------------------------------------------------------------------
  373. void IDOMParser::resetDocumentPool()
  374. {
  375.     //  We cannot enter here while a regular parse is in progress.
  376.     if (fParseInProgress)
  377.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  378.     if (fDocumentVector)
  379.         fDocumentVector->removeAllElements();
  380.     delete fDocument;
  381.     fDocument = 0;
  382. }
  383. // ---------------------------------------------------------------------------
  384. //  IDOMParser: Implementation of the XMLErrorReporter interface
  385. // ---------------------------------------------------------------------------
  386. void IDOMParser::error(  const   unsigned int                code
  387.                       , const XMLCh* const                msgDomain
  388.                       , const XMLErrorReporter::ErrTypes  errType
  389.                       , const XMLCh* const                errorText
  390.                       , const XMLCh* const                systemId
  391.                       , const XMLCh* const                publicId
  392.                       , const unsigned int                lineNum
  393.                       , const unsigned int                colNum)
  394. {
  395.     SAXParseException toThrow = SAXParseException
  396.         (
  397.         errorText
  398.         , publicId
  399.         , systemId
  400.         , lineNum
  401.         , colNum
  402.         );
  403.     //
  404.     //  If there is an error handler registered, call it, otherwise ignore
  405.     //  all but the fatal errors.
  406.     //
  407.     if (!fErrorHandler)
  408.     {
  409.         if (errType == XMLErrorReporter::ErrType_Fatal)
  410.             throw toThrow;
  411.         return;
  412.     }
  413.     if (errType == XMLErrorReporter::ErrType_Warning)
  414.         fErrorHandler->warning(toThrow);
  415.     else if (errType >= XMLErrorReporter::ErrType_Fatal)
  416.         fErrorHandler->fatalError(toThrow);
  417.     else
  418.         fErrorHandler->error(toThrow);
  419. }
  420. void IDOMParser::resetErrors()
  421. {
  422. }
  423. // ---------------------------------------------------------------------------
  424. //  IDOMParser: Implementation of XMLEntityHandler interface
  425. // ---------------------------------------------------------------------------
  426. InputSource*
  427. IDOMParser::resolveEntity(const XMLCh* const publicId, const XMLCh* const systemId)
  428. {
  429.     //
  430.     //  Just map it to the SAX entity resolver. If there is not one installed,
  431.     //  return a null pointer to cause the default resolution.
  432.     //
  433.     if (fEntityResolver)
  434.         return fEntityResolver->resolveEntity(publicId, systemId);
  435.     return 0;
  436. }
  437. // ---------------------------------------------------------------------------
  438. //  IDOMParser: Implementation of XMLDocumentHandler interface
  439. // ---------------------------------------------------------------------------
  440. void IDOMParser::docCharacters(  const   XMLCh* const    chars
  441.                               , const unsigned int    length
  442.                               , const bool            cdataSection)
  443. {
  444.     // Ignore chars outside of content
  445.     if (!fWithinElement)
  446.         return;
  447.     // idom_revisit.  Is it really safe to null-terminate here?
  448.     //                Does the scanner do it already?
  449.     //                If scanner goes up to the very end of an unterminated
  450.     //                buffer, we may be stepping on something bad here.
  451.     //           Probably best to modify the scanner to null terminate.
  452.     XMLCh savedChar = chars[length];
  453.     XMLCh *ncChars  = (XMLCh *)chars;   // cast off const
  454.     ncChars[length] = 0;
  455.     if (cdataSection == true)
  456.     {
  457.         IDOM_CDATASection *node = fDocument->createCDATASection(chars);
  458.         fCurrentParent->appendChild(node);
  459.         fCurrentNode = node;
  460.     }
  461.     else
  462.     {
  463.         if (fCurrentNode->getNodeType() == IDOM_Node::TEXT_NODE)
  464.         {
  465.             IDOM_Text *node = (IDOM_Text *)fCurrentNode;
  466.             node->appendData(chars);
  467.         }
  468.         else
  469.         {
  470.             IDOM_Text *node = fDocument->createTextNode(chars);
  471.             //If the node type is entityRef then set the readOnly flag to false before appending node
  472.             if (fCurrentParent->getNodeType() == IDOM_Node::ENTITY_REFERENCE_NODE) {
  473.                 IDEntityReferenceImpl *erImpl = (IDEntityReferenceImpl *) fCurrentParent;
  474.                 bool oldReadFlag = erImpl->fNode.isReadOnly();
  475.                 erImpl->fNode.isReadOnly(false);
  476.                 fCurrentParent->appendChild(node);
  477.                 erImpl->fNode.isReadOnly(oldReadFlag);
  478.             }
  479.             else
  480.             {
  481.                 fCurrentParent->appendChild(node);
  482.    }
  483.             fCurrentNode = node;
  484.         }
  485.     }
  486.     ncChars[length] = savedChar;
  487.     return;
  488. }
  489. void IDOMParser::docComment(const XMLCh* const comment)
  490. {
  491.     IDOM_Comment *dcom = fDocument->createComment(comment);
  492.     fCurrentParent->appendChild(dcom);
  493.     fCurrentNode = dcom;
  494. }
  495. void IDOMParser::docPI(  const   XMLCh* const    target
  496.                       , const XMLCh* const    data)
  497. {
  498.     IDOM_ProcessingInstruction *pi = fDocument->createProcessingInstruction
  499.         (
  500.         target
  501.         , data
  502.         );
  503.     fCurrentParent->appendChild(pi);
  504.     fCurrentNode = pi;
  505. }
  506. void IDOMParser::endEntityReference(const XMLEntityDecl& entDecl)
  507. {
  508.     if (fCreateEntityReferenceNodes == true)
  509.     {
  510.         fCurrentParent = fNodeStack->pop();
  511.         fCurrentNode   = fCurrentParent;
  512.     }
  513. }
  514. void IDOMParser::endElement( const   XMLElementDecl&     elemDecl
  515.                            , const unsigned int        urlId
  516.                            , const bool                isRoot)
  517. {
  518.     fCurrentNode   = fCurrentParent;
  519.     fCurrentParent = fNodeStack->pop();
  520.     // If we've hit the end of content, clear the flag
  521.     if (fNodeStack->empty())
  522.         fWithinElement = false;
  523. }
  524. void IDOMParser::ignorableWhitespace(const   XMLCh* const    chars
  525.                                     , const unsigned int    length
  526.                                     , const bool            cdataSection)
  527. {
  528.     // Ignore chars before the root element
  529.     if (!fWithinElement || !fIncludeIgnorableWhitespace)
  530.         return;
  531.     // idom_revisit.  Not safe to slam in a null like this.
  532.     XMLCh savedChar = chars[length];
  533.     XMLCh *ncChars  = (XMLCh *)chars;   // cast off const
  534.     ncChars[length] = chNull;
  535.     if (fCurrentNode->getNodeType() == IDOM_Node::TEXT_NODE)
  536.     {
  537.         IDOM_Text *node = (IDOM_Text *)fCurrentNode;
  538.         node->appendData(chars);
  539.     }
  540.     else
  541.     {
  542.         IDTextImpl *node = (IDTextImpl *)fDocument->createTextNode(chars);
  543.         node->setIgnorableWhitespace(true);
  544.         //If the node type is entityRef then set the readOnly flag to false before appending node
  545.         if (fCurrentParent->getNodeType() == IDOM_Node::ENTITY_REFERENCE_NODE) {
  546.             IDEntityReferenceImpl *erImpl = (IDEntityReferenceImpl *) fCurrentParent;
  547.             bool oldReadFlag = erImpl->fNode.isReadOnly();
  548.             erImpl->fNode.isReadOnly(false);
  549.             fCurrentParent->appendChild(node);
  550.             erImpl->fNode.isReadOnly(oldReadFlag);
  551.         }
  552.         else
  553.         {
  554.             fCurrentParent->appendChild(node);
  555.         }
  556.         fCurrentNode = node;
  557.     }
  558.     ncChars[length] = savedChar;
  559. }
  560. void IDOMParser::resetDocument()
  561. {
  562.     //
  563.     //  The reset methods are called before a new parse event occurs.
  564.     //  Reset this parsers state to clear out anything that may be left
  565.     //  from a previous use, in particular the IDOM document itself.
  566.     //
  567.     this->reset();
  568.     fDocument = (IDDocumentImpl *)IDOM_DOMImplementation::getImplementation()->createDocument();
  569. }
  570. void IDOMParser::startDocument()
  571. {
  572.     // Just set the document as the current parent and current node
  573.     fCurrentParent = fDocument;
  574.     fCurrentNode   = fDocument;
  575.     // set IDOM error checking off
  576.     fDocument->setErrorChecking(false);
  577. }
  578. void IDOMParser::endDocument()
  579. {
  580.     // set IDOM error checking back on
  581.     fDocument->setErrorChecking(true);
  582. }
  583. void IDOMParser::startElement(const  XMLElementDecl&         elemDecl
  584.                              , const unsigned int            urlId
  585.                              , const XMLCh* const            elemPrefix
  586.                              , const RefVectorOf<XMLAttr>&   attrList
  587.                              , const unsigned int            attrCount
  588.                              , const bool                    isEmpty
  589.                              , const bool                    isRoot)
  590. {
  591.     IDOM_Element     *elem;
  592.     if (fScanner -> getDoNamespaces()) {    //IDOM Level 2, doNamespaces on
  593.         XMLBuffer buf;
  594.         XMLCh* namespaceURI = 0;
  595.         if (urlId != fScanner->getEmptyNamespaceId()) {  //TagName has a prefix
  596.             fScanner->getURIText(urlId, buf);   //get namespaceURI
  597.             namespaceURI = buf.getRawBuffer();
  598.         }
  599.         elem = fDocument->createElementNS(namespaceURI, elemDecl.getFullName());
  600.         IDElementImpl *elemImpl = (IDElementImpl *) elem;
  601.         for (unsigned int index = 0; index < attrCount; ++index) {
  602.             static const XMLCh XMLNS[] = {
  603.             chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull
  604.             };
  605.             const XMLAttr* oneAttrib = attrList.elementAt(index);
  606.             unsigned int attrURIId = oneAttrib -> getURIId();
  607.             namespaceURI = 0;
  608.             if (!XMLString::compareString(oneAttrib -> getName(), XMLNS))    //for xmlns=...
  609.                 attrURIId = fScanner->getXMLNSNamespaceId();
  610.             if (attrURIId != fScanner->getEmptyNamespaceId()) {  //TagName has a prefix
  611.                 fScanner->getURIText(attrURIId, buf);   //get namespaceURI
  612.                 namespaceURI = buf.getRawBuffer();
  613.             }
  614.             //  idom_revisit.  Optimize to init the named node map to the
  615.             //                 right size up front.
  616.             IDAttrImpl *attr = (IDAttrImpl *)
  617.                 fDocument->createAttributeNS(namespaceURI, oneAttrib->getQName());
  618.             attr->setValue(oneAttrib -> getValue());
  619.             elemImpl->setAttributeNode(attr);
  620.             //IDAttrImpl *attr = elemImpl->setAttributeNS(namespaceURI, oneAttrib -> getQName(),
  621.             //    oneAttrib -> getValue());
  622.             // Attributes of type ID.  If this is one, add it to the hashtable of IDs
  623.             //   that is constructed for use by GetElementByID().
  624.             //
  625.             if (oneAttrib->getType()==XMLAttDef::ID)
  626.             {
  627.                 if (fDocument->fNodeIDMap == 0)
  628.                     fDocument->fNodeIDMap = new (fDocument) IDNodeIDMap(500, fDocument);
  629.                 fDocument->fNodeIDMap->add(attr);
  630.                 attr->fNode.isIdAttr(true);
  631.             }
  632.             attr->setSpecified(oneAttrib->getSpecified());
  633.         }
  634.     }
  635.     else {    //DOM Level 1
  636.         elem = fDocument->createElement(elemDecl.getFullName());
  637.         IDElementImpl *elemImpl = (IDElementImpl *) elem;
  638. for (unsigned int index = 0; index < attrCount; ++index) {
  639. const XMLAttr* oneAttrib = attrList.elementAt(index);
  640.             //AttrImpl *attr = elemImpl->setAttribute(oneAttrib->getName(), oneAttrib->getValue());
  641.             IDAttrImpl *attr = (IDAttrImpl *)
  642.                 fDocument->createAttribute(oneAttrib->getName());
  643.             attr->setValue(oneAttrib -> getValue());
  644.             elemImpl->setAttributeNode(attr);
  645. attr->setSpecified(oneAttrib->getSpecified());
  646. // Attributes of type ID.  If this is one, add it to the hashtable of IDs
  647. //   that is constructed for use by GetElementByID().
  648. //
  649. if (oneAttrib->getType()==XMLAttDef::ID)
  650. {
  651.                 if (fDocument->fNodeIDMap == 0)
  652.                     fDocument->fNodeIDMap = new (fDocument) IDNodeIDMap(500, fDocument);
  653.                 fDocument->fNodeIDMap->add(attr);
  654.                 attr->fNode.isIdAttr(true);
  655.             }
  656.         }
  657.     }
  658.     //If the node type is entityRef then set the readOnly flag to false before appending node
  659.     bool oldReadFlag;
  660.     if (fCurrentParent->getNodeType() == IDOM_Node::ENTITY_REFERENCE_NODE) {
  661.         IDEntityReferenceImpl *erNode = (IDEntityReferenceImpl *)fCurrentParent;
  662.         oldReadFlag = erNode->fNode.isReadOnly();
  663.         erNode->fNode.isReadOnly(false);
  664.         fCurrentParent->appendChild(elem);
  665.         erNode->fNode.isReadOnly(oldReadFlag);
  666.     }
  667.     else
  668.     {
  669.         fCurrentParent->appendChild(elem);
  670.     }
  671.     fNodeStack->push(fCurrentParent);
  672.     fCurrentParent = elem;
  673.     fCurrentNode = elem;
  674.     fWithinElement = true;
  675.     // If an empty element, do end right now (no endElement() will be called)
  676.     if (isEmpty)
  677.         endElement(elemDecl, urlId, isRoot);
  678. }
  679. void IDOMParser::startEntityReference(const XMLEntityDecl& entDecl)
  680. {
  681.     if (fCreateEntityReferenceNodes == true)
  682.     {
  683.         const XMLCh * entName = entDecl.getName();
  684.         IDOM_EntityReference *er = fDocument->createEntityReference(entName);
  685.         fCurrentParent->appendChild(er);
  686.         fNodeStack->push(fCurrentParent);
  687.         fCurrentParent = er;
  688.         fCurrentNode = er;
  689.         // this entityRef needs to be stored in Entity map too.
  690.         // We'd decide later whether the entity nodes should be created by a
  691.         // separated method in parser or not. For now just stick it in if
  692.         // the ref nodes are created
  693.         IDOM_NamedNodeMap *entities = fDocumentType->getEntities();
  694.         IDEntityImpl* entity = (IDEntityImpl*)entities->getNamedItem(entName);
  695.         entity->setEntityRef(er);
  696.     }
  697. }
  698. void IDOMParser::XMLDecl(const   XMLCh* const version
  699.                         , const XMLCh* const encoding
  700.                         , const XMLCh* const standalone
  701.                         , const XMLCh* const actualEncStr)
  702. {
  703.     // placehold for DOM Level 3
  704. }
  705. // ---------------------------------------------------------------------------
  706. //  IDOMParser: Deprecated methods
  707. // ---------------------------------------------------------------------------
  708. bool IDOMParser::getDoValidation() const
  709. {
  710.     //
  711.     //  We don't want to tie the public parser classes to the enum used
  712.     //  by the scanner, so we use a separate one and map.
  713.     //
  714.     //  DON'T mix the new and old methods!!
  715.     //
  716.     const XMLScanner::ValSchemes scheme = fScanner->getValidationScheme();
  717.     if (scheme == XMLScanner::Val_Always)
  718.         return true;
  719.     return false;
  720. }
  721. void IDOMParser::setDoValidation(const bool newState)
  722. {
  723.     fScanner->setDoValidation
  724.     (
  725.         newState ? XMLScanner::Val_Always : XMLScanner::Val_Never
  726.     );
  727. }
  728. //doctypehandler interfaces
  729. void IDOMParser::attDef
  730. (
  731.     const   DTDElementDecl&     elemDecl
  732.     , const DTDAttDef&          attDef
  733.     , const bool                ignoring
  734. )
  735. {
  736.     if (fDocumentType->isIntSubsetReading())
  737.     {
  738.         XMLBuffer attString;
  739.         if (elemDecl.hasAttDefs())
  740.         {
  741.             attString.append(chOpenAngle);
  742.             attString.append(chBang);
  743.             attString.append(XMLUni::fgAttListString);
  744.             attString.append(chSpace);
  745.             attString.append(elemDecl.getFullName());
  746.             attString.append(chSpace);
  747.             attString.append(attDef.getFullName());
  748.             // Get the type and display it
  749.             const XMLAttDef::AttTypes type = attDef.getType();
  750.             switch(type)
  751.             {
  752.             case XMLAttDef::CData :
  753.                 attString.append(chSpace);
  754.                 attString.append(XMLUni::fgCDATAString);
  755.                 break;
  756.             case XMLAttDef::ID :
  757.                 attString.append(chSpace);
  758.                 attString.append(XMLUni::fgIDString);
  759.                 break;
  760.             case XMLAttDef::IDRef :
  761.                 attString.append(chSpace);
  762.                 attString.append(XMLUni::fgIDRefString);
  763.                 break;
  764.             case XMLAttDef::IDRefs :
  765.                 attString.append(chSpace);
  766.                 attString.append(XMLUni::fgIDRefsString);
  767.                 break;
  768.             case XMLAttDef::Entity :
  769.                 attString.append(chSpace);
  770.                 attString.append(XMLUni::fgEntityString);
  771.                 break;
  772.             case XMLAttDef::Entities :
  773.                 attString.append(chSpace);
  774.                 attString.append(XMLUni::fgEntitiesString);
  775.                 break;
  776.             case XMLAttDef::NmToken :
  777.                 attString.append(chSpace);
  778.                 attString.append(XMLUni::fgNmTokenString);
  779.                 break;
  780.             case XMLAttDef::NmTokens :
  781.                 attString.append(chSpace);
  782.                 attString.append(XMLUni::fgNmTokensString);
  783.                 break;
  784.             case XMLAttDef::Notation :
  785.                 attString.append(chSpace);
  786.                 attString.append(XMLUni::fgNotationString);
  787.                 break;
  788.             case XMLAttDef::Enumeration :
  789.                 attString.append(chSpace);
  790.                 const XMLCh* enumString = attDef.getEnumeration();
  791.                 int length = XMLString::stringLen(enumString);
  792.                 if (length > 0) {
  793.                     XMLBuffer anotherEnumString;
  794.                     anotherEnumString.append(chOpenParen );
  795.                     for(int i=0; i<length; i++) {
  796.                         if (enumString[i] == chSpace)
  797.                             anotherEnumString.append(chPipe);
  798.                         else
  799.                             anotherEnumString.append(enumString[i]);
  800.                     }
  801.                     anotherEnumString.append(chCloseParen);
  802.                     attString.append(anotherEnumString.getRawBuffer());
  803.                 }
  804.                 break;
  805.             }
  806.             //get te default types of the attlist
  807.             const XMLAttDef::DefAttTypes def = attDef.getDefaultType();
  808.             switch(def)
  809.             {
  810.             case XMLAttDef::Required :
  811.                 attString.append(chSpace);
  812.                 attString.append(XMLUni::fgRequiredString);
  813.                 break;
  814.             case XMLAttDef::Implied :
  815.                 attString.append(chSpace);
  816.                 attString.append(XMLUni::fgImpliedString);
  817.                 break;
  818.             case XMLAttDef::Fixed :
  819.                 attString.append(chSpace);
  820.                 attString.append(XMLUni::fgFixedString);
  821.                 break;
  822.             }
  823.             const XMLCh* defaultValue = attDef.getValue();
  824.             if (defaultValue != 0) {
  825.                 attString.append(chSpace);
  826.                 attString.append(chDoubleQuote);
  827.                 attString.append(defaultValue);
  828.                 attString.append(chDoubleQuote);
  829.             }
  830.             attString.append(chCloseAngle);
  831.             fDocumentType->setInternalSubset(attString.getRawBuffer());
  832.         }
  833.     }
  834. }
  835. void IDOMParser::doctypeComment
  836. (
  837.     const   XMLCh* const    comment
  838. )
  839. {
  840.     if (fDocumentType->isIntSubsetReading())
  841.     {
  842.         if (comment != 0)
  843.         {
  844.             XMLBuffer comString;
  845.             comString.append(XMLUni::fgCommentString);
  846.             comString.append(chSpace);
  847.             comString.append(comment);
  848.             comString.append(chSpace);
  849.             comString.append(chDash);
  850.             comString.append(chDash);
  851.             comString.append(chCloseAngle);
  852.             fDocumentType->setInternalSubset(comString.getRawBuffer());
  853.         }
  854.     }
  855. }
  856. void IDOMParser::doctypeDecl
  857. (
  858.     const   DTDElementDecl& elemDecl
  859.     , const XMLCh* const    publicId
  860.     , const XMLCh* const    systemId
  861.     , const bool            hasIntSubset
  862. )
  863. {
  864.     fDocumentType = (IDDocumentTypeImpl *) fDocument->createDocumentType(elemDecl.getFullName(), publicId, systemId);
  865.     fDocument->setDocumentType(fDocumentType);
  866. }
  867. void IDOMParser::doctypePI
  868. (
  869.     const   XMLCh* const    target
  870.     , const XMLCh* const    data
  871. )
  872. {
  873.     if (fDocumentType->isIntSubsetReading())
  874. {
  875. //add these chars to internalSubset variable
  876.         XMLBuffer pi;
  877.         pi.append(chOpenAngle);
  878.         pi.append(chQuestion);
  879.         pi.append(target);
  880.         pi.append(chSpace);
  881.         pi.append(data);
  882.         pi.append(chQuestion);
  883.         pi.append(chCloseAngle);
  884. fDocumentType->setInternalSubset(pi.getRawBuffer());
  885. }
  886. }
  887. void IDOMParser::doctypeWhitespace
  888. (
  889.     const   XMLCh* const    chars
  890.     , const unsigned int    length
  891. )
  892. {
  893.     if (fDocumentType->isIntSubsetReading())
  894. fDocumentType->setInternalSubset(chars);
  895. }
  896. void IDOMParser::elementDecl
  897. (
  898.     const   DTDElementDecl& decl
  899.     , const bool            isIgnored
  900. )
  901. {
  902.     if (fDocumentType->isIntSubsetReading())
  903. {
  904.         XMLBuffer elemDecl;
  905.         elemDecl.append(chOpenAngle);
  906.         elemDecl.append(chBang);
  907.         elemDecl.append(XMLUni::fgElemString);
  908.         elemDecl.append(chSpace);
  909.         elemDecl.append(decl.getFullName());
  910.         //get the ContentSpec information
  911.         const XMLCh* contentModel = decl.getFormattedContentModel();
  912.         if (contentModel != 0) {
  913.             elemDecl.append(chSpace);
  914.             elemDecl.append(contentModel);
  915.         }
  916.         elemDecl.append(chCloseAngle);
  917. fDocumentType->setInternalSubset(elemDecl.getRawBuffer());
  918. }
  919. }
  920. void IDOMParser::endAttList
  921. (
  922.     const   DTDElementDecl& elemDecl
  923. )
  924. {
  925. // this section sets up default attributes.
  926. // default attribute nodes are stored in a NamedNodeMap DocumentTypeImpl::elements
  927. // default attribute data attached to the document is used to conform to the
  928. // IDOM spec regarding creating element nodes & removing attributes with default values
  929. // see DocumentTypeImpl
  930. if (elemDecl.hasAttDefs())
  931. {
  932. XMLAttDefList* defAttrs = &elemDecl.getAttDefList();
  933. XMLAttDef* attr = 0;
  934. IDAttrImpl * insertAttr = 0;
  935.       IDOM_Element     *elem  = fDocument->createElement(elemDecl.getFullName());
  936.       IDElementImpl *elemImpl = (IDElementImpl *) elem;
  937. while (defAttrs->hasMoreElements())
  938.         {
  939.             attr = &defAttrs->nextElement();
  940.             if (attr->getValue() != 0)
  941.             {
  942.                 if (fScanner->getDoNamespaces())
  943.                 {
  944.                     // DOM Level 2 wants all namespace declaration attributes
  945.                     // to be bound to "http://www.w3.org/2000/xmlns/"
  946.                     // So as long as the XML parser doesn't do it, it needs to
  947.                     // done here.
  948.                     const XMLCh* qualifiedName = attr->getFullName();
  949.                     int index = IDDocumentImpl::indexofQualifiedName(qualifiedName);
  950.                     XMLBuffer buf;
  951.                     static const XMLCh XMLNS[] = {
  952.                         chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull};
  953.                     if (index > 0) {
  954.                         // there is prefix
  955.                         // map to XML URI for all cases except when prefix == "xmlns"
  956.                         XMLCh* prefix;
  957.                         XMLCh temp[1000];
  958.                         if (index > 999)
  959.                             prefix = new XMLCh[index+1];
  960.                         else
  961.                             prefix = temp;
  962.                         XMLString::subString(prefix ,qualifiedName, 0, index);
  963.                         if (!XMLString::compareString(prefix,XMLNS))
  964.                             buf.append(XMLUni::fgXMLNSURIName);
  965.                         else
  966.                             buf.append(XMLUni::fgXMLURIName);
  967.                         if (index > 999)
  968.                             delete prefix;
  969.                     }
  970.                     else {
  971.                         //   No prefix
  972.                         if (!XMLString::compareString(qualifiedName,XMLNS))
  973.                             buf.append(XMLUni::fgXMLNSURIName);
  974.                     }
  975.                     insertAttr = (IDAttrImpl *) fDocument->createAttributeNS(
  976.                        buf.getRawBuffer(),     // NameSpaceURI
  977.                        qualifiedName);   // qualified name
  978.                 }
  979.                 else
  980.                 {
  981.                     // Namespaces is turned off...
  982.                     insertAttr = (IDAttrImpl *) fDocument->createAttribute(attr->getFullName());
  983.                 }
  984.                 insertAttr->setValue(attr->getValue());
  985.                 elemImpl->setAttributeNode(insertAttr);
  986.                 insertAttr->setSpecified(false);
  987.             }
  988.         }
  989.         fDocumentType->getElements()->setNamedItem(elemImpl);
  990.     }
  991. }
  992. void IDOMParser::endIntSubset()
  993. {
  994. fDocumentType->intSubsetReading = false;
  995. }
  996. void IDOMParser::endExtSubset()
  997. {
  998. }
  999. void IDOMParser::entityDecl
  1000. (
  1001.     const   DTDEntityDecl&  entityDecl
  1002.     , const bool            isPEDecl
  1003.     , const bool            isIgnored
  1004. )
  1005. {
  1006.     IDEntityImpl* entity = (IDEntityImpl *) fDocument->createEntity(entityDecl.getName());
  1007.     entity->setPublicId(entityDecl.getPublicId());
  1008.     entity->setSystemId(entityDecl.getSystemId());
  1009.     entity->setNotationName(entityDecl.getNotationName());
  1010.     IDEntityImpl *previousDef = (IDEntityImpl *)
  1011.     fDocumentType->getEntities()->setNamedItem( entity );
  1012.     #ifdef idom_revisit
  1013.     //
  1014.     //  If this new entity node is replacing an entity node that was already
  1015.     //    in the entities named node map (happens if documents redefine the
  1016.     //    predefined entited such as lt), we need to delete the original
  1017.     //    entitiy node, assuming no-one else was referencing it.
  1018.     //
  1019.     if (previousDef != 0 && previousDef->nodeRefCount == 0)
  1020.              NodeImpl::deleteIf(previousDef);
  1021.     #endif
  1022.     if (fDocumentType->isIntSubsetReading())
  1023.     {
  1024.         //add thes chars to internalSubset variable
  1025.         XMLBuffer entityName;
  1026.         entityName.append(chOpenAngle);
  1027.         entityName.append(chBang);
  1028.         entityName.append(XMLUni::fgEntityString);
  1029.         entityName.append(chSpace);
  1030.         entityName.append(entityDecl.getName());
  1031.         const XMLCh* id = entity->getPublicId();
  1032.         if (id != 0) {
  1033.             entityName.append(chSpace);
  1034.             entityName.append(XMLUni::fgPubIDString);
  1035.             entityName.append(chSpace);
  1036.             entityName.append(chDoubleQuote);
  1037.             entityName.append(id);
  1038.             entityName.append(chDoubleQuote);
  1039.         }
  1040.         id = entity->getSystemId();
  1041.         if (id != 0) {
  1042.             entityName.append(chSpace);
  1043.             entityName.append(XMLUni::fgSysIDString);
  1044.             entityName.append(chSpace);
  1045.             entityName.append(chDoubleQuote);
  1046.             entityName.append(id);
  1047.             entityName.append(chDoubleQuote);
  1048.         }
  1049.         id = entity->getNotationName();
  1050.         if (id != 0) {
  1051.             entityName.append(chSpace);
  1052.             entityName.append(XMLUni::fgNDATAString);
  1053.             entityName.append(chSpace);
  1054.             entityName.append(chDoubleQuote);
  1055.             entityName.append(id);
  1056.             entityName.append(chDoubleQuote);
  1057.         }
  1058.         id = entityDecl.getValue();
  1059.         if (id !=0) {
  1060.             entityName.append(chSpace);
  1061.             entityName.append(chDoubleQuote);
  1062.             entityName.append(id);
  1063.             entityName.append(chDoubleQuote);
  1064.         }
  1065.         entityName.append(chCloseAngle);
  1066.         fDocumentType->setInternalSubset(entityName.getRawBuffer());
  1067.     }
  1068. }
  1069. void IDOMParser::resetDocType()
  1070. {
  1071. fDocumentType = 0;
  1072. }
  1073. void IDOMParser::notationDecl
  1074. (
  1075.     const   XMLNotationDecl&    notDecl
  1076.     , const bool                isIgnored
  1077. )
  1078. {
  1079. IDNotationImpl* notation = (IDNotationImpl *)fDocument->createNotation(notDecl.getName());
  1080. notation->setPublicId(notDecl.getPublicId());
  1081. notation->setSystemId(notDecl.getSystemId());
  1082. fDocumentType->getNotations()->setNamedItem( notation );
  1083. }
  1084. void IDOMParser::startAttList
  1085. (
  1086.     const   DTDElementDecl& elemDecl
  1087. )
  1088. {
  1089. }
  1090. void IDOMParser::startIntSubset()
  1091. {
  1092. fDocumentType->intSubsetReading = true;
  1093. }
  1094. void IDOMParser::startExtSubset()
  1095. {
  1096. }
  1097. void IDOMParser::TextDecl
  1098. (
  1099.     const   XMLCh* const    versionStr
  1100.     , const XMLCh* const    encodingStr
  1101. )
  1102. {
  1103. }