{
int cnt=0; // use to name anonymous RefExp.
Iterator itr = heads.iterator();
while( itr.hasNext() ) {
Expression exp = (Expression)itr.next();
if( exp instanceof ReferenceExp ) {
ReferenceExp rexp = (ReferenceExp)exp;
if( rexp.name == null ) {
// generate unique name
while( name2exp.containsKey("anonymous"+cnt) )
cnt++;
name2exp.put( "anonymous"+cnt, exp );
} else
if( name2exp.containsKey(rexp.name) ) {
// name conflict. try to add suffix.
int i = 2;
while( name2exp.containsKey(rexp.name+i) )
i++;
name2exp.put( rexp.name+i, exp );
} else {
// name of this RefExp can be directly used without modification.
name2exp.put( rexp.name, exp );
}
}
else
if( exp instanceof ElementExp ) {
ElementExp eexp = (ElementExp)exp;
NameClass nc = eexp.getNameClass();
if( nc instanceof SimpleNameClass
&& !name2exp.containsKey( ((SimpleNameClass)nc).localName ) )
name2exp.put( ((SimpleNameClass)nc).localName, exp );
else {
// generate unique name
while( name2exp.containsKey("element"+cnt) )
cnt++;
name2exp.put( "element"+cnt, exp );
}
} else
throw new Error(); // assertion failed.
// it must be ElementExp or ReferenceExp.
}
}
// then reverse name2ref to ref2name
exp2name = new HashMap();
{
Iterator itr = name2exp.keySet().iterator();
while( itr.hasNext() ) {
String name = (String)itr.next();
exp2name.put( name2exp.get(name), name );
}
}
nameClassWriter = createNameClassWriter();
// generates SAX events
try {
final DocumentHandler handler = writer.getDocumentHandler();
handler.setDocumentLocator( new LocatorImpl() );
handler.startDocument();
// to work around the bug of current serializer,
// report xmlns declarations as attributes.
if( defaultNs!=null )
writer.start("grammar",new String[]{
"ns",defaultNs,
"xmlns",RELAXNGReader.RELAXNGNamespace,
"datatypeLibrary", XSDVocabulary.XMLSchemaNamespace });
else
writer.start("grammar", new String[]{
"xmlns",RELAXNGReader.RELAXNGNamespace,
"datatypeLibrary", XSDVocabulary.XMLSchemaNamespace });
{// write start pattern.
writer.start("start");
writeIsland( g.getTopLevel() );
writer.end("start");
}
// write all named expressions
Iterator itr = exp2name.keySet().iterator();
while( itr.hasNext() ) {
Expression exp = (Expression)itr.next();
String name = (String)exp2name.get(exp);
if( exp instanceof ReferenceExp )
exp = ((ReferenceExp)exp).exp;
writer.start("define",new String[]{"name",name});
writeIsland( exp );