diff --git a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java index 03c59e4ca..6ff2c11ad 100644 --- a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java +++ b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java @@ -80,7 +80,6 @@ import org.apache.olingo.commons.core.data.AtomEntryImpl; import org.apache.olingo.commons.core.data.AtomPropertyImpl; import org.apache.olingo.commons.core.data.AtomSerializer; import org.apache.olingo.commons.core.data.JSONEntryImpl; -import org.apache.olingo.commons.core.data.JSONFeedImpl; import org.apache.olingo.commons.core.data.NullValueImpl; import org.apache.olingo.commons.core.data.PrimitiveValueImpl; import org.apache.olingo.fit.metadata.EntitySet; @@ -97,8 +96,8 @@ import org.apache.olingo.fit.utils.AbstractUtilities; import org.apache.olingo.fit.utils.AbstractXMLUtilities; import org.apache.olingo.fit.utils.LinkInfo; import org.apache.olingo.fit.metadata.Metadata; -import org.apache.olingo.fit.serializer.JsonFeedContainer; -import org.apache.olingo.fit.serializer.JsonEntryContainer; +import org.apache.olingo.fit.serializer.JSONFeedContainer; +import org.apache.olingo.fit.serializer.JSONEntryContainer; import org.apache.olingo.fit.utils.ConstantKey; import org.apache.olingo.fit.utils.Constants; import org.apache.olingo.fit.utils.DataBinder; @@ -138,7 +137,7 @@ public abstract class AbstractServices { this.version = version; this.atomDeserializer = Commons.getAtomDeserializer(version); this.atomSerializer = Commons.getAtomSerializer(version); - this.mapper = Commons.getJsonMapper(version); + this.mapper = Commons.getJSONMapper(version); this.dataBinder = new DataBinder(version); if (version.compareTo(ODataServiceVersion.V30) <= 0) { @@ -421,7 +420,7 @@ public abstract class AbstractServices { mapper.readValue(IOUtils.toInputStream(changes), new TypeReference() { }); - entryChanges = dataBinder.getAtomEntry(jcont.getObject()); + entryChanges = dataBinder.toAtomEntry(jcont.getObject()); } final Container container = atomDeserializer.read(entityInfo.getValue(), AtomEntryImpl.class); @@ -511,7 +510,7 @@ public abstract class AbstractServices { final Container jcont = mapper.readValue(res, new TypeReference() { }); cres = new Container(jcont.getContextURL(), jcont.getMetadataETag(), - dataBinder.getAtomEntry(jcont.getObject())); + dataBinder.toAtomEntry(jcont.getObject())); } final String path = Commons.getEntityBasePath(entitySetName, entityId); @@ -611,7 +610,7 @@ public abstract class AbstractServices { mapper.readValue(IOUtils.toInputStream(entity), new TypeReference() { }); - entry = dataBinder.getAtomEntry(jcontainer.getObject()); + entry = dataBinder.toAtomEntry(jcontainer.getObject()); container = new Container( jcontainer.getContextURL(), @@ -887,8 +886,8 @@ public abstract class AbstractServices { writer.close(); } else { mapper.writeValue( - writer, new JsonFeedContainer(container.getContextURL(), container.getMetadataETag(), - dataBinder.getJsonFeed(container.getObject()))); + writer, new JSONFeedContainer(container.getContextURL(), container.getMetadataETag(), + dataBinder.toJSONFeed(container.getObject()))); } return xml.createResponse( @@ -1076,7 +1075,6 @@ public abstract class AbstractServices { xml.writeEntry(utils.getKey(), container), Commons.getETag(entityInfo.getKey(), version), utils.getKey()); - } catch (Exception e) { LOG.error("Error retrieving entity", e); return xml.createFaultResponse(accept, e); @@ -1502,9 +1500,9 @@ public abstract class AbstractServices { } else { mapper.writeValue( writer, - new JsonFeedContainer(container.getContextURL(), + new JSONFeedContainer(container.getContextURL(), container.getMetadataETag(), - dataBinder.getJsonFeed((AtomFeedImpl) container.getObject()))); + dataBinder.toJSONFeed((AtomFeedImpl) container.getObject()))); } } else { final Container container = atomDeserializer.read(stream, AtomEntryImpl.class); @@ -1515,9 +1513,9 @@ public abstract class AbstractServices { } else { mapper.writeValue( writer, - new JsonEntryContainer(container.getContextURL(), + new JSONEntryContainer(container.getContextURL(), container.getMetadataETag(), - dataBinder.getJsonEntry((AtomEntryImpl) container.getObject()))); + dataBinder.toJSONEntry((AtomEntryImpl) container.getObject()))); } } diff --git a/fit/src/main/java/org/apache/olingo/fit/V4Services.java b/fit/src/main/java/org/apache/olingo/fit/V4Services.java index 9165af1b1..60c2e05fc 100644 --- a/fit/src/main/java/org/apache/olingo/fit/V4Services.java +++ b/fit/src/main/java/org/apache/olingo/fit/V4Services.java @@ -25,7 +25,6 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; -import java.io.StringWriter; import java.net.URI; import java.util.HashMap; import java.util.List; @@ -62,13 +61,10 @@ import org.apache.olingo.commons.core.data.AtomPropertyImpl; import org.apache.olingo.commons.core.data.CollectionValueImpl; import org.apache.olingo.commons.core.data.EnumValueImpl; import org.apache.olingo.commons.core.data.JSONEntryImpl; -import org.apache.olingo.commons.core.data.JSONFeedImpl; import org.apache.olingo.commons.core.data.JSONPropertyImpl; import org.apache.olingo.commons.core.data.PrimitiveValueImpl; import org.apache.olingo.commons.core.edm.EdmTypeInfo; import org.apache.olingo.fit.methods.PATCH; -import org.apache.olingo.fit.serializer.JsonFeedContainer; -import org.apache.olingo.fit.serializer.JsonPropertyContainer; import org.apache.olingo.fit.utils.AbstractUtilities; import org.apache.olingo.fit.utils.Accept; import org.apache.olingo.fit.utils.ConstantKey; @@ -180,6 +176,266 @@ public class V4Services extends AbstractServices { return new ByteArrayInputStream(bos.toByteArray()); } + @GET + @Path("/Company") + public Response getSingletonCompany( + @Context UriInfo uriInfo, + @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, + @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format) { + + return getEntityInternal( + uriInfo.getRequestUri().toASCIIString(), accept, "Company", StringUtils.EMPTY, format, null, null, false); + } + + @GET + @Path("/Company/Microsoft.Test.OData.Services.ODataWCFService.GetEmployeesCount") + public Response functionGetEmployeesCount( + @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, + @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format) { + + try { + final Accept acceptType; + if (StringUtils.isNotBlank(format)) { + acceptType = Accept.valueOf(format.toUpperCase()); + } else { + acceptType = Accept.parse(accept, version); + } + + final AtomPropertyImpl property = new AtomPropertyImpl(); + property.setType("Edm.Int32"); + property.setValue(new PrimitiveValueImpl("2")); + final Container container = new Container( + URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX) + property.getType()), null, + property); + + return xml.createResponse( + null, + xml.writeProperty(acceptType, container), + null, + acceptType); + } catch (Exception e) { + return xml.createFaultResponse(accept, e); + } + } + + @POST + @Path("/Company/Microsoft.Test.OData.Services.ODataWCFService.IncreaseRevenue") + public Response actionIncreaseRevenue( + @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, + @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) String contentType, + @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format, + final String param) { + + try { + final Accept acceptType; + if (StringUtils.isNotBlank(format)) { + acceptType = Accept.valueOf(format.toUpperCase()); + } else { + acceptType = Accept.parse(accept, version); + } + + final Accept contentTypeValue = Accept.parse(contentType, version); + final Entry entry = xml.readEntry(contentTypeValue, IOUtils.toInputStream(param, Constants.ENCODING)); + + return xml.createResponse( + null, + xml.writeProperty(acceptType, entry.getProperty("IncreaseValue")), + null, + acceptType); + } catch (Exception e) { + return xml.createFaultResponse(accept, e); + } + } + + @GET + @Path("/Products({entityId})/Microsoft.Test.OData.Services.ODataWCFService.GetProductDetails({param:.*})") + public Response functionGetProductDetails( + @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, + @PathParam("entityId") String entityId, + @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format) { + + try { + final Accept acceptType; + if (StringUtils.isNotBlank(format)) { + acceptType = Accept.valueOf(format.toUpperCase()); + } else { + acceptType = Accept.parse(accept, version); + } + + final AtomEntryImpl entry = new AtomEntryImpl(); + entry.setType("Microsoft.Test.OData.Services.ODataWCFService.ProductDetail"); + final Property productId = new AtomPropertyImpl(); + productId.setName("ProductID"); + productId.setType("Edm.Int32"); + productId.setValue(new PrimitiveValueImpl(entityId)); + entry.getProperties().add(productId); + final Property productDetailId = new AtomPropertyImpl(); + productDetailId.setName("ProductDetailID"); + productDetailId.setType("Edm.Int32"); + productDetailId.setValue(new PrimitiveValueImpl("2")); + entry.getProperties().add(productDetailId); + + final AtomFeedImpl feed = new AtomFeedImpl(); + feed.getEntries().add(entry); + + final Container container = new Container( + URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX) + "ProductDetail"), null, + feed); + + return xml.createResponse( + null, + xml.writeFeed(acceptType, container), + null, + acceptType); + } catch (Exception e) { + return xml.createFaultResponse(accept, e); + } + } + + @POST + @Path("/Products({entityId})/Microsoft.Test.OData.Services.ODataWCFService.AddAccessRight") + public Response actionAddAccessRight( + @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, + @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) String contentType, + @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format, + final String param) { + + try { + final Accept acceptType; + if (StringUtils.isNotBlank(format)) { + acceptType = Accept.valueOf(format.toUpperCase()); + } else { + acceptType = Accept.parse(accept, version); + } + + final Accept contentTypeValue = Accept.parse(contentType, version); + final Entry entry = xml.readEntry(contentTypeValue, IOUtils.toInputStream(param, Constants.ENCODING)); + + assert 1 == entry.getProperties().size(); + assert entry.getProperty("accessRight") != null; + + entry.getProperty("accessRight").setType("Microsoft.Test.OData.Services.ODataWCFService.AccessLevel"); + + return xml.createResponse( + null, + xml.writeProperty(acceptType, entry.getProperty("accessRight")), + null, + acceptType); + } catch (Exception e) { + return xml.createFaultResponse(accept, e); + } + } + + @POST + @Path("/Customers(PersonID={personId})/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress") + public Response actionResetAddress( + @Context UriInfo uriInfo, + @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, + @PathParam("personId") String personId, + @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) String contentType, + @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format, + final String param) { + + try { + final Accept contentTypeValue = Accept.parse(contentType, version); + final Entry entry = xml.readEntry(contentTypeValue, IOUtils.toInputStream(param, Constants.ENCODING)); + + assert 2 == entry.getProperties().size(); + assert entry.getProperty("addresses") != null; + assert entry.getProperty("index") != null; + + return getEntityInternal( + uriInfo.getRequestUri().toASCIIString(), accept, "Customers", personId, format, null, null, false); + } catch (Exception e) { + return xml.createFaultResponse(accept, e); + } + } + + @GET + @Path("/ProductDetails(ProductID={productId},ProductDetailID={productDetailId})" + + "/Microsoft.Test.OData.Services.ODataWCFService.GetRelatedProduct") + public Response functionGetRelatedProduct( + @Context UriInfo uriInfo, + @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, + @PathParam("productId") String productId, + @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format) { + + return getEntityInternal( + uriInfo.getRequestUri().toASCIIString(), accept, "Products", productId, format, null, null, false); + } + + @POST + @Path("/Accounts(101)/Microsoft.Test.OData.Services.ODataWCFService.RefreshDefaultPI") + public Response actionRefreshDefaultPI( + @Context UriInfo uriInfo, + @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, + @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) String contentType, + @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format, + final String param) { + + try { + final Accept contentTypeValue = Accept.parse(contentType, version); + final Entry entry = xml.readEntry(contentTypeValue, IOUtils.toInputStream(param, Constants.ENCODING)); + + assert 1 == entry.getProperties().size(); + assert entry.getProperty("newDate") != null; + + return functionGetDefaultPI(accept, format); + } catch (Exception e) { + return xml.createFaultResponse(accept, e); + } + } + + @GET + @Path("/Accounts(101)/Microsoft.Test.OData.Services.ODataWCFService.GetDefaultPI") + public Response functionGetDefaultPI( + @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, + @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format) { + + return getContainedEntity(accept, "101", "MyPaymentInstruments", "101901", format); + } + + @GET + @Path("/Accounts({entityId})/Microsoft.Test.OData.Services.ODataWCFService.GetAccountInfo") + public Response functionGetAccountInfo( + @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, + @PathParam("entityId") String entityId, + @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format) { + + return getPath(accept, "Accounts", entityId, "AccountInfo", format); + } + + @GET + @Path("/Accounts({entityId})/MyGiftCard/Microsoft.Test.OData.Services.ODataWCFService.GetActualAmount({param:.*})") + public Response functionGetActualAmount( + @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, + @PathParam("entityId") String entityId, + @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format) { + + try { + final Accept acceptType; + if (StringUtils.isNotBlank(format)) { + acceptType = Accept.valueOf(format.toUpperCase()); + } else { + acceptType = Accept.parse(accept, version); + } + + final AtomPropertyImpl property = new AtomPropertyImpl(); + property.setType("Edm.Double"); + property.setValue(new PrimitiveValueImpl("41.79")); + + final Container container = new Container(null, null, property); + + return xml.createResponse( + null, + xml.writeProperty(acceptType, container), + null, + acceptType); + } catch (Exception e) { + return xml.createFaultResponse(accept, e); + } + } + /** * Retrieve entity reference sample. * @@ -280,9 +536,11 @@ public class V4Services extends AbstractServices { throw new UnsupportedMediaTypeException("Unsupported media type"); } - final InputStream entry = FSManager.instance(version). - readFile(containedPath(entityId, containedEntitySetName). - append('(').append(containedEntityId).append(')').toString(), Accept.ATOM); + final StringBuilder containedPath = containedPath(entityId, containedEntitySetName); + if (StringUtils.isNotBlank(containedEntityId)) { + containedPath.append('(').append(containedEntityId).append(')'); + } + final InputStream entry = FSManager.instance(version).readFile(containedPath.toString(), Accept.ATOM); final Container container = atomDeserializer.read(entry, AtomEntryImpl.class); @@ -306,7 +564,6 @@ public class V4Services extends AbstractServices { @PathParam("containedEntitySetName") String containedEntitySetName, final String entity) { - // default try { final Accept acceptType = Accept.parse(accept, version); if (acceptType == Accept.XML || acceptType == Accept.TEXT) { @@ -327,7 +584,7 @@ public class V4Services extends AbstractServices { mapper.readValue(IOUtils.toInputStream(entity), new TypeReference() { }); - entry = dataBinder.getAtomEntry(jcontainer.getObject()); + entry = dataBinder.toAtomEntry(jcontainer.getObject()); entryContainer = new Container( jcontainer.getContextURL(), @@ -425,7 +682,7 @@ public class V4Services extends AbstractServices { new TypeReference() { }); jsonContainer.getObject().setType(typeInfo.getFullQualifiedName().toString()); - entryChanges = dataBinder.getAtomEntry(jsonContainer.getObject()); + entryChanges = dataBinder.toAtomEntry(jsonContainer.getObject()); } for (Property property : entryChanges.getProperties()) { @@ -494,6 +751,10 @@ public class V4Services extends AbstractServices { @PathParam("containedEntitySetName") String containedEntitySetName, @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format) { + if ("MyGiftCard".equals(containedEntitySetName)) { + return getContainedEntity(accept, entityId, containedEntitySetName, null, format); + } + try { final Accept acceptType; if (StringUtils.isNotBlank(format)) { @@ -510,22 +771,9 @@ public class V4Services extends AbstractServices { final Container container = atomDeserializer.read(feed, AtomFeedImpl.class); - final ByteArrayOutputStream content = new ByteArrayOutputStream(); - final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING); - - if (acceptType == Accept.ATOM) { - atomSerializer.write(writer, container); - writer.flush(); - writer.close(); - } else { - mapper.writeValue( - writer, new JsonFeedContainer(container.getContextURL(), container.getMetadataETag(), - dataBinder.getJsonFeed(container.getObject()))); - } - return xml.createResponse( null, - new ByteArrayInputStream(content.toByteArray()), + xml.writeFeed(acceptType, container), null, acceptType); } catch (Exception e) { @@ -554,22 +802,9 @@ public class V4Services extends AbstractServices { URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX) + property.getType()), null, property); - final ByteArrayOutputStream content = new ByteArrayOutputStream(); - final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING); - - if (acceptType == Accept.XML) { - atomSerializer.write(writer, container); - writer.flush(); - writer.close(); - } else { - mapper.writeValue( - writer, new JsonPropertyContainer(container.getContextURL(), - container.getMetadataETag(), dataBinder.getJsonProperty(container.getObject()))); - } - return xml.createResponse( null, - new ByteArrayInputStream(content.toByteArray()), + xml.writeProperty(acceptType, container), null, acceptType); } catch (Exception e) { @@ -637,22 +872,9 @@ public class V4Services extends AbstractServices { URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX) + property.getType()), null, property); - final ByteArrayOutputStream content = new ByteArrayOutputStream(); - final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING); - - if (acceptType == Accept.XML) { - atomSerializer.write(writer, container); - writer.flush(); - writer.close(); - } else { - mapper.writeValue( - writer, new JsonPropertyContainer(container.getContextURL(), - container.getMetadataETag(), dataBinder.getJsonProperty(container.getObject()))); - } - return xml.createResponse( null, - new ByteArrayInputStream(content.toByteArray()), + xml.writeProperty(acceptType, container), null, acceptType); } catch (Exception e) { @@ -685,22 +907,9 @@ public class V4Services extends AbstractServices { URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX) + property.getType()), null, property); - final ByteArrayOutputStream content = new ByteArrayOutputStream(); - final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING); - - if (acceptType == Accept.XML) { - atomSerializer.write(writer, container); - writer.flush(); - writer.close(); - } else { - mapper.writeValue( - writer, new JsonPropertyContainer(container.getContextURL(), - container.getMetadataETag(), dataBinder.getJsonProperty(container.getObject()))); - } - return xml.createResponse( null, - new ByteArrayInputStream(content.toByteArray()), + xml.writeProperty(acceptType, container), null, acceptType); } catch (Exception e) { @@ -785,7 +994,7 @@ public class V4Services extends AbstractServices { return xml.createResponse( null, - new ByteArrayInputStream(param.getBytes(Constants.ENCODING)), + IOUtils.toInputStream(param, Constants.ENCODING), null, acceptType); } catch (Exception e) { @@ -810,33 +1019,15 @@ public class V4Services extends AbstractServices { } final Accept contentTypeValue = Accept.parse(contentType, version); - Entry entry; - if (contentTypeValue == Accept.XML) { - final Container paramContainer = atomDeserializer.read( - IOUtils.toInputStream(param, Constants.ENCODING), AtomEntryImpl.class); - entry = paramContainer.getObject(); - } else { - final Container paramContainer = - mapper.readValue(IOUtils.toInputStream(param, Constants.ENCODING), - new TypeReference() { - }); - entry = paramContainer.getObject(); - } + final Entry entry = xml.readEntry(contentTypeValue, IOUtils.toInputStream(param, Constants.ENCODING)); assert 1 == entry.getProperties().size(); assert "Collection(Edm.String)".equals(entry.getProperty("emails").getType()); assert entry.getProperty("emails").getValue().isCollection(); - final StringWriter writer = new StringWriter(); - if (acceptType == Accept.XML) { - atomSerializer.write(writer, entry.getProperty("emails")); - } else { - mapper.writeValue(writer, entry.getProperty("emails")); - } - return xml.createResponse( null, - new ByteArrayInputStream(writer.toString().getBytes(Constants.ENCODING)), + xml.writeProperty(acceptType, entry.getProperty("emails")), null, acceptType); } catch (Exception e) { diff --git a/fit/src/main/java/org/apache/olingo/fit/serializer/JsonEntryContainer.java b/fit/src/main/java/org/apache/olingo/fit/serializer/JSONEntryContainer.java similarity index 85% rename from fit/src/main/java/org/apache/olingo/fit/serializer/JsonEntryContainer.java rename to fit/src/main/java/org/apache/olingo/fit/serializer/JSONEntryContainer.java index 5ff4f6eb8..f61f36a83 100644 --- a/fit/src/main/java/org/apache/olingo/fit/serializer/JsonEntryContainer.java +++ b/fit/src/main/java/org/apache/olingo/fit/serializer/JSONEntryContainer.java @@ -23,13 +23,14 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import java.net.URI; import org.apache.olingo.commons.api.data.Container; import org.apache.olingo.commons.core.data.JSONEntryDeserializer; +import org.apache.olingo.commons.core.data.JSONEntryImpl; import org.apache.olingo.commons.core.data.JSONEntrySerializer; @JsonDeserialize(using = JSONEntryDeserializer.class) @JsonSerialize(using = JSONEntrySerializer.class) -public class JsonEntryContainer extends Container { +public class JSONEntryContainer extends Container { - public JsonEntryContainer(final URI contextURL, final String metadataETag, final T object) { + public JSONEntryContainer(final URI contextURL, final String metadataETag, final JSONEntryImpl object) { super(contextURL, metadataETag, object); } } diff --git a/fit/src/main/java/org/apache/olingo/fit/serializer/JsonFeedContainer.java b/fit/src/main/java/org/apache/olingo/fit/serializer/JSONFeedContainer.java similarity index 85% rename from fit/src/main/java/org/apache/olingo/fit/serializer/JsonFeedContainer.java rename to fit/src/main/java/org/apache/olingo/fit/serializer/JSONFeedContainer.java index 6af08ddd8..3c64f4fa6 100644 --- a/fit/src/main/java/org/apache/olingo/fit/serializer/JsonFeedContainer.java +++ b/fit/src/main/java/org/apache/olingo/fit/serializer/JSONFeedContainer.java @@ -23,13 +23,14 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import java.net.URI; import org.apache.olingo.commons.api.data.Container; import org.apache.olingo.commons.core.data.JSONFeedDeserializer; +import org.apache.olingo.commons.core.data.JSONFeedImpl; import org.apache.olingo.commons.core.data.JSONFeedSerializer; @JsonDeserialize(using = JSONFeedDeserializer.class) @JsonSerialize(using = JSONFeedSerializer.class) -public class JsonFeedContainer extends Container { +public class JSONFeedContainer extends Container { - public JsonFeedContainer(final URI contextURL, final String metadataETag, final T object) { + public JSONFeedContainer(final URI contextURL, final String metadataETag, final JSONFeedImpl object) { super(contextURL, metadataETag, object); } } diff --git a/fit/src/main/java/org/apache/olingo/fit/serializer/JsonPropertyContainer.java b/fit/src/main/java/org/apache/olingo/fit/serializer/JSONPropertyContainer.java similarity index 84% rename from fit/src/main/java/org/apache/olingo/fit/serializer/JsonPropertyContainer.java rename to fit/src/main/java/org/apache/olingo/fit/serializer/JSONPropertyContainer.java index a79c39791..2cf7a7c39 100644 --- a/fit/src/main/java/org/apache/olingo/fit/serializer/JsonPropertyContainer.java +++ b/fit/src/main/java/org/apache/olingo/fit/serializer/JSONPropertyContainer.java @@ -23,13 +23,14 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import java.net.URI; import org.apache.olingo.commons.api.data.Container; import org.apache.olingo.commons.core.data.JSONPropertyDeserializer; +import org.apache.olingo.commons.core.data.JSONPropertyImpl; import org.apache.olingo.commons.core.data.JSONPropertySerializer; @JsonDeserialize(using = JSONPropertyDeserializer.class) @JsonSerialize(using = JSONPropertySerializer.class) -public class JsonPropertyContainer extends Container { +public class JSONPropertyContainer extends Container { - public JsonPropertyContainer(final URI contextURL, final String metadataETag, final T object) { + public JSONPropertyContainer(final URI contextURL, final String metadataETag, final JSONPropertyImpl object) { super(contextURL, metadataETag, object); } } diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractJSONUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractJSONUtilities.java index 3a22c6401..369d6576d 100644 --- a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractJSONUtilities.java +++ b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractJSONUtilities.java @@ -201,7 +201,7 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities { final ObjectNode propertyNode = new ObjectNode(JsonNodeFactory.instance); - if (StringUtils.isNotBlank(edmType)) { + if (StringUtils.isNotBlank(edmType) && version.compareTo(ODataServiceVersion.V40) < 0) { propertyNode.put(Constants.get( version, ConstantKey.JSON_ODATAMETADATA_NAME), Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX) + edmType); diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java index a84ef60d9..6a1dc105f 100644 --- a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java +++ b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java @@ -25,7 +25,6 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStreamWriter; import java.io.StringWriter; import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; @@ -46,13 +45,21 @@ import org.apache.commons.vfs2.FileObject; import org.apache.olingo.commons.api.data.Container; import org.apache.olingo.commons.api.data.Entry; import org.apache.olingo.commons.api.data.Link; +import org.apache.olingo.commons.api.data.Property; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.commons.core.data.AtomEntryImpl; +import org.apache.olingo.commons.core.data.AtomFeedImpl; +import org.apache.olingo.commons.core.data.AtomPropertyImpl; +import org.apache.olingo.commons.core.data.AtomSerializer; import org.apache.olingo.commons.core.data.JSONEntryImpl; +import org.apache.olingo.commons.core.data.JSONPropertyImpl; import org.apache.olingo.fit.UnsupportedMediaTypeException; import org.apache.olingo.fit.metadata.Metadata; import org.apache.olingo.fit.metadata.NavigationProperty; -import org.apache.olingo.fit.serializer.JsonEntryContainer; +import org.apache.olingo.fit.serializer.FITAtomDeserializer; +import org.apache.olingo.fit.serializer.JSONEntryContainer; +import org.apache.olingo.fit.serializer.JSONFeedContainer; +import org.apache.olingo.fit.serializer.JSONPropertyContainer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -63,10 +70,6 @@ public abstract class AbstractUtilities { */ protected static final Logger LOG = LoggerFactory.getLogger(AbstractUtilities.class); - protected final ODataServiceVersion version; - - protected final FSManager fsManager; - protected static final Pattern ENTITY_URI_PATTERN = Pattern.compile(".*\\/.*\\(.*\\)"); /** @@ -84,9 +87,25 @@ public abstract class AbstractUtilities { */ public static final String BOUNDARY = "boundary"; + protected final ODataServiceVersion version; + + protected final FSManager fsManager; + + protected final DataBinder dataBinder; + + protected final FITAtomDeserializer atomDeserializer; + + protected final AtomSerializer atomSerializer; + + protected final ObjectMapper mapper; + public AbstractUtilities(final ODataServiceVersion version) throws Exception { this.version = version; this.fsManager = FSManager.instance(version); + this.dataBinder = new DataBinder(version); + this.atomDeserializer = Commons.getAtomDeserializer(version); + this.atomSerializer = Commons.getAtomSerializer(version); + this.mapper = Commons.getJSONMapper(version); } public boolean isMediaContent(final String entityName) { @@ -181,7 +200,7 @@ public abstract class AbstractUtilities { private InputStream toInputStream(final AtomEntryImpl entry) throws XMLStreamException { final StringWriter writer = new StringWriter(); - Commons.getAtomSerializer(version).write(writer, entry); + atomSerializer.write(writer, entry); return IOUtils.toInputStream(writer.toString(), Constants.ENCODING); } @@ -273,7 +292,8 @@ public abstract class AbstractUtilities { final List hrefs = new ArrayList(); for (final Link link : entry.getNavigationLinks()) { - final NavigationProperty navProp = navigationProperties == null? null: navigationProperties.get(link.getTitle()); + final NavigationProperty navProp = navigationProperties == null + ? null : navigationProperties.get(link.getTitle()); if (navProp != null) { final String inlineEntitySetName = navProp.getTarget(); if (link.getInlineEntry() != null) { @@ -555,20 +575,36 @@ public abstract class AbstractUtilities { return builder.build(); } + public InputStream writeFeed(final Accept accept, final Container container) + throws XMLStreamException, IOException { + + final StringWriter writer = new StringWriter(); + if (accept == Accept.ATOM) { + atomSerializer.write(writer, container); + writer.flush(); + writer.close(); + } else { + mapper.writeValue( + writer, new JSONFeedContainer(container.getContextURL(), + container.getMetadataETag(), dataBinder.toJSONFeed(container.getObject()))); + } + + return IOUtils.toInputStream(writer.toString(), Constants.ENCODING); + } + public AtomEntryImpl readEntry(final Accept contentTypeValue, final InputStream entity) throws XMLStreamException, IOException { final AtomEntryImpl entry; - if (Accept.ATOM == contentTypeValue) { - final Container container = Commons.getAtomDeserializer(version). - read(entity, AtomEntryImpl.class); + if (Accept.ATOM == contentTypeValue || Accept.XML == contentTypeValue) { + final Container container = atomDeserializer.read(entity, AtomEntryImpl.class); entry = container.getObject(); } else { - final Container jcontainer = - Commons.getJsonMapper(version).readValue(entity, new TypeReference() { + final Container container = + mapper.readValue(entity, new TypeReference() { }); - entry = new DataBinder(version).getAtomEntry(jcontainer.getObject()); + entry = dataBinder.toAtomEntry(container.getObject()); } return entry; @@ -577,21 +613,46 @@ public abstract class AbstractUtilities { public InputStream writeEntry(final Accept accept, final Container container) throws XMLStreamException, IOException { - final ByteArrayOutputStream content = new ByteArrayOutputStream(); - final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING); - + final StringWriter writer = new StringWriter(); if (accept == Accept.ATOM) { - Commons.getAtomSerializer(version).write(writer, container); - writer.flush(); - writer.close(); + atomSerializer.write(writer, container); } else { - final ObjectMapper mapper = Commons.getJsonMapper(version); mapper.writeValue( - writer, new JsonEntryContainer(container.getContextURL(), container.getMetadataETag(), - new DataBinder(version).getJsonEntry((AtomEntryImpl) container.getObject()))); + writer, new JSONEntryContainer(container.getContextURL(), container.getMetadataETag(), + dataBinder.toJSONEntry(container.getObject()))); } - return new ByteArrayInputStream(content.toByteArray()); + return IOUtils.toInputStream(writer.toString(), Constants.ENCODING); + } + + public InputStream writeProperty(final Accept accept, final Property property) + throws XMLStreamException, IOException { + + final StringWriter writer = new StringWriter(); + if (accept == Accept.XML || accept == Accept.ATOM) { + atomSerializer.write(writer, property instanceof AtomPropertyImpl + ? property : dataBinder.toAtomProperty((JSONPropertyImpl) property, property.getType())); + } else { + mapper.writeValue(writer, property instanceof JSONPropertyImpl + ? property : dataBinder.toJSONProperty((AtomPropertyImpl) property)); + } + + return IOUtils.toInputStream(writer.toString(), Constants.ENCODING); + } + + public InputStream writeProperty(final Accept accept, final Container container) + throws XMLStreamException, IOException { + + final StringWriter writer = new StringWriter(); + if (accept == Accept.XML) { + atomSerializer.write(writer, container); + } else { + mapper.writeValue( + writer, new JSONPropertyContainer(container.getContextURL(), container.getMetadataETag(), + dataBinder.toJSONProperty(container.getObject()))); + } + + return IOUtils.toInputStream(writer.toString(), Constants.ENCODING); } private String getDefaultEntryKey(final String entitySetName, final AtomEntryImpl entry, final String propertyName) diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java b/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java index c3c0cbbf4..5d35bdc76 100644 --- a/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java +++ b/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java @@ -111,7 +111,7 @@ public abstract class Commons { return ATOM_SERIALIZER.get(version); } - public static ObjectMapper getJsonMapper(final ODataServiceVersion version) { + public static ObjectMapper getJSONMapper(final ODataServiceVersion version) { if (!JSON_MAPPER.containsKey(version)) { final ObjectMapper mapper = new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL); diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/DataBinder.java b/fit/src/main/java/org/apache/olingo/fit/utils/DataBinder.java index 986c99770..c9b364610 100644 --- a/fit/src/main/java/org/apache/olingo/fit/utils/DataBinder.java +++ b/fit/src/main/java/org/apache/olingo/fit/utils/DataBinder.java @@ -52,7 +52,7 @@ public class DataBinder { this.version = version; } - public JSONFeedImpl getJsonFeed(final AtomFeedImpl atomfeed) { + public JSONFeedImpl toJSONFeed(final AtomFeedImpl atomfeed) { final JSONFeedImpl jsonfeed = new JSONFeedImpl(); BeanUtils.copyProperties(atomfeed, jsonfeed, "baseURI", "metadataContextURL"); @@ -62,13 +62,13 @@ public class DataBinder { final Collection entries = jsonfeed.getEntries(); for (Entry entry : atomfeed.getEntries()) { - entries.add(getJsonEntry((AtomEntryImpl) entry)); + entries.add(toJSONEntry((AtomEntryImpl) entry)); } return jsonfeed; } - public AtomFeedImpl getAtomFeed(final JSONFeedImpl jsonfeed) { + public AtomFeedImpl toAtomFeed(final JSONFeedImpl jsonfeed) { final AtomFeedImpl atomfeed = new AtomFeedImpl(); BeanUtils.copyProperties(jsonfeed, atomfeed, "baseURI", "metadataContextURL"); @@ -78,17 +78,18 @@ public class DataBinder { final Collection entries = atomfeed.getEntries(); for (Entry entry : jsonfeed.getEntries()) { - entries.add(getAtomEntry((JSONEntryImpl) entry)); + entries.add(toAtomEntry((JSONEntryImpl) entry)); } return atomfeed; } - public JSONEntryImpl getJsonEntry(final AtomEntryImpl atomentry) { + public JSONEntryImpl toJSONEntry(final AtomEntryImpl atomentry) { final JSONEntryImpl jsonentry = new JSONEntryImpl(); BeanUtils.copyProperties(atomentry, jsonentry, "baseURI", "properties", "links"); jsonentry.setBaseURI(atomentry.getBaseURI() == null ? null : atomentry.getBaseURI().toASCIIString()); + jsonentry.getOperations().addAll(atomentry.getOperations()); for (Link link : atomentry.getNavigationLinks()) { final Link jlink = new LinkImpl(); @@ -100,12 +101,12 @@ public class DataBinder { if (link.getInlineEntry() instanceof AtomEntryImpl) { final Entry inlineEntry = link.getInlineEntry(); if (inlineEntry instanceof AtomEntryImpl) { - jlink.setInlineEntry(getJsonEntry((AtomEntryImpl) link.getInlineEntry())); + jlink.setInlineEntry(toJSONEntry((AtomEntryImpl) link.getInlineEntry())); } } else if (link.getInlineFeed() instanceof AtomFeedImpl) { final Feed inlineFeed = link.getInlineFeed(); if (inlineFeed instanceof AtomFeedImpl) { - jlink.setInlineFeed(getJsonFeed((AtomFeedImpl) link.getInlineFeed())); + jlink.setInlineFeed(toJSONFeed((AtomFeedImpl) link.getInlineFeed())); } } @@ -114,13 +115,13 @@ public class DataBinder { final Collection properties = jsonentry.getProperties(); for (Property property : atomentry.getProperties()) { - properties.add(getJsonProperty((AtomPropertyImpl) property)); + properties.add(toJSONProperty((AtomPropertyImpl) property)); } return jsonentry; } - public AtomEntryImpl getAtomEntry(final JSONEntryImpl jsonentry) { + public AtomEntryImpl toAtomEntry(final JSONEntryImpl jsonentry) { final AtomEntryImpl atomentry = new AtomEntryImpl(); final Metadata metadata = Commons.getMetadata(version); @@ -143,12 +144,12 @@ public class DataBinder { if (link.getInlineEntry() instanceof JSONEntryImpl) { final Entry inlineEntry = link.getInlineEntry(); if (inlineEntry instanceof JSONEntryImpl) { - alink.setInlineEntry(getAtomEntry((JSONEntryImpl) link.getInlineEntry())); + alink.setInlineEntry(toAtomEntry((JSONEntryImpl) link.getInlineEntry())); } } else if (link.getInlineFeed() instanceof JSONFeedImpl) { final Feed inlineFeed = link.getInlineFeed(); if (inlineFeed instanceof JSONFeedImpl) { - alink.setInlineFeed(getAtomFeed((JSONFeedImpl) link.getInlineFeed())); + alink.setInlineFeed(toAtomFeed((JSONFeedImpl) link.getInlineFeed())); } } @@ -187,7 +188,7 @@ public class DataBinder { final Entry inlineEntry = new AtomEntryImpl(); inlineEntry.setType(navProperties.get(property.getName()).getType()); for (Property prop : entry.asComplex().get()) { - inlineEntry.getProperties().add(getAtomProperty((JSONPropertyImpl) prop, inlineEntry.getType())); + inlineEntry.getProperties().add(toAtomProperty((JSONPropertyImpl) prop, inlineEntry.getType())); } inline.getEntries().add(inlineEntry); } @@ -197,14 +198,14 @@ public class DataBinder { } atomentry.getNavigationLinks().add(alink); } else { - properties.add(getAtomProperty((JSONPropertyImpl) property, atomentry.getType())); + properties.add(toAtomProperty((JSONPropertyImpl) property, atomentry.getType())); } } return atomentry; } - public JSONPropertyImpl getJsonProperty(final AtomPropertyImpl atomproperty) { + public JSONPropertyImpl toJSONProperty(final AtomPropertyImpl atomproperty) { final JSONPropertyImpl jsonproperty = new JSONPropertyImpl(); BeanUtils.copyProperties(atomproperty, jsonproperty, "value"); @@ -213,7 +214,7 @@ public class DataBinder { jsonproperty.setValue(complex); for (Property field : atomproperty.getValue().asComplex().get()) { - complex.get().add(getJsonProperty((AtomPropertyImpl) field)); + complex.get().add(toJSONProperty((AtomPropertyImpl) field)); } } else if (atomproperty.getValue().isCollection()) { final CollectionValueImpl collection = new CollectionValueImpl(); @@ -225,7 +226,7 @@ public class DataBinder { collection.get().add(complex); for (Property field : element.asComplex().get()) { - complex.get().add(getJsonProperty((AtomPropertyImpl) field)); + complex.get().add(toJSONProperty((AtomPropertyImpl) field)); } } else { collection.get().add(element); @@ -238,14 +239,14 @@ public class DataBinder { return jsonproperty; } - public AtomPropertyImpl getAtomProperty(final JSONPropertyImpl jsonproperty, final String entryType) { + public AtomPropertyImpl toAtomProperty(final JSONPropertyImpl jsonproperty, final String entryType) { final AtomPropertyImpl atomproperty = new AtomPropertyImpl(); atomproperty.setName(jsonproperty.getName()); if (StringUtils.isNotBlank(jsonproperty.getType())) { atomproperty.setType(jsonproperty.getType()); } else { - final EntityType entityType = Commons.getMetadata(version).getEntityType(entryType); + final EntityType entityType = entryType == null ? null : Commons.getMetadata(version).getEntityType(entryType); if (entityType != null) { atomproperty.setType(entityType.getProperty(jsonproperty.getName()).getType()); } @@ -256,7 +257,7 @@ public class DataBinder { atomproperty.setValue(complex); for (Property field : jsonproperty.getValue().asComplex().get()) { - complex.get().add(getAtomProperty((JSONPropertyImpl) field, atomproperty.getType())); + complex.get().add(toAtomProperty((JSONPropertyImpl) field, atomproperty.getType())); } } else if (jsonproperty.getValue().isCollection()) { final CollectionValueImpl collection = new CollectionValueImpl(); @@ -268,8 +269,10 @@ public class DataBinder { collection.get().add(complex); for (Property field : element.asComplex().get()) { - complex.get().add(getAtomProperty((JSONPropertyImpl) field, - atomproperty.getType().replaceAll("^Collection\\(", "").replaceAll("\\)$", ""))); + complex.get().add(toAtomProperty((JSONPropertyImpl) field, + atomproperty.getType() == null + ? null + : atomproperty.getType().replaceAll("^Collection\\(", "").replaceAll("\\)$", ""))); } } else { collection.get().add(element); diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java b/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java index b7d21f448..014da7d5c 100644 --- a/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java +++ b/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java @@ -40,8 +40,7 @@ import org.apache.olingo.commons.api.data.Container; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.commons.core.data.AtomEntryImpl; import org.apache.olingo.commons.core.data.AtomSerializer; -import org.apache.olingo.commons.core.data.JSONEntryImpl; -import org.apache.olingo.fit.serializer.JsonEntryContainer; +import org.apache.olingo.fit.serializer.JSONEntryContainer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -113,12 +112,12 @@ public class FSManager { putInMemory(new ByteArrayInputStream(content.toByteArray()), getAbsolutePath(relativePath, Accept.ATOM)); content.reset(); - final ObjectMapper mapper = Commons.getJsonMapper(version); + final ObjectMapper mapper = Commons.getJSONMapper(version); mapper.writeValue( - writer, new JsonEntryContainer( + writer, new JSONEntryContainer( container.getContextURL(), container.getMetadataETag(), - new DataBinder(version).getJsonEntry(container.getObject()))); + new DataBinder(version).toJSONEntry(container.getObject()))); putInMemory(new ByteArrayInputStream(content.toByteArray()), getAbsolutePath(relativePath, Accept.JSON_FULLMETA)); } catch (Exception e) { diff --git a/fit/src/main/resources/V40/Accounts/101/entity.xml b/fit/src/main/resources/V40/Accounts/101/entity.xml index 6ee3a87c2..82c8976e0 100644 --- a/fit/src/main/resources/V40/Accounts/101/entity.xml +++ b/fit/src/main/resources/V40/Accounts/101/entity.xml @@ -32,6 +32,15 @@ + + + 101 diff --git a/fit/src/main/resources/V40/Accounts/101/links/MyGiftCard.full.json b/fit/src/main/resources/V40/Accounts/101/links/MyGiftCard.full.json new file mode 100644 index 000000000..4f8c0b964 --- /dev/null +++ b/fit/src/main/resources/V40/Accounts/101/links/MyGiftCard.full.json @@ -0,0 +1,15 @@ +{ + "@odata.context": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Accounts(101)/MyGiftCard/$entity", + "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.GiftCard", + "@odata.id": "Accounts(101)/MyGiftCard", + "@odata.editLink": "Accounts(101)/MyGiftCard", + "GiftCardID": 301, + "GiftCardNO": "AAA123A", + "Amount": 19.9, + "ExperationDate@odata.type": "#DateTimeOffset", + "ExperationDate": "2013-12-30T00:00:00Z", + "#Microsoft.Test.OData.Services.ODataWCFService.GetActualAmount": { + "title": "Microsoft.Test.OData.Services.ODataWCFService.GetActualAmount", + "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Accounts(101)/MyGiftCard/Microsoft.Test.OData.Services.ODataWCFService.GetActualAmount" + } +} diff --git a/fit/src/main/resources/V40/Accounts/101/links/MyGiftCard.xml b/fit/src/main/resources/V40/Accounts/101/links/MyGiftCard.xml new file mode 100644 index 000000000..b3328231a --- /dev/null +++ b/fit/src/main/resources/V40/Accounts/101/links/MyGiftCard.xml @@ -0,0 +1,41 @@ + + + + + + + <updated>2014-04-23T13:48:48Z</updated> + <author> + <name /> + </author> + <m:action metadata="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Microsoft.Test.OData.Services.ODataWCFService.GetActualAmount" + title="Microsoft.Test.OData.Services.ODataWCFService.GetActualAmount" + target="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Accounts(101)/MyGiftCard/Microsoft.Test.OData.Services.ODataWCFService.GetActualAmount"/> + <content type="application/xml"> + <m:properties> + <d:GiftCardID m:type="Int32">301</d:GiftCardID> + <d:GiftCardNO>AAA123A</d:GiftCardNO> + <d:Amount m:type="Double">19.9</d:Amount> + <d:ExperationDate m:type="DateTimeOffset">2013-12-30T00:00:00Z</d:ExperationDate> + </m:properties> + </content> +</entry> diff --git a/fit/src/main/resources/V40/Company/entity.xml b/fit/src/main/resources/V40/Company/entity.xml index 6beed3b65..49a616732 100644 --- a/fit/src/main/resources/V40/Company/entity.xml +++ b/fit/src/main/resources/V40/Company/entity.xml @@ -32,6 +32,12 @@ <author> <name /> </author> + <m:action metadata="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Microsoft.Test.OData.Services.ODataWCFService.IncreaseRevenue" + title="Microsoft.Test.OData.Services.ODataWCFService.IncreaseRevenue" + target="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company/Microsoft.Test.OData.Services.ODataWCFService.IncreaseRevenue"/> + <m:action metadata="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Microsoft.Test.OData.Services.ODataWCFService.GetEmployeesCount" + title="Microsoft.Test.OData.Services.ODataWCFService.GetEmployeesCount" + target="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company/Microsoft.Test.OData.Services.ODataWCFService.GetEmployeesCount"/> <content type="application/xml"> <m:properties> <d:CompanyID m:type="Int32">0</d:CompanyID> diff --git a/fit/src/main/resources/V40/Customers/2/entity.full.json b/fit/src/main/resources/V40/Customers/2/entity.full.json new file mode 100644 index 000000000..2756d8889 --- /dev/null +++ b/fit/src/main/resources/V40/Customers/2/entity.full.json @@ -0,0 +1,50 @@ +{ + "@odata.context": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Customers/$entity", + "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Customer", + "@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)", + "@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)", + "PersonID": 2, + "FirstName": "Jill", + "LastName": "Jones", + "MiddleName": null, + "HomeAddress": { + "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Address", + "Street": "Piazza La Bomba E Scappa", + "City": "Tollo", + "PostalCode": "66010" + }, + "Home@odata.type": "#GeographyPoint", + "Home": { + "type": "Point", + "coordinates": [161.8, 15.0], + "crs": { + "type": "name", + "properties": { + "name": "EPSG:4326" + } + } + }, + "Numbers@odata.type": "#Collection(String)", + "Numbers": [], + "Emails@odata.type": "#Collection(String)", + "Emails": [], + "City": "Sydney", + "Birthday@odata.type": "#DateTimeOffset", + "Birthday": "1983-01-15T00:00:00Z", + "TimeBetweenLastTwoOrders@odata.type": "#Duration", + "TimeBetweenLastTwoOrders": "PT0.0000002S", + "Parent@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)/Parent/$ref", + "Parent@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)/Parent", + "Orders@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)/Orders/$ref", + "Orders@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)/Orders", + "Company@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)/Company/$ref", + "Company@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)/Company", + "#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress": { + "title": "Microsoft.Test.OData.Services.ODataWCFService.ResetAddress", + "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress" + }, + "#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress": { + "title": "Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress", + "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress" + } +} diff --git a/fit/src/main/resources/V40/Customers/2/entity.xml b/fit/src/main/resources/V40/Customers/2/entity.xml new file mode 100644 index 000000000..686fcacdd --- /dev/null +++ b/fit/src/main/resources/V40/Customers/2/entity.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +--> +<entry xml:base="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://docs.oasis-open.org/odata/ns/data" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" m:context="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Customers/$entity"> + <id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)</id> + <category term="#Microsoft.Test.OData.Services.ODataWCFService.Customer" scheme="http://docs.oasis-open.org/odata/ns/scheme" /> + <link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)" /> + <link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)/Parent" /> + <link rel="http://docs.oasis-open.org/odata/ns/related/Orders" type="application/atom+xml;type=feed" title="Orders" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)/Orders" /> + <link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)/Company" /> + <title /> + <updated>2014-04-23T15:27:13Z</updated> + <author> + <name /> + </author> + <m:action metadata="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress" + title="Microsoft.Test.OData.Services.ODataWCFService.ResetAddress" + target="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress"/> + <m:action metadata="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress" + title="Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress" + target="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"/> + <content type="application/xml"> + <m:properties> + <d:PersonID m:type="Int32">2</d:PersonID> + <d:FirstName>Jill</d:FirstName> + <d:LastName>Jones</d:LastName> + <d:MiddleName m:null="true" /> + <d:HomeAddress m:type="#Microsoft.Test.OData.Services.ODataWCFService.Address"> + <d:Street>Piazza La Bomba E Scappa</d:Street> + <d:City>Tollo</d:City> + <d:PostalCode>66010</d:PostalCode> + </d:HomeAddress> + <d:Home m:type="GeographyPoint"> + <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326"> + <gml:pos>15 161.8</gml:pos> + </gml:Point> + </d:Home> + <d:Numbers m:type="#Collection(String)" /> + <d:Emails m:type="#Collection(String)" /> + <d:City>Sydney</d:City> + <d:Birthday m:type="DateTimeOffset">1983-01-15T00:00:00Z</d:Birthday> + <d:TimeBetweenLastTwoOrders m:type="Duration">PT0.0000002S</d:TimeBetweenLastTwoOrders> + </m:properties> + </content> +</entry> diff --git a/fit/src/main/resources/V40/ProductDetails/6 1/entity.xml b/fit/src/main/resources/V40/ProductDetails/6 1/entity.xml index ae66ac858..53d00b709 100644 --- a/fit/src/main/resources/V40/ProductDetails/6 1/entity.xml +++ b/fit/src/main/resources/V40/ProductDetails/6 1/entity.xml @@ -30,6 +30,9 @@ <author> <name /> </author> + <m:action metadata="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Microsoft.Test.OData.Services.ODataWCFService.GetRelatedProduct" + title="Microsoft.Test.OData.Services.ODataWCFService.GetRelatedProduct" + target="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/ProductDetails(ProductID=6,ProductDetailID=1)/Microsoft.Test.OData.Services.ODataWCFService.GetRelatedProduct"/> <content type="application/xml"> <m:properties> <d:ProductID m:type="Int32">6</d:ProductID> diff --git a/fit/src/main/resources/V40/Products/5/entity.full.json b/fit/src/main/resources/V40/Products/5/entity.full.json new file mode 100644 index 000000000..174daaf99 --- /dev/null +++ b/fit/src/main/resources/V40/Products/5/entity.full.json @@ -0,0 +1,29 @@ +{ + "@odata.context": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Products/$entity", + "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Product", + "@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Products(5)", + "@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Products(5)", + "ProductID": 5, + "Name": "Cheetos", + "QuantityPerUnit": "100g Bag", + "UnitPrice@odata.type": "#Single", + "UnitPrice": 3.24, + "QuantityInStock": 100, + "Discontinued": true, + "UserAccess@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.AccessLevel", + "UserAccess": "None", + "SkinColor@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Color", + "SkinColor": "Red", + "CoverColors@odata.type": "#Collection(Microsoft.Test.OData.Services.ODataWCFService.Color)", + "CoverColors": ["Green", "Blue", "Blue"], + "Details@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Products(5)/Details/$ref", + "Details@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Products(5)/Details", + "#Microsoft.Test.OData.Services.ODataWCFService.AddAccessRight": { + "title": "Microsoft.Test.OData.Services.ODataWCFService.AddAccessRight", + "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Products(5)/Microsoft.Test.OData.Services.ODataWCFService.AddAccessRight" + }, + "#Microsoft.Test.OData.Services.ODataWCFService.GetProductDetails": { + "title": "Microsoft.Test.OData.Services.ODataWCFService.GetProductDetails", + "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Products(5)/Microsoft.Test.OData.Services.ODataWCFService.GetProductDetails" + } +} diff --git a/fit/src/main/resources/V40/Products/5/entity.xml b/fit/src/main/resources/V40/Products/5/entity.xml new file mode 100644 index 000000000..3f9f1bc03 --- /dev/null +++ b/fit/src/main/resources/V40/Products/5/entity.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +--> +<entry xml:base="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://docs.oasis-open.org/odata/ns/data" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" m:context="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Products/$entity"> + <id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Products(5)</id> + <category term="#Microsoft.Test.OData.Services.ODataWCFService.Product" scheme="http://docs.oasis-open.org/odata/ns/scheme" /> + <link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Products(5)" /> + <link rel="http://docs.oasis-open.org/odata/ns/related/Details" type="application/atom+xml;type=feed" title="Details" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Products(5)/Details" /> + <title /> + <updated>2014-04-23T11:54:53Z</updated> + <author> + <name /> + </author> + <m:action metadata="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Microsoft.Test.OData.Services.ODataWCFService.AddAccessRight" + title="Microsoft.Test.OData.Services.ODataWCFService.AddAccessRight" + target="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Products(5)/Microsoft.Test.OData.Services.ODataWCFService.AddAccessRight"/> + <m:action metadata="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Microsoft.Test.OData.Services.ODataWCFService.GetProductDetails" + title="Microsoft.Test.OData.Services.ODataWCFService.GetProductDetails" + target="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Products(5)/Microsoft.Test.OData.Services.ODataWCFService.GetProductDetails"/> + <content type="application/xml"> + <m:properties> + <d:ProductID m:type="Int32">5</d:ProductID> + <d:Name>Cheetos</d:Name> + <d:QuantityPerUnit>100g Bag</d:QuantityPerUnit> + <d:UnitPrice m:type="Single">3.24</d:UnitPrice> + <d:QuantityInStock m:type="Int32">100</d:QuantityInStock> + <d:Discontinued m:type="Boolean">true</d:Discontinued> + <d:UserAccess m:type="#Microsoft.Test.OData.Services.ODataWCFService.AccessLevel">None</d:UserAccess> + <d:SkinColor m:type="#Microsoft.Test.OData.Services.ODataWCFService.Color">Red</d:SkinColor> + <d:CoverColors m:type="#Collection(Microsoft.Test.OData.Services.ODataWCFService.Color)"> + <m:element>Green</m:element> + <m:element>Blue</m:element> + <m:element>Blue</m:element> + </d:CoverColors> + </m:properties> + </content> +</entry> diff --git a/fit/src/main/resources/V40/Products/6/entity.full.json b/fit/src/main/resources/V40/Products/6/entity.full.json new file mode 100644 index 000000000..f3b2c544d --- /dev/null +++ b/fit/src/main/resources/V40/Products/6/entity.full.json @@ -0,0 +1,29 @@ +{ + "@odata.context": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Products/$entity", + "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Product", + "@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Products(6)", + "@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Products(6)", + "ProductID": 6, + "Name": "Mushrooms", + "QuantityPerUnit": "Pound", + "UnitPrice@odata.type": "#Single", + "UnitPrice": 3.24, + "QuantityInStock": 100, + "Discontinued": false, + "UserAccess@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.AccessLevel", + "UserAccess": "ReadWrite", + "SkinColor@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Color", + "SkinColor": "Blue", + "CoverColors@odata.type": "#Collection(Microsoft.Test.OData.Services.ODataWCFService.Color)", + "CoverColors": ["Red", "Blue"], + "Details@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Products(6)/Details/$ref", + "Details@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Products(6)/Details", + "#Microsoft.Test.OData.Services.ODataWCFService.AddAccessRight": { + "title": "Microsoft.Test.OData.Services.ODataWCFService.AddAccessRight", + "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Products(6)/Microsoft.Test.OData.Services.ODataWCFService.AddAccessRight" + }, + "#Microsoft.Test.OData.Services.ODataWCFService.GetProductDetails": { + "title": "Microsoft.Test.OData.Services.ODataWCFService.GetProductDetails", + "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Products(6)/Microsoft.Test.OData.Services.ODataWCFService.GetProductDetails" + } +} diff --git a/fit/src/main/resources/V40/Products/6/entity.xml b/fit/src/main/resources/V40/Products/6/entity.xml new file mode 100644 index 000000000..e7bdabb88 --- /dev/null +++ b/fit/src/main/resources/V40/Products/6/entity.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +--> +<entry xml:base="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://docs.oasis-open.org/odata/ns/data" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" m:context="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Products/$entity"> + <id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Products(6)</id> + <category term="#Microsoft.Test.OData.Services.ODataWCFService.Product" scheme="http://docs.oasis-open.org/odata/ns/scheme" /> + <link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Products(6)" /> + <link rel="http://docs.oasis-open.org/odata/ns/related/Details" type="application/atom+xml;type=feed" title="Details" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Products(6)/Details" /> + <title /> + <updated>2014-04-23T11:58:19Z</updated> + <author> + <name /> + </author> + <content type="application/xml"> + <m:properties> + <d:ProductID m:type="Int32">6</d:ProductID> + <d:Name>Mushrooms</d:Name> + <d:QuantityPerUnit>Pound</d:QuantityPerUnit> + <d:UnitPrice m:type="Single">3.24</d:UnitPrice> + <d:QuantityInStock m:type="Int32">100</d:QuantityInStock> + <d:Discontinued m:type="Boolean">false</d:Discontinued> + <d:UserAccess m:type="#Microsoft.Test.OData.Services.ODataWCFService.AccessLevel">ReadWrite</d:UserAccess> + <d:SkinColor m:type="#Microsoft.Test.OData.Services.ODataWCFService.Color">Blue</d:SkinColor> + <d:CoverColors m:type="#Collection(Microsoft.Test.OData.Services.ODataWCFService.Color)"> + <m:element>Red</m:element> + <m:element>Blue</m:element> + </d:CoverColors> + </m:properties> + </content> +</entry> diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/AbstractODataInvokeRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/AbstractODataInvokeRequest.java index 6e27741c4..21669b1e0 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/AbstractODataInvokeRequest.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/AbstractODataInvokeRequest.java @@ -185,6 +185,7 @@ public abstract class AbstractODataInvokeRequest<T extends ODataInvokeResult> * Just to create response templates to be initialized from batch. */ private ODataInvokeResponseImpl() { + super(); } /** @@ -203,20 +204,16 @@ public abstract class AbstractODataInvokeRequest<T extends ODataInvokeResult> @Override public T getBody() { if (invokeResult == null) { - if (ODataNoContent.class.isAssignableFrom(reference)) { - invokeResult = reference.cast(new ODataNoContent()); - } - try { - if (CommonODataEntitySet.class.isAssignableFrom(reference)) { + if (ODataNoContent.class.isAssignableFrom(reference)) { + invokeResult = reference.cast(new ODataNoContent()); + } else if (CommonODataEntitySet.class.isAssignableFrom(reference)) { invokeResult = reference.cast(odataClient.getReader().readEntitySet(res.getEntity().getContent(), ODataPubFormat.fromString(getContentType()))); - } - if (CommonODataEntity.class.isAssignableFrom(reference)) { + } else if (CommonODataEntity.class.isAssignableFrom(reference)) { invokeResult = reference.cast(odataClient.getReader().readEntity(res.getEntity().getContent(), ODataPubFormat.fromString(getContentType()))); - } - if (CommonODataProperty.class.isAssignableFrom(reference)) { + } else if (CommonODataProperty.class.isAssignableFrom(reference)) { invokeResult = reference.cast(odataClient.getReader().readProperty(res.getEntity().getContent(), ODataFormat.fromString(getContentType()))); } diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/BoundOperationInvokeTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/BoundOperationInvokeTestITCase.java index 6bb930717..f00d14a4e 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/BoundOperationInvokeTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/BoundOperationInvokeTestITCase.java @@ -22,14 +22,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.Socket; import java.util.Collections; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; -import org.apache.commons.io.IOUtils; import org.apache.olingo.client.api.communication.request.invoke.ODataInvokeRequest; import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest; import org.apache.olingo.client.api.uri.v4.URIBuilder; @@ -50,34 +45,13 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.format.ODataPubFormat; -import org.junit.Assume; -import org.junit.BeforeClass; import org.junit.Test; public class BoundOperationInvokeTestITCase extends AbstractTestITCase { - private static final String serviceRoot = "http://odatae2etest.azurewebsites.net/javatest/DefaultService"; - - // TODO: remove once fit provides function / action imports - @BeforeClass - public static void checkServerIsOnline() throws IOException { - final Socket socket = new Socket(); - boolean reachable = false; - try { - socket.connect(new InetSocketAddress("odatae2etest.azurewebsites.net", 80), 2000); - reachable = true; - } catch (Exception e) { - LOG.warn("External test service not reachable, ignoring this whole class: {}", - OperationImportInvokeTestITCase.class.getName()); - } finally { - IOUtils.closeQuietly(socket); - } - Assume.assumeTrue(reachable); - } - private Edm getEdm() { final Edm edm = getClient().getRetrieveRequestFactory(). - getMetadataRequest(serviceRoot).execute().getBody(); + getMetadataRequest(testStaticServiceRootURL).execute().getBody(); assertNotNull(edm); return edm; @@ -89,11 +63,10 @@ public class BoundOperationInvokeTestITCase extends AbstractTestITCase { assertNotNull(container); // GetEmployeesCount - URIBuilder builder = getClient().getURIBuilder(serviceRoot).appendSingletonSegment("Company"); + URIBuilder builder = getClient().getURIBuilder(testStaticServiceRootURL).appendSingletonSegment("Company"); ODataEntityRequest<ODataEntity> entityReq = getClient().getRetrieveRequestFactory().getEntityRequest(builder.build()); - // TODO: remove when fit is used since external test server does not advertise actions in Atom - entityReq.setFormat(ODataPubFormat.JSON_FULL_METADATA); + entityReq.setFormat(format); ODataEntity entity = entityReq.execute().getBody(); assertNotNull(entity); @@ -112,10 +85,10 @@ public class BoundOperationInvokeTestITCase extends AbstractTestITCase { assertTrue(getEmployeesCountRes.hasPrimitiveValue()); // GetProductDetails - builder = getClient().getURIBuilder(serviceRoot).appendEntitySetSegment("Products").appendKeySegment(5); + builder = getClient().getURIBuilder(testStaticServiceRootURL). + appendEntitySetSegment("Products").appendKeySegment(5); entityReq = getClient().getRetrieveRequestFactory().getEntityRequest(builder.build()); - // TODO: remove when fit is used since external test server does not advertise actions in Atom - entityReq.setFormat(ODataPubFormat.JSON_FULL_METADATA); + entityReq.setFormat(format); entity = entityReq.execute().getBody(); assertNotNull(entity); @@ -135,14 +108,13 @@ public class BoundOperationInvokeTestITCase extends AbstractTestITCase { assertEquals(1, getProductDetailsRes.getCount()); // GetRelatedProduct - final Map<String, Object> keyMap = new HashMap<String, Object>(); + final Map<String, Object> keyMap = new LinkedHashMap<String, Object>(); keyMap.put("ProductID", 6); keyMap.put("ProductDetailID", 1); - builder = getClient().getURIBuilder(serviceRoot).appendEntitySetSegment("ProductDetails"). - appendKeySegment(keyMap); + builder = getClient().getURIBuilder(testStaticServiceRootURL). + appendEntitySetSegment("ProductDetails").appendKeySegment(keyMap); entityReq = getClient().getRetrieveRequestFactory().getEntityRequest(builder.build()); - // TODO: remove when fit is used since external test server does not advertise actions in Atom - entityReq.setFormat(ODataPubFormat.JSON_FULL_METADATA); + entityReq.setFormat(format); entity = entityReq.execute().getBody(); assertNotNull(entity); @@ -155,22 +127,17 @@ public class BoundOperationInvokeTestITCase extends AbstractTestITCase { final ODataInvokeRequest<ODataEntity> getRelatedProductReq = getClient().getInvokeRequestFactory().getInvokeRequest(boundOp.getTarget(), func); getRelatedProductReq.setFormat(format); - //TODO test service returns error instead of Products(6) - try { - final ODataEntity getRelatedProductRes = getRelatedProductReq.execute().getBody(); - assertNotNull(getRelatedProductRes); - assertEquals("Microsoft.Test.OData.Services.ODataWCFService.Product", - getRelatedProductRes.getTypeName().toString()); - assertEquals(6, getRelatedProductRes.getProperty("ProductID").getPrimitiveValue().toCastValue(Integer.class), 0); - } catch (Exception e) { - // ignore - } + final ODataEntity getRelatedProductRes = getRelatedProductReq.execute().getBody(); + assertNotNull(getRelatedProductRes); + assertEquals("Microsoft.Test.OData.Services.ODataWCFService.Product", + getRelatedProductRes.getTypeName().toString()); + assertEquals(6, getRelatedProductRes.getProperty("ProductID").getPrimitiveValue().toCastValue(Integer.class), 0); // GetDefaultPI - builder = getClient().getURIBuilder(serviceRoot).appendEntitySetSegment("Accounts").appendKeySegment(101); + builder = getClient().getURIBuilder(testStaticServiceRootURL). + appendEntitySetSegment("Accounts").appendKeySegment(101); entityReq = getClient().getRetrieveRequestFactory().getEntityRequest(builder.build()); - // TODO: remove when fit is used since external test server does not advertise actions in Atom - entityReq.setFormat(ODataPubFormat.JSON_FULL_METADATA); + entityReq.setFormat(format); entity = entityReq.execute().getBody(); assertNotNull(entity); @@ -209,8 +176,7 @@ public class BoundOperationInvokeTestITCase extends AbstractTestITCase { // GetActualAmount entityReq = getClient().getRetrieveRequestFactory().getEntityRequest( entity.getNavigationLink("MyGiftCard").getLink()); - // TODO: remove when fit is used since external test server does not advertise actions in Atom - entityReq.setFormat(ODataPubFormat.JSON_FULL_METADATA); + entityReq.setFormat(format); entity = entityReq.execute().getBody(); assertNotNull(entity); assertEquals(301, entity.getProperty("GiftCardID").getPrimitiveValue().toCastValue(Integer.class), 0); @@ -247,11 +213,10 @@ public class BoundOperationInvokeTestITCase extends AbstractTestITCase { assertNotNull(container); // IncreaseRevenue - URIBuilder builder = getClient().getURIBuilder(serviceRoot).appendSingletonSegment("Company"); + URIBuilder builder = getClient().getURIBuilder(testStaticServiceRootURL).appendSingletonSegment("Company"); ODataEntityRequest<ODataEntity> entityReq = getClient().getRetrieveRequestFactory().getEntityRequest(builder.build()); - // TODO: remove when fit is used since external test server does not advertise actions in Atom - entityReq.setFormat(ODataPubFormat.JSON_FULL_METADATA); + entityReq.setFormat(format); ODataEntity entity = entityReq.execute().getBody(); assertNotNull(entity); @@ -272,10 +237,10 @@ public class BoundOperationInvokeTestITCase extends AbstractTestITCase { assertTrue(increaseRevenueRes.hasPrimitiveValue()); // AddAccessRight - builder = getClient().getURIBuilder(serviceRoot).appendEntitySetSegment("Products").appendKeySegment(5); + builder = getClient().getURIBuilder(testStaticServiceRootURL). + appendEntitySetSegment("Products").appendKeySegment(5); entityReq = getClient().getRetrieveRequestFactory().getEntityRequest(builder.build()); - // TODO: remove when fit is used since external test server does not advertise actions in Atom - entityReq.setFormat(ODataPubFormat.JSON_FULL_METADATA); + entityReq.setFormat(format); entity = entityReq.execute().getBody(); assertNotNull(entity); @@ -296,10 +261,10 @@ public class BoundOperationInvokeTestITCase extends AbstractTestITCase { assertTrue(getProductDetailsRes.hasEnumValue()); // ResetAddress - builder = getClient().getURIBuilder(serviceRoot).appendEntitySetSegment("Customers").appendKeySegment(2); + builder = getClient().getURIBuilder(testStaticServiceRootURL). + appendEntitySetSegment("Customers").appendKeySegment(2); entityReq = getClient().getRetrieveRequestFactory().getEntityRequest(builder.build()); - // TODO: remove when fit is used since external test server does not advertise actions in Atom - entityReq.setFormat(ODataPubFormat.JSON_FULL_METADATA); + entityReq.setFormat(format); entity = entityReq.execute().getBody(); assertNotNull(entity); @@ -334,10 +299,10 @@ public class BoundOperationInvokeTestITCase extends AbstractTestITCase { assertEquals(2, resetAddressRes.getProperty("PersonID").getPrimitiveValue().toCastValue(Integer.class), 0); // RefreshDefaultPI - builder = getClient().getURIBuilder(serviceRoot).appendEntitySetSegment("Accounts").appendKeySegment(101); + builder = getClient().getURIBuilder(testStaticServiceRootURL). + appendEntitySetSegment("Accounts").appendKeySegment(101); entityReq = getClient().getRetrieveRequestFactory().getEntityRequest(builder.build()); - // TODO: remove when fit is used since external test server does not advertise actions in Atom - entityReq.setFormat(ODataPubFormat.JSON_FULL_METADATA); + entityReq.setFormat(format); entity = entityReq.execute().getBody(); assertNotNull(entity); @@ -363,12 +328,7 @@ public class BoundOperationInvokeTestITCase extends AbstractTestITCase { @Test public void atomActions() throws EdmPrimitiveTypeException { - //TODO test service doesn't support yet Atom POST params - try { - actions(ODataPubFormat.ATOM); - } catch (Exception e) { - // ignore - } + actions(ODataPubFormat.ATOM); } @Test diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/OperationImportInvokeTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/OperationImportInvokeTestITCase.java index bfc5718d8..96ec485ed 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/OperationImportInvokeTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/OperationImportInvokeTestITCase.java @@ -40,7 +40,6 @@ import org.apache.olingo.commons.api.edm.EdmActionImport; import org.apache.olingo.commons.api.edm.EdmEntityContainer; import org.apache.olingo.commons.api.edm.EdmFunctionImport; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; -import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.format.ODataPubFormat; import org.junit.Test; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomSerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomSerializer.java index b3777fd49..6b8746985 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomSerializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomSerializer.java @@ -34,6 +34,7 @@ import org.apache.olingo.commons.api.data.Feed; import org.apache.olingo.commons.api.data.Link; import org.apache.olingo.commons.api.data.Property; import org.apache.olingo.commons.api.data.Value; +import org.apache.olingo.commons.api.domain.ODataOperation; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.commons.api.format.ContentType; @@ -214,7 +215,6 @@ public class AtomSerializer extends AbstractAtomDealer { writer.writeAttribute(XMLConstants.XML_NS_URI, Constants.ATTR_XML_BASE, entry.getBaseURI().toASCIIString()); } - // server mode only if (serverMode && StringUtils.isNotBlank(entry.getETag())) { writer.writeAttribute( version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), @@ -239,7 +239,6 @@ public class AtomSerializer extends AbstractAtomDealer { common(writer, (AbstractODataObject) entry); } - // server mode only if (serverMode) { if (entry.getEditLink() != null) { links(writer, Collections.singletonList(entry.getEditLink())); @@ -254,6 +253,17 @@ public class AtomSerializer extends AbstractAtomDealer { links(writer, entry.getNavigationLinks()); links(writer, entry.getMediaEditLinks()); + if (serverMode) { + for (ODataOperation operation : entry.getOperations()) { + writer.writeStartElement( + version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ATOM_ELEM_ACTION); + writer.writeAttribute(Constants.ATTR_METADATA, operation.getMetadataAnchor()); + writer.writeAttribute(Constants.ATTR_TITLE, operation.getTitle()); + writer.writeAttribute(Constants.ATTR_TARGET, operation.getTarget().toASCIIString()); + writer.writeEndElement(); + } + } + writer.writeStartElement(Constants.ATOM_ELEM_CONTENT); if (entry.isMediaEntry()) { if (StringUtils.isNotBlank(entry.getMediaContentType())) { diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONEntrySerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONEntrySerializer.java index db4ab7c73..b7dcf8d7d 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONEntrySerializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONEntrySerializer.java @@ -29,6 +29,7 @@ import org.apache.olingo.commons.api.data.Container; import org.apache.olingo.commons.api.data.Entry; import org.apache.olingo.commons.api.data.Link; import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.domain.ODataOperation; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.commons.core.edm.EdmTypeInfo; @@ -107,6 +108,15 @@ public class JSONEntrySerializer extends AbstractJsonSerializer<JSONEntryImpl> { } } + if (serverMode) { + for (ODataOperation operation : entry.getOperations()) { + jgen.writeObjectFieldStart("#" + StringUtils.substringAfterLast(operation.getMetadataAnchor(), "#")); + jgen.writeStringField(Constants.ATTR_TITLE, operation.getTitle()); + jgen.writeStringField(Constants.ATTR_TARGET, operation.getTarget().toASCIIString()); + jgen.writeEndObject(); + } + } + jgen.writeEndObject(); } }