| /* |
| * 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 |
| */ |
| |