GME  13
DoubleDatatypeValidator.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: DoubleDatatypeValidator.cpp 676911 2008-07-15 13:27:32Z amassari $
00020  */
00021 
00022 // ---------------------------------------------------------------------------
00023 //  Includes
00024 // ---------------------------------------------------------------------------
00025 #include <xercesc/validators/datatype/DoubleDatatypeValidator.hpp>
00026 #include <xercesc/validators/datatype/InvalidDatatypeFacetException.hpp>
00027 #include <xercesc/validators/datatype/InvalidDatatypeValueException.hpp>
00028 
00029 XERCES_CPP_NAMESPACE_BEGIN
00030 
00031 // ---------------------------------------------------------------------------
00032 //  Constructors and Destructor
00033 // ---------------------------------------------------------------------------
00034 DoubleDatatypeValidator::DoubleDatatypeValidator(MemoryManager* const manager)
00035 :AbstractNumericValidator(0, 0, 0, DatatypeValidator::Double, manager)
00036 {
00037     setOrdered(XSSimpleTypeDefinition::ORDERED_PARTIAL);
00038     setBounded(true);
00039     setFinite(true);
00040     setNumeric(true);
00041 }
00042 
00043 DoubleDatatypeValidator::DoubleDatatypeValidator(
00044                           DatatypeValidator*            const baseValidator
00045                         , RefHashTableOf<KVStringPair>* const facets
00046                         , RefArrayVectorOf<XMLCh>*      const enums
00047                         , const int                           finalSet
00048                         , MemoryManager* const                manager)
00049 :AbstractNumericValidator(baseValidator, facets, finalSet, DatatypeValidator::Double, manager)
00050 {
00051     init(enums, manager);
00052 }
00053 
00054 DoubleDatatypeValidator::~DoubleDatatypeValidator()
00055 {}
00056 
00057 // -----------------------------------------------------------------------
00058 // Compare methods
00059 // -----------------------------------------------------------------------
00060 int DoubleDatatypeValidator::compare(const XMLCh* const lValue
00061                                    , const XMLCh* const rValue
00062                                    , MemoryManager* const manager)
00063 {
00064     XMLDouble lObj(lValue, manager);
00065     XMLDouble rObj(rValue, manager);
00066 
00067     return compareValues(&lObj, &rObj);
00068 }
00069 
00070 DatatypeValidator* DoubleDatatypeValidator::newInstance
00071 (
00072       RefHashTableOf<KVStringPair>* const facets
00073     , RefArrayVectorOf<XMLCh>* const      enums
00074     , const int                           finalSet
00075     , MemoryManager* const                manager
00076 )
00077 {
00078     return (DatatypeValidator*) new (manager) DoubleDatatypeValidator(this, facets, enums, finalSet, manager);
00079 }
00080 
00081 // -----------------------------------------------------------------------
00082 // ctor provided to be used by derived classes
00083 // -----------------------------------------------------------------------
00084 DoubleDatatypeValidator::DoubleDatatypeValidator(DatatypeValidator*            const baseValidator
00085                                                , RefHashTableOf<KVStringPair>* const facets
00086                                                , const int                           finalSet
00087                                                , const ValidatorType                 type
00088                                                , MemoryManager* const                manager)
00089 :AbstractNumericValidator(baseValidator, facets, finalSet, type, manager)
00090 {
00091     //do not invoke init here !!!
00092 }
00093 
00094 int  DoubleDatatypeValidator::compareValues(const XMLNumber* const lValue
00095                                           , const XMLNumber* const rValue)
00096 {
00097     return XMLDouble::compareValues((XMLDouble*) lValue, (XMLDouble*) rValue);
00098 }
00099 
00100 void  DoubleDatatypeValidator::setMaxInclusive(const XMLCh* const value)
00101 {
00102     fMaxInclusive = new (fMemoryManager) XMLDouble(value, fMemoryManager);
00103 }
00104 
00105 void  DoubleDatatypeValidator::setMaxExclusive(const XMLCh* const value)
00106 {
00107     fMaxExclusive = new (fMemoryManager) XMLDouble(value, fMemoryManager);
00108 }
00109 
00110 void  DoubleDatatypeValidator::setMinInclusive(const XMLCh* const value)
00111 {
00112     fMinInclusive = new (fMemoryManager) XMLDouble(value, fMemoryManager);
00113 }
00114 
00115 void  DoubleDatatypeValidator::setMinExclusive(const XMLCh* const value)
00116 {
00117     fMinExclusive = new (fMemoryManager) XMLDouble(value, fMemoryManager);
00118 }
00119 
00120 void  DoubleDatatypeValidator::setEnumeration(MemoryManager* const manager)
00121 {
00122     // check 4.3.5.c0 must: enumeration values from the value space of base
00123     //
00124     // 1. shall be from base value space
00125     // 2. shall be from current value space as well ( shall go through boundsCheck() )
00126     //
00127     if (!fStrEnumeration)
00128         return;
00129 
00130     XMLSize_t i = 0;
00131     XMLSize_t enumLength = fStrEnumeration->size();
00132 
00133     DoubleDatatypeValidator *numBase = (DoubleDatatypeValidator*) getBaseValidator();
00134     if (numBase)
00135     {
00136         try
00137         {
00138             for ( i = 0; i < enumLength; i++)
00139             {
00140                 numBase->checkContent(fStrEnumeration->elementAt(i), (ValidationContext*)0, false, manager);
00141             }
00142         }
00143         catch (XMLException&)
00144         {
00145             ThrowXMLwithMemMgr1(InvalidDatatypeFacetException
00146                     , XMLExcepts::FACET_enum_base
00147                     , fStrEnumeration->elementAt(i)
00148                     , manager);
00149 
00150         }
00151     }
00152 
00153 #if 0
00154 // spec says that only base has to checkContent          
00155     // We put the this->checkContent in a separate loop
00156     // to not block original message with in that method.
00157     //
00158     for ( i = 0; i < enumLength; i++)
00159     {
00160         checkContent(fStrEnumeration->elementAt(i), (ValidationContext*)0, false, manager);
00161     }
00162 #endif
00163 
00164     fEnumeration = new (manager) RefVectorOf<XMLNumber>(enumLength, true, manager);
00165     fEnumerationInherited = false;
00166 
00167     for ( i = 0; i < enumLength; i++)
00168     {
00169         fEnumeration->insertElementAt(new (manager) XMLDouble(fStrEnumeration->elementAt(i), manager), i);
00170     }
00171 }
00172 
00173 // -----------------------------------------------------------------------
00174 // Abstract interface from AbstractNumericValidator
00175 // -----------------------------------------------------------------------
00176 
00177 void DoubleDatatypeValidator::checkContent(const XMLCh*             const content
00178                                           ,      ValidationContext* const context
00179                                           ,      bool                     asBase
00180                                           ,      MemoryManager*     const manager)
00181 {
00182 
00183     //validate against base validator if any
00184     DoubleDatatypeValidator *pBase = (DoubleDatatypeValidator*) this->getBaseValidator();
00185     if (pBase)
00186         pBase->checkContent(content, context, true, manager);
00187 
00188     // we check pattern first
00189     if ( (getFacetsDefined() & DatatypeValidator::FACET_PATTERN ) != 0 )
00190     {
00191         if (getRegex()->matches(content, manager) ==false)
00192         {
00193             ThrowXMLwithMemMgr2(InvalidDatatypeValueException
00194                     , XMLExcepts::VALUE_NotMatch_Pattern
00195                     , content
00196                     , getPattern()
00197                     , manager);
00198         }
00199     }
00200 
00201     // if this is a base validator, we only need to check pattern facet
00202     // all other facet were inherited by the derived type
00203     if (asBase)
00204         return;
00205 
00206     XMLDouble theValue(content, manager);
00207     XMLDouble *theData = &theValue;
00208 
00209     if (getEnumeration())
00210     {
00211         XMLSize_t i=0;
00212         XMLSize_t enumLength = getEnumeration()->size();
00213         for ( ; i < enumLength; i++)
00214         {
00215             if (compareValues(theData, (XMLDouble*) getEnumeration()->elementAt(i)) ==0 )
00216                 break;
00217         }
00218 
00219         if (i == enumLength)
00220             ThrowXMLwithMemMgr1(InvalidDatatypeValueException, XMLExcepts::VALUE_NotIn_Enumeration, content, manager);
00221     }
00222 
00223     boundsCheck(theData, manager);
00224 }
00225 
00226 /***
00227  * Support for Serialization/De-serialization
00228  ***/
00229 
00230 IMPL_XSERIALIZABLE_TOCREATE(DoubleDatatypeValidator)
00231 
00232 void DoubleDatatypeValidator::serialize(XSerializeEngine& serEng)
00233 {
00234     /***
00235      * Note: 
00236      *
00237      *     During storing, we need write the specific number
00238      *     type info before calling base::serialize().
00239      *
00240      *     While loading, we do nothing here
00241      ***/
00242 
00243     if (serEng.isStoring())
00244     {
00245         serEng<<(int) (XMLNumber::Double);
00246     }
00247 
00248     AbstractNumericValidator::serialize(serEng);
00249 
00250 }
00251 
00252 XERCES_CPP_NAMESPACE_END
00253