Example #1
0
  private EdmAssociation.Builder parseEdmAssociation(
      XMLEventReader2 reader,
      String schemaNamespace,
      String schemaAlias,
      StartElement2 associationElement) {
    String name = associationElement.getAttributeByName("Name").getValue();

    List<EdmAssociationEnd.Builder> ends = new ArrayList<EdmAssociationEnd.Builder>();
    List<EdmAnnotation<?>> annotElements = new ArrayList<EdmAnnotation<?>>();
    EdmReferentialConstraint.Builder referentialConstraint = null;

    while (reader.hasNext()) {
      XMLEvent2 event = reader.nextEvent();
      if (event.isStartElement()) {
        if (isElement(
            event,
            EDM2006_END,
            EDM2007_END,
            EDM2008_1_END,
            EDM2008_9_END,
            EDM2009_8_END,
            EDM2009_11_END)) {
          EdmAssociationEnd.Builder edmAssociationEnd = parseEdmAssociationEnd(reader, event);
          ends.add(edmAssociationEnd);
        } else if (isElement(
            event,
            EDM2006_REFCONSTRAINT,
            EDM2007_REFCONSTRAINT,
            EDM2008_1_REFCONSTRAINT,
            EDM2008_9_REFCONSTRAINT,
            EDM2009_8_REFCONSTRAINT,
            EDM2009_11_REFCONSTRAINT)) {
          StartElement2 constraintElement = event.asStartElement();
          referentialConstraint = parseEdmConstraintElement(reader, constraintElement);
        } else {
          EdmAnnotation<?> anElement = getAnnotationElements(event, reader);
          if (anElement != null) {
            annotElements.add(anElement);
          }
        }
      }

      if (isEndElement(event, associationElement.getName())) {
        return EdmAssociation.newBuilder()
            .setNamespace(schemaNamespace)
            .setAlias(schemaAlias)
            .setName(name)
            .setEnds(ends.get(0), ends.get(1))
            .setRefConstraint(referentialConstraint == null ? null : referentialConstraint)
            .setAnnotations(getAnnotations(associationElement))
            .setAnnotationElements(annotElements);
      }
    }
    throw new UnsupportedOperationException();
  }
  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);
    }
  }
  public static EdmEntitySet.Builder getBuilder(String namespace) {
    EdmEntityType.Builder modelBuilder = MdHierNodeWrapper.getEntityModel(namespace);

    EdmEntityType.Builder rowType =
        EdmEntityType.newBuilder().setNamespace(namespace).setName("Row");
    EdmEntityType.Builder mdDataDimType = MdDataDimWrapper.getEntityModel(namespace);
    EdmEntityType.Builder mdHierarchyType = MdHierarchyWrapper.getEntityModel(namespace);

    EdmAssociationEnd.Builder mdHierNodeRowEnd =
        EdmAssociationEnd.newBuilder()
            .setRole("MdHierNode")
            .setType(modelBuilder)
            .setMultiplicity(EdmMultiplicity.ONE);
    EdmAssociationEnd.Builder rowMdHierNodeEnd =
        EdmAssociationEnd.newBuilder()
            .setRole("Rows")
            .setType(rowType)
            .setMultiplicity(EdmMultiplicity.MANY);
    EdmAssociation.Builder mdHierNodeRow =
        EdmAssociation.newBuilder()
            .setName("MdHierNode-Rows")
            .setEnds(mdHierNodeRowEnd, rowMdHierNodeEnd);

    EdmAssociationEnd.Builder mdHierNodeMdDataDimEnd =
        EdmAssociationEnd.newBuilder()
            .setRole("MdHierNode")
            .setType(modelBuilder)
            .setMultiplicity(EdmMultiplicity.ONE);
    EdmAssociationEnd.Builder mdDataDimMdHierNodeEnd =
        EdmAssociationEnd.newBuilder()
            .setRole("MdDataDim")
            .setType(mdDataDimType)
            .setMultiplicity(EdmMultiplicity.MANY);
    EdmAssociation.Builder mdHierNodeMdDataDim =
        EdmAssociation.newBuilder()
            .setName("MdHierNode-MdDataDim")
            .setEnds(mdHierNodeMdDataDimEnd, mdDataDimMdHierNodeEnd);

    EdmAssociationEnd.Builder mdHierarchyMdHierNodeEnd =
        EdmAssociationEnd.newBuilder()
            .setRole("MdHierarchy")
            .setType(mdHierarchyType)
            .setMultiplicity(EdmMultiplicity.ONE);
    EdmAssociationEnd.Builder mdHierNodeMdHierarchyEnd =
        EdmAssociationEnd.newBuilder()
            .setRole("MdHierNode")
            .setType(modelBuilder)
            .setMultiplicity(EdmMultiplicity.MANY);
    EdmAssociation.Builder mdHierNodeMdHierarchy =
        EdmAssociation.newBuilder()
            .setName("MdHierNode-MdHierarchy")
            .setEnds(mdHierNodeMdHierarchyEnd, mdHierarchyMdHierNodeEnd);

    EdmNavigationProperty.Builder nodeHierarchyNavigationProperty =
        EdmNavigationProperty.newBuilder("IdHierarchy")
            .setRelationship(mdHierNodeMdHierarchy)
            .setFromTo(mdHierNodeMdHierarchy.getEnd1(), mdHierNodeMdHierarchy.getEnd2());
    modelBuilder.addNavigationProperties(nodeHierarchyNavigationProperty);

    EdmNavigationProperty.Builder nodeRowsNavigationProperty =
        EdmNavigationProperty.newBuilder("NodeRows")
            .setRelationship(mdHierNodeRow)
            .setFromTo(mdHierNodeRow.getEnd1(), mdHierNodeRow.getEnd2());
    modelBuilder.addNavigationProperties(nodeRowsNavigationProperty);

    EdmNavigationProperty.Builder nodeDataNavigationProperty =
        EdmNavigationProperty.newBuilder("NodeData")
            .setRelationship(mdHierNodeMdDataDim)
            .setFromTo(mdHierNodeMdDataDim.getEnd1(), mdHierNodeMdDataDim.getEnd2());
    modelBuilder.addNavigationProperties(nodeDataNavigationProperty);

    return EdmEntitySet.newBuilder().setName("MdHierNode").setEntityType(modelBuilder);
  }
  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();
  }