MSOpenTech/ODataJClient — pull request #152 by mkostin (2014-01-16 16:49:30+00:00)
Title: Added partial Enum support (work in progress on issue #110)

This commit is a part of the effort to moke proxy code generation work against OData v4 endpoint namely Office 365 Exchange API that is now very close but not fully compilant with OData v4 spec as of now. It is yet under development.

Actions are added as a stub as it is the dependency to make project work with metadata containing 'Actions'.

I have added enumerations generating template into plugin. It looks like there are no errors during generation but engine cannot handle actual values retrieved from server.

It assumes that value has string type, not enumeration. Sample:

{ … "Importance": "Normal", … }

Importance is defined in metadata as `EnumType`:

The following code was generated:

@Namespace("Microsoft.Exchange.Services.OData.Model")
@EnumType(value = "Importance")
public enum Importance implements Serializable {

Normal(0),
Low(1),
High(2);

private final int value;

Importance(int value) {
this.value= value;
}
}

However the actual value returned by `getImportance()` (using entity returned from the server) is `null`.
I believe the reason is that `@odata.type` annotation may be absent if type can be heuristically determined (http://docs.oasis-open.org/odata/odata-json-format/v4.0/cs01/odata-json-format-v4.0-cs01.html#_Toc365464687)

Currently I use the following approach for data determining (it is a part of the request):

EdmType edmType = StringUtils.isBlank(property.getAttribute(ODataConstants.ATTR_M_TYPE)) ? null :
new EdmType(property.getAttribute(ODataConstants.ATTR_M_TYPE));

if (edmType != null && edmType.isSimpleType() && edmType.getSimpleType() == EdmSimpleType.String) {
// possibly this is not string
// it is not string if no @odata.type annotation presented for this property and
// this simple type represented as string in JSON (DateTimeOffset, Int64 for example)
// See OData JSON format v4.0 section 4.5.3 for more information
boolean isTimeStamp = true;
try {
ODataTimestamp.parse(EdmSimpleType.DateTime, property.getTextContent());
} catch (Exception e) {
isTimeStamp = false;
}

if (isTimeStamp) {
edmType = new EdmType("Edm.DateTime"); // TODO how to distinguish DateTime and DateTimeOffset here?
} else { …

My next step is supposed to be parsing `Enum` values in similar way (e.g. by accessing metadata and getting possible field values). Do you think this implementation is feasible or there is another place in the class hierachy where it suits better?