Details

    • Type: Improvement
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: V4.0_WD01
    • Fix Version/s: V4.0_WD01
    • Component/s: CSDL XML
    • Labels:
      None
    • Environment:

      [Proposed]

      Description

      In mashup scenarios it is often the case that a third party can detect a rule that allows constructing URLs from information provided in an entity that allow navigation to other resources in the web.
      Annotations allow to express these construction rules, this construction rules can also be seen as "special navigation properties defined via annotations".

      We want to annotate these "special navigagtion properties" in a such a way, that they can be used in further annotation similar to native navigation properties.
      In the following example two navigation properties ( to a supplier and to purchase orders ) and one property is annotated at the product entity type; and they are used in a other annotation. This example is currently invalid, because the <Url> element isn't specified so far.
      Complete annotation file example (it uses https://tools.oasis-open.org/issues/browse/ODATA-257):

      <?xml version="1.0" encoding="utf-8"?>
      <edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx/4.0">
      <edmx:Reference Url="http://biz.org/odata/foobar/ProductService.srv/$metadata" />
      <edmx:Reference Url="http://example.org:1234/odata/bar/SupplierService.srv/$metadata" />
      <edmx:Reference Url="http://somewhere.org/odata/foo/Purchasing.srv/$metadata" />
      <edmx:DataServices DataServiceVersion="4.0">
      <Schema xmlns="http://docs.oasis-open.org/odata/ns/csdl/4.0" Namespace="AnnotationCrossReference" Alias="ACR">
      <Using Namespace="com.sap.erp.products" Alias="ServiceA" />
      <Using Namespace="com.sap.erp.supplier" Alias="ServiceB" />
      <Using Namespace="com.sap.foo.purchasing" Alias="ServiceC" />

      <Term Name="DataFieldWithNavigation" Type="DataFieldWithNavigationType" />
      <ComplexType Name="DataFieldWithNavigationType">
      <Property Name="Label" Type="String" Nullable="true">
      <Annotation Term="Core.IsLanguageDependent" />
      </Property>
      <Property Name="Value" Type="Edm.PrimitiveType" Nullable="false" />
      <Property Name="NavigationPath" Type="Edm.NavigationPropertyPath" Nullable="false" />
      </ComplexType>

      <Term Name="Supplier" Type="ServiceB.Supplier" />
      <Term Name="PurchaseOrders" Type="Collection(ServiceC.PurchaseOrder)" />
      <Term Name="NumberOfPurchaseOrders" Type="Edm.Int32" />

      <Annotations Target="ServiceA.Product">
      <Annotation Term="Supplier">
      <Url>
      <Apply Function="odata.fillUriTemplate">
      <!-- ... construct path to ServiceB.Supplier -->
      <String>http://example.org:1234/odata/bar/SupplierService.srv/Suppliers(

      {suppID}

      )</String>
      <LabeledElement Name="suppID">
      <Apply Function="odata.UriEncode">
      <Path>SupplierId</Path>
      </Apply>
      </LabeledElement>
      </Apply>
      </Url>
      </Annotation>
      <Annotation Term="PurchaseOrders">
      <Url>
      <Apply Function="odata.fillUriTemplate">
      <!-- ... construct path to a ServiceC.EntiySet of entity type PurchaseOrders -->
      <String>http://somewhere.org/odata/foo/Purchasing.srv/PurchaseOrders?$search=

      {productID}</String>
      <LabeledElement Name="productID">
      <Apply Function="odata.UriEncode">
      <Path>ProductKey</Path>
      </Apply>
      </LabeledElement>
      </Apply>
      </Url>
      </Annotation>
      <Annotation Term="NumberOfPurchaseOrders">
      <Url>
      <Apply Function="odata.fillUriTemplate">
      <!-- ... construct path an int value -->
      <String>http://somewhere.org/odata/foo/Purchasing.srv/PurchaseOrders/$count?$search={productID}

      </String>
      <LabeledElement Name="productID">
      <Apply Function="odata.UriEncode">
      <Path>ProductKey</Path>
      </Apply>
      </LabeledElement>
      </Apply>
      </Url>
      </Annotation>

      <Annotation Term="DataFieldWithNavigation" Qualifier="FirstDataField">
      <Record>
      <PropertyValue Property="Label" String="Supplier" />
      <PropertyValue Property="Value" Path="@ACR.Supplier/SupplierName" />
      <PropertyValue Property="NavigationPath" NavigationPropertyPath="@ACR.Supplier" />
      </Record>
      </Annotation>

      <Annotation Term="DataFieldWithNavigation" Qualifier="SecondDataField">
      <Record>
      <PropertyValue Property="Label" String="Purchase Orders" />
      <PropertyValue Property="Value" Path="@ACR.NumberOfPurchaseOrders" />
      <PropertyValue Property="NavigationPath" NavigationPropertyPath="@ACR.PurchaseOrders" />
      </Record>
      </Annotation>
      </Annotations>

      </Schema>
      </edmx:DataServices>
      </edmx:Edmx>

        Attachments

          Activity

          martin.zurmuehl Martin Zurmuehl (Inactive) created issue -
          martin.zurmuehl Martin Zurmuehl (Inactive) made changes -
          Field Original Value New Value
          Proposal Introduce a edm:Url expression as a child of edm:annotation element:
          The edm:Url expression enables a value to be obtained by sending a GET request to the edm:Url expression value . A Url expression MUST be assigned a value of the type xs:string see [XML-Schema-2], section 3.2.1.

          The response body of the GET request MUST be returned as the result of the edm:Url expression. The edm:Url expression result MUST be type compatible with the type expected by the surrounding edm:Annotation element.
          Introduce a edm:Url expression as a child of edm:annotation element:
          The edm:Url expression enables a value to be obtained by sending a GET request to the edm:Url expression value . A Url expression MUST be assigned a value of the type xs:string see [XML-Schema-2], section 3.2.1.

          The response body of the GET request MUST be returned as the result of the edm:Url expression. The edm:Url expression result MUST be type compatible with the type expected by the surrounding element or expression.
          Summary Introduce edm:Url expression as child element of the edm:Annotation element. Introduce vocabulary expression edm:Url
          martin.zurmuehl Martin Zurmuehl (Inactive) made changes -
          Description In mashup scenarios it is often the case that a third party can detect a rule that allows constructing URLs from information provided in an entity that allow navigation to other resources in the web.
          Annotations allow to express these construction rules, this construction rules can also be seen as "special navigation properties defined via annotations".

          We want to annotate these "special navigagtion properties" in a such a way, that they can be used in further annotation similar to native navigation properties.
          In the following example two navigation properties ( to a supplier and to purchase orders ) and one property is annotated at the product entity type; and they are used in a other annotation. This example is currently invalid, because the <Url> element isn't specified so far.
          Complete annotation file example (it uses https://tools.oasis-open.org/issues/browse/ODATA-257):

          <?xml version="1.0" encoding="utf-8"?>
          <edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx/4.0">
            <edmx:Reference Url="http://biz.org/odata/foobar/ProductService.srv/$metadata" />
            <edmx:Reference Url="http://example.org:1234/odata/bar/SupplierService.srv/$metadata" />
            <edmx:Reference Url="http://somewhere.org/odata/foo/Purchasing.srv/$metadata" />
            <edmx:DataServices DataServiceVersion="4.0">
              <Schema xmlns="http://docs.oasis-open.org/odata/ns/csdl/4.0" Namespace="AnnotationCrossReference" Alias="ACR">
                <Using Namespace="com.sap.erp.products" Alias="ServiceA" />
                <Using Namespace="com.sap.erp.supplier" Alias="ServiceB" />
                <Using Namespace="com.sap.foo.purchasing" Alias="ServiceC" />

                <Term Name="DataFieldWithNavigation" Type="DataFieldWithNavigationType" />
                <ComplexType Name="DataFieldWithNavigationType">
                  <Property Name="Label" Type="String" Nullable="true">
                    <Annotation Term="Core.IsLanguageDependent" />
                  </Property>
                  <Property Name="Value" Type="Edm.PrimitiveType" Nullable="false" />
                  <Property Name="NavigationPath" Type="Edm.NavigationPropertyPath" Nullable="false" />
                </ComplexType>


                <Term Name="Supplier" Type="ServiceB.Supplier" />
                <Term Name="PurchaseOrders" Type="Collection(ServiceC.PurchaseOrder)" />
                <Term Name="NumberOfPurchaseOrders" Type="Edm.Int32" />


                <Annotations Target="ServiceA.Product">
                  <Annotation Term="Supplier">
                    <Url>
                      <Apply Function="odata.fillUriTemplate">
                        <!-- ... construct path to ServiceB.Supplier -->
                        <String>http://example.org:1234/odata/bar/SupplierService.srv/Suppliers(&#39;{suppID}')</String>
                        <LabeledElement Name="suppID">
                          <Apply Function="odata.UriEncode">
                            <Path>SupplierId</Path>
                          </Apply>
                        </LabeledElement>
                      </Apply>
                    </Url>
                  </Annotation>
                  <Annotation Term="PurchaseOrders">
                    <Url>
                      <Apply Function="odata.fillUriTemplate">
                        <!-- ... construct path to a ServiceC.EntiySet of entity type PurchaseOrders -->
                        <String>http://somewhere.org/odata/foo/Purchasing.srv/PurchaseOrders?$search={productID}</String>
                        <LabeledElement Name="productID">
                          <Apply Function="odata.UriEncode">
                            <Path>ProductKey</Path>
                          </Apply>
                        </LabeledElement>
                      </Apply>
                    </Url>
                  </Annotation>
                  <Annotation Term="NumberOfPurchaseOrders">
                    <Url>
                      <Apply Function="odata.fillUriTemplate">
                        <!-- ... construct path an int value -->
                        <String>http://somewhere.org/odata/foo/Purchasing.srv/PurchaseOrders/$count?$search={productID}</String>
                        <LabeledElement Name="productID">
                          <Apply Function="odata.UriEncode">
                            <Path>ProductKey</Path>
                          </Apply>
                        </LabeledElement>
                      </Apply>
                    </Url>
                  </Annotation>


                  <Annotation Term="DataFieldWithNavigation" Qualifier="FirstDataField">
                    <Record>
                      <PropertyValue Property="Label" String="Supplier" />
                      <PropertyValue Property="Value" Path="@ACR.Supplier/SupplierName" />
                      <PropertyValue Property="NavigationPath" NavigationPropertyPath="@ACR.Supplier" />
                    </Record>
                  </Annotation>

                  <Annotation Term="DataFieldWithNavigation" Qualifier="SecondDataField">
                    <Record>
                      <PropertyValue Property="Label" String="Purchase Orders" />
                      <PropertyValue Property="Value" Path="@ACR.NumberOfPurchaseOrders" />
                      <PropertyValue Property="NavigationPath" NavigationPropertyPath="@ACR.PurchaseOrders" />
                    </Record>
                  </Annotation>
                </Annotations>


              </Schema>
            </edmx:DataServices>
          </edmx:Edmx>
          In mashup scenarios it is often the case that a third party can detect a rule that allows constructing URLs from information provided in an entity that allow navigation to other resources in the web.
          Annotations allow to express these construction rules, this construction rules can also be seen as "special navigation properties defined via annotations".

          We want to annotate these "special navigagtion properties" in a such a way, that they can be used in further annotation similar to native navigation properties.
          In the following example two navigation properties ( to a supplier and to purchase orders ) and one property is annotated at the product entity type; and they are used in a other annotation. This example is currently invalid, because the <Url> element isn't specified so far.
          Complete annotation file example (it uses https://tools.oasis-open.org/issues/browse/ODATA-257):

          <?xml version="1.0" encoding="utf-8"?>
          <edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx/4.0">
            <edmx:Reference Url="http://biz.org/odata/foobar/ProductService.srv/$metadata" />
            <edmx:Reference Url="http://example.org:1234/odata/bar/SupplierService.srv/$metadata" />
            <edmx:Reference Url="http://somewhere.org/odata/foo/Purchasing.srv/$metadata" />
            <edmx:DataServices DataServiceVersion="4.0">
              <Schema xmlns="http://docs.oasis-open.org/odata/ns/csdl/4.0" Namespace="AnnotationCrossReference" Alias="ACR">
                <Using Namespace="com.sap.erp.products" Alias="ServiceA" />
                <Using Namespace="com.sap.erp.supplier" Alias="ServiceB" />
                <Using Namespace="com.sap.foo.purchasing" Alias="ServiceC" />

                <Term Name="DataFieldWithNavigation" Type="DataFieldWithNavigationType" />
                <ComplexType Name="DataFieldWithNavigationType">
                  <Property Name="Label" Type="String" Nullable="true">
                    <Annotation Term="Core.IsLanguageDependent" />
                  </Property>
                  <Property Name="Value" Type="Edm.PrimitiveType" Nullable="false" />
                  <Property Name="NavigationPath" Type="Edm.NavigationPropertyPath" Nullable="false" />
                </ComplexType>


                <Term Name="Supplier" Type="ServiceB.Supplier" />
                <Term Name="PurchaseOrders" Type="Collection(ServiceC.PurchaseOrder)" />
                <Term Name="NumberOfPurchaseOrders" Type="Edm.Int32" />


                <Annotations Target="ServiceA.Product">
                  <Annotation Term="Supplier">
                    <Url>
                      <Apply Function="odata.fillUriTemplate">
                        <!-- ... construct path to ServiceB.Supplier -->
                        <String>http://example.org:1234/odata/bar/SupplierService.srv/Suppliers({suppID})</String>
                        <LabeledElement Name="suppID">
                          <Apply Function="odata.UriEncode">
                            <Path>SupplierId</Path>
                          </Apply>
                        </LabeledElement>
                      </Apply>
                    </Url>
                  </Annotation>
                  <Annotation Term="PurchaseOrders">
                    <Url>
                      <Apply Function="odata.fillUriTemplate">
                        <!-- ... construct path to a ServiceC.EntiySet of entity type PurchaseOrders -->
                        <String>http://somewhere.org/odata/foo/Purchasing.srv/PurchaseOrders?$search={productID}</String>
                        <LabeledElement Name="productID">
                          <Apply Function="odata.UriEncode">
                            <Path>ProductKey</Path>
                          </Apply>
                        </LabeledElement>
                      </Apply>
                    </Url>
                  </Annotation>
                  <Annotation Term="NumberOfPurchaseOrders">
                    <Url>
                      <Apply Function="odata.fillUriTemplate">
                        <!-- ... construct path an int value -->
                        <String>http://somewhere.org/odata/foo/Purchasing.srv/PurchaseOrders/$count?$search={productID}</String>
                        <LabeledElement Name="productID">
                          <Apply Function="odata.UriEncode">
                            <Path>ProductKey</Path>
                          </Apply>
                        </LabeledElement>
                      </Apply>
                    </Url>
                  </Annotation>


                  <Annotation Term="DataFieldWithNavigation" Qualifier="FirstDataField">
                    <Record>
                      <PropertyValue Property="Label" String="Supplier" />
                      <PropertyValue Property="Value" Path="@ACR.Supplier/SupplierName" />
                      <PropertyValue Property="NavigationPath" NavigationPropertyPath="@ACR.Supplier" />
                    </Record>
                  </Annotation>

                  <Annotation Term="DataFieldWithNavigation" Qualifier="SecondDataField">
                    <Record>
                      <PropertyValue Property="Label" String="Purchase Orders" />
                      <PropertyValue Property="Value" Path="@ACR.NumberOfPurchaseOrders" />
                      <PropertyValue Property="NavigationPath" NavigationPropertyPath="@ACR.PurchaseOrders" />
                    </Record>
                  </Annotation>
                </Annotations>


              </Schema>
            </edmx:DataServices>
          </edmx:Edmx>
          ralfhandl Ralf Handl made changes -
          Proposal Introduce a edm:Url expression as a child of edm:annotation element:
          The edm:Url expression enables a value to be obtained by sending a GET request to the edm:Url expression value . A Url expression MUST be assigned a value of the type xs:string see [XML-Schema-2], section 3.2.1.

          The response body of the GET request MUST be returned as the result of the edm:Url expression. The edm:Url expression result MUST be type compatible with the type expected by the surrounding element or expression.
          Introduce a edm:Url expression as a child of edm:annotation element:
          The edm:Url expression enables a value to be obtained by sending a GET request to the edm:Url expression value . A Url expression MUST be assigned a value of the type xs:string see [XML-Schema-2], section 3.2.1.

          The response body of the GET request MUST be returned as the result of the edm:Url expression. The edm:Url expression result MUST be type compatible with the type expected by the surrounding element or expression.

          Accepted: https://www.oasis-open.org/committees/download.php/48411/odata-meeting-27_on-20130228-minutes.html#odata-278
          Status New [ 10000 ] Open [ 1 ]
          ralfhandl Ralf Handl made changes -
          Resolution Fixed [ 1 ]
          Status Open [ 1 ] Resolved [ 5 ]
          ralfhandl Ralf Handl made changes -
          Assignee Ralf Handl [ ralfhandl ]
          ralfhandl Ralf Handl made changes -
          handl Ralf Handl made changes -
          Assignee Ralf Handl [ ralfhandl ] Ralf Handl [ handl ]
          handl Ralf Handl made changes -
          Reporter Martin Zurmuehl [ martin.zurmuehl ] Martin Zurmuehl [ martinzurmuehl ]

            People

            • Assignee:
              handl Ralf Handl
              Reporter:
              martinzurmuehl Martin Zurmuehl
            • Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: