void XSObjectFactory::processFacets()

in src/xercesc/internal/XSObjectFactory.cpp [824:1015]


void XSObjectFactory::processFacets(DatatypeValidator* const dv,
                                    XSModel* const xsModel,
                                    XSSimpleTypeDefinition* const xsST)
{
    // NOTE: XSMultiValueFacetList is not owned by XSModel!
    // NOTE: XSFacetList is not owned by XSModel!
    bool isFixed = false;
    int dvFacetsDefined = dv->getFacetsDefined();
    int dvFixedFacets = dv->getFixed();
    int definedFacets = 0;
    int fixedFacets = 0;
    XSMultiValueFacetList* xsMultiFacetList = 0;
    StringList* patternList = 0;
    XSFacetList* xsFacetList = new (fMemoryManager) RefVectorOf<XSFacet>(4, false, fMemoryManager);

    if (isMultiValueFacetDefined(dv))
        xsMultiFacetList = new (fMemoryManager) RefVectorOf<XSMultiValueFacet>(2, false, fMemoryManager);

    if (dvFacetsDefined & DatatypeValidator::FACET_ENUMERATION)
    {
        RefArrayVectorOf<XMLCh>* enumList = (RefArrayVectorOf<XMLCh>*) dv->getEnumString();

        if (dvFixedFacets & DatatypeValidator::FACET_ENUMERATION)
        {
            isFixed = true;
            fixedFacets |= XSSimpleTypeDefinition::FACET_ENUMERATION;
        }

        XSMultiValueFacet* mvFacet = new (fMemoryManager) XSMultiValueFacet(
            XSSimpleTypeDefinition::FACET_ENUMERATION , enumList, isFixed
            , getAnnotationFromModel(xsModel, enumList), xsModel, fMemoryManager
        );

        fDeleteVector->addElement(mvFacet);
        xsMultiFacetList->addElement(mvFacet);
        definedFacets |= XSSimpleTypeDefinition::FACET_ENUMERATION;
    }

    if (dv->getFacets())
    {
        RefHashTableOfEnumerator<KVStringPair> e(dv->getFacets(), false, fMemoryManager);
        while (e.hasMoreElements())
        {
            KVStringPair& pair = e.nextElement();
            XMLCh* key = pair.getKey();
            XSSimpleTypeDefinition::FACET facetType;
            XSAnnotation* annot = getAnnotationFromModel(xsModel, &pair);

            if (XMLString::equals(key, SchemaSymbols::fgELT_MAXINCLUSIVE))
            {
                facetType = XSSimpleTypeDefinition::FACET_MAXINCLUSIVE;
                isFixed = ((dvFixedFacets & DatatypeValidator::FACET_MAXINCLUSIVE) != 0);
            }
            else if (XMLString::equals(key, SchemaSymbols::fgELT_MAXEXCLUSIVE))
            {
                facetType = XSSimpleTypeDefinition::FACET_MAXEXCLUSIVE;
                isFixed = ((dvFixedFacets & DatatypeValidator::FACET_MAXEXCLUSIVE) !=0);
            }
            else if (XMLString::equals(key, SchemaSymbols::fgELT_MININCLUSIVE))
            {
                facetType = XSSimpleTypeDefinition::FACET_MININCLUSIVE;
                isFixed = ((dvFixedFacets & DatatypeValidator::FACET_MININCLUSIVE) !=0);
            }
            else if (XMLString::equals(key, SchemaSymbols::fgELT_MINEXCLUSIVE))
            {
                facetType = XSSimpleTypeDefinition::FACET_MINEXCLUSIVE;
                isFixed = ((dvFixedFacets & DatatypeValidator::FACET_MINEXCLUSIVE) != 0);
            }
            else if (XMLString::equals(key, SchemaSymbols::fgELT_LENGTH))
            {
                facetType = XSSimpleTypeDefinition::FACET_LENGTH;
                isFixed = ((dvFixedFacets & DatatypeValidator::FACET_LENGTH) != 0);
            }
            else if (XMLString::equals(key, SchemaSymbols::fgELT_MINLENGTH))
            {
                facetType = XSSimpleTypeDefinition::FACET_MINLENGTH;
                isFixed = ((dvFixedFacets & DatatypeValidator::FACET_MINLENGTH) != 0);
            }
            else if (XMLString::equals(key, SchemaSymbols::fgELT_MAXLENGTH))
            {
                facetType = XSSimpleTypeDefinition::FACET_MAXLENGTH;
                isFixed = ((dvFixedFacets & DatatypeValidator::FACET_MAXLENGTH) != 0);
            }
            else if (XMLString::equals(key, SchemaSymbols::fgELT_TOTALDIGITS))
            {
                facetType = XSSimpleTypeDefinition::FACET_TOTALDIGITS;
                isFixed = ((dvFixedFacets & DatatypeValidator::FACET_TOTALDIGITS) != 0);
            }
            else if (XMLString::equals(key, SchemaSymbols::fgELT_FRACTIONDIGITS))
            {
                facetType = XSSimpleTypeDefinition::FACET_FRACTIONDIGITS;
                isFixed = ((dvFixedFacets & DatatypeValidator::FACET_FRACTIONDIGITS) != 0);
            }
            else if (XMLString::equals(key, SchemaSymbols::fgELT_WHITESPACE))
            {
                facetType = XSSimpleTypeDefinition::FACET_WHITESPACE;
                isFixed = ((dvFixedFacets & DatatypeValidator::FACET_WHITESPACE) != 0);
            }
            else if (XMLString::equals(key, SchemaSymbols::fgELT_PATTERN) && xsMultiFacetList)
            {
                XMLStringTokenizer tokenizer(dv->getPattern(), regexSeparator, fMemoryManager);
                patternList = new (fMemoryManager) RefArrayVectorOf<XMLCh>(
                    tokenizer.countTokens(), true, fMemoryManager
                );

                while (tokenizer.hasMoreTokens())
                    patternList->addElement(XMLString::replicate(tokenizer.nextToken(), fMemoryManager));

                if (dvFixedFacets & DatatypeValidator::FACET_PATTERN)
                {
                    isFixed = true;
                    fixedFacets |= XSSimpleTypeDefinition::FACET_PATTERN;
                }

                XSMultiValueFacet* mvFacet = new (fMemoryManager) XSMultiValueFacet(
                    XSSimpleTypeDefinition::FACET_PATTERN, patternList
                    , isFixed, annot, xsModel, fMemoryManager
                );
                fDeleteVector->addElement(mvFacet);
                xsMultiFacetList->addElement(mvFacet);
                definedFacets |= XSSimpleTypeDefinition::FACET_PATTERN;
                continue;
            }
            else
            {
                // REVISIT: hmm... what about XSSimpleTypeDefinition::FACET_NONE
                // don't think I need to create an empty Facet?
                continue;
            }

            XSFacet* xsFacet = new (fMemoryManager) XSFacet(
                facetType, pair.getValue(), isFixed, annot, xsModel, fMemoryManager);

            fDeleteVector->addElement(xsFacet);
            xsFacetList->addElement(xsFacet);
            definedFacets |= facetType;
            if (isFixed)
                fixedFacets |= facetType;
        }
    }

    // add whistespace facet if missing
    if ((definedFacets & XSSimpleTypeDefinition::FACET_WHITESPACE) == 0)
    {
        XSFacet* xsFacet = new (fMemoryManager) XSFacet(
            XSSimpleTypeDefinition::FACET_WHITESPACE
            , dv->getWSstring(dv->getWSFacet())
            , false, 0, xsModel, fMemoryManager);

        fDeleteVector->addElement(xsFacet);
        xsFacetList->addElement(xsFacet);
        definedFacets |= XSSimpleTypeDefinition::FACET_WHITESPACE;
    }

    // inherit facets from base

    if (xsST->getBaseType() && xsST->getBaseType()->getTypeCategory() == XSTypeDefinition::SIMPLE_TYPE)
    {
        XSSimpleTypeDefinition* baseST = (XSSimpleTypeDefinition*) xsST->getBaseType();
        XSFacetList* baseFacets = baseST->getFacets();

        for (unsigned int i=0; i<baseFacets->size(); i++)
        {
            XSFacet* bFacet = baseFacets->elementAt(i);
            if ((definedFacets & bFacet->getFacetKind()) == 0)
            {
                definedFacets |= bFacet->getFacetKind();
                xsFacetList->addElement(bFacet);
                if (bFacet->isFixed())
                    fixedFacets |= bFacet->getFacetKind();
            }
        }

        if (baseST->getMultiValueFacets() && xsMultiFacetList)
        {
            XSMultiValueFacetList* baseMVFacets = baseST->getMultiValueFacets();
            for (unsigned int j=0; j<baseMVFacets->size(); j++)
            {
                XSMultiValueFacet* bFacet = baseMVFacets->elementAt(j);
                if ((definedFacets & bFacet->getFacetKind()) == 0)
                {
                    definedFacets |= bFacet->getFacetKind();
                    xsMultiFacetList->addElement(bFacet);
                    if (bFacet->isFixed())
                        fixedFacets |= bFacet->getFacetKind();
                }
            }
        }
    }

    xsST->setFacetInfo(definedFacets, fixedFacets, xsFacetList, xsMultiFacetList, patternList);
}