Ignore:
Timestamp:
Dec 12, 2012, 6:10:33 PM (6 years ago)
Author:
cameron
Message:

Various fixes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • icXML/icXML-devel/src/xercesc/dom/impl/DOMXPathExpressionImpl.cpp

    r2722 r2774  
    1 /*
    2  * Licensed to the Apache Software Foundation (ASF) under one or more
    3  * contributor license agreements.  See the NOTICE file distributed with
    4  * this work for additional information regarding copyright ownership.
    5  * The ASF licenses this file to You under the Apache License, Version 2.0
    6  * (the "License"); you may not use this file except in compliance with
    7  * the License.  You may obtain a copy of the License at
    8  *
    9  *      http://www.apache.org/licenses/LICENSE-2.0
    10  *
    11  * Unless required by applicable law or agreed to in writing, software
    12  * distributed under the License is distributed on an "AS IS" BASIS,
    13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  * See the License for the specific language governing permissions and
    15  * limitations under the License.
    16  */
    17 
    18 #include "DOMXPathExpressionImpl.hpp"
    19 #include "DOMXPathResultImpl.hpp"
    20 #include <xercesc/validators/schema/identity/XercesXPath.hpp>
    21 #include <xercesc/validators/schema/identity/XPathMatcher.hpp>
    22 #include <xercesc/validators/schema/identity/XPathException.hpp>
    23 #include <xercesc/validators/schema/SchemaElementDecl.hpp>
    24 #include <xercesc/util/StringPool.hpp>
    25 #include <xercesc/util/OutOfMemoryException.hpp>
    26 #include <xercesc/dom/DOMXPathException.hpp>
    27 #include <xercesc/dom/DOM.hpp>
    28 
    29 XERCES_CPP_NAMESPACE_BEGIN
    30 
    31 class WrapperForXPathNSResolver : public XercesNamespaceResolver
    32 {
    33 public:
    34     WrapperForXPathNSResolver(XMLStringPool* pool, const DOMXPathNSResolver *resolver, MemoryManager* const manager) :
    35       fStringPool(pool),
    36       fResolver(resolver),
    37       fMemoryManager(manager)
    38     {
    39     }
    40 
    41     virtual unsigned int getNamespaceForPrefix(const XMLCh* const prefix) const
    42     {
    43         if(fResolver==NULL)
    44             throw DOMException(DOMException::NAMESPACE_ERR, 0, fMemoryManager);
    45         const XMLCh* nsUri=fResolver->lookupNamespaceURI(prefix);
    46         if(nsUri==NULL)
    47             throw DOMException(DOMException::NAMESPACE_ERR, 0, fMemoryManager);
    48         return fStringPool->addOrFind(nsUri);
    49     }
    50 
    51 protected:
    52     XMLStringPool*              fStringPool;
    53     const DOMXPathNSResolver *  fResolver;
    54     MemoryManager* const        fMemoryManager;
    55 };
    56 
    57 
    58 typedef JanitorMemFunCall<DOMXPathExpressionImpl>     CleanupType;
    59 
    60 DOMXPathExpressionImpl::DOMXPathExpressionImpl(const XMLCh *expression, const DOMXPathNSResolver *resolver, MemoryManager* const manager) :
    61  fStringPool(NULL),
    62  fParsedExpression(NULL),
    63  fExpression(NULL),
    64  fMoveToRoot(false),
    65  fMemoryManager(manager)
    66 {
    67     if(expression==NULL || *expression==0)
    68         throw DOMXPathException(DOMXPathException::INVALID_EXPRESSION_ERR, 0, fMemoryManager);
    69 
    70     CleanupType cleanup(this, &DOMXPathExpressionImpl::cleanUp);
    71     fStringPool = new (fMemoryManager) XMLStringPool(109, fMemoryManager);
    72     // XercesPath will complain if the expression starts with '/', add a "." in front of it and start from the document root
    73     if(*expression==chForwardSlash)
    74     {
    75         fExpression=(XMLCh*)fMemoryManager->allocate((XMLString::stringLen(expression)+2)*sizeof(XMLCh));
    76         *fExpression = chPeriod;
    77         *(fExpression+1) = chNull;
    78         XMLString::catString(fExpression, expression);
    79         fMoveToRoot=true;
    80     }
    81     else
    82         fExpression=XMLString::replicate(expression);
    83 
    84     try
    85     {
    86         WrapperForXPathNSResolver wrappedResolver(fStringPool, resolver, fMemoryManager);
    87         fParsedExpression = new (fMemoryManager) XercesXPath(fExpression, fStringPool, &wrappedResolver, 0, true, fMemoryManager);
    88     }
    89     catch(const XPathException& )
    90     {
    91         throw DOMXPathException(DOMXPathException::INVALID_EXPRESSION_ERR, 0, fMemoryManager);
    92     }
    93     catch(const OutOfMemoryException&)
    94     {
    95         cleanup.release();
    96 
    97         throw;
    98     }
    99 
    100     cleanup.release();
    101 }
    102 
    103 DOMXPathExpressionImpl::~DOMXPathExpressionImpl()
    104 {
    105     cleanUp();
    106 }
    107 
    108 void DOMXPathExpressionImpl::cleanUp()
    109 {
    110     XMLString::release(&fExpression, fMemoryManager);
    111     delete fParsedExpression;
    112     delete fStringPool;
    113 }
    114 
    115 DOMXPathResult* DOMXPathExpressionImpl::evaluate(const DOMNode *contextNode,
    116                                                  DOMXPathResult::ResultType type,
    117                                                  DOMXPathResult* result) const
    118 {
    119     if(type!=DOMXPathResult::FIRST_ORDERED_NODE_TYPE && type!=DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE &&
    120        type!=DOMXPathResult::ANY_UNORDERED_NODE_TYPE && type!=DOMXPathResult::UNORDERED_NODE_SNAPSHOT_TYPE)
    121         throw DOMXPathException(DOMXPathException::TYPE_ERR, 0, fMemoryManager);
    122 
    123     if(contextNode==NULL || contextNode->getNodeType()!=DOMNode::ELEMENT_NODE)
    124         throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, fMemoryManager);
    125 
    126     JanitorMemFunCall<DOMXPathResultImpl> r_cleanup (
    127       0, &DOMXPathResultImpl::release);
    128     DOMXPathResultImpl* r=(DOMXPathResultImpl*)result;
    129     if(r==NULL)
    130     {
    131       r=new (fMemoryManager) DOMXPathResultImpl(type, fMemoryManager);
    132       r_cleanup.reset (r);
    133     }
    134     else
    135         r->reset(type);
    136 
    137     XPathMatcher matcher(fParsedExpression, fMemoryManager);
    138     matcher.startDocumentFragment();
    139 
    140     if(fMoveToRoot)
    141     {
    142         contextNode=contextNode->getOwnerDocument();
    143         if(contextNode==NULL)
    144             throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, fMemoryManager);
    145 
    146         QName qName(contextNode->getNodeName(), 0, fMemoryManager);
    147         SchemaElementDecl elemDecl(&qName);
    148         RefVectorOf<XMLAttr> attrList(0, true, fMemoryManager);
    149         matcher.startElement(elemDecl, 0, XMLUni::fgZeroLenString, attrList, 0);
    150         DOMNode* child=contextNode->getFirstChild();
    151         while(child)
    152         {
    153             if(child->getNodeType()==DOMNode::ELEMENT_NODE)
    154                 testNode(&matcher, r, (DOMElement*)child);
    155             child=child->getNextSibling();
    156         }
    157         matcher.endElement(elemDecl, XMLUni::fgZeroLenString);
    158     }
    159     else
    160         testNode(&matcher, r, (DOMElement*)contextNode);
    161 
    162     r_cleanup.release ();
    163     return r;
    164 }
    165 
    166 bool DOMXPathExpressionImpl::testNode(XPathMatcher* matcher, DOMXPathResultImpl* result, DOMElement *node) const
    167 {
    168     int uriId=fStringPool->addOrFind(node->getNamespaceURI());
    169     QName qName(node->getNodeName(), uriId, fMemoryManager);
    170     SchemaElementDecl elemDecl(&qName);
    171     DOMNamedNodeMap* attrMap=node->getAttributes();
    172     XMLSize_t attrCount = attrMap->getLength();
    173     RefVectorOf<XMLAttr> attrList(attrCount, true, fMemoryManager);
    174     for(XMLSize_t i=0;i<attrCount;i++)
    175     {
    176         DOMAttr* attr=(DOMAttr*)attrMap->item(i);
    177         attrList.addElement(new (fMemoryManager) XMLAttr(fStringPool->addOrFind(attr->getNamespaceURI()),
    178                                                          attr->getNodeName(),
    179                                                          attr->getNodeValue(),
    180                                                          XMLAttDef::CData,
    181                                                          attr->getSpecified(),
    182                                                          fMemoryManager,
    183                                                          NULL,
    184                                                          true));
    185     }
    186     matcher->startElement(elemDecl, uriId, node->getPrefix(), attrList, attrCount);
    187     unsigned char nMatch=matcher->isMatched();
    188     if(nMatch!=0 && nMatch!=XPathMatcher::XP_MATCHED_DP)
    189     {
    190         result->addResult(node);
    191         if(result->getResultType()==DOMXPathResult::ANY_UNORDERED_NODE_TYPE || result->getResultType()==DOMXPathResult::FIRST_ORDERED_NODE_TYPE)
    192             return true;    // abort navigation, we found one result
    193     }
    194 
    195     if(nMatch==0 || nMatch==XPathMatcher::XP_MATCHED_D || nMatch==XPathMatcher::XP_MATCHED_DP)
    196     {
    197         DOMNode* child=node->getFirstChild();
    198         while(child)
    199         {
    200             if(child->getNodeType()==DOMNode::ELEMENT_NODE)
    201                 if(testNode(matcher, result, (DOMElement*)child))
    202                     return true;
    203             child=child->getNextSibling();
    204         }
    205     }
    206     matcher->endElement(elemDecl, XMLUni::fgZeroLenString);
    207     return false;
    208 }
    209 
    210 void DOMXPathExpressionImpl::release()
    211 {
    212     DOMXPathExpressionImpl* me = this;
    213     delete me;
    214 }
    215 
    216 XERCES_CPP_NAMESPACE_END
     1#include <icxercesc/dom/impl/DOMXPathExpressionImpl.cpp>
Note: See TracChangeset for help on using the changeset viewer.