// if an error was found, stop processing.
if( hadError ) return exp;
// check Tahiti attributes.
final StartTagInfo tag = state.getStartTag();
String role = tag.getAttribute(TahitiNamespace,"role");
if( role==null ) {
// there is no markup.
// insert an ClassItem if this is the <element> tag.
// some of those temporarily added ClassItems will be removed
// in the final wrap up.
if( tag.localName.equals("element") ) {
// if( exp instanceof ElementExp ) {
/*
ElementExp eexp = (ElementExp)exp;
// add a ClassItem between the ElementExp and the content model.
ClassItem t = annGrammar.createClassItem( decideName(state,exp,"class"), eexp.contentModel );
eexp.contentModel = t;
t.isTemporary = true; // this flag indicates that this class item is a temporary one.
return eexp;
*/
// to make marshalling easy, ClassItem is generated above the ElementExp
// calculate the unique name to avoid name conflicts.
String baseName = decideName(state,exp,"class");
if( annGrammar.classes.containsKey(baseName) ) {
int cnt = 2;
while( annGrammar.classes.containsKey(baseName+cnt) )
cnt++;
baseName += cnt;
}
ClassItem t = annGrammar.createClassItem( baseName, exp );
t.isTemporary = true;
return t;
} else {
// if this element has the t:name attribute, store that
// information by using a ReferenceExp. This information
// might be useful to various annotators.
// String name = tag.getAttribute(TahitiNamespace,"name");
// if(name!=null) exp = new ReferenceExp( name, exp );
}
return exp; // the "role" attribute is not present.
}
OtherExp roleExp;
if( role.equals("none") ) {
// do nothing. this will prevent automatic ClassItem insertion.
return exp;
} else
if( role.equals("superClass") ) {
roleExp = new SuperClassItem();
} else
if( role.equals("class") ) {
/*
removes silly use of temporary ClassItem.
Consider the following grammar fragment:
<define name="foo" t:role="class">
<element name="foo">
...
</element>
</define>
Since there is no tahiti markup for <element> element, a temporary ClassItem
is inserted. Immediately after that, a <define> element is processed, and
a new ClassItem is inserted.
The following code is a quick hack to prevent this situation by removing
temporary ClassItem if it is the immediate child of the user-defined class.
*/
/*
We changed the code and now temporary class items are generated
*above* elements. So now this code is unnecessary.
*/
/* TODO:
we have to think in much broader view.
This could be done as a part of temporary class item removal.
Otherwise, we have to implement this mechanism to every reader.
Also, this particular situation would interact with the combine attribute.
*/
/* if( (exp instanceof ClassItem) && ((ClassItem)exp).isTemporary )
exp = ((ClassItem)exp).exp;
if( exp.getClass()==ReferenceExp.class ) {
ReferenceExp rexp = (ReferenceExp)exp;
if( (rexp.exp instanceof ClassItem) && ((ClassItem)rexp.exp).isTemporary )
rexp.exp = ((ClassItem)rexp.exp).exp;
}
*/
roleExp = annGrammar.createClassItem(decideName(state,exp,role),null);
} else
if( role.equals("field") ) {
FieldItem fi = new FieldItem(decideName(state,exp,role));
roleExp = fi;
// read the additional configuration.
String collection = tag.getAttribute(TahitiNamespace,"collection");
if(collection!=null) {
fi.collectionType = fi.collectionType.parse(collection);
if(fi.collectionType==null)
reportError( ERR_INVALID_COLLECTION_TYPE, collection );
}
String access = tag.getAttribute(TahitiNamespace,"access");
if(access!=null) {
fi.accessModifier = fi.accessModifier.parse(access);
if(fi.accessModifier==null)
reportError( ERR_INVALID_ACCESS_MODIFIER, access );
}
String method = tag.getAttribute(TahitiNamespace,"method");
if(method!=null) {
fi.accessor = fi.accessor.parse(method);
if(fi.accessModifier==null)
reportError( ERR_INVALID_ACCESSOR, method );
}