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

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

More paths and missing files.

File size: 14.4 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                        //  There can only be one child and it has to be of the
329                        //  element type we stored.
330                        //
331                        if (!childCount)
332                        {
333                                *indexOfFailingChild=0;
334                                return false;
335                        }
336
337                        if ((children[0]->getURI() != fFirstChild->getURI()) ||
338                                !XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart()))
339                        {
340                                if (!comparator.isEquivalentTo(children[0], fFirstChild))
341                                {
342                                        *indexOfFailingChild=0;
343                                        return false;
344                                }
345                        }
346
347                        if (childCount > 1)
348                        {
349                                *indexOfFailingChild=1;
350                                return false;
351                        }
352                        break;
353
354                case ContentSpecNode::ZeroOrOne :
355                        //
356                        //  If the child count is greater than one, then obviously
357                        //  bad. Otherwise, if its one, then the one child must be
358                        //  of the type we stored.
359                        //
360                        if ((childCount == 1) &&
361                           ((children[0]->getURI() != fFirstChild->getURI()) ||
362                                !XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart())))
363                        {
364                                if(!comparator.isEquivalentTo(children[0], fFirstChild))
365                                {
366                                        *indexOfFailingChild=0;
367                                        return false;
368                                }
369                        }
370
371                        if (childCount > 1)
372                        {
373                                *indexOfFailingChild=1;
374                                return false;
375                        }
376                        break;
377
378                case ContentSpecNode::ZeroOrMore :
379                        //
380                        //  If the child count is zero, that's fine. If its more than
381                        //  zero, then make sure that all children are of the element
382                        //  type that we stored.
383                        //
384                        if (childCount > 0)
385                        {
386                                for (index = 0; index < childCount; index++)
387                                {
388                                        if ((children[index]->getURI() != fFirstChild->getURI()) ||
389                                                !XMLString::equals(children[index]->getLocalPart(), fFirstChild->getLocalPart()))
390                                        {
391                                                if (!comparator.isEquivalentTo(children[index], fFirstChild))
392                                                {
393                                                        *indexOfFailingChild=index;
394                                                        return false;
395                                                }
396                                        }
397                                }
398                        }
399                        break;
400
401                case ContentSpecNode::OneOrMore :
402                        //
403                        //  If the child count is zero, that's an error. If its more
404                        //  than zero, then make sure that all children are of the
405                        //  element type that we stored.
406                        //
407                        if (childCount == 0)
408                        {
409                                *indexOfFailingChild=0;
410                                return false;
411                        }
412
413                        for (index = 0; index < childCount; index++)
414                        {
415                                if ((children[index]->getURI() != fFirstChild->getURI()) ||
416                                        !XMLString::equals(children[index]->getLocalPart(), fFirstChild->getLocalPart()))
417                                {
418                                        if (!comparator.isEquivalentTo(children[index], fFirstChild))
419                                        {
420                                                *indexOfFailingChild=index;
421                                                return false;
422                                        }
423                                }
424                        }
425                        break;
426
427                case ContentSpecNode::Choice :
428                        //
429                        //  There can only be one child, and it must be one of the
430                        //  two types we stored.
431                        //
432                        if (!childCount)
433                        {
434                                *indexOfFailingChild=0;
435                                return false;
436                        }
437
438                        if (((children[0]->getURI() != fFirstChild->getURI()) ||
439                                 !XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart())) &&
440                                ((children[0]->getURI() != fSecondChild->getURI()) ||
441                                 !XMLString::equals(children[0]->getLocalPart(), fSecondChild->getLocalPart())))
442                        {
443
444                                 if (!comparator.isEquivalentTo(children[0], fFirstChild) &&
445                                         !comparator.isEquivalentTo(children[0], fSecondChild) )
446                                 {
447                                         *indexOfFailingChild=0;
448                                         return false;
449                                 }
450                        }
451
452                        if (childCount > 1)
453                        {
454                                *indexOfFailingChild=1;
455                                return false;
456                        }
457                        break;
458
459                case ContentSpecNode::Sequence :
460                        //
461                        //  There must be two children and they must be the two values
462                        //  we stored, in the stored order. So first check the obvious
463                        //  problem of an empty content, which would never be valid
464                        //  in this content mode.
465                        //
466                        if (!childCount)
467                        {
468                                *indexOfFailingChild=0;
469                                return false;
470                        }
471
472                        // test first child
473                        if ((children[0]->getURI() != fFirstChild->getURI()) ||
474                                !XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart()))
475                        {
476                                if(!comparator.isEquivalentTo(children[0], fFirstChild))
477                                {
478                                        *indexOfFailingChild=0;
479                                        return false;
480                                }
481                        }
482                        // test second child, if present
483                        if( childCount == 1)
484                        {
485                                // missing second child
486                                *indexOfFailingChild=1;
487                                return false;
488                        }
489                        else
490                        {
491                                if ((children[1]->getURI() != fSecondChild->getURI()) ||
492                                        !XMLString::equals(children[1]->getLocalPart(), fSecondChild->getLocalPart()))
493                                {
494                                        if (!comparator.isEquivalentTo(children[1], fSecondChild))
495                                        {
496                                                *indexOfFailingChild=1;
497                                                return false;
498                                        }
499                                }
500
501                                if (childCount > 2) {
502                                        *indexOfFailingChild=2;
503                                        return false;
504                                }
505
506                        }
507                        break;
508
509                default :
510                        ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);
511                        break;
512        }
513        return true;
514}
515
516ContentLeafNameTypeVector* SimpleContentModel::getContentLeafNameTypeVector() const
517{
518        return 0;
519}
520
521void SimpleContentModel::checkUniqueParticleAttribution
522(
523        SchemaGrammar*    const                 pGrammar
524        , GrammarResolver*  const               pGrammarResolver
525        , XMLNamespaceResolver* const   pUriResolver
526        , XMLValidator*     const               pValidator
527        , unsigned int*     const               pContentSpecOrgURI
528        , const XMLCh*                                  pComplexTypeName /*= 0*/
529)
530{
531        // rename back
532        unsigned int orgURIIndex = 0;
533
534        orgURIIndex = fFirstChild->getURI();
535        if ((orgURIIndex != XMLContentModel::gEOCFakeId) &&
536                (orgURIIndex != XMLElementDecl::fgInvalidElemId) &&
537                (orgURIIndex != XMLElementDecl::fgPCDataElemId))
538                fFirstChild->setURI(pContentSpecOrgURI[orgURIIndex]);
539
540        orgURIIndex = fSecondChild->getURI();
541        if ((orgURIIndex != XMLContentModel::gEOCFakeId) &&
542                (orgURIIndex != XMLElementDecl::fgInvalidElemId) &&
543                (orgURIIndex != XMLElementDecl::fgPCDataElemId))
544                fSecondChild->setURI(pContentSpecOrgURI[orgURIIndex]);
545
546        // only possible violation is when it's a choice
547        if ((fOp & 0x0f) == ContentSpecNode::Choice)
548        {
549
550                SubstitutionGroupComparator comparator(pGrammarResolver, pUriResolver);
551
552                if (XercesElementWildcard::conflict(pGrammar,
553                                                                                        ContentSpecNode::Leaf,
554                                                                                        fFirstChild,
555                                                                                        ContentSpecNode::Leaf,
556                                                                                        fSecondChild,
557                                                                                        &comparator))
558
559                        pValidator->emitError(XMLValid::UniqueParticleAttributionFail,
560                                                                  pComplexTypeName,
561                                                                  fFirstChild->getRawName(),
562                                                                  fSecondChild->getRawName());
563        }
564}
565
566bool SimpleContentModel::validateContent
567(
568        QName** const
569  , XMLSize_t
570  , unsigned int
571  , XMLSize_t*
572  , MemoryManager*  const
573)
574const
575{
576        DEPRECATED_FEATURE_IN_ICXML;
577}
578
579bool SimpleContentModel::validateContentSpecial
580(
581        QName** const
582  , XMLSize_t
583  , unsigned int
584  , GrammarResolver*  const
585  , XMLStringPool*    const
586  , XMLSize_t*
587  , MemoryManager*    const
588)
589const
590{
591        DEPRECATED_FEATURE_IN_ICXML;
592}
593
594void SimpleContentModel::checkUniqueParticleAttribution
595(
596        SchemaGrammar*    const
597  , GrammarResolver*  const
598  , XMLStringPool*    const
599  , XMLValidator*     const
600  , unsigned int*     const
601  , const XMLCh*
602)
603{
604        DEPRECATED_FEATURE_IN_ICXML;
605}
606
607XERCES_CPP_NAMESPACE_END
608
Note: See TracBrowser for help on using the repository browser.