source: icXML/icXML-devel/src/icxercesc/validators/datatype/QNameDatatypeValidator.cpp @ 2720

Last change on this file since 2720 was 2720, checked in by cameron, 6 years ago

Initial check-in of icXML 0.8 source files

File size: 7.1 KB
Line 
1/*
2 * Unless required by applicable law or agreed to in writing, software
3 * distributed under the License is distributed on an "AS IS" BASIS,
4 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5 * See the License for the specific language governing permissions and
6 * limitations under the License.
7 */
8
9/*
10 * $Id: QNameDatatypeValidator.cpp 676911 2008-07-15 13:27:32Z amassari $
11 */
12
13// ---------------------------------------------------------------------------
14//  Includes
15// ---------------------------------------------------------------------------
16#include <xercesc/validators/datatype/QNameDatatypeValidator.hpp>
17#include <xercesc/validators/datatype/InvalidDatatypeFacetException.hpp>
18#include <xercesc/validators/datatype/InvalidDatatypeValueException.hpp>
19#include <xercesc/internal/ValidationContextImpl.hpp>
20#include <xercesc/util/XMLChar.hpp>
21
22XERCES_CPP_NAMESPACE_BEGIN
23
24// ---------------------------------------------------------------------------
25//  Constructors and Destructor
26// ---------------------------------------------------------------------------
27QNameDatatypeValidator::QNameDatatypeValidator(MemoryManager* const manager)
28:AbstractStringValidator(0, 0, 0, DatatypeValidator::QName, manager)
29{
30
31}
32
33QNameDatatypeValidator::~QNameDatatypeValidator()
34{
35
36}
37
38QNameDatatypeValidator::QNameDatatypeValidator(
39                                                  DatatypeValidator*            const baseValidator
40                                                , RefHashTableOf<KVStringPair>* const facets
41                                                , RefArrayVectorOf<XMLCh>*      const enums
42                                                , const int                           finalSet
43                                                , MemoryManager* const                manager)
44:AbstractStringValidator(baseValidator, facets, finalSet, DatatypeValidator::QName, manager)
45{
46        init(enums, manager);
47}
48
49DatatypeValidator* QNameDatatypeValidator::newInstance
50(
51          RefHashTableOf<KVStringPair>* const facets
52        , RefArrayVectorOf<XMLCh>* const      enums
53        , const int                           finalSet
54        , MemoryManager* const                manager
55)
56{
57        return (DatatypeValidator*) new (manager) QNameDatatypeValidator(this, facets, enums, finalSet, manager);
58}
59
60// ---------------------------------------------------------------------------
61//  Utilities
62// ---------------------------------------------------------------------------
63
64void QNameDatatypeValidator::checkValueSpace(const XMLCh* const content
65                                                                                         , MemoryManager* const manager)
66{
67        //
68        // check 3.2.18.c0 must: QName
69        //
70
71        if ( !XMLChar1_0::isValidQName(content, XMLString::stringLen(content)) )
72        {
73                ThrowXMLwithMemMgr1(InvalidDatatypeValueException
74                                , XMLExcepts::VALUE_QName_Invalid
75                                , content
76                                , manager);
77        }
78}
79
80void QNameDatatypeValidator::checkContent( const XMLCh*             const content
81                                                                                  ,      ValidationContext* const context
82                                                                                  ,      bool                     asBase
83                                                                                  ,      MemoryManager*     const manager
84                                                                                  )
85{
86        //validate against base validator if any
87        QNameDatatypeValidator *pBaseValidator = (QNameDatatypeValidator*) this->getBaseValidator();
88        if (pBaseValidator)
89                pBaseValidator->checkContent(content, context, true, manager);
90
91        int thisFacetsDefined = getFacetsDefined();
92
93        // we check pattern first
94        if ( (thisFacetsDefined & DatatypeValidator::FACET_PATTERN ) != 0 )
95        {
96                if (getRegex()->matches(content, manager) ==false)
97                {
98                        ThrowXMLwithMemMgr2(InvalidDatatypeValueException
99                                        , XMLExcepts::VALUE_NotMatch_Pattern
100                                        , content
101                                        , getPattern()
102                                        , manager);
103                }
104        }
105
106        // if this is a base validator, we only need to check pattern facet
107        // all other facet were inherited by the derived type
108        if (asBase)
109        {
110                return;
111        }
112
113        checkValueSpace(content, manager);
114
115        int colonPos = 0;
116        XMLCh* prefix = 0;
117        ArrayJanitor<XMLCh>  jan(prefix, manager);
118
119        if (context)
120        {
121                prefix = XMLString::replicate(content, manager);
122                jan.reset(prefix, manager);
123                normalizeContent(prefix, manager);
124                colonPos = XMLString::indexOf(content, chColon);
125
126                if (colonPos > 0)
127                {
128                        prefix[colonPos] = chNull;
129                        if (context->isPrefixUnknown(prefix))
130                        {
131                                ThrowXMLwithMemMgr1(InvalidDatatypeValueException
132                                        , XMLExcepts::VALUE_QName_Invalid2
133                                        , content
134                                        , manager);
135                        }
136                }
137        }
138
139        if ((thisFacetsDefined & DatatypeValidator::FACET_ENUMERATION) != 0 && (getEnumeration() != 0) && context)
140        {
141                XMLCh* localName;
142                if (colonPos > 0)
143                {
144                        localName = prefix + colonPos + 1;
145                }
146                else
147                {
148                        localName = prefix;
149                }
150
151                XMLCh* enumPrefix;
152                XMLCh* enumLocalName;
153                XMLSize_t i=0;
154                XMLSize_t enumLength = getEnumeration()->size();
155                bool foundURIId = false;
156                const XMLCh* normURI = 0;
157                // The +=2 is because the enumeration has prefix:localname as one entry followed
158                // by the URI string for the prefix as the next entry.
159                for ( ; i < enumLength; i+=2)
160                {
161                        enumPrefix = XMLString::replicate(getEnumeration()->elementAt(i), manager);
162                        ArrayJanitor<XMLCh>  janEnum(enumPrefix, manager);
163                        colonPos = XMLString::indexOf(enumPrefix, chColon, 0, manager);
164
165                        if (colonPos != -1)
166                        {
167                                enumLocalName = enumPrefix + colonPos + 1;
168                                enumPrefix[colonPos] = chNull;
169                        }
170                        else
171                        {
172                                enumLocalName = enumPrefix;
173                        }
174
175                        if (XMLString::equals(localName, enumLocalName))
176                        {
177                                if (colonPos < 0)
178                                        break;
179
180                                // now need to see if the prefix URI's are the same
181                                if (!foundURIId)
182                                {
183                                        normURI = context->getURIForPrefix(prefix);
184                                        foundURIId = true;
185                                }
186                                if (XMLString::equals(normURI, getEnumeration()->elementAt(i + 1)))
187                                {
188                                        break;
189                                }
190                        }
191                }
192
193                if (i == enumLength)
194                {
195                        ThrowXMLwithMemMgr1(InvalidDatatypeValueException, XMLExcepts::VALUE_NotIn_Enumeration, content, manager);
196                }
197        }
198        checkAdditionalFacet(content, manager);
199}
200
201//
202//  Check vs base
203//         check common facets
204//         check enumeration
205//         check Additional Facet Constraint
206//
207void QNameDatatypeValidator::inspectFacetBase(MemoryManager* const manager)
208{
209
210        QNameDatatypeValidator *pBaseValidator = (QNameDatatypeValidator*) getBaseValidator();
211        int thisFacetsDefined = getFacetsDefined();
212
213        if ( (!thisFacetsDefined && !getEnumeration()) ||
214                 (!pBaseValidator)                      )
215                return;
216
217        // check 4.3.5.c0 must: enumeration values from the value space of base
218        if ( ((thisFacetsDefined & DatatypeValidator::FACET_ENUMERATION) != 0) &&
219                (getEnumeration() !=0))
220        {
221                XMLSize_t i = 0;
222                XMLSize_t enumLength = getEnumeration()->size();
223                // The +=2 is because the enumeration has prefix:localname as one entry followed
224                // by the URI string for the prefix as the next entry.
225                for ( ; i < enumLength; i+=2)
226                {
227                        // ask parent do a complete check
228                        pBaseValidator->checkContent(getEnumeration()->elementAt(i), (ValidationContext*)0, false, manager);
229#if 0
230// spec says that only base has to checkContent
231                        // enum shall pass this->checkContent() as well.
232                        checkContent(getEnumeration()->elementAt(i), (ValidationContext*)0, false, manager);
233#endif
234                }
235        }
236
237        checkAdditionalFacetConstraints(manager);
238
239} //end of inspectFacetBase
240
241/***
242 * Support for Serialization/De-serialization
243 ***/
244
245IMPL_XSERIALIZABLE_TOCREATE(QNameDatatypeValidator)
246
247void QNameDatatypeValidator::serialize(XSerializeEngine& serEng)
248{
249        AbstractStringValidator::serialize(serEng);
250}
251
252XERCES_CPP_NAMESPACE_END
253
254/**
255  * End of file QNameDatatypeValidator.cpp
256  */
Note: See TracBrowser for help on using the repository browser.