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);
}
Exemple #2
0
XERCES_CPP_NAMESPACE_BEGIN

// ---------------------------------------------------------------------------
//  AllContentModel: Constructors and Destructor
// ---------------------------------------------------------------------------
AllContentModel::AllContentModel( ContentSpecNode* const parentContentSpec
                                , const bool             isMixed
                                , MemoryManager* const   manager) :
   fMemoryManager(manager)
 , fCount(0)
 , fChildren(0)
 , fChildOptional(0)
 , fNumRequired(0)
 , fIsMixed(isMixed)
 , fHasOptionalContent(false)
{
    //
    //  Create a vector of unsigned ints that will be filled in with the
    //  ids of the child nodes. It will be expanded as needed but we give
    //  it an initial capacity of 64 which should be more than enough for
    //  99% of the scenarios.
    //

    ValueVectorOf<QName*> children(64, fMemoryManager);
    ValueVectorOf<bool> childOptional(64, fMemoryManager);

    //
    //  Get the parent element's content spec. This is the head of the tree
    //  of nodes that describes the content model. We will iterate this
    //  tree.
    //
    ContentSpecNode* curNode = parentContentSpec;
    if (!curNode)
        ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_NoParentCSN, fMemoryManager);

    // And now call the private recursive method that iterates the tree
    if (curNode->getType() == ContentSpecNode::All
        && curNode->getMinOccurs() == 0) {
        fHasOptionalContent = true;
    }
    buildChildList(curNode, children, childOptional);

    //
    //  And now we know how many elements we need in our member list. So
    //  fill them in.
    //
    fCount = children.size();
    fChildren = (QName**) fMemoryManager->allocate(fCount * sizeof(QName*)); //new QName*[fCount];
    fChildOptional = (bool*) fMemoryManager->allocate(fCount * sizeof(bool)); //new bool[fCount];
    for (unsigned int index = 0; index < fCount; index++) {
        fChildren[index] = new (fMemoryManager) QName(*(children.elementAt(index)));
        fChildOptional[index] = childOptional.elementAt(index);
    }
}
void XMLInitializer::initializeComplexTypeInfo()
{
  // create type name
  XMLCh typeName[128];
  XMLSize_t nsLen = XMLString::stringLen(SchemaSymbols::fgURI_SCHEMAFORSCHEMA);

  XMLString::copyString(typeName, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
  typeName[nsLen] = chComma;
  XMLString::copyString(typeName + nsLen + 1, SchemaSymbols::fgATTVAL_ANYTYPE);

  // Create and initialize 'anyType'
  ComplexTypeInfo::fAnyType = new ComplexTypeInfo();

  ContentSpecNode* term = new ContentSpecNode
    (
      new QName
      (
        XMLUni::fgZeroLenString
        , XMLUni::fgZeroLenString
        , 1
      )
      , false
    );
  term->setType(ContentSpecNode::Any_Lax);
  term->setMinOccurs(0);
  term->setMaxOccurs(SchemaSymbols::XSD_UNBOUNDED);

  ContentSpecNode* particle = new ContentSpecNode
    (
      ContentSpecNode::ModelGroupSequence
      , term
      , 0
    );

  SchemaAttDef* attWildCard = new SchemaAttDef
    (
      XMLUni::fgZeroLenString
      , XMLUni::fgZeroLenString
      , 1
      , XMLAttDef::Any_Any
      , XMLAttDef::ProcessContents_Lax
    );

  ComplexTypeInfo::fAnyType->setTypeName(typeName);
  ComplexTypeInfo::fAnyType->setBaseComplexTypeInfo(ComplexTypeInfo::fAnyType);
  ComplexTypeInfo::fAnyType->setDerivedBy(SchemaSymbols::XSD_RESTRICTION);
  ComplexTypeInfo::fAnyType->setContentType(SchemaElementDecl::Mixed_Complex);
  ComplexTypeInfo::fAnyType->setContentSpec(particle);
  ComplexTypeInfo::fAnyType->setAttWildCard(attWildCard);
}
Exemple #4
0
// ---------------------------------------------------------------------------
//  AllContentModel: Private helper methods
// ---------------------------------------------------------------------------
void
AllContentModel::buildChildList(ContentSpecNode* const       curNode
                              , ValueVectorOf<QName*>&       toFill
                              , ValueVectorOf<bool>&         toOptional)
{
    // Get the type of spec node our current node is
    const ContentSpecNode::NodeTypes curType = curNode->getType();

    if (curType == ContentSpecNode::All)
    {
        // Get both the child node pointers
        ContentSpecNode* leftNode = curNode->getFirst();
        ContentSpecNode* rightNode = curNode->getSecond();

        // Recurse on the left and right nodes
        buildChildList(leftNode, toFill, toOptional);
        buildChildList(rightNode, toFill, toOptional);
    }
    else if (curType == ContentSpecNode::Leaf)
    {
        // At leaf, add the element to list of elements permitted in the all
        toFill.addElement(curNode->getElement());
        toOptional.addElement(false);
        fNumRequired++;
    }
    else if (curType == ContentSpecNode::ZeroOrOne)
    {
        // At ZERO_OR_ONE node, subtree must be an element
        // that was specified with minOccurs=0, maxOccurs=1
        ContentSpecNode* leftNode = curNode->getFirst();
        if (leftNode->getType() != ContentSpecNode::Leaf)
            ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);

        toFill.addElement(leftNode->getElement());
        toOptional.addElement(true);
    }
    else
        ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);
}
ContentSpecNode* ComplexTypeInfo::expandContentModel(ContentSpecNode* const specNode,
                                                     int minOccurs,
                                                     int maxOccurs,
                                                     bool bAllowCompactSyntax)
{
    if (!specNode) {
        return 0;
    }

    ContentSpecNode* saveNode = specNode;
    ContentSpecNode* retNode = specNode;

    if (minOccurs == 1 && maxOccurs == 1) {
    }
    else if (minOccurs == 0 && maxOccurs == 1) {

        retNode = new (fMemoryManager) ContentSpecNode
        (
            ContentSpecNode::ZeroOrOne
            , retNode
            , 0
            , true
            , true
            , fMemoryManager
        );
    }
    else if (minOccurs == 0 && maxOccurs == -1) {
        retNode = new (fMemoryManager) ContentSpecNode
        (
            ContentSpecNode::ZeroOrMore
            , retNode
            , 0
            , true
            , true
            , fMemoryManager
        );
    }
    else if (minOccurs == 1 && maxOccurs == -1) {
        retNode = new (fMemoryManager) ContentSpecNode
        (
            ContentSpecNode::OneOrMore
            , retNode
            , 0
            , true
            , true
            , fMemoryManager
        );
    }
    // if what is being repeated is a leaf avoid expanding the tree
    else if(bAllowCompactSyntax &&
        (saveNode->getType()==ContentSpecNode::Leaf ||
        (saveNode->getType() & 0x0f)==ContentSpecNode::Any ||
        (saveNode->getType() & 0x0f)==ContentSpecNode::Any_Other ||
        (saveNode->getType() & 0x0f)==ContentSpecNode::Any_NS))
    {
        retNode = new (fMemoryManager) ContentSpecNode
        (
            ContentSpecNode::Loop
            , retNode
            , 0
            , true
            , true
            , fMemoryManager
        );
        retNode->setMinOccurs(minOccurs);
        retNode->setMaxOccurs(maxOccurs);

        if(minOccurs==0)
            retNode = new (fMemoryManager) ContentSpecNode
            (
                ContentSpecNode::ZeroOrMore
                , retNode
                , 0
                , true
                , true
                , fMemoryManager
            );
        else
            retNode = new (fMemoryManager) ContentSpecNode
            (
                ContentSpecNode::OneOrMore
                , retNode
                , 0
                , true
                , true
                , fMemoryManager
            );

    }
    else if (maxOccurs == -1) {

        retNode = new (fMemoryManager) ContentSpecNode
        (
            ContentSpecNode::OneOrMore
            , retNode
            , 0
            , true
            , true
            , fMemoryManager
        );

        for (int i=0; i < (minOccurs-1); i++) {
            retNode = new (fMemoryManager) ContentSpecNode
            (
                ContentSpecNode::Sequence
                , saveNode
                , retNode
                , false
                , true
                , fMemoryManager
            );
        }
    }
    else {

        if (minOccurs == 0) {

            ContentSpecNode* optional = new (fMemoryManager) ContentSpecNode
            (
                ContentSpecNode::ZeroOrOne
                , saveNode
                , 0
                , true
                , true
                , fMemoryManager
            );

            retNode = optional;

            for (int i=0; i < (maxOccurs-1); i++) {
                retNode = new (fMemoryManager) ContentSpecNode
                (
                    ContentSpecNode::Sequence
                    , retNode
                    , optional
                    , true
                    , false
                    , fMemoryManager
                );
            }
        }
        else {

            if (minOccurs > 1) {

                retNode = new (fMemoryManager) ContentSpecNode
                (
                    ContentSpecNode::Sequence
                    , retNode
                    , saveNode
                    , true
                    , false
                    , fMemoryManager
                );

                for (int i=1; i < (minOccurs-1); i++) {
                    retNode = new (fMemoryManager) ContentSpecNode
                    (
                        ContentSpecNode::Sequence
                        , retNode
                        , saveNode
                        , true
                        , false
                        , fMemoryManager
                    );
                }
            }

            int counter = maxOccurs-minOccurs;

            if (counter > 0) {

                ContentSpecNode* optional = new (fMemoryManager) ContentSpecNode
                (
                    ContentSpecNode::ZeroOrOne
                    , saveNode
                    , 0
                    , false
                    , true
                    , fMemoryManager
                );

                retNode = new (fMemoryManager) ContentSpecNode
                (
                    ContentSpecNode::Sequence
                    , retNode
                    , optional
                    , true
                    , true
                    , fMemoryManager
                );

                for (int j=1; j < counter; j++) {

                    retNode = new (fMemoryManager) ContentSpecNode
                    (
                        ContentSpecNode::Sequence
                        , retNode
                        , optional
                        , true
                        , false
                        , fMemoryManager
                    );
                }
            }
        }
    }

    return retNode;
}
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 #7
0
ComplexTypeInfo* ComplexTypeInfo::getAnyType(unsigned int emptyNSId)
{
    if (!sAnyTypeMutexRegistered)
    {
        if (!sAnyTypeMutex)
        {
            XMLMutexLock lock(XMLPlatformUtils::fgAtomicMutex);
            if (!sAnyTypeMutex)
                sAnyTypeMutex = new XMLMutex;
        }

        // Use a faux scope to synchronize while we do this
        {
            XMLMutexLock lock(sAnyTypeMutex);

            // If we got here first, then register it and set the registered flag
            if (!sAnyTypeMutexRegistered)
            {
                // create type name
                XMLCh typeName[128];
                unsigned int nsLen = XMLString::stringLen(
                                         SchemaSymbols::fgURI_SCHEMAFORSCHEMA);

                XMLString::copyString(
                    typeName, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                typeName[nsLen] = chComma;
                XMLString::copyString(
                    typeName + nsLen + 1, SchemaSymbols::fgATTVAL_ANYTYPE);

                // Create and initialize 'anyType'
                fAnyType = new ComplexTypeInfo();

                ContentSpecNode* term = new ContentSpecNode
                (
                    new QName
                    (
                        XMLUni::fgZeroLenString
                        , XMLUni::fgZeroLenString
                        , emptyNSId
                    )
                    , false
                );
                term->setType(ContentSpecNode::Any_Lax);
                term->setMinOccurs(0);
                term->setMaxOccurs(SchemaSymbols::XSD_UNBOUNDED);

                ContentSpecNode* particle = new ContentSpecNode
                (
                    ContentSpecNode::ModelGroupSequence
                    , term
                    , 0
                );

                SchemaAttDef* attWildCard = new SchemaAttDef
                (
                    XMLUni::fgZeroLenString
                    , XMLUni::fgZeroLenString
                    , emptyNSId
                    , XMLAttDef::Any_Any
                    , XMLAttDef::ProcessContents_Lax
                );

                fAnyType->setTypeName(typeName);
                fAnyType->setBaseComplexTypeInfo(fAnyType);
                fAnyType->setDerivedBy(SchemaSymbols::XSD_RESTRICTION);
                fAnyType->setContentType(SchemaElementDecl::Mixed_Complex);
                fAnyType->setContentSpec(particle);
                fAnyType->setAttWildCard(attWildCard);

                // register cleanup method
                anyTypeCleanup.registerCleanup(ComplexTypeInfo::reinitAnyType);
                sAnyTypeMutexRegistered = true;
            }
        }
    }

    return fAnyType;
}
Exemple #8
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()
    );
}