Iterator itr = defaultedAttributes.entrySet().iterator();
ResidualCalculator resCalc = new ResidualCalculator(reader.pool);
while( itr.hasNext() ) {
Map.Entry item = (Map.Entry)itr.next();
AttributeExp exp = (AttributeExp)item.getKey();
String value = (String)item.getValue();
// tests if the name class is simple
if(!(exp.nameClass instanceof SimpleNameClass))
reportCompError(
new Locator[]{reader.getDeclaredLocationOf(exp)},
CERR_DEFVALUE_NAME_IS_NOT_SIMPLE);
// tests if there is no context-dependent datatypes
try {
exp.exp.visit( contextDependentTypeChecker );
} catch( Abort a ) {
continue; // abort further check. this error is already reported.
}
// tests if the default value matches the content model of this attribute
StringToken token = new StringToken(resCalc,value,null,null);
if(!resCalc.calcResidual( exp.exp, token ).isEpsilonReducible() ) {
// the default value was rejected by the content model.
reportCompError(
new Locator[]{reader.getDeclaredLocationOf(exp)},
CERR_DEFVALUE_INVALID, new Object[]{value});
}
}
if( !grammar.isDefaultAttributeValueCompatible )
// if there already is an error, abort further check.
return;
// a map from element names to DefAttMap
final Map name2value = new HashMap();
// a set of all ElementExps in the grammar.
final Set elements = new HashSet();
// tests if defaulted attributes are optional and doesn't have
// oneOrMoreAncestor.
// also (element name,attribute name)->default value
// map is created here.
grammar.visit( new ExpressionWalker() {
// in the first pass, the elements variable
// is used to record visited ElementExps.
// condition that has to be met for default attributes to be valid.
private boolean inOneOrMore = false;
private boolean inChoice = false;
private boolean inOptionalChoice = false;
private boolean inSimpleElement = false;
/**
* A map from attribute name to defaulted AttributeExps
* of the current element.
*/
private Map currentAttributes = null;
/**
* name of the current ElementExp
* within which we are currently processing.
*/
private SimpleNameClass currentElementName = null;
public void onElement( ElementExp exp ) {
if( !elements.add(exp) )
return; // this element is already checked.
// otherwise check the content model of this element.
// update the value of the isSimpleElement field.
final boolean oldSE = inSimpleElement;
final boolean oldOC = inOptionalChoice;
final boolean oldC = inChoice;
final boolean oldOOM = inOneOrMore;
final SimpleNameClass prevElemName = currentElementName;
final Map oldCA = currentAttributes;
inSimpleElement = (exp.getNameClass() instanceof SimpleNameClass);
inOptionalChoice = true;
inChoice = false;
inOneOrMore = false;
StringPair en = null;
if(inSimpleElement) {
currentElementName = (SimpleNameClass)exp.getNameClass();
en = new StringPair(currentElementName);
currentAttributes = new HashMap();
} else
currentElementName = null;