_localElement = null;
_wildcardElement = null;
State state = topState();
SchemaType elementType = null;
SchemaField elementField = null;
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._isNil && 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;
if (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 )
{
_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._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, null, XmlValidationError.ELEMENT_TYPE_INVALID, null);
_eatContent = 1;
return;
}
}
if (elementType != null && elementType.isAbstract())
{
emitError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$ABSTRACT,
new Object[] { elementType },
event.getName(), elementType, null, 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 == null ? null : elementField.getName(), elementType, null,
XmlValidationError.ELEMENT_TYPE_INVALID, (state == null ? null : state._type));
}
newState( elementType, elementField, isNil );