1
|
|
/*
|
2
|
|
* JBind
|
3
|
|
*
|
4
|
|
* Copyright (c) by Stefan Wachter. All rights reserved.
|
5
|
|
*
|
6
|
|
* Usage, modification, and redistribution is subject to license terms that are
|
7
|
|
* available at 'http://www.jbind.org'. The JBind license is like the
|
8
|
|
* 'Apache Software License V 1.1'.
|
9
|
|
*/
|
10
|
|
package org.jbind.xml.schema.element;
|
11
|
|
|
12
|
|
import java.util.Collections;
|
13
|
|
import java.util.Iterator;
|
14
|
|
import java.util.Set;
|
15
|
|
|
16
|
|
import org.jbind.xml.base.FinalType;
|
17
|
|
import org.jbind.xml.base.IAttribute;
|
18
|
|
import org.jbind.xml.base.IBindingAttributes;
|
19
|
|
import org.jbind.xml.base.IRef;
|
20
|
|
import org.jbind.xml.base.Range;
|
21
|
|
import org.jbind.xml.core.cmp.IAttributesModel;
|
22
|
|
import org.jbind.xml.core.cmp.IComplexContentModel;
|
23
|
|
import org.jbind.xml.core.cmp.IComponent;
|
24
|
|
import org.jbind.xml.core.cmp.IComponentStore;
|
25
|
|
import org.jbind.xml.core.cmp.IContentModel;
|
26
|
|
import org.jbind.xml.core.cmp.ISchema;
|
27
|
|
import org.jbind.xml.core.constraint.IConstraint;
|
28
|
|
import org.jbind.xml.core.constraint.IConstraints;
|
29
|
|
import org.jbind.xml.core.constraint.IIdentityConstraint;
|
30
|
|
import org.jbind.xml.core.constraint.IIdentityConstraintComponent;
|
31
|
|
import org.jbind.xml.core.content.IAttrGroupDecl;
|
32
|
|
import org.jbind.xml.core.content.IAttrRefOrDecl;
|
33
|
|
import org.jbind.xml.core.content.IElemGroupDesc;
|
34
|
|
import org.jbind.xml.core.type.IAnyType;
|
35
|
|
import org.jbind.xml.core.type.IListType;
|
36
|
|
import org.jbind.xml.msg.IConstraintViolations;
|
37
|
|
import org.jbind.xml.msg.XmlException;
|
38
|
|
import org.jbind.xml.msg.XmlMessages;
|
39
|
|
import org.jbind.xml.schema.cmp.ComplexContentModel;
|
40
|
|
import org.jbind.xml.schema.cmp.ComplexType;
|
41
|
|
import org.jbind.xml.schema.cmp.ComplexTypeCC;
|
42
|
|
import org.jbind.xml.schema.cmp.ComplexTypeSC;
|
43
|
|
import org.jbind.xml.schema.cmp.SequenceDecl;
|
44
|
|
import org.jbind.xml.schema.cmp.W3CTypes;
|
45
|
|
import org.jbind.xml.schema.cmp.XPathMethod;
|
46
|
|
import org.jbind.xml.schema.constraint.AttributesConstraint;
|
47
|
|
import org.jbind.xml.schema.constraint.Constraints;
|
48
|
|
import org.jbind.xml.schema.constraint.IdConstraint;
|
49
|
|
import org.jbind.xml.schema.constraint.IdRefConstraint;
|
50
|
|
import org.jbind.xml.schema.constraint.IdRefsConstraint;
|
51
|
|
import org.jbind.xml.schema.constraint.IdsConstraint;
|
52
|
|
import org.jbind.xml.schema.instantiation.IComponentSetter;
|
53
|
|
import org.jbind.xml.schema.instantiation.IElemValHelper;
|
54
|
|
import org.jbind.xml.schema.instantiation.IElementHelper;
|
55
|
|
import org.jbind.xml.schema.instantiation.IJobRefs;
|
56
|
|
import org.jbind.xml.schema.instantiation.ITopLevelElement;
|
57
|
|
|
58
|
|
public class ComplexTypeDef extends TypeDef implements IComplexTypeDef {
|
59
|
|
|
60
|
|
private CreationParams myCreationParams = null;
|
61
|
|
|
62
|
|
private boolean myIsAbstract = false;
|
63
|
|
private Boolean myIsMixed = null;
|
64
|
|
|
65
|
|
private Set myBlockTypes = Collections.EMPTY_SET;
|
66
|
|
|
67
|
|
/**
|
68
|
|
* <i>(required)</i>.
|
69
|
|
* The complexContent or simpleContent element. If there is no nested content model
|
70
|
|
* element then the abbreviated content model is used.
|
71
|
|
*/
|
72
|
|
private IContentModelDesc myContentModelDesc = null;
|
73
|
|
|
74
|
|
/**
|
75
|
|
* Inlined model group definition. The model group definition may either be a direct
|
76
|
|
* decendant of the complex type or enclosed by a complex content element.
|
77
|
|
*/
|
78
|
|
private IModelGroup myInlinedModelGroup = null;
|
79
|
|
|
80
|
|
/**
|
81
|
|
* Referenced model group definition. The reference may either be a direct decendant
|
82
|
|
* of the complex type or enclosed by a complex content element.
|
83
|
|
*/
|
84
|
|
private IModelGroupRef myModelGroupRef = null;
|
85
|
|
|
86
|
|
/**
|
87
|
|
*
|
88
|
|
*/
|
89
|
|
private IAttributeInfos myAttributeInfos = null;
|
90
|
|
|
91
|
|
/**
|
92
|
|
* Constraints whose creation is started in the creation step.
|
93
|
|
*/
|
94
|
|
private final IConstraints myComponentConstraints = new Constraints();
|
95
|
|
|
96
|
|
private IElemGroupDesc myLocalGroup = null;
|
97
|
|
|
98
|
|
private boolean myIsExtension = false;
|
99
|
|
|
100
|
506
|
public ComplexTypeDef(CreationParams aCreationParams, String aRole) {
|
101
|
506
|
super(aCreationParams, aRole);
|
102
|
506
|
myCreationParams = aCreationParams;
|
103
|
|
}
|
104
|
|
|
105
|
353
|
protected IAttribute doCreateAttribute(ACParams anACParams) throws XmlException {
|
106
|
353
|
IAttribute res = null;
|
107
|
353
|
String an = NameUtil.getSchemaAttributeName(anACParams);
|
108
|
353
|
if ("abstract".equals(an)) {
|
109
|
14
|
res = new BooleanAttribute(anACParams);
|
110
|
14
|
myIsAbstract = res.getBoolean();
|
111
|
339
|
} else if ("mixed".equals(an)) {
|
112
|
11
|
res = new BooleanAttribute(anACParams);
|
113
|
11
|
setIsMixed(new Boolean(res.getBoolean()));
|
114
|
328
|
} else if ("block".equals(an)) {
|
115
|
2
|
res = new Attribute(anACParams);
|
116
|
2
|
myBlockTypes = ConstantResolver.getBlockTypes(res.getStringValue(), this);
|
117
|
|
} else {
|
118
|
326
|
res = super.doCreateAttribute(anACParams);
|
119
|
|
}
|
120
|
353
|
return res;
|
121
|
|
}
|
122
|
|
|
123
|
809
|
protected IElement doCreateChild(CreationParams aCreationParams) throws XmlException {
|
124
|
809
|
IElement res = null;
|
125
|
809
|
String componentName = NameUtil.getSchemaComponentName(aCreationParams);
|
126
|
809
|
if ("simpleContent".equals(componentName)) {
|
127
|
35
|
res = new SimpleContentModelDesc(aCreationParams, getRole());
|
128
|
774
|
} else if ("complexContent".equals(componentName)) {
|
129
|
165
|
res = new ComplexContentModelDesc(aCreationParams);
|
130
|
609
|
} else if ("group".equals(componentName)) {
|
131
|
5
|
res = new ModelGroupRef(aCreationParams);
|
132
|
604
|
} else if ("all".equals(componentName)) {
|
133
|
11
|
res = new AllModelGroup(aCreationParams);
|
134
|
593
|
} else if ("choice".equals(componentName)) {
|
135
|
68
|
res = new ChoiceModelGroup(aCreationParams);
|
136
|
525
|
} else if ("sequence".equals(componentName)) {
|
137
|
119
|
res = new SequenceModelGroup(aCreationParams);
|
138
|
406
|
} else if ("attribute".equals(componentName)) {
|
139
|
320
|
res = new AttributeDeclaration(aCreationParams, true);
|
140
|
86
|
} else if ("attributeGroup".equals(componentName)) {
|
141
|
24
|
res = new AttributeGroupRef(aCreationParams);
|
142
|
62
|
} else if ("anyAttribute".equals(componentName)) {
|
143
|
16
|
res = new AnyAttribute(aCreationParams);
|
144
|
|
} else {
|
145
|
46
|
res = super.doCreateChild(aCreationParams);
|
146
|
|
}
|
147
|
809
|
return res;
|
148
|
|
}
|
149
|
|
|
150
|
|
|
151
|
485
|
public Set getBlockTypes() {
|
152
|
485
|
return myBlockTypes;
|
153
|
|
}
|
154
|
|
|
155
|
0
|
public boolean getIsAbstract() {
|
156
|
0
|
return myIsAbstract;
|
157
|
|
}
|
158
|
|
|
159
|
|
|
160
|
486
|
public Boolean isMixed() {
|
161
|
486
|
return myIsMixed;
|
162
|
|
}
|
163
|
11
|
public void setIsMixed(Boolean aBoolean) {
|
164
|
11
|
myIsMixed = aBoolean;
|
165
|
|
}
|
166
|
|
|
167
|
|
|
168
|
0
|
public IAttributeInfos getAttributeInfos() {
|
169
|
0
|
return myAttributeInfos;
|
170
|
|
}
|
171
|
|
|
172
|
506
|
public void validateElement(IElemValHelper aHelper, IConstraintViolations aViolations) {
|
173
|
506
|
super.validateElement(aHelper, aViolations);
|
174
|
|
|
175
|
506
|
myContentModelDesc = (IContentModelDesc)getSubElement(IContentModelDesc.class, "duplicate content model", aViolations);
|
176
|
506
|
myInlinedModelGroup = (IModelGroup)getSubElement(IModelGroup.class, "duplicate model group", aViolations);
|
177
|
506
|
myModelGroupRef = (IModelGroupRef)getSubElement(IModelGroupRef.class, "duplicate model group reference", aViolations);
|
178
|
|
|
179
|
|
// Only one of ContentModel, InlinedModelGroup, or ModelGroupRef must exist
|
180
|
506
|
if (((null != myContentModelDesc) && (null != myInlinedModelGroup)) || ((null != myContentModelDesc) && (null != myModelGroupRef)) || ((null != myInlinedModelGroup) && (null != myModelGroupRef))) {
|
181
|
0
|
aViolations.add(XmlMessages.invalidContentModel(this));
|
182
|
|
}
|
183
|
|
|
184
|
506
|
if (null == myContentModelDesc) {
|
185
|
|
// There is no simpleContent or complexContent element
|
186
|
|
|
187
|
306
|
myAttributeInfos = new AttributeInfos(this);
|
188
|
306
|
myContentModelDesc = new AbbreviatedContentModel(myCreationParams, myInlinedModelGroup, myModelGroupRef);
|
189
|
|
|
190
|
|
} else {
|
191
|
|
// There is a simpleContent or complexContent element
|
192
|
|
|
193
|
200
|
if (iterChildrenByClass(IAttributeDeclaration.class).hasNext() || iterChildrenByClass(IAttributeGroupRef.class).hasNext() || iterChildrenByClass(IAnyAttribute.class).hasNext()) {
|
194
|
0
|
aViolations.add(XmlMessages.unexpectedAttributeInfo(this));
|
195
|
|
}
|
196
|
|
|
197
|
200
|
myAttributeInfos = myContentModelDesc.getDerivation().getAttributeInfos();
|
198
|
200
|
myInlinedModelGroup = myContentModelDesc.getDerivation().getModelGroup();
|
199
|
200
|
myModelGroupRef = myContentModelDesc.getDerivation().getModelGroupRef();
|
200
|
|
|
201
|
|
}
|
202
|
|
|
203
|
506
|
if (!myContentModelDesc.isComplex() && (null != isMixed())) {
|
204
|
0
|
aViolations.add(XmlMessages.mixedOnlyAllowedForCc(this));
|
205
|
|
}
|
206
|
|
|
207
|
506
|
myAttributeInfos.validate(aViolations);
|
208
|
|
|
209
|
506
|
myIsExtension = myContentModelDesc.getDerivation().getIsExtension();
|
210
|
|
|
211
|
|
}
|
212
|
|
|
213
|
|
|
214
|
|
//
|
215
|
|
// Implementation of IComponentJobHelper
|
216
|
|
//
|
217
|
|
|
218
|
723
|
public void collectRefsForCreation(IJobRefs aJobRefs) {
|
219
|
723
|
if (myContentModelDesc.isComplex()) {
|
220
|
|
// The base type of a complex type with a complex content model needs not
|
221
|
|
// to be validated for the complex type to be created.
|
222
|
|
// The reason is that the base type may depend on this type and may be validated
|
223
|
|
// only after this type was created.
|
224
|
681
|
aJobRefs.add(myContentModelDesc.getDerivation().getBaseAttribute(), false, myContentModelDesc.getDerivation());
|
225
|
|
} else {
|
226
|
|
// The base type of a complex type with a simple content model must have been validated.
|
227
|
|
// The content type of the base type is accessed in the creation step of this
|
228
|
|
// complex type.
|
229
|
42
|
if (null != myContentModelDesc.getDerivation().getBaseAttribute()) {
|
230
|
42
|
aJobRefs.add(myContentModelDesc.getDerivation().getBaseAttribute(), true, myContentModelDesc.getDerivation());
|
231
|
|
}
|
232
|
42
|
if (null != myContentModelDesc.getDerivation().getInlinedBaseAttribute()) {
|
233
|
|
// The content model may contain an inlined type whose base must have been validated.
|
234
|
0
|
aJobRefs.add(myContentModelDesc.getDerivation().getInlinedBaseAttribute(), true, myContentModelDesc.getDerivation());
|
235
|
|
}
|
236
|
|
}
|
237
|
723
|
myAttributeInfos.collectRefsForCreation(aJobRefs);
|
238
|
|
}
|
239
|
|
|
240
|
|
|
241
|
1387
|
public void collectRefsForCompletion(IElementHelper anElementHelper, IJobRefs aJobRefs) {
|
242
|
1387
|
if (myContentModelDesc.isComplex()) {
|
243
|
1308
|
aJobRefs.add(myContentModelDesc.getDerivation().getBaseAttribute(), true, myContentModelDesc.getDerivation());
|
244
|
|
}
|
245
|
1387
|
if (null != myModelGroupRef) {
|
246
|
54
|
aJobRefs.add(myModelGroupRef.getRef(), true, myModelGroupRef);
|
247
|
|
}
|
248
|
|
}
|
249
|
|
|
250
|
0
|
public void collectRefsForValidation(IElementHelper anElementHelper, IJobRefs aJobRefs) {}
|
251
|
|
|
252
|
|
|
253
|
485
|
public IComponent createComponent(IElementHelper anElementHelper, final IConstraintViolations aViolations) {
|
254
|
485
|
Set finalTypes = getFinalTypes();
|
255
|
485
|
if (null == finalTypes) {
|
256
|
485
|
finalTypes = getSchemaElement().getDefaultFinalTypes();
|
257
|
|
}
|
258
|
485
|
Set blockTypes = getBlockTypes();
|
259
|
485
|
if (null == blockTypes) {
|
260
|
0
|
blockTypes = getSchemaElement().getDefaultBlockTypes();
|
261
|
|
}
|
262
|
|
|
263
|
485
|
ComplexType res = null;
|
264
|
|
|
265
|
485
|
if (myContentModelDesc.isComplex()) {
|
266
|
451
|
res = new ComplexTypeCC(this, getTargetNamespace(), getName(), getRole(), finalTypes, blockTypes, myIsAbstract, myIsExtension);
|
267
|
|
} else {
|
268
|
34
|
res = new ComplexTypeSC(this, getTargetNamespace(), getName(), getRole(), finalTypes, blockTypes, myIsAbstract, myIsExtension);
|
269
|
|
}
|
270
|
|
|
271
|
485
|
IAnyType bType = null;
|
272
|
485
|
if (null != myContentModelDesc.getDerivation().getBaseAttribute()) {
|
273
|
485
|
bType = (IAnyType)anElementHelper.getComponent(myContentModelDesc.getDerivation().getBaseAttribute(), false);
|
274
|
|
}
|
275
|
485
|
IAnyType baseType = (IAnyType)anElementHelper.getComponent(myContentModelDesc.getDerivation().getEffectiveBaseAttribute(), false);
|
276
|
|
|
277
|
485
|
if ((null != bType) && !bType.isBaseType(baseType)) {
|
278
|
0
|
aViolations.add(XmlMessages.inlinedTypeNotSubType(this));
|
279
|
|
}
|
280
|
|
|
281
|
485
|
if (myIsExtension && baseType.isActive(FinalType.EXTENSION)) {
|
282
|
0
|
aViolations.add(XmlMessages.baseTypeMustNotBeExtended(this));
|
283
|
|
}
|
284
|
485
|
if (!myIsExtension && baseType.isActive(FinalType.RESTRICTION)) {
|
285
|
0
|
aViolations.add(XmlMessages.baseTypeMustNotBeRestricted(this));
|
286
|
|
}
|
287
|
|
|
288
|
485
|
res.setBaseType(baseType);
|
289
|
|
|
290
|
485
|
IAttributesModel baseModel = baseType.getAttributesModel();
|
291
|
485
|
final IAttributesModel attributesModel = myIsExtension ? baseModel.extend(res) : baseModel.restrict(res);
|
292
|
485
|
res.setAttributesModel(attributesModel);
|
293
|
|
|
294
|
485
|
AttributesModelGroupCreator creator = new AttributesModelGroupCreator(myAttributeInfos);
|
295
|
|
|
296
|
485
|
anElementHelper.addSubJob(creator, new IComponentSetter() {
|
297
|
485
|
public void set(IComponent aComponent, IConstraintViolations aVls) {
|
298
|
485
|
attributesModel.setAttrGroupDecl((IAttrGroupDecl)aComponent);
|
299
|
|
}
|
300
|
|
});
|
301
|
|
|
302
|
485
|
if (myContentModelDesc.isComplex()) {
|
303
|
|
// A complex type with complex or mixed content
|
304
|
|
//
|
305
|
|
// - Create the (complex) content model (the group use is not set because
|
306
|
|
// an inlined model group must first be created by a sub job.
|
307
|
|
// - Start a sub job for the element group (if necessary)
|
308
|
|
|
309
|
|
// The base type must have a complex content model
|
310
|
451
|
IContentModel baseContentModel = baseType.getContentModel();
|
311
|
451
|
if (!baseContentModel.isComplex()) {
|
312
|
0
|
aViolations.add(XmlMessages.baseContentModelMustBeComplex(this));
|
313
|
|
}
|
314
|
|
|
315
|
451
|
IComplexContentModel complexContentModel = new ComplexContentModel();
|
316
|
451
|
complexContentModel.setIsMixed(getEffectiveMixed());
|
317
|
451
|
res.setContentModel(complexContentModel);
|
318
|
|
|
319
|
451
|
if (null != myInlinedModelGroup) {
|
320
|
289
|
anElementHelper.addSubJob(myInlinedModelGroup, new IComponentSetter() {
|
321
|
282
|
public void set(IComponent aComponent, IConstraintViolations aVls) {
|
322
|
282
|
myLocalGroup = (IElemGroupDesc)aComponent;
|
323
|
|
}
|
324
|
|
});
|
325
|
162
|
} else if (null != myModelGroupRef) {
|
326
|
19
|
anElementHelper.addSubJob(myModelGroupRef, new IComponentSetter() {
|
327
|
18
|
public void set(IComponent aComponent, IConstraintViolations aVls) {
|
328
|
18
|
myLocalGroup = (IElemGroupDesc)aComponent;
|
329
|
|
}
|
330
|
|
});
|
331
|
|
}
|
332
|
|
|
333
|
|
} else {
|
334
|
|
// A complex type with simple content
|
335
|
|
|
336
|
34
|
if (myIsExtension && !baseType.isSimple()) {
|
337
|
0
|
aViolations.add(XmlMessages.baseMustBeSimpleOrCTSC(this));
|
338
|
34
|
} else if (!myIsExtension && (!baseType.isComplex() || !baseType.isSimple())) {
|
339
|
1
|
aViolations.add(XmlMessages.baseMustBeCTSC(this));
|
340
|
|
}
|
341
|
|
|
342
|
|
}
|
343
|
|
|
344
|
485
|
final ISchema schema = getSchema();
|
345
|
|
|
346
|
485
|
for (Iterator a = iterAppInfos(); a.hasNext(); ) {
|
347
|
20
|
IAppInfoElement appInfo = (IAppInfoElement)a.next();
|
348
|
20
|
for (Iterator i = appInfo.iterChildrenByClass(IIdentityConstraintElement.class);
|
349
|
36
|
i.hasNext(); ) {
|
350
|
16
|
IIdentityConstraintElement ice = (IIdentityConstraintElement)i.next();
|
351
|
16
|
anElementHelper.addSubJob(ice, new IComponentSetter() {
|
352
|
16
|
public void set(IComponent aComponent, IConstraintViolations aVls) {
|
353
|
16
|
myComponentConstraints.add((IIdentityConstraintComponent)aComponent, aVls, ComplexTypeDef.this);
|
354
|
16
|
schema.setComponent(aComponent, aVls);
|
355
|
|
}
|
356
|
|
});
|
357
|
|
}
|
358
|
20
|
for (Iterator i = appInfo.iterChildrenByClass(IXPathConstraintElement.class);
|
359
|
22
|
i.hasNext(); ) {
|
360
|
2
|
IXPathConstraintElement ce = (IXPathConstraintElement)i.next();
|
361
|
2
|
try {
|
362
|
2
|
IConstraint c = ce.createXPathConstraint(anElementHelper);
|
363
|
2
|
myComponentConstraints.add(c, aViolations, this);
|
364
|
|
} catch (XmlException e) {
|
365
|
0
|
aViolations.add(e.getXmlMessage());
|
366
|
|
}
|
367
|
|
}
|
368
|
|
}
|
369
|
|
|
370
|
485
|
return res;
|
371
|
|
}
|
372
|
|
|
373
|
451
|
private boolean getEffectiveMixed() {
|
374
|
451
|
Boolean m = myContentModelDesc.isMixed();
|
375
|
451
|
if (null == m) {
|
376
|
451
|
m = isMixed();
|
377
|
|
}
|
378
|
451
|
return (null != m) ? m.booleanValue() : false;
|
379
|
|
}
|
380
|
|
|
381
|
476
|
public void completeComponent(IElementHelper anElementHelper, final IComponent aComponent, IConstraintViolations aViolations) {
|
382
|
476
|
ComplexType complexType = (ComplexType)aComponent;
|
383
|
476
|
IAnyType baseType = complexType.getBaseType();
|
384
|
|
|
385
|
476
|
if (myContentModelDesc.isComplex()) {
|
386
|
|
// Finish the complex content model.
|
387
|
|
// The local group is available now.
|
388
|
|
|
389
|
443
|
IComplexContentModel complexContentModel = (IComplexContentModel)complexType.getContentModel();
|
390
|
|
|
391
|
443
|
IComplexContentModel baseModel = (IComplexContentModel)baseType.getContentModel();
|
392
|
443
|
IElemGroupDesc baseGroup = baseModel.getGroup();
|
393
|
|
|
394
|
443
|
IElemGroupDesc derivedGroup = null;
|
395
|
|
|
396
|
443
|
if (myIsExtension) {
|
397
|
85
|
if (!baseModel.isEmpty() && (baseModel.isMixed() != complexContentModel.isMixed())) {
|
398
|
0
|
aViolations.add(XmlMessages.extensionCanNotChangeMixed(String.valueOf(baseModel.isMixed()), this));
|
399
|
|
}
|
400
|
|
|
401
|
85
|
if ((null != myLocalGroup) && (null != baseGroup)) {
|
402
|
|
// Use the local group as the source info. Otherwise the created
|
403
|
|
// sequence might count as being a top level sequence (if this complex
|
404
|
|
// type is a top level component).
|
405
|
33
|
derivedGroup = new SequenceDecl(myLocalGroup, null, null, Range.ONE);
|
406
|
33
|
derivedGroup.add(baseGroup);
|
407
|
33
|
derivedGroup.add(myLocalGroup);
|
408
|
52
|
} else if (null != myLocalGroup) {
|
409
|
8
|
derivedGroup = myLocalGroup;
|
410
|
|
} else {
|
411
|
44
|
derivedGroup = baseGroup;
|
412
|
|
}
|
413
|
|
|
414
|
|
} else {
|
415
|
358
|
derivedGroup = myLocalGroup;
|
416
|
|
|
417
|
|
}
|
418
|
|
|
419
|
443
|
complexContentModel.setGroup(derivedGroup);
|
420
|
|
|
421
|
|
}
|
422
|
|
|
423
|
|
|
424
|
476
|
IAttributesModel attributesModel = complexType.getAttributesModel();
|
425
|
476
|
attributesModel.completeDerivedModel(aViolations);
|
426
|
|
|
427
|
|
}
|
428
|
|
|
429
|
451
|
public void addSchemaData(IComponentStore aComponentStore, IComponent aComponent, IConstraintViolations aViolations) {
|
430
|
451
|
ComplexType type = (ComplexType)aComponent;
|
431
|
451
|
if (!type.isExtension()) {
|
432
|
343
|
IContentModel baseModel = type.getBaseType().getContentModel();
|
433
|
343
|
if (baseModel.isComplex()) {
|
434
|
333
|
IElemGroupDesc baseGroup = ((IComplexContentModel)baseModel).getGroup();
|
435
|
333
|
IComplexContentModel restrictedModel = (IComplexContentModel)type.getContentModel();
|
436
|
333
|
IElemGroupDesc restrictedGroup = restrictedModel.getGroup();
|
437
|
333
|
ComplexTypeDefHelper.validateRestriction(baseGroup, restrictedGroup, aViolations, this);
|
438
|
|
}
|
439
|
|
}
|
440
|
|
|
441
|
451
|
buildConstraints(aComponentStore, type, aViolations);
|
442
|
451
|
if (!myContentModelDesc.isComplex() && !myIsExtension) {
|
443
|
|
// It is a simple content restriction -> collect the facets
|
444
|
10
|
((ISimpleRestrictionDerivation)myContentModelDesc.getDerivation()).addSchemaData(aComponentStore, aComponent, aViolations);
|
445
|
|
}
|
446
|
451
|
type.addXPathMethods(type.getBaseType().getXPathMethods());
|
447
|
451
|
for (Iterator a = iterAppInfos(); a.hasNext(); ) {
|
448
|
20
|
IAppInfoElement appInfo = (IAppInfoElement)a.next();
|
449
|
20
|
for (Iterator i = appInfo.iterChildrenByClass(XPathMethodElement.class);
|
450
|
32
|
i.hasNext(); ) {
|
451
|
12
|
XPathMethodElement me = (XPathMethodElement)i.next();
|
452
|
12
|
IAttribute upa = me.getLocalBindingAttribute(IBindingAttributes.REFERENCED_TYPE);
|
453
|
12
|
IAnyType referencedType = null;
|
454
|
12
|
if (null != upa) {
|
455
|
0
|
referencedType = (IAnyType)aComponentStore.getComponent(upa.getRef());
|
456
|
|
}
|
457
|
12
|
XPathMethod xPathMethod = new XPathMethod(me, me.getName(), me.getXPath(), me.getMethodType(), referencedType);
|
458
|
12
|
if (null != type.addXPathMethod(xPathMethod)) {
|
459
|
0
|
aViolations.add(XmlMessages.duplicateXPathMethod(me.getName(), me));
|
460
|
|
}
|
461
|
|
}
|
462
|
|
}
|
463
|
|
}
|
464
|
|
|
465
|
451
|
private void buildConstraints(IComponentStore aComponentStore, IAnyType aType, IConstraintViolations aViolations) {
|
466
|
451
|
IAnyType baseType = aType.getBaseType();
|
467
|
|
|
468
|
451
|
IConstraints constraints = baseType.getConstraints().shallowCopy();
|
469
|
451
|
aType.setConstraints(constraints);
|
470
|
451
|
constraints.add(new AttributesConstraint(aType.getAttributesModel()), aViolations, this);
|
471
|
|
|
472
|
|
// Add attribute constraints (id, idref, and idrefs)
|
473
|
451
|
IAttributesModel attributesModel = aType.getAttributesModel();
|
474
|
451
|
IAttributesModel baseAttributesModel = aType.getBaseType().getAttributesModel();
|
475
|
451
|
for (Iterator i = attributesModel.iterAttributes(); i.hasNext(); ) {
|
476
|
824
|
IAttrRefOrDecl attr = (IAttrRefOrDecl)i.next();
|
477
|
824
|
IAnyType baseAttributeType = null;
|
478
|
824
|
IAttrRefOrDecl baseAttr = baseAttributesModel.getAttrRefOrDecl(attr.getGlobalRef());
|
479
|
824
|
if (null != baseAttr) {
|
480
|
337
|
baseAttributeType = baseAttr.getType();
|
481
|
|
}
|
482
|
824
|
IAnyType type = attr.getType();
|
483
|
824
|
if (type.isInstanceType(W3CTypes.id)) {
|
484
|
6
|
if ((null != baseAttributeType) && baseAttributeType.isInstanceType(W3CTypes.id)) {
|
485
|
0
|
continue;
|
486
|
|
}
|
487
|
6
|
IdConstraint c = new IdConstraint(attr, this);
|
488
|
6
|
constraints.add(c, aViolations, this);
|
489
|
6
|
IAttribute upa = attr.getLocalBindingAttribute(IBindingAttributes.REFERENCED_TYPE);
|
490
|
6
|
if (null != upa) {
|
491
|
0
|
c.setDataType((IAnyType)aComponentStore.getComponent(upa.getRef()));
|
492
|
|
} else {
|
493
|
6
|
c.setDataType(W3CTypes.anyType);
|
494
|
|
}
|
495
|
818
|
} else if (type.isInstanceType(W3CTypes.idRef)) {
|
496
|
6
|
if ((null != baseAttributeType) && baseAttributeType.isInstanceType(W3CTypes.idRef)) {
|
497
|
0
|
continue;
|
498
|
|
}
|
499
|
6
|
IIdentityConstraint c = new IdRefConstraint(attr, this);
|
500
|
6
|
constraints.add(c, aViolations, this);
|
501
|
6
|
IAttribute upa = attr.getLocalBindingAttribute(IBindingAttributes.REFERENCED_TYPE);
|
502
|
6
|
if (null != upa) {
|
503
|
0
|
c.setDataType((IAnyType)aComponentStore.getComponent(upa.getRef()));
|
504
|
|
} else {
|
505
|
6
|
c.setDataType(W3CTypes.anyType);
|
506
|
|
}
|
507
|
812
|
} else if (type instanceof IListType) {
|
508
|
14
|
if (((IListType)type).getItemType().isInstanceType(W3CTypes.idRef)) {
|
509
|
6
|
if ((null != baseAttributeType) && (baseAttributeType instanceof IListType) && ((IListType)baseAttributeType).getItemType().isInstanceType(W3CTypes.idRef)) {
|
510
|
0
|
continue;
|
511
|
|
}
|
512
|
6
|
IIdentityConstraint c = new IdRefsConstraint(attr, this);
|
513
|
6
|
constraints.add(c, aViolations, this);
|
514
|
6
|
IAttribute upa = attr.getLocalBindingAttribute(IBindingAttributes.REFERENCED_TYPE);
|
515
|
6
|
if (null != upa) {
|
516
|
0
|
c.setDataType((IAnyType)aComponentStore.getComponent(upa.getRef()));
|
517
|
|
} else {
|
518
|
6
|
c.setDataType(W3CTypes.anyType);
|
519
|
|
}
|
520
|
8
|
} else if (((IListType)type).getItemType().isInstanceType(W3CTypes.id)) {
|
521
|
2
|
if ((null != baseAttributeType) && (baseAttributeType instanceof IListType) && ((IListType)baseAttributeType).getItemType().isInstanceType(W3CTypes.id)) {
|
522
|
0
|
continue;
|
523
|
|
}
|
524
|
2
|
IIdentityConstraint c = new IdsConstraint(attr, this);
|
525
|
2
|
constraints.add(c, aViolations, this);
|
526
|
2
|
IAttribute upa = attr.getLocalBindingAttribute(IBindingAttributes.REFERENCED_TYPE);
|
527
|
2
|
if (null != upa) {
|
528
|
0
|
c.setDataType((IAnyType)aComponentStore.getComponent(upa.getRef()));
|
529
|
|
} else {
|
530
|
2
|
c.setDataType(W3CTypes.anyType);
|
531
|
|
}
|
532
|
|
}
|
533
|
|
}
|
534
|
|
}
|
535
|
|
|
536
|
|
// Add type identity constraints (key, unique, keyRef)
|
537
|
451
|
constraints.add(myComponentConstraints, aViolations, this);
|
538
|
|
|
539
|
|
}
|
540
|
|
|
541
|
3
|
public void redefine(ITopLevelElement aRedefinedElement, IConstraintViolations aViolations) {
|
542
|
3
|
if (getGlobalRef().equals(myContentModelDesc.getDerivation().getBaseAttribute())) {
|
543
|
3
|
myContentModelDesc.getDerivation().setBaseAttribute(aRedefinedElement.getGlobalRef());
|
544
|
|
} else {
|
545
|
0
|
aViolations.add(XmlMessages.baseTypeOfRedefinitionMustBeItself(getGlobalRef(), myContentModelDesc.getDerivation().getBaseAttribute(), this));
|
546
|
|
}
|
547
|
|
}
|
548
|
|
|
549
|
|
private IRef myRedefinedRef = null;
|
550
|
0
|
public IRef getRedefinedRef() {
|
551
|
0
|
return myRedefinedRef;
|
552
|
|
}
|
553
|
3
|
public void setRedefinedRef(IRef aRef) {
|
554
|
3
|
myRedefinedRef = aRef;
|
555
|
|
}
|
556
|
|
|
557
|
|
}
|
558
|
|
|