When using the Proxy Generation Wizard in the SAP Netweaver Gateway Java Library I noticed for a few of my Collections where the property was set as the title, the Proxy code did not bring back the value.
In ABAP the default value for the method /IWBEP/IF_MGW_ODATA_PROPERTY~SET_AS_TITLE import parameter IV_KEEP_IN_CONTENT is ABAP_FALSE.
eg.
<Property Name="Name".. m:FC_TargetPath="SyndicationTitle" m:FC_KeepInContent="false"/>
This sets the value of Name to the atom:title, and omits Name from the atom:content properties
The proxy doesn't pick this up and tries to find the value in the properties
eg.
Mproperties properties = atomEntry.getContent().getmProperties();
this.Name = TypeConverter.convertToType( String.class,properties.getDataValue("Name"));
when it should be reading
this.Name = atomEntry.getAtomTitle(); or something similar.
Can m:FC_KeepInContent="false" be supported in future releases?
Cheers
JSP
NB. File Creating and Importing the Service Description File - SAP Documentation http://bit.ly/wpwNwu uses m:FC_KeepInContent="false" as do other example.
Hi John,
Thank you for providing this to our attention.
We are curretnly providing two solutions for simplifying Gateway service (OData) consumption in Java: proxy generation and a java client library (jar file).
I can advise you to use the java client library for this issue (as the proxy generation does not support these annotations). You can modify the "getName()" method of the generated proxy to return the value from the atom title with the client library (in this way you can still use the generated proxy).
We will look into supporting Feed Customization (FC) annotations in our proxy generation for future release.
Thanks,
Nir
Hi Nir,
Thanks for the quick response, I will start using the jar.
Are there any examples available for accessing the SAP Annotations?
eg.
Property( ).getSAPLabel( )
or Property( ).getSAPSemantics( )
Cheers
JSP
Hi John,
Unfortunately, we currently do not have any examples for accessing SAP Annotations.
However, please feel free to ask any question and we will try our best to answer quickly with a complementary example.
Regards,
Gal
Hi Gal,
Thanks for the response and the offer.
I'll rephrase the question to give it context.
The proxy generates a METADATA class, which for example has constants for values in the sap:label annotation.
eg
public static class METADATA {
public static final String CategoryID_label = "Category ID";
public static final String Name_label = "Category Name";
very easy to use
System.out.println(Category.METADATA.CategoryID_label + ": " + c.getCategoryID());
System.out.println(Category.METADATA.Name_label + ": "+ c.getName());
Category ID: 001
Category Name: Beverages
My question is how do I reference the $metadata when using the java client library on its own?
Cheers
JSP
Hi JSP,
To reference the metadata by using the java client library on its own you first need to have a metadata edmx document.
You can get it either from the SAP NetWeaver Gateway server by using online call or load it from an xml file.
Then, call the SDPHelper to parse the xml string into an Edmx object you can work with. Follow the code example below:
IGatewayConfiguration gateway = new GatewayConfiguration("<host>", "<port>", "<client>", "<username>", "<password>", "<useSSL>");
RestClient client = new RestClient(gateway);
String edmxXmlResponse = client.get("<url to metadata edmx xml>");
Edmx edmx = SDPHelper.fromXmlToEdmx(edmxXmlResponse);
List<Property> properties = EdmxUtilities.getProperties("<entity type name, e.g. Category>", edmx);
// iterate the entity type properties and get reference to their metadata attributes
for (Property property : properties) {
property.getSapLabel();
property.getName();
property.getType();
// get attribute by name
property.getAttribute("Nullable");
}
Thanks,
Gal
Hi Gal,
Thanks a lot for the example, that is actually what i was after.
I came up with a solution last night which took the scenic route
edmx.getEdmxDataServices().getSchemas()
schema.getEntityTypes())
if (entityType.getName().contentEquals("Category")
Property[] properties = entityType.getProperties();
I much prefer your solution,
List<Property> properties = EdmxUtilities.getProperties("Category", edmx);
cannot believe i didn't see the EdmxUtilities class before.
Thanks again
JSP
Your solution is also valid of course. You can still take the scenic route in cases you don't find what you need in EdmxUtilities.
Cheers,
Gal
Hi John,
As we are considering to support Feed Customization (FC) annotations in our proxy generation for future release, can you please explain what is the use case of this annotation?
Thanks,
Nir
Hi Nir
I came across FC_KeepInContent="false" when setting up the OData Channel - Subscription and Push Flow http://bit.ly/skVFJ0. I think this is a good use case. Users subscribe to entity changes on their devices. The notification I create in my mobile app uses the atom:title and looks like "X changes to entity Y", this value doesn't add value if it was to be also included in the content, in fact it would be an unwanted overhead.
If it helps my findings FC_KeepInContent="false" is supported in most OData browsers and libraries, currently datajs was the only method not supporting it and this is probably more to do with how this library is used.
If you are looking for more things, last night I found an anomaly with the way the generated proxy handles associations.
In my service the entity Supplier has a 0:N association with Product, the code generated in the proxy is trying to return a Supplier
// Supplier navigation properties
/**
* Navigation to Products
* @return Supplier
* @throws ProxyException
*/
public Supplier Products() throws ProxyException
{
Supplier result = null;
String url = this.atomEntry.getAtomId() + "/" + "Products";
String response = ZNWGWSAMPService.getInstance().getResponseString(url);
try {
AtomEntry atomEntry = SDPHelper.fromXmlToAtomEntry(response);
result = new Supplier (atomEntry);
} catch (ParserException e) {
throw new ProxyException("ParserException thrown in Products", e);
}
return result;
}
.
when it should be returning a list of Products, something like
public List<Product> Products() throws ProxyException
{
List<Product> list = new LinkedList<Product>();
String url = this.atomEntry.getAtomId() + "/" + "Products";
String response = ZNWGWSAMPService.getInstance().getResponseString(url);
try {
AtomFeed feed = SDPHelper.fromXmlToAtomFeed(response);
for (AtomEntry atomEntry : feed.getEntries())
{
list.add(new Product(atomEntry));
}
} catch (ParserException e) {
throw new ProxyException("ParserException thrown in Products", e);
}
return list;
}
I hope you don't mind me highlighting my findings, I really like the generated proxies and think they show a lot of promise.
Cheers
JSP
Hi John,
I am happy that you are highlighting your findings - it helps us to improve our product. Can you send us the metadata document for which the proxy was generated - we want to see if the problem is with the metadata document or a bug in our code.
Regarding FC annotation support for proxies - most likely we will add this in our next release.
Thanks,
Nir
Hi Nir
I have just spent some time looking into the anomaly with the associations. The majority of the time the code is correct. For the example above I created a Gateway service for http://services.odata.org/Northwind/Northwind.svc/$metadata using the OData Channel Generation tool.
I noticed using the RMTSAMPLEFLIGHT on NPL that something similar was generated for the Flight Entity and the Carrier association.
/**
* Navigation to FlightCarrier
* @return List<Flight>
* @throws ProxyException
*/
public List<Flight> FlightCarrier() throws ProxyException
{
List<Flight> result = null;
String url = this.atomEntry.getAtomId() + "/" + "FlightCarrier";
String response = RMTSAMPLEFLIGHTService.getInstance().getResponseString(url);
try {
AtomFeed feed = SDPHelper.fromXmlToAtomFeed(response);
result = new LinkedList<Flight>();
for (AtomEntry atomEntry : feed.getEntries())
{
result.add(new Flight (atomEntry));
}
} catch (ParserException e) {
throw new ProxyException("ParserException thrown in FlightCarrier", e);
}
return result;
}
Instead of returning a list of Flights, it should return a Carrier.
Hope it helps.
Cheers
JSP
Hi John,
Thanks for the feedback, we will look into the anomalies you mentioned.
Please note that we have a new version released on SCN [here|http://www.sdn.sap.com/irj/scn/downloads?rid=/webcontent/uuid/b09d414f-f227-2f10-bdbf-ba31c844b432].
In the new version we already added support for feed customizations in the generated proxies.
For example, The below metadata
<Property Name="title" Type="Edm.String" sap:label="Subscribed To" m:FC_TargetPath="SyndicationTitle" m:FC_KeepInContent="true" />
will result in the following code generated in the entity type constructor:
this.title = ((AtomEntry) entry).getAtomTitle();
Thanks and regards,
Gal