public void emit(Root root) { m_root = root; m_errors = new ErrorReport(); m_symbols = new SymbolTable(m_errors, m_root); m_links = new HashSet(); m_fks = new HashSet(); m_propertyCollisions = new HashMap(); m_emitted = new HashMap(); m_nodes = new HashMap();  m_ast.traverse(new Node.Switch() { public void onNode(Node nd) { for (Iterator it = nd.getFields().iterator(); it.hasNext(); ) { String error = nd.validate((Node.Field) it.next()); if (error != null) { m_errors.fatal(nd, error); } } } });  m_errors.check();  if (m_autoLoad && root.getObjectType("global.String") == null) { emitGlobal(root); }  for (Iterator it = m_root.getObjectTypes().iterator(); it.hasNext(); ) { m_symbols.addEmitted((ObjectType) it.next()); }  m_ast.traverse(new Node.Switch() { public void onObjectType(ObjectTypeNd ot) { if (ot.hasReturns()) { m_errors.warn(ot, "returns clause is deprecated"); } m_symbols.define(ot); } });  m_errors.check();  m_ast.traverse(new Node.Switch() { public void onType(TypeNd t) { m_symbols.resolve(t); } });  m_errors.check();  m_symbols.sort();  m_errors.check();  m_symbols.emit();  m_ast.traverse(new Node.Switch() { public void onAssociation(AssociationNd assn) { if (assn.getProperties().size() == 0) { return; }  ObjectType ot = new ObjectType (Model.getInstance (assn.getFile().getModel().getName()), linkName(assn.getRoleOne(), assn.getRoleTwo()), null); m_symbols.addEmitted(ot); } });  m_ast.traverse(new Node.Switch() { private Role define(ObjectType type, PropertyNd prop) { String name = prop.getName().getName();   Property prev = (Property) m_propertyCollisions.get (type.getQualifiedName() + ":" + name); if (prev == null) { prev = type.getProperty(name); } if (prev != null) { m_errors.fatal (prop, "duplicate property: " + name + ", previous definition: " + getNode(prev).getLocation()); return null; }   Integer upper = prop.getUpper(); Integer lower = prop.getLower(); if (upper != null && upper.intValue() <= 0 || lower != null && lower.intValue() < 0 || (upper != null && lower != null && upper.intValue() < lower.intValue())) { m_errors.fatal(prop, "bad multiplicity: " + name); return null; }   Role result = new Role(prop.getName().getName(), m_symbols.getEmitted(prop.getType()), prop.isComponent(), prop.isCollection(), prop.isNullable()); m_symbols.setLocation(result, prop);  type.addProperty(result); if (prop.isImmediate()) { type.addImmediateProperty(result); }   emit(prop, result);   ObjectType ot = type; while (ot != null) { m_propertyCollisions.put (ot.getQualifiedName() + ":" + name, result); ot = ot.getSupertype(); }  return result; }  public void onProperty(PropertyNd prop) { ObjectType type = m_symbols.getEmitted((ObjectTypeNd) prop.getParent());  Role role = define(type, prop);   if (prop.isComposite()) { String rev = "~" + prop.getName().getName() + ":" + type.getQualifiedName().replace('.', '$'); Role reverse = new Role(rev, type, true, true, true); role.getType().addProperty(reverse); role.setReverse(reverse); } }  public void onAssociation(AssociationNd assn) { PropertyNd one = assn.getRoleOne(); PropertyNd two = assn.getRoleTwo(); if (one.isComposite()) { two.setComponent(); } if (two.isComposite()) { one.setComponent(); } Collection props = assn.getProperties(); ObjectType oneot = m_symbols.getEmitted(one.getType()); ObjectType twoot = m_symbols.getEmitted(two.getType());  if (props.size() > 0) { Role rone = new Role(one.getName().getName(), oneot, one.isComponent(), false, false); m_symbols.setLocation(rone, one); Role rtwo = new Role(two.getName().getName(), twoot, two.isComponent(), false, false); m_symbols.setLocation(rtwo, two);  ObjectType ot = m_symbols.getEmitted(linkName(assn));  ot.addProperty(rone); Role revOne = new Role(rtwo.getName() + LINK, ot, true, two.isCollection(), two.isNullable()); rone.getType().addProperty(revOne); rone.setReverse(revOne);  ot.addProperty(rtwo); Role revTwo = new Role(rone.getName() + LINK, ot, true, one.isCollection(), one.isNullable()); rtwo.getType().addProperty(revTwo); rtwo.setReverse(revTwo);  for (Iterator it = props.iterator(); it.hasNext(); ) { PropertyNd prop = (PropertyNd) it.next(); define(ot, prop); }  Link l = new Link(rone.getName(), rtwo, rone, one.isCollection(), one.isNullable()); m_symbols.setLocation(l, one); m_links.add(l); twoot.addProperty(l); l = new Link(rtwo.getName(), rone, rtwo, two.isCollection(), two.isNullable()); m_symbols.setLocation(l, two); m_links.add(l); oneot.addProperty(l); } else { Role rone = define(oneot, two); Role rtwo = define(twoot, one); if (rone != null && rtwo != null) { rone.setReverse(rtwo); } } } }, new Node.IncludeFilter(new Node.Field[] { AST.FILES, FileNd.OBJECT_TYPES, ObjectTypeNd.PROPERTIES, FileNd.ASSOCIATIONS }));  m_errors.check();  for (Iterator it = m_symbols.getObjectTypes().iterator(); it.hasNext(); ) { ObjectTypeNd ot = (ObjectTypeNd) it.next(); m_root.addObjectType(m_symbols.getEmitted(ot)); }  m_ast.traverse(new Node.Switch() { public void onObjectType(ObjectTypeNd otn) { ObjectMap om = new ObjectMap(m_symbols.getEmitted(otn)); m_root.addObjectMap(om); m_symbols.setLocation(om, otn); } public void onAssociation(AssociationNd assn) { ObjectType ot = m_symbols.getEmitted(linkName(assn)); if (ot != null) { ObjectMap om = new ObjectMap(ot); m_root.addObjectType(ot); m_root.addObjectMap(om); m_symbols.setLocation(om, assn); } } });  emitDDL();  m_errors.check();  emitMapping();  m_errors.check();  emitEvents();  m_errors.check();  emitDataOperations();  m_errors.check();  m_ast.traverse(new Node.Switch() { public void onObjectType(ObjectTypeNd nd) { ObjectType ot = m_symbols.getEmitted(nd); JavaClassNd jcn = nd.getJavaClass(); JavaClassNd acn = nd.getAdapterClass();  if (jcn == null || acn == null) { return; }  Class javaClass; try { javaClass = Class.forName(jcn.getName()); } catch (ClassNotFoundException e) { m_errors.fatal(jcn, e.getMessage()); return; }  ot.setJavaClass(javaClass);  try { Class adapterClass = Class.forName(acn.getName()); Adapter ad = (Adapter) adapterClass.newInstance(); m_root.addAdapter(javaClass, ad); } catch (IllegalAccessException e) { m_errors.fatal (acn, "illegal access: " + e.getMessage()); } catch (ClassNotFoundException e) { m_errors.fatal (acn, "class not found: " + e.getMessage()); } catch (InstantiationException e) { m_errors.fatal (acn, "instantiation exception: " + e.getMessage()); } } });  m_errors.check();  m_ast.traverse(new Node.Switch() { public void onProperty(PropertyNd pnd) { Node n = pnd.getMapping(); if (!(n instanceof ColumnNd)) { return; }  ObjectType ot = m_symbols.getEmitted(pnd.getType()); Column col = lookup((ColumnNd)n); if (col.getType() == Integer.MIN_VALUE) { Adapter ad = m_root.getAdapter(ot.getJavaClass()); col.setType(ad.defaultJDBCType()); } } });  propogateTypes();  m_errors.check();  m_ast.traverse(new Node.Switch() { public void onSuper(SuperNd sn) { m_errors.warn (sn, "super is no longer necessary and deprecated, " + "please remove"); } });  m_errors.check();
void emit(Node node, Object emitted) { m_nodes.put(emitted, node); m_emitted.put(node, emitted);
    public void emit(Root root) {	m_root = root;        m_errors = new ErrorReport();        m_symbols = new SymbolTable(m_errors, m_root);        m_links = new HashSet();        m_fks = new HashSet();        m_propertyCollisions = new HashMap();        m_emitted = new HashMap();        m_nodes = new HashMap();        m_ast.traverse(new Node.Switch() {            public void onNode(Node nd) {                for (Iterator it = nd.getFields().iterator(); it.hasNext(); ) {                    String error = nd.validate((Node.Field) it.next());                    if (error != null) {                        m_errors.fatal(nd, error);                    }                }            }        });        m_errors.check();        if (m_autoLoad && root.getObjectType("global.String") == null) {            emitGlobal(root);        }        for (Iterator it = m_root.getObjectTypes().iterator();	     it.hasNext(); ) {            m_symbols.addEmitted((ObjectType) it.next());        }        m_ast.traverse(new Node.Switch() {                public void onObjectType(ObjectTypeNd ot) {                    if (ot.hasReturns()) {                        m_errors.warn(ot, "returns clause is deprecated");                    }                    m_symbols.define(ot);                }            });	m_errors.check();        m_ast.traverse(new Node.Switch() {                public void onType(TypeNd t) {                    m_symbols.resolve(t);                }            });	m_errors.check();        m_symbols.sort();	m_errors.check();        m_symbols.emit();	m_ast.traverse(new Node.Switch() {		public void onAssociation(AssociationNd assn) {		    if (assn.getProperties().size() == 0) {			return;		    }		    ObjectType ot = new ObjectType			(Model.getInstance			 (assn.getFile().getModel().getName()),			 linkName(assn.getRoleOne(), assn.getRoleTwo()), null);		    m_symbols.addEmitted(ot);		}	    });        m_ast.traverse(new Node.Switch() {                private Role define(ObjectType type, PropertyNd prop) {                    String name = prop.getName().getName();                    // Check for collisions                    Property prev = (Property) m_propertyCollisions.get                        (type.getQualifiedName() + ":" + name);                    if (prev == null) {                        prev = type.getProperty(name);                    }                    if (prev != null) {                        m_errors.fatal                            (prop, "duplicate property: " + name +                             ", previous definition: " +                             getNode(prev).getLocation());                        return null;                    }                    // Check for bad multiplicity                    Integer upper = prop.getUpper();                    Integer lower = prop.getLower();                    if (upper != null && upper.intValue() <= 0                        || lower != null && lower.intValue() < 0                        || (upper != null && lower != null                            && upper.intValue() < lower.intValue())) {                        m_errors.fatal(prop, "bad multiplicity: " + name);                        return null;                    }                    // Create the property                    Role result =                        new Role(prop.getName().getName(),                                 m_symbols.getEmitted(prop.getType()),                                 prop.isComponent(),                                 prop.isCollection(),                                 prop.isNullable());                    m_symbols.setLocation(result, prop);                    type.addProperty(result);                    if (prop.isImmediate()) {                        type.addImmediateProperty(result);                    }                    // Track what node defined this property and vice versa                    emit(prop, result);                    // Track for collision detection                    ObjectType ot = type;                    while (ot != null) {                        m_propertyCollisions.put                            (ot.getQualifiedName() + ":" + name, result);                        ot = ot.getSupertype();                    }                    return result;                }                public void onProperty(PropertyNd prop) {                    ObjectType type =                        m_symbols.getEmitted((ObjectTypeNd) prop.getParent());                    Role role = define(type, prop);                    /* if the property is a composite, the other end is a                     * needs to be set up for cascading deletes to work                     */                    if (prop.isComposite()) {                        String rev = "~" + prop.getName().getName() + ":" +                            type.getQualifiedName().replace('.', '$');                        Role reverse = new Role(rev, type, true, true, true);                        role.getType().addProperty(reverse);                        role.setReverse(reverse);                    }                }                public void onAssociation(AssociationNd assn) {		    PropertyNd one = assn.getRoleOne();		    PropertyNd two = assn.getRoleTwo();                    if (one.isComposite()) { two.setComponent(); }                    if (two.isComposite()) { one.setComponent(); }		    Collection props = assn.getProperties();		    ObjectType oneot =			m_symbols.getEmitted(one.getType());		    ObjectType twoot =			m_symbols.getEmitted(two.getType());		    if (props.size() > 0) {			Role rone = new Role(one.getName().getName(), oneot,					     one.isComponent(), false, false);                        m_symbols.setLocation(rone, one);			Role rtwo = new Role(two.getName().getName(), twoot,					     two.isComponent(), false, false);                        m_symbols.setLocation(rtwo, two);			ObjectType ot = m_symbols.getEmitted(linkName(assn));			ot.addProperty(rone);			Role revOne = new Role(rtwo.getName() + LINK, ot,                                               true,                                               two.isCollection(),                                               two.isNullable());			rone.getType().addProperty(revOne);			rone.setReverse(revOne);			ot.addProperty(rtwo);			Role revTwo = new Role(rone.getName() + LINK, ot,                                               true,                                               one.isCollection(),                                               one.isNullable());			rtwo.getType().addProperty(revTwo);			rtwo.setReverse(revTwo);			for (Iterator it = props.iterator(); it.hasNext(); ) {			    PropertyNd prop = (PropertyNd) it.next();			    define(ot, prop);			}			Link l = new Link(rone.getName(), rtwo, rone,					  one.isCollection(),					  one.isNullable());                        m_symbols.setLocation(l, one);			m_links.add(l);			twoot.addProperty(l);			l = new Link(rtwo.getName(), rone, rtwo,				     two.isCollection(), two.isNullable());                        m_symbols.setLocation(l, two);			m_links.add(l);			oneot.addProperty(l);		    } else {			Role rone = define(oneot, two);			Role rtwo = define(twoot, one);			if (rone != null && rtwo != null) {			    rone.setReverse(rtwo);			}		    }                }            }, new Node.IncludeFilter(new Node.Field[] {                AST.FILES, FileNd.OBJECT_TYPES, ObjectTypeNd.PROPERTIES,                FileNd.ASSOCIATIONS            }));        m_errors.check();        for (Iterator it = m_symbols.getObjectTypes().iterator();             it.hasNext(); ) {            ObjectTypeNd ot = (ObjectTypeNd) it.next();            m_root.addObjectType(m_symbols.getEmitted(ot));        }        m_ast.traverse(new Node.Switch() {                public void onObjectType(ObjectTypeNd otn) {                    ObjectMap om = new ObjectMap(m_symbols.getEmitted(otn));                    m_root.addObjectMap(om);                    m_symbols.setLocation(om, otn);                }		public void onAssociation(AssociationNd assn) {		    ObjectType ot = m_symbols.getEmitted(linkName(assn));		    if (ot != null) {                        ObjectMap om = new ObjectMap(ot);                        m_root.addObjectType(ot);			m_root.addObjectMap(om);                        m_symbols.setLocation(om, assn);		    }		}            });        emitDDL();        m_errors.check();        emitMapping();        m_errors.check();        emitEvents();        m_errors.check();        emitDataOperations();        m_errors.check();	m_ast.traverse(new Node.Switch() {		public void onObjectType(ObjectTypeNd nd) {		    ObjectType ot = m_symbols.getEmitted(nd);		    JavaClassNd jcn = nd.getJavaClass();		    JavaClassNd acn = nd.getAdapterClass();		    if (jcn == null || acn == null) {			return;		    }		    Class javaClass;		    try {			javaClass = Class.forName(jcn.getName());		    } catch (ClassNotFoundException e) {			m_errors.fatal(jcn, e.getMessage());			return;		    }		    ot.setJavaClass(javaClass);		    try {			Class adapterClass = Class.forName(acn.getName());			Adapter ad = (Adapter) adapterClass.newInstance();			m_root.addAdapter(javaClass, ad);		    } catch (IllegalAccessException e) {			m_errors.fatal                            (acn, "illegal access: " + e.getMessage());		    } catch (ClassNotFoundException e) {			m_errors.fatal                            (acn, "class not found: " + e.getMessage());		    } catch (InstantiationException e) {			m_errors.fatal                            (acn, "instantiation exception: " +                             e.getMessage());		    }		}	    });	m_errors.check();        m_ast.traverse(new Node.Switch() {            public void onProperty(PropertyNd pnd) {                Node n = pnd.getMapping();                if (!(n instanceof ColumnNd)) {                    return;                }                ObjectType ot = m_symbols.getEmitted(pnd.getType());                Column col = lookup((ColumnNd)n);                if (col.getType() == Integer.MIN_VALUE) {                    Adapter ad = m_root.getAdapter(ot.getJavaClass());                    col.setType(ad.defaultJDBCType());                }            }        });	propogateTypes();        m_errors.check();        m_ast.traverse(new Node.Switch() {            public void onSuper(SuperNd sn) {                m_errors.warn                    (sn, "super is no longer necessary and deprecated, " +                     "please remove");            }        });        m_errors.check();    }