private static void buildAssosiationSets(MetadataStore metadataStore, List<Builder> edmSchemas) { for (Schema schema : metadataStore.getSchemaList()) { EdmSchema.Builder odataSchema = findSchema(edmSchemas, schema.getName()); EdmEntityContainer.Builder entityContainer = findEntityContainer(edmSchemas, schema.getName()); List<EdmAssociationSet.Builder> assosiationSets = new ArrayList<EdmAssociationSet.Builder>(); List<EdmAssociation.Builder> assosiations = new ArrayList<EdmAssociation.Builder>(); for (Table table : schema.getTables().values()) { // build Associations for (ForeignKey fk : table.getForeignKeys()) { EdmEntitySet.Builder entitySet = findEntitySet(edmSchemas, schema.getName(), table.getName()); EdmEntitySet.Builder refEntitySet = findEntitySet(edmSchemas, schema.getName(), fk.getReferenceTableName()); EdmEntityType.Builder entityType = findEntityType(edmSchemas, schema.getName(), table.getName()); EdmEntityType.Builder refEntityType = findEntityType(edmSchemas, schema.getName(), fk.getReferenceTableName()); // check to see if fk is part of this table's pk, then it is 1 to 1 relation boolean onetoone = sameColumnSet(table.getPrimaryKey(), fk); // Build Association Ends EdmAssociationEnd.Builder endSelf = EdmAssociationEnd.newBuilder() .setRole(table.getName()) .setType(entityType) .setMultiplicity(onetoone ? EdmMultiplicity.ZERO_TO_ONE : EdmMultiplicity.MANY); EdmAssociationEnd.Builder endRef = EdmAssociationEnd.newBuilder() .setRole(fk.getReferenceTableName()) .setType(refEntityType) .setMultiplicity(EdmMultiplicity.ZERO_TO_ONE); // Build Association EdmAssociation.Builder association = EdmAssociation.newBuilder(); association.setName(table.getName() + "_" + fk.getName()); association.setEnds(endSelf, endRef); association.setNamespace( refEntityType .getFullyQualifiedTypeName() .substring(0, refEntityType.getFullyQualifiedTypeName().indexOf('.'))); assosiations.add(association); // Build ReferentialConstraint if (fk.getReferenceColumns() != null) { EdmReferentialConstraint.Builder erc = EdmReferentialConstraint.newBuilder(); erc.setPrincipalRole(fk.getReferenceTableName()); erc.addPrincipalReferences(fk.getReferenceColumns()); erc.setDependentRole(table.getName()); erc.addDependentReferences(getColumnNames(fk.getColumns())); association.setRefConstraint(erc); } // Add EdmNavigationProperty to entity type EdmNavigationProperty.Builder nav = EdmNavigationProperty.newBuilder(fk.getReferenceTableName()); nav.setRelationshipName(fk.getName()); nav.setFromToName(table.getName(), fk.getReferenceTableName()); nav.setRelationship(association); nav.setFromTo(endSelf, endRef); entityType.addNavigationProperties(nav); // Add EdmNavigationProperty to Reference entity type EdmNavigationProperty.Builder refNav = EdmNavigationProperty.newBuilder(table.getName()); refNav.setRelationshipName(fk.getName()); refNav.setFromToName(fk.getReferenceTableName(), table.getName()); refNav.setRelationship(association); refNav.setFromTo(endRef, endSelf); refEntityType.addNavigationProperties(refNav); // build AssosiationSet EdmAssociationSet.Builder assosiationSet = EdmAssociationSet.newBuilder() .setName(table.getName() + "_" + fk.getName()) .setAssociationName(fk.getName()); // Build AssosiationSet Ends EdmAssociationSetEnd.Builder endOne = EdmAssociationSetEnd.newBuilder() .setEntitySet(entitySet) .setRoleName(table.getName()) .setRole( EdmAssociationEnd.newBuilder() .setType(entityType) .setRole(entityType.getName())); EdmAssociationSetEnd.Builder endTwo = EdmAssociationSetEnd.newBuilder() .setEntitySet(refEntitySet) .setRoleName(fk.getReferenceTableName()) .setRole( EdmAssociationEnd.newBuilder() .setType(refEntityType) .setRole(refEntityType.getName())); assosiationSet.setEnds(endOne, endTwo); assosiationSet.setAssociation(association); assosiationSets.add(assosiationSet); } } entityContainer.addAssociationSets(assosiationSets); odataSchema.addAssociations(assosiations); } }
private void resolve() { final Map<String, EdmEntityType.Builder> allEetsByFQName = Enumerable.create(dataServices.getEntityTypes()) .toMap(EdmEntityType.Builder.func1_getFullyQualifiedTypeName()); final Map<String, EdmEntityType.Builder> allEetsByFQAliasName = Enumerable.create(dataServices.getEntityTypes()) .where(EdmEntityType.Builder.pred1_hasAlias()) .toMap(EdmEntityType.Builder.func1_getFQAliasName()); final Map<String, EdmAssociation.Builder> allEasByFQName = Enumerable.create(dataServices.getAssociations()) .toMap(EdmAssociation.Builder.func1_getFQNamespaceName()); for (EdmSchema.Builder edmSchema : dataServices.getSchemas()) { // resolve associations for (int i = 0; i < edmSchema.getAssociations().size(); i++) { EdmAssociation.Builder tmpAssociation = edmSchema.getAssociations().get(i); tmpAssociation .getEnd1() .setType(allEetsByFQName.get(tmpAssociation.getEnd1().getTypeName())); tmpAssociation .getEnd2() .setType(allEetsByFQName.get(tmpAssociation.getEnd2().getTypeName())); } // resolve navproperties for (EdmEntityType.Builder eet : edmSchema.getEntityTypes()) { List<EdmNavigationProperty.Builder> navProps = eet.getNavigationProperties(); for (int i = 0; i < navProps.size(); i++) { final EdmNavigationProperty.Builder tmp = navProps.get(i); final EdmAssociation.Builder ea = allEasByFQName.get(tmp.getRelationshipName()); if (ea == null) throw new IllegalArgumentException( "Invalid relationship name " + tmp.getRelationshipName()); List<EdmAssociationEnd.Builder> finalEnds = Enumerable.create(tmp.getFromRoleName(), tmp.getToRoleName()) .select( new Func1<String, EdmAssociationEnd.Builder>() { public EdmAssociationEnd.Builder apply(String input) { if (ea.getEnd1().getRole().equals(input)) return ea.getEnd1(); if (ea.getEnd2().getRole().equals(input)) return ea.getEnd2(); throw new IllegalArgumentException("Invalid role name " + input); } }) .toList(); tmp.setRelationship(ea).setFromTo(finalEnds.get(0), finalEnds.get(1)); } } // resolve entitysets for (EdmEntityContainer.Builder edmEntityContainer : edmSchema.getEntityContainers()) { for (int i = 0; i < edmEntityContainer.getEntitySets().size(); i++) { final EdmEntitySet.Builder tmpEes = edmEntityContainer.getEntitySets().get(i); EdmEntityType.Builder eet = allEetsByFQName.get(tmpEes.getEntityTypeName()); if (eet == null) eet = allEetsByFQAliasName.get(tmpEes.getEntityTypeName()); if (eet == null) throw new IllegalArgumentException("Invalid entity type " + tmpEes.getEntityTypeName()); edmEntityContainer .getEntitySets() .set( i, EdmEntitySet.newBuilder() .setName(tmpEes.getName()) .setEntityType(eet) .setAnnotationElements(tmpEes.getAnnotationElements()) .setAnnotations(tmpEes.getAnnotations())); } } // resolve associationsets for (final EdmEntityContainer.Builder edmEntityContainer : edmSchema.getEntityContainers()) { for (int i = 0; i < edmEntityContainer.getAssociationSets().size(); i++) { final EdmAssociationSet.Builder tmpEas = edmEntityContainer.getAssociationSets().get(i); final EdmAssociation.Builder ea = allEasByFQName.get(tmpEas.getAssociationName()); List<EdmAssociationSetEnd.Builder> finalEnds = Enumerable.create(tmpEas.getEnd1(), tmpEas.getEnd2()) .select( new Func1<EdmAssociationSetEnd.Builder, EdmAssociationSetEnd.Builder>() { public EdmAssociationSetEnd.Builder apply( final EdmAssociationSetEnd.Builder input) { EdmAssociationEnd.Builder eae = ea.getEnd1().getRole().equals(input.getRoleName()) ? ea.getEnd1() : ea.getEnd2().getRole().equals(input.getRoleName()) ? ea.getEnd2() : null; if (eae == null) throw new IllegalArgumentException( "Invalid role name " + input.getRoleName()); EdmEntitySet.Builder ees = Enumerable.create(edmEntityContainer.getEntitySets()) .first( OPredicates.nameEquals( EdmEntitySet.Builder.class, input.getEntitySetName())); return EdmAssociationSetEnd.newBuilder() .setRole(eae) .setEntitySet(ees) .setAnnotationElements(input.getAnnotationElements()) .setAnnotations(input.getAnnotations()); } }) .toList(); tmpEas.setAssociation(ea).setEnds(finalEnds.get(0), finalEnds.get(1)); } } // resolve functionimports for (final EdmEntityContainer.Builder edmEntityContainer : edmSchema.getEntityContainers()) { for (int i = 0; i < edmEntityContainer.getFunctionImports().size(); i++) { final EdmFunctionImport.Builder tmpEfi = edmEntityContainer.getFunctionImports().get(i); EdmEntitySet.Builder ees = Enumerable.create(edmEntityContainer.getEntitySets()) .firstOrNull( new Predicate1<EdmEntitySet.Builder>() { public boolean apply(EdmEntitySet.Builder input) { return input.getName().equals(tmpEfi.getEntitySetName()); } }); EdmType.Builder<?, ?> typeBuilder = null; if (tmpEfi.getReturnTypeName() != null) { typeBuilder = dataServices.resolveType(tmpEfi.getReturnTypeName()); if (typeBuilder == null) throw new RuntimeException("Edm-type not found: " + tmpEfi.getReturnTypeName()); if (tmpEfi.isCollection()) { typeBuilder = EdmCollectionType.newBuilder() .setKind(CollectionKind.Collection) .setCollectionType(typeBuilder); } } edmEntityContainer .getFunctionImports() .set( i, EdmFunctionImport.newBuilder() .setName(tmpEfi.getName()) .setEntitySet(ees) .setReturnType(typeBuilder) .setHttpMethod(tmpEfi.getHttpMethod()) .addParameters(tmpEfi.getParameters()) .setAnnotationElements(tmpEfi.getAnnotationElements()) .setAnnotations(tmpEfi.getAnnotations())); } } // resolve type hierarchy for (Entry<String, EdmEntityType.Builder> entry : allEetsByFQName.entrySet()) { String baseTypeName = entry.getValue().getFQBaseTypeName(); if (baseTypeName != null) { EdmEntityType.Builder baseType = allEetsByFQName.get(baseTypeName); if (baseType == null) { throw new IllegalArgumentException("Invalid baseType: " + baseTypeName); } entry.getValue().setBaseType(baseType); } } } }