Esempio n. 1
0
  private EdmFunctionImport.Builder parseEdmFunctionImport(
      XMLEventReader2 reader, String schemaNamespace, StartElement2 functionImportElement) {
    String name = functionImportElement.getAttributeByName("Name").getValue();
    String entitySet = getAttributeValueIfExists(functionImportElement, "EntitySet");
    Attribute2 returnTypeAttr = functionImportElement.getAttributeByName("ReturnType");
    String returnType = returnTypeAttr != null ? returnTypeAttr.getValue() : null;

    List<EdmAnnotation<?>> annotElements = new ArrayList<EdmAnnotation<?>>();

    // strict parsing
    boolean isCollection = returnType != null && returnType.matches("^Collection\\(.*\\)$");
    if (isCollection) {
      returnType = returnType.substring(11, returnType.length() - 1);
    }
    String httpMethod =
        getAttributeValueIfExists(functionImportElement, new QName2(NS_METADATA, "HttpMethod"));

    List<EdmFunctionParameter.Builder> parameters = new ArrayList<EdmFunctionParameter.Builder>();

    while (reader.hasNext()) {
      XMLEvent2 event = reader.nextEvent();
      if (event.isStartElement()) {
        if (isElement(
            event,
            EDM2006_PARAMETER,
            EDM2007_PARAMETER,
            EDM2008_1_PARAMETER,
            EDM2008_9_PARAMETER,
            EDM2009_8_PARAMETER,
            EDM2009_11_PARAMETER)) {
          StartElement2 paramStartElement = event.asStartElement();
          EdmFunctionParameter.Builder functionParameter =
              parseEdmFunctionParameter(reader, paramStartElement);
          parameters.add(functionParameter);
        } else {
          EdmAnnotation<?> anElement = getAnnotationElements(event, reader);
          if (anElement != null) {
            annotElements.add(anElement);
          }
        }
      }
      if (isEndElement(event, functionImportElement.getName())) {
        return EdmFunctionImport.newBuilder()
            .setName(name)
            .setEntitySetName(entitySet)
            .setReturnTypeName(returnType)
            .setIsCollection(isCollection)
            .setHttpMethod(httpMethod)
            .addParameters(parameters)
            .setAnnotations(getAnnotations(functionImportElement))
            .setAnnotationElements(annotElements);
      }
    }
    throw new UnsupportedOperationException();
  }
  private static void buildFunctionImports(MetadataStore metadataStore, List<Builder> edmSchemas) {
    for (Schema schema : metadataStore.getSchemaList()) {

      EdmSchema.Builder odataSchema = findSchema(edmSchemas, schema.getName());
      EdmEntityContainer.Builder entityContainer =
          findEntityContainer(edmSchemas, schema.getName());

      // procedures
      for (Procedure proc : schema.getProcedures().values()) {
        EdmFunctionImport.Builder edmProcedure = EdmFunctionImport.newBuilder();
        edmProcedure.setName(proc.getName());
        String httpMethod = "POST";

        for (ProcedureParameter pp : proc.getParameters()) {
          if (pp.getName().equals("return")) {
            httpMethod = "GET";
            edmProcedure.setReturnType(
                ODataTypeManager.odataType(pp.getDatatype().getRuntimeTypeName()));
            continue;
          }

          EdmFunctionParameter.Builder param = EdmFunctionParameter.newBuilder();
          param.setName(pp.getName());
          param.setType(ODataTypeManager.odataType(pp.getDatatype().getRuntimeTypeName()));

          if (pp.getType() == ProcedureParameter.Type.In) {
            param.setMode(Mode.In);
          } else if (pp.getType() == ProcedureParameter.Type.InOut) {
            param.setMode(Mode.InOut);
          } else if (pp.getType() == ProcedureParameter.Type.Out) {
            param.setMode(Mode.Out);
          }

          param.setNullable(pp.getNullType() == NullType.Nullable);
          edmProcedure.addParameters(param);
        }

        // add a complex type for return resultset.
        ColumnSet<Procedure> returnColumns = proc.getResultSet();
        if (returnColumns != null) {
          httpMethod = "GET";
          EdmComplexType.Builder complexType = EdmComplexType.newBuilder();
          complexType.setName(proc.getName() + "_" + returnColumns.getName());
          complexType.setNamespace(schema.getName());
          for (Column c : returnColumns.getColumns()) {
            EdmProperty.Builder property =
                EdmProperty.newBuilder(c.getName())
                    .setType(ODataTypeManager.odataType(c.getDatatype().getRuntimeTypeName()))
                    .setNullable(c.getNullType() == NullType.Nullable);
            if (c.getDatatype()
                .getRuntimeTypeName()
                .equals(DataTypeManager.DefaultDataTypes.STRING)) {
              property
                  .setFixedLength(c.isFixedLength())
                  .setMaxLength(c.getLength())
                  .setUnicode(true);
            }
            complexType.addProperties(property);
          }
          odataSchema.addComplexTypes(complexType);
          edmProcedure.setIsCollection(true);
          edmProcedure.setReturnType(
              EdmCollectionType.newBuilder()
                  .setCollectionType(complexType)
                  .setKind(CollectionKind.Collection));
        }
        edmProcedure.setHttpMethod(httpMethod);
        entityContainer.addFunctionImports(edmProcedure);
      }
    }
  }
  @Override
  public BaseResponse callFunction(
      ODataContext context,
      EdmFunctionImport name,
      Map<String, OFunctionParameter> params,
      QueryInfo queryInfo) {
    BaseResponse response;

    ServiceOperationsProducerMock.LOGGER.debug("EdmFunctionImport Object:    " + name.getName());
    ServiceOperationsProducerMock.LOGGER.debug("EdmFunctionImport Parameter: " + params);
    ServiceOperationsProducerMock.LOGGER.debug("EdmFunctionImport QueryInfo: " + queryInfo);

    this.queryParameter = params;
    this.queryInfo = queryInfo;

    if (ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_STRING.equals(name.getName())) {
      response =
          Responses.simple(
              EdmSimpleType.STRING, name.getName(), ServiceOperationsProducerMock.SOME_TEXT);
    } else if (ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_STRING_PUT.equals(
        name.getName())) {
      response =
          Responses.simple(
              EdmSimpleType.STRING, name.getName(), ServiceOperationsProducerMock.SOME_TEXT);
    } else if (ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_STRING_GET.equals(
        name.getName())) {
      response =
          Responses.simple(
              EdmSimpleType.STRING, name.getName(), ServiceOperationsProducerMock.SOME_TEXT);
    } else if (ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_STRING_DELETE.equals(
        name.getName())) {
      response =
          Responses.simple(
              EdmSimpleType.STRING, name.getName(), ServiceOperationsProducerMock.SOME_TEXT);
    } else if (ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_STRING_PATCH.equals(
        name.getName())) {
      response =
          Responses.simple(
              EdmSimpleType.STRING, name.getName(), ServiceOperationsProducerMock.SOME_TEXT);
    } else if (ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_STRING_MERGE.equals(
        name.getName())) {
      response =
          Responses.simple(
              EdmSimpleType.STRING, name.getName(), ServiceOperationsProducerMock.SOME_TEXT);
    } else if (ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_STRING_POST.equals(
        name.getName())) {
      response =
          Responses.simple(
              EdmSimpleType.STRING, name.getName(), ServiceOperationsProducerMock.SOME_TEXT);
    } else if (ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_BOOLEAN.equals(name.getName())) {
      response =
          Responses.simple(
              EdmSimpleType.BOOLEAN, name.getName(), ServiceOperationsProducerMock.BOOLEAN_VALUE);
    } else if (ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_INT16.equals(name.getName())) {
      response =
          Responses.simple(
              EdmSimpleType.INT16, name.getName(), ServiceOperationsProducerMock.INT16_VALUE);
    } else if (ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_ENTITY.equals(name.getName())) {
      OEntity entity = this.createEmployeeEntity();
      response = Responses.entity(entity);
    } else if (ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_COMPLEX_TYPE.equals(
        name.getName())) {
      OComplexObject complexObject = this.createComplexTypeLocation();
      response =
          Responses.complexObject(
              complexObject, ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_COMPLEX_TYPE);
    } else if (ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_COLLECTION_STRING.equals(
        name.getName())) {
      Builder<OObject> collectionBuilder = OCollections.newBuilder(EdmSimpleType.STRING);
      collectionBuilder
          .add(
              OSimpleObjects.create(
                  EdmSimpleType.STRING, ServiceOperationsProducerMock.COLLECTION_STRING1))
          .build();
      collectionBuilder
          .add(
              OSimpleObjects.create(
                  EdmSimpleType.STRING, ServiceOperationsProducerMock.COLLECTION_STRING2))
          .build();
      OCollection<OObject> collection = collectionBuilder.build();
      response =
          Responses.collection(
              collection,
              null,
              null,
              null,
              ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_COLLECTION_STRING);
    } else if (ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_COLLECTION_DOUBLE.equals(
        name.getName())) {
      Builder<OObject> collectionBuilder = OCollections.newBuilder(EdmSimpleType.DOUBLE);
      collectionBuilder
          .add(
              OSimpleObjects.create(
                  EdmSimpleType.DOUBLE, ServiceOperationsProducerMock.COLLECTION_DOUBLE1))
          .build();
      collectionBuilder
          .add(
              OSimpleObjects.create(
                  EdmSimpleType.DOUBLE, ServiceOperationsProducerMock.COLLECTION_DOUBLE2))
          .build();
      OCollection<OObject> collection = collectionBuilder.build();
      response =
          Responses.collection(
              collection,
              null,
              null,
              null,
              ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_COLLECTION_DOUBLE);
    } else if (ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_COLLECTION_COMPLEX_TYPE.equals(
        name.getName())) {
      OComplexObject complexObject1 = this.createComplexTypeLocation();
      OComplexObject complexObject2 = this.createComplexTypeLocation();

      EdmComplexType type =
          this.getMetadata()
              .findEdmComplexType(ServiceOperationsProducerMock.COMPLEY_TYPE_NAME_LOCATION);
      Builder<OObject> collectionBuilder = OCollections.newBuilder(type);

      collectionBuilder.add(complexObject1);
      collectionBuilder.add(complexObject2);

      OCollection<OObject> collection = collectionBuilder.build();
      response =
          Responses.collection(
              collection,
              null,
              null,
              null,
              ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_COLLECTION_COMPLEX_TYPE);
    } else if (ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_COLLECTION_ENTITY.equals(
        name.getName())) {
      OEntity entity = this.createEmployeeEntity();

      Builder<OObject> collectionBuilder = OCollections.newBuilder(entity.getType());
      collectionBuilder.add(entity);
      OCollection<OObject> collection = collectionBuilder.build();

      response =
          Responses.collection(
              collection,
              entity.getEntitySet(),
              null,
              null,
              ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_COLLECTION_ENTITY);
    } else if (ServiceOperationsMetadataUtil.TEST_FUNCTION_RETURN_ENTITYSET.equals(
        name.getName())) {
      List<OEntity> entities = new ArrayList<OEntity>();
      entities.add(createEmployeeEntity());
      response = Responses.entities(entities, name.getEntitySet(), null, null);
    } else {
      throw new RuntimeException("Unsupported Test Case for FunctionImport: " + name.getName());
    }

    return response;
  }
  public static void write(EdmDataServices services, Writer w) {

    XMLWriter2 writer = XMLFactoryProvider2.getInstance().newXMLWriterFactory2().createXMLWriter(w);
    writer.startDocument();

    writer.startElement(new QName2(edmx, "Edmx", "edmx"));
    writer.writeAttribute("Version", "1.0");
    writer.writeNamespace("edmx", edmx);
    writer.writeNamespace("d", d);
    writer.writeNamespace("m", m);
    writeExtensionNamespaces(services, writer);

    writer.startElement(new QName2(edmx, "DataServices", "edmx"));
    writer.writeAttribute(new QName2(m, "DataServiceVersion", "m"), "1.0");

    // Schema
    for (EdmSchema schema : services.getSchemas()) {

      writer.startElement(new QName2("Schema"), edm);
      writer.writeAttribute("Namespace", schema.getNamespace());
      writeAnnotationAttributes(schema, writer);
      writeDocumentation(schema, writer);

      // ComplexType
      for (EdmComplexType ect : schema.getComplexTypes()) {
        writer.startElement(new QName2("ComplexType"));

        writer.writeAttribute("Name", ect.getName());
        if (null != ect.getIsAbstract()) {
          writer.writeAttribute("Abstract", ect.getIsAbstract().toString());
        }
        writeAnnotationAttributes(ect, writer);
        writeDocumentation(ect, writer);

        writeProperties(ect.getProperties(), writer);
        writeAnnotationElements(ect, writer);
        writer.endElement("ComplexType");
      }
      // EntityType
      for (EdmEntityType eet : schema.getEntityTypes()) {
        writer.startElement(new QName2("EntityType"));

        writer.writeAttribute("Name", eet.getName());
        if (null != eet.getIsAbstract()) {
          writer.writeAttribute("Abstract", eet.getIsAbstract().toString());
        }

        if (Boolean.TRUE.equals(eet.getHasStream())) {
          writer.writeAttribute(new QName2(m, "HasStream", "m"), "true");
        }

        // keys only on base types
        if (eet.isRootType()) {
          writeAnnotationAttributes(eet, writer);
          writeDocumentation(eet, writer);
          writer.startElement(new QName2("Key"));
          for (String key : eet.getKeys()) {
            writer.startElement(new QName2("PropertyRef"));
            writer.writeAttribute("Name", key);
            writer.endElement("PropertyRef");
          }

          writer.endElement("Key");
        } else {
          writer.writeAttribute("BaseType", eet.getBaseType().getFullyQualifiedTypeName());
          writeAnnotationAttributes(eet, writer);
          writeDocumentation(eet, writer);
        }

        writeProperties(eet.getDeclaredProperties(), writer);

        for (EdmNavigationProperty np : eet.getDeclaredNavigationProperties()) {

          writer.startElement(new QName2("NavigationProperty"));
          writer.writeAttribute("Name", np.getName());
          writer.writeAttribute("Relationship", np.getRelationship().getFQNamespaceName());
          writer.writeAttribute("FromRole", np.getFromRole().getRole());
          writer.writeAttribute("ToRole", np.getToRole().getRole());
          writeAnnotationAttributes(np, writer);
          writeDocumentation(np, writer);
          writeAnnotationElements(np, writer);
          writer.endElement("NavigationProperty");
        }

        writeAnnotationElements(eet, writer);
        writer.endElement("EntityType");
      }

      // Association
      for (EdmAssociation assoc : schema.getAssociations()) {
        writer.startElement(new QName2("Association"));

        writer.writeAttribute("Name", assoc.getName());
        writeAnnotationAttributes(assoc, writer);
        writeDocumentation(assoc, writer);

        writer.startElement(new QName2("End"));
        writer.writeAttribute("Role", assoc.getEnd1().getRole());
        writer.writeAttribute("Type", assoc.getEnd1().getType().getFullyQualifiedTypeName());
        writer.writeAttribute("Multiplicity", assoc.getEnd1().getMultiplicity().getSymbolString());
        writer.endElement("End");

        writer.startElement(new QName2("End"));
        writer.writeAttribute("Role", assoc.getEnd2().getRole());
        writer.writeAttribute("Type", assoc.getEnd2().getType().getFullyQualifiedTypeName());
        writer.writeAttribute("Multiplicity", assoc.getEnd2().getMultiplicity().getSymbolString());
        writer.endElement("End");

        writeAnnotationElements(assoc, writer);
        writer.endElement("Association");
      }

      // EntityContainer
      for (EdmEntityContainer container : schema.getEntityContainers()) {
        writer.startElement(new QName2("EntityContainer"));

        writer.writeAttribute("Name", container.getName());
        writer.writeAttribute(
            new QName2(m, "IsDefaultEntityContainer", "m"),
            Boolean.toString(container.isDefault()));
        writeAnnotationAttributes(container, writer);
        writeDocumentation(container, writer);

        for (EdmEntitySet ees : container.getEntitySets()) {
          writer.startElement(new QName2("EntitySet"));
          writer.writeAttribute("Name", ees.getName());
          writer.writeAttribute("EntityType", ees.getType().getFullyQualifiedTypeName());
          writeAnnotationAttributes(ees, writer);
          writeDocumentation(ees, writer);
          writeAnnotationElements(ees, writer);
          writer.endElement("EntitySet");
        }

        for (EdmFunctionImport fi : container.getFunctionImports()) {
          writer.startElement(new QName2("FunctionImport"));
          writer.writeAttribute("Name", fi.getName());
          if (null != fi.getEntitySet()) {
            writer.writeAttribute("EntitySet", fi.getEntitySet().getName());
          }
          if (fi.getReturnType() != null) {
            // TODO: how to differentiate inline ReturnType vs embedded ReturnType?
            writer.writeAttribute("ReturnType", fi.getReturnType().getFullyQualifiedTypeName());
          }
          writer.writeAttribute(new QName2(m, "HttpMethod", "m"), fi.getHttpMethod());
          writeAnnotationAttributes(fi, writer);
          writeDocumentation(fi, writer);

          for (EdmFunctionParameter param : fi.getParameters()) {
            writer.startElement(new QName2("Parameter"));
            writer.writeAttribute("Name", param.getName());
            writer.writeAttribute("Type", param.getType().getFullyQualifiedTypeName());
            if (param.getMode() != null) writer.writeAttribute("Mode", param.getMode().toString());
            writeAnnotationAttributes(param, writer);
            writeDocumentation(param, writer);
            writeAnnotationElements(param, writer);
            writer.endElement("Parameter");
          }
          writeAnnotationElements(fi, writer);
          writer.endElement("FunctionImport");
        }

        for (EdmAssociationSet eas : container.getAssociationSets()) {
          writer.startElement(new QName2("AssociationSet"));
          writer.writeAttribute("Name", eas.getName());
          writer.writeAttribute("Association", eas.getAssociation().getFQNamespaceName());
          writeAnnotationAttributes(eas, writer);
          writeDocumentation(eas, writer);

          writer.startElement(new QName2("End"));
          writer.writeAttribute("Role", eas.getEnd1().getRole().getRole());
          writer.writeAttribute("EntitySet", eas.getEnd1().getEntitySet().getName());
          writer.endElement("End");

          writer.startElement(new QName2("End"));
          writer.writeAttribute("Role", eas.getEnd2().getRole().getRole());
          writer.writeAttribute("EntitySet", eas.getEnd2().getEntitySet().getName());
          writer.endElement("End");

          writeAnnotationElements(eas, writer);
          writer.endElement("AssociationSet");
        }

        writeAnnotationElements(container, writer);
        writer.endElement("EntityContainer");
      }

      writeAnnotationElements(schema, writer);
      writer.endElement("Schema");
    }

    writer.endDocument();
  }
Esempio n. 5
0
  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);
        }
      }
    }
  }