_wildcardElement = null;
String message = 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, "Nil element cannot have element content");
_eatContent = 1;
return;
}
if (!state.visit( name ))
{
message = findDetailedErrorBegin(state , name);
if (message != null)
{
emitFieldError(event, message);
message = null;
}
else
{
emitFieldError(event, "Element not allowed:", 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
emitFieldError( event, "Element not allowed:", name );
_eatContent = 1;
return;
}
int wildcardProcess = currentParticle.getWildcardProcess();
if (wildcardProcess == SchemaParticle.SKIP)
{
_eatContent = 1;
return;
}
_localElement = _globalTypes.findElement( name );
elementField = _localElement;
if (elementField == null)
{
if (wildcardProcess == SchemaParticle.STRICT)
{
emitFieldError(
event, "Element not allowed (strict wildcard, and no definition found):", name );
}
_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,
"Element substitution not allowed when group head has block='substitution'", name);
_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, "Invalid type.");
_eatContent = 1;
}
//
// See if the element has an xsi:type on it
//
SchemaType xsiType = null;
if (event.getXsiType( _chars ))
{
String value = _chars.asString();
// 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)
{
emitFieldError(
event, "Invalid xsi:type qname: '" + value + "'" );
_eatContent = 1;
return;
}
else if (xsiType == null)
{
emitError(event, "Could not find xsi:type: '" + value + "'");
_eatContent = 1;
return;
}
}
if (xsiType != null && !xsiType.equals(elementType))
{
if (!elementType.isAssignableFrom(xsiType))
{
emitFieldError(
event,
"Type '" + xsiType +
"' is not derived from '" + elementType + "'" );
_eatContent = 1;
return;
}
if (elementType.blockExtension())
{
for ( SchemaType t = xsiType ; ! t.equals( elementType ) ;
t = t.getBaseType() )
{
if (t.getDerivationType() == SchemaType.DT_EXTENSION)
{
emitFieldError(
event,
"Extension type: '" + xsiType +
"' may not be substituted for: '" +
elementType + "'" );
_eatContent = 1;
return;
}
}
}
if (elementType.blockRestriction())
{
for ( SchemaType t = xsiType ; ! t.equals( elementType ) ;
t = t.getBaseType() )
{
if (t.getDerivationType() == SchemaType.DT_RESTRICTION)
{
emitFieldError(
event,
"Restriction type: '" + xsiType +
"' may not be substituted for: '" +
elementType + "'" );
_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()))
{
emitError(
event,
"Derived type: '" + xsiType +
"' may not be substituted for element '" +
QNameHelper.pretty(sle.getName()) + "'" );
_eatContent = 1;
return;
}
}
}
}
elementType = xsiType;
}
if (elementField instanceof SchemaLocalElement)
{
SchemaLocalElement sle = (SchemaLocalElement)elementField;
_localElement = sle;
if (sle.isAbstract())
{
emitError(event, "Element '" + QNameHelper.pretty(sle.getName()) +
"' is abstract and cannot be used in an instance.");
_eatContent = 1;
return;
}
}
if (elementType != null && elementType.isAbstract())
{
emitFieldError(
event,
"Abstract type: " + elementType +
" cannot be used in an instance" );
_eatContent = 1;
return;
}
boolean isNil = false;
boolean hasNil = false;
if (event.getXsiNil(_chars))
{
_vc._event = event;
isNil = JavaBooleanHolder.validateLexical(_chars.asString(), _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.isNillable())
{
emitFieldError(event, "Element has xsi:nil attribute but is not nillable");
_eatContent = 1;
return;