GME  13
DateTimeValidator.cpp
Go to the documentation of this file.
00001 /*
00002  * Licensed to the Apache Software Foundation (ASF) under one or more
00003  * contributor license agreements.  See the NOTICE file distributed with
00004  * this work for additional information regarding copyright ownership.
00005  * The ASF licenses this file to You under the Apache License, Version 2.0
00006  * (the "License"); you may not use this file except in compliance with
00007  * the License.  You may obtain a copy of the License at
00008  * 
00009  *      http://www.apache.org/licenses/LICENSE-2.0
00010  * 
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 /*
00019  * $Id: DateTimeValidator.cpp 676911 2008-07-15 13:27:32Z amassari $
00020  */
00021 
00022 // ---------------------------------------------------------------------------
00023 //  Includes
00024 // ---------------------------------------------------------------------------
00025 #include <xercesc/validators/datatype/DateTimeValidator.hpp>
00026 #include <xercesc/validators/datatype/InvalidDatatypeFacetException.hpp>
00027 #include <xercesc/validators/datatype/InvalidDatatypeValueException.hpp>
00028 #include <xercesc/validators/schema/SchemaSymbols.hpp>
00029 #include <xercesc/util/OutOfMemoryException.hpp>
00030 
00031 XERCES_CPP_NAMESPACE_BEGIN
00032 
00033 // ---------------------------------------------------------------------------
00034 //  Macro
00035 // ---------------------------------------------------------------------------
00036 #define  REPORT_VALUE_ERROR(val1, val2, except_code, manager)    \
00037   ThrowXMLwithMemMgr2(InvalidDatatypeValueException               \
00038           , except_code                                 \
00039           , val1->getRawData()                          \
00040           , val2->getRawData()                          \
00041           , manager);
00042 
00043 // ---------------------------------------------------------------------------
00044 //  Constructors and Destructor
00045 // ---------------------------------------------------------------------------
00046 DateTimeValidator::~DateTimeValidator()
00047 {
00048 }
00049 
00050 DateTimeValidator::DateTimeValidator(
00051                           DatatypeValidator*            const baseValidator
00052                         , RefHashTableOf<KVStringPair>* const facets
00053                         , const int                           finalSet
00054                         , const ValidatorType                 type
00055                         , MemoryManager* const                manager)
00056 :AbstractNumericFacetValidator(baseValidator, facets, finalSet, type, manager)
00057 {
00058     //do not invoke init() here !!!
00059 }
00060 
00061 void DateTimeValidator::validate(const XMLCh*             const content
00062                                ,       ValidationContext* const context
00063                                ,       MemoryManager*     const manager)
00064 {
00065     checkContent(content, context, false, manager);
00066 }
00067 
00068 int DateTimeValidator::compare(const XMLCh* const value1
00069                              , const XMLCh* const value2
00070                              , MemoryManager* const manager)
00071 {
00072     try
00073     {
00074         XMLDateTime *pDate1 = parse(value1, manager);
00075         Janitor<XMLDateTime> jName1(pDate1);
00076         XMLDateTime *pDate2 = parse(value2, manager);
00077         Janitor<XMLDateTime> jName2(pDate2);
00078         int result = compareDates(pDate1, pDate2, true);
00079         return (result==INDETERMINATE)? -1 : result;
00080     }
00081     catch(const OutOfMemoryException&)
00082     {
00083         throw;
00084     }
00085     catch (...) // RuntimeException e
00086     {
00087         return -1; // revisit after implement compareDates()
00088     }
00089 
00090 }
00091 
00092 
00093 void DateTimeValidator::checkContent(const XMLCh*             const content
00094                                    ,       ValidationContext* const context
00095                                    ,       bool                     asBase
00096                                    ,       MemoryManager*     const manager)
00097 {
00098     //validate against base validator if any
00099     DateTimeValidator *pBaseValidator = (DateTimeValidator*) this->getBaseValidator();
00100     if (pBaseValidator)
00101         pBaseValidator->checkContent(content, context, true, manager);
00102 
00103     int thisFacetsDefined = getFacetsDefined();
00104 
00105     // we check pattern first
00106     if ( (thisFacetsDefined & DatatypeValidator::FACET_PATTERN ) != 0 )
00107     {
00108         if (getRegex()->matches(content, manager) ==false)
00109         {
00110             ThrowXMLwithMemMgr2(InvalidDatatypeValueException
00111                     , XMLExcepts::VALUE_NotMatch_Pattern
00112                     , content
00113                     , getPattern()
00114                     , manager);
00115         }
00116     }
00117 
00118     // if this is a base validator, we only need to check pattern facet
00119     // all other facet were inherited by the derived type
00120     if (asBase)
00121         return;
00122 
00123     // the derived classes' parse() method constructs an
00124     // XMLDateTime object anc invokes appropriate XMLDateTime's
00125     // parser to parse the content.
00126     XMLDateTime dateTimeValue(content, manager);
00127     XMLDateTime* dateTime = &dateTimeValue;
00128     
00129     parse(dateTime);
00130 
00131     // must be < MaxExclusive
00132     if ((thisFacetsDefined & DatatypeValidator::FACET_MAXEXCLUSIVE) != 0)
00133     {
00134         if (compareValues(dateTime, getMaxExclusive()) != XMLDateTime::LESS_THAN)
00135         {
00136             REPORT_VALUE_ERROR( dateTime
00137                               , getMaxExclusive()
00138                               , XMLExcepts::VALUE_exceed_maxExcl
00139                               , manager)
00140         }
00141     }   
00142 
00143     // must be <= MaxInclusive
00144     if ((thisFacetsDefined & DatatypeValidator::FACET_MAXINCLUSIVE) != 0)
00145     {
00146         int result = compareValues(dateTime, getMaxInclusive());
00147         if ( result == XMLDateTime::GREATER_THAN || result == XMLDateTime::INDETERMINATE )
00148         {
00149             REPORT_VALUE_ERROR( dateTime
00150                               , getMaxInclusive()
00151                               , XMLExcepts::VALUE_exceed_maxIncl
00152                               , manager)
00153         }
00154     }
00155 
00156     // must be >= MinInclusive
00157     if ((thisFacetsDefined & DatatypeValidator::FACET_MININCLUSIVE) != 0)
00158     {
00159         int result = compareValues(dateTime, getMinInclusive());
00160         if (result == XMLDateTime::LESS_THAN || result == XMLDateTime::INDETERMINATE)
00161         {
00162             REPORT_VALUE_ERROR( dateTime
00163                               , getMinInclusive()
00164                               , XMLExcepts::VALUE_exceed_minIncl
00165                               , manager)
00166         }
00167     }
00168 
00169     // must be > MinExclusive
00170     if ( (thisFacetsDefined & DatatypeValidator::FACET_MINEXCLUSIVE) != 0 )
00171     {
00172         if (compareValues(dateTime, getMinExclusive()) != XMLDateTime::GREATER_THAN)
00173         {
00174             REPORT_VALUE_ERROR( dateTime
00175                               , getMinExclusive()
00176                               , XMLExcepts::VALUE_exceed_minExcl
00177                               , manager)
00178         }
00179     }
00180 
00181     if ((thisFacetsDefined & DatatypeValidator::FACET_ENUMERATION) != 0 &&
00182         (getEnumeration() != 0))
00183     {
00184         XMLSize_t i=0;
00185         XMLSize_t enumLength = getEnumeration()->size();
00186         for ( ; i < enumLength; i++)
00187         {
00188             if (compareValues(dateTime, getEnumeration()->elementAt(i)) == XMLDateTime::EQUAL)
00189                 break;
00190         }
00191 
00192         if (i == enumLength)
00193             ThrowXMLwithMemMgr1(InvalidDatatypeValueException, XMLExcepts::VALUE_NotIn_Enumeration, content, manager);
00194     }
00195 }
00196 
00197 //
00198 // Comparision methods
00199 //
00200 int DateTimeValidator::compareValues(const XMLNumber* const lValue
00201                                    , const XMLNumber* const rValue)
00202 {
00203     return compareDates((XMLDateTime*) lValue, (XMLDateTime*) rValue, true);
00204 }
00205 
00215 int DateTimeValidator::compareDates(const XMLDateTime* const date1
00216                                   , const XMLDateTime* const date2
00217                                   , bool)
00218 {
00219     return XMLDateTime::compare(date1, date2);
00220 }
00221 
00222 //
00223 // In fact, the proper way of the following set*() shall be
00224 // {
00225 // if (fMaxInclusive)
00226 //     delete fMaxInclusive;
00227 //
00228 //    fMaxInclusive = parse(value);
00229 //
00230 // }
00231 //
00232 // But we know this function is invoked once and only once
00233 // since there is no duplicated facet passed in, therefore
00234 // fMaxInclusive is alwasy zero before, so for the
00235 // sake of performance, we do not do the checking/delete.
00236 //
00237 
00238 void DateTimeValidator::setMaxInclusive(const XMLCh* const value)
00239 {
00240     fMaxInclusive = parse(value, fMemoryManager);
00241 }
00242 
00243 void DateTimeValidator::setMaxExclusive(const XMLCh* const value)
00244 {
00245     fMaxExclusive = parse(value, fMemoryManager);
00246 }
00247 
00248 void DateTimeValidator::setMinInclusive(const XMLCh* const value)
00249 {
00250     fMinInclusive = parse(value, fMemoryManager);
00251 }
00252 
00253 void DateTimeValidator::setMinExclusive(const XMLCh* const value)
00254 {
00255     fMinExclusive = parse(value, fMemoryManager);
00256 }
00257 
00258 void DateTimeValidator::setEnumeration(MemoryManager* const)
00259 {
00260 // to do: do we need to check against base value space???
00261 
00262     if (!fStrEnumeration)
00263         return;
00264 
00265     XMLSize_t enumLength = fStrEnumeration->size();
00266     fEnumeration = new (fMemoryManager) RefVectorOf<XMLNumber>(enumLength, true, fMemoryManager);
00267     fEnumerationInherited = false;
00268 
00269     for ( XMLSize_t i = 0; i < enumLength; i++)
00270         fEnumeration->insertElementAt(parse(fStrEnumeration->elementAt(i), fMemoryManager), i);
00271 
00272 }
00273 
00274 /***
00275  * Support for Serialization/De-serialization
00276  ***/
00277 
00278 IMPL_XSERIALIZABLE_NOCREATE(DateTimeValidator)
00279 
00280 void DateTimeValidator::serialize(XSerializeEngine& serEng)
00281 {
00282     /***
00283      *
00284      * Note: All its derivatives share the same number type, that is
00285      *       XMLNumber::DateTime, so this class would write it.
00286      ***/
00287 
00288     if (serEng.isStoring())
00289     {
00290         serEng<<(int) XMLNumber::DateTime;
00291     }
00292 
00293     AbstractNumericFacetValidator::serialize(serEng);
00294 
00295     //dateTime can be instantiated during checkContent(), so don't serialize it.
00296 }
00297 
00298 XERCES_CPP_NAMESPACE_END
00299