source: icXML/icXML-devel/src/icxercesc/validators/common/SimpleContentModel.cpp @ 3153

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

Initial imports for icXML v0.9

File size: 14.9 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: SimpleContentModel.cpp 799211 2009-07-30 09:06:43Z amassari $
11 */
12
13
14// ---------------------------------------------------------------------------
15//  Includes
16// ---------------------------------------------------------------------------
17#include <xercesc/util/RuntimeException.hpp>
18#include <icxercesc/framework/XMLValidator.hpp>
19#include <icxercesc/validators/common/SimpleContentModel.hpp>
20#include <icxercesc/validators/schema/SubstitutionGroupComparator.hpp>
21#include <xercesc/validators/schema/XercesElementWildcard.hpp>
22
23XERCES_CPP_NAMESPACE_BEGIN
24
25// ---------------------------------------------------------------------------
26//  SimpleContentModel: Implementation of the ContentModel virtual interface
27// ---------------------------------------------------------------------------
28//
29//  This method is called to validate our content. For this one, its just a
30//  pretty simple 'bull your way through it' test according to what kind of
31//  operation it is for.
32//
33
34bool
35SimpleContentModel::validateContent
36(
37        #ifdef STORE_CHILDREN_INFORMATION_IN_PARSER
38        XMLElementDecl ** const         children
39        #else
40        QName** const                           children
41        #endif
42        , XMLSize_t                                     childCount
43        , XMLSize_t*                            indexOfFailingChild
44        , MemoryManager*    const       manager
45) const
46{
47        DEBUG_MESSAGE("SimpleContentModel::validateContent");
48
49        //
50        //  According to the type of operation, we do the correct type of
51        //  content check.
52        //
53        XMLSize_t index;
54        switch (fOp & 0x0f)
55        {
56                case ContentSpecNode::Leaf :
57                        //
58                        //  There can only be one child and it has to be of the
59                        //  element type we stored.
60                        //
61                        if (!childCount)
62                        {
63                                *indexOfFailingChild=0;
64                                return false;
65                        }
66
67                        // If the 0th child is not the right kind, report an error at 0
68                        if (fDTD)
69                        {
70                                if (!XMLString::equals(children[0]->getRawName(), fFirstChild->getRawName()))
71                                {
72                                        *indexOfFailingChild=0;
73                                        return false;
74                                }
75                        }
76                        else
77                        {
78                                if ((children[0]->getURI() != fFirstChild->getURI()) || !XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart()))
79                                {
80                                        *indexOfFailingChild=0;
81                                        return false;
82                                }
83                        }
84
85                        if (childCount > 1)
86                        {
87                                *indexOfFailingChild=1;
88                                return false;
89                        }
90                        break;
91
92                case ContentSpecNode::ZeroOrOne :
93                        //
94                        //  If the child count is greater than one, then obviously
95                        //  bad. Otherwise, if its one, then the one child must be
96                        //  of the type we stored.
97                        //
98                        if (childCount == 1)
99                        {
100                                if (fDTD)
101                                {
102                                        if (!XMLString::equals(children[0]->getRawName(), fFirstChild->getRawName()))
103                                        {
104                                                *indexOfFailingChild=0;
105                                                return false;
106                                        }
107                                }
108                                else
109                                {
110                                        if ((children[0]->getURI() != fFirstChild->getURI()) ||
111                                                (!XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart()))) {
112                                                *indexOfFailingChild=0;
113                                                return false;
114                                        }
115                                }
116                        }
117
118                        if (childCount > 1)
119                        {
120                                *indexOfFailingChild=1;
121                                return false;
122                        }
123                        break;
124
125                case ContentSpecNode::ZeroOrMore :
126                        //
127                        //  If the child count is zero, that's fine. If its more than
128                        //  zero, then make sure that all children are of the element
129                        //  type that we stored.
130                        //
131                        if (childCount > 0)
132                        {
133                                if (fDTD)
134                                {
135                                        for (index = 0; index < childCount; index++)
136                                        {
137                                                if (!XMLString::equals(children[index]->getRawName(), fFirstChild->getRawName()))
138                                                {
139                                                        *indexOfFailingChild=index;
140                                                        return false;
141                                                }
142                                        }
143                                }
144                                else
145                                {
146                                        for (index = 0; index < childCount; index++)
147                                        {
148                                                if ((children[index]->getURI() != fFirstChild->getURI()) ||
149                                                        !XMLString::equals(children[index]->getLocalPart(), fFirstChild->getLocalPart())) {
150                                                        *indexOfFailingChild=index;
151                                                        return false;
152                                                }
153                                        }
154                                }
155                        }
156                        break;
157
158                case ContentSpecNode::OneOrMore :
159                        //
160                        //  If the child count is zero, that's an error. If its more
161                        //  than zero, then make sure that all children are of the
162                        //  element type that we stored.
163                        //
164                        if (childCount == 0)
165                        {
166                                *indexOfFailingChild=0;
167                                return false;
168                        }
169
170                        if (fDTD)
171                        {
172                                for (index = 0; index < childCount; index++)
173                                {
174                                        if (!XMLString::equals(children[index]->getRawName(), fFirstChild->getRawName()))
175                                        {
176                                                *indexOfFailingChild=index;
177                                                return false;
178                                        }
179                                }
180                        }
181                        else
182                        {
183                                for (index = 0; index < childCount; index++)
184                                {
185                                        if ((children[index]->getURI() != fFirstChild->getURI()) ||
186                                                !XMLString::equals(children[index]->getLocalPart(), fFirstChild->getLocalPart()))
187                                        {
188                                                *indexOfFailingChild=index;
189                                                return false;
190                                        }
191                                }
192                        }
193                        break;
194
195                case ContentSpecNode::Choice :
196                        //
197                        //  There can only be one child, and it must be one of the
198                        //  two types we stored.
199                        //
200                        if (!childCount)
201                        {
202                                *indexOfFailingChild=0;
203                                return false;
204                        }
205
206                        if (fDTD) {
207                                if (!XMLString::equals(children[0]->getRawName(), fFirstChild->getRawName()) &&
208                                        !XMLString::equals(children[0]->getRawName(), fSecondChild->getRawName())) {
209                                        *indexOfFailingChild=0;
210                                        return false;
211                                }
212                        }
213                        else {
214                                if (((children[0]->getURI() != fFirstChild->getURI()) ||
215                                         !XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart())) &&
216                                        ((children[0]->getURI() != fSecondChild->getURI()) ||
217                                         !XMLString::equals(children[0]->getLocalPart(), fSecondChild->getLocalPart()))) {
218                                         *indexOfFailingChild=0;
219                                         return false;
220                                }
221                        }
222
223                        if (childCount > 1)
224                        {
225                                *indexOfFailingChild=1;
226                                return false;
227                        }
228                        break;
229
230                case ContentSpecNode::Sequence :
231                        //
232                        //  There must be two children and they must be the two values
233                        //  we stored, in the stored order. So first check the obvious
234                        //  problem of an empty content, which would never be valid
235                        //  in this content mode.
236                        //
237                        if (!childCount)
238                        {
239                                *indexOfFailingChild=0;
240                                return false;
241                        }
242
243                        // test first child
244                        if (fDTD)
245                        {
246                                if (!XMLString::equals(children[0]->getRawName(), fFirstChild->getRawName()))
247                                {
248                                        *indexOfFailingChild=0;
249                                        return false;
250                                }
251                        }
252                        else
253                        {
254                                if ((children[0]->getURI() != fFirstChild->getURI()) ||
255                                        !XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart()))
256                                {
257                                        *indexOfFailingChild=0;
258                                        return false;
259                                }
260                        }
261                        // test second child, if present
262                        if (childCount == 1)
263                        {
264                                // missing second child
265                                *indexOfFailingChild=1;
266                                return false;
267                        }
268                        else
269                        {
270                                if (fDTD)
271                                {
272                                        if (!XMLString::equals(children[1]->getRawName(), fSecondChild->getRawName()))
273                                        {
274                                                *indexOfFailingChild=1;
275                                                return false;
276                                        }
277                                }
278                                else
279                                {
280                                        if ((children[1]->getURI() != fSecondChild->getURI()) ||
281                                                !XMLString::equals(children[1]->getLocalPart(), fSecondChild->getLocalPart()))
282                                        {
283                                                *indexOfFailingChild=1;
284                                                return false;
285                                        }
286                                }
287
288                                if (childCount > 2)
289                                {
290                                        *indexOfFailingChild=2;
291                                        return false;
292                                }
293                        }
294                        break;
295
296                default :
297                        ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);
298                        break;
299        }
300        return true;
301}
302
303bool SimpleContentModel::validateContentSpecial
304(
305        #ifdef STORE_CHILDREN_INFORMATION_IN_PARSER
306        XMLElementDecl ** const                 children
307        #else
308        QName** const                                   children
309        #endif
310        , XMLSize_t                                             childCount
311        , GrammarResolver*  const               pGrammarResolver
312        , XMLNamespaceResolver* const   pUriResolver
313        , XMLSize_t*                                    indexOfFailingChild
314        , MemoryManager*    const               manager
315) const
316{
317        SubstitutionGroupComparator comparator(pGrammarResolver, pUriResolver);
318
319        //
320        //  According to the type of operation, we do the correct type of
321        //  content check.
322        //
323        unsigned int index;
324        switch(fOp & 0x0f)
325        {
326                case ContentSpecNode::Leaf :
327
328                        //
329                        //  There can only be one child and it has to be of the
330                        //  element type we stored.
331                        //
332                        if (!childCount)
333                        {
334                                *indexOfFailingChild=0;
335                                return false;
336                        }
337
338                        if ((children[0]->getURI() != fFirstChild->getURI()) ||
339                                !XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart()))
340                        {
341                                if (!comparator.isEquivalentTo(children[0], fFirstChild))
342                                {
343                                        *indexOfFailingChild=0;
344                                        return false;
345                                }
346                        }
347
348                        if (childCount > 1)
349                        {
350                                *indexOfFailingChild=1;
351                                return false;
352                        }
353                        break;
354
355                case ContentSpecNode::ZeroOrOne :
356                        //
357                        //  If the child count is greater than one, then obviously
358                        //  bad. Otherwise, if its one, then the one child must be
359                        //  of the type we stored.
360                        //
361                        if ((childCount == 1) &&
362                           ((children[0]->getURI() != fFirstChild->getURI()) ||
363                                !XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart())))
364                        {
365                                if(!comparator.isEquivalentTo(children[0], fFirstChild))
366                                {
367                                        *indexOfFailingChild=0;
368                                        return false;
369                                }
370                        }
371
372                        if (childCount > 1)
373                        {
374                                *indexOfFailingChild=1;
375                                return false;
376                        }
377                        break;
378
379                case ContentSpecNode::ZeroOrMore :
380                        //
381                        //  If the child count is zero, that's fine. If its more than
382                        //  zero, then make sure that all children are of the element
383                        //  type that we stored.
384                        //
385                        if (childCount > 0)
386                        {
387                                for (index = 0; index < childCount; index++)
388                                {
389                                        if ((children[index]->getURI() != fFirstChild->getURI()) ||
390                                                !XMLString::equals(children[index]->getLocalPart(), fFirstChild->getLocalPart()))
391                                        {
392                                                if (!comparator.isEquivalentTo(children[index], fFirstChild))
393                                                {
394                                                        *indexOfFailingChild=index;
395                                                        return false;
396                                                }
397                                        }
398                                }
399                        }
400                        break;
401
402                case ContentSpecNode::OneOrMore :
403                        //
404                        //  If the child count is zero, that's an error. If its more
405                        //  than zero, then make sure that all children are of the
406                        //  element type that we stored.
407                        //
408                        if (childCount == 0)
409                        {
410                                *indexOfFailingChild=0;
411                                return false;
412                        }
413
414                        for (index = 0; index < childCount; index++)
415                        {
416                                if ((children[index]->getURI() != fFirstChild->getURI()) ||
417                                        !XMLString::equals(children[index]->getLocalPart(), fFirstChild->getLocalPart()))
418                                {
419                                        if (!comparator.isEquivalentTo(children[index], fFirstChild))
420                                        {
421                                                *indexOfFailingChild=index;
422                                                return false;
423                                        }
424                                }
425                        }
426                        break;
427
428                case ContentSpecNode::Choice :
429                        //
430                        //  There can only be one child, and it must be one of the
431                        //  two types we stored.
432                        //
433                        if (!childCount)
434                        {
435                                *indexOfFailingChild=0;
436                                return false;
437                        }
438
439                        if (((children[0]->getURI() != fFirstChild->getURI()) ||
440                                 !XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart())) &&
441                                ((children[0]->getURI() != fSecondChild->getURI()) ||
442                                 !XMLString::equals(children[0]->getLocalPart(), fSecondChild->getLocalPart())))
443                        {
444
445                                 if (!comparator.isEquivalentTo(children[0], fFirstChild) &&
446                                         !comparator.isEquivalentTo(children[0], fSecondChild) )
447                                 {
448                                         *indexOfFailingChild=0;
449                                         return false;
450                                 }
451                        }
452
453                        if (childCount > 1)
454                        {
455                                *indexOfFailingChild=1;
456                                return false;
457                        }
458                        break;
459
460                case ContentSpecNode::Sequence :
461                        //
462                        //  There must be two children and they must be the two values
463                        //  we stored, in the stored order. So first check the obvious
464                        //  problem of an empty content, which would never be valid
465                        //  in this content mode.
466                        //
467                        if (!childCount)
468                        {
469                                *indexOfFailingChild=0;
470                                return false;
471                        }
472
473            DEBUG_GRAMMAR_MESSAGE("children[0]=" << children[0]->getURI() << "," << children[0]->getLocalPart());
474            DEBUG_GRAMMAR_MESSAGE("fFirstChild=" << fFirstChild->getURI() << "," << fFirstChild->getLocalPart());
475
476                        // test first child
477            if ((children[0]->getURI() != fFirstChild->getURI()) || !XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart()))
478                        {
479                if (!comparator.isEquivalentTo(children[0], fFirstChild))
480                                {
481                                        *indexOfFailingChild=0;
482                                        return false;
483                                }
484                        }
485                        // test second child, if present
486                        if( childCount == 1)
487                        {
488                                // missing second child
489                                *indexOfFailingChild=1;
490                                return false;
491                        }
492                        else
493                        {
494                DEBUG_GRAMMAR_MESSAGE("children[1]=" << children[1]->getURI() << "," << children[1]->getLocalPart());
495                DEBUG_GRAMMAR_MESSAGE("fSecondChild=" << fFirstChild->getURI() << "," << fSecondChild->getLocalPart());
496
497                if ((children[1]->getURI() != fSecondChild->getURI()) || !XMLString::equals(children[1]->getLocalPart(), fSecondChild->getLocalPart()))
498                                {
499                                        if (!comparator.isEquivalentTo(children[1], fSecondChild))
500                                        {
501                                                *indexOfFailingChild=1;
502                                                return false;
503                                        }
504                                }
505
506                if (childCount > 2)
507                {
508                                        *indexOfFailingChild=2;
509                                        return false;
510                                }
511                        }
512                        break;
513
514                default :
515                        ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);
516                        break;
517        }
518        return true;
519}
520
521ContentLeafNameTypeVector* SimpleContentModel::getContentLeafNameTypeVector() const
522{
523        return 0;
524}
525
526void SimpleContentModel::checkUniqueParticleAttribution
527(
528        SchemaGrammar*    const                 pGrammar
529        , GrammarResolver*  const               pGrammarResolver
530        , XMLNamespaceResolver* const   pUriResolver
531        , XMLValidator*     const               pValidator
532        , unsigned int*     const               pContentSpecOrgURI
533        , const XMLCh*                                  pComplexTypeName /*= 0*/
534)
535{
536        // rename back
537        unsigned int orgURIIndex = 0;
538
539        orgURIIndex = fFirstChild->getURI();
540        if ((orgURIIndex != XMLContentModel::gEOCFakeId) &&
541                (orgURIIndex != XMLElementDecl::fgInvalidElemId) &&
542                (orgURIIndex != XMLElementDecl::fgPCDataElemId))
543                fFirstChild->setURI(pContentSpecOrgURI[orgURIIndex]);
544
545        orgURIIndex = fSecondChild->getURI();
546        if ((orgURIIndex != XMLContentModel::gEOCFakeId) &&
547                (orgURIIndex != XMLElementDecl::fgInvalidElemId) &&
548                (orgURIIndex != XMLElementDecl::fgPCDataElemId))
549                fSecondChild->setURI(pContentSpecOrgURI[orgURIIndex]);
550
551        // only possible violation is when it's a choice
552        if ((fOp & 0x0f) == ContentSpecNode::Choice)
553        {
554
555                SubstitutionGroupComparator comparator(pGrammarResolver, pUriResolver);
556
557                if (XercesElementWildcard::conflict(pGrammar,
558                                                                                        ContentSpecNode::Leaf,
559                                                                                        fFirstChild,
560                                                                                        ContentSpecNode::Leaf,
561                                                                                        fSecondChild,
562                                                                                        &comparator))
563
564                        pValidator->emitError(XMLValid::UniqueParticleAttributionFail,
565                                                                  pComplexTypeName,
566                                                                  fFirstChild->getRawName(),
567                                                                  fSecondChild->getRawName());
568        }
569}
570
571bool SimpleContentModel::validateContent
572(
573        QName** const
574  , XMLSize_t
575  , unsigned int
576  , XMLSize_t*
577  , MemoryManager*  const
578)
579const
580{
581        DEPRECATED_FEATURE_IN_ICXML;
582}
583
584bool SimpleContentModel::validateContentSpecial
585(
586        QName** const
587  , XMLSize_t
588  , unsigned int
589  , GrammarResolver*  const
590  , XMLStringPool*    const
591  , XMLSize_t*
592  , MemoryManager*    const
593)
594const
595{
596        DEPRECATED_FEATURE_IN_ICXML;
597}
598
599void SimpleContentModel::checkUniqueParticleAttribution
600(
601        SchemaGrammar*    const
602  , GrammarResolver*  const
603  , XMLStringPool*    const
604  , XMLValidator*     const
605  , unsigned int*     const
606  , const XMLCh*
607)
608{
609        DEPRECATED_FEATURE_IN_ICXML;
610}
611
612XERCES_CPP_NAMESPACE_END
613
Note: See TracBrowser for help on using the repository browser.