Qt 4.8
qxsdschemachecker_helper.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
43 
44 using namespace QPatternist;
45 
47 {
48  const int length = list.count();
49 
50  for (int i = 0; i < length; ++i) {
51  for (int j = 0; j < length; ++j) {
52  if (i == j)
53  continue;
54 
55  if (list.at(i)->attribute()->name(m_namePool) == list.at(j)->attribute()->name(m_namePool)) {
56  conflictingAttribute = list.at(i)->attribute();
57  return true;
58  }
59  }
60  }
61 
62  return false;
63 }
64 
66 {
67  const int length = list.count();
68 
69  bool hasIdDerivedAttribute = false;
70  for (int i = 0; i < length; ++i) {
71  if (BuiltinTypes::xsID->wxsTypeMatches(list.at(i)->attribute()->type())) {
72  if (hasIdDerivedAttribute)
73  return true;
74  else
75  hasIdDerivedAttribute = true;
76  }
77  }
78 
79  return false;
80 }
81 
83 {
84  const int length = list.count();
85 
86  for (int i = 0; i < length; ++i) {
87  const XsdAttributeUse::Ptr attributeUse(list.at(i));
88  if (BuiltinTypes::xsID->wxsTypeMatches(attributeUse->attribute()->type())) {
89  if (attributeUse->valueConstraint()) {
90  conflictingAttribute = attributeUse->attribute();
91  return true;
92  }
93  }
94  }
95 
96  return false;
97 }
98 
99 bool XsdSchemaChecker::particleEqualsRecursively(const XsdParticle::Ptr &particle, const XsdParticle::Ptr &otherParticle) const
100 {
101  // @see http://www.w3.org/TR/xmlschema11-1/#cos-particle-extend
102  //TODO: find out what 'properties' of a particle should be checked here...
103 
104  if (particle->minimumOccurs() != otherParticle->minimumOccurs())
105  return false;
106 
107  if (particle->maximumOccursUnbounded() != otherParticle->maximumOccursUnbounded())
108  return false;
109 
110  if (particle->maximumOccurs() != otherParticle->maximumOccurs())
111  return false;
112 
113  const XsdTerm::Ptr term = particle->term();
114  const XsdTerm::Ptr otherTerm = otherParticle->term();
115 
116  if (term->isElement() && !(otherTerm->isElement()))
117  return false;
118 
119  if (term->isModelGroup() && !(otherTerm->isModelGroup()))
120  return false;
121 
122  if (term->isWildcard() && !(otherTerm->isWildcard()))
123  return false;
124 
125  if (term->isElement()) {
126  const XsdElement::Ptr element = term;
127  const XsdElement::Ptr otherElement = otherTerm;
128 
129  if (element->name(m_namePool) != otherElement->name(m_namePool))
130  return false;
131 
132  if (element->type()->name(m_namePool) != otherElement->type()->name(m_namePool))
133  return false;
134  }
135 
136  if (term->isModelGroup()) {
137  const XsdModelGroup::Ptr group = term;
138  const XsdModelGroup::Ptr otherGroup = otherTerm;
139 
140  if (group->particles().count() != otherGroup->particles().count())
141  return false;
142 
143  for (int i = 0; i < group->particles().count(); ++i) {
144  if (!particleEqualsRecursively(group->particles().at(i), otherGroup->particles().at(i)))
145  return false;
146  }
147  }
148 
149  if (term->isWildcard()) {
150  }
151 
152  return true;
153 }
154 
156 {
157  // @see http://www.w3.org/TR/xmlschema11-1/#cos-particle-extend
158 
159  // 1
160  if (extension == base)
161  return true;
162 
163  // 2
164  if (extension->minimumOccurs() == 1 && extension->maximumOccurs() == 1 && extension->maximumOccursUnbounded() == false) {
165  if (extension->term()->isModelGroup()) {
166  const XsdModelGroup::Ptr modelGroup = extension->term();
167  if (modelGroup->compositor() == XsdModelGroup::SequenceCompositor) {
168  if (particleEqualsRecursively(modelGroup->particles().first(), base))
169  return true;
170  }
171  }
172  }
173 
174  // 3
175  if (extension->minimumOccurs() == base->minimumOccurs()) { // 3.1
176  if (extension->term()->isModelGroup() && base->term()->isModelGroup()) {
177  const XsdModelGroup::Ptr extensionGroup(extension->term());
178  const XsdModelGroup::Ptr baseGroup(base->term());
179 
180  if (extensionGroup->compositor() == XsdModelGroup::AllCompositor && baseGroup->compositor() == XsdModelGroup::AllCompositor) {
181  const XsdParticle::List extensionParticles = extensionGroup->particles();
182  const XsdParticle::List baseParticles = baseGroup->particles();
183  for (int i = 0; i < baseParticles.count() && i < extensionParticles.count(); ++i) {
184  if (baseParticles.at(i) != extensionParticles.at(i))
185  return false;
186  }
187  }
188  }
189  }
190 
191  return false;
192 }
193 
195 {
197 
198  const XsdTerm::Ptr term(particle->term());
199  if (term->isElement()) {
200  elements.insert(XsdElement::Ptr(term));
201  } else if (term->isModelGroup()) {
202  const XsdModelGroup::Ptr group(term);
203 
204  for (int i = 0; i < group->particles().count(); ++i)
205  elements.unite(collectAllElements(group->particles().at(i)));
206  }
207 
208  return elements;
209 }
210 
212 {
214 
215  // collect global elements
216  const XsdElement::List elementList = schema->elements();
217  for (int i = 0; i < elementList.count(); ++i)
218  elements.insert(elementList.at(i));
219 
220  // collect all elements from global groups
221  const XsdModelGroup::List groupList = schema->elementGroups();
222  for (int i = 0; i < groupList.count(); ++i) {
223  const XsdModelGroup::Ptr group(groupList.at(i));
224 
225  for (int j = 0; j < group->particles().count(); ++j)
226  elements.unite(collectAllElements(group->particles().at(j)));
227  }
228 
229  // collect all elements from complex type definitions
231  types << schema->types() << schema->anonymousTypes();
232 
233  for (int i = 0; i < types.count(); ++i) {
234  if (types.at(i)->isComplexType() && types.at(i)->isDefinedBySchema()) {
235  const XsdComplexType::Ptr complexType(types.at(i));
236  if (complexType->contentType()->particle())
237  elements.unite(collectAllElements(complexType->contentType()->particle()));
238  }
239  }
240 
241  return elements;
242 }
243 
245 {
246  // @see http://www.w3.org/TR/xmlschema11-1/#cvc-accept
247 
248  if (particle->term()->isWildcard()) { // 1
249  const XsdWildcard::Ptr wildcard(particle->term());
250 
251  // 1.1
252  if ((unsigned int)sequence->particles().count() < particle->minimumOccurs())
253  return false;
254 
255  // 1.2
256  if (!particle->maximumOccursUnbounded()) {
257  if ((unsigned int)sequence->particles().count() > particle->maximumOccurs())
258  return false;
259  }
260 
261  // 1.3
262  const XsdParticle::List particles(sequence->particles());
263  for (int i = 0; i < particles.count(); ++i) {
264  if (particles.at(i)->term()->isElement()) {
265  if (!XsdSchemaHelper::wildcardAllowsExpandedName(XsdElement::Ptr(particles.at(i)->term())->name(m_namePool), wildcard, m_namePool))
266  return false;
267  }
268  }
269  } else if (particle->term()->isElement()) { // 2
270  const XsdElement::Ptr element(particle->term());
271 
272  // 2.1
273  if ((unsigned int)sequence->particles().count() < particle->minimumOccurs())
274  return false;
275 
276  // 2.2
277  if (!particle->maximumOccursUnbounded()) {
278  if ((unsigned int)sequence->particles().count() > particle->maximumOccurs())
279  return false;
280  }
281 
282  // 2.3
283  const XsdParticle::List particles(sequence->particles());
284  for (int i = 0; i < particles.count(); ++i) {
285  bool isValid = false;
286  if (particles.at(i)->term()->isElement()) {
287  const XsdElement::Ptr seqElement(particles.at(i)->term());
288 
289  // 2.3.1
290  if (element->name(m_namePool) == seqElement->name(m_namePool))
291  isValid = true;
292 
293  // 2.3.2
294  if (element->scope() && element->scope()->variety() == XsdElement::Scope::Global) {
295  if (!(element->disallowedSubstitutions() & NamedSchemaComponent::SubstitutionConstraint)) {
296  //TODO: continue
297  }
298  }
299  }
300  }
301  }
302 
303  return true;
304 }
305 
static const AtomicType::Ptr xsID
QSet< T > & unite(const QSet< T > &other)
Definition: qset.h:244
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
XsdTerm::Ptr term() const
The model group contains elements only.
SchemaType::List anonymousTypes() const
Definition: qxsdschema.cpp:181
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
virtual bool isWildcard() const
Definition: qxsdterm.cpp:58
QSet< XsdElement::Ptr > collectAllElements(const XsdParticle::Ptr &particle)
XsdModelGroup::List elementGroups() const
Definition: qxsdschema.cpp:223
static const uint base
Definition: qurl.cpp:268
bool hasConstraintIDAttributeUse(const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const
SchemaType::Ptr type() const
unsigned int maximumOccurs() const
virtual bool isElement() const
Definition: qxsdterm.cpp:48
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
unsigned int minimumOccurs() const
XsdParticle::List particles() const
virtual bool isComplexType() const
Definition: qschematype.cpp:70
const char * name
bool elementSequenceAccepted(const XsdModelGroup::Ptr &sequence, const XsdParticle::Ptr &particle) const
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The namespace for the internal API of QtXmlPatterns.
const_iterator insert(const T &value)
Definition: qset.h:179
virtual QXmlName name(const NamePool::Ptr &namePool) const
T & first()
Returns a reference to the first item in the list.
Definition: qlist.h:282
bool maximumOccursUnbounded() const
static const struct @32 types[]
static bool wxsTypeMatches(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, QSet< SchemaType::Ptr > &visitedTypes, SchemaType::Ptr &conflictingType)
The element is defined globally as child of the schema object.
virtual bool isModelGroup() const
Definition: qxsdterm.cpp:53
bool hasDuplicatedAttributeUses(const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const
static const QTextHtmlElement elements[Html_NumElements]
bool particleEqualsRecursively(const XsdParticle::Ptr &particle, const XsdParticle::Ptr &otherParticle) const
ModelCompositor compositor() const
bool isValidParticleExtension(const XsdParticle::Ptr &extension, const XsdParticle::Ptr &base) const
static bool wildcardAllowsExpandedName(const QXmlName &name, const XsdWildcard::Ptr &wildcard, const NamePool::Ptr &namePool)
virtual bool isDefinedBySchema() const
Definition: qschematype.cpp:75
SchemaType::List types() const
Definition: qxsdschema.cpp:131
virtual QXmlName name(const NamePool::Ptr &np) const =0
Returns the name of the type.
XsdElement::List elements() const
Definition: qxsdschema.cpp:89
bool hasMultipleIDAttributeUses(const XsdAttributeUse::List &list) const