if (role.isCollection()) { m_errors.fatal (id, "collections cannot be keys: " + id.getName()); } else { om.getKeyProperties().add(role); role.setNullable(false); } } } }, new Node.IncludeFilter(new Node.Field[] { AST.FILES, FileNd.OBJECT_TYPES, ObjectTypeNd.PROPERTIES, PropertyNd.NESTED_MAP, NestedMapNd.OBJECT_KEY, NestedMapNd.MAPPINGS, NestedMappingNd.NESTED_MAP, ObjectTypeNd.OBJECT_KEY, ObjectKeyNd.PROPERTIES }));
om.getKeyProperties().add(role); role.setNullable(false); } } } }, new Node.IncludeFilter(new Node.Field[] { AST.FILES, FileNd.OBJECT_TYPES, ObjectTypeNd.PROPERTIES, PropertyNd.NESTED_MAP, NestedMapNd.OBJECT_KEY, NestedMapNd.MAPPINGS, NestedMappingNd.NESTED_MAP, ObjectTypeNd.OBJECT_KEY, ObjectKeyNd.PROPERTIES }));
    private void emitMapping() {        m_ast.traverse(new Node.Switch() {                public void onIdentifier(IdentifierNd id) {                    ObjectMap om = getMap(id.getParent().getParent());                    ObjectType ot = om.getObjectType();                    Role role = (Role) ot.getProperty(id.getName());                    if (role == null) {                        m_errors.fatal                            (id, "no such property: " + id.getName());                    } else {                        if (role.isCollection()) {                            m_errors.fatal                                (id, "collections cannot be keys: " +                                 id.getName());                        } else {                            om.getKeyProperties().add(role);                            role.setNullable(false);                        }                    }                }            }, new Node.IncludeFilter(new Node.Field[] {                AST.FILES, FileNd.OBJECT_TYPES, ObjectTypeNd.PROPERTIES,                PropertyNd.NESTED_MAP, NestedMapNd.OBJECT_KEY,                NestedMapNd.MAPPINGS, NestedMappingNd.NESTED_MAP,                ObjectTypeNd.OBJECT_KEY, ObjectKeyNd.PROPERTIES            }));	m_ast.traverse(new Node.Switch() {		public void onAssociation(AssociationNd assn) {		    if (assn.getProperties().size() == 0) {			return;		    }		    PropertyNd one = assn.getRoleOne();		    PropertyNd two = assn.getRoleTwo();		    ObjectType ot = m_symbols.getEmitted(linkName(assn));		    ObjectMap om = m_root.getObjectMap(ot);		    Collection keys = om.getKeyProperties();		    Role pone = (Role) ot.getProperty(one.getName().getName());		    Role ptwo = (Role) ot.getProperty(two.getName().getName());                    Link lone = (Link)                        ptwo.getType().getProperty(pone.getName());                    Link ltwo = (Link)                        pone.getType().getProperty(ptwo.getName());		    keys.add(ptwo);		    keys.add(pone);		    if (one.getMapping() != null) {			emitMapping(pone, (JoinPathNd) one.getMapping(), 1, 2);			emitMapping(pone.getReverse(),				    (JoinPathNd) two.getMapping(), 0, 1);                        emitMapping(ltwo, (JoinPathNd) two.getMapping(), 0, 2);		    } else {			om.addMapping(new Static(Path.get(pone.getName())));                        ObjectMap oneom = m_root.getObjectMap(pone.getType());                        oneom.addMapping                            (new Static                             (Path.get(pone.getReverse().getName())));                        oneom.addMapping(new Static(Path.get(ltwo.getName())));		    }		    if (two.getMapping() != null) {			emitMapping(ptwo, (JoinPathNd) two.getMapping(), 1, 2);			emitMapping(ptwo.getReverse(),				    (JoinPathNd) one.getMapping(), 0, 1);                        emitMapping(lone, (JoinPathNd) one.getMapping(), 0, 2);		    } else {			om.addMapping(new Static(Path.get(ptwo.getName())));                        ObjectMap twoom = m_root.getObjectMap(ptwo.getType());                        twoom.addMapping			    (new Static			     (Path.get(ptwo.getReverse().getName())));                        twoom.addMapping(new Static(Path.get(lone.getName())));		    }		    String[] paths = new String[] { pone.getName(),						    ptwo.getName() };		    for (int i = 0; i < paths.length; i++) {			Mapping m = om.getMapping(Path.get(paths[i]));			if (m.getTable() != null) {			    om.setTable(m.getTable());			    break;			}		    }		}	    });        m_ast.traverse(new Node.Switch() {            public void onProperty(PropertyNd pn) {                emit(pn);                Node mapping = getMapping(pn);                Role prop = (Role) getEmitted(pn);                // auto generate reverse way for one-way composites                if (pn.isComposite()                    && pn.getParent() instanceof ObjectTypeNd) {                    if (mapping == null) {                        m_errors.fatal                            (pn, "one-way composite must have metadata");                    } else {                        Role rev = prop.getReverse();                        if (mapping instanceof JoinPathNd) {                            emitMapping(rev, (JoinPathNd) mapping, true);                        } else {                            m_errors.fatal(pn, "must have a join path");                        }                    }                }            }            public void onNestedMapping(NestedMappingNd nm) {                emit(nm);            }            private Node getMapping(Node nd) {                if (nd instanceof PropertyNd) {                    return (Node) nd.get(PropertyNd.MAPPING);                } else if (nd instanceof NestedMappingNd) {                    return (Node) nd.get(NestedMappingNd.MAPPING);                } else {                    throw new IllegalArgumentException("" + nd);                }            }            private NestedMapNd getNestedMap(Node nd) {                if (nd instanceof PropertyNd) {                    return (NestedMapNd) nd.get(PropertyNd.NESTED_MAP);                } else if (nd instanceof NestedMappingNd) {                    return (NestedMapNd) nd.get(NestedMappingNd.NESTED_MAP);                } else {                    throw new IllegalArgumentException("" + nd);                }            }            private void emit(Node nd) {                ObjectMap om;                if (nd.getParent() instanceof AssociationNd) {                    Property p = (Property) getEmitted(nd);                    if (p == null) { return; }                    om = m_root.getObjectMap(p.getContainer());                } else {                    om = getMap(nd.getParent());                }                if (om == null) { return; }                Role prop = (Role) om.getObjectType().getProperty(getPath(nd));                if (prop == null) { return; }                Node mapping = getMapping(nd);                if (mapping == null) {                    Path p = Path.get(prop.getName());                    om.addMapping(new Static(p));                } else if (mapping instanceof ColumnNd) {                    emitMapping(om, prop, (ColumnNd) mapping);                } else if (mapping instanceof JoinPathNd) {                    emitMapping(om, prop, (JoinPathNd) mapping);                } else {                    emitMapping(om, prop, (QualiasNd) mapping);                }                if (!m_root.hasObjectMap(prop.getType())) {                    Mapping m = om.getMapping(prop);                    if (m != null) {                        NestedMapNd nm = getNestedMap(nd);                        if (nm == null) {                            m.setMap(new ObjectMap(prop.getType()));                        } else {                            m.setMap(getMap(nm));                        }                    }                }            }        });        m_ast.traverse(new Node.Switch() {                public void onReferenceKey(ReferenceKeyNd rkn) {                    Column key = lookup(rkn.getCol());                    ObjectMap om = getMap(rkn.getParent());                    om.setTable(key.getTable());                }                public void onObjectKey(ObjectKeyNd okn) {                    ObjectMap om = getMap(okn.getParent());                    IdentifierNd prop =                        (IdentifierNd) okn.getProperties().iterator().next();                    Mapping m = om.getMapping(Path.get(prop.getName()));                    if (m != null) {                        om.setTable(m.getTable());                    }                }            });	m_ast.traverse(new Node.Switch() {		public void onReferenceKey(ReferenceKeyNd rkn) {		    Column key = lookup(rkn.getCol());		    ObjectMap om = getMap(rkn.getParent());		    Column[] cols = new Column[] {key};		    if (key.getTable().getForeignKey(cols) == null) {			ObjectMap sm = om.getSuperMap();			Table table = null;			while (sm != null) {			    table = sm.getTable();			    if (table != null) {				break;			    }			    sm = sm.getSuperMap();			}			if (table == null) {			    throw new IllegalStateException				("unable to find supertable for " +                                 om.getObjectType());			}			fk(cols, table.getPrimaryKey());		    }		}	    });        m_ast.traverse(new Node.Switch() {                public void onPath(PathNd nd) {                    ObjectMap om = m_root.getObjectMap                        (m_symbols.getEmitted                         ((ObjectTypeNd) nd.getParent().getParent()));                    om.addFetchedPath(nd.getPath());                }            }, new Node.IncludeFilter(new Node.Field[] {                AST.FILES, FileNd.OBJECT_TYPES, ObjectTypeNd.AGGRESSIVE_LOAD,                AggressiveLoadNd.PATHS            }));    }