/* * 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$ */ // --------------------------------------------------------------------------- // Includes // --------------------------------------------------------------------------- #include #include #include #include #include XERCES_CPP_NAMESPACE_BEGIN static const int BUF_LEN = 64; #define REPORT_FACET_ERROR(val1, val2, except_code, manager) \ XMLCh value1[BUF_LEN+1]; \ XMLCh value2[BUF_LEN+1]; \ XMLString::sizeToText(val1, value1, BUF_LEN, 10, manager); \ XMLString::sizeToText(val2, value2, BUF_LEN, 10, manager); \ ThrowXMLwithMemMgr2(InvalidDatatypeFacetException \ , except_code \ , value1 \ , value2 \ , manager); #define REPORT_VALUE_ERROR(data, val1, val2, except_code, manager) \ XMLCh value1[BUF_LEN+1]; \ XMLCh value2[BUF_LEN+1]; \ XMLString::sizeToText(val1, value1, BUF_LEN, 10, manager); \ XMLString::sizeToText(val2, value2, BUF_LEN, 10, manager); \ ThrowXMLwithMemMgr3(InvalidDatatypeValueException \ , except_code \ , data \ , value1 \ , value2 \ , manager); // --------------------------------------------------------------------------- // Constructors and Destructor // --------------------------------------------------------------------------- AbstractStringValidator::~AbstractStringValidator() { //~RefVectorOf will delete all adopted elements if ( !fEnumerationInherited && fEnumeration) { delete fEnumeration; fEnumeration = 0; } } AbstractStringValidator::AbstractStringValidator( DatatypeValidator* const baseValidator , RefHashTableOf* const facets , const int finalSet , const ValidatorType type , MemoryManager* const manager) :DatatypeValidator(baseValidator, facets, finalSet, type, manager) ,fLength(0) ,fMaxLength(SchemaSymbols::fgINT_MAX_VALUE) ,fMinLength(0) ,fEnumerationInherited(false) ,fEnumeration(0) { // init() is invoked from derived class's ctor instead of from // here to allow correct resolution of virutal method, such as // assigneAdditionalFacet(), inheritAdditionalFacet(). } void AbstractStringValidator::init(RefArrayVectorOf* const enums ,MemoryManager* const manager) { if (enums) { setEnumeration(enums, false); normalizeEnumeration(manager); } assignFacet(manager); inspectFacet(manager); inspectFacetBase(manager); inheritFacet(); } // // Assign facets // assign common facets // assign additional facet // void AbstractStringValidator::assignFacet(MemoryManager* const manager) { RefHashTableOf* facets = getFacets(); if (!facets) return; XMLCh* key; RefHashTableOfEnumerator e(facets, false, manager); while (e.hasMoreElements()) { KVStringPair pair = e.nextElement(); key = pair.getKey(); XMLCh* value = pair.getValue(); if (XMLString::equals(key, SchemaSymbols::fgELT_LENGTH)) { int val; try { val = XMLString::parseInt(value, manager); } catch (NumberFormatException&) { ThrowXMLwithMemMgr1(InvalidDatatypeFacetException, XMLExcepts::FACET_Invalid_Len, value, manager); } if ( val < 0 ) ThrowXMLwithMemMgr1(InvalidDatatypeFacetException, XMLExcepts::FACET_NonNeg_Len, value, manager); setLength(val); setFacetsDefined(DatatypeValidator::FACET_LENGTH); } else if (XMLString::equals(key, SchemaSymbols::fgELT_MINLENGTH)) { int val; try { val = XMLString::parseInt(value, manager); } catch (NumberFormatException&) { ThrowXMLwithMemMgr1(InvalidDatatypeFacetException, XMLExcepts::FACET_Invalid_minLen, value, manager); } if ( val < 0 ) ThrowXMLwithMemMgr1(InvalidDatatypeFacetException, XMLExcepts::FACET_NonNeg_minLen, value, manager); setMinLength(val); setFacetsDefined(DatatypeValidator::FACET_MINLENGTH); } else if (XMLString::equals(key, SchemaSymbols::fgELT_MAXLENGTH)) { int val; try { val = XMLString::parseInt(value, manager); } catch (NumberFormatException&) { ThrowXMLwithMemMgr1(InvalidDatatypeFacetException, XMLExcepts::FACET_Invalid_maxLen, value, manager); } if ( val < 0 ) ThrowXMLwithMemMgr1(InvalidDatatypeFacetException, XMLExcepts::FACET_NonNeg_maxLen, value, manager); setMaxLength(val); setFacetsDefined(DatatypeValidator::FACET_MAXLENGTH); } else if (XMLString::equals(key, SchemaSymbols::fgELT_PATTERN)) { setPattern(value); if (getPattern()) setFacetsDefined(DatatypeValidator::FACET_PATTERN); // do not construct regex until needed } else if (XMLString::equals(key, SchemaSymbols::fgATT_FIXED)) { unsigned int val; bool retStatus; try { retStatus = XMLString::textToBin(value, val, fMemoryManager); } catch (RuntimeException&) { ThrowXMLwithMemMgr(InvalidDatatypeFacetException, XMLExcepts::FACET_internalError_fixed, manager); } if (!retStatus) { ThrowXMLwithMemMgr(InvalidDatatypeFacetException, XMLExcepts::FACET_internalError_fixed, manager); } setFixed(val); //no setFacetsDefined here } // // else if (XMLString::equals(key, SchemaSymbols::fgELT_SPECIAL_TOKEN)) // TODO // // Note: whitespace is taken care of by TraverseSchema. // else { assignAdditionalFacet(key, value, manager); } }//while }//end of assigneFacet() // // Check facet among self // check common facets // check Additional Facet Constraint // void AbstractStringValidator::inspectFacet(MemoryManager* const manager) { int thisFacetsDefined = getFacetsDefined(); if (!thisFacetsDefined) return; // check 4.3.1.c1 error: length & (maxLength | minLength) if ((thisFacetsDefined & DatatypeValidator::FACET_LENGTH) != 0) { if ((thisFacetsDefined & DatatypeValidator::FACET_MAXLENGTH) != 0) ThrowXMLwithMemMgr(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen, manager); else if (((thisFacetsDefined & DatatypeValidator::FACET_MINLENGTH) != 0)) ThrowXMLwithMemMgr(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_minLen, manager); } // check 4.3.2.c1 must: minLength <= maxLength if ((thisFacetsDefined & (DatatypeValidator::FACET_MINLENGTH |DatatypeValidator::FACET_MAXLENGTH)) != 0) { XMLSize_t thisMinLength = getMinLength(); XMLSize_t thisMaxLength = getMaxLength(); if ( thisMinLength > thisMaxLength ) { REPORT_FACET_ERROR(thisMaxLength , thisMinLength , XMLExcepts::FACET_maxLen_minLen , manager) } } }// end of inspectFacet() // // Check vs base // check common facets // check enumeration // check Additional Facet Constraint // void AbstractStringValidator::inspectFacetBase(MemoryManager* const manager) { AbstractStringValidator *pBaseValidator = (AbstractStringValidator*) getBaseValidator(); int thisFacetsDefined = getFacetsDefined(); if ( (!thisFacetsDefined && !fEnumeration) || (!pBaseValidator) ) return; int baseFacetsDefined = pBaseValidator->getFacetsDefined(); XMLSize_t thisLength = getLength(); XMLSize_t thisMinLength = getMinLength(); XMLSize_t thisMaxLength = getMaxLength(); XMLSize_t baseLength = pBaseValidator->getLength(); XMLSize_t baseMinLength = pBaseValidator->getMinLength(); XMLSize_t baseMaxLength = pBaseValidator->getMaxLength(); int baseFixed = pBaseValidator->getFixed(); /*** check facets against base.facets Note: later we need to check the "fix" option of the base type and apply that to every individual facet. ***/ /*** Non coexistence of derived' length and base' (minLength | maxLength) base' length and derived' (minLength | maxLength) E2-35 It is an error for both length and either of minLength or maxLength to be members of {facets}, unless they are specified in different derivation steps in which case the following must be true: the {value} of minLength <= the {value} of length <= the {value} of maxLength ***/ // error: length > base.maxLength // length < base.minLength if ((thisFacetsDefined & DatatypeValidator::FACET_LENGTH) !=0) { if (((baseFacetsDefined & DatatypeValidator::FACET_MAXLENGTH) !=0) && (thisLength > baseMaxLength) ) { REPORT_FACET_ERROR(thisLength , baseMaxLength , XMLExcepts::FACET_Len_baseMaxLen , manager) } if (((baseFacetsDefined & DatatypeValidator::FACET_MINLENGTH) !=0) && (thisLength < baseMinLength) ) { REPORT_FACET_ERROR(thisLength , baseMinLength , XMLExcepts::FACET_Len_baseMinLen , manager) } } // error: baseLength > maxLength // baseLength < minLength if ((baseFacetsDefined & DatatypeValidator::FACET_LENGTH) !=0) { if (((thisFacetsDefined & DatatypeValidator::FACET_MAXLENGTH) !=0) && (baseLength > thisMaxLength) ) { REPORT_FACET_ERROR(thisMaxLength , baseLength , XMLExcepts::FACET_maxLen_baseLen , manager) } if (((thisFacetsDefined & DatatypeValidator::FACET_MINLENGTH) !=0) && (baseLength < thisMinLength) ) { REPORT_FACET_ERROR(thisMinLength , baseLength , XMLExcepts::FACET_minLen_baseLen , manager) } } // check 4.3.1.c2 error: length != base.length if (((thisFacetsDefined & DatatypeValidator::FACET_LENGTH) !=0) && ((baseFacetsDefined & DatatypeValidator::FACET_LENGTH) !=0)) { if ( thisLength != baseLength ) { REPORT_FACET_ERROR(thisLength , baseLength , XMLExcepts::FACET_Len_baseLen , manager) } } /*** |--- derived ---| base.minLength <= minLength <= maxLength <= base.maxLength |------------------- base -------------------| ***/ // check 4.3.2.c1 must: minLength <= base.maxLength if (((thisFacetsDefined & DatatypeValidator::FACET_MINLENGTH ) != 0) && ((baseFacetsDefined & DatatypeValidator::FACET_MAXLENGTH ) != 0)) { if ( thisMinLength > baseMaxLength ) { REPORT_FACET_ERROR(thisMinLength , baseMaxLength , XMLExcepts::FACET_minLen_basemaxLen , manager) } } // check 4.3.2.c2 error: minLength < base.minLength if (((thisFacetsDefined & DatatypeValidator::FACET_MINLENGTH) !=0) && ((baseFacetsDefined & DatatypeValidator::FACET_MINLENGTH) != 0)) { if ((baseFixed & DatatypeValidator::FACET_MINLENGTH) !=0) { if ( thisMinLength != baseMinLength ) { REPORT_FACET_ERROR(thisMinLength , baseMinLength , XMLExcepts::FACET_minLen_base_fixed , manager) } } else { if ( thisMinLength < baseMinLength ) { REPORT_FACET_ERROR(thisMinLength , baseMinLength , XMLExcepts::FACET_minLen_baseminLen , manager) } } } // check 4.3.2.c1 must: base.minLength <= maxLength if (((baseFacetsDefined & DatatypeValidator::FACET_MINLENGTH) !=0) && ((thisFacetsDefined & DatatypeValidator::FACET_MAXLENGTH) !=0)) { if ( baseMinLength > thisMaxLength ) { REPORT_FACET_ERROR(thisMaxLength , baseMinLength , XMLExcepts::FACET_maxLen_baseminLen , manager) } } // check 4.3.3.c1 error: maxLength > base.maxLength if (((thisFacetsDefined & DatatypeValidator::FACET_MAXLENGTH) !=0) && ((baseFacetsDefined & DatatypeValidator::FACET_MAXLENGTH) !=0)) { if ((baseFixed & DatatypeValidator::FACET_MAXLENGTH) !=0) { if ( thisMaxLength != baseMaxLength ) { REPORT_FACET_ERROR(thisMaxLength , baseMaxLength , XMLExcepts::FACET_maxLen_base_fixed , manager) } } else { if ( thisMaxLength > baseMaxLength ) { REPORT_FACET_ERROR(thisMaxLength , baseMaxLength , XMLExcepts::FACET_maxLen_basemaxLen , manager) } } } // check 4.3.5.c0 must: enumeration values from the value space of base if ( ((thisFacetsDefined & DatatypeValidator::FACET_ENUMERATION) != 0) && (getEnumeration() !=0)) { XMLSize_t i = 0; XMLSize_t enumLength = getEnumeration()->size(); for ( ; i < enumLength; i++) { // ask parent do a complete check pBaseValidator->checkContent(getEnumeration()->elementAt(i), (ValidationContext*)0, false, manager); #if 0 // spec says that only base has to checkContent // enum shall pass this->checkContent() as well. checkContent(getEnumeration()->elementAt(i), (ValidationContext*)0, false, manager); #endif } } checkAdditionalFacetConstraints(manager); } //end of inspectFacetBase // // Inherit facet from base // a. inherit common facets // b. inherit additional facet // void AbstractStringValidator::inheritFacet() { /*** P3. Inherit facets from base.facets The reason of this inheriting (or copying values) is to ease schema constraint checking, so that we need NOT trace back to our very first base validator in the hierachy. Instead, we are pretty sure checking against immediate base validator is enough. ***/ AbstractStringValidator *pBaseValidator = (AbstractStringValidator*) getBaseValidator(); if (!pBaseValidator) return; int thisFacetsDefined = getFacetsDefined(); int baseFacetsDefined = pBaseValidator->getFacetsDefined(); // inherit length if (((baseFacetsDefined & DatatypeValidator::FACET_LENGTH) != 0) && ((thisFacetsDefined & DatatypeValidator::FACET_LENGTH) == 0)) { setLength(pBaseValidator->getLength()); setFacetsDefined(DatatypeValidator::FACET_LENGTH); } // inherit minLength if (((baseFacetsDefined & DatatypeValidator::FACET_MINLENGTH) !=0) && ((thisFacetsDefined & DatatypeValidator::FACET_MINLENGTH) == 0)) { setMinLength(pBaseValidator->getMinLength()); setFacetsDefined(DatatypeValidator::FACET_MINLENGTH); } // inherit maxLength if (((baseFacetsDefined & DatatypeValidator::FACET_MAXLENGTH) !=0) && ((thisFacetsDefined & DatatypeValidator::FACET_MAXLENGTH) == 0)) { setMaxLength(pBaseValidator->getMaxLength()); setFacetsDefined(DatatypeValidator::FACET_MAXLENGTH); } // inherit enumeration if (((baseFacetsDefined & DatatypeValidator::FACET_ENUMERATION) !=0) && ((thisFacetsDefined & DatatypeValidator::FACET_ENUMERATION) == 0)) { setEnumeration(pBaseValidator->getEnumeration(), true); } // we don't inherit pattern // inherit "fixed" option setFixed(getFixed() | pBaseValidator->getFixed()); // inherit additional facet inheritAdditionalFacet(); } // end of inheritance // ----------------------------------------------------------------------- // Compare methods // ----------------------------------------------------------------------- int AbstractStringValidator::compare(const XMLCh* const lValue , const XMLCh* const rValue , MemoryManager* const) { return XMLString::compareString(lValue, rValue); } void AbstractStringValidator::validate( const XMLCh* const content , ValidationContext* const context , MemoryManager* const manager) { checkContent(content, context, false, manager); } void AbstractStringValidator::checkContent( const XMLCh* const content , ValidationContext* const context , bool asBase , MemoryManager* const manager ) { //validate against base validator if any AbstractStringValidator *pBaseValidator = (AbstractStringValidator*) this->getBaseValidator(); if (pBaseValidator) pBaseValidator->checkContent(content, context, true, manager); int thisFacetsDefined = getFacetsDefined(); // we check pattern first if ( (thisFacetsDefined & DatatypeValidator::FACET_PATTERN ) != 0 ) { if (getRegex()->matches(content, manager) ==false) { ThrowXMLwithMemMgr2(InvalidDatatypeValueException , XMLExcepts::VALUE_NotMatch_Pattern , content , getPattern() , manager); } } // if this is a base validator, we only need to check pattern facet // all other facet were inherited by the derived type if (asBase) return; checkValueSpace(content, manager); XMLSize_t length = getLength(content, manager); if (((thisFacetsDefined & DatatypeValidator::FACET_MAXLENGTH) != 0) && (length > getMaxLength())) { REPORT_VALUE_ERROR(content , length , getMaxLength() , XMLExcepts::VALUE_GT_maxLen , manager) } if (((thisFacetsDefined & DatatypeValidator::FACET_MINLENGTH) != 0) && (length < getMinLength())) { REPORT_VALUE_ERROR(content , length , getMinLength() , XMLExcepts::VALUE_LT_minLen , manager) } if (((thisFacetsDefined & DatatypeValidator::FACET_LENGTH) != 0) && (length != getLength())) { REPORT_VALUE_ERROR(content , length , getLength() , XMLExcepts::VALUE_NE_Len , manager) } if ((thisFacetsDefined & DatatypeValidator::FACET_ENUMERATION) != 0 && (getEnumeration() != 0)) { XMLCh* normContent = XMLString::replicate(content, manager); ArrayJanitor jan(normContent, manager); normalizeContent(normContent, manager); XMLSize_t i=0; XMLSize_t enumLength = getEnumeration()->size(); for ( ; i < enumLength; i++) { if (XMLString::equals(normContent, getEnumeration()->elementAt(i))) break; } if (i == enumLength) ThrowXMLwithMemMgr1(InvalidDatatypeValueException, XMLExcepts::VALUE_NotIn_Enumeration, content, manager); } checkAdditionalFacet(content, manager); } const RefArrayVectorOf* AbstractStringValidator::getEnumString() const { return getEnumeration(); } void AbstractStringValidator::normalizeEnumeration(MemoryManager* const manager) { AbstractStringValidator *pBaseValidator = (AbstractStringValidator*) getBaseValidator(); if (!fEnumeration || !pBaseValidator) return; int baseFacetsDefined = pBaseValidator->getFacetsDefined(); if ((baseFacetsDefined & DatatypeValidator::FACET_WHITESPACE) == 0) return; short whiteSpace = pBaseValidator->getWSFacet(); if ( whiteSpace == DatatypeValidator::PRESERVE ) { return; } else if ( whiteSpace == DatatypeValidator::REPLACE ) { XMLSize_t enumLength = getEnumeration()->size(); for ( XMLSize_t i=0; i < enumLength; i++) { XMLString::replaceWS(getEnumeration()->elementAt(i), manager); } } else if ( whiteSpace == DatatypeValidator::COLLAPSE ) { XMLSize_t enumLength = getEnumeration()->size(); for ( XMLSize_t i=0; i < enumLength; i++) { XMLString::collapseWS(getEnumeration()->elementAt(i), manager); } } } void AbstractStringValidator::normalizeContent(XMLCh* const, MemoryManager* const) const { // default implementation: do nothing return; } void AbstractStringValidator::checkAdditionalFacetConstraints(MemoryManager* const) const { return; } void AbstractStringValidator::checkAdditionalFacet(const XMLCh* const , MemoryManager* const) const { return; } void AbstractStringValidator::inheritAdditionalFacet() { return; } void AbstractStringValidator::assignAdditionalFacet( const XMLCh* const key , const XMLCh* const , MemoryManager* const manager) { ThrowXMLwithMemMgr1(InvalidDatatypeFacetException , XMLExcepts::FACET_Invalid_Tag , key , manager); } XMLSize_t AbstractStringValidator::getLength(const XMLCh* const content , MemoryManager* const) const { return XMLString::stringLen(content); } /*** * Support for Serialization/De-serialization ***/ IMPL_XSERIALIZABLE_NOCREATE(AbstractStringValidator) void AbstractStringValidator::serialize(XSerializeEngine& serEng) { DatatypeValidator::serialize(serEng); if (serEng.isStoring()) { serEng.writeSize (fLength); serEng.writeSize (fMaxLength); serEng.writeSize (fMinLength); serEng< * ***/ XTemplateSerializer::storeObject(fEnumeration, serEng); } else { serEng.readSize (fLength); serEng.readSize (fMaxLength); serEng.readSize (fMinLength); serEng>>fEnumerationInherited; /*** * * Deserialize RefArrayVectorOf * ***/ XTemplateSerializer::loadObject(&fEnumeration, 8, true, serEng); } } XERCES_CPP_NAMESPACE_END /** * End of file AbstractStringValidator.cpp */