From 57e55165b1b1718efc15994c25688e5fa6fdab0c Mon Sep 17 00:00:00 2001
From: Tinny Ng <tng@apache.org>
Date: Mon, 25 Feb 2002 21:28:26 +0000
Subject: [PATCH] Schema Fix: Thread-safe the built-in datatype validator
 factory.

git-svn-id: https://svn.apache.org/repos/asf/xerces/c/trunk@173532 13f79535-47bb-0310-9956-ffa450edef68
---
 .../datatype/DatatypeValidatorFactory.cpp     | 499 ++++++++----------
 .../datatype/DatatypeValidatorFactory.hpp     | 119 ++---
 2 files changed, 277 insertions(+), 341 deletions(-)

diff --git a/src/xercesc/validators/datatype/DatatypeValidatorFactory.cpp b/src/xercesc/validators/datatype/DatatypeValidatorFactory.cpp
index 3345ea7ff..76cc67e9d 100644
--- a/src/xercesc/validators/datatype/DatatypeValidatorFactory.cpp
+++ b/src/xercesc/validators/datatype/DatatypeValidatorFactory.cpp
@@ -56,8 +56,11 @@
 
 /*
  * $Log$
- * Revision 1.1  2002/02/01 22:22:40  peiyongz
- * Initial revision
+ * Revision 1.2  2002/02/25 21:28:26  tng
+ * Schema Fix: Thread-safe the built-in datatype validator factory.
+ *
+ * Revision 1.1.1.1  2002/02/01 22:22:40  peiyongz
+ * sane_include
  *
  * Revision 1.26  2001/11/07 19:18:52  peiyongz
  * DateTime Port
@@ -333,7 +336,6 @@ const XMLCh fgP1M[] =
 //  DatatypeValidatorFactory: Static member data
 // ---------------------------------------------------------------------------
 RefHashTableOf<DatatypeValidator>* DatatypeValidatorFactory::fBuiltInRegistry = 0;
-int DatatypeValidatorFactory::fRegistryExpanded = 0;
 
 // ---------------------------------------------------------------------------
 //  DatatypeValidatorFactory: Constructors and Destructor
@@ -367,19 +369,16 @@ void DatatypeValidatorFactory::resetRegistry() {
 void DatatypeValidatorFactory::reinitRegistry() {
 	delete fBuiltInRegistry;
 	fBuiltInRegistry = 0;
-	fRegistryExpanded = 0;
 }
 
 // ---------------------------------------------------------------------------
 //  DatatypeValidatorFactory: Registry initialization methods
 // ---------------------------------------------------------------------------
-void DatatypeValidatorFactory::initializeDTDRegistry()
+void DatatypeValidatorFactory::expandRegistryToFullSchemaSet()
 {
-    if (fRegistryExpanded)
-        return;
-
     static XMLRegisterCleanup builtInRegistryCleanup;
 
+    // Initialize common Schema/DTD Datatype validator set if not initialized
     if (fBuiltInRegistry == 0) {
         RefHashTableOf<DatatypeValidator>* t = new RefHashTableOf<DatatypeValidator>(109);
         if (XMLPlatformUtils::compareAndSwap((void **)&fBuiltInRegistry, t, 0) != 0)
@@ -389,311 +388,267 @@ void DatatypeValidatorFactory::initializeDTDRegistry()
         else
         {
             builtInRegistryCleanup.registerCleanup(reinitRegistry);
-        }
-
-    }
 
-    fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_STRING,
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_STRING,
                        new StringDatatypeValidator());
-    fBuiltInRegistry->put((void*) XMLUni::fgIDString,
-                       new IDDatatypeValidator());
-    fBuiltInRegistry->put((void*) XMLUni::fgIDRefString,
-                       new IDREFDatatypeValidator());
-    fBuiltInRegistry->put((void*) XMLUni::fgEntityString,
-                       new ENTITYDatatypeValidator());
-    fBuiltInRegistry->put((void*) XMLUni::fgNotationString,
+            fBuiltInRegistry->put((void*) XMLUni::fgNotationString,
                        new NOTATIONDatatypeValidator());
 
 
-    // Create 'IDREFS' datatype validator
-	 createDatatypeValidator(XMLUni::fgIDRefsString,
-                    getDatatypeValidator(XMLUni::fgIDRefString), 0, 0, true, 0, false);
-
-    // Create 'ENTITIES' datatype validator
-    createDatatypeValidator(XMLUni::fgEntitiesString,
-		            getDatatypeValidator(XMLUni::fgEntityString), 0, 0, true, 0, false);
-
-    RefHashTableOf<KVStringPair>* facets = new RefHashTableOf<KVStringPair>(2);
-
-    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));
-
-    // Create 'NMTOKEN' datatype validator
-    createDatatypeValidator(XMLUni::fgNmTokenString,
-                    getDatatypeValidator(SchemaSymbols::fgDT_STRING),facets, 0, false, 0, false);
-
-    // Create 'NMTOKENS' datatype validator
-    createDatatypeValidator(XMLUni::fgNmTokensString,
-	                 getDatatypeValidator(XMLUni::fgNmTokenString), 0, 0, true, 0, false);
-
-    fRegistryExpanded = 1;
-}
-
-
-void DatatypeValidatorFactory::expandRegistryToFullSchemaSet()
-{
-	if (fRegistryExpanded == 2)
-		return;
-
-	// Initialize common Schema/DTD Datatype validator set if not initialized
-    if (fBuiltInRegistry == 0
-        || fBuiltInRegistry->get(SchemaSymbols::fgDT_STRING) == 0) {
-        initializeDTDRegistry();
-    }
-
-        fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_ANYSIMPLETYPE,
-                       new AnySimpleTypeDatatypeValidator());
-        fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_BOOLEAN,
-                       new BooleanDatatypeValidator());
-        fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_DECIMAL,
-                       new DecimalDatatypeValidator());
-        fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_HEXBINARY,
-                       new HexBinaryDatatypeValidator());
-        fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_BASE64BINARY,
-                       new Base64BinaryDatatypeValidator());
-        fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_DOUBLE,
-                       new DoubleDatatypeValidator());
-        fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_FLOAT,
-                       new FloatDatatypeValidator());
-        fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_ANYURI,
-                       new AnyURIDatatypeValidator());
-        fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_QNAME,
-                       new QNameDatatypeValidator());
-        fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_NAME,
-                       new NameDatatypeValidator());
-        fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_NCNAME,
-                       new NCNameDatatypeValidator());
-
-        fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_DATETIME,
-                       new DateTimeDatatypeValidator());
-        fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_DATE,
-                       new DateDatatypeValidator());
-        fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_TIME,
-                       new TimeDatatypeValidator());
-        fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_DAY,
-                       new DayDatatypeValidator());
-        fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_MONTH,
-                       new MonthDatatypeValidator());
-        fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_MONTHDAY,
-                       new MonthDayDatatypeValidator());
-        fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_YEAR,
-                       new YearDatatypeValidator());
-        fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_YEARMONTH,
-                       new YearMonthDatatypeValidator());
-        fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_DURATION,
-                       new DurationDatatypeValidator());
-
-        // 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.
-
-        // Create 'normalizedString' datatype validator
-        RefHashTableOf<KVStringPair>* facets = new RefHashTableOf<KVStringPair>(3);
-
-        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);
-
-        // Create 'language' datatype validator
-        facets = new RefHashTableOf<KVStringPair>(3);
-
-        facets->put((void*) SchemaSymbols::fgELT_PATTERN,
-                    new KVStringPair(SchemaSymbols::fgELT_PATTERN, fgLangPattern));
-
-        createDatatypeValidator(SchemaSymbols::fgDT_LANGUAGE,
-                      getDatatypeValidator(SchemaSymbols::fgDT_TOKEN),
-                      facets, 0, false, 0, false);
-
-        // Create 'Name' datatype validator
-        /***
-        facets = new RefHashTableOf<KVStringPair>(3);
-
-        facets->put((void*) SchemaSymbols::fgELT_PATTERN,
-                    new KVStringPair(SchemaSymbols::fgELT_PATTERN, fgNamePattern));
-
-        createDatatypeValidator(SchemaSymbols::fgDT_NAME,
-                      getDatatypeValidator(SchemaSymbols::fgDT_TOKEN),
-                      facets, 0, false, 0, false);
-
-        // Create a 'NCName' datatype validator
-        facets = new RefHashTableOf<KVStringPair>(3);
-
-        facets->put((void*) SchemaSymbols::fgELT_PATTERN,
-                    new KVStringPair(SchemaSymbols::fgELT_PATTERN, fgNCNamePattern));
-
-        createDatatypeValidator(SchemaSymbols::fgDT_NCNAME,
-                      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, fgValueZero));
-
-        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, 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,fgNegOne));
-
-        createDatatypeValidator(SchemaSymbols::fgDT_NEGATIVEINTEGER,
-                      getDatatypeValidator(SchemaSymbols::fgDT_NONPOSITIVEINTEGER),
-                      facets, 0, false, 0, false);
-
-        // Create 'long' datatype validator
-        facets = new RefHashTableOf<KVStringPair>(2);
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_ANYSIMPLETYPE,
+                           new AnySimpleTypeDatatypeValidator());
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_BOOLEAN,
+                           new BooleanDatatypeValidator());
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_DECIMAL,
+                           new DecimalDatatypeValidator());
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_HEXBINARY,
+                           new HexBinaryDatatypeValidator());
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_BASE64BINARY,
+                           new Base64BinaryDatatypeValidator());
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_DOUBLE,
+                           new DoubleDatatypeValidator());
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_FLOAT,
+                           new FloatDatatypeValidator());
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_ANYURI,
+                           new AnyURIDatatypeValidator());
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_QNAME,
+                           new QNameDatatypeValidator());
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_NAME,
+                           new NameDatatypeValidator());
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_NCNAME,
+                           new NCNameDatatypeValidator());
+
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_DATETIME,
+                           new DateTimeDatatypeValidator());
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_DATE,
+                           new DateDatatypeValidator());
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_TIME,
+                           new TimeDatatypeValidator());
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_DAY,
+                           new DayDatatypeValidator());
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_MONTH,
+                           new MonthDatatypeValidator());
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_MONTHDAY,
+                           new MonthDayDatatypeValidator());
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_YEAR,
+                           new YearDatatypeValidator());
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_YEARMONTH,
+                           new YearMonthDatatypeValidator());
+            fBuiltInRegistry->put((void*) SchemaSymbols::fgDT_DURATION,
+                           new DurationDatatypeValidator());
+
+            // 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 'NMTOKEN' datatype validator
+            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_STRING),facets, 0, false, 0, false);
+
+            // Create 'NMTOKENS' datatype validator
+            createDatatypeValidator(XMLUni::fgNmTokensString,
+        	                 getDatatypeValidator(XMLUni::fgNmTokenString), 0, 0, true, 0, false);
+
+            // Create 'normalizedString' datatype validator
+            facets = new RefHashTableOf<KVStringPair>(3);
+            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);
+
+            // Create 'language' datatype validator
+            facets = new RefHashTableOf<KVStringPair>(3);
+
+            facets->put((void*) SchemaSymbols::fgELT_PATTERN,
+                        new KVStringPair(SchemaSymbols::fgELT_PATTERN, 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, fgValueZero));
+
+            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, 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,fgNegOne));
 
-        facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
-                    new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE,fgLongMaxInc));
-        facets->put((void*) SchemaSymbols::fgELT_MININCLUSIVE,
-                    new KVStringPair(SchemaSymbols::fgELT_MININCLUSIVE,fgLongMinInc));
+            createDatatypeValidator(SchemaSymbols::fgDT_NEGATIVEINTEGER,
+                          getDatatypeValidator(SchemaSymbols::fgDT_NONPOSITIVEINTEGER),
+                          facets, 0, false, 0, false);
 
-        createDatatypeValidator(SchemaSymbols::fgDT_LONG,
-                      getDatatypeValidator(SchemaSymbols::fgDT_INTEGER),
-                      facets, 0, false, 0, false);
+            // Create 'long' datatype validator
+            facets = new RefHashTableOf<KVStringPair>(2);
 
-        // Create 'int' datatype validator
-        facets = new RefHashTableOf<KVStringPair>(2);
+            facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
+                        new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE,fgLongMaxInc));
+            facets->put((void*) SchemaSymbols::fgELT_MININCLUSIVE,
+                        new KVStringPair(SchemaSymbols::fgELT_MININCLUSIVE,fgLongMinInc));
 
-        facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
-                    new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, fgIntMaxInc));
-        facets->put((void*) SchemaSymbols::fgELT_MININCLUSIVE,
-                    new KVStringPair(SchemaSymbols::fgELT_MININCLUSIVE, fgIntMinInc));
+            createDatatypeValidator(SchemaSymbols::fgDT_LONG,
+                          getDatatypeValidator(SchemaSymbols::fgDT_INTEGER),
+                          facets, 0, false, 0, false);
 
-        createDatatypeValidator(SchemaSymbols::fgDT_INT,
-                      getDatatypeValidator(SchemaSymbols::fgDT_LONG),
-                      facets, 0, false, 0, false);
+            // Create 'int' datatype validator
+            facets = new RefHashTableOf<KVStringPair>(2);
 
-        // Create 'short' datatype validator
-        facets = new RefHashTableOf<KVStringPair>(2);
+            facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
+                        new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, fgIntMaxInc));
+            facets->put((void*) SchemaSymbols::fgELT_MININCLUSIVE,
+                        new KVStringPair(SchemaSymbols::fgELT_MININCLUSIVE, fgIntMinInc));
 
-        facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
-                    new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, fgShortMaxInc));
-        facets->put((void*) SchemaSymbols::fgELT_MININCLUSIVE,
-                    new KVStringPair(SchemaSymbols::fgELT_MININCLUSIVE, fgShortMinInc));
+            createDatatypeValidator(SchemaSymbols::fgDT_INT,
+                          getDatatypeValidator(SchemaSymbols::fgDT_LONG),
+                          facets, 0, false, 0, false);
 
-        createDatatypeValidator(SchemaSymbols::fgDT_SHORT,
-                      getDatatypeValidator(SchemaSymbols::fgDT_INT),
-                      facets, 0, false, 0 ,false);
+            // Create 'short' datatype validator
+            facets = new RefHashTableOf<KVStringPair>(2);
 
-        // Create 'byte' datatype validator
-        facets = new RefHashTableOf<KVStringPair>(2);
+            facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
+                        new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, fgShortMaxInc));
+            facets->put((void*) SchemaSymbols::fgELT_MININCLUSIVE,
+                        new KVStringPair(SchemaSymbols::fgELT_MININCLUSIVE, fgShortMinInc));
 
-        facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
-                    new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, fgByteMaxInc));
-        facets->put((void*) SchemaSymbols::fgELT_MININCLUSIVE,
-                    new KVStringPair(SchemaSymbols::fgELT_MININCLUSIVE, fgByteMinInc));
+            createDatatypeValidator(SchemaSymbols::fgDT_SHORT,
+                          getDatatypeValidator(SchemaSymbols::fgDT_INT),
+                          facets, 0, false, 0 ,false);
 
-        createDatatypeValidator(SchemaSymbols::fgDT_BYTE,
-                      getDatatypeValidator(SchemaSymbols::fgDT_SHORT),
-                      facets, 0, false, 0, false);
+            // Create 'byte' datatype validator
+            facets = new RefHashTableOf<KVStringPair>(2);
 
-        // Create 'nonNegativeInteger' datatype validator
-        facets = new RefHashTableOf<KVStringPair>(2);
+            facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
+                        new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, fgByteMaxInc));
+            facets->put((void*) SchemaSymbols::fgELT_MININCLUSIVE,
+                        new KVStringPair(SchemaSymbols::fgELT_MININCLUSIVE, fgByteMinInc));
 
-        facets->put((void*) SchemaSymbols::fgELT_MININCLUSIVE,
-                    new KVStringPair(SchemaSymbols::fgELT_MININCLUSIVE, fgValueZero));
+            createDatatypeValidator(SchemaSymbols::fgDT_BYTE,
+                          getDatatypeValidator(SchemaSymbols::fgDT_SHORT),
+                          facets, 0, false, 0, false);
 
-        createDatatypeValidator(SchemaSymbols::fgDT_NONNEGATIVEINTEGER,
-                      getDatatypeValidator(SchemaSymbols::fgDT_INTEGER),
-                      facets, 0, false, 0, false);
+            // Create 'nonNegativeInteger' datatype validator
+            facets = new RefHashTableOf<KVStringPair>(2);
 
-        // Create 'unsignedLong' datatype validator
-        facets = new RefHashTableOf<KVStringPair>(2);
+            facets->put((void*) SchemaSymbols::fgELT_MININCLUSIVE,
+                        new KVStringPair(SchemaSymbols::fgELT_MININCLUSIVE, fgValueZero));
 
-        facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
-                    new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, fgULongMaxInc));
+            createDatatypeValidator(SchemaSymbols::fgDT_NONNEGATIVEINTEGER,
+                          getDatatypeValidator(SchemaSymbols::fgDT_INTEGER),
+                          facets, 0, false, 0, false);
 
-        createDatatypeValidator(SchemaSymbols::fgDT_ULONG,
-                      getDatatypeValidator(SchemaSymbols::fgDT_NONNEGATIVEINTEGER),
-                      facets, 0, false, 0, false);
+            // Create 'unsignedLong' datatype validator
+            facets = new RefHashTableOf<KVStringPair>(2);
 
-        // Create 'unsignedInt' datatype validator
-        facets = new RefHashTableOf<KVStringPair>(2);
+            facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
+                        new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, fgULongMaxInc));
 
-        facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
-                    new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, fgUIntMaxInc));
+            createDatatypeValidator(SchemaSymbols::fgDT_ULONG,
+                          getDatatypeValidator(SchemaSymbols::fgDT_NONNEGATIVEINTEGER),
+                          facets, 0, false, 0, false);
 
-        createDatatypeValidator(SchemaSymbols::fgDT_UINT,
-                      getDatatypeValidator(SchemaSymbols::fgDT_ULONG),
-                      facets, 0, false, 0, false);
+            // Create 'unsignedInt' datatype validator
+            facets = new RefHashTableOf<KVStringPair>(2);
 
-        // Create 'unsignedShort' datatypeValidator
-        facets = new RefHashTableOf<KVStringPair>(2);
+            facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
+                        new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, fgUIntMaxInc));
 
-        facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
-                    new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, fgUShortMaxInc));
+            createDatatypeValidator(SchemaSymbols::fgDT_UINT,
+                          getDatatypeValidator(SchemaSymbols::fgDT_ULONG),
+                          facets, 0, false, 0, false);
 
-        createDatatypeValidator(SchemaSymbols::fgDT_USHORT,
-                      getDatatypeValidator(SchemaSymbols::fgDT_UINT),
-                      facets, 0, false, 0, false);
+            // Create 'unsignedShort' datatypeValidator
+            facets = new RefHashTableOf<KVStringPair>(2);
 
-        // Create 'unsignedByte' datatype validator
-        facets = new RefHashTableOf<KVStringPair>(2);
+            facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
+                        new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, fgUShortMaxInc));
 
-        facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
-                    new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, fgUByteMaxInc));
+            createDatatypeValidator(SchemaSymbols::fgDT_USHORT,
+                          getDatatypeValidator(SchemaSymbols::fgDT_UINT),
+                          facets, 0, false, 0, false);
 
-        createDatatypeValidator(SchemaSymbols::fgDT_UBYTE,
-                      getDatatypeValidator(SchemaSymbols::fgDT_USHORT),
-                      facets, 0, false, 0, false);
+            // Create 'unsignedByte' datatype validator
+            facets = new RefHashTableOf<KVStringPair>(2);
 
-        // Create 'positiveInteger' datatype validator
-        facets = new RefHashTableOf<KVStringPair>(2);
+            facets->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE,
+                        new KVStringPair(SchemaSymbols::fgELT_MAXINCLUSIVE, fgUByteMaxInc));
 
-        facets->put((void*) SchemaSymbols::fgELT_MININCLUSIVE,
-                    new KVStringPair(SchemaSymbols::fgELT_MININCLUSIVE, fgValueOne));
+            createDatatypeValidator(SchemaSymbols::fgDT_UBYTE,
+                          getDatatypeValidator(SchemaSymbols::fgDT_USHORT),
+                          facets, 0, false, 0, false);
 
-        createDatatypeValidator(SchemaSymbols::fgDT_POSITIVEINTEGER,
-                      getDatatypeValidator(SchemaSymbols::fgDT_NONNEGATIVEINTEGER),
-                      facets, 0, false, 0, false);
+            // Create 'positiveInteger' datatype validator
+            facets = new RefHashTableOf<KVStringPair>(2);
 
-        // REVISIT - Add the remaining datatype validators
-        // Create 'dateTime' datatype validator
+            facets->put((void*) SchemaSymbols::fgELT_MININCLUSIVE,
+                        new KVStringPair(SchemaSymbols::fgELT_MININCLUSIVE, fgValueOne));
 
-        // Create 'date' datatype validator
+            createDatatypeValidator(SchemaSymbols::fgDT_POSITIVEINTEGER,
+                          getDatatypeValidator(SchemaSymbols::fgDT_NONNEGATIVEINTEGER),
+                          facets, 0, false, 0, false);
+        }
+    }
 
-        // Create 'gMonthDay' datatype validator
+    // ID, IDREF IDREFS, ENTITY, ENTITIES  DTV have specific data member
+    //   and cannot be shared across threads
+    // So instead of storing them in the static fBuiltInRegistry,
+    //   store them in local data fUserDefinedRegistry
+    if (fUserDefinedRegistry == 0) {
+        fUserDefinedRegistry = new RefHashTableOf<DatatypeValidator>(29);
+    }
 
-        // Create 'gYearMonth' datatype validator
+    fUserDefinedRegistry->put((void*) XMLUni::fgIDString,
+                       new IDDatatypeValidator());
+    fUserDefinedRegistry->put((void*) XMLUni::fgIDRefString,
+                       new IDREFDatatypeValidator());
+    fUserDefinedRegistry->put((void*) XMLUni::fgEntityString,
+                       new ENTITYDatatypeValidator());
 
-        // Create 'gYear' datatype validator
+    // Create 'IDREFS' datatype validator
+	 createDatatypeValidator(XMLUni::fgIDRefsString,
+                    getDatatypeValidator(XMLUni::fgIDRefString), 0, 0, true, 0, true);
 
-        // Create 'gMonth' datatype validator
+    // Create 'ENTITIES' datatype validator
+    createDatatypeValidator(XMLUni::fgEntitiesString,
+		            getDatatypeValidator(XMLUni::fgEntityString), 0, 0, true, 0, true);
 
-        fRegistryExpanded = 2;
 }
 
 // ---------------------------------------------------------------------------
diff --git a/src/xercesc/validators/datatype/DatatypeValidatorFactory.hpp b/src/xercesc/validators/datatype/DatatypeValidatorFactory.hpp
index 8cd526163..a39c7bac4 100644
--- a/src/xercesc/validators/datatype/DatatypeValidatorFactory.hpp
+++ b/src/xercesc/validators/datatype/DatatypeValidatorFactory.hpp
@@ -74,7 +74,7 @@
  * facets and registering the Datatype into registry table.
  * This implementation uses a Hahtable as a registry. The datatype validators created
  * by the factory will be deleted by the registry.
- * 
+ *
  * As the Parser parses an instance document it knows if validation needs
  * to be checked. If no validation is necesary we should not instantiate a
  * DatatypeValidatorFactory.
@@ -99,7 +99,7 @@ class VALIDATORS_EXPORT DatatypeValidatorFactory
 {
 public:
 
-	// -----------------------------------------------------------------------
+    // -----------------------------------------------------------------------
     //  Public Constructors and Destructor
     // -----------------------------------------------------------------------
     /** @name Constructors */
@@ -107,14 +107,14 @@ public:
 
     DatatypeValidatorFactory();
 
-	//@}
+    //@}
 
-	/** @name Destructor. */
+    /** @name Destructor. */
     //@{
 
     ~DatatypeValidatorFactory();
 
-	//@}
+    //@}
 
     // -----------------------------------------------------------------------
     // Getter methods
@@ -123,11 +123,11 @@ public:
     //@{
 
     /**
-      * Returns the datatype validator
-	  *
-	  * @param  dvType   Datatype validator name/type
-	  */
-	DatatypeValidator* getDatatypeValidator(const XMLCh* const dvType) const;
+     * Returns the datatype validator
+     *
+     * @param  dvType   Datatype validator name/type
+     */
+    DatatypeValidator* getDatatypeValidator(const XMLCh* const dvType) const;
 
     //@}
 
@@ -138,67 +138,52 @@ public:
     //@{
 
     /**
-	  * Initializes registry with primitive and derived Simple types.
-      * 
-      * This method does not clear the registry to clear the registry you 
-	  * have to call resetRegistry.
-      * 
-      * The net effect of this method is to start with a the smallest set of 
-	  * datatypes needed by the validator.
-	  *
-	  * If we start with DTD's, then we initialize the table to only 
-	  * the 9 validators needed by DTD Validation.
-	  */
-	void initializeDTDRegistry();
-
-	/**
-	  * Initializes registry with primitive and derived Simple types.
-      * 
-      * This method does not clear the registry to clear the registry you 
-	  * have to call resetRegistry.
-      * 
-      * The net effect of this method is to start with a the smallest set of 
-	  * datatypes needed by the validator.
-	  *
-      * If we start with Schema's then we initialize to to full set of 
-	  * validators.	  
-	  */
-	void expandRegistryToFullSchemaSet();
-
-	//@}
+     * Initializes registry with primitive and derived Simple types.
+     *
+     * This method does not clear the registry to clear the registry you
+     * have to call resetRegistry.
+     *
+     * The net effect of this method is to start with the smallest set of
+     * datatypes needed by the validator.
+     *
+     * If we start with Schema's then we initialize to full set of
+     * validators.	
+     */
+    void expandRegistryToFullSchemaSet();
 
+    //@}
     // -----------------------------------------------------------------------
     // Validator Factory methods
     // -----------------------------------------------------------------------
     /** @name Validator Factory Functions */
     //@{
 
-    /** 
-      * Creates a new datatype validator of type baseValidator's class and
-      * adds it to the registry
-      *
-      * @param  typeName       Datatype validator name
-      *
-      * @param  baseValidator  Base datatype validator
-      *
-      * @param  facets         datatype facets if any
-      *
-      * @param  enums          vector of values for enum facet
-      *
-      * @param  derivedByList  Indicates whether the datatype is derived by
-	  *                        list or not
-      *
-      * @param  finalSet       'final' values of the simpleType
-	  */
-	DatatypeValidator* createDatatypeValidator(const XMLCh* const,
-		                                       DatatypeValidator* const,
+    /**
+     * Creates a new datatype validator of type baseValidator's class and
+     * adds it to the registry
+     *
+     * @param  typeName       Datatype validator name
+     *
+     * @param  baseValidator  Base datatype validator
+     *
+     * @param  facets         datatype facets if any
+     *
+     * @param  enums          vector of values for enum facet
+     *
+     * @param  derivedByList  Indicates whether the datatype is derived by
+     *                        list or not
+     *
+     * @param  finalSet       'final' values of the simpleType
+     */
+     DatatypeValidator* createDatatypeValidator(const XMLCh* const,
+                                               DatatypeValidator* const,
                                                RefHashTableOf<KVStringPair>* const,
                                                RefVectorOf<XMLCh>* const enums,
                                                const bool,
                                                const int = 0,
                                                const bool = true);
 
-    /** 
+    /**
       * Creates a new datatype validator of type UnionDatatypeValidator and
       * adds it to the registry
       *
@@ -212,30 +197,27 @@ public:
                                                const int finalSet,
                                                const bool = true);
 
-	//@}
+    //@}
 
     /**
       * Reset datatype validator registry
       */
-	void resetRegistry();
+    void resetRegistry();
 
-	// -----------------------------------------------------------------------
+    // -----------------------------------------------------------------------
     //  Notification that lazy data has been deleted
     // -----------------------------------------------------------------------
-	static void reinitRegistry();
+    static void reinitRegistry();
 
 private:
     // -----------------------------------------------------------------------
     //  CleanUp methods
     // -----------------------------------------------------------------------
-	void cleanUp();
+    void cleanUp();
 
     // -----------------------------------------------------------------------
     //  Private data members
     //
-    //  fRegistryExpanded
-    //      Indicated whether we have expanded the registry or not.
-	//		
     //  fUserDefinedRegistry
     //      This is a hashtable of user defined dataype validators.
     //
@@ -243,15 +225,14 @@ private:
     //      This is a hashtable of built-in primitive datatype validators.
     // -----------------------------------------------------------------------
     RefHashTableOf<DatatypeValidator>*        fUserDefinedRegistry;
-	static int                                fRegistryExpanded;
-	static RefHashTableOf<DatatypeValidator>* fBuiltInRegistry;
+    static RefHashTableOf<DatatypeValidator>* fBuiltInRegistry;
 };
 
 
 // ---------------------------------------------------------------------------
 //  DatatypeValidatorFactory: Getters
 // ---------------------------------------------------------------------------
-inline DatatypeValidator* 
+inline DatatypeValidator*
 DatatypeValidatorFactory::getDatatypeValidator(const XMLCh* const dvType) const
 {
 	if (dvType) {
-- 
GitLab