Exemple #1
0
XERCES_CPP_NAMESPACE_BEGIN

// ---------------------------------------------------------------------------
//  ContentSpecNode: Copy Constructor
//
//  Note: this copy constructor has dependency on various get*() methods
//        and shall be placed after those method's declaration.
//        aka inline function compilation error on AIX 4.2, xlC 3 r ev.1
// ---------------------------------------------------------------------------

ContentSpecNode::ContentSpecNode(const ContentSpecNode& toCopy) :
    fMemoryManager(toCopy.fMemoryManager)
    , fElement(0)
    , fElementDecl(toCopy.fElementDecl)
    , fFirst(0)
    , fSecond(0)
    , fType(toCopy.fType)
    , fAdoptFirst(true)
    , fAdoptSecond(true)
    , fMinOccurs(toCopy.fMinOccurs)
    , fMaxOccurs(toCopy.fMaxOccurs)
{
    const QName* tempElement = toCopy.getElement();
    if (tempElement)
        fElement = new (fMemoryManager) QName(*tempElement);

    const ContentSpecNode *tmp = toCopy.getFirst();
    if (tmp)
        fFirst = new (fMemoryManager) ContentSpecNode(*tmp);

    tmp = toCopy.getSecond();
    if (tmp)
        fSecond = new (fMemoryManager) ContentSpecNode(*tmp);
}
XMLContentModel* ComplexTypeInfo::makeContentModel(bool checkUPA)
{
    ContentSpecNode* aSpecNode = new (fMemoryManager) ContentSpecNode(*fContentSpec);

    if (checkUPA) {
        fContentSpecOrgURI = (unsigned int*) fMemoryManager->allocate
        (
            fContentSpecOrgURISize * sizeof(unsigned int)
        ); //new unsigned int[fContentSpecOrgURISize];
    }

    aSpecNode = convertContentSpecTree(aSpecNode, checkUPA, useRepeatingLeafNodes(aSpecNode));

    Janitor<ContentSpecNode> janSpecNode(aSpecNode);

    XMLContentModel* cmRet = 0;
    if (fContentType == SchemaElementDecl::Simple ||
        fContentType == SchemaElementDecl::ElementOnlyEmpty) {
       // just return nothing
    }
    else if (fContentType == SchemaElementDecl::Mixed_Simple)
    {
        //
        //  Just create a mixel content model object. This type of
        //  content model is optimized for mixed content validation.
        //
        cmRet = new (fMemoryManager) MixedContentModel(false, aSpecNode, false, fMemoryManager);
    }
    else if (fContentType == SchemaElementDecl::Mixed_Complex ||
             fContentType == SchemaElementDecl::Children)
    {
        bool isMixed = (fContentType == SchemaElementDecl::Mixed_Complex);

        //
        //  This method will create an optimal model for the complexity
        //  of the element's defined model. If its simple, it will create
        //  a SimpleContentModel object. If its a simple list, it will
        //  create a SimpleListContentModel object. If its complex, it
        //  will create a DFAContentModel object.
        //
        if(!aSpecNode)
            ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);

        ContentSpecNode::NodeTypes specType = aSpecNode->getType();
        //
        //  Do a sanity check that the node is does not have a PCDATA id. Since,
        //  if it was, it should have already gotten taken by the Mixed model.
        //
        if (aSpecNode->getElement() && aSpecNode->getElement()->getURI() == XMLElementDecl::fgPCDataElemId)
            ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_NoPCDATAHere, fMemoryManager);

        //
        //  According to the type of node, we will create the correct type of
        //  content model.
        //
        if (((specType & 0x0f) == ContentSpecNode::Any) ||
           ((specType & 0x0f) == ContentSpecNode::Any_Other) ||
           ((specType & 0x0f) == ContentSpecNode::Any_NS) ||
           specType == ContentSpecNode::Loop) {
           // let fall through to build a DFAContentModel
        }
        else if (isMixed)
        {
            if (specType == ContentSpecNode::All) {
                // All the nodes under an ALL must be additional ALL nodes and
                // ELEMENTs (or ELEMENTs under ZERO_OR_ONE nodes.)
                // We collapse the ELEMENTs into a single vector.
                cmRet = new (fMemoryManager) AllContentModel(aSpecNode, true, fMemoryManager);
            }
            else if (specType == ContentSpecNode::ZeroOrOne) {
                // An ALL node can appear under a ZERO_OR_ONE node.
                if (aSpecNode->getFirst()->getType() == ContentSpecNode::All) {
                    cmRet = new (fMemoryManager) AllContentModel(aSpecNode->getFirst(), true, fMemoryManager);
                }
            }

            // otherwise, let fall through to build a DFAContentModel
        }
         else if (specType == ContentSpecNode::Leaf)
        {
            // Create a simple content model
            cmRet = new (fMemoryManager) SimpleContentModel
            (
                false
                , aSpecNode->getElement()
                , 0
                , ContentSpecNode::Leaf
                , fMemoryManager
            );
        }
         else if (((specType & 0x0f) == ContentSpecNode::Choice)
              ||  ((specType & 0x0f) == ContentSpecNode::Sequence))
        {
            //
            //  Lets see if both of the children are leafs. If so, then it has to
            //  be a simple content model
            //
            if ((aSpecNode->getFirst()->getType() == ContentSpecNode::Leaf)
            &&  (aSpecNode->getSecond())
            &&  (aSpecNode->getSecond()->getType() == ContentSpecNode::Leaf))
            {
                cmRet = new (fMemoryManager) SimpleContentModel
                (
                    false
                    , aSpecNode->getFirst()->getElement()
                    , aSpecNode->getSecond()->getElement()
                    , specType
                    , fMemoryManager
                );
            }
        }
         else if ((specType == ContentSpecNode::OneOrMore)
              ||  (specType == ContentSpecNode::ZeroOrMore)
              ||  (specType == ContentSpecNode::ZeroOrOne))
        {
            //
            //  Its a repetition, so see if its one child is a leaf. If so its a
            //  repetition of a single element, so we can do a simple content
            //  model for that.
            //
            if (aSpecNode->getFirst()->getType() == ContentSpecNode::Leaf)
            {
                cmRet = new (fMemoryManager) SimpleContentModel
                (
                    false
                    , aSpecNode->getFirst()->getElement()
                    , 0
                    , specType
                    , fMemoryManager
                );
            }
            else if (aSpecNode->getFirst()->getType() == ContentSpecNode::All)
                cmRet = new (fMemoryManager) AllContentModel(aSpecNode->getFirst(), false, fMemoryManager);

        }
        else if (specType == ContentSpecNode::All)
            cmRet = new (fMemoryManager) AllContentModel(aSpecNode, false, fMemoryManager);
        else
        {
            ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);
        }

        // Its not any simple type of content, so create a DFA based content model
        if(cmRet==0)
            cmRet = new (fMemoryManager) DFAContentModel(false, aSpecNode, isMixed, fMemoryManager);
    }
     else
    {
        ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_MustBeMixedOrChildren, fMemoryManager);
    }

    return cmRet;
}
Exemple #3
0
XMLContentModel* DTDElementDecl::createChildModel()
{
    // Get the content spec node of the element
    ContentSpecNode* specNode = getContentSpec();

    if(!specNode)
        ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, getMemoryManager());

    //
    //  Do a sanity check that the node does not have a PCDATA id. Since,
    //  if it was, it should have already gotten taken by the Mixed model.
    //
    if (specNode->getElement()) {
        if (specNode->getElement()->getURI() == XMLElementDecl::fgPCDataElemId)
            ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_NoPCDATAHere, getMemoryManager());
    }

    //
    //  According to the type of node, we will create the correct type of
    //  content model.
    //
    if (specNode->getType() == ContentSpecNode::Leaf)
    {
        // Create a simple content model
        return new (getMemoryManager()) SimpleContentModel
        (
            true
            , specNode->getElement()
            , 0
            , ContentSpecNode::Leaf
            , getMemoryManager()
        );
    }
     else if ((specNode->getType() == ContentSpecNode::Choice)
          ||  (specNode->getType() == ContentSpecNode::Sequence))
    {
        //
        //  Lets see if both of the children are leafs. If so, then it has to
        //  be a simple content model
        //
        if ((specNode->getFirst()->getType() == ContentSpecNode::Leaf)
        &&  (specNode->getSecond()->getType() == ContentSpecNode::Leaf))
        {
            return new (getMemoryManager()) SimpleContentModel
            (
                true
                , specNode->getFirst()->getElement()
                , specNode->getSecond()->getElement()
                , specNode->getType()
                , getMemoryManager()
            );
        }
    }
     else if ((specNode->getType() == ContentSpecNode::OneOrMore)
          ||  (specNode->getType() == ContentSpecNode::ZeroOrMore)
          ||  (specNode->getType() == ContentSpecNode::ZeroOrOne))
    {
        //
        //  Its a repetition, so see if its one child is a leaf. If so its a
        //  repetition of a single element, so we can do a simple content
        //  model for that.
        //
        if (specNode->getFirst()->getType() == ContentSpecNode::Leaf)
        {
            return new (getMemoryManager()) SimpleContentModel
            (
                true
                , specNode->getFirst()->getElement()
                , 0
                , specNode->getType()
                , getMemoryManager()
            );
        }
    }
     else
    {
        ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, getMemoryManager());
    }

    // Its not any simple type of content, so create a DFA based content model
    return new (getMemoryManager()) DFAContentModel
    (
        true
        , this->getContentSpec()
        , getMemoryManager()
    );
}