in src/main/java/org/apache/xmlbeans/impl/validator/Validator.java [177:492]
private void beginEvent(Event event) {
_localElement = null;
_wildcardElement = null;
State state = topState();
SchemaType elementType;
SchemaField elementField;
if (state == null) {
elementType = _rootType;
elementField = _rootField;
} else {
QName name = event.getName();
assert name != null;
state._isEmpty = false;
if (state._isNil) {
emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$NIL_WITH_CONTENT,
null, state._field.getName(), state._type, null,
XmlValidationError.NIL_ELEMENT, state._type);
_eatContent = 1;
return;
}
if (state._field != null && state._field.isFixed()) {
emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$FIXED_WITH_CONTENT,
new Object[]{QNameHelper.pretty(state._field.getName())},
state._field.getName(), state._type, null,
XmlValidationError.ELEMENT_NOT_ALLOWED, state._type);
}
if (!state.visit(name)) {
findDetailedErrorBegin(event, state, name);
_eatContent = 1;
return;
}
SchemaParticle currentParticle = state.currentParticle();
_wildcardElement = currentParticle;
if (currentParticle.getParticleType() == SchemaParticle.WILDCARD) {
//_wildcardElement = currentParticle;
QNameSet elemWildcardSet = currentParticle.getWildcardSet();
if (!elemWildcardSet.contains(name)) {
// Additional processing may be needed to generate more
// descriptive messages
// KHK: cvc-complex-type.2.4? cvc-particle.1.3? cvc-wildcard-namespace ?
emitFieldError(event, XmlErrorCodes.PARTICLE_VALID$NOT_WILDCARD_VALID,
new Object[]{QNameHelper.pretty(name)},
name, null, null,
XmlValidationError.ELEMENT_NOT_ALLOWED, state._type);
_eatContent = 1;
return;
}
int wildcardProcess = currentParticle.getWildcardProcess();
if (wildcardProcess == SchemaParticle.SKIP ||
wildcardProcess == SchemaParticle.LAX && _treatLaxAsSkip) {
_eatContent = 1;
return;
}
_localElement = _globalTypes.findElement(name);
elementField = _localElement;
if (elementField == null) {
if (wildcardProcess == SchemaParticle.STRICT) {
// KHK: cvc-complex-type.2.4c? cvc-assess-elt.1.1.1.3.2?
emitFieldError(event, XmlErrorCodes.ASSESS_ELEM_SCHEMA_VALID$NOT_RESOLVED,
new Object[]{QNameHelper.pretty(name)},
name, state._type, null,
XmlValidationError.ELEMENT_NOT_ALLOWED, state._type);
}
_eatContent = 1;
return;
}
} else {
assert currentParticle.getParticleType() == SchemaParticle.ELEMENT;
// If the current element particle name does not match the name
// of the event, then the current element is a substitute for
// the current particle. Replace the field with the global
// element for the replacement
if (!currentParticle.getName().equals(name)) {
if (((SchemaLocalElement) currentParticle).blockSubstitution()) {
emitFieldError(event, XmlErrorCodes.PARTICLE_VALID$BLOCK_SUBSTITUTION,
new Object[]{QNameHelper.pretty(name)},
name, state._type, null,
XmlValidationError.ELEMENT_NOT_ALLOWED, state._type);
_eatContent = 1;
return;
}
SchemaGlobalElement newField = _globalTypes.findElement(name);
assert newField != null;
elementField = newField;
_localElement = newField;
} else {
elementField = (SchemaField) currentParticle;
}
}
elementType = elementField.getType();
}
assert elementType != null;
//
// the no-type is always invalid (even if there is an xsi:type)
//
if (elementType.isNoType()) {
emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$NO_TYPE,
null, event.getName(), null, null,
XmlValidationError.ELEMENT_TYPE_INVALID, null);
_eatContent = 1;
}
//
// See if the element has an xsi:type on it
//
SchemaType xsiType = null;
String value = event.getXsiType();
if (value != null) {
// Turn off the listener so a public error message
// does not get generated, but I can see if there was
// an error through the error state
int originalErrorState = _errorState;
_suspendErrors++;
try {
_vc._event = null;
xsiType = _globalTypes.findType(XmlQNameImpl.validateLexical(value, _vc, event));
} catch (Throwable t) {
if (ExceptionUtil.isFatal(t)) {
ExceptionUtil.rethrow(t);
}
_errorState++;
} finally {
_suspendErrors--;
}
if (originalErrorState != _errorState) {
// not sure how to extract this one
emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_INVALID_QNAME,
new Object[]{value}, event.getName(), xsiType, null,
XmlValidationError.ELEMENT_TYPE_INVALID, (state == null ? null : state._type));
_eatContent = 1;
return;
} else if (xsiType == null) {
// NOT SURE errorAttributes._expectedSchemaType = xsiType;
emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_NOT_FOUND,
new Object[]{value}, event.getName(), null, null,
XmlValidationError.ELEMENT_TYPE_INVALID, null);
_eatContent = 1;
return;
}
}
if (xsiType != null && !xsiType.equals(elementType)) {
if (!elementType.isAssignableFrom(xsiType)) {
emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_NOT_DERIVED,
new Object[]{xsiType, elementType}, event.getName(), elementType, null,
XmlValidationError.ELEMENT_TYPE_INVALID, (state == null ? null : state._type));
_eatContent = 1;
return;
}
if (elementType.blockExtension()) {
for (SchemaType t = xsiType; !t.equals(elementType);
t = t.getBaseType()) {
if (t.getDerivationType() == SchemaType.DT_EXTENSION) {
emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_BLOCK_EXTENSION,
new Object[]{xsiType, elementType}, event.getName(), elementType, null,
XmlValidationError.ELEMENT_TYPE_INVALID, (state == null ? null : state._type));
_eatContent = 1;
return;
}
}
}
if (elementType.blockRestriction()) {
for (SchemaType t = xsiType; !t.equals(elementType);
t = t.getBaseType()) {
if (t.getDerivationType() == SchemaType.DT_RESTRICTION) {
emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_BLOCK_RESTRICTION,
new Object[]{xsiType, elementType}, event.getName(), elementType, null,
XmlValidationError.ELEMENT_TYPE_INVALID, (state == null ? null : state._type));
_eatContent = 1;
return;
}
}
}
if (elementField instanceof SchemaLocalElement) {
SchemaLocalElement sle = (SchemaLocalElement) elementField;
_localElement = sle;
if (sle.blockExtension() || sle.blockRestriction()) {
for (SchemaType t = xsiType; !t.equals(elementType);
t = t.getBaseType()) {
if ((t.getDerivationType() == SchemaType.DT_RESTRICTION && sle.blockRestriction()) ||
(t.getDerivationType() == SchemaType.DT_EXTENSION && sle.blockExtension())) {
//need to find a way to get the right type
emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_PROHIBITED_SUBST,
new Object[]{xsiType, QNameHelper.pretty(sle.getName())},
sle.getName(), null, null, XmlValidationError.ELEMENT_TYPE_INVALID, null);
_eatContent = 1;
return;
}
}
}
}
elementType = xsiType;
}
if (elementField instanceof SchemaLocalElement) {
SchemaLocalElement sle = (SchemaLocalElement) elementField;
_localElement = sle;
if (sle.isAbstract()) {
//todo (dutta) need to find a way to get the right type
emitError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$ABSTRACT,
new Object[]{QNameHelper.pretty(sle.getName())},
sle.getName(), null, XmlValidationError.ELEMENT_TYPE_INVALID, null);
_eatContent = 1;
return;
}
}
if (elementType.isAbstract()) {
emitError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$ABSTRACT,
new Object[]{elementType},
event.getName(), elementType, XmlValidationError.ELEMENT_TYPE_INVALID, (state == null ? null : state._type));
_eatContent = 1;
return;
}
boolean isNil = false;
boolean hasNil = false;
String nilValue = event.getXsiNil();
if (nilValue != null) {
_vc._event = event;
isNil = JavaBooleanHolder.validateLexical(nilValue, _vc);
hasNil = true;
}
// note in schema spec 3.3.4, you're not even allowed to say xsi:nil="false" if you're not nillable!
if (hasNil && (elementField == null || !elementField.isNillable())) {
emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$NOT_NILLABLE, null,
elementField == null ? null : elementField.getName(), elementType, null,
XmlValidationError.ELEMENT_TYPE_INVALID, (state == null ? null : state._type));
_eatContent = 1;
return;
}
if (isNil && elementField != null && elementField.isFixed()) {
emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$NIL_WITH_FIXED, null,
elementField.getName(), elementType, null,
XmlValidationError.ELEMENT_TYPE_INVALID, (state == null ? null : state._type));
}
newState(elementType, elementField, isNil);
// Dispatch this element event to any identity constraints
// As well as adding any new identity constraints that exist
_constraintEngine.element(
event,
elementType,
elementField instanceof SchemaLocalElement
? ((SchemaLocalElement) elementField).getIdentityConstraints()
: null);
}