GME  13
AbstractDOMParser.cpp
Go to the documentation of this file.
00001 /*
00002  * Licensed to the Apache Software Foundation (ASF) under one or more
00003  * contributor license agreements.  See the NOTICE file distributed with
00004  * this work for additional information regarding copyright ownership.
00005  * The ASF licenses this file to You under the Apache License, Version 2.0
00006  * (the "License"); you may not use this file except in compliance with
00007  * the License.  You may obtain a copy of the License at
00008  *
00009  *      http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00027 // ---------------------------------------------------------------------------
00028 //  Includes
00029 // ---------------------------------------------------------------------------
00030 #include <xercesc/parsers/AbstractDOMParser.hpp>
00031 #include <xercesc/internal/XMLScannerResolver.hpp>
00032 #include <xercesc/internal/ElemStack.hpp>
00033 #include <xercesc/util/XMLUniDefs.hpp>
00034 #include <xercesc/framework/XMLNotationDecl.hpp>
00035 #include <xercesc/framework/XMLValidator.hpp>
00036 #include <xercesc/framework/psvi/PSVIElement.hpp>
00037 #include <xercesc/framework/psvi/PSVIAttribute.hpp>
00038 #include <xercesc/framework/psvi/PSVIAttributeList.hpp>
00039 #include <xercesc/framework/psvi/XSElementDeclaration.hpp>
00040 #include <xercesc/util/IOException.hpp>
00041 #include <xercesc/dom/DOMImplementation.hpp>
00042 #include <xercesc/dom/DOMImplementationRegistry.hpp>
00043 #include <xercesc/dom/DOMElement.hpp>
00044 #include <xercesc/dom/impl/DOMAttrImpl.hpp>
00045 #include <xercesc/dom/impl/DOMAttrNSImpl.hpp>
00046 #include <xercesc/dom/impl/DOMTypeInfoImpl.hpp>
00047 #include <xercesc/dom/impl/DOMCDATASectionImpl.hpp>
00048 #include <xercesc/dom/DOMComment.hpp>
00049 #include <xercesc/dom/impl/DOMTextImpl.hpp>
00050 #include <xercesc/dom/impl/DOMDocumentImpl.hpp>
00051 #include <xercesc/dom/impl/DOMDocumentTypeImpl.hpp>
00052 #include <xercesc/dom/DOMDocumentType.hpp>
00053 #include <xercesc/dom/impl/DOMElementNSImpl.hpp>
00054 #include <xercesc/dom/impl/DOMEntityImpl.hpp>
00055 #include <xercesc/dom/impl/DOMEntityReferenceImpl.hpp>
00056 #include <xercesc/dom/impl/DOMNotationImpl.hpp>
00057 #include <xercesc/dom/DOMNamedNodeMap.hpp>
00058 #include <xercesc/dom/DOMProcessingInstruction.hpp>
00059 #include <xercesc/dom/impl/DOMProcessingInstructionImpl.hpp>
00060 #include <xercesc/dom/impl/DOMNodeIDMap.hpp>
00061 #include <xercesc/dom/impl/DOMCasts.hpp>
00062 #include <xercesc/validators/common/ContentSpecNode.hpp>
00063 #include <xercesc/validators/common/GrammarResolver.hpp>
00064 #include <xercesc/validators/schema/SchemaSymbols.hpp>
00065 #include <xercesc/util/OutOfMemoryException.hpp>
00066 #include <xercesc/xinclude/XIncludeUtils.hpp>
00067 
00068 XERCES_CPP_NAMESPACE_BEGIN
00069 
00070 
00071 // ---------------------------------------------------------------------------
00072 //  AbstractDOMParser: Constructors and Destructor
00073 // ---------------------------------------------------------------------------
00074 
00075 
00076 typedef JanitorMemFunCall<AbstractDOMParser>    CleanupType;
00077 typedef JanitorMemFunCall<AbstractDOMParser>    ResetInProgressType;
00078 
00079 
00080 AbstractDOMParser::AbstractDOMParser( XMLValidator* const   valToAdopt
00081                                     , MemoryManager* const  manager
00082                                     , XMLGrammarPool* const gramPool) :
00083 
00084   fCreateEntityReferenceNodes(true)
00085 , fIncludeIgnorableWhitespace(true)
00086 , fWithinElement(false)
00087 , fParseInProgress(false)
00088 , fCreateCommentNodes(true)
00089 , fDocumentAdoptedByUser(false)
00090 , fCreateSchemaInfo(false)
00091 , fDoXInclude(false)
00092 , fScanner(0)
00093 , fImplementationFeatures(0)
00094 , fCurrentParent(0)
00095 , fCurrentNode(0)
00096 , fCurrentEntity(0)
00097 , fDocument(0)
00098 , fDocumentType(0)
00099 , fDocumentVector(0)
00100 , fGrammarResolver(0)
00101 , fURIStringPool(0)
00102 , fValidator(valToAdopt)
00103 , fMemoryManager(manager)
00104 , fGrammarPool(gramPool)
00105 , fBufMgr(manager)
00106 , fInternalSubset(fBufMgr.bidOnBuffer())
00107 , fPSVIHandler(0)
00108 {
00109     CleanupType cleanup(this, &AbstractDOMParser::cleanUp);
00110 
00111     try
00112     {
00113         initialize();
00114     }
00115     catch(const OutOfMemoryException&)
00116     {
00117         // Don't cleanup when out of memory, since executing the
00118         // code can cause problems.
00119         cleanup.release();
00120 
00121         throw;
00122     }
00123 
00124     cleanup.release();
00125 }
00126 
00127 
00128 AbstractDOMParser::~AbstractDOMParser()
00129 {
00130     cleanUp();
00131 }
00132 
00133 // ---------------------------------------------------------------------------
00134 //  AbstractDOMParser: Initialize/CleanUp methods
00135 // ---------------------------------------------------------------------------
00136 void AbstractDOMParser::initialize()
00137 {
00138     //  Create grammar resolver and string pool to pass to the scanner
00139     fGrammarResolver = new (fMemoryManager) GrammarResolver(fGrammarPool, fMemoryManager);
00140     fURIStringPool = fGrammarResolver->getStringPool();
00141 
00142     //  Create a scanner and tell it what validator to use. Then set us
00143     //  as the document event handler so we can fill the DOM document.
00144     fScanner = XMLScannerResolver::getDefaultScanner(fValidator, fGrammarResolver, fMemoryManager);
00145     fScanner->setDocHandler(this);
00146     fScanner->setDocTypeHandler(this);
00147     fScanner->setURIStringPool(fURIStringPool);
00148 
00149     this->reset();
00150 }
00151 
00152 void AbstractDOMParser::cleanUp()
00153 {
00154     if (fDocumentVector)
00155         delete fDocumentVector;
00156 
00157     if (!fDocumentAdoptedByUser && fDocument)
00158         fDocument->release();
00159 
00160     delete fScanner;
00161     delete fGrammarResolver;
00162     // grammar pool *always* owns this
00163     //delete fURIStringPool;
00164     fMemoryManager->deallocate(fImplementationFeatures);
00165 
00166     if (fValidator)
00167         delete fValidator;
00168 }
00169 
00170 // ---------------------------------------------------------------------------
00171 //  AbstractDOMParser: Utilities
00172 // ---------------------------------------------------------------------------
00173 void AbstractDOMParser::reset()
00174 {
00175     // if fDocument exists already, store the old pointer in the vector for deletion later
00176     if (fDocument && !fDocumentAdoptedByUser) {
00177         if (!fDocumentVector) {
00178             // allocate the vector if not exists yet
00179             fDocumentVector  = new (fMemoryManager) RefVectorOf<DOMDocumentImpl>(10, true, fMemoryManager) ;
00180         }
00181         fDocumentVector->addElement(fDocument);
00182     }
00183 
00184     fDocument = 0;
00185     resetDocType();
00186     fCurrentParent   = 0;
00187     fCurrentNode     = 0;
00188     fCurrentEntity   = 0;
00189     fWithinElement   = false;
00190     fDocumentAdoptedByUser = false;
00191     fInternalSubset.reset();
00192 }
00193 
00194 
00195 void AbstractDOMParser::resetInProgress()
00196 {
00197     fParseInProgress = false;
00198 }
00199 
00200 
00201 void AbstractDOMParser::resetPool()
00202 {
00203     //  We cannot enter here while a regular parse is in progress.
00204     if (fParseInProgress)
00205         ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
00206 
00207     if (fDocumentVector)
00208         fDocumentVector->removeAllElements();
00209 
00210     if (!fDocumentAdoptedByUser && fDocument)
00211         fDocument->release();
00212 
00213     fDocument = 0;
00214 }
00215 
00216 bool AbstractDOMParser::isDocumentAdopted() const
00217 {
00218     return fDocumentAdoptedByUser;
00219 }
00220 
00221 DOMDocument* AbstractDOMParser::adoptDocument()
00222 {
00223     fDocumentAdoptedByUser = true;
00224     return fDocument;
00225 }
00226 
00227 
00228 // ---------------------------------------------------------------------------
00229 //  AbstractDOMParser: Getter methods
00230 // ---------------------------------------------------------------------------
00231 DOMDocument* AbstractDOMParser::getDocument()
00232 {
00233     return fDocument;
00234 }
00235 
00236 const XMLValidator& AbstractDOMParser::getValidator() const
00237 {
00238     return *fScanner->getValidator();
00239 }
00240 
00241 bool AbstractDOMParser::getDoNamespaces() const
00242 {
00243     return fScanner->getDoNamespaces();
00244 }
00245 
00246 bool AbstractDOMParser::getGenerateSyntheticAnnotations() const
00247 {
00248     return fScanner->getGenerateSyntheticAnnotations();
00249 }
00250 
00251 bool AbstractDOMParser::getValidateAnnotations() const
00252 {
00253     return fScanner->getValidateAnnotations();
00254 }
00255 
00256 bool AbstractDOMParser::getExitOnFirstFatalError() const
00257 {
00258     return fScanner->getExitOnFirstFatal();
00259 }
00260 
00261 bool AbstractDOMParser::getValidationConstraintFatal() const
00262 {
00263     return fScanner->getValidationConstraintFatal();
00264 }
00265 
00266 AbstractDOMParser::ValSchemes AbstractDOMParser::getValidationScheme() const
00267 {
00268     const XMLScanner::ValSchemes scheme = fScanner->getValidationScheme();
00269 
00270     if (scheme == XMLScanner::Val_Always)
00271         return Val_Always;
00272     else if (scheme == XMLScanner::Val_Never)
00273         return Val_Never;
00274 
00275     return Val_Auto;
00276 }
00277 
00278 bool AbstractDOMParser::getDoSchema() const
00279 {
00280     return fScanner->getDoSchema();
00281 }
00282 
00283 bool AbstractDOMParser::getValidationSchemaFullChecking() const
00284 {
00285     return fScanner->getValidationSchemaFullChecking();
00286 }
00287 
00288 bool AbstractDOMParser::getIdentityConstraintChecking() const
00289 {
00290     return fScanner->getIdentityConstraintChecking();
00291 }
00292 
00293 XMLSize_t AbstractDOMParser::getErrorCount() const
00294 {
00295     return fScanner->getErrorCount();
00296 }
00297 
00298 XMLCh* AbstractDOMParser::getExternalSchemaLocation() const
00299 {
00300     return fScanner->getExternalSchemaLocation();
00301 }
00302 
00303 XMLCh* AbstractDOMParser::getExternalNoNamespaceSchemaLocation() const
00304 {
00305     return fScanner->getExternalNoNamespaceSchemaLocation();
00306 }
00307 
00308 SecurityManager* AbstractDOMParser::getSecurityManager() const
00309 {
00310     return fScanner->getSecurityManager();
00311 }
00312 
00313 // Return it as a reference so that we cn return as void* from getParameter.
00314 //
00315 const XMLSize_t& AbstractDOMParser::getLowWaterMark() const
00316 {
00317     return fScanner->getLowWaterMark();
00318 }
00319 
00320 bool AbstractDOMParser::getLoadExternalDTD() const
00321 {
00322     return fScanner->getLoadExternalDTD();
00323 }
00324 
00325 bool AbstractDOMParser::getLoadSchema() const
00326 {
00327     return fScanner->getLoadSchema();
00328 }
00329 
00330 bool AbstractDOMParser::getCalculateSrcOfs() const
00331 {
00332     return fScanner->getCalculateSrcOfs();
00333 }
00334 
00335 bool AbstractDOMParser::getStandardUriConformant() const
00336 {
00337     return fScanner->getStandardUriConformant();
00338 }
00339 
00340 bool AbstractDOMParser::getIgnoreAnnotations() const
00341 {
00342     return fScanner->getIgnoreAnnotations();
00343 }
00344 
00345 bool AbstractDOMParser::getDisableDefaultEntityResolution() const
00346 {
00347     return fScanner->getDisableDefaultEntityResolution();
00348 }
00349 
00350 bool AbstractDOMParser::getSkipDTDValidation() const
00351 {
00352     return fScanner->getSkipDTDValidation();
00353 }
00354 
00355 bool AbstractDOMParser::getHandleMultipleImports() const
00356 {
00357     return fScanner->getHandleMultipleImports();
00358 }
00359 
00360 // ---------------------------------------------------------------------------
00361 //  AbstractDOMParser: Setter methods
00362 // ---------------------------------------------------------------------------
00363 void AbstractDOMParser::setPSVIHandler(PSVIHandler* const handler)
00364 {
00365     fPSVIHandler = handler;
00366     if (fPSVIHandler) {
00367         fScanner->setPSVIHandler(this);
00368     }
00369     else if(!fCreateSchemaInfo) {
00370         fScanner->setPSVIHandler(0);
00371     }
00372 }
00373 
00374 
00375 void AbstractDOMParser::setDoNamespaces(const bool newState)
00376 {
00377     fScanner->setDoNamespaces(newState);
00378 }
00379 
00380 void AbstractDOMParser::setGenerateSyntheticAnnotations(const bool newState)
00381 {
00382     fScanner->setGenerateSyntheticAnnotations(newState);
00383 }
00384 
00385 void AbstractDOMParser::setValidateAnnotations(const bool newState)
00386 {
00387     fScanner->setValidateAnnotations(newState);
00388 }
00389 
00390 void AbstractDOMParser::setExitOnFirstFatalError(const bool newState)
00391 {
00392     fScanner->setExitOnFirstFatal(newState);
00393 }
00394 
00395 void AbstractDOMParser::setValidationConstraintFatal(const bool newState)
00396 {
00397     fScanner->setValidationConstraintFatal(newState);
00398 }
00399 
00400 void AbstractDOMParser::setValidationScheme(const ValSchemes newScheme)
00401 {
00402     if (newScheme == Val_Never)
00403         fScanner->setValidationScheme(XMLScanner::Val_Never);
00404     else if (newScheme == Val_Always)
00405         fScanner->setValidationScheme(XMLScanner::Val_Always);
00406     else
00407         fScanner->setValidationScheme(XMLScanner::Val_Auto);
00408 }
00409 
00410 void AbstractDOMParser::setDoSchema(const bool newState)
00411 {
00412     fScanner->setDoSchema(newState);
00413 }
00414 
00415 void AbstractDOMParser::setValidationSchemaFullChecking(const bool schemaFullChecking)
00416 {
00417     fScanner->setValidationSchemaFullChecking(schemaFullChecking);
00418 }
00419 
00420 void AbstractDOMParser::setIdentityConstraintChecking(const bool identityConstraintChecking)
00421 {
00422     fScanner->setIdentityConstraintChecking(identityConstraintChecking);
00423 }
00424 
00425 void AbstractDOMParser::setExternalSchemaLocation(const XMLCh* const schemaLocation)
00426 {
00427     fScanner->setExternalSchemaLocation(schemaLocation);
00428 }
00429 void AbstractDOMParser::setExternalNoNamespaceSchemaLocation(const XMLCh* const noNamespaceSchemaLocation)
00430 {
00431     fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation);
00432 }
00433 
00434 void AbstractDOMParser::setExternalSchemaLocation(const char* const schemaLocation)
00435 {
00436     fScanner->setExternalSchemaLocation(schemaLocation);
00437 }
00438 void AbstractDOMParser::setExternalNoNamespaceSchemaLocation(const char* const noNamespaceSchemaLocation)
00439 {
00440     fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation);
00441 }
00442 
00443 void AbstractDOMParser::setSecurityManager(SecurityManager* const securityManager)
00444 {
00445     // since this could impact various components, don't permit it to change
00446     // during a parse
00447     if (fParseInProgress)
00448         ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
00449 
00450     fScanner->setSecurityManager(securityManager);
00451 }
00452 
00453 void AbstractDOMParser::setLowWaterMark(XMLSize_t lwm)
00454 {
00455     fScanner->setLowWaterMark(lwm);
00456 }
00457 
00458 void AbstractDOMParser::setLoadExternalDTD(const bool newState)
00459 {
00460     fScanner->setLoadExternalDTD(newState);
00461 }
00462 
00463 void AbstractDOMParser::setLoadSchema(const bool newState)
00464 {
00465     fScanner->setLoadSchema(newState);
00466 }
00467 
00468 void AbstractDOMParser::setCalculateSrcOfs(const bool newState)
00469 {
00470     fScanner->setCalculateSrcOfs(newState);
00471 }
00472 
00473 void AbstractDOMParser::setStandardUriConformant(const bool newState)
00474 {
00475     fScanner->setStandardUriConformant(newState);
00476 }
00477 
00478 void AbstractDOMParser::useScanner(const XMLCh* const scannerName)
00479 {
00480     XMLScanner* tempScanner = XMLScannerResolver::resolveScanner
00481     (
00482         scannerName
00483         , fValidator
00484         , fGrammarResolver
00485         , fMemoryManager
00486     );
00487 
00488     if (tempScanner) {
00489 
00490         tempScanner->setParseSettings(fScanner);
00491         tempScanner->setURIStringPool(fURIStringPool);
00492         delete fScanner;
00493         fScanner = tempScanner;
00494     }
00495 }
00496 
00497 void AbstractDOMParser::setCreateSchemaInfo(const bool create)
00498 {
00499     fCreateSchemaInfo = create;
00500     if(fCreateSchemaInfo)
00501         fScanner->setPSVIHandler(this);
00502     else if(!fPSVIHandler)
00503         fScanner->setPSVIHandler(0);
00504 }
00505 
00506 void AbstractDOMParser::setIgnoreAnnotations(const bool newValue)
00507 {
00508     fScanner->setIgnoreAnnotations(newValue);
00509 }
00510 
00511 void AbstractDOMParser::setDisableDefaultEntityResolution(const bool newValue)
00512 {
00513     fScanner->setDisableDefaultEntityResolution(newValue);
00514 }
00515 
00516 void AbstractDOMParser::setSkipDTDValidation(const bool newValue)
00517 {
00518     fScanner->setSkipDTDValidation(newValue);
00519 }
00520 
00521 void AbstractDOMParser::setHandleMultipleImports(const bool newValue)
00522 {
00523     fScanner->setHandleMultipleImports(newValue);
00524 }
00525 
00526 void AbstractDOMParser::setDocument(DOMDocument* toSet)
00527 {
00528     fDocument = (DOMDocumentImpl *)toSet;
00529 }
00530 
00531 // ---------------------------------------------------------------------------
00532 //  AbstractDOMParser: Parsing methods
00533 // ---------------------------------------------------------------------------
00534 void AbstractDOMParser::parse(const InputSource& source)
00535 {
00536     // Avoid multiple entrance
00537     if (fParseInProgress)
00538         ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
00539 
00540     ResetInProgressType     resetInProgress(this, &AbstractDOMParser::resetInProgress);
00541 
00542     try
00543     {
00544         fParseInProgress = true;
00545         fScanner->scanDocument(source);
00546 
00547         if (fDoXInclude && getErrorCount()==0){
00548                     DOMDocument *doc = getDocument();
00549             // after XInclude, the document must be normalized
00550             if(doc)
00551                 doc->normalizeDocument();
00552         }
00553     }
00554     catch(const OutOfMemoryException&)
00555     {
00556         resetInProgress.release();
00557 
00558         throw;
00559     }
00560 }
00561 
00562 void AbstractDOMParser::parse(const XMLCh* const systemId)
00563 {
00564     // Avoid multiple entrance
00565     if (fParseInProgress)
00566         ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
00567 
00568     ResetInProgressType     resetInProgress(this, &AbstractDOMParser::resetInProgress);
00569 
00570     try
00571     {
00572         fParseInProgress = true;
00573         fScanner->scanDocument(systemId);
00574 
00575         if (fDoXInclude && getErrorCount()==0){
00576                     DOMDocument *doc = getDocument();
00577             // after XInclude, the document must be normalized
00578             if(doc)
00579                 doc->normalizeDocument();
00580         }
00581     }
00582     catch(const OutOfMemoryException&)
00583     {
00584         resetInProgress.release();
00585 
00586         throw;
00587     }
00588 }
00589 
00590 void AbstractDOMParser::parse(const char* const systemId)
00591 {
00592     // Avoid multiple entrance
00593     if (fParseInProgress)
00594         ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
00595 
00596     ResetInProgressType     resetInProgress(this, &AbstractDOMParser::resetInProgress);
00597 
00598     try
00599     {
00600         fParseInProgress = true;
00601         fScanner->scanDocument(systemId);
00602 
00603         if (fDoXInclude && getErrorCount()==0){
00604                     DOMDocument *doc = getDocument();
00605             // after XInclude, the document must be normalized
00606             if(doc)
00607                 doc->normalizeDocument();
00608         }
00609     }
00610     catch(const OutOfMemoryException&)
00611     {
00612         resetInProgress.release();
00613 
00614         throw;
00615     }
00616 }
00617 
00618 
00619 
00620 // ---------------------------------------------------------------------------
00621 //  AbstractDOMParser: Progressive parse methods
00622 // ---------------------------------------------------------------------------
00623 bool AbstractDOMParser::parseFirst( const XMLCh* const    systemId
00624                                    ,       XMLPScanToken&  toFill)
00625 {
00626     //
00627     //  Avoid multiple entrance. We cannot enter here while a regular parse
00628     //  is in progress.
00629     //
00630     if (fParseInProgress)
00631         ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
00632 
00633     return fScanner->scanFirst(systemId, toFill);
00634 }
00635 
00636 bool AbstractDOMParser::parseFirst( const char* const         systemId
00637                                    ,       XMLPScanToken&      toFill)
00638 {
00639     //
00640     //  Avoid multiple entrance. We cannot enter here while a regular parse
00641     //  is in progress.
00642     //
00643     if (fParseInProgress)
00644         ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
00645 
00646     return fScanner->scanFirst(systemId, toFill);
00647 }
00648 
00649 bool AbstractDOMParser::parseFirst( const InputSource& source
00650                                    ,       XMLPScanToken&  toFill)
00651 {
00652     //
00653     //  Avoid multiple entrance. We cannot enter here while a regular parse
00654     //  is in progress.
00655     //
00656     if (fParseInProgress)
00657         ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
00658 
00659     return fScanner->scanFirst(source, toFill);
00660 }
00661 
00662 bool AbstractDOMParser::parseNext(XMLPScanToken& token)
00663 {
00664     return fScanner->scanNext(token);
00665 }
00666 
00667 void AbstractDOMParser::parseReset(XMLPScanToken& token)
00668 {
00669     // Reset the scanner, and then reset the parser
00670     fScanner->scanReset(token);
00671     reset();
00672 }
00673 
00674 
00675 // ---------------------------------------------------------------------------
00676 //  AbstractDOMParser: Implementation of PSVIHandler interface
00677 // ---------------------------------------------------------------------------
00678 void AbstractDOMParser::handleElementPSVI(const XMLCh* const            localName
00679                                         , const XMLCh* const            uri
00680                                         ,       PSVIElement *           elementInfo)
00681 {
00682     // associate the info now; if the user wants, she can override what we did
00683     if(fCreateSchemaInfo)
00684     {
00685         DOMTypeInfoImpl* typeInfo=new (getDocument()) DOMTypeInfoImpl();
00686         typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Validity, elementInfo->getValidity());
00687         typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Validation_Attempted, elementInfo->getValidationAttempted());
00688         if(elementInfo->getTypeDefinition())
00689         {
00690             typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Type, elementInfo->getTypeDefinition()->getTypeCategory());
00691             typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Anonymous, elementInfo->getTypeDefinition()->getAnonymous());
00692             typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Namespace,
00693                 fDocument->getPooledString(elementInfo->getTypeDefinition()->getNamespace()));
00694             typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Name,
00695                 fDocument->getPooledString(elementInfo->getTypeDefinition()->getName()));
00696         }
00697         else if(elementInfo->getValidity()==PSVIItem::VALIDITY_VALID)
00698         {
00699             // if we are valid but we don't have a type validator, we are xs:anyType
00700             typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Type, XSTypeDefinition::COMPLEX_TYPE);
00701             typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Anonymous, false);
00702             typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Namespace, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
00703             typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Name, SchemaSymbols::fgATTVAL_ANYTYPE);
00704         }
00705         if(elementInfo->getMemberTypeDefinition())
00706         {
00707             typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Anonymous, elementInfo->getMemberTypeDefinition()->getAnonymous());
00708             typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Namespace,
00709                 fDocument->getPooledString(elementInfo->getMemberTypeDefinition()->getNamespace()));
00710             typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Name,
00711                 fDocument->getPooledString(elementInfo->getMemberTypeDefinition()->getName()));
00712         }
00713         if(elementInfo->getElementDeclaration())
00714             typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Nil, elementInfo->getElementDeclaration()->getNillable());
00715         typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Schema_Default, fDocument->getPooledString(elementInfo->getSchemaDefault()));
00716         typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Schema_Normalized_Value, fDocument->getPooledString(elementInfo->getSchemaNormalizedValue()));
00717         typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Schema_Specified, true);
00718         ((DOMElementNSImpl*)fCurrentParent)->setSchemaTypeInfo(typeInfo);
00719     }
00720     if(fPSVIHandler)
00721         fPSVIHandler->handleElementPSVI(localName, uri, elementInfo);
00722 }
00723 
00724 void AbstractDOMParser::handlePartialElementPSVI(const XMLCh* const            localName
00725                                                , const XMLCh* const            uri
00726                                                ,       PSVIElement *           elementInfo)
00727 {
00728     if(fPSVIHandler)
00729         fPSVIHandler->handlePartialElementPSVI(localName, uri, elementInfo);
00730 }
00731 
00732 void AbstractDOMParser::handleAttributesPSVI( const XMLCh* const            localName
00733                                             , const XMLCh* const            uri
00734                                             ,       PSVIAttributeList *     psviAttributes)
00735 {
00736     if(fCreateSchemaInfo)
00737     {
00738         for (XMLSize_t index=0; index < psviAttributes->getLength(); index++) {
00739             XERCES_CPP_NAMESPACE_QUALIFIER PSVIAttribute *attrInfo=psviAttributes->getAttributePSVIAtIndex(index);
00740             XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* pAttrNode=fCurrentNode->getAttributes()->getNamedItemNS(psviAttributes->getAttributeNamespaceAtIndex(index),
00741                                                                                                             psviAttributes->getAttributeNameAtIndex(index));
00742             if(pAttrNode!=NULL)
00743             {
00744                 DOMTypeInfoImpl* typeInfo=new (getDocument()) DOMTypeInfoImpl();
00745                 typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Validity, attrInfo->getValidity());
00746                 typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Validation_Attempted, attrInfo->getValidationAttempted());
00747                 if(attrInfo->getTypeDefinition())
00748                 {
00749                     typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Type, XSTypeDefinition::SIMPLE_TYPE);
00750                     typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Anonymous, attrInfo->getTypeDefinition()->getAnonymous());
00751                     typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Namespace,
00752                         fDocument->getPooledString(attrInfo->getTypeDefinition()->getNamespace()));
00753                     typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Name,
00754                         fDocument->getPooledString(attrInfo->getTypeDefinition()->getName()));
00755                 }
00756                 else if(attrInfo->getValidity()==PSVIItem::VALIDITY_VALID)
00757                 {
00758                     // if we are valid but we don't have a type validator, we are xs:anySimpleType
00759                     typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Type, XSTypeDefinition::SIMPLE_TYPE);
00760                     typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Anonymous, false);
00761                     typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Namespace, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
00762                     typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Name, SchemaSymbols::fgDT_ANYSIMPLETYPE);
00763                 }
00764                 if(attrInfo->getMemberTypeDefinition())
00765                 {
00766                     typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Anonymous, attrInfo->getMemberTypeDefinition()->getAnonymous());
00767                     typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Namespace,
00768                         fDocument->getPooledString(attrInfo->getMemberTypeDefinition()->getNamespace()));
00769                     typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Name,
00770                         fDocument->getPooledString(attrInfo->getMemberTypeDefinition()->getName()));
00771                 }
00772                 typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Schema_Default, fDocument->getPooledString(attrInfo->getSchemaDefault()));
00773                 typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Schema_Normalized_Value, fDocument->getPooledString(attrInfo->getSchemaNormalizedValue()));
00774                 typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Schema_Specified, true);
00775                 ((DOMAttrImpl*)pAttrNode)->setSchemaTypeInfo(typeInfo);
00776             }
00777         }
00778     }
00779     // associate the info now; if the user wants, she can override what we did
00780     if(fPSVIHandler)
00781         fPSVIHandler->handleAttributesPSVI(localName, uri, psviAttributes);
00782 }
00783 
00784 // ---------------------------------------------------------------------------
00785 //  AbstractDOMParser: Implementation of XMLDocumentHandler interface
00786 // ---------------------------------------------------------------------------
00787 void AbstractDOMParser::docCharacters(  const   XMLCh* const    chars
00788                               , const XMLSize_t    length
00789                               , const bool         cdataSection)
00790 {
00791     // Ignore chars outside of content
00792     if (!fWithinElement)
00793         return;
00794 
00795     if (cdataSection == true)
00796     {
00797         DOMCDATASection *node = createCDATASection (chars, length);
00798         castToParentImpl (fCurrentParent)->appendChildFast (node);
00799         fCurrentNode = node;
00800     }
00801     else
00802     {
00803         if (fCurrentNode->getNodeType() == DOMNode::TEXT_NODE)
00804         {
00805             DOMTextImpl *node = (DOMTextImpl*)fCurrentNode;
00806             node->appendData(chars, length);
00807         }
00808         else
00809         {
00810             DOMText *node = createText (chars, length);
00811             castToParentImpl (fCurrentParent)->appendChildFast (node);
00812             fCurrentNode = node;
00813         }
00814     }
00815 }
00816 
00817 
00818 void AbstractDOMParser::docComment(const XMLCh* const comment)
00819 {
00820     if (fCreateCommentNodes) {
00821         DOMComment *dcom = fDocument->createComment(comment);
00822         castToParentImpl (fCurrentParent)->appendChildFast (dcom);
00823         fCurrentNode = dcom;
00824     }
00825 }
00826 
00827 
00828 void AbstractDOMParser::docPI(  const   XMLCh* const    target
00829                       , const XMLCh* const    data)
00830 {
00831     DOMProcessingInstruction *pi = fDocument->createProcessingInstruction
00832         (
00833         target
00834         , data
00835         );
00836     castToParentImpl (fCurrentParent)->appendChildFast (pi);
00837     fCurrentNode = pi;
00838 }
00839 
00840 
00841 void AbstractDOMParser::endEntityReference(const XMLEntityDecl&)
00842 {
00843     if (!fCreateEntityReferenceNodes)
00844       return;
00845 
00846     DOMEntityReferenceImpl *erImpl = 0;
00847 
00848     if (fCurrentParent->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE)
00849         erImpl = (DOMEntityReferenceImpl *) fCurrentParent;
00850 
00851     fCurrentNode   = fCurrentParent;
00852     fCurrentParent = fCurrentNode->getParentNode ();
00853 
00854     // When the document is invalid but we continue parsing, we may
00855     // end up seeing more 'end' events than the 'start' ones.
00856     //
00857     if (fCurrentParent == 0 && fDocument != 0)
00858     {
00859       fCurrentNode = fDocument->getDocumentElement ();
00860       fCurrentParent = fCurrentNode;
00861     }
00862 
00863     if (erImpl)
00864         erImpl->setReadOnly(true, true);
00865 }
00866 
00867 
00868 void AbstractDOMParser::endElement( const   XMLElementDecl&
00869                            , const unsigned int
00870                            , const bool
00871                            , const XMLCh* const)
00872 {
00873     fCurrentNode   = fCurrentParent;
00874     fCurrentParent = fCurrentNode->getParentNode ();
00875 
00876     // When the document is invalid but we continue parsing, we may
00877     // end up seeing more 'end' events than the 'start' ones.
00878     //
00879     if (fCurrentParent == 0 && fDocument != 0)
00880     {
00881       fCurrentNode = fDocument->getDocumentElement ();
00882       fCurrentParent = fCurrentNode;
00883     }
00884 
00885     // If we've hit the end of content, clear the flag.
00886     //
00887     if (fCurrentParent == fDocument)
00888         fWithinElement = false;
00889 
00890     if(fDoXInclude &&
00891        (XIncludeUtils::isXIIncludeDOMNode(fCurrentNode) ||
00892         ((XIncludeUtils::isXIFallbackDOMNode(fCurrentNode) &&
00893           !XMLString::equals(fCurrentParent->getNamespaceURI(), XIncludeUtils::fgXIIIncludeNamespaceURI)))))
00894     {
00895         XIncludeUtils xiu((XMLErrorReporter *) this);
00896             // process the XInclude node, then update the fCurrentNode with the new content
00897             if(xiu.parseDOMNodeDoingXInclude(fCurrentNode, fDocument, getScanner()->getEntityHandler()))
00898             fCurrentNode = fCurrentParent->getLastChild();
00899     }
00900 }
00901 
00902 
00903 void AbstractDOMParser::ignorableWhitespace(  const XMLCh* const    chars
00904                                             , const XMLSize_t       length
00905                                             , const bool)
00906 {
00907     // Ignore chars before the root element
00908     if (!fWithinElement || !fIncludeIgnorableWhitespace)
00909         return;
00910 
00911     // revisit.  Not safe to slam in a null like this.
00912     XMLCh savedChar = chars[length];
00913     XMLCh *ncChars  = (XMLCh *)chars;   // cast off const
00914     ncChars[length] = chNull;
00915 
00916     if (fCurrentNode->getNodeType() == DOMNode::TEXT_NODE)
00917     {
00918         DOMText *node = (DOMText *)fCurrentNode;
00919         node->appendData(chars);
00920     }
00921     else
00922     {
00923         DOMTextImpl *node = (DOMTextImpl *)fDocument->createTextNode(chars);
00924         node->setIgnorableWhitespace(true);
00925         castToParentImpl (fCurrentParent)->appendChildFast (node);
00926 
00927         fCurrentNode = node;
00928     }
00929     ncChars[length] = savedChar;
00930 }
00931 
00932 
00933 void AbstractDOMParser::resetDocument()
00934 {
00935     //
00936     //  The reset methods are called before a new parse event occurs.
00937     //  Reset this parsers state to clear out anything that may be left
00938     //  from a previous use, in particular the DOM document itself.
00939     //
00940     this->reset();
00941 }
00942 
00943 
00944 void AbstractDOMParser::startDocument()
00945 {
00946     if(fImplementationFeatures == 0)
00947         fDocument = (DOMDocumentImpl *)DOMImplementation::getImplementation()->createDocument(fMemoryManager);
00948     else
00949         fDocument = (DOMDocumentImpl *)DOMImplementationRegistry::getDOMImplementation(fImplementationFeatures)->createDocument(fMemoryManager);
00950 
00951     // Just set the document as the current parent and current node
00952     fCurrentParent = fDocument;
00953     fCurrentNode   = fDocument;
00954     // set DOM error checking off
00955     fDocument->setErrorChecking(false);
00956     fDocument->setDocumentURI(fScanner->getLocator()->getSystemId());
00957     fDocument->setInputEncoding(fScanner->getReaderMgr()->getCurrentEncodingStr());
00958 }
00959 
00960 
00961 void AbstractDOMParser::endDocument()
00962 {
00963     // set DOM error checking back on
00964     fDocument->setErrorChecking(true);
00965 
00966     // DOM L2 does not support editing DocumentType nodes
00967     if (fDocumentType && fScanner -> getDoNamespaces())
00968         fDocumentType->setReadOnly(true, true);
00969 }
00970 
00971 
00972 void AbstractDOMParser::startElement(const XMLElementDecl&   elemDecl
00973                              , const unsigned int            urlId
00974                              , const XMLCh* const            elemPrefix
00975                              , const RefVectorOf<XMLAttr>&   attrList
00976                              , const XMLSize_t               attrCount
00977                              , const bool                    isEmpty
00978                              , const bool                    isRoot)
00979 {
00980     DOMElement     *elem;
00981     DOMElementImpl *elemImpl;
00982     const XMLCh* namespaceURI = 0;
00983     bool doNamespaces = fScanner->getDoNamespaces();
00984 
00985     // Create the element name. Here we are going to bypass the
00986     // DOMDocument::createElement() interface and instantiate the
00987     // required types directly in order to avoid name checking
00988     // overhead.
00989     //
00990     if (doNamespaces)
00991     {
00992         //DOM Level 2, doNamespaces on
00993         //
00994         const XMLCh* localName = elemDecl.getBaseName();
00995 
00996         if (urlId != fScanner->getEmptyNamespaceId()) {  //TagName has a prefix
00997 
00998             namespaceURI = fScanner->getURIText(urlId); //get namespaceURI
00999 
01000             if (elemPrefix && *elemPrefix)
01001             {
01002                 XMLBufBid elemQName(&fBufMgr);
01003 
01004                 elemQName.set(elemPrefix);
01005                 elemQName.append(chColon);
01006                 elemQName.append(localName);
01007 
01008                 elem = createElementNS (
01009                   namespaceURI, elemPrefix, localName, elemQName.getRawBuffer());
01010             }
01011             else
01012               elem = createElementNS (namespaceURI, 0, localName, localName);
01013         }
01014         else
01015           elem = createElementNS (namespaceURI, 0, localName, localName);
01016     }
01017     else
01018     {   //DOM Level 1
01019         elem = createElement (elemDecl.getFullName());
01020     }
01021 
01022     elemImpl = (DOMElementImpl *) elem;
01023 
01024     if (attrCount)
01025     {
01026       unsigned int xmlnsNSId = fScanner->getXMLNSNamespaceId();
01027       unsigned int emptyNSId = fScanner->getEmptyNamespaceId();
01028 
01029       DOMAttrMapImpl* map = elemImpl->fAttributes;
01030       map->reserve (attrCount);
01031 
01032       for (XMLSize_t index = 0; index < attrCount; ++index)
01033       {
01034         const XMLAttr* oneAttrib = attrList.elementAt(index);
01035         DOMAttrImpl *attr = 0;
01036 
01037         if (doNamespaces)
01038         {
01039             //DOM Level 2, doNamespaces on
01040             //
01041             unsigned int attrURIId = oneAttrib->getURIId();
01042             const XMLCh* localName = oneAttrib->getName();
01043             const XMLCh* prefix = oneAttrib->getPrefix();
01044             namespaceURI = 0;
01045 
01046             if ((prefix==0 || *prefix==0) && XMLString::equals(localName, XMLUni::fgXMLNSString))
01047             {
01048                 // xmlns=...
01049                 attrURIId = xmlnsNSId;
01050             }
01051             if (attrURIId != emptyNSId)
01052             {
01053                 //TagName has a prefix
01054                 namespaceURI = fScanner->getURIText(attrURIId);
01055             }
01056 
01057             attr = (DOMAttrImpl*) createAttrNS (namespaceURI,
01058                                                 prefix,
01059                                                 localName,
01060                                                 oneAttrib->getQName());
01061 
01062             map->setNamedItemNSFast(attr);
01063         }
01064         else
01065         {
01066             attr = (DOMAttrImpl*) createAttr (oneAttrib->getName());
01067             map->setNamedItemFast(attr);
01068         }
01069 
01070         attr->setValueFast(oneAttrib->getValue());
01071 
01072         // Attributes of type ID.  If this is one, add it to the hashtable of IDs
01073         //   that is constructed for use by GetElementByID().
01074         //
01075         if (oneAttrib->getType()==XMLAttDef::ID)
01076         {
01077             if (fDocument->fNodeIDMap == 0)
01078                 fDocument->fNodeIDMap = new (fDocument) DOMNodeIDMap(500, fDocument);
01079             fDocument->fNodeIDMap->add(attr);
01080             attr->fNode.isIdAttr(true);
01081         }
01082 
01083         attr->setSpecified(oneAttrib->getSpecified());
01084 
01085         // store DTD validation information
01086         if(fCreateSchemaInfo)
01087         {
01088             switch(oneAttrib->getType())
01089             {
01090             case XMLAttDef::CData:          attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedCDATAAttribute); break;
01091             case XMLAttDef::ID:             attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDAttribute); break;
01092             case XMLAttDef::IDRef:          attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFAttribute); break;
01093             case XMLAttDef::IDRefs:         attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFSAttribute); break;
01094             case XMLAttDef::Entity:         attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITYAttribute); break;
01095             case XMLAttDef::Entities:       attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITIESAttribute); break;
01096             case XMLAttDef::NmToken:        attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENAttribute); break;
01097             case XMLAttDef::NmTokens:       attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENSAttribute); break;
01098             case XMLAttDef::Notation:       attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNOTATIONAttribute); break;
01099             case XMLAttDef::Enumeration:    attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENUMERATIONAttribute); break;
01100             default:                        attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdNotValidatedAttribute); break;
01101             }
01102         }
01103       }
01104     }
01105 
01106     //Set up the default attributes if any.
01107     //
01108     if (elemDecl.hasAttDefs())
01109     {
01110         XMLAttDefList* defAttrs = &elemDecl.getAttDefList();
01111         XMLAttDef* attr = 0;
01112         DOMAttrImpl * insertAttr = 0;
01113 
01114         for(XMLSize_t i=0; i<defAttrs->getAttDefCount(); i++)
01115         {
01116             attr = &defAttrs->getAttDef(i);
01117 
01118             const XMLAttDef::DefAttTypes defType = attr->getDefaultType();
01119             if ((defType == XMLAttDef::Default)
01120             ||  (defType == XMLAttDef::Fixed))
01121             {
01122 
01123                 if (doNamespaces)
01124                 {
01125                     // DOM Level 2 wants all namespace declaration attributes
01126                     // to be bound to "http://www.w3.org/2000/xmlns/"
01127                     // So as long as the XML parser doesn't do it, it needs to
01128                     // be done here.
01129                     const XMLCh* qualifiedName = attr->getFullName();
01130                     XMLBufBid bbPrefixQName(&fBufMgr);
01131                     XMLBuffer& prefixBuf = bbPrefixQName.getBuffer();
01132                     int colonPos = -1;
01133                     unsigned int uriId = fScanner->resolveQName(qualifiedName, prefixBuf, ElemStack::Mode_Attribute, colonPos);
01134 
01135                     const XMLCh* namespaceURI = 0;
01136                     if (XMLString::equals(qualifiedName, XMLUni::fgXMLNSString))    //for xmlns=...
01137                         uriId = fScanner->getXMLNSNamespaceId();
01138                     if (uriId != fScanner->getEmptyNamespaceId()) {  //TagName has a prefix
01139                         namespaceURI = fScanner->getURIText(uriId);
01140                     }
01141 
01142                     insertAttr = (DOMAttrImpl *) fDocument->createAttributeNS(namespaceURI,     // NameSpaceURI
01143                                                                               qualifiedName);   // qualified name
01144 
01145                     DOMAttr* remAttr = elemImpl->setDefaultAttributeNodeNS(insertAttr);
01146                     if (remAttr)
01147                         remAttr->release();
01148                 }
01149                 else
01150                 {
01151                     // Namespaces is turned off...
01152                     insertAttr = (DOMAttrImpl *) fDocument->createAttribute(attr->getFullName());
01153 
01154                     DOMNode* remAttr = elemImpl->setDefaultAttributeNode(insertAttr);
01155                     if (remAttr)
01156                         remAttr->release();
01157                 }
01158                 //need to do this before the get as otherwise we overwrite any value in the attr
01159                 if (attr->getValue() != 0)
01160                 {
01161                     insertAttr->setValueFast(attr->getValue());
01162                     insertAttr->setSpecified(false);
01163                 }
01164 
01165                 // store DTD validation information
01166                 if(fCreateSchemaInfo)
01167                 {
01168                     switch(attr->getType())
01169                     {
01170                     case XMLAttDef::CData:          insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedCDATAAttribute); break;
01171                     case XMLAttDef::ID:             insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDAttribute); break;
01172                     case XMLAttDef::IDRef:          insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFAttribute); break;
01173                     case XMLAttDef::IDRefs:         insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFSAttribute); break;
01174                     case XMLAttDef::Entity:         insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITYAttribute); break;
01175                     case XMLAttDef::Entities:       insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITIESAttribute); break;
01176                     case XMLAttDef::NmToken:        insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENAttribute); break;
01177                     case XMLAttDef::NmTokens:       insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENSAttribute); break;
01178                     case XMLAttDef::Notation:       insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNOTATIONAttribute); break;
01179                     case XMLAttDef::Enumeration:    insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENUMERATIONAttribute); break;
01180                     default:                        insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdNotValidatedAttribute); break;
01181                     }
01182                 }
01183             }
01184 
01185             insertAttr = 0;
01186             attr->reset();
01187         }
01188     }
01189 
01190     if (fCurrentParent != fDocument)
01191       castToParentImpl (fCurrentParent)->appendChildFast (elem);
01192     else
01193       fCurrentParent->appendChild (elem);
01194 
01195     fCurrentParent = elem;
01196     fCurrentNode = elem;
01197     fWithinElement = true;
01198 
01199     // If an empty element, do end right now (no endElement() will be called)
01200     if (isEmpty)
01201         endElement(elemDecl, urlId, isRoot, elemPrefix);
01202 }
01203 
01204 
01205 void AbstractDOMParser::startEntityReference(const XMLEntityDecl& entDecl)
01206 {
01207     const XMLCh * entName = entDecl.getName();
01208     DOMNamedNodeMap *entities = fDocumentType->getEntities();
01209     DOMEntityImpl* entity = (DOMEntityImpl*)entities->getNamedItem(entName);
01210     if (entity)
01211         entity->setInputEncoding(fScanner->getReaderMgr()->getCurrentEncodingStr());
01212     fCurrentEntity = entity;
01213 
01214 
01215     // Following line has been moved up so that erImpl is only declared
01216     // and used if create entity ref flag is true
01217     if (fCreateEntityReferenceNodes == true)    {
01218         DOMEntityReference *er = fDocument->createEntityReferenceByParser(entName);
01219 
01220         //set the readOnly flag to false before appending node, will be reset
01221         // in endEntityReference
01222         DOMEntityReferenceImpl *erImpl = (DOMEntityReferenceImpl *) er;
01223         erImpl->setReadOnly(false, true);
01224 
01225         castToParentImpl (fCurrentParent)->appendChildFast (er);
01226 
01227         fCurrentParent = er;
01228         fCurrentNode = er;
01229 
01230     // this entityRef needs to be stored in Entity map too.
01231     // We'd decide later whether the entity nodes should be created by a
01232     // separated method in parser or not. For now just stick it in if
01233     // the ref nodes are created
01234         if (entity)
01235             entity->setEntityRef(er);
01236     }
01237 }
01238 
01239 
01240 void AbstractDOMParser::XMLDecl(const   XMLCh* const version
01241                                 , const XMLCh* const encoding
01242                                 , const XMLCh* const standalone
01243                                 , const XMLCh* const actualEncStr)
01244 {
01245     fDocument->setXmlStandalone(XMLString::equals(XMLUni::fgYesString, standalone));
01246     fDocument->setXmlVersion(version);
01247     fDocument->setXmlEncoding(encoding);
01248     fDocument->setInputEncoding(actualEncStr);
01249 }
01250 
01251 // ---------------------------------------------------------------------------
01252 //  AbstractDOMParser: Helper methods
01253 // ---------------------------------------------------------------------------
01254 
01255 //doctypehandler interfaces
01256 void AbstractDOMParser::attDef
01257 (
01258     const   DTDElementDecl&     elemDecl
01259     , const DTDAttDef&          attDef
01260     , const bool
01261 )
01262 {
01263     if (fDocumentType->isIntSubsetReading())
01264     {
01265         if (elemDecl.hasAttDefs())
01266         {
01267             fInternalSubset.append(attDef.getFullName());
01268 
01269             // Get the type and display it
01270             const XMLAttDef::AttTypes type = attDef.getType();
01271             switch(type)
01272             {
01273             case XMLAttDef::CData :
01274                 fInternalSubset.append(chSpace);
01275                 fInternalSubset.append(XMLUni::fgCDATAString);
01276                 break;
01277             case XMLAttDef::ID :
01278                 fInternalSubset.append(chSpace);
01279                 fInternalSubset.append(XMLUni::fgIDString);
01280                 break;
01281             case XMLAttDef::IDRef :
01282                 fInternalSubset.append(chSpace);
01283                 fInternalSubset.append(XMLUni::fgIDRefString);
01284                 break;
01285             case XMLAttDef::IDRefs :
01286                 fInternalSubset.append(chSpace);
01287                 fInternalSubset.append(XMLUni::fgIDRefsString);
01288                 break;
01289             case XMLAttDef::Entity :
01290                 fInternalSubset.append(chSpace);
01291                 fInternalSubset.append(XMLUni::fgEntityString);
01292                 break;
01293             case XMLAttDef::Entities :
01294                 fInternalSubset.append(chSpace);
01295                 fInternalSubset.append(XMLUni::fgEntitiesString);
01296                 break;
01297             case XMLAttDef::NmToken :
01298                 fInternalSubset.append(chSpace);
01299                 fInternalSubset.append(XMLUni::fgNmTokenString);
01300                 break;
01301             case XMLAttDef::NmTokens :
01302                 fInternalSubset.append(chSpace);
01303                 fInternalSubset.append(XMLUni::fgNmTokensString);
01304                 break;
01305 
01306             case XMLAttDef::Notation :
01307                 fInternalSubset.append(chSpace);
01308                 fInternalSubset.append(XMLUni::fgNotationString);
01309                 break;
01310 
01311             case XMLAttDef::Enumeration :
01312                 {
01313                     fInternalSubset.append(chSpace);
01314                     const XMLCh* enumString = attDef.getEnumeration();
01315                     XMLSize_t length = XMLString::stringLen(enumString);
01316                     if (length > 0) {
01317 
01318                         fInternalSubset.append(chOpenParen );
01319                         for(XMLSize_t i=0; i<length; i++) {
01320                             if (enumString[i] == chSpace)
01321                                 fInternalSubset.append(chPipe);
01322                             else
01323                                 fInternalSubset.append(enumString[i]);
01324                         }
01325                         fInternalSubset.append(chCloseParen);
01326                     }
01327                 }
01328                 break;
01329             default:
01330                 // remaining types don't belong to a DTD
01331                 break;
01332             }
01333             //get te default types of the attlist
01334             const XMLAttDef::DefAttTypes def = attDef.getDefaultType();
01335             switch(def)
01336             {
01337             case XMLAttDef::Required :
01338                 fInternalSubset.append(chSpace);
01339                 fInternalSubset.append(XMLUni::fgRequiredString);
01340                 break;
01341             case XMLAttDef::Implied :
01342                 fInternalSubset.append(chSpace);
01343                 fInternalSubset.append(XMLUni::fgImpliedString);
01344                 break;
01345             case XMLAttDef::Fixed :
01346                 fInternalSubset.append(chSpace);
01347                 fInternalSubset.append(XMLUni::fgFixedString);
01348                 break;
01349             default:
01350                 // remaining types don't belong to a DTD
01351                 break;
01352             }
01353 
01354             const XMLCh* defaultValue = attDef.getValue();
01355             if (defaultValue != 0) {
01356                 fInternalSubset.append(chSpace);
01357                 fInternalSubset.append(chDoubleQuote);
01358                 fInternalSubset.append(defaultValue);
01359                 fInternalSubset.append(chDoubleQuote);
01360             }
01361         }
01362     }
01363 }
01364 
01365 void AbstractDOMParser::doctypeComment
01366 (
01367     const   XMLCh* const    comment
01368 )
01369 {
01370     if (fDocumentType->isIntSubsetReading())
01371     {
01372         if (comment != 0)
01373         {
01374             fInternalSubset.append(XMLUni::fgCommentString);
01375             fInternalSubset.append(chSpace);
01376             fInternalSubset.append(comment);
01377             fInternalSubset.append(chSpace);
01378             fInternalSubset.append(chDash);
01379             fInternalSubset.append(chDash);
01380             fInternalSubset.append(chCloseAngle);
01381         }
01382     }
01383 }
01384 
01385 void AbstractDOMParser::doctypeDecl
01386 (
01387     const   DTDElementDecl& elemDecl
01388     , const XMLCh* const    publicId
01389     , const XMLCh* const    systemId
01390     , const bool
01391     , const bool
01392 )
01393 {
01394     fDocumentType = (DOMDocumentTypeImpl *) fDocument->createDocumentType(elemDecl.getFullName(), publicId, systemId);
01395     fDocument->setDocumentType(fDocumentType);
01396 
01397 }
01398 
01399 void AbstractDOMParser::doctypePI
01400 (
01401     const   XMLCh* const    target
01402     , const XMLCh* const    data
01403 )
01404 {
01405     if (fDocumentType->isIntSubsetReading())
01406     {
01407         //add these chars to internalSubset variable
01408         fInternalSubset.append(chOpenAngle);
01409         fInternalSubset.append(chQuestion);
01410         fInternalSubset.append(target);
01411         fInternalSubset.append(chSpace);
01412         fInternalSubset.append(data);
01413         fInternalSubset.append(chQuestion);
01414         fInternalSubset.append(chCloseAngle);
01415     }
01416 }
01417 
01418 
01419 void AbstractDOMParser::doctypeWhitespace
01420 (
01421     const   XMLCh* const    chars
01422     , const XMLSize_t       length
01423 )
01424 {
01425     if (fDocumentType->isIntSubsetReading())
01426         fInternalSubset.append(chars, length);
01427 }
01428 
01429 void AbstractDOMParser::elementDecl
01430 (
01431     const   DTDElementDecl& decl
01432     , const bool
01433 )
01434 {
01435     if (fDocumentType->isIntSubsetReading())
01436     {
01437         fInternalSubset.append(chOpenAngle);
01438         fInternalSubset.append(chBang);
01439         fInternalSubset.append(XMLUni::fgElemString);
01440         fInternalSubset.append(chSpace);
01441         fInternalSubset.append(decl.getFullName());
01442 
01443         //get the ContentSpec information
01444         const XMLCh* contentModel = decl.getFormattedContentModel();
01445         if (contentModel != 0) {
01446             fInternalSubset.append(chSpace);
01447             fInternalSubset.append(contentModel);
01448         }
01449 
01450         fInternalSubset.append(chCloseAngle);
01451     }
01452 }
01453 
01454 void AbstractDOMParser::endAttList
01455 (
01456     const   DTDElementDecl& elemDecl
01457 )
01458 {
01459     if (fDocumentType->isIntSubsetReading())
01460     {
01461         //print the closing angle
01462         fInternalSubset.append(chCloseAngle);
01463     }
01464 
01465         // this section sets up default attributes.
01466         // default attribute nodes are stored in a NamedNodeMap DocumentTypeImpl::elements
01467         // default attribute data attached to the document is used to conform to the
01468         // DOM spec regarding creating element nodes & removing attributes with default values
01469         // see DocumentTypeImpl
01470         if (elemDecl.hasAttDefs())
01471         {
01472         XMLAttDefList* defAttrs = &elemDecl.getAttDefList();
01473         XMLAttDef* attr = 0;
01474 
01475         DOMAttrImpl * insertAttr = 0;
01476         DOMElement     *elem  = fDocument->createElement(elemDecl.getFullName());
01477         DOMElementImpl *elemImpl = (DOMElementImpl *) elem;
01478         bool doNamespaces = fScanner->getDoNamespaces();
01479 
01480         for(XMLSize_t i=0; i<defAttrs->getAttDefCount(); i++)
01481         {
01482             attr = &defAttrs->getAttDef(i);
01483             if (attr->getValue() != 0)
01484             {
01485                 if (doNamespaces)
01486                 {
01487                     // DOM Level 2 wants all namespace declaration attributes
01488                     // to be bound to "http://www.w3.org/2000/xmlns/"
01489                     // So as long as the XML parser doesn't do it, it needs to
01490                     // done here.
01491                     const XMLCh* qualifiedName = attr->getFullName();
01492                     int index = DOMDocumentImpl::indexofQualifiedName(qualifiedName);
01493 
01494                     XMLBufBid bbQName(&fBufMgr);
01495                     XMLBuffer& buf = bbQName.getBuffer();
01496                     static const XMLCh XMLNS[] = {
01497                         chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull};
01498 
01499                     if (index > 0) {
01500                         // there is prefix
01501                         // map to XML URI for all cases except when prefix == "xmlns"
01502                         XMLCh* prefix;
01503                         XMLCh temp[1000];
01504 
01505                         if (index > 999)
01506                             prefix = (XMLCh*) fMemoryManager->allocate
01507                             (
01508                                 (index + 1) * sizeof(XMLCh)
01509                             );//new XMLCh[index+1];
01510                         else
01511                             prefix = temp;
01512 
01513                         XMLString::subString(prefix ,qualifiedName, 0, index, fMemoryManager);
01514 
01515                         if (XMLString::equals(prefix,XMLNS))
01516                             buf.append(XMLUni::fgXMLNSURIName);
01517                         else
01518                             buf.append(XMLUni::fgXMLURIName);
01519 
01520                         if (index > 999)
01521                             fMemoryManager->deallocate(prefix);//delete [] prefix;
01522                     }
01523                     else {
01524                         //   No prefix
01525                         if (XMLString::equals(qualifiedName,XMLNS))
01526                             buf.append(XMLUni::fgXMLNSURIName);
01527                     }
01528 
01529                     insertAttr = (DOMAttrImpl *) fDocument->createAttributeNS(
01530                        buf.getRawBuffer(),     // NameSpaceURI
01531                        qualifiedName);   // qualified name
01532 
01533                     DOMNode* remAttr = elemImpl->setAttributeNodeNS(insertAttr);
01534                     if (remAttr)
01535                         remAttr->release();
01536                 }
01537                 else
01538                 {
01539                     // Namespaces is turned off...
01540                     insertAttr = (DOMAttrImpl *) fDocument->createAttribute(attr->getFullName());
01541                     DOMNode* remAttr = elemImpl->setAttributeNode(insertAttr);
01542                     if (remAttr)
01543                         remAttr->release();
01544                 }
01545 
01546                 insertAttr->setValueFast(attr->getValue());
01547                 insertAttr->setSpecified(false);
01548             }
01549         }
01550         DOMNode* rem = fDocumentType->getElements()->setNamedItem(elemImpl);
01551         if (rem)
01552             rem->release();
01553     }
01554 }
01555 
01556 void AbstractDOMParser::endIntSubset()
01557 {
01558     fDocumentType->setInternalSubset(fInternalSubset.getRawBuffer());
01559     // the buffer shouldn't be released as it is reused in the next parse
01560     // fBufMgr.releaseBuffer(fInternalSubset);
01561     fDocumentType->fIntSubsetReading = false;
01562 }
01563 
01564 void AbstractDOMParser::endExtSubset()
01565 {
01566 }
01567 
01568 void AbstractDOMParser::entityDecl
01569 (
01570     const   DTDEntityDecl&  entityDecl
01571     , const bool
01572     , const bool
01573 )
01574 {
01575     DOMEntityImpl* entity = (DOMEntityImpl *) fDocument->createEntity(entityDecl.getName());
01576 
01577     entity->setPublicId(entityDecl.getPublicId());
01578     entity->setSystemId(entityDecl.getSystemId());
01579     entity->setNotationName(entityDecl.getNotationName());
01580     entity->setBaseURI(entityDecl.getBaseURI());
01581 
01582     DOMEntityImpl *previousDef = (DOMEntityImpl *)
01583             fDocumentType->getEntities()->setNamedItem( entity );
01584 
01585     if (previousDef)
01586         previousDef->release();
01587 
01588     if (fDocumentType->isIntSubsetReading())
01589     {
01590         //add thes chars to internalSubset variable
01591         fInternalSubset.append(chOpenAngle);
01592         fInternalSubset.append(chBang);
01593         fInternalSubset.append(XMLUni::fgEntityString);
01594         fInternalSubset.append(chSpace);
01595 
01596         fInternalSubset.append(entityDecl.getName());
01597 
01598         const XMLCh* id = entity->getPublicId();
01599         if (id != 0) {
01600             fInternalSubset.append(chSpace);
01601             fInternalSubset.append(XMLUni::fgPubIDString);
01602             fInternalSubset.append(chSpace);
01603             fInternalSubset.append(chDoubleQuote);
01604             fInternalSubset.append(id);
01605             fInternalSubset.append(chDoubleQuote);
01606         }
01607         id = entity->getSystemId();
01608         if (id != 0) {
01609             fInternalSubset.append(chSpace);
01610             fInternalSubset.append(XMLUni::fgSysIDString);
01611             fInternalSubset.append(chSpace);
01612             fInternalSubset.append(chDoubleQuote);
01613             fInternalSubset.append(id);
01614             fInternalSubset.append(chDoubleQuote);
01615 
01616         }
01617         id = entity->getNotationName();
01618         if (id != 0) {
01619             fInternalSubset.append(chSpace);
01620             fInternalSubset.append(XMLUni::fgNDATAString);
01621             fInternalSubset.append(chSpace);
01622             fInternalSubset.append(id);
01623         }
01624         id = entityDecl.getValue();
01625         if (id !=0) {
01626             fInternalSubset.append(chSpace);
01627             fInternalSubset.append(chDoubleQuote);
01628             fInternalSubset.append(id);
01629             fInternalSubset.append(chDoubleQuote);
01630         }
01631 
01632         fInternalSubset.append(chCloseAngle);
01633     }
01634 
01635 }
01636 
01637 void AbstractDOMParser::resetDocType()
01638 {
01639         fDocumentType = 0;
01640 }
01641 
01642 void AbstractDOMParser::notationDecl
01643 (
01644     const   XMLNotationDecl&    notDecl
01645     , const bool
01646 )
01647 {
01648     DOMNotationImpl* notation = (DOMNotationImpl *)fDocument->createNotation(notDecl.getName());
01649     notation->setPublicId(notDecl.getPublicId());
01650     notation->setSystemId(notDecl.getSystemId());
01651     notation->setBaseURI(notDecl.getBaseURI());
01652 
01653     DOMNode* rem = fDocumentType->getNotations()->setNamedItem( notation );
01654     if (rem)
01655         rem->release();
01656 
01657     if (fDocumentType->isIntSubsetReading())
01658     {
01659         //add thes chars to internalSubset variable
01660         fInternalSubset.append(chOpenAngle);
01661         fInternalSubset.append(chBang);
01662         fInternalSubset.append(XMLUni::fgNotationString);
01663         fInternalSubset.append(chSpace);
01664 
01665         fInternalSubset.append(notDecl.getName());
01666 
01667         const XMLCh* id = notation->getPublicId();
01668         if (id != 0) {
01669             fInternalSubset.append(chSpace);
01670             fInternalSubset.append(XMLUni::fgPubIDString);
01671             fInternalSubset.append(chSpace);
01672             fInternalSubset.append(chDoubleQuote);
01673             fInternalSubset.append(id);
01674             fInternalSubset.append(chDoubleQuote);
01675         }
01676         id = notation->getSystemId();
01677         if (id != 0) {
01678             fInternalSubset.append(chSpace);
01679             fInternalSubset.append(XMLUni::fgSysIDString);
01680             fInternalSubset.append(chSpace);
01681             fInternalSubset.append(chDoubleQuote);
01682             fInternalSubset.append(id);
01683             fInternalSubset.append(chDoubleQuote);
01684 
01685         }
01686         fInternalSubset.append(chCloseAngle);
01687     }
01688 }
01689 
01690 void AbstractDOMParser::startAttList
01691 (
01692     const   DTDElementDecl& elemDecl
01693 )
01694 {
01695     if (fDocumentType->isIntSubsetReading())
01696     {
01697         fInternalSubset.append(chOpenAngle);
01698         fInternalSubset.append(chBang);
01699         fInternalSubset.append(XMLUni::fgAttListString);
01700         fInternalSubset.append(chSpace);
01701         fInternalSubset.append(elemDecl.getFullName());
01702     }
01703 }
01704 
01705 void AbstractDOMParser::startIntSubset()
01706 {
01707         fDocumentType->fIntSubsetReading = true;
01708 }
01709 
01710 void AbstractDOMParser::startExtSubset()
01711 {
01712 }
01713 
01714 void AbstractDOMParser::TextDecl
01715 (
01716     const   XMLCh* const    versionStr
01717     , const XMLCh* const    encodingStr
01718 )
01719 {
01720     if (fCurrentEntity) {
01721         fCurrentEntity->setXmlVersion(versionStr);
01722         fCurrentEntity->setXmlEncoding(encodingStr);
01723     }
01724 }
01725 
01726 DOMCDATASection* AbstractDOMParser::
01727 createCDATASection (const XMLCh* s, XMLSize_t n)
01728 {
01729   return new (fDocument, DOMMemoryManager::CDATA_SECTION_OBJECT)
01730     DOMCDATASectionImpl(fDocument, s, n);
01731 }
01732 
01733 
01734 DOMText* AbstractDOMParser::
01735 createText (const XMLCh* s, XMLSize_t n)
01736 {
01737   return new (fDocument, DOMMemoryManager::TEXT_OBJECT)
01738     DOMTextImpl(fDocument, s, n);
01739 }
01740 
01741 
01742 DOMElement* AbstractDOMParser::
01743 createElement (const XMLCh* name)
01744 {
01745   return new (fDocument, DOMMemoryManager::ELEMENT_OBJECT)
01746     DOMElementImpl(fDocument, name);
01747 }
01748 
01749 DOMElement* AbstractDOMParser::
01750 createElementNS (const XMLCh* namespaceURI,
01751                  const XMLCh* elemPrefix,
01752                  const XMLCh* localName,
01753                  const XMLCh* qName)
01754 {
01755   return new (fDocument, DOMMemoryManager::ELEMENT_NS_OBJECT)
01756     DOMElementNSImpl (fDocument,
01757                       namespaceURI,
01758                       elemPrefix,
01759                       localName,
01760                       qName);
01761 }
01762 
01763 DOMAttr* AbstractDOMParser::
01764 createAttr (const XMLCh* name)
01765 {
01766   return new (fDocument, DOMMemoryManager::ATTR_OBJECT)
01767     DOMAttrImpl(fDocument, name);
01768 }
01769 
01770 DOMAttr* AbstractDOMParser::
01771 createAttrNS (const XMLCh* namespaceURI,
01772               const XMLCh* elemPrefix,
01773               const XMLCh* localName,
01774               const XMLCh* qName)
01775 {
01776   return new (fDocument, DOMMemoryManager::ATTR_NS_OBJECT)
01777     DOMAttrNSImpl (fDocument,
01778                    namespaceURI,
01779                    elemPrefix,
01780                    localName,
01781                    qName);
01782 }
01783 
01784 XERCES_CPP_NAMESPACE_END