/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * $Id: DatatypeValidatorFactory.cpp 568078 2007-08-21 11:43:25Z amassari $
 */


// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/validators/datatype/DatatypeValidatorFactory.hpp>
#include <xercesc/validators/schema/SchemaSymbols.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/util/Janitor.hpp>
#include <xercesc/validators/datatype/StringDatatypeValidator.hpp>
#include <xercesc/validators/datatype/BooleanDatatypeValidator.hpp>
#include <xercesc/validators/datatype/DecimalDatatypeValidator.hpp>
#include <xercesc/validators/datatype/HexBinaryDatatypeValidator.hpp>
#include <xercesc/validators/datatype/Base64BinaryDatatypeValidator.hpp>
#include <xercesc/validators/datatype/IDDatatypeValidator.hpp>
#include <xercesc/validators/datatype/IDREFDatatypeValidator.hpp>
#include <xercesc/validators/datatype/NOTATIONDatatypeValidator.hpp>
#include <xercesc/validators/datatype/ENTITYDatatypeValidator.hpp>
#include <xercesc/validators/datatype/QNameDatatypeValidator.hpp>
#include <xercesc/validators/datatype/NameDatatypeValidator.hpp>
#include <xercesc/validators/datatype/NCNameDatatypeValidator.hpp>
#include <xercesc/validators/datatype/ListDatatypeValidator.hpp>
#include <xercesc/validators/datatype/UnionDatatypeValidator.hpp>
#include <xercesc/validators/datatype/DoubleDatatypeValidator.hpp>
#include <xercesc/validators/datatype/FloatDatatypeValidator.hpp>
#include <xercesc/validators/datatype/AnyURIDatatypeValidator.hpp>
#include <xercesc/validators/datatype/AnySimpleTypeDatatypeValidator.hpp>
#include <xercesc/validators/datatype/DateTimeDatatypeValidator.hpp>
#include <xercesc/validators/datatype/DateDatatypeValidator.hpp>
#include <xercesc/validators/datatype/TimeDatatypeValidator.hpp>
#include <xercesc/validators/datatype/DayDatatypeValidator.hpp>
#include <xercesc/validators/datatype/MonthDatatypeValidator.hpp>
#include <xercesc/validators/datatype/MonthDayDatatypeValidator.hpp>
#include <xercesc/validators/datatype/YearDatatypeValidator.hpp>
#include <xercesc/validators/datatype/YearMonthDatatypeValidator.hpp>
#include <xercesc/validators/datatype/DurationDatatypeValidator.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLRegisterCleanup.hpp>
#include <xercesc/util/XMLInitializer.hpp>

#include <xercesc/internal/XTemplateSerializer.hpp>
#include <xercesc/util/HashPtr.hpp>

XERCES_CPP_NAMESPACE_BEGIN


// ---------------------------------------------------------------------------
//  DatatypeValidatorFactory: Local const data
// ---------------------------------------------------------------------------
const XMLCh fgTokPattern[] =
{
    chBackSlash, chLatin_c, chPlus, chNull
};

//E2-43
//[+\-]?[0-9]+
const XMLCh fgIntegerPattern[] =
{
    chOpenSquare, chPlus, chBackSlash, chDash, chCloseSquare, chQuestion,
    chOpenSquare, chDigit_0, chDash, chDigit_9, chCloseSquare, chPlus, chNull
};

//"\\i\\c*"
const XMLCh fgNamePattern[] =
{
    chBackSlash, chLatin_i, chBackSlash, chLatin_c, chAsterisk, chNull
};

//"[\\i-[:]][\\c-[:]]*"
const XMLCh fgNCNamePattern[] =
{
    chOpenSquare, chBackSlash, chLatin_i, chDash, chOpenSquare, chColon, chCloseSquare,
    chCloseSquare, chOpenSquare, chBackSlash, chLatin_c, chDash, chOpenSquare,
    chColon, chCloseSquare, chCloseSquare, chAsterisk, chNull
};



const XMLCh fgP0Y[] =
{
    chLatin_P, chDigit_0, chLatin_Y, chNull
};

const XMLCh fgP1Y[] =
{
    chLatin_P, chDigit_1, chLatin_Y, chNull
};

const XMLCh fgP100Y[] =
{
    chLatin_P, chDigit_1, chDigit_0, chDigit_0, chLatin_Y, chNull
};

const XMLCh fgPT24H[] =
{
    chLatin_P, chLatin_T, chDigit_2, chDigit_4, chLatin_H, chNull
};

const XMLCh fgP1M[] =
{
    chLatin_P, chDigit_1, chLatin_M, chNull
};


// ---------------------------------------------------------------------------
//  Local static data
// ---------------------------------------------------------------------------
static bool               sBuiltInRegistryMutexRegistered = false;
static XMLMutex*          sBuiltInRegistryMutex = 0;
static XMLRegisterCleanup builtInRegistryCleanup;


// ---------------------------------------------------------------------------
//  DatatypeValidatorFactory: Static member data
// ---------------------------------------------------------------------------
RefHashTableOf<DatatypeValidator>* DatatypeValidatorFactory::fBuiltInRegistry = 0;
RefHashTableOf<XMLCanRepGroup>*    DatatypeValidatorFactory::fCanRepRegistry = 0;

// ---------------------------------------------------------------------------
//  DatatypeValidatorFactory: Constructors and Destructor
// ---------------------------------------------------------------------------
DatatypeValidatorFactory::DatatypeValidatorFactory(MemoryManager* const manager)
    : fUserDefinedRegistry(0)
    , fMemoryManager(manager)
{
}

DatatypeValidatorFactory::~DatatypeValidatorFactory()
{
	cleanUp();
}


// ---------------------------------------------------------------------------
//  DatatypeValidatorFactory: Reset methods
// ---------------------------------------------------------------------------
void DatatypeValidatorFactory::resetRegistry() {

    if (fUserDefinedRegistry != 0) {
        fUserDefinedRegistry->removeAll();
    }

}


// -----------------------------------------------------------------------
//  Notification that lazy data has been deleted
// -----------------------------------------------------------------------
void DatatypeValidatorFactory::reinitRegistry() {

    delete fBuiltInRegistry;
    fBuiltInRegistry = 0;

    delete fCanRepRegistry;
    fCanRepRegistry = 0;

    // delete local static data
    delete sBuiltInRegistryMutex;
    sBuiltInRegistryMutex = 0;
    sBuiltInRegistryMutexRegistered = false;
}

void XMLInitializer::initializeDVFactory()
{
    DatatypeValidatorFactory *dvFactory = new DatatypeValidatorFactory();
    if (dvFactory) {
        dvFactory->expandRegistryToFullSchemaSet();
        delete dvFactory;
    }
}

// ---------------------------------------------------------------------------
//  DatatypeValidatorFactory: Registry initialization methods
// ---------------------------------------------------------------------------
void DatatypeValidatorFactory::expandRegistryToFullSchemaSet()
{
    if (!sBuiltInRegistryMutexRegistered)
    {
        if (!sBuiltInRegistryMutex)
        {
            XMLMutexLock lock(XMLPlatformUtils::fgAtomicMutex);
            if (!sBuiltInRegistryMutex)
                sBuiltInRegistryMutex = new XMLMutex(XMLPlatformUtils::fgMemoryManager);
        }

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

            // If we got here first, then register it and set the registered flag
            if (!sBuiltInRegistryMutexRegistered)
            {
                //Initialize common Schema/DTD Datatype validator set
                fBuiltInRegistry = new RefHashTableOf<DatatypeValidator>(29);

                DatatypeValidator *dv = new StringDatatypeValidator(); 
                dv->setTypeName(SchemaSymbols::fgDT_STRING, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_STRING, dv);
            
                dv = new NOTATIONDatatypeValidator();
                dv->setTypeName(XMLUni::fgNotationString, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) XMLUni::fgNotationString, dv);

                dv = new AnySimpleTypeDatatypeValidator();
                dv->setTypeName(SchemaSymbols::fgDT_ANYSIMPLETYPE, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_ANYSIMPLETYPE, dv);

                dv = new BooleanDatatypeValidator();
                dv->setTypeName(SchemaSymbols::fgDT_BOOLEAN, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_BOOLEAN, dv);

                dv = new DecimalDatatypeValidator();
                dv->setTypeName(SchemaSymbols::fgDT_DECIMAL, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_DECIMAL, dv);

                dv = new HexBinaryDatatypeValidator();
                dv->setTypeName(SchemaSymbols::fgDT_HEXBINARY, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_HEXBINARY, dv);

                dv = new Base64BinaryDatatypeValidator();
                dv->setTypeName(SchemaSymbols::fgDT_BASE64BINARY, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_BASE64BINARY, dv);

                dv = new DoubleDatatypeValidator();
                dv->setTypeName(SchemaSymbols::fgDT_DOUBLE, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_DOUBLE, dv);

                dv = new FloatDatatypeValidator();
                dv->setTypeName(SchemaSymbols::fgDT_FLOAT, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_FLOAT, dv);

                dv = new AnyURIDatatypeValidator();
                dv->setTypeName(SchemaSymbols::fgDT_ANYURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_ANYURI, dv);

                dv = new QNameDatatypeValidator();
                dv->setTypeName(SchemaSymbols::fgDT_QNAME, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_QNAME, dv);

                dv = new DateTimeDatatypeValidator();
                dv->setTypeName(SchemaSymbols::fgDT_DATETIME, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_DATETIME, dv);

                dv = new DateDatatypeValidator();
                dv->setTypeName(SchemaSymbols::fgDT_DATE, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_DATE, dv);

                dv = new TimeDatatypeValidator();
                dv->setTypeName(SchemaSymbols::fgDT_TIME, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_TIME, dv);

                dv = new DayDatatypeValidator();
                dv->setTypeName(SchemaSymbols::fgDT_DAY, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_DAY, dv);

                dv = new MonthDatatypeValidator();
                dv->setTypeName(SchemaSymbols::fgDT_MONTH, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_MONTH, dv);

                dv = new MonthDayDatatypeValidator();
                dv->setTypeName(SchemaSymbols::fgDT_MONTHDAY, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_MONTHDAY, dv);

                dv = new YearDatatypeValidator();
                dv->setTypeName(SchemaSymbols::fgDT_YEAR, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_YEAR, dv);

                dv = new YearMonthDatatypeValidator();
                dv->setTypeName(SchemaSymbols::fgDT_YEARMONTH, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_YEARMONTH, dv);

                dv = new DurationDatatypeValidator();
                dv->setTypeName(SchemaSymbols::fgDT_DURATION, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_DURATION, dv);

                // REVISIT
                // We are creating a lot of Hashtables for the facets of the different
                // validators. It's better to have some kind of a memory pool and ask
                // the pool to give us a new instance of the hashtable.
                RefHashTableOf<KVStringPair>* facets = new RefHashTableOf<KVStringPair>(3);

                // Create 'normalizedString' datatype validator
                facets->put((void*) SchemaSymbols::fgELT_WHITESPACE,
                            new KVStringPair(SchemaSymbols::fgELT_WHITESPACE, SchemaSymbols::fgWS_REPLACE));

                createDatatypeValidator(SchemaSymbols::fgDT_NORMALIZEDSTRING,
                                        getDatatypeValidator(SchemaSymbols::fgDT_STRING),
                                        facets, 0, false, 0, false);

                // Create 'token' datatype validator
                facets = new RefHashTableOf<KVStringPair>(3);
                facets->put((void*) SchemaSymbols::fgELT_WHITESPACE,
                            new KVStringPair(SchemaSymbols::fgELT_WHITESPACE, SchemaSymbols::fgWS_COLLAPSE));

                createDatatypeValidator(SchemaSymbols::fgDT_TOKEN,
                              getDatatypeValidator(SchemaSymbols::fgDT_NORMALIZEDSTRING),
                              facets, 0, false, 0, false);


                dv = new NameDatatypeValidator(getDatatypeValidator(SchemaSymbols::fgDT_TOKEN), 0, 0, 0);
                dv->setTypeName(SchemaSymbols::fgDT_NAME, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_NAME, dv);


                dv = new NCNameDatatypeValidator(getDatatypeValidator(SchemaSymbols::fgDT_NAME), 0, 0, 0);
                dv->setTypeName(SchemaSymbols::fgDT_NCNAME, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_NCNAME, dv);

                // Create 'NMTOKEN' datatype validator
                facets = new RefHashTableOf<KVStringPair>(3);

                facets->put((void*) SchemaSymbols::fgELT_PATTERN ,
                                new KVStringPair(SchemaSymbols::fgELT_PATTERN,fgTokPattern));
                facets->put((void*) SchemaSymbols::fgELT_WHITESPACE,
                                new KVStringPair(SchemaSymbols::fgELT_WHITESPACE, SchemaSymbols::fgWS_COLLAPSE));

                createDatatypeValidator(XMLUni::fgNmTokenString,
                                getDatatypeValidator(SchemaSymbols::fgDT_TOKEN),facets, 0, false, 0, false);

                // Create 'NMTOKENS' datatype validator
                facets = new RefHashTableOf<KVStringPair>(2);
                facets->put((void*) SchemaSymbols::fgELT_MINLENGTH,
                            new KVStringPair(SchemaSymbols::fgELT_MINLENGTH, XMLUni::fgValueOne));

                createDatatypeValidator(XMLUni::fgNmTokensString,
        	                     getDatatypeValidator(XMLUni::fgNmTokenString), facets, 0, true, 0, false);

                // Create 'language' datatype validator
                facets = new RefHashTableOf<KVStringPair>(3);

                facets->put((void*) SchemaSymbols::fgELT_PATTERN,
                    new KVStringPair(SchemaSymbols::fgELT_PATTERN, XMLUni::fgLangPattern));

                createDatatypeValidator(SchemaSymbols::fgDT_LANGUAGE,
                              getDatatypeValidator(SchemaSymbols::fgDT_TOKEN),
                              facets, 0, false, 0, false);

                // Create 'integer' datatype validator
                facets = new RefHashTableOf<KVStringPair>(3);

                facets->put((void*) SchemaSymbols::fgELT_FRACTIONDIGITS,
                    new KVStringPair(SchemaSymbols::fgELT_FRACTIONDIGITS, XMLUni::fgValueZero));

                facets->put((void*) SchemaSymbols::fgELT_PATTERN,
                            new KVStringPair(SchemaSymbols::fgELT_PATTERN, fgIntegerPattern));

                createDatatypeValidator(SchemaSymbols::fgDT_INTEGER,
                              getDatatypeValidator(SchemaSymbols::fgDT_DECIMAL),
                              facets, 0, false, 0, false);

                // Create 'nonPositiveInteger' datatype validator
                facets = new RefHashTableOf<KVStringPair>(2);

                facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
                            new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, XMLUni::fgValueZero));

                createDatatypeValidator(SchemaSymbols::fgDT_NONPOSITIVEINTEGER,
                              getDatatypeValidator(SchemaSymbols::fgDT_INTEGER),
                              facets, 0, false, 0, false);

                // Create 'negativeInteger' datatype validator
                facets = new RefHashTableOf<KVStringPair>(2);

                facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
    			            new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, XMLUni::fgNegOne));

                createDatatypeValidator(SchemaSymbols::fgDT_NEGATIVEINTEGER,
                              getDatatypeValidator(SchemaSymbols::fgDT_NONPOSITIVEINTEGER),
                              facets, 0, false, 0, false);

                // Create 'long' datatype validator
                facets = new RefHashTableOf<KVStringPair>(2);

                facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
                            new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, XMLUni::fgLongMaxInc));
                facets->put((void*) SchemaSymbols::fgELT_MININCLUSIVE,
                            new KVStringPair(SchemaSymbols::fgELT_MININCLUSIVE, XMLUni::fgLongMinInc));

                createDatatypeValidator(SchemaSymbols::fgDT_LONG,
                              getDatatypeValidator(SchemaSymbols::fgDT_INTEGER),
                              facets, 0, false, 0, false);

                // Create 'int' datatype validator
                facets = new RefHashTableOf<KVStringPair>(2);

                facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
                            new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, XMLUni::fgIntMaxInc));
                facets->put((void*) SchemaSymbols::fgELT_MININCLUSIVE,
                            new KVStringPair(SchemaSymbols::fgELT_MININCLUSIVE, XMLUni::fgIntMinInc));

                createDatatypeValidator(SchemaSymbols::fgDT_INT,
                              getDatatypeValidator(SchemaSymbols::fgDT_LONG),
                              facets, 0, false, 0, false);

                // Create 'short' datatype validator
                facets = new RefHashTableOf<KVStringPair>(2);

                facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
                            new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, XMLUni::fgShortMaxInc));
                facets->put((void*) SchemaSymbols::fgELT_MININCLUSIVE,
                            new KVStringPair(SchemaSymbols::fgELT_MININCLUSIVE, XMLUni::fgShortMinInc));

                createDatatypeValidator(SchemaSymbols::fgDT_SHORT,
                              getDatatypeValidator(SchemaSymbols::fgDT_INT),
                              facets, 0, false, 0 ,false);

                // Create 'byte' datatype validator
                facets = new RefHashTableOf<KVStringPair>(2);

                facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
                            new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, XMLUni::fgByteMaxInc));
                facets->put((void*) SchemaSymbols::fgELT_MININCLUSIVE,
                            new KVStringPair(SchemaSymbols::fgELT_MININCLUSIVE, XMLUni::fgByteMinInc));

                createDatatypeValidator(SchemaSymbols::fgDT_BYTE,
                              getDatatypeValidator(SchemaSymbols::fgDT_SHORT),
                              facets, 0, false, 0, false);

                // Create 'nonNegativeInteger' datatype validator
                facets = new RefHashTableOf<KVStringPair>(2);

                facets->put((void*) SchemaSymbols::fgELT_MININCLUSIVE,
                            new KVStringPair(SchemaSymbols::fgELT_MININCLUSIVE, XMLUni::fgValueZero));

                createDatatypeValidator(SchemaSymbols::fgDT_NONNEGATIVEINTEGER,
                              getDatatypeValidator(SchemaSymbols::fgDT_INTEGER),
                              facets, 0, false, 0, false);

                // Create 'unsignedLong' datatype validator
                facets = new RefHashTableOf<KVStringPair>(2);

                facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
                            new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, XMLUni::fgULongMaxInc));

                createDatatypeValidator(SchemaSymbols::fgDT_ULONG,
                              getDatatypeValidator(SchemaSymbols::fgDT_NONNEGATIVEINTEGER),
                              facets, 0, false, 0, false);

                // Create 'unsignedInt' datatype validator
                facets = new RefHashTableOf<KVStringPair>(2);

                facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
                            new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, XMLUni::fgUIntMaxInc));

                createDatatypeValidator(SchemaSymbols::fgDT_UINT,
                              getDatatypeValidator(SchemaSymbols::fgDT_ULONG),
                              facets, 0, false, 0, false);

                // Create 'unsignedShort' datatypeValidator
                facets = new RefHashTableOf<KVStringPair>(2);

                facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
                            new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, XMLUni::fgUShortMaxInc));

                createDatatypeValidator(SchemaSymbols::fgDT_USHORT,
                              getDatatypeValidator(SchemaSymbols::fgDT_UINT),
                              facets, 0, false, 0, false);

                // Create 'unsignedByte' datatype validator
                facets = new RefHashTableOf<KVStringPair>(2);

                facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
                            new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, XMLUni::fgUByteMaxInc));

                createDatatypeValidator(SchemaSymbols::fgDT_UBYTE,
                              getDatatypeValidator(SchemaSymbols::fgDT_USHORT),
                              facets, 0, false, 0, false);

                // Create 'positiveInteger' datatype validator
                facets = new RefHashTableOf<KVStringPair>(2);

                facets->put((void*) SchemaSymbols::fgELT_MININCLUSIVE,
                            new KVStringPair(SchemaSymbols::fgELT_MININCLUSIVE, XMLUni::fgValueOne));

                createDatatypeValidator(SchemaSymbols::fgDT_POSITIVEINTEGER,
                              getDatatypeValidator(SchemaSymbols::fgDT_NONNEGATIVEINTEGER),
                              facets, 0, false, 0, false);

                // Create 'ID', 'IDREF' and 'ENTITY' datatype validator
                dv = new IDDatatypeValidator(getDatatypeValidator(SchemaSymbols::fgDT_NCNAME), 0, 0, 0);
                dv->setTypeName(XMLUni::fgIDString, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) XMLUni::fgIDString, dv);

                dv = new IDREFDatatypeValidator(getDatatypeValidator(SchemaSymbols::fgDT_NCNAME), 0, 0, 0);
                dv->setTypeName(XMLUni::fgIDRefString, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) XMLUni::fgIDRefString, dv);

                dv = new ENTITYDatatypeValidator(getDatatypeValidator(SchemaSymbols::fgDT_NCNAME), 0, 0, 0);
                dv->setTypeName(XMLUni::fgEntityString, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                fBuiltInRegistry->put((void*) XMLUni::fgEntityString, dv);

                facets = new RefHashTableOf<KVStringPair>(2);
                facets->put((void*) SchemaSymbols::fgELT_MINLENGTH,
                            new KVStringPair(SchemaSymbols::fgELT_MINLENGTH, XMLUni::fgValueOne));

                // Create 'IDREFS' datatype validator
                createDatatypeValidator
                (
                    XMLUni::fgIDRefsString
                  , getDatatypeValidator(XMLUni::fgIDRefString)
                  , facets
                  , 0
                  , true
                  , 0
                  , false
                );

                facets = new RefHashTableOf<KVStringPair>(2);

                facets->put((void*) SchemaSymbols::fgELT_MINLENGTH,
                            new KVStringPair(SchemaSymbols::fgELT_MINLENGTH, XMLUni::fgValueOne));

               // Create 'ENTITIES' datatype validator
               createDatatypeValidator
               (
                   XMLUni::fgEntitiesString
                 , getDatatypeValidator(XMLUni::fgEntityString)
                 , facets
                 , 0
                 , true
                 , 0
                 , false
               );

                initCanRepRegistory();

                // register cleanup method
                builtInRegistryCleanup.registerCleanup(DatatypeValidatorFactory::reinitRegistry);
                sBuiltInRegistryMutexRegistered = true;
            }
        }
    }
}

/***
 *
 *   For Decimal-derivated, an instance of DecimalDatatypeValidator
 *   can be used by the primitive datatype, decimal, or any one of 
 *   the derivated datatypes, such as int, long, unsighed short, just
 *   name a few, or any user-defined datatypes, which may derivate from
 *   either the primitive datatype, decimal, or from any one of those 
 *   decimal derivated datatypes, or other user-defined datatypes, which
 *   in turn, indirectly derivate from decimal or decimal-derived.
 *
 *   fCanRepRegisty captures deciaml dv and its derivatives.
 *
 ***/
void DatatypeValidatorFactory::initCanRepRegistory()
{

     /***
      * key:  dv
      * data: XMLCanRepGroup
      ***/
     fCanRepRegistry  = new RefHashTableOf<XMLCanRepGroup>(29, true, new HashPtr() );

     fCanRepRegistry->put((void*) getDatatypeValidator(SchemaSymbols::fgDT_DECIMAL),
                        new  XMLCanRepGroup(XMLCanRepGroup::Decimal));

     fCanRepRegistry->put((void*) getDatatypeValidator(SchemaSymbols::fgDT_INTEGER),
                        new  XMLCanRepGroup(XMLCanRepGroup::Decimal_Derivated_signed));
     fCanRepRegistry->put((void*) getDatatypeValidator(SchemaSymbols::fgDT_LONG),
                        new  XMLCanRepGroup(XMLCanRepGroup::Decimal_Derivated_signed));
     fCanRepRegistry->put((void*) getDatatypeValidator(SchemaSymbols::fgDT_INT),
                        new  XMLCanRepGroup(XMLCanRepGroup::Decimal_Derivated_signed));
     fCanRepRegistry->put((void*) getDatatypeValidator(SchemaSymbols::fgDT_SHORT),
                        new  XMLCanRepGroup(XMLCanRepGroup::Decimal_Derivated_signed));
     fCanRepRegistry->put((void*) getDatatypeValidator(SchemaSymbols::fgDT_BYTE),
                        new  XMLCanRepGroup(XMLCanRepGroup::Decimal_Derivated_signed));
     fCanRepRegistry->put((void*) getDatatypeValidator(SchemaSymbols::fgDT_NONNEGATIVEINTEGER),
                        new  XMLCanRepGroup(XMLCanRepGroup::Decimal_Derivated_signed));
     fCanRepRegistry->put((void*) getDatatypeValidator(SchemaSymbols::fgDT_POSITIVEINTEGER),
                        new  XMLCanRepGroup(XMLCanRepGroup::Decimal_Derivated_signed));

     fCanRepRegistry->put((void*) getDatatypeValidator(SchemaSymbols::fgDT_NEGATIVEINTEGER),
                        new  XMLCanRepGroup(XMLCanRepGroup::Decimal_Derivated_unsigned));
     fCanRepRegistry->put((void*) getDatatypeValidator(SchemaSymbols::fgDT_ULONG),
                        new  XMLCanRepGroup(XMLCanRepGroup::Decimal_Derivated_unsigned));
     fCanRepRegistry->put((void*) getDatatypeValidator(SchemaSymbols::fgDT_UINT),
                        new  XMLCanRepGroup(XMLCanRepGroup::Decimal_Derivated_unsigned));
     fCanRepRegistry->put((void*) getDatatypeValidator(SchemaSymbols::fgDT_USHORT),
                        new  XMLCanRepGroup(XMLCanRepGroup::Decimal_Derivated_unsigned));        
     fCanRepRegistry->put((void*) getDatatypeValidator(SchemaSymbols::fgDT_UBYTE),
                        new  XMLCanRepGroup(XMLCanRepGroup::Decimal_Derivated_unsigned));

     fCanRepRegistry->put((void*) getDatatypeValidator(SchemaSymbols::fgDT_NONPOSITIVEINTEGER),
                        new  XMLCanRepGroup(XMLCanRepGroup::Decimal_Derivated_npi));
}

/***
 *
 *   For any dv other than Decimaldv, return String only.
 *   Later on if support to dv other than Decimaldv arise, we may
 *   add them fCanRepRegistry during DatatypeValidatorFactory::initCanRepRegistory()
 *
 ***/
XMLCanRepGroup::CanRepGroup DatatypeValidatorFactory::getCanRepGroup(const DatatypeValidator* const dv)
{
    if (!dv)
        return XMLCanRepGroup::String;

    DatatypeValidator *curdv = (DatatypeValidator*) dv;

    while (curdv)
    {
        if (fCanRepRegistry->containsKey(curdv))
            return fCanRepRegistry->get(curdv)->getGroup();
        else
            curdv = curdv->getBaseValidator();
    }

    return XMLCanRepGroup::String;
}

DatatypeValidator* DatatypeValidatorFactory::getBuiltInBaseValidator(const DatatypeValidator* const dv)
{
    DatatypeValidator *curdv = (DatatypeValidator*)dv;

    while (curdv)
    {
        if (curdv == getBuiltInRegistry()->get(curdv->getTypeLocalName()))
            return curdv;
        else
            curdv = curdv->getBaseValidator();
     }

     return 0;
}

// ---------------------------------------------------------------------------
//  DatatypeValidatorFactory: factory methods
// ---------------------------------------------------------------------------
DatatypeValidator* DatatypeValidatorFactory::createDatatypeValidator
(
      const XMLCh* const                  typeName
	, DatatypeValidator* const            baseValidator
    , RefHashTableOf<KVStringPair>* const facets
    , RefArrayVectorOf<XMLCh>* const      enums
    , const bool                          isDerivedByList
    , const int                           finalSet
    , const bool                          isUserDefined
    , MemoryManager* const                userManager
)
{
	if (baseValidator == 0) {

        if (facets) {
            Janitor<KVStringPairHashTable> janFacets(facets);
        }

        if (enums) {
            Janitor<XMLChRefVector> janEnums(enums);
        }

        return 0;
    }

	DatatypeValidator* datatypeValidator = 0;
    MemoryManager* const manager = (isUserDefined)
        ? userManager : XMLPlatformUtils::fgMemoryManager;

    if (isDerivedByList) {
        datatypeValidator = new (manager) ListDatatypeValidator(baseValidator, facets, enums, finalSet, manager);

        // Set PSVI information for Ordered, Numeric, Bounded & Finite
        datatypeValidator->setOrdered(XSSimpleTypeDefinition::ORDERED_FALSE);
        datatypeValidator->setNumeric(false);
        if (facets &&
             ((facets->get(SchemaSymbols::fgELT_LENGTH) || 
              (facets->get(SchemaSymbols::fgELT_MINLENGTH) && facets->get(SchemaSymbols::fgELT_MAXLENGTH)))))
        {
            datatypeValidator->setBounded(true);
            datatypeValidator->setFinite(true);
        }
        else
        {
            datatypeValidator->setBounded(false);
            datatypeValidator->setFinite(false);
        }
    }
    else {

        if ((baseValidator->getType() != DatatypeValidator::String) && facets) {

            KVStringPair* value = facets->get(SchemaSymbols::fgELT_WHITESPACE);

            if (value != 0) {
                facets->removeKey(SchemaSymbols::fgELT_WHITESPACE);
            }
        }

        datatypeValidator = baseValidator->newInstance
        (
            facets
            , enums
            , finalSet
            , manager
        );

        // Set PSVI information for Ordered, Numeric, Bounded & Finite
        datatypeValidator->setOrdered(baseValidator->getOrdered());
        datatypeValidator->setNumeric(baseValidator->getNumeric());
        RefHashTableOf<KVStringPair>* baseFacets = baseValidator->getFacets();
        if (facets  && 
            ((facets->get(SchemaSymbols::fgELT_MININCLUSIVE) || 
              facets->get(SchemaSymbols::fgELT_MINEXCLUSIVE) ||
              (baseFacets && (baseFacets->get(SchemaSymbols::fgELT_MININCLUSIVE) || 
                              baseFacets->get(SchemaSymbols::fgELT_MINEXCLUSIVE))))) &&
             (facets->get(SchemaSymbols::fgELT_MAXINCLUSIVE) || 
              facets->get(SchemaSymbols::fgELT_MAXEXCLUSIVE) || 
              (baseFacets && ((baseFacets->get(SchemaSymbols::fgELT_MAXINCLUSIVE) || 
                               baseFacets->get(SchemaSymbols::fgELT_MAXEXCLUSIVE))))))
        {
            datatypeValidator->setBounded(true);
        }
        else
        {
            datatypeValidator->setBounded(false);
        }
        if (baseValidator->getFinite())
        {
            datatypeValidator->setFinite(true);
        }
        else if (!facets)
        {
            datatypeValidator->setFinite(false);
        }
        else if (facets->get(SchemaSymbols::fgELT_LENGTH) || facets->get(SchemaSymbols::fgELT_MAXLENGTH) ||
                 facets->get(SchemaSymbols::fgELT_TOTALDIGITS))
        {
            datatypeValidator->setFinite(true);
        }
        //for efficiency use this instead of rechecking...
        //else if ((facets->get(SchemaSymbols::fgELT_MININCLUSIVE) || facets->get(SchemaSymbols::fgELT_MINEXCLUSIVE)) &&
        //         (facets->get(SchemaSymbols::fgELT_MAXINCLUSIVE) || facets->get(SchemaSymbols::fgELT_MAXEXCLUSIVE)))
        else if (datatypeValidator->getBounded() ||
                 datatypeValidator->getType() == DatatypeValidator::Date      || 
                 datatypeValidator->getType() == DatatypeValidator::YearMonth ||
                 datatypeValidator->getType() == DatatypeValidator::Year      ||
                 datatypeValidator->getType() == DatatypeValidator::MonthDay  ||
                 datatypeValidator->getType() == DatatypeValidator::Day       ||
                 datatypeValidator->getType() == DatatypeValidator::Month)
        {
            if (facets->get(SchemaSymbols::fgELT_FRACTIONDIGITS))
            {
                datatypeValidator->setFinite(true);
            }
            else 
            {
                datatypeValidator->setFinite(false);
            }
        }
        else 
        {
            datatypeValidator->setFinite(false);
        }      
    }

    if (datatypeValidator != 0) {

        if (isUserDefined) {

            if (!fUserDefinedRegistry) {
                fUserDefinedRegistry = new (userManager) RefHashTableOf<DatatypeValidator>(29, userManager);
            }

            fUserDefinedRegistry->put((void *)typeName, datatypeValidator);
        }
        else {
            fBuiltInRegistry->put((void *)typeName, datatypeValidator);
        }

        datatypeValidator->setTypeName(typeName);
    }

    return datatypeValidator;
}

static DatatypeValidator::ValidatorType getPrimitiveDV(DatatypeValidator::ValidatorType validationDV)
{
    if (validationDV == DatatypeValidator::ID    || 
        validationDV == DatatypeValidator::IDREF || 
        validationDV == DatatypeValidator::ENTITY)
    {
        return DatatypeValidator::String;
    }
    return validationDV;
}

DatatypeValidator* DatatypeValidatorFactory::createDatatypeValidator
(
      const XMLCh* const                    typeName
    , RefVectorOf<DatatypeValidator>* const validators
    , const int                             finalSet
    , const bool                            userDefined
    , MemoryManager* const                  userManager
)
{
    if (validators == 0)
        return 0;

    DatatypeValidator* datatypeValidator = 0;
    MemoryManager* const manager = (userDefined)
        ? userManager : XMLPlatformUtils::fgMemoryManager;

    datatypeValidator = new (manager) UnionDatatypeValidator(validators, finalSet, manager);

    if (datatypeValidator != 0) {

        if (userDefined) {

            if (!fUserDefinedRegistry) {
                fUserDefinedRegistry = new (userManager) RefHashTableOf<DatatypeValidator>(29, userManager);
            }

            fUserDefinedRegistry->put((void *)typeName, datatypeValidator);
        }
        else {
            fBuiltInRegistry->put((void *)typeName, datatypeValidator);
        }
        datatypeValidator->setTypeName(typeName);

        // Set PSVI information for Ordered, Numeric, Bounded & Finite
        unsigned int valSize = validators->size();
        if (valSize) 
        {
            DatatypeValidator::ValidatorType ancestorId = getPrimitiveDV(validators->elementAt(0)->getType());

            // For a union the ORDERED {value} is partial unless one of the following:
            // 1. If every member of {member type definitions} is derived from a common ancestor other than the simple ur-type, then {value} is the same as that ancestor's ordered facet.
            // 2. If every member of {member type definitions} has a {value} of false for the ordered facet, then {value} is false.
            bool allOrderedFalse = true;
            bool commonAnc = ancestorId != DatatypeValidator::AnySimpleType;
            bool allNumeric = true;
            bool allBounded = true;
            bool allFinite  = true;
        
            for(unsigned int i = 0 ; (i < valSize) && (commonAnc || allOrderedFalse || allNumeric || allBounded || allFinite); i++)
            {
                // for the other member types, check whether the value is false
                // and whether they have the same ancestor as the first one
                if (commonAnc)
                    commonAnc = ancestorId == getPrimitiveDV(validators->elementAt(i)->getType());
                if (allOrderedFalse)
                    allOrderedFalse = validators->elementAt(i)->getOrdered() == XSSimpleTypeDefinition::ORDERED_FALSE;
           
                if (allNumeric && !validators->elementAt(i)->getNumeric())
                {
                    allNumeric = false;
                }
                if (allBounded && (!validators->elementAt(i)->getBounded() ||
                                   ancestorId != getPrimitiveDV(validators->elementAt(i)->getType())))
                {
                    allBounded = false;
                }
                if (allFinite && !validators->elementAt(i)->getFinite())
                {
                    allFinite = false;
                }        
            }
            if (commonAnc) 
            {
                datatypeValidator->setOrdered(validators->elementAt(0)->getOrdered());
            } 
            else if (allOrderedFalse) 
            {
                datatypeValidator->setOrdered(XSSimpleTypeDefinition::ORDERED_FALSE);
            } 
            else 
            {
                datatypeValidator->setOrdered(XSSimpleTypeDefinition::ORDERED_PARTIAL);
            }
            datatypeValidator->setNumeric(allNumeric);
            datatypeValidator->setBounded(allBounded);
            datatypeValidator->setFinite(allFinite);
        }
        else // size = 0
        {
            datatypeValidator->setOrdered(XSSimpleTypeDefinition::ORDERED_PARTIAL);
            datatypeValidator->setNumeric(true);
            datatypeValidator->setBounded(true);
            datatypeValidator->setFinite(true);
        }
    }
    return datatypeValidator;
}

/***
 * Support for Serialization/De-serialization
 ***/

IMPL_XSERIALIZABLE_TOCREATE(DatatypeValidatorFactory)

void DatatypeValidatorFactory::serialize(XSerializeEngine& serEng)
{
      
    // Need not to serialize static data member, fBuiltInRegistry

    if (serEng.isStoring())
    {
        /***
         * Serialize RefHashTableOf<DatatypeValidator>
         ***/
        XTemplateSerializer::storeObject(fUserDefinedRegistry, serEng);
    }
    else
    {
        /***
         * DV in the UserDefinedRegistry rely on the fBuiltInRegistry
         * to resolve their built-in baseValidator
         ***/
        expandRegistryToFullSchemaSet();

        /***
         * Deserialize RefHashTableOf<DatatypeValidator>
         ***/
        XTemplateSerializer::loadObject(&fUserDefinedRegistry, 29, true, serEng);
    }

}

XERCES_CPP_NAMESPACE_END

/**
  * End of file DatatypeValidatorFactory.cpp
  */

