blob: ee5040d0f6b4930470f3b7893c562ea5e20b28be [file] [log] [blame]
/*
* 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: DateTimeValidator.cpp 568078 2007-08-21 11:43:25Z amassari $
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include <xercesc/validators/datatype/DateTimeValidator.hpp>
#include <xercesc/validators/datatype/InvalidDatatypeFacetException.hpp>
#include <xercesc/validators/datatype/InvalidDatatypeValueException.hpp>
#include <xercesc/validators/schema/SchemaSymbols.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>
XERCES_CPP_NAMESPACE_BEGIN
// ---------------------------------------------------------------------------
// Macro
// ---------------------------------------------------------------------------
#define REPORT_VALUE_ERROR(val1, val2, except_code, manager) \
ThrowXMLwithMemMgr2(InvalidDatatypeValueException \
, except_code \
, val1->getRawData() \
, val2->getRawData() \
, manager);
// ---------------------------------------------------------------------------
// Constructors and Destructor
// ---------------------------------------------------------------------------
DateTimeValidator::~DateTimeValidator()
{
}
DateTimeValidator::DateTimeValidator(
DatatypeValidator* const baseValidator
, RefHashTableOf<KVStringPair>* const facets
, const int finalSet
, const ValidatorType type
, MemoryManager* const manager)
:AbstractNumericFacetValidator(baseValidator, facets, finalSet, type, manager)
{
//do not invoke init() here !!!
}
void DateTimeValidator::validate(const XMLCh* const content
, ValidationContext* const context
, MemoryManager* const manager)
{
checkContent(content, context, false, manager);
}
int DateTimeValidator::compare(const XMLCh* const value1
, const XMLCh* const value2
, MemoryManager* const manager)
{
try
{
XMLDateTime *pDate1 = parse(value1, manager);
Janitor<XMLDateTime> jName1(pDate1);
XMLDateTime *pDate2 = parse(value2, manager);
Janitor<XMLDateTime> jName2(pDate2);
int result = compareDates(pDate1, pDate2, true);
return (result==INDETERMINATE)? -1 : result;
}
catch(const OutOfMemoryException&)
{
throw;
}
catch (...) // RuntimeException e
{
return -1; // revisit after implement compareDates()
}
}
void DateTimeValidator::checkContent(const XMLCh* const content
, ValidationContext* const context
, bool asBase
, MemoryManager* const manager)
{
//validate against base validator if any
DateTimeValidator *pBaseValidator = (DateTimeValidator*) 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;
// the derived classes' parse() method constructs an
// XMLDateTime object anc invokes appropriate XMLDateTime's
// parser to parse the content.
XMLDateTime dateTimeValue(content, manager);
XMLDateTime* dateTime = &dateTimeValue;
parse(dateTime);
// must be < MaxExclusive
if ((thisFacetsDefined & DatatypeValidator::FACET_MAXEXCLUSIVE) != 0)
{
if (compareValues(dateTime, getMaxExclusive()) != XMLDateTime::LESS_THAN)
{
REPORT_VALUE_ERROR( dateTime
, getMaxExclusive()
, XMLExcepts::VALUE_exceed_maxExcl
, manager)
}
}
// must be <= MaxInclusive
if ((thisFacetsDefined & DatatypeValidator::FACET_MAXINCLUSIVE) != 0)
{
int result = compareValues(dateTime, getMaxInclusive());
if ( result == XMLDateTime::GREATER_THAN || result == XMLDateTime::INDETERMINATE )
{
REPORT_VALUE_ERROR( dateTime
, getMaxInclusive()
, XMLExcepts::VALUE_exceed_maxIncl
, manager)
}
}
// must be >= MinInclusive
if ((thisFacetsDefined & DatatypeValidator::FACET_MININCLUSIVE) != 0)
{
int result = compareValues(dateTime, getMinInclusive());
if (result == XMLDateTime::LESS_THAN || result == XMLDateTime::INDETERMINATE)
{
REPORT_VALUE_ERROR( dateTime
, getMinInclusive()
, XMLExcepts::VALUE_exceed_minIncl
, manager)
}
}
// must be > MinExclusive
if ( (thisFacetsDefined & DatatypeValidator::FACET_MINEXCLUSIVE) != 0 )
{
if (compareValues(dateTime, getMinExclusive()) != XMLDateTime::GREATER_THAN)
{
REPORT_VALUE_ERROR( dateTime
, getMinExclusive()
, XMLExcepts::VALUE_exceed_minExcl
, manager)
}
}
if ((thisFacetsDefined & DatatypeValidator::FACET_ENUMERATION) != 0 &&
(getEnumeration() != 0))
{
int i=0;
int enumLength = getEnumeration()->size();
for ( ; i < enumLength; i++)
{
if (compareValues(dateTime, getEnumeration()->elementAt(i)) == XMLDateTime::EQUAL)
break;
}
if (i == enumLength)
ThrowXMLwithMemMgr1(InvalidDatatypeValueException, XMLExcepts::VALUE_NotIn_Enumeration, content, manager);
}
}
//
// Comparision methods
//
int DateTimeValidator::compareValues(const XMLNumber* const lValue
, const XMLNumber* const rValue)
{
return compareDates((XMLDateTime*) lValue, (XMLDateTime*) rValue, true);
}
/**
* Compare algorithm described in dateDime (3.2.7).
* Duration datatype overwrites this method
*
* @param date1 normalized date representation of the first value
* @param date2 normalized date representation of the second value
* @param strict
* @return less, greater, less_equal, greater_equal, equal
*/
int DateTimeValidator::compareDates(const XMLDateTime* const date1
, const XMLDateTime* const date2
, bool)
{
return XMLDateTime::compare(date1, date2);
}
//
// In fact, the proper way of the following set*() shall be
// {
// if (fMaxInclusive)
// delete fMaxInclusive;
//
// fMaxInclusive = parse(value);
//
// }
//
// But we know this function is invoked once and only once
// since there is no duplicated facet passed in, therefore
// fMaxInclusive is alwasy zero before, so for the
// sake of performance, we do not do the checking/delete.
//
void DateTimeValidator::setMaxInclusive(const XMLCh* const value)
{
fMaxInclusive = parse(value, fMemoryManager);
}
void DateTimeValidator::setMaxExclusive(const XMLCh* const value)
{
fMaxExclusive = parse(value, fMemoryManager);
}
void DateTimeValidator::setMinInclusive(const XMLCh* const value)
{
fMinInclusive = parse(value, fMemoryManager);
}
void DateTimeValidator::setMinExclusive(const XMLCh* const value)
{
fMinExclusive = parse(value, fMemoryManager);
}
void DateTimeValidator::setEnumeration(MemoryManager* const)
{
// to do: do we need to check against base value space???
if (!fStrEnumeration)
return;
int enumLength = fStrEnumeration->size();
fEnumeration = new (fMemoryManager) RefVectorOf<XMLNumber>(enumLength, true, fMemoryManager);
fEnumerationInherited = false;
for ( int i = 0; i < enumLength; i++)
fEnumeration->insertElementAt(parse(fStrEnumeration->elementAt(i), fMemoryManager), i);
}
/***
* Support for Serialization/De-serialization
***/
IMPL_XSERIALIZABLE_NOCREATE(DateTimeValidator)
void DateTimeValidator::serialize(XSerializeEngine& serEng)
{
/***
*
* Note: All its derivatives share the same number type, that is
* XMLNumber::DateTime, so this class would write it.
***/
if (serEng.isStoring())
{
serEng<<(int) XMLNumber::DateTime;
}
AbstractNumericFacetValidator::serialize(serEng);
//dateTime can be instantiated during checkContent(), so don't serialize it.
}
XERCES_CPP_NAMESPACE_END
/**
* End of file DateTimeValidator::cpp
*/