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 9777381ad..a3a414d87 100644 --- a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java +++ b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java @@ -67,7 +67,7 @@ import org.apache.cxf.jaxrs.client.WebClient; import org.apache.cxf.jaxrs.ext.multipart.Attachment; import org.apache.cxf.jaxrs.ext.multipart.Multipart; import org.apache.cxf.jaxrs.ext.multipart.MultipartBody; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.Entry; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.format.ContentType; @@ -92,9 +92,9 @@ import org.apache.olingo.fit.serializer.FITAtomDeserializer; import org.apache.olingo.fit.utils.Accept; import org.apache.olingo.fit.utils.FSManager; import org.apache.olingo.fit.utils.Commons; -import org.apache.olingo.fit.utils.AbstractJSONUtilities; +import org.apache.olingo.fit.utils.JSONUtilities; import org.apache.olingo.fit.utils.AbstractUtilities; -import org.apache.olingo.fit.utils.AbstractXMLUtilities; +import org.apache.olingo.fit.utils.XMLUtilities; import org.apache.olingo.fit.utils.LinkInfo; import org.apache.olingo.fit.metadata.Metadata; import org.apache.olingo.fit.serializer.JSONFeedContainer; @@ -128,9 +128,9 @@ public abstract class AbstractServices { protected final DataBinder dataBinder; - protected final AbstractXMLUtilities xml; + protected final XMLUtilities xml; - protected final AbstractJSONUtilities json; + protected final JSONUtilities json; protected Metadata metadata; @@ -141,13 +141,8 @@ public abstract class AbstractServices { this.mapper = Commons.getJSONMapper(version); this.dataBinder = new DataBinder(version); - if (version.compareTo(ODataServiceVersion.V30) <= 0) { - this.xml = new org.apache.olingo.fit.utils.v3.XMLUtilities(); - this.json = new org.apache.olingo.fit.utils.v3.JSONUtilities(); - } else { - this.xml = new org.apache.olingo.fit.utils.v4.XMLUtilities(); - this.json = new org.apache.olingo.fit.utils.v4.JSONUtilities(); - } + this.xml = new XMLUtilities(version); + this.json = new JSONUtilities(version); } protected Metadata getMetadataObj() { @@ -397,8 +392,6 @@ public abstract class AbstractServices { throw new UnsupportedMediaTypeException("Unsupported media type"); } - final AbstractUtilities util = acceptType == Accept.ATOM ? xml : json; - final Map.Entry entityInfo = xml.readEntity(entitySetName, entityId, Accept.ATOM); final String etag = Commons.getETag(entityInfo.getKey(), version); @@ -414,23 +407,23 @@ public abstract class AbstractServices { throw new UnsupportedMediaTypeException("Unsupported media type"); } else if (contentTypeValue == Accept.ATOM) { entryChanges = atomDeserializer.read( - IOUtils.toInputStream(changes, Constants.ENCODING), AtomEntryImpl.class).getObject(); + IOUtils.toInputStream(changes, Constants.ENCODING), AtomEntryImpl.class).getPayload(); } else { - final Container jcont = mapper.readValue(IOUtils.toInputStream(changes, Constants.ENCODING), + final ResWrap jcont = mapper.readValue(IOUtils.toInputStream(changes, Constants.ENCODING), new TypeReference() { - }); + }); - entryChanges = dataBinder.toAtomEntry(jcont.getObject()); + entryChanges = dataBinder.toAtomEntry(jcont.getPayload()); } - final Container container = atomDeserializer.read(entityInfo.getValue(), AtomEntryImpl.class); + final ResWrap container = atomDeserializer.read(entityInfo.getValue(), AtomEntryImpl.class); for (Property property : entryChanges.getProperties()) { - container.getObject().getProperty(property.getName()).setValue(property.getValue()); + container.getPayload().getProperty(property.getName()).setValue(property.getValue()); } for (Link link : entryChanges.getNavigationLinks()) { - container.getObject().getNavigationLinks().add(link); + container.getPayload().getNavigationLinks().add(link); } final ByteArrayOutputStream content = new ByteArrayOutputStream(); @@ -440,11 +433,11 @@ public abstract class AbstractServices { writer.close(); final InputStream res = xml.addOrReplaceEntity( - entityId, entitySetName, new ByteArrayInputStream(content.toByteArray()), container.getObject()); + entityId, entitySetName, new ByteArrayInputStream(content.toByteArray()), container.getPayload()); - final Container cres = atomDeserializer.read(res, AtomEntryImpl.class); + final ResWrap cres = atomDeserializer.read(res, AtomEntryImpl.class); - normalizeAtomEntry(cres.getObject(), entitySetName, entityId); + normalizeAtomEntry(cres.getPayload(), entitySetName, entityId); final String path = Commons.getEntityBasePath(entitySetName, entityId); FSManager.instance(version).putInMemory( @@ -454,7 +447,7 @@ public abstract class AbstractServices { if ("return-content".equalsIgnoreCase(prefer)) { response = xml.createResponse( uriInfo.getRequestUri().toASCIIString(), - util.readEntity(entitySetName, entityId, acceptType).getValue(), + xml.readEntity(entitySetName, entityId, acceptType).getValue(), null, acceptType, Response.Status.OK); } else { res.close(); @@ -487,6 +480,7 @@ public abstract class AbstractServices { @PathParam("entitySetName") String entitySetName, @PathParam("entityId") String entityId, final String entity) { + try { final Accept acceptType = Accept.parse(accept, version); @@ -494,23 +488,18 @@ public abstract class AbstractServices { throw new UnsupportedMediaTypeException("Unsupported media type"); } - InputStream res; - if (acceptType == Accept.ATOM) { - res = xml.addOrReplaceEntity(entityId, entitySetName, IOUtils.toInputStream(entity, Constants.ENCODING), - getUtilities(acceptType).readEntry(acceptType, IOUtils.toInputStream(entity, Constants.ENCODING))); - } else { - res = json.addOrReplaceEntity(entityId, entitySetName, IOUtils.toInputStream(entity, Constants.ENCODING), - getUtilities(acceptType).readEntry(acceptType, IOUtils.toInputStream(entity, Constants.ENCODING))); - } + final InputStream res = getUtilities(acceptType).addOrReplaceEntity(entityId, entitySetName, + IOUtils.toInputStream(entity, Constants.ENCODING), + xml.readEntry(acceptType, IOUtils.toInputStream(entity, Constants.ENCODING))); - final Container cres; + final ResWrap cres; if (acceptType == Accept.ATOM) { cres = atomDeserializer.read(res, AtomEntryImpl.class); } else { - final Container jcont = mapper.readValue(res, new TypeReference() { + final ResWrap jcont = mapper.readValue(res, new TypeReference() { }); - cres = new Container(jcont.getContextURL(), jcont.getMetadataETag(), - dataBinder.toAtomEntry(jcont.getObject())); + cres = new ResWrap(jcont.getContextURL(), jcont.getMetadataETag(), + dataBinder.toAtomEntry(jcont.getPayload())); } final String path = Commons.getEntityBasePath(entitySetName, entityId); @@ -521,7 +510,7 @@ public abstract class AbstractServices { if ("return-content".equalsIgnoreCase(prefer)) { response = xml.createResponse( uriInfo.getRequestUri().toASCIIString(), - getUtilities(acceptType).readEntity(entitySetName, entityId, acceptType).getValue(), + xml.readEntity(entitySetName, entityId, acceptType).getValue(), null, acceptType, Response.Status.OK); @@ -556,31 +545,27 @@ public abstract class AbstractServices { @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) String prefer, @PathParam("entitySetName") String entitySetName, final String entity) { - // default - AbstractUtilities utils = xml; + try { final Accept acceptType = Accept.parse(accept, version); if (acceptType == Accept.XML || acceptType == Accept.TEXT) { throw new UnsupportedMediaTypeException("Unsupported media type"); } - utils = getUtilities(acceptType); - - final Container container; + final ResWrap container; final EntitySet entitySet = getMetadataObj().getEntitySet(entitySetName); + final AtomEntryImpl entry; - final String entityKey; - - if (utils.isMediaContent(entitySetName)) { + if (xml.isMediaContent(entitySetName)) { entry = new AtomEntryImpl(); entry.setMediaContentType(ContentType.WILDCARD); entry.setType(entitySet.getType()); entityKey = xml.getDefaultEntryKey(entitySetName, entry); - utils.addMediaEntityValue(entitySetName, entityKey, IOUtils.toInputStream(entity, Constants.ENCODING)); + xml.addMediaEntityValue(entitySetName, entityKey, IOUtils.toInputStream(entity, Constants.ENCODING)); final String id = Commons.getMediaContent().get(entitySetName); if (StringUtils.isNotBlank(id)) { @@ -599,27 +584,27 @@ public abstract class AbstractServices { entry.setMediaContentSource(editLink.getHref() + "/$value"); - container = new Container(null, null, entry); + container = new ResWrap((URI) null, null, entry); } else { final Accept contentTypeValue = Accept.parse(contentType, version); if (Accept.ATOM == contentTypeValue) { container = atomDeserializer.read(IOUtils.toInputStream(entity, Constants.ENCODING), AtomEntryImpl.class); - entry = container.getObject(); + entry = container.getPayload(); } else { - final Container jcontainer = + final ResWrap jcontainer = mapper.readValue(IOUtils.toInputStream(entity, Constants.ENCODING), - new TypeReference() { - }); + new TypeReference() { + }); - entry = dataBinder.toAtomEntry(jcontainer.getObject()); + entry = dataBinder.toAtomEntry(jcontainer.getPayload()); - container = new Container( + container = new ResWrap( jcontainer.getContextURL(), jcontainer.getMetadataETag(), entry); } - entityKey = getUtilities(contentTypeValue).getDefaultEntryKey(entitySetName, entry); + entityKey = xml.getDefaultEntryKey(entitySetName, entry); } normalizeAtomEntry(entry, entitySetName, entityKey); @@ -633,10 +618,11 @@ public abstract class AbstractServices { final InputStream serialization = xml.addOrReplaceEntity(null, entitySetName, new ByteArrayInputStream(content.toByteArray()), entry); - Container result = atomDeserializer.read(serialization, AtomEntryImpl.class); - result = new Container( - URI.create(Constants.get(version, ConstantKey.DEFAULT_SERVICE_URL) - + "$metadata#" + entitySetName + "/$entity"), null, result.getObject()); + ResWrap result = atomDeserializer.read(serialization, AtomEntryImpl.class); + result = new ResWrap( + URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX) + + entitySetName + Constants.get(version, ConstantKey.ODATA_METADATA_ENTITY_SUFFIX)), + null, result.getPayload()); final String path = Commons.getEntityBasePath(entitySetName, entityKey); FSManager.instance(version).putInMemory( @@ -646,16 +632,16 @@ public abstract class AbstractServices { final Response response; if ("return-no-content".equalsIgnoreCase(prefer)) { - response = utils.createResponse( + response = xml.createResponse( location, null, null, acceptType, Response.Status.NO_CONTENT); } else { - response = utils.createResponse( + response = xml.createResponse( location, - utils.writeEntry(acceptType, result), + xml.writeEntry(acceptType, result), null, acceptType, Response.Status.CREATED); @@ -668,7 +654,7 @@ public abstract class AbstractServices { return response; } catch (Exception e) { LOG.error("While creating new entity", e); - return utils.createFaultResponse(accept, e); + return xml.createFaultResponse(accept, e); } } @@ -698,13 +684,13 @@ public abstract class AbstractServices { replaceAll("\"Salary\":[0-9]*,", "\"Salary\":0,"). replaceAll("\"Title\":\".*\"", "\"Title\":\"[Sacked]\""). replaceAll("\\.*\\", - "0"). + "0"). replaceAll("\\.*\\", "[Sacked]"); final FSManager fsManager = FSManager.instance(version); fsManager.putInMemory(IOUtils.toInputStream(newContent, Constants.ENCODING), fsManager.getAbsolutePath(Commons.getEntityBasePath("Person", entityId) + Constants.get(version, - ConstantKey.ENTITY), utils.getKey())); + ConstantKey.ENTITY), utils.getKey())); return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT); } catch (Exception e) { @@ -756,9 +742,9 @@ public abstract class AbstractServices { final Long newSalary = Long.valueOf(salaryMatcher.group(1)) + n; newContent = newContent. replaceAll("\"Salary\":" + salaryMatcher.group(1) + ",", - "\"Salary\":" + newSalary + ","). + "\"Salary\":" + newSalary + ","). replaceAll("\\" + salaryMatcher.group(1) + "", - "" + newSalary + ""); + "" + newSalary + ""); } FSManager.instance(version).putInMemory(IOUtils.toInputStream(newContent, Constants.ENCODING), @@ -876,9 +862,9 @@ public abstract class AbstractServices { final InputStream feed = FSManager.instance(version).readFile(builder.toString(), Accept.ATOM); - final Container container = atomDeserializer.read(feed, AtomFeedImpl.class); + final ResWrap container = atomDeserializer.read(feed, AtomFeedImpl.class); - setInlineCount(container.getObject(), count); + setInlineCount(container.getPayload(), count); final ByteArrayOutputStream content = new ByteArrayOutputStream(); final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING); @@ -886,7 +872,7 @@ public abstract class AbstractServices { // ----------------------------------------------- // Evaluate $skip and $top // ----------------------------------------------- - List entries = new ArrayList(container.getObject().getEntries()); + List entries = new ArrayList(container.getPayload().getEntries()); if (StringUtils.isNotBlank(skip)) { entries = entries.subList(Integer.valueOf(skip), entries.size()); @@ -896,8 +882,8 @@ public abstract class AbstractServices { entries = entries.subList(0, Integer.valueOf(top)); } - container.getObject().getEntries().clear(); - container.getObject().getEntries().addAll(entries); + container.getPayload().getEntries().clear(); + container.getPayload().getEntries().addAll(entries); // ----------------------------------------------- if (acceptType == Accept.ATOM) { @@ -907,7 +893,7 @@ public abstract class AbstractServices { } else { mapper.writeValue( writer, new JSONFeedContainer(container.getContextURL(), container.getMetadataETag(), - dataBinder.toJSONFeed(container.getObject()))); + dataBinder.toJSONFeed(container.getPayload()))); } return xml.createResponse( @@ -1014,13 +1000,13 @@ public abstract class AbstractServices { final InputStream entity = entityInfo.getValue(); - Container container = atomDeserializer.read(entity, AtomEntryImpl.class); + ResWrap container = atomDeserializer.read(entity, AtomEntryImpl.class); if (container.getContextURL() == null) { - container = new Container(URI.create(Constants.get(version, ConstantKey.DEFAULT_SERVICE_URL) - + "$metadata#" + entitySetName + "/$entity"), - container.getMetadataETag(), container.getObject()); + container = new ResWrap(URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX) + + entitySetName + Constants.get(version, ConstantKey.ODATA_METADATA_ENTITY_SUFFIX)), + container.getMetadataETag(), container.getPayload()); } - final Entry entry = container.getObject(); + final Entry entry = container.getPayload(); if (keyAsSegment) { final Link editLink = new LinkImpl(); @@ -1071,13 +1057,13 @@ public abstract class AbstractServices { // inline entry final Entry inline = atomDeserializer.read( xml.expandEntity(entitySetName, entityId, link.getTitle()), - AtomEntryImpl.class).getObject(); + AtomEntryImpl.class).getPayload(); rep.setInlineEntry(inline); } else if (link.getType().equals(Constants.get(version, ConstantKey.ATOM_LINK_FEED))) { // inline feed final Feed inline = atomDeserializer.read( xml.expandEntity(entitySetName, entityId, link.getTitle()), - AtomFeedImpl.class).getObject(); + AtomFeedImpl.class).getPayload(); rep.setInlineFeed(inline); } replace.put(link, rep); @@ -1147,6 +1133,7 @@ public abstract class AbstractServices { } private Response replaceProperty( + final String location, final String accept, final String prefer, final String entitySetName, @@ -1155,6 +1142,7 @@ public abstract class AbstractServices { final String format, final String changes, final boolean justValue) { + try { Accept acceptType = null; if (StringUtils.isNotBlank(format)) { @@ -1168,7 +1156,7 @@ public abstract class AbstractServices { final AbstractUtilities utils = getUtilities(acceptType); - final InputStream changed = utils.replaceProperty( + utils.replaceProperty( entitySetName, entityId, IOUtils.toInputStream(changes, Constants.ENCODING), @@ -1178,9 +1166,8 @@ public abstract class AbstractServices { final Response response; if ("return-content".equalsIgnoreCase(prefer)) { - response = xml.createResponse(null, changed, null, acceptType, Response.Status.OK); + response = getEntityInternal(location, accept, entitySetName, entityId, format, null, null, false); } else { - changed.close(); response = xml.createResponse(null, null, null, acceptType, Response.Status.NO_CONTENT); } @@ -1189,7 +1176,6 @@ public abstract class AbstractServices { } return response; - } catch (Exception e) { return xml.createFaultResponse(accept, e); } @@ -1254,6 +1240,7 @@ public abstract class AbstractServices { @PUT @Path("/{entitySetName}({entityId})/{path:.*}/$value") public Response replacePropertyValue( + @Context UriInfo uriInfo, @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) String prefer, @PathParam("entitySetName") String entitySetName, @@ -1261,7 +1248,9 @@ public abstract class AbstractServices { @PathParam("path") String path, @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format, final String changes) { - return replaceProperty(accept, prefer, entitySetName, entityId, path, format, changes, true); + + return replaceProperty(uriInfo.getRequestUri().toASCIIString(), + accept, prefer, entitySetName, entityId, path, format, changes, true); } /** @@ -1278,6 +1267,7 @@ public abstract class AbstractServices { @MERGE @Path("/{entitySetName}({entityId})/{path:.*}") public Response mergeProperty( + @Context UriInfo uriInfo, @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) String prefer, @PathParam("entitySetName") String entitySetName, @@ -1285,7 +1275,9 @@ public abstract class AbstractServices { @PathParam("path") String path, @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format, final String changes) { - return replaceProperty(accept, prefer, entitySetName, entityId, path, format, changes, false); + + return replaceProperty(uriInfo.getRequestUri().toASCIIString(), + accept, prefer, entitySetName, entityId, path, format, changes, false); } /** @@ -1302,6 +1294,7 @@ public abstract class AbstractServices { @PATCH @Path("/{entitySetName}({entityId})/{path:.*}") public Response patchProperty( + @Context UriInfo uriInfo, @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) String prefer, @PathParam("entitySetName") String entitySetName, @@ -1309,7 +1302,9 @@ public abstract class AbstractServices { @PathParam("path") String path, @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format, final String changes) { - return replaceProperty(accept, prefer, entitySetName, entityId, path, format, changes, false); + + return replaceProperty(uriInfo.getRequestUri().toASCIIString(), + accept, prefer, entitySetName, entityId, path, format, changes, false); } @PUT @@ -1366,6 +1361,7 @@ public abstract class AbstractServices { @PUT @Path("/{entitySetName}({entityId})/{path:.*}") public Response replaceProperty( + @Context UriInfo uriInfo, @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) String prefer, @PathParam("entitySetName") String entitySetName, @@ -1373,10 +1369,12 @@ public abstract class AbstractServices { @PathParam("path") String path, @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format, final String changes) { + if (xml.isMediaContent(entitySetName + "/" + path)) { return replaceMediaProperty(prefer, entitySetName, entityId, path, changes); } else { - return replaceProperty(accept, prefer, entitySetName, entityId, path, format, changes, false); + return replaceProperty(uriInfo.getRequestUri().toASCIIString(), + accept, prefer, entitySetName, entityId, path, format, changes, false); } } @@ -1386,6 +1384,7 @@ public abstract class AbstractServices { final String entityId, final String path, final String value) { + try { final AbstractUtilities utils = getUtilities(null); @@ -1405,7 +1404,6 @@ public abstract class AbstractServices { } return response; - } catch (Exception e) { LOG.error("Error retrieving entity", e); return xml.createFaultResponse(Accept.JSON.toString(version), e); @@ -1454,7 +1452,6 @@ public abstract class AbstractServices { @PathParam("path") String path, @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format) { - AbstractUtilities utils = null; try { Accept acceptType = null; if (StringUtils.isNotBlank(format)) { @@ -1462,12 +1459,10 @@ public abstract class AbstractServices { } else if (StringUtils.isNotBlank(accept)) { acceptType = Accept.parse(accept, version, null); } - utils = getUtilities(acceptType); return navigateProperty(acceptType, entitySetName, entityId, path, true); - } catch (Exception e) { - return (utils == null ? xml : utils).createFaultResponse(accept, e); + return xml.createFaultResponse(accept, e); } } @@ -1513,7 +1508,7 @@ public abstract class AbstractServices { final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING); if (linkInfo.isFeed()) { - final Container container = atomDeserializer.read(stream, AtomFeedImpl.class); + final ResWrap container = atomDeserializer.read(stream, AtomFeedImpl.class); if (acceptType == Accept.ATOM) { atomSerializer.write(writer, container); @@ -1523,11 +1518,11 @@ public abstract class AbstractServices { mapper.writeValue( writer, new JSONFeedContainer(container.getContextURL(), - container.getMetadataETag(), - dataBinder.toJSONFeed((AtomFeedImpl) container.getObject()))); + container.getMetadataETag(), + dataBinder.toJSONFeed((AtomFeedImpl) container.getPayload()))); } } else { - final Container container = atomDeserializer.read(stream, AtomEntryImpl.class); + final ResWrap container = atomDeserializer.read(stream, AtomEntryImpl.class); if (acceptType == Accept.ATOM) { atomSerializer.write(writer, container); writer.flush(); @@ -1536,8 +1531,8 @@ public abstract class AbstractServices { mapper.writeValue( writer, new JSONEntryContainer(container.getContextURL(), - container.getMetadataETag(), - dataBinder.toJSONEntry((AtomEntryImpl) container.getObject()))); + container.getMetadataETag(), + dataBinder.toJSONEntry((AtomEntryImpl) container.getPayload()))); } } @@ -1580,26 +1575,49 @@ public abstract class AbstractServices { throw new UnsupportedMediaTypeException("Unsupported media type " + acceptType); } - final String basePath = Commons.getEntityBasePath(entitySetName, entityId); - final AbstractUtilities utils = getUtilities(acceptType); - final List pathElements = Arrays.asList(path.split("\\/")); + final Map.Entry entityInfo = utils.readEntity(entitySetName, entityId, Accept.ATOM); - InputStream stream; + final InputStream entity = entityInfo.getValue(); - if (searchForValue) { - stream = FSManager.instance(version).readFile( - basePath + Constants.get(version, ConstantKey.ENTITY), - acceptType == null || acceptType == Accept.TEXT ? Accept.XML : acceptType); + final ResWrap entryContainer = atomDeserializer.read(entity, AtomEntryImpl.class); - stream = utils.getPropertyValue(stream, pathElements); - } else { - final String edmType = xml.getEdmTypeFromAtom(entitySetName, entityId, pathElements); - stream = utils.getProperty(entitySetName, entityId, pathElements, edmType); + final String[] pathElems = StringUtils.split(path, "/"); + AtomPropertyImpl property = (AtomPropertyImpl) entryContainer.getPayload().getProperty(pathElems[0]); + if (pathElems.length > 1 && property.getValue().isComplex()) { + for (Property sub : property.getValue().asComplex().get()) { + if (pathElems[1].equals(sub.getName())) { + property = (AtomPropertyImpl) sub; + if (pathElems.length > 2 && property.getValue().isComplex()) { + for (Property subsub : property.getValue().asComplex().get()) { + if (pathElems[2].equals(subsub.getName())) { + property = (AtomPropertyImpl) subsub; + } + } + } + } + } } - return xml.createResponse(null, stream, Commons.getETag(basePath, version), acceptType); + final ResWrap container = new ResWrap( + URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX) + + (version.compareTo(ODataServiceVersion.V40) >= 0 + ? entitySetName + "(" + entityId + ")/" + path + : property.getType())), + entryContainer.getMetadataETag(), + property); + + return xml.createResponse( + null, + searchForValue + ? IOUtils.toInputStream( + container.getPayload().getValue() == null || container.getPayload().getValue().isNull() + ? StringUtils.EMPTY + : container.getPayload().getValue().asPrimitive().get(), Constants.ENCODING) + : utils.writeProperty(acceptType, container), + Commons.getETag(Commons.getEntityBasePath(entitySetName, entityId), version), + acceptType); } /** 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 fde79c2b9..25eac8948 100644 --- a/fit/src/main/java/org/apache/olingo/fit/V4Services.java +++ b/fit/src/main/java/org/apache/olingo/fit/V4Services.java @@ -52,7 +52,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.cxf.interceptor.InInterceptors; import org.apache.cxf.jaxrs.ext.multipart.Attachment; import org.apache.olingo.commons.api.data.CollectionValue; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.Entry; import org.apache.olingo.commons.api.data.Feed; import org.apache.olingo.commons.api.data.Property; @@ -310,7 +310,7 @@ public class V4Services extends AbstractServices { final AtomPropertyImpl property = new AtomPropertyImpl(); property.setType("Edm.Int32"); property.setValue(new PrimitiveValueImpl("2")); - final Container container = new Container( + final ResWrap container = new ResWrap( URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX) + property.getType()), null, property); @@ -384,7 +384,7 @@ public class V4Services extends AbstractServices { final AtomFeedImpl feed = new AtomFeedImpl(); feed.getEntries().add(entry); - final Container container = new Container( + final ResWrap container = new ResWrap( URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX) + "ProductDetail"), null, feed); @@ -530,7 +530,7 @@ public class V4Services extends AbstractServices { property.setType("Edm.Double"); property.setValue(new PrimitiveValueImpl("41.79")); - final Container container = new Container(null, null, property); + final ResWrap container = new ResWrap((URI) null, null, property); return xml.createResponse( null, @@ -568,7 +568,7 @@ public class V4Services extends AbstractServices { return utils.getValue().createResponse( FSManager.instance(version).readFile(Constants.get(version, ConstantKey.REF) - + File.separatorChar + filename, utils.getKey()), + + File.separatorChar + filename, utils.getKey()), null, utils.getKey()); } catch (Exception e) { @@ -590,7 +590,7 @@ public class V4Services extends AbstractServices { final Response response = getEntityInternal(uriInfo.getRequestUri().toASCIIString(), - accept, entitySetName, entityId, accept, StringUtils.EMPTY, StringUtils.EMPTY, false); + accept, entitySetName, entityId, accept, StringUtils.EMPTY, StringUtils.EMPTY, false); return response.getStatus() >= 400 ? postNewEntity(uriInfo, accept, contentType, prefer, entitySetName, changes) : super.patchEntity(uriInfo, accept, contentType, prefer, ifMatch, entitySetName, entityId, changes); @@ -648,7 +648,7 @@ public class V4Services extends AbstractServices { } final InputStream entry = FSManager.instance(version).readFile(containedPath.toString(), Accept.ATOM); - final Container container = atomDeserializer.read(entry, AtomEntryImpl.class); + final ResWrap container = atomDeserializer.read(entry, AtomEntryImpl.class); return xml.createResponse( null, @@ -679,21 +679,21 @@ public class V4Services extends AbstractServices { final AbstractUtilities utils = getUtilities(acceptType); // 1. parse the entry (from Atom or JSON) into AtomEntryImpl - final Container entryContainer; + final ResWrap entryContainer; final AtomEntryImpl entry; final Accept contentTypeValue = Accept.parse(contentType, version); if (Accept.ATOM == contentTypeValue) { entryContainer = atomDeserializer.read(IOUtils.toInputStream(entity, Constants.ENCODING), AtomEntryImpl.class); - entry = entryContainer.getObject(); + entry = entryContainer.getPayload(); } else { - final Container jcontainer = + final ResWrap jcontainer = mapper.readValue(IOUtils.toInputStream(entity, Constants.ENCODING), - new TypeReference() { - }); + new TypeReference() { + }); - entry = dataBinder.toAtomEntry(jcontainer.getObject()); + entry = dataBinder.toAtomEntry(jcontainer.getPayload()); - entryContainer = new Container( + entryContainer = new ResWrap( jcontainer.getContextURL(), jcontainer.getMetadataETag(), entry); @@ -714,8 +714,8 @@ public class V4Services extends AbstractServices { // 3. Update the contained entity set final String atomFeedRelativePath = containedPath(entityId, containedEntitySetName).toString(); final InputStream feedIS = FSManager.instance(version).readFile(atomFeedRelativePath, Accept.ATOM); - final Container feedContainer = atomDeserializer.read(feedIS, AtomFeedImpl.class); - feedContainer.getObject().getEntries().add(entry); + final ResWrap feedContainer = atomDeserializer.read(feedIS, AtomFeedImpl.class); + feedContainer.getPayload().getEntries().add(entry); final ByteArrayOutputStream content = new ByteArrayOutputStream(); final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING); @@ -772,24 +772,24 @@ public class V4Services extends AbstractServices { final LinkInfo links = xml.readLinks( entitySetName, entityId, containedEntitySetName + "(" + containedEntityId + ")", Accept.ATOM); - Container container = atomDeserializer.read(links.getLinks(), AtomEntryImpl.class); - final AtomEntryImpl original = container.getObject(); + ResWrap container = atomDeserializer.read(links.getLinks(), AtomEntryImpl.class); + final AtomEntryImpl original = container.getPayload(); final AtomEntryImpl entryChanges; if (Accept.ATOM == contentTypeValue) { container = atomDeserializer.read(IOUtils.toInputStream(changes, Constants.ENCODING), AtomEntryImpl.class); - entryChanges = container.getObject(); + entryChanges = container.getPayload(); } else { final String entityType = getMetadataObj().getEntitySet(entitySetName).getType(); final String containedType = getMetadataObj().getEntityType(entityType). getNavigationProperty(containedEntitySetName).getType(); final EdmTypeInfo typeInfo = new EdmTypeInfo.Builder().setTypeExpression(containedType).build(); - final Container jsonContainer = mapper.readValue( + final ResWrap jsonContainer = mapper.readValue( IOUtils.toInputStream(changes, Constants.ENCODING), new TypeReference() { - }); - jsonContainer.getObject().setType(typeInfo.getFullQualifiedName().toString()); - entryChanges = dataBinder.toAtomEntry(jsonContainer.getObject()); + }); + jsonContainer.getPayload().setType(typeInfo.getFullQualifiedName().toString()); + entryChanges = dataBinder.toAtomEntry(jsonContainer.getPayload()); } for (Property property : entryChanges.getProperties()) { @@ -800,7 +800,7 @@ public class V4Services extends AbstractServices { original.getProperties().add(property); } - FSManager.instance(version).putInMemory(new Container(null, null, original), + FSManager.instance(version).putInMemory(new ResWrap((URI) null, null, original), xml.getLinksBasePath(entitySetName, entityId) + containedEntitySetName + "(" + containedEntityId + ")"); return xml.createResponse(null, null, acceptType, Response.Status.NO_CONTENT); @@ -820,8 +820,8 @@ public class V4Services extends AbstractServices { // 1. Fetch the contained entity to be removed final InputStream entry = FSManager.instance(version). readFile(containedPath(entityId, containedEntitySetName). - append('(').append(containedEntityId).append(')').toString(), Accept.ATOM); - final Container container = atomDeserializer.read(entry, AtomEntryImpl.class); + append('(').append(containedEntityId).append(')').toString(), Accept.ATOM); + final ResWrap container = atomDeserializer.read(entry, AtomEntryImpl.class); // 2. Remove the contained entity final String atomEntryRelativePath = containedPath(entityId, containedEntitySetName). @@ -831,8 +831,8 @@ public class V4Services extends AbstractServices { // 3. Update the contained entity set final String atomFeedRelativePath = containedPath(entityId, containedEntitySetName).toString(); final InputStream feedIS = FSManager.instance(version).readFile(atomFeedRelativePath, Accept.ATOM); - final Container feedContainer = atomDeserializer.read(feedIS, AtomFeedImpl.class); - feedContainer.getObject().getEntries().remove(container.getObject()); + final ResWrap feedContainer = atomDeserializer.read(feedIS, AtomFeedImpl.class); + feedContainer.getPayload().getEntries().remove(container.getPayload()); final ByteArrayOutputStream content = new ByteArrayOutputStream(); final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING); @@ -876,7 +876,7 @@ public class V4Services extends AbstractServices { final InputStream feed = FSManager.instance(version). readFile(containedPath(entityId, containedEntitySetName).toString(), Accept.ATOM); - final Container container = atomDeserializer.read(feed, AtomFeedImpl.class); + final ResWrap container = atomDeserializer.read(feed, AtomFeedImpl.class); return xml.createResponse( null, @@ -905,7 +905,7 @@ public class V4Services extends AbstractServices { final AtomPropertyImpl property = new AtomPropertyImpl(); property.setType("Microsoft.Test.OData.Services.ODataWCFService.Color"); property.setValue(new EnumValueImpl("Red")); - final Container container = new Container( + final ResWrap container = new ResWrap( URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX) + property.getType()), null, property); @@ -975,7 +975,7 @@ public class V4Services extends AbstractServices { value.get().add(new PrimitiveValueImpl("Car")); value.get().add(new PrimitiveValueImpl("Computer")); property.setValue(value); - final Container container = new Container( + final ResWrap container = new ResWrap( URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX) + property.getType()), null, property); @@ -1010,7 +1010,7 @@ public class V4Services extends AbstractServices { value.get().add(new PrimitiveValueImpl("first@olingo.apache.org")); value.get().add(new PrimitiveValueImpl("second@olingo.apache.org")); property.setValue(value); - final Container container = new Container( + final ResWrap container = new ResWrap( URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX) + property.getType()), null, property); @@ -1043,15 +1043,15 @@ public class V4Services extends AbstractServices { final Accept contentTypeValue = Accept.parse(contentType, version); Property property; if (contentTypeValue == Accept.ATOM) { - final Container paramContainer = atomDeserializer.read( + final ResWrap paramContainer = atomDeserializer.read( IOUtils.toInputStream(param, Constants.ENCODING), AtomPropertyImpl.class); - property = paramContainer.getObject(); + property = paramContainer.getPayload(); } else { - final Container paramContainer = + final ResWrap paramContainer = mapper.readValue(IOUtils.toInputStream(param, Constants.ENCODING), - new TypeReference() { - }); - property = paramContainer.getObject(); + new TypeReference() { + }); + property = paramContainer.getPayload(); } assert property.getValue().isComplex(); @@ -1085,15 +1085,15 @@ public class V4Services extends AbstractServices { final Accept contentTypeValue = Accept.parse(contentType, version); Property property; if (contentTypeValue == Accept.XML) { - final Container paramContainer = atomDeserializer.read( + final ResWrap paramContainer = atomDeserializer.read( IOUtils.toInputStream(param, Constants.ENCODING), AtomPropertyImpl.class); - property = paramContainer.getObject(); + property = paramContainer.getPayload(); } else { - final Container paramContainer = + final ResWrap paramContainer = mapper.readValue(IOUtils.toInputStream(param, Constants.ENCODING), - new TypeReference() { - }); - property = paramContainer.getObject(); + new TypeReference() { + }); + property = paramContainer.getPayload(); } assert "Microsoft.Test.OData.Services.ODataWCFService.Address".equals(property.getType()); 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 index f61f36a83..364380d3a 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 @@ -20,17 +20,17 @@ package org.apache.olingo.fit.serializer; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import java.net.URI; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ContextURL; +import org.apache.olingo.commons.api.data.ResWrap; 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 ResWrap { - public JSONEntryContainer(final URI contextURL, final String metadataETag, final JSONEntryImpl object) { + public JSONEntryContainer(final ContextURL 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 index 3c64f4fa6..7a53213cd 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 @@ -20,17 +20,17 @@ package org.apache.olingo.fit.serializer; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import java.net.URI; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ContextURL; +import org.apache.olingo.commons.api.data.ResWrap; 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 ResWrap { - public JSONFeedContainer(final URI contextURL, final String metadataETag, final JSONFeedImpl object) { + public JSONFeedContainer(final ContextURL 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 index 2cf7a7c39..f642a19b6 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 @@ -20,17 +20,17 @@ package org.apache.olingo.fit.serializer; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import java.net.URI; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ContextURL; +import org.apache.olingo.commons.api.data.ResWrap; 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 ResWrap { - public JSONPropertyContainer(final URI contextURL, final String metadataETag, final JSONPropertyImpl object) { + public JSONPropertyContainer(final ContextURL contextURL, final String metadataETag, final JSONPropertyImpl object) { super(contextURL, metadataETag, object); } } 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 ab8ed81f6..c01718628 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 @@ -26,6 +26,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; +import java.net.URI; import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; import java.util.Collection; @@ -42,10 +43,10 @@ import javax.xml.stream.XMLStreamException; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; 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.data.ResWrap; 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; @@ -352,68 +353,6 @@ public abstract class AbstractUtilities { // ----------------------------------------- } - public InputStream addMediaEntity( - final String entitySetName, - final InputStream is) throws Exception { - - final String entityKey = getDefaultEntryKey(entitySetName, null); - - addMediaEntityValue(entitySetName, entityKey, is); - - final String path = Commons.getEntityBasePath(entitySetName, entityKey); - - // ----------------------------------------- - // 2. save entity as atom - // ----------------------------------------- - final String entityURI = Commons.getEntityURI(entitySetName, entityKey); - String entity = "" - + "" - + "" + Constants.get(version, ConstantKey.DEFAULT_SERVICE_URL) + entityURI + "" - + "" - + "" - + "" - + "" - + "" - + "" + entityKey + "" - + "" - + "" - + ""; - - fsManager.putInMemory( - IOUtils.toInputStream(entity, Constants.ENCODING), - fsManager.getAbsolutePath(path + Constants.get(version, ConstantKey.ENTITY), Accept.ATOM)); - // ----------------------------------------- - - // ----------------------------------------- - // 3. save entity as json - // ----------------------------------------- - entity = "{" - + "\"odata.metadata\": \"" + Constants.get(version, ConstantKey.DEFAULT_SERVICE_URL) - + "/$metadata#" + entitySetName + "/@Element\"," - + "\"odata.type\": \"Microsoft.Test.OData.Services.AstoriaDefaultService." + entitySetName + "\"," - + "\"odata.id\": \"" + Constants.get(version, ConstantKey.DEFAULT_SERVICE_URL) + entityURI + "\"," - + "\"odata.editLink\": \"" + entityURI + "\"," - + "\"odata.mediaEditLink\": \"" + entityURI + "/$value\"," - + "\"odata.mediaReadLink\": \"" + entityURI + "/$value\"," - + "\"odata.mediaContentType\": \"*/*\"," - + "\"" + Commons.MEDIA_CONTENT.get(entitySetName) + "\": " + entityKey + "," - + "\"Description\": null" + "}"; - - fsManager.putInMemory( - IOUtils.toInputStream(entity, Constants.ENCODING), - fsManager.getAbsolutePath(path + Constants.get(version, ConstantKey.ENTITY), - Accept.JSON_FULLMETA)); - // ----------------------------------------- - - return readEntity(entitySetName, entityKey, getDefaultFormat()).getValue(); - } - public void putLinksInMemory( final String basePath, final String entitySetName, @@ -601,51 +540,51 @@ public abstract class AbstractUtilities { return builder.build(); } - public InputStream writeFeed(final Accept accept, final Container container) + public InputStream writeFeed(final Accept accept, final ResWrap container) throws XMLStreamException, IOException { final StringWriter writer = new StringWriter(); - if (accept == Accept.ATOM) { + if (accept == Accept.ATOM || accept == Accept.XML) { atomSerializer.write(writer, container); writer.flush(); writer.close(); } else { mapper.writeValue( writer, new JSONFeedContainer(container.getContextURL(), - container.getMetadataETag(), dataBinder.toJSONFeed(container.getObject()))); + container.getMetadataETag(), dataBinder.toJSONFeed(container.getPayload()))); } return IOUtils.toInputStream(writer.toString(), Constants.ENCODING); } - public AtomEntryImpl readEntry(final Accept contentTypeValue, final InputStream entity) + public AtomEntryImpl readEntry(final Accept accept, final InputStream entity) throws XMLStreamException, IOException { final AtomEntryImpl entry; - if (Accept.ATOM == contentTypeValue || Accept.XML == contentTypeValue) { - final Container container = atomDeserializer.read(entity, AtomEntryImpl.class); - entry = container.getObject(); + if (accept == Accept.ATOM || accept == Accept.XML) { + final ResWrap container = atomDeserializer.read(entity, AtomEntryImpl.class); + entry = container.getPayload(); } else { - final Container container = + final ResWrap container = mapper.readValue(entity, new TypeReference() { - }); - entry = dataBinder.toAtomEntry(container.getObject()); + }); + entry = dataBinder.toAtomEntry(container.getPayload()); } return entry; } - public InputStream writeEntry(final Accept accept, final Container container) + public InputStream writeEntry(final Accept accept, final ResWrap container) throws XMLStreamException, IOException { final StringWriter writer = new StringWriter(); - if (accept == Accept.ATOM) { + if (accept == Accept.ATOM || accept == Accept.XML) { atomSerializer.write(writer, container); } else { mapper.writeValue( writer, new JSONEntryContainer(container.getContextURL(), container.getMetadataETag(), - dataBinder.toJSONEntry(container.getObject()))); + dataBinder.toJSONEntry(container.getPayload()))); } return IOUtils.toInputStream(writer.toString(), Constants.ENCODING); @@ -666,16 +605,16 @@ public abstract class AbstractUtilities { return IOUtils.toInputStream(writer.toString(), Constants.ENCODING); } - public InputStream writeProperty(final Accept accept, final Container container) + public InputStream writeProperty(final Accept accept, final ResWrap container) throws XMLStreamException, IOException { final StringWriter writer = new StringWriter(); - if (accept == Accept.XML) { + if (accept == Accept.XML || accept == Accept.ATOM) { atomSerializer.write(writer, container); } else { mapper.writeValue( writer, new JSONPropertyContainer(container.getContextURL(), container.getMetadataETag(), - dataBinder.toJSONProperty(container.getObject()))); + dataBinder.toJSONProperty(container.getPayload()))); } return IOUtils.toInputStream(writer.toString(), Constants.ENCODING); @@ -829,6 +768,7 @@ public abstract class AbstractUtilities { public Map.Entry readEntity( final String entitySetName, final String entityId, final Accept accept) { + if (accept == Accept.XML || accept == Accept.TEXT) { throw new UnsupportedMediaTypeException("Unsupported media type"); } @@ -876,7 +816,7 @@ public abstract class AbstractUtilities { // -------------------------------- } - public InputStream replaceProperty( + public void replaceProperty( final String entitySetName, final String entityId, final InputStream changes, @@ -889,17 +829,14 @@ public abstract class AbstractUtilities { final Accept acceptType = accept == null || Accept.TEXT == accept ? Accept.XML : accept.getExtension().equals(Accept.JSON.getExtension()) ? Accept.JSON_FULLMETA : accept; - // read atom InputStream stream = fsManager.readFile(basePath + Constants.get(version, ConstantKey.ENTITY), acceptType); - - // change atom stream = replaceProperty(stream, changes, path, justValue); - // save atom - fsManager.putInMemory(stream, - fsManager.getAbsolutePath(basePath + Constants.get(version, ConstantKey.ENTITY), acceptType)); + final AtomEntryImpl entry = readEntry(acceptType, stream); + final ResWrap container = new ResWrap((URI) null, null, entry); - return fsManager.readFile(basePath + Constants.get(version, ConstantKey.ENTITY), acceptType); + fsManager.putInMemory(writeEntry(Accept.ATOM, container), + fsManager.getAbsolutePath(basePath + Constants.get(version, ConstantKey.ENTITY), Accept.ATOM)); } public InputStream deleteProperty( @@ -950,13 +887,6 @@ public abstract class AbstractUtilities { protected abstract InputStream deleteProperty(final InputStream src, final List path) throws Exception; - public abstract InputStream getProperty( - final String entitySetName, final String entityId, final List path, final String edmType) - throws Exception; - - public abstract InputStream getPropertyValue(final InputStream is, final List path) - throws Exception; - public abstract Map.Entry> extractLinkURIs(final InputStream is) throws Exception; public abstract Map.Entry> extractLinkURIs( diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/ConstantKey.java b/fit/src/main/java/org/apache/olingo/fit/utils/ConstantKey.java index 3c46e94eb..40b030d18 100644 --- a/fit/src/main/java/org/apache/olingo/fit/utils/ConstantKey.java +++ b/fit/src/main/java/org/apache/olingo/fit/utils/ConstantKey.java @@ -24,6 +24,7 @@ public enum ConstantKey { DEFAULT_SERVICE_URL, ODATA_COUNT_NAME, ODATA_METADATA_PREFIX, + ODATA_METADATA_ENTITY_SUFFIX, ATOM_DEF_TYPE, ATOM_PROPERTY_PREFIX, ATOM_METADATA_PREFIX, diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/Constants.java b/fit/src/main/java/org/apache/olingo/fit/utils/Constants.java index 355e92997..1d79c91e8 100644 --- a/fit/src/main/java/org/apache/olingo/fit/utils/Constants.java +++ b/fit/src/main/java/org/apache/olingo/fit/utils/Constants.java @@ -50,6 +50,7 @@ public class Constants { v4constants.put(ConstantKey.ODATA_SERVICE_VERSION, "OData-Version"); v4constants.put(ConstantKey.DEFAULT_SERVICE_URL, "http://localhost:9080/StaticService/V40/Static.svc/"); v4constants.put(ConstantKey.ODATA_METADATA_PREFIX, "http://localhost:9080/StaticService/V40/Static.svc/$metadata#"); + v4constants.put(ConstantKey.ODATA_METADATA_ENTITY_SUFFIX, "/$entity"); // ----------------------------- // ----------------------------- @@ -59,6 +60,7 @@ public class Constants { constants.put(ConstantKey.DEFAULT_SERVICE_URL, "http://localhost:9080/StaticService/V30/Static.svc/"); constants.put(ConstantKey.ODATA_COUNT_NAME, "odata.count"); constants.put(ConstantKey.ODATA_METADATA_PREFIX, "http://localhost:9080/StaticService/V30/Static.svc/$metadata#"); + constants.put(ConstantKey.ODATA_METADATA_ENTITY_SUFFIX, "/@Element"); constants.put(ConstantKey.ATOM_DEF_TYPE, "Edm.String"); constants.put(ConstantKey.ATOM_PROPERTY_PREFIX, "d:"); constants.put(ConstantKey.ATOM_METADATA_PREFIX, "m:"); 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 014da7d5c..9304454fb 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 @@ -36,7 +36,7 @@ import org.apache.commons.vfs2.FileSelector; import org.apache.commons.vfs2.FileSystemException; import org.apache.commons.vfs2.FileSystemManager; import org.apache.commons.vfs2.VFS; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; 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; @@ -98,7 +98,7 @@ public class FSManager { return memObject; } - public void putInMemory(final Container container, final String relativePath) + public void putInMemory(final ResWrap container, final String relativePath) throws IOException { try { final AtomSerializer atomSerializer = Commons.getAtomSerializer(version); @@ -117,7 +117,7 @@ public class FSManager { writer, new JSONEntryContainer( container.getContextURL(), container.getMetadataETag(), - new DataBinder(version).toJSONEntry(container.getObject()))); + new DataBinder(version).toJSONEntry(container.getPayload()))); putInMemory(new ByteArrayInputStream(content.toByteArray()), getAbsolutePath(relativePath, Accept.JSON_FULLMETA)); } catch (Exception e) { diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractJSONUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java similarity index 82% rename from fit/src/main/java/org/apache/olingo/fit/utils/AbstractJSONUtilities.java rename to fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java index b0493d219..55cfb2dcd 100644 --- a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractJSONUtilities.java +++ b/fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java @@ -19,9 +19,7 @@ package org.apache.olingo.fit.utils; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.TextNode; import java.io.ByteArrayInputStream; @@ -42,9 +40,9 @@ import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.fit.metadata.Metadata; import org.apache.olingo.fit.metadata.NavigationProperty; -public abstract class AbstractJSONUtilities extends AbstractUtilities { +public class JSONUtilities extends AbstractUtilities { - public AbstractJSONUtilities(final ODataServiceVersion version) throws Exception { + public JSONUtilities(final ODataServiceVersion version) throws Exception { super(version); } @@ -57,7 +55,7 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities { protected InputStream addLinks( final String entitySetName, final String entitykey, final InputStream is, final Set links) throws Exception { - + final ObjectNode srcNode = (ObjectNode) mapper.readTree(is); IOUtils.closeQuietly(is); @@ -66,12 +64,11 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities { new TextNode(Commons.getLinksURI(version, entitySetName, entitykey, link))); } - return IOUtils.toInputStream(srcNode.toString(), "UTF-8"); + return IOUtils.toInputStream(srcNode.toString(), Constants.ENCODING); } @Override protected Set retrieveAllLinkNames(InputStream is) throws Exception { - final ObjectNode srcNode = (ObjectNode) mapper.readTree(is); IOUtils.closeQuietly(is); @@ -101,7 +98,6 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities { protected NavigationLinks retrieveNavigationInfo(final String entitySetName, final InputStream is) throws Exception { - final ObjectNode srcNode = (ObjectNode) mapper.readTree(is); IOUtils.closeQuietly(is); @@ -129,7 +125,7 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities { links.addLinks(title, hrefs); } else if (navigationProperties.containsKey(field.getKey())) { - links.addInlines(field.getKey(), IOUtils.toInputStream(field.getValue().toString(), "UTF-8")); + links.addInlines(field.getKey(), IOUtils.toInputStream(field.getValue().toString(), Constants.ENCODING)); } } @@ -144,7 +140,6 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities { final String entitySetName, final String entityKey, final InputStream is, final NavigationLinks links) throws Exception { - final ObjectNode srcNode = (ObjectNode) mapper.readTree(is); if (links != null) { @@ -178,72 +173,10 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities { return IOUtils.toInputStream(srcNode.toString(), Constants.ENCODING); } - @Override - public InputStream getPropertyValue(final InputStream src, final List path) - throws Exception { - - final JsonNode srcNode = mapper.readTree(src); - final JsonNode node = getProperty(srcNode, path); - return IOUtils.toInputStream(node.asText(), Constants.ENCODING); - } - - @Override - public InputStream getProperty( - final String entitySetName, final String entityId, final List path, final String edmType) - throws Exception { - - final InputStream src = fsManager.readFile( - Commons.getEntityBasePath(entitySetName, entityId) + Constants.get(version, ConstantKey.ENTITY), - Accept.JSON_FULLMETA); - - - final JsonNode srcNode = mapper.readTree(src); - - final ObjectNode propertyNode = new ObjectNode(JsonNodeFactory.instance); - - 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); - } - - JsonNode jsonNode = getProperty(srcNode, path); - - if (jsonNode.isArray()) { - propertyNode.put("value", (ArrayNode) jsonNode); - } else if (jsonNode.isObject()) { - propertyNode.putAll((ObjectNode) jsonNode); - } else { - propertyNode.put("value", jsonNode.asText()); - } - - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - mapper.writeValue(bos, propertyNode); - - final InputStream res = new ByteArrayInputStream(bos.toByteArray()); - IOUtils.closeQuietly(bos); - - return res; - } - - private JsonNode getProperty(final JsonNode node, final List path) - throws NotFoundException { - - JsonNode propertyNode = node; - for (int i = 0; i < path.size(); i++) { - propertyNode = propertyNode.get(path.get(i)); - if (propertyNode == null) { - throw new NotFoundException(); - } - } - - return propertyNode; - } - public InputStream addJsonInlinecount( final InputStream src, final int count, final Accept accept) throws Exception { - + final JsonNode srcNode = mapper.readTree(src); ((ObjectNode) srcNode).put(Constants.get(version, ConstantKey.ODATA_COUNT_NAME), count); @@ -258,7 +191,7 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities { } public InputStream wrapJsonEntities(final InputStream entities) throws Exception { - + final JsonNode node = mapper.readTree(entities); final ObjectNode res; @@ -287,7 +220,7 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities { @Override public InputStream selectEntity(final InputStream src, final String[] propertyNames) throws Exception { - + final ObjectNode srcNode = (ObjectNode) mapper.readTree(src); final Set retain = new HashSet(); @@ -307,7 +240,7 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities { srcNode.retain(retain); - return IOUtils.toInputStream(srcNode.toString(), "UTF-8"); + return IOUtils.toInputStream(srcNode.toString(), Constants.ENCODING); } @Override @@ -319,7 +252,6 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities { throw new NotFoundException(); } - final ObjectNode node = mapper.createObjectNode(); final ByteArrayOutputStream bos = new ByteArrayOutputStream(); @@ -356,14 +288,13 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities { node.set(Constants.get(version, ConstantKey.JSON_NEXTLINK_NAME), new TextNode(next)); } - return IOUtils.toInputStream(node.toString(), "UTF-8"); + return IOUtils.toInputStream(node.toString(), Constants.ENCODING); } @Override protected InputStream replaceLink( final InputStream toBeChanged, final String linkName, final InputStream replacement) throws Exception { - final ObjectNode toBeChangedNode = (ObjectNode) mapper.readTree(toBeChanged); final ObjectNode replacementNode = (ObjectNode) mapper.readTree(replacement); @@ -379,20 +310,19 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities { toBeChangedNode.set(linkName + Constants.get(version, ConstantKey.JSON_NEXTLINK_SUFFIX), next); } - return IOUtils.toInputStream(toBeChangedNode.toString(), "UTF-8"); + return IOUtils.toInputStream(toBeChangedNode.toString(), Constants.ENCODING); } @Override protected Map getChanges(final InputStream src) throws Exception { final Map res = new HashMap(); - final JsonNode srcObject = mapper.readTree(src); final Iterator> fields = srcObject.fields(); while (fields.hasNext()) { final Map.Entry field = fields.next(); - res.put(field.getKey(), IOUtils.toInputStream(field.getValue().toString(), "UTF-8")); + res.put(field.getKey(), IOUtils.toInputStream(field.getValue().toString(), Constants.ENCODING)); } return res; @@ -409,7 +339,7 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities { @Override public Map.Entry> extractLinkURIs(final InputStream is) throws Exception { - + final ObjectNode srcNode = (ObjectNode) mapper.readTree(is); IOUtils.closeQuietly(is); @@ -436,19 +366,18 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities { @Override public InputStream addEditLink( final InputStream content, final String title, final String href) throws Exception { - + final ObjectNode srcNode = (ObjectNode) mapper.readTree(content); IOUtils.closeQuietly(content); srcNode.set(Constants.get(version, ConstantKey.JSON_EDITLINK_NAME), new TextNode(href)); - return IOUtils.toInputStream(srcNode.toString(), "UTF-8"); + return IOUtils.toInputStream(srcNode.toString(), Constants.ENCODING); } @Override public InputStream addOperation(final InputStream content, final String name, final String metaAnchor, final String href) throws Exception { - final ObjectNode srcNode = (ObjectNode) mapper.readTree(content); IOUtils.closeQuietly(content); @@ -457,22 +386,25 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities { action.set("target", new TextNode(href)); srcNode.set(metaAnchor, action); - return IOUtils.toInputStream(srcNode.toString(), "UTF-8"); + return IOUtils.toInputStream(srcNode.toString(), Constants.ENCODING); } @Override public InputStream replaceProperty( final InputStream src, final InputStream replacement, final List path, final boolean justValue) throws Exception { - + final ObjectNode srcNode = (ObjectNode) mapper.readTree(src); IOUtils.closeQuietly(src); - final JsonNode replacementNode; + JsonNode replacementNode; if (justValue) { replacementNode = new TextNode(IOUtils.toString(replacement)); } else { - replacementNode = (ObjectNode) mapper.readTree(replacement); + replacementNode = mapper.readTree(replacement); + if (replacementNode.has("value")) { + replacementNode = replacementNode.get("value"); + } } IOUtils.closeQuietly(replacement); @@ -484,14 +416,14 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities { } } - ((ObjectNode) node).set(path.get(path.size() - 1), replacementNode); - - return IOUtils.toInputStream(srcNode.toString(), "UTF-8"); + ((ObjectNode) node).set(path.get(path.size() - 1), replacementNode); + + return IOUtils.toInputStream(srcNode.toString(), Constants.ENCODING); } @Override public InputStream deleteProperty(final InputStream src, final List path) throws Exception { - + final ObjectNode srcNode = (ObjectNode) mapper.readTree(src); IOUtils.closeQuietly(src); @@ -505,6 +437,6 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities { ((ObjectNode) node).set(path.get(path.size() - 1), null); - return IOUtils.toInputStream(srcNode.toString(), "UTF-8"); + return IOUtils.toInputStream(srcNode.toString(), Constants.ENCODING); } } diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/XmlElement.java b/fit/src/main/java/org/apache/olingo/fit/utils/XMLElement.java similarity index 89% rename from fit/src/main/java/org/apache/olingo/fit/utils/XmlElement.java rename to fit/src/main/java/org/apache/olingo/fit/utils/XMLElement.java index 850c862eb..304b8ff4a 100644 --- a/fit/src/main/java/org/apache/olingo/fit/utils/XmlElement.java +++ b/fit/src/main/java/org/apache/olingo/fit/utils/XMLElement.java @@ -24,7 +24,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; -import java.nio.charset.Charset; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLStreamException; import javax.xml.stream.events.EndElement; @@ -33,14 +32,12 @@ import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class XmlElement { +public class XMLElement { /** * Logger. */ - protected static final Logger LOG = LoggerFactory.getLogger(XmlElement.class); - - private static Charset encoding = Charset.forName("UTF-8"); + private static final Logger LOG = LoggerFactory.getLogger(XMLElement.class); private StartElement start; @@ -75,8 +72,8 @@ public class XmlElement { public void setContent(final InputStream content) throws IOException { this.content.reset(); - final InputStreamReader reader = new InputStreamReader(content, encoding); - final OutputStreamWriter writer = new OutputStreamWriter(this.content, encoding); + final InputStreamReader reader = new InputStreamReader(content, Constants.ENCODING); + final OutputStreamWriter writer = new OutputStreamWriter(this.content, Constants.ENCODING); IOUtils.copyLarge(reader, writer); writer.flush(); @@ -89,11 +86,11 @@ public class XmlElement { InputStream res; try { final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - final OutputStreamWriter osw = new OutputStreamWriter(bos, encoding); + final OutputStreamWriter osw = new OutputStreamWriter(bos, Constants.ENCODING); getStart().writeAsEncodedUnicode(osw); - IOUtils.copy(getContent(), osw, encoding); + IOUtils.copy(getContent(), osw, Constants.ENCODING); getEnd().writeAsEncodedUnicode(osw); osw.flush(); @@ -101,7 +98,7 @@ public class XmlElement { res = new ByteArrayInputStream(bos.toByteArray()); } catch (Exception e) { - LOG.error("Error serializing elemnt", e); + LOG.error("Error serializing element", e); res = null; } return res; diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractXMLUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java similarity index 88% rename from fit/src/main/java/org/apache/olingo/fit/utils/AbstractXMLUtilities.java rename to fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java index ea18750c1..162221a2e 100644 --- a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractXMLUtilities.java +++ b/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java @@ -56,13 +56,13 @@ import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.fit.metadata.Metadata; import org.apache.olingo.fit.metadata.NavigationProperty; -public abstract class AbstractXMLUtilities extends AbstractUtilities { +public class XMLUtilities extends AbstractUtilities { protected static XMLInputFactory ifactory = null; protected static XMLOutputFactory ofactory = null; - public AbstractXMLUtilities(final ODataServiceVersion version) throws Exception { + public XMLUtilities(final ODataServiceVersion version) throws Exception { super(version); } @@ -142,7 +142,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { final ByteArrayOutputStream bos = new ByteArrayOutputStream(); final XMLEventWriter writer = getEventWriter(bos); // ----------------------------------------- - final Map.Entry entry = + final Map.Entry entry = extractElement(reader, writer, Collections.singletonList("entry"), 0, 1, 1); writer.add(entry.getValue().getStart()); @@ -194,7 +194,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { int startDepth = 0; while (true) { - final Map.Entry linkInfo = + final Map.Entry linkInfo = extractElement(reader, null, Collections.singletonList(Constants.get(version, ConstantKey.LINK)), startDepth, 2, 2); @@ -233,10 +233,10 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { while (true) { // a. search for link with type attribute equals to "application/atom+xml;type=entry/feed" - final Map.Entry linkInfo = extractElement( + final Map.Entry linkInfo = extractElement( reader, null, Collections.singletonList(Constants.get(version, ConstantKey.LINK)), filter, true, startDepth, 2, 2); - final XmlElement link = linkInfo.getValue(); + final XMLElement link = linkInfo.getValue(); startDepth = linkInfo.getKey(); final String title = link.getStart().getAttributeByName(new QName("title")).getValue(); @@ -245,7 +245,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { final String href = hrefAttr == null ? null : hrefAttr.getValue(); try { - final XmlElement inlineElement = + final XMLElement inlineElement = extractElement(link.getContentReader(), null, Collections.singletonList(Constants.get(version, ConstantKey.INLINE)), 0, -1, -1). getValue(); @@ -253,7 +253,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { try { while (true) { - final XmlElement entry = + final XMLElement entry = extractElement(inlineReader, null, Collections.singletonList("entry"), 0, -1, -1). getValue(); links.addInlines(title, entry.toStream()); @@ -310,7 +310,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { filter.add(new AbstractMap.SimpleEntry("type", "application/atom+xml;type=entry")); filter.add(new AbstractMap.SimpleEntry("type", "application/atom+xml;type=feed")); - Map.Entry linkInfo = null; + Map.Entry linkInfo = null; while (true) { // a. search for link with type attribute equals to "application/atom+xml;type=entry/feed" @@ -318,7 +318,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { reader, writer, Collections.singletonList(Constants.get(version, ConstantKey.LINK)), filter, true, linkInfo == null ? 0 : linkInfo.getKey(), 2, 2); - final XmlElement link = linkInfo.getValue(); + final XMLElement link = linkInfo.getValue(); final String title = link.getStart().getAttributeByName(new QName("title")).getValue(); @@ -365,12 +365,12 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { } - public XmlElement getXmlElement( + public XMLElement getXmlElement( final StartElement start, final XMLEventReader reader) throws Exception { - final XmlElement res = new XmlElement(); + final XMLElement res = new XMLElement(); res.setStart(start); final Charset encoding = Charset.forName("UTF-8"); @@ -463,7 +463,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { bos = new ByteArrayOutputStream(); writer = getEventWriter(bos); - final XmlElement entryElement = + final XMLElement entryElement = extractElement(reader, writer, Collections.singletonList("entry"), 0, 1, 1).getValue(); writer.add(entryElement.getStart()); @@ -515,7 +515,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { try { // check edit link existence - XmlElement contentElement = + XMLElement contentElement = extractElement(reader, writer, Collections.singletonList("content"), 0, 2, 2).getValue(); writer.add(contentElement.getStart()); writer.add(contentElement.getContentReader()); @@ -529,7 +529,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { writer = getEventWriter(bos); if (isMediaContent(title)) { - final XmlElement entryElement = + final XMLElement entryElement = extractElement(reader, writer, Collections.singletonList("entry"), 0, 1, 1).getValue(); writer.add(entryElement.getStart()); @@ -542,7 +542,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { writer.add(entryElement.getEnd()); } else { try { - final XmlElement entryElement = + final XMLElement entryElement = extractElement(reader, writer, Collections.singletonList( Constants.get(version, ConstantKey.PROPERTIES)), 0, 2, 3).getValue(); @@ -564,7 +564,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { bos = new ByteArrayOutputStream(); writer = getEventWriter(bos); - final XmlElement entryElement = + final XMLElement entryElement = extractElement(reader, writer, Collections.singletonList("entry"), 0, 1, 1).getValue(); writer.add(entryElement.getStart()); writer.add(entryElement.getContentReader()); @@ -630,14 +630,14 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { return count; } - public Map.Entry extractElement( + public Map.Entry extractElement( final XMLEventReader reader, final XMLEventWriter writer, final List path, final int startPathPos, final int minPathPos, final int maxPathPos) throws Exception { return extractElement(reader, writer, path, null, false, startPathPos, minPathPos, maxPathPos); } - public Map.Entry extractElement( + public Map.Entry extractElement( final XMLEventReader reader, final XMLEventWriter writer, final List path, final Collection> filter, final boolean filterInOr, @@ -724,7 +724,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { throw new NotFoundException(); } - return new SimpleEntry(Integer.valueOf(depth - 1), getXmlElement(start, reader)); + return new SimpleEntry(Integer.valueOf(depth - 1), getXmlElement(start, reader)); } public InputStream addAtomInlinecount( @@ -737,7 +737,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { try { - final XmlElement feedElement = + final XMLElement feedElement = extractElement(reader, writer, Collections.singletonList("feed"), 0, 1, 1).getValue(); writer.add(feedElement.getStart()); @@ -759,25 +759,6 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { return new ByteArrayInputStream(bos.toByteArray()); } - @Override - public InputStream getPropertyValue(final InputStream is, final List path) - throws Exception { - - final List pathElements = new ArrayList(); - - for (String element : path) { - pathElements.add(Constants.get(version, ConstantKey.ATOM_PROPERTY_PREFIX) + element); - } - - final XMLEventReader reader = getEventReader(is); - final Map.Entry property = extractElement(reader, null, pathElements, 0, 3, 4); - - reader.close(); - IOUtils.closeQuietly(is); - - return property.getValue().getContent(); - } - @Override public InputStream selectEntity(final InputStream entity, final String[] propertyNames) throws Exception { final XMLEventReader reader = getEventReader(entity); @@ -896,7 +877,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { try { final Map.Entry uri = Commons.parseEntityURI(link); - final XmlElement entry = + final XMLElement entry = extractElement( getEventReader(readEntity(uri.getKey(), uri.getValue(), Accept.ATOM).getValue()), null, @@ -936,7 +917,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { // retrieve properties ... XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray())); - final Map.Entry propertyElement = + final Map.Entry propertyElement = extractElement(reader, null, Collections.singletonList(Constants.get(version, ConstantKey.PROPERTIES)), 0, 2, 3); reader.close(); @@ -945,7 +926,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { try { while (true) { - final XmlElement property = extractElement(reader, null, null, 0, -1, -1).getValue(); + final XMLElement property = extractElement(reader, null, null, 0, -1, -1).getValue(); res.put(property.getStart().getName().getLocalPart(), property.toStream()); } } catch (Exception ignore) { @@ -960,7 +941,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { try { int pos = 0; while (true) { - final Map.Entry linkElement = + final Map.Entry linkElement = extractElement(reader, null, Collections.singletonList(Constants.get(version, ConstantKey.LINK)), pos, 2, 2); @@ -990,7 +971,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { XMLEvent newLine = eventFactory.createSpace("\n"); try { - final XmlElement linkElement = + final XMLElement linkElement = extractElement(reader, writer, Collections.singletonList(Constants.get(version, ConstantKey.LINK)), Collections.>singletonList( @@ -1022,34 +1003,6 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { return new ByteArrayInputStream(bos.toByteArray()); } - public String getEdmTypeFromAtom(final String entitySetName, final String entityId, final List path) - throws Exception { - InputStream src = fsManager.readFile(Commons.getEntityBasePath(entitySetName, entityId) - + Constants.get(version, ConstantKey.ENTITY), Accept.XML); - - final List atomPathElements = new ArrayList(); - - for (String element : path) { - atomPathElements.add(Constants.get(version, ConstantKey.ATOM_PROPERTY_PREFIX) + element); - } - - final Map.Entry prop = extractElement(getEventReader(src), null, atomPathElements, 0, 3, 4); - IOUtils.closeQuietly(src); - - final Attribute type = - prop.getValue().getStart().getAttributeByName(new QName(Constants.get(version, ConstantKey.TYPE))); - - final String edmType; - - if (type == null) { - edmType = Constants.get(version, ConstantKey.ATOM_DEF_TYPE); - } else { - edmType = type.getValue(); - } - - return edmType; - } - @Override public Map.Entry> extractLinkURIs( final String entitySetName, final String entityId, final String linkName) @@ -1093,56 +1046,6 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { return new AbstractMap.SimpleEntry>(next, links); } - @Override - public InputStream getProperty( - final String entitySetName, final String entityId, final List path, final String edmType) - throws Exception { - - final List pathElements = new ArrayList(); - - for (String element : path) { - pathElements.add(Constants.get(version, ConstantKey.ATOM_PROPERTY_PREFIX) + element); - } - - final InputStream src = - fsManager.readFile(Commons.getEntityBasePath(entitySetName, entityId) - + Constants.get(version, ConstantKey.ENTITY), Accept.XML); - - final XMLEventReader reader = getEventReader(src); - final XmlElement property = extractElement(reader, null, pathElements, 0, 3, 4).getValue(); - - reader.close(); - IOUtils.closeQuietly(src); - - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - final XMLEventWriter writer = getEventWriter(bos); - - final XMLEventFactory eventFactory = XMLEventFactory.newInstance(); - writer.add(eventFactory.createStartDocument("UTF-8", "1.0")); - writer.add(property.getStart()); - - if (property.getStart().getAttributeByName(new QName( - Constants.get(version, ConstantKey.ATOM_DATASERVICE_NS))) == null) { - writer.add(eventFactory.createNamespace( - Constants.get(version, ConstantKey.ATOM_PROPERTY_PREFIX).substring(0, 1), - Constants.get(version, ConstantKey.DATASERVICES_NS))); - } - if (property.getStart().getAttributeByName(new QName( - Constants.get(version, ConstantKey.ATOM_METADATA_NS))) == null) { - writer.add(eventFactory.createNamespace( - Constants.get(version, ConstantKey.ATOM_METADATA_PREFIX).substring(0, 1), - Constants.get(version, ConstantKey.METADATA_NS))); - } - - writer.add(property.getContentReader()); - writer.add(property.getEnd()); - - writer.flush(); - writer.close(); - - return new ByteArrayInputStream(bos.toByteArray()); - } - @Override public InputStream replaceProperty( final InputStream src, final InputStream replacement, final List path, final boolean justValue) @@ -1159,7 +1062,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { final ByteArrayOutputStream bos = new ByteArrayOutputStream(); final XMLEventWriter writer = getEventWriter(bos); - final Map.Entry element = extractElement(reader, writer, pathElements, 0, 3, 4); + final Map.Entry element = extractElement(reader, writer, pathElements, 0, 3, 4); if (justValue) { writer.add(element.getValue().getStart()); @@ -1197,7 +1100,6 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { @Override public InputStream deleteProperty(final InputStream src, final List path) throws Exception { - final List pathElements = new ArrayList(); for (String element : path) { @@ -1209,7 +1111,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities { final ByteArrayOutputStream bos = new ByteArrayOutputStream(); final XMLEventWriter writer = getEventWriter(bos); - final Map.Entry element = extractElement(reader, writer, pathElements, 0, 3, 4); + final Map.Entry element = extractElement(reader, writer, pathElements, 0, 3, 4); final XMLEventReader changesReader = new XMLEventReaderWrapper(IOUtils.toInputStream( String.format("<%s m:null=\"true\" />", path.get(path.size() - 1)), Constants.ENCODING)); diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/v3/JSONUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/v3/JSONUtilities.java deleted file mode 100644 index 24b6c55a9..000000000 --- a/fit/src/main/java/org/apache/olingo/fit/utils/v3/JSONUtilities.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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. - */ -package org.apache.olingo.fit.utils.v3; - -import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; - -public class JSONUtilities extends org.apache.olingo.fit.utils.AbstractJSONUtilities { - - public JSONUtilities() throws Exception { - super(ODataServiceVersion.V30); - } -} diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/v4/XMLUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/v4/XMLUtilities.java deleted file mode 100644 index 86e6e3c26..000000000 --- a/fit/src/main/java/org/apache/olingo/fit/utils/v4/XMLUtilities.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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. - */ -package org.apache.olingo.fit.utils.v4; - -import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; - -public class XMLUtilities extends org.apache.olingo.fit.utils.AbstractXMLUtilities { - - public XMLUtilities() throws Exception { - super(ODataServiceVersion.V40); - } -} diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonEdmEnabledODataClient.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonEdmEnabledODataClient.java new file mode 100644 index 000000000..2b5478f34 --- /dev/null +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonEdmEnabledODataClient.java @@ -0,0 +1,44 @@ +/* + * 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. + */ +package org.apache.olingo.client.api; + +import java.net.URI; +import org.apache.olingo.client.api.communication.request.cud.CommonUpdateType; +import org.apache.olingo.commons.api.edm.Edm; + +/** + * Client interface that caches the Edm metadata information for a given service root. + *
+ * Be aware that any request generated via this client instance will be performed against the given service root. + * + * @param concrete update type, depending on the protocol version + */ +public interface CommonEdmEnabledODataClient extends CommonODataClient { + + String getServiceRoot(); + + /** + * Checks if the cached Edm matadata information matches the argument and, if not, updates the cache against the + * configured service root. + * + * @param metadataETag metadata ETag to be compared against the cache + * @return Edm + */ + Edm getEdm(String metadataETag); +} diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonODataClient.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonODataClient.java index b3a44275d..fccaa54e0 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonODataClient.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonODataClient.java @@ -36,6 +36,11 @@ import org.apache.olingo.client.api.uri.CommonURIBuilder; import org.apache.olingo.client.api.uri.CommonFilterFactory; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; +/** + * Generic client interface (common to all supported OData protocol versions). + * + * @param concrete update type, depending on the protocol version + */ public interface CommonODataClient { ODataServiceVersion getServiceVersion(); diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataRawResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataRawResponse.java index 8dd189acc..a3de84fc3 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataRawResponse.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataRawResponse.java @@ -18,6 +18,8 @@ */ package org.apache.olingo.client.api.communication.response; +import org.apache.olingo.commons.api.data.ResWrap; + /** * This interface represents a generic OData response. */ @@ -29,5 +31,5 @@ public interface ODataRawResponse extends ODataResponse { * @param reference an OData domain object class reference * @return response body parsed as the given reference, if available, null otherwise */ - T getBodyAs(final Class reference); + ResWrap getBodyAs(final Class reference); } diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java index 7da07ec3b..1538ad3a1 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java @@ -19,7 +19,6 @@ package org.apache.olingo.client.api.communication.response; import java.io.InputStream; -import java.net.URI; import java.util.Collection; import java.util.Map; import org.apache.http.HttpResponse; @@ -59,31 +58,7 @@ public interface ODataResponse { * * @return ETag header value, if provided */ - String getEtag(); - - /** - * The context URL describes the content of the payload. It consists of the canonical metadata document URL and a - * fragment identifying the relevant portion of the metadata document. - *
- * Request payloads generally do not require context URLs as the type of the payload can generally be determined from - * the request URL. - *
- * For details on how the context URL is used to describe a payload, see the relevant sections in the particular - * format. - * - * @return context URL. - */ - URI getContextURL(); - - /** - * An ETag header MAY also be returned on a metadata document request or service document request to allow the client - * subsequently to make a conditional request for the metadata or service document. Clients can also compare the value - * of the ETag header returned from a metadata document request to the metadata ETag returned in a response in order - * to verify the version of the metadata used to generate that response. - * - * @return metadata ETag. - */ - String getMetadataETag(); + String getETag(); /** * Gets the content type. diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataEntitySetIterator.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataEntitySetIterator.java index 107816f64..8002845d1 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataEntitySetIterator.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataEntitySetIterator.java @@ -31,16 +31,17 @@ import org.apache.commons.lang3.StringUtils; import org.apache.olingo.client.api.CommonODataClient; import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.data.Entry; -import org.apache.olingo.commons.api.format.ODataPubFormat; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.domain.CommonODataEntity; import org.apache.olingo.commons.api.domain.CommonODataEntitySet; +import org.apache.olingo.commons.api.format.ODataPubFormat; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * OData entity set iterator class. *
- * Please don't forget to call the close()>/ method when not needed any more. + * Please don't forget to call the close()>/ method when not needed any more. * * @param concrete ODataEntity implementation * @param concrete ODataEntitySet implementation @@ -61,7 +62,7 @@ public class ODataEntitySetIterator cached; private ES entitySet; @@ -78,7 +79,7 @@ public class ODataEntitySetIterator odataClient, final InputStream stream, final ODataPubFormat format) { this.odataClient = odataClient; @@ -171,10 +172,10 @@ public class ODataEntitySetIterator nextJsonEntryFromFeed(final InputStream input, final OutputStream osFeed) { final ByteArrayOutputStream entry = new ByteArrayOutputStream(); - Entry jsonEntry = null; + ResWrap jsonEntry = null; try { int c; @@ -209,7 +210,7 @@ public class ODataEntitySetIterator= 0) { jsonEntry = odataClient.getDeserializer().toEntry( - new ByteArrayInputStream(entry.toByteArray()), ODataPubFormat.JSON).getObject(); + new ByteArrayInputStream(entry.toByteArray()), ODataPubFormat.JSON); } } else { while ((c = input.read()) >= 0) { @@ -230,10 +231,12 @@ public class ODataEntitySetIterator nextAtomEntryFromFeed( + final InputStream input, final OutputStream osFeed, final String namespaces) { + final ByteArrayOutputStream entry = new ByteArrayOutputStream(); - Entry atomEntry = null; + ResWrap atomEntry = null; try { if (consume(input, "", osFeed, false) >= 0) { @@ -243,7 +246,7 @@ public class ODataEntitySetIterator", entry, true) >= 0) { atomEntry = odataClient.getDeserializer(). - toEntry(new ByteArrayInputStream(entry.toByteArray()), ODataPubFormat.ATOM).getObject(); + toEntry(new ByteArrayInputStream(entry.toByteArray()), ODataPubFormat.ATOM); } } } catch (Exception e) { diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ClientODataDeserializer.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ClientODataDeserializer.java index 24b6e60ff..9bca91a85 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ClientODataDeserializer.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ClientODataDeserializer.java @@ -21,7 +21,7 @@ package org.apache.olingo.client.api.op; import java.io.InputStream; import org.apache.olingo.client.api.data.ServiceDocument; import org.apache.olingo.client.api.edm.xml.XMLMetadata; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.format.ODataFormat; import org.apache.olingo.commons.api.op.CommonODataDeserializer; @@ -36,5 +36,5 @@ public interface ClientODataDeserializer extends CommonODataDeserializer { * @param format OData service document format. * @return ServiceDocument object. */ - Container toServiceDocument(InputStream input, ODataFormat format); + ResWrap toServiceDocument(InputStream input, ODataFormat format); } diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataBinder.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataBinder.java index 0d8da5226..acb08aebc 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataBinder.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataBinder.java @@ -19,12 +19,12 @@ package org.apache.olingo.client.api.op; import java.io.Serializable; -import java.net.URI; import org.apache.olingo.commons.api.data.Entry; 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.client.api.data.ServiceDocument; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.domain.CommonODataEntity; import org.apache.olingo.commons.api.domain.CommonODataEntitySet; import org.apache.olingo.commons.api.domain.ODataLink; @@ -90,41 +90,23 @@ public interface CommonODataBinder extends Serializable { * Gets ODataEntitySet from the given feed resource. * * @param resource feed resource. - * @return ODataEntitySet object. + * @return {@link CommonODataEntitySet} object. */ - CommonODataEntitySet getODataEntitySet(Feed resource); - - /** - * Gets ODataEntitySet from the given feed resource. - * - * @param resource feed resource. - * @param defaultBaseURI default base URI. - * @return ODataEntitySet object. - */ - CommonODataEntitySet getODataEntitySet(Feed resource, URI defaultBaseURI); + CommonODataEntitySet getODataEntitySet(ResWrap resource); /** * Gets ODataEntity from the given entry resource. * * @param resource entry resource. - * @return ODataEntity object. + * @return {@link CommonODataEntity} object. */ - CommonODataEntity getODataEntity(Entry resource); - - /** - * Gets ODataEntity from the given entry resource. - * - * @param resource entry resource. - * @param defaultBaseURI default base URI. - * @return ODataEntity object. - */ - CommonODataEntity getODataEntity(Entry resource, URI defaultBaseURI); + CommonODataEntity getODataEntity(ResWrap resource); /** * Gets an ODataProperty from the given property resource. * - * @param property property resource. - * @return ODataProperty object. + * @param resource property resource. + * @return {@link CommonODataProperty} object. */ - CommonODataProperty getODataProperty(Property property); + CommonODataProperty getODataProperty(ResWrap resource); } diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataReader.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataReader.java index 923ac231b..0f1335a6a 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataReader.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataReader.java @@ -22,7 +22,7 @@ import java.io.InputStream; import java.io.Serializable; import java.util.List; import org.apache.olingo.client.api.edm.xml.Schema; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.domain.ODataError; import org.apache.olingo.commons.api.domain.CommonODataEntity; import org.apache.olingo.commons.api.domain.CommonODataEntitySet; @@ -112,5 +112,5 @@ public interface CommonODataReader extends Serializable { * @param reference reference. * @return read object. */ - Container read(InputStream src, String format, Class reference); + ResWrap read(InputStream src, String format, Class reference); } diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataBinder.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataBinder.java index 52cb62513..92d3061cf 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataBinder.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataBinder.java @@ -18,13 +18,13 @@ */ package org.apache.olingo.client.api.op.v3; -import java.net.URI; import org.apache.olingo.commons.api.data.v3.LinkCollection; import org.apache.olingo.client.api.domain.v3.ODataLinkCollection; import org.apache.olingo.client.api.op.CommonODataBinder; import org.apache.olingo.commons.api.data.Entry; import org.apache.olingo.commons.api.data.Feed; import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.domain.v3.ODataEntity; import org.apache.olingo.commons.api.domain.v3.ODataEntitySet; import org.apache.olingo.commons.api.domain.v3.ODataProperty; @@ -32,19 +32,13 @@ import org.apache.olingo.commons.api.domain.v3.ODataProperty; public interface ODataBinder extends CommonODataBinder { @Override - ODataEntitySet getODataEntitySet(Feed resource); + ODataEntitySet getODataEntitySet(ResWrap resource); @Override - ODataEntitySet getODataEntitySet(Feed resource, URI defaultBaseURI); + ODataEntity getODataEntity(ResWrap resource); @Override - ODataEntity getODataEntity(Entry resource); - - @Override - ODataEntity getODataEntity(Entry resource, URI defaultBaseURI); - - @Override - ODataProperty getODataProperty(Property property); + ODataProperty getODataProperty(ResWrap resource); /** * Gets ODataLinkCollection from the given link collection resource. diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataDeserializer.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataDeserializer.java index bc16b74c4..ff559a1d7 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataDeserializer.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataDeserializer.java @@ -20,7 +20,7 @@ package org.apache.olingo.client.api.op.v3; import java.io.InputStream; import org.apache.olingo.client.api.op.ClientODataDeserializer; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.v3.LinkCollection; import org.apache.olingo.commons.api.format.ODataFormat; @@ -33,6 +33,6 @@ public interface ODataDeserializer extends ClientODataDeserializer { * @param format OData format. * @return de-serialized links. */ - Container toLinkCollection(InputStream input, ODataFormat format); + ResWrap toLinkCollection(InputStream input, ODataFormat format); } diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v4/ODataBinder.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v4/ODataBinder.java index d2805bb32..9c84a8c2c 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v4/ODataBinder.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v4/ODataBinder.java @@ -18,11 +18,11 @@ */ package org.apache.olingo.client.api.op.v4; -import java.net.URI; import org.apache.olingo.client.api.op.CommonODataBinder; import org.apache.olingo.commons.api.data.Entry; import org.apache.olingo.commons.api.data.Feed; import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.domain.v4.ODataEntity; import org.apache.olingo.commons.api.domain.v4.ODataEntitySet; import org.apache.olingo.commons.api.domain.v4.ODataProperty; @@ -30,19 +30,11 @@ import org.apache.olingo.commons.api.domain.v4.ODataProperty; public interface ODataBinder extends CommonODataBinder { @Override - ODataEntitySet getODataEntitySet(Feed resource); + ODataEntitySet getODataEntitySet(ResWrap resource); @Override - ODataEntitySet getODataEntitySet(Feed resource, URI defaultBaseURI); + ODataEntity getODataEntity(ResWrap resource); @Override - ODataEntity getODataEntity(Entry resource); - - @Override - ODataEntity getODataEntity(Entry resource, URI defaultBaseURI); - - @Override - ODataProperty getODataProperty(Property property); - - ODataProperty getODataProperty(Property property, URI base); + ODataProperty getODataProperty(ResWrap resource); } diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/v3/XMLUtilities.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/v3/EdmEnabledODataClient.java similarity index 74% rename from fit/src/main/java/org/apache/olingo/fit/utils/v3/XMLUtilities.java rename to lib/client-api/src/main/java/org/apache/olingo/client/api/v3/EdmEnabledODataClient.java index 2eb098329..379c8b0f5 100644 --- a/fit/src/main/java/org/apache/olingo/fit/utils/v3/XMLUtilities.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/v3/EdmEnabledODataClient.java @@ -16,13 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.fit.utils.v3; +package org.apache.olingo.client.api.v3; -import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; +import org.apache.olingo.client.api.CommonEdmEnabledODataClient; +import org.apache.olingo.client.api.communication.request.cud.v3.UpdateType; -public class XMLUtilities extends org.apache.olingo.fit.utils.AbstractXMLUtilities { +public interface EdmEnabledODataClient extends CommonEdmEnabledODataClient, ODataClient { - public XMLUtilities() throws Exception { - super(ODataServiceVersion.V30); - } } diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/v4/JSONUtilities.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/v4/EdmEnabledODataClient.java similarity index 74% rename from fit/src/main/java/org/apache/olingo/fit/utils/v4/JSONUtilities.java rename to lib/client-api/src/main/java/org/apache/olingo/client/api/v4/EdmEnabledODataClient.java index 9b2d60743..abd341d8e 100644 --- a/fit/src/main/java/org/apache/olingo/fit/utils/v4/JSONUtilities.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/v4/EdmEnabledODataClient.java @@ -16,13 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.fit.utils.v4; +package org.apache.olingo.client.api.v4; -import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; +import org.apache.olingo.client.api.CommonEdmEnabledODataClient; +import org.apache.olingo.client.api.communication.request.cud.v4.UpdateType; -public class JSONUtilities extends org.apache.olingo.fit.utils.AbstractJSONUtilities { +public interface EdmEnabledODataClient extends CommonEdmEnabledODataClient, ODataClient { - public JSONUtilities() throws Exception { - super(ODataServiceVersion.V40); - } } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataClientFactory.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataClientFactory.java index e0fcd76c5..a9c87ed75 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataClientFactory.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataClientFactory.java @@ -18,16 +18,32 @@ */ package org.apache.olingo.client.core; +import org.apache.olingo.commons.api.format.ODataPubFormat; + public final class ODataClientFactory { public static org.apache.olingo.client.api.v3.ODataClient getV3() { return new org.apache.olingo.client.core.v3.ODataClientImpl(); } + public static org.apache.olingo.client.api.v3.EdmEnabledODataClient getEdmEnabledV3(final String serviceRoot) { + final org.apache.olingo.client.api.v3.EdmEnabledODataClient instance = + new org.apache.olingo.client.core.v3.EdmEnabledODataClientImpl(serviceRoot); + instance.getConfiguration().setDefaultPubFormat(ODataPubFormat.JSON); + return instance; + } + public static org.apache.olingo.client.api.v4.ODataClient getV4() { return new org.apache.olingo.client.core.v4.ODataClientImpl(); } + public static org.apache.olingo.client.api.v4.EdmEnabledODataClient getEdmEnabledV4(final String serviceRoot) { + final org.apache.olingo.client.api.v4.EdmEnabledODataClient instance = + new org.apache.olingo.client.core.v4.EdmEnabledODataClientImpl(serviceRoot); + instance.getConfiguration().setDefaultPubFormat(ODataPubFormat.JSON); + return instance; + } + private ODataClientFactory() { // empty constructory for static utility class } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataRequest.java index 8bc4d1c01..c8185d4cc 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataRequest.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataRequest.java @@ -364,6 +364,8 @@ public abstract class AbstractODataRequest extends AbstractReq * @return HttpReponse object. */ protected HttpResponse doExecute() { + checkRequest(odataClient, request); + // Set Content-Type and Accept headers with default values, if not yet set if (StringUtils.isBlank(odataHeaders.getHeader(HeaderName.contentType))) { setContentType(getContentType()); @@ -390,7 +392,7 @@ public abstract class AbstractODataRequest extends AbstractReq } } - final HttpResponse response; + HttpResponse response; try { response = this.httpClient.execute(this.request); } catch (IOException e) { @@ -400,7 +402,7 @@ public abstract class AbstractODataRequest extends AbstractReq throw new HttpClientException(e); } - checkForResponse(odataClient, response, getAccept()); + checkResponse(odataClient, response, getAccept()); return response; } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java index 25514b870..5779e088e 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java @@ -18,6 +18,8 @@ package org.apache.olingo.client.core.communication.request; import java.io.IOException; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.olingo.client.api.CommonEdmEnabledODataClient; import org.apache.olingo.client.api.CommonODataClient; import org.apache.olingo.client.api.communication.ODataClientErrorException; import org.apache.olingo.client.api.communication.ODataServerErrorException; @@ -50,8 +52,21 @@ public abstract class AbstractRequest { return error; } - protected > void checkForResponse( - final C odataClient, final HttpResponse response, final String accept) { + protected void checkRequest(final CommonODataClient odataClient, final HttpUriRequest request) { + // If using and Edm enabled client, checks that the cached service root matches the request URI + if (odataClient instanceof CommonEdmEnabledODataClient + && !request.getURI().toASCIIString().startsWith( + ((CommonEdmEnabledODataClient) odataClient).getServiceRoot())) { + + throw new IllegalArgumentException( + String.format("The current request URI %s does not match the configured service root %s", + request.getURI().toASCIIString(), + ((CommonEdmEnabledODataClient) odataClient).getServiceRoot())); + } + } + + protected void checkResponse( + final CommonODataClient odataClient, final HttpResponse response, final String accept) { if (response.getStatusLine().getStatusCode() >= 500) { throw new ODataServerErrorException(response.getStatusLine()); diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java index 7f9ad36e9..19ed949af 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java @@ -33,7 +33,7 @@ import org.apache.olingo.client.api.http.HttpMethod; import org.apache.olingo.client.core.uri.URIUtils; import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest; import org.apache.olingo.client.core.communication.response.AbstractODataResponse; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.Entry; /** @@ -119,10 +119,10 @@ public class ODataEntityCreateRequestImpl public E getBody() { if (entity == null) { try { - final Container container = odataClient.getDeserializer().toEntry(getRawResponse(), - ODataPubFormat.fromString(getAccept())); - - entity = (E) odataClient.getBinder().getODataEntity(extractFromContainer(container)); + final ResWrap resource = odataClient.getDeserializer(). + toEntry(getRawResponse(), ODataPubFormat.fromString(getAccept())); + + entity = (E) odataClient.getBinder().getODataEntity(resource); } finally { this.close(); } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java index 67be0d437..1134d7920 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java @@ -33,7 +33,7 @@ import org.apache.olingo.client.api.http.HttpMethod; import org.apache.olingo.client.core.uri.URIUtils; import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest; import org.apache.olingo.client.core.communication.response.AbstractODataResponse; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.Entry; /** @@ -124,10 +124,10 @@ public class ODataEntityUpdateRequestImpl public E getBody() { if (entity == null) { try { - final Container container = odataClient.getDeserializer().toEntry(getRawResponse(), - ODataPubFormat.fromString(getAccept())); + final ResWrap resource = odataClient.getDeserializer(). + toEntry(getRawResponse(), ODataPubFormat.fromString(getAccept())); - entity = (E) odataClient.getBinder().getODataEntity(extractFromContainer(container)); + entity = (E) odataClient.getBinder().getODataEntity(resource); } finally { this.close(); } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java index 26250dc20..81e1dd4b8 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java @@ -33,7 +33,7 @@ import org.apache.olingo.client.api.http.HttpMethod; import org.apache.olingo.client.core.uri.URIUtils; import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest; import org.apache.olingo.client.core.communication.response.AbstractODataResponse; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.Property; /** @@ -118,10 +118,10 @@ public class ODataPropertyUpdateRequestImpl extends AbstractODataBasicRequest container = odataClient.getDeserializer().toProperty(getRawResponse(), - ODataFormat.fromString(getAccept())); + final ResWrap resource = odataClient.getDeserializer(). + toProperty(getRawResponse(), ODataFormat.fromString(getAccept())); - property = odataClient.getBinder().getODataProperty(extractFromContainer(container)); + property = odataClient.getBinder().getODataProperty(resource); } finally { this.close(); } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/EdmMetadataRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/EdmMetadataRequestImpl.java index 00f9cb4b6..37a422062 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/EdmMetadataRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/EdmMetadataRequestImpl.java @@ -39,7 +39,7 @@ class EdmMetadataRequestImpl extends AbstractMetadataRequestImpl implements * @param odataClient client instance getting this request * @param uri metadata URI. */ - EdmMetadataRequestImpl(final CommonODataClient odataClient, final String serviceRoot, final URI uri) { + EdmMetadataRequestImpl(final CommonODataClient odataClient, final String serviceRoot, final URI uri) { super(odataClient, uri); this.serviceRoot = serviceRoot; } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntityRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntityRequestImpl.java index 3c01148e6..c51bcdcb4 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntityRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntityRequestImpl.java @@ -24,7 +24,7 @@ import org.apache.http.client.HttpClient; import org.apache.olingo.client.api.CommonODataClient; import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.Entry; import org.apache.olingo.commons.api.domain.CommonODataEntity; import org.apache.olingo.commons.api.format.ODataPubFormat; @@ -81,10 +81,10 @@ public class ODataEntityRequestImpl public E getBody() { if (entity == null) { try { - final Container container = - odataClient.getDeserializer().toEntry(getRawResponse(), ODataPubFormat.fromString(getContentType())); + final ResWrap resource = odataClient.getDeserializer(). + toEntry(getRawResponse(), ODataPubFormat.fromString(getContentType())); - entity = (E) odataClient.getBinder().getODataEntity(extractFromContainer(container)); + entity = (E) odataClient.getBinder().getODataEntity(resource); } finally { this.close(); } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntitySetRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntitySetRequestImpl.java index 0fc236a90..a14b4a8a4 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntitySetRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntitySetRequestImpl.java @@ -24,7 +24,7 @@ import org.apache.http.client.HttpClient; import org.apache.olingo.client.api.CommonODataClient; import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.Feed; import org.apache.olingo.commons.api.domain.CommonODataEntitySet; import org.apache.olingo.commons.api.format.ODataPubFormat; @@ -90,10 +90,10 @@ public class ODataEntitySetRequestImpl public ES getBody() { if (entitySet == null) { try { - final Container container = - odataClient.getDeserializer().toFeed(getRawResponse(), ODataPubFormat.fromString(getContentType())); + final ResWrap resource = odataClient.getDeserializer(). + toFeed(getRawResponse(), ODataPubFormat.fromString(getContentType())); - entitySet = (ES) odataClient.getBinder().getODataEntitySet(extractFromContainer(container)); + entitySet = (ES) odataClient.getBinder().getODataEntitySet(resource); } finally { this.close(); } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataPropertyRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataPropertyRequestImpl.java index fb385e2d5..d97e7b3a3 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataPropertyRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataPropertyRequestImpl.java @@ -28,7 +28,7 @@ import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse import org.apache.olingo.commons.api.domain.CommonODataProperty; import org.apache.olingo.commons.api.format.ODataFormat; import org.apache.olingo.client.api.http.HttpClientException; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.Property; /** @@ -86,11 +86,10 @@ public class ODataPropertyRequestImpl public T getBody() { if (property == null) { try { - final Container container = - odataClient.getDeserializer().toProperty( + final ResWrap resource = odataClient.getDeserializer().toProperty( res.getEntity().getContent(), ODataFormat.fromString(getContentType())); - property = (T) odataClient.getBinder().getODataProperty(extractFromContainer(container)); + property = (T) odataClient.getBinder().getODataProperty(resource); } catch (IOException e) { throw new HttpClientException(e); } finally { diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java index c7e53b225..003a01324 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java @@ -31,7 +31,7 @@ import org.apache.olingo.commons.api.format.ODataPubFormat; import org.apache.olingo.client.api.http.HttpMethod; import org.apache.olingo.client.core.communication.request.AbstractODataRequest; import org.apache.olingo.client.core.communication.response.AbstractODataResponse; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; /** * This class implements a generic OData request. @@ -83,7 +83,7 @@ public class ODataRawRequestImpl extends AbstractODataRequest } @Override - public T getBodyAs(final Class reference) { + public ResWrap getBodyAs(final Class reference) { if (obj == null) { try { this.obj = IOUtils.toByteArray(getRawResponse()); @@ -94,10 +94,8 @@ public class ODataRawRequestImpl extends AbstractODataRequest } } - final Container container = - odataClient.getReader().read(new ByteArrayInputStream(obj), getContentType(), reference); - - return extractFromContainer(container); + return odataClient.getReader(). + read(new ByteArrayInputStream(obj), getContentType(), reference); } } } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataServiceDocumentRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataServiceDocumentRequestImpl.java index 2b9f347ae..2222c0d64 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataServiceDocumentRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataServiceDocumentRequestImpl.java @@ -25,7 +25,7 @@ import org.apache.olingo.client.api.CommonODataClient; import org.apache.olingo.client.api.communication.request.retrieve.ODataServiceDocumentRequest; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; import org.apache.olingo.client.api.data.ServiceDocument; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.domain.ODataServiceDocument; import org.apache.olingo.commons.api.format.ODataFormat; @@ -83,10 +83,10 @@ public class ODataServiceDocumentRequestImpl extends AbstractODataRetrieveReques public ODataServiceDocument getBody() { if (serviceDocument == null) { try { - final Container container = odataClient.getDeserializer().toServiceDocument( - getRawResponse(), ODataFormat.fromString(getContentType())); + final ResWrap resource = odataClient.getDeserializer(). + toServiceDocument(getRawResponse(), ODataFormat.fromString(getContentType())); - serviceDocument = odataClient.getBinder().getODataServiceDocument(extractFromContainer(container)); + serviceDocument = odataClient.getBinder().getODataServiceDocument(resource.getPayload()); } finally { this.close(); } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityCreateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityCreateRequestImpl.java index 188891c21..0eb503743 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityCreateRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityCreateRequestImpl.java @@ -31,7 +31,7 @@ import org.apache.olingo.commons.api.domain.CommonODataEntity; import org.apache.olingo.client.api.http.HttpMethod; import org.apache.olingo.client.core.communication.request.AbstractODataStreamManager; import org.apache.olingo.client.core.communication.response.AbstractODataResponse; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.Entry; /** @@ -123,8 +123,9 @@ public class ODataMediaEntityCreateRequestImpl public E getBody() { if (entity == null) { try { - final Container container = odataClient.getDeserializer().toEntry(getRawResponse(), getFormat()); - entity = (E) odataClient.getBinder().getODataEntity(extractFromContainer(container)); + final ResWrap resource = odataClient.getDeserializer().toEntry(getRawResponse(), getFormat()); + + entity = (E) odataClient.getBinder().getODataEntity(resource); } finally { this.close(); } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityUpdateRequestImpl.java index bb8ef6407..476fb8dd0 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityUpdateRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityUpdateRequestImpl.java @@ -31,7 +31,7 @@ import org.apache.olingo.commons.api.domain.CommonODataEntity; import org.apache.olingo.client.api.http.HttpMethod; import org.apache.olingo.client.core.communication.request.AbstractODataStreamManager; import org.apache.olingo.client.core.communication.response.AbstractODataResponse; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.Entry; /** @@ -122,8 +122,9 @@ public class ODataMediaEntityUpdateRequestImpl public E getBody() { if (entity == null) { try { - final Container container = odataClient.getDeserializer().toEntry(getRawResponse(), getFormat()); - entity = (E) odataClient.getBinder().getODataEntity(extractFromContainer(container)); + final ResWrap resource = odataClient.getDeserializer().toEntry(getRawResponse(), getFormat()); + + entity = (E) odataClient.getBinder().getODataEntity(resource); } finally { this.close(); } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestWrapperImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestWrapperImpl.java index c9fb23deb..57305cd7a 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestWrapperImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestWrapperImpl.java @@ -49,9 +49,9 @@ import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; public class AsyncRequestWrapperImpl extends AbstractRequest implements AsyncRequestWrapper { - private final ODataClient odataClient; + private static final int MAX_RETRY = 5; - private final static int MAX_RETRY = 5; + private final ODataClient odataClient; /** * Request to be wrapped. @@ -131,7 +131,6 @@ public class AsyncRequestWrapperImpl extends AbstractRe } private HttpResponse doExecute() { - // Add all available headers for (String key : odataRequest.getHeaderNames()) { final String value = odataRequest.getHeader(key); @@ -159,7 +158,6 @@ public class AsyncRequestWrapperImpl extends AbstractRe */ @SuppressWarnings("unchecked") public AsyncResponseWrapperImpl(final HttpResponse res) { - if (res.getStatusLine().getStatusCode() == 202) { retrieveMonitorDetails(res, true); } else { @@ -236,9 +234,7 @@ public class AsyncRequestWrapperImpl extends AbstractRe @SuppressWarnings("unchecked") private R instantiateResponse(final HttpResponse res) { R odataResponse; - try { - odataResponse = (R) ((AbstractODataRequest) odataRequest).getResponseTemplate(). initFromEnclosedPart(res.getEntity().getContent()); @@ -292,7 +288,9 @@ public class AsyncRequestWrapperImpl extends AbstractRe } private HttpResponse executeHttpRequest(final HttpClient client, final HttpUriRequest req) { - final HttpResponse response; + checkRequest(odataClient, request); + + HttpResponse response; try { response = client.execute(req); } catch (IOException e) { @@ -302,7 +300,7 @@ public class AsyncRequestWrapperImpl extends AbstractRe throw new HttpClientException(e); } - checkForResponse(odataClient, response, odataRequest.getAccept()); + checkResponse(odataClient, response, odataRequest.getAccept()); return response; } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/AbstractODataResponse.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/AbstractODataResponse.java index 5564bdf9a..d66fa2045 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/AbstractODataResponse.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/AbstractODataResponse.java @@ -24,7 +24,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; -import java.net.URI; import java.nio.charset.Charset; import java.util.Collection; import java.util.HashSet; @@ -43,7 +42,6 @@ import org.apache.olingo.client.core.communication.request.batch.ODataBatchContr import org.apache.olingo.client.core.communication.request.batch.ODataBatchLineIteratorImpl; import org.apache.olingo.client.core.communication.request.batch.ODataBatchUtilities; import org.apache.olingo.commons.api.Constants; -import org.apache.olingo.commons.api.data.Container; import org.slf4j.LoggerFactory; /** @@ -56,16 +54,6 @@ public abstract class AbstractODataResponse implements ODataResponse { */ protected static final org.slf4j.Logger LOG = LoggerFactory.getLogger(ODataResponse.class); - /** - * Context URL. - */ - private URI contextURL; - - /** - * Metadata ETag. - */ - private String metadataETag; - /** * HTTP client. */ @@ -127,24 +115,6 @@ public abstract class AbstractODataResponse implements ODataResponse { initFromHttpResponse(res); } - @Override - public URI getContextURL() { - return contextURL; - } - - protected void setContextURL(final URI contextURL) { - this.contextURL = contextURL; - } - - @Override - public String getMetadataETag() { - return metadataETag; - } - - protected void setMetadataETag(final String metadataETag) { - this.metadataETag = metadataETag; - } - /** * {@inheritDoc} */ @@ -173,7 +143,7 @@ public abstract class AbstractODataResponse implements ODataResponse { * {@inheritDoc} */ @Override - public String getEtag() { + public String getETag() { final Collection etag = getHeader(HeaderName.etag); return etag == null || etag.isEmpty() ? null @@ -361,14 +331,4 @@ public abstract class AbstractODataResponse implements ODataResponse { return payload; } - - protected T extractFromContainer(final Container container) { - if (container == null) { - return null; - } - - setContextURL(container.getContextURL()); - setMetadataETag(container.getMetadataETag()); - return container.getObject(); - } } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/batch/ODataBatchErrorResponse.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/batch/ODataBatchErrorResponse.java index d2dd8843b..fa41b8226 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/batch/ODataBatchErrorResponse.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/batch/ODataBatchErrorResponse.java @@ -18,7 +18,6 @@ */ package org.apache.olingo.client.core.communication.response.batch; -import java.net.URI; import java.util.Collection; import java.util.Map; import org.apache.olingo.client.api.communication.request.batch.ODataBatchLineIterator; @@ -55,17 +54,7 @@ public class ODataBatchErrorResponse extends AbstractODataResponse { } @Override - public String getEtag() { - return null; - } - - @Override - public URI getContextURL() { - return null; - } - - @Override - public String getMetadataETag() { + public String getETag() { return null; } } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONServiceDocumentDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONServiceDocumentDeserializer.java index 7cff5395e..c7b62f410 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONServiceDocumentDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONServiceDocumentDeserializer.java @@ -30,14 +30,14 @@ import java.util.Iterator; import org.apache.commons.lang3.StringUtils; import org.apache.olingo.commons.api.Constants; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.commons.core.data.ODataJacksonDeserializer; -public class JSONServiceDocumentDeserializer extends ODataJacksonDeserializer> { +public class JSONServiceDocumentDeserializer extends ODataJacksonDeserializer> { @Override - protected Container doDeserialize( + protected ResWrap doDeserialize( final JsonParser parser, final DeserializationContext ctxt) throws IOException, JsonProcessingException { @@ -90,6 +90,6 @@ public class JSONServiceDocumentDeserializer extends ODataJacksonDeserializer(contextURL, metadataETag, serviceDocument); + return new ResWrap(contextURL, metadataETag, serviceDocument); } } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/XMLServiceDocumentDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/XMLServiceDocumentDeserializer.java index 1b1804048..8edf2e7d9 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/XMLServiceDocumentDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/XMLServiceDocumentDeserializer.java @@ -30,10 +30,10 @@ import java.net.URI; import org.apache.olingo.client.api.data.ServiceDocument; import org.apache.olingo.client.core.uri.URIUtils; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; -public class XMLServiceDocumentDeserializer extends ODataJacksonDeserializer> { +public class XMLServiceDocumentDeserializer extends ODataJacksonDeserializer> { private String getTitle(final JsonParser jp) throws IOException { String title = jp.nextTextValue(); @@ -69,7 +69,7 @@ public class XMLServiceDocumentDeserializer extends ODataJacksonDeserializer doDeserialize(final JsonParser jp, final DeserializationContext ctxt) + protected ResWrap doDeserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException { final AbstractServiceDocument sdoc = ODataServiceVersion.V30 == version @@ -117,7 +117,7 @@ public class XMLServiceDocumentDeserializer extends ODataJacksonDeserializer( + return new ResWrap( contextURL == null ? null : URIUtils.getURI(sdoc.getBaseURI(), contextURL), metadataETag, sdoc); } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmClientImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmClientImpl.java index 1e16adb2e..58e896350 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmClientImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmClientImpl.java @@ -154,9 +154,11 @@ public class EdmClientImpl extends AbstractEdm { EdmEntityType result = null; final Schema schema = xmlSchemaByNamespace.get(entityTypeName.getNamespace()); - final EntityType xmlEntityType = schema.getEntityType(entityTypeName.getName()); - if (xmlEntityType != null) { - result = EdmEntityTypeImpl.getInstance(this, entityTypeName, xmlEntityType); + if (schema != null) { + final EntityType xmlEntityType = schema.getEntityType(entityTypeName.getName()); + if (xmlEntityType != null) { + result = EdmEntityTypeImpl.getInstance(this, entityTypeName, xmlEntityType); + } } return result; @@ -167,9 +169,11 @@ public class EdmClientImpl extends AbstractEdm { EdmComplexType result = null; final Schema schema = xmlSchemaByNamespace.get(complexTypeName.getNamespace()); - final ComplexType xmlComplexType = schema.getComplexType(complexTypeName.getName()); - if (xmlComplexType != null) { - result = EdmComplexTypeImpl.getInstance(this, complexTypeName, xmlComplexType); + if (schema != null) { + final ComplexType xmlComplexType = schema.getComplexType(complexTypeName.getName()); + if (xmlComplexType != null) { + result = EdmComplexTypeImpl.getInstance(this, complexTypeName, xmlComplexType); + } } return result; diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmNavigationPropertyImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmNavigationPropertyImpl.java index c2a38c472..6ea464b53 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmNavigationPropertyImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmNavigationPropertyImpl.java @@ -35,6 +35,7 @@ public class EdmNavigationPropertyImpl extends AbstractEdmNavigationProperty { private final NavigationProperty navigationProperty; private final EdmTypeInfo edmTypeInfo; + private List referentialConstraints; public EdmNavigationPropertyImpl(final Edm edm, final NavigationProperty navigationProperty) { @@ -63,6 +64,11 @@ public class EdmNavigationPropertyImpl extends AbstractEdmNavigationProperty { return navigationProperty.isNullable(); } + @Override + public Boolean containsTarget() { + return navigationProperty.isContainsTarget(); + } + @Override public String getReferencingPropertyName(final String referencedPropertyName) { final List referentialConstraints = navigationProperty.getReferentialConstraints(); @@ -84,7 +90,7 @@ public class EdmNavigationPropertyImpl extends AbstractEdmNavigationProperty { if (providerConstraints != null) { for (ReferentialConstraint constraint : providerConstraints) { referentialConstraints.add(new EdmReferentialConstraintImpl(constraint.getProperty(), constraint - .getReferencedProperty())); + .getReferencedProperty())); } } } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java index 5b74502d2..95efa7cf8 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java @@ -21,34 +21,45 @@ package org.apache.olingo.client.core.op; import java.io.StringWriter; import java.net.URI; import java.util.Iterator; -import java.util.List; import org.apache.commons.lang3.StringUtils; import org.apache.olingo.client.api.CommonODataClient; import org.apache.olingo.client.api.data.ServiceDocument; import org.apache.olingo.client.api.data.ServiceDocumentItem; import org.apache.olingo.client.api.op.CommonODataBinder; +import org.apache.olingo.client.api.v4.EdmEnabledODataClient; import org.apache.olingo.client.core.uri.URIUtils; import org.apache.olingo.commons.api.Constants; +import org.apache.olingo.commons.api.data.ContextURL; import org.apache.olingo.commons.api.data.Entry; import org.apache.olingo.commons.api.data.Feed; import org.apache.olingo.commons.api.data.Link; import org.apache.olingo.commons.api.data.Linked; import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.Value; -import org.apache.olingo.commons.api.domain.ODataCollectionValue; -import org.apache.olingo.commons.api.domain.ODataComplexValue; import org.apache.olingo.commons.api.domain.CommonODataEntity; import org.apache.olingo.commons.api.domain.CommonODataEntitySet; +import org.apache.olingo.commons.api.domain.CommonODataProperty; +import org.apache.olingo.commons.api.domain.ODataCollectionValue; +import org.apache.olingo.commons.api.domain.ODataComplexValue; import org.apache.olingo.commons.api.domain.ODataInlineEntity; import org.apache.olingo.commons.api.domain.ODataInlineEntitySet; import org.apache.olingo.commons.api.domain.ODataLink; -import org.apache.olingo.commons.api.domain.ODataOperation; -import org.apache.olingo.commons.api.domain.CommonODataProperty; import org.apache.olingo.commons.api.domain.ODataLinkType; import org.apache.olingo.commons.api.domain.ODataLinked; +import org.apache.olingo.commons.api.domain.ODataOperation; import org.apache.olingo.commons.api.domain.ODataServiceDocument; import org.apache.olingo.commons.api.domain.ODataValue; +import org.apache.olingo.commons.api.edm.Edm; +import org.apache.olingo.commons.api.edm.EdmBindingTarget; +import org.apache.olingo.commons.api.edm.EdmEntityContainer; +import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.apache.olingo.commons.api.edm.EdmNavigationProperty; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; +import org.apache.olingo.commons.api.edm.EdmProperty; +import org.apache.olingo.commons.api.edm.EdmSchema; +import org.apache.olingo.commons.api.edm.EdmStructuredType; +import org.apache.olingo.commons.api.edm.EdmType; import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.edm.geo.Geospatial; import org.apache.olingo.commons.api.format.ODataPubFormat; @@ -73,9 +84,9 @@ public abstract class AbstractODataBinder implements CommonODataBinder { */ protected final Logger LOG = LoggerFactory.getLogger(AbstractODataBinder.class); - protected final CommonODataClient client; + protected final CommonODataClient client; - protected AbstractODataBinder(final CommonODataClient client) { + protected AbstractODataBinder(final CommonODataClient client) { this.client = client; } @@ -241,55 +252,61 @@ public abstract class AbstractODataBinder implements CommonODataBinder { return valueResource; } - @Override - public CommonODataEntitySet getODataEntitySet(final Feed resource) { - return getODataEntitySet(resource, null); - } - protected abstract boolean add(CommonODataEntitySet entitySet, CommonODataEntity entity); @Override - public CommonODataEntitySet getODataEntitySet(final Feed resource, final URI defaultBaseURI) { + public CommonODataEntitySet getODataEntitySet(final ResWrap resource) { if (LOG.isDebugEnabled()) { final StringWriter writer = new StringWriter(); - client.getSerializer().feed(resource, writer); + client.getSerializer().feed(resource.getPayload(), writer); writer.flush(); LOG.debug("Feed -> ODataEntitySet:\n{}", writer.toString()); } - final URI base = defaultBaseURI == null ? resource.getBaseURI() : defaultBaseURI; + final URI base = resource.getContextURL() == null + ? resource.getPayload().getBaseURI() : resource.getContextURL().getServiceRoot(); - final URI next = resource.getNext(); + final URI next = resource.getPayload().getNext(); final CommonODataEntitySet entitySet = next == null ? client.getObjectFactory().newEntitySet() : client.getObjectFactory().newEntitySet(URIUtils.getURI(base, next.toASCIIString())); - if (resource.getCount() != null) { - entitySet.setCount(resource.getCount()); + if (resource.getPayload().getCount() != null) { + entitySet.setCount(resource.getPayload().getCount()); } - for (Entry entryResource : resource.getEntries()) { - add(entitySet, getODataEntity(entryResource)); + for (Entry entryResource : resource.getPayload().getEntries()) { + add(entitySet, getODataEntity( + new ResWrap(resource.getContextURL(), resource.getMetadataETag(), entryResource))); } return entitySet; } - @Override - public CommonODataEntity getODataEntity(final Entry resource) { - return getODataEntity(resource, null); - } + protected void odataNavigationLinks(final EdmStructuredType edmType, + final Linked linked, final ODataLinked odataLinked, final String metadataETag, final URI base) { - protected void odataLinks(final Linked linked, final ODataLinked odataLinked, final URI base) { for (Link link : linked.getNavigationLinks()) { final Entry inlineEntry = link.getInlineEntry(); final Feed inlineFeed = link.getInlineFeed(); if (inlineEntry == null && inlineFeed == null) { - final ODataLinkType linkType = link.getType() == null - ? ODataLinkType.ENTITY_NAVIGATION - : ODataLinkType.fromString(client.getServiceVersion(), link.getRel(), link.getType()); + ODataLinkType linkType = null; + if (edmType != null) { + final EdmNavigationProperty navProp = edmType.getNavigationProperty(link.getTitle()); + if (navProp != null) { + linkType = navProp.isCollection() + ? ODataLinkType.ENTITY_SET_NAVIGATION + : ODataLinkType.ENTITY_NAVIGATION; + } + } + if (linkType == null) { + linkType = link.getType() == null + ? ODataLinkType.ENTITY_NAVIGATION + : ODataLinkType.fromString(client.getServiceVersion(), link.getRel(), link.getType()); + } + odataLinked.addLink(linkType == ODataLinkType.ENTITY_NAVIGATION ? client.getObjectFactory(). newEntityNavigationLink(link.getTitle(), URIUtils.getURI(base, link.getHref())) @@ -298,114 +315,193 @@ public abstract class AbstractODataBinder implements CommonODataBinder { } else if (inlineEntry != null) { odataLinked.addLink(new ODataInlineEntity(client.getServiceVersion(), URIUtils.getURI(base, link.getHref()), ODataLinkType.ENTITY_NAVIGATION, link.getTitle(), - getODataEntity(inlineEntry, - inlineEntry.getBaseURI() == null ? base : inlineEntry.getBaseURI()))); + getODataEntity(new ResWrap( + inlineEntry.getBaseURI() == null ? base : inlineEntry.getBaseURI(), + metadataETag, + inlineEntry)))); } else { odataLinked.addLink(new ODataInlineEntitySet(client.getServiceVersion(), URIUtils.getURI(base, link.getHref()), ODataLinkType.ENTITY_SET_NAVIGATION, link.getTitle(), - getODataEntitySet(inlineFeed, - inlineFeed.getBaseURI() == null ? base : inlineFeed.getBaseURI()))); + getODataEntitySet(new ResWrap( + inlineFeed.getBaseURI() == null ? base : inlineFeed.getBaseURI(), + metadataETag, + inlineFeed)))); } } } - protected abstract void copyProperties(List src, CommonODataEntity dst, final URI base); + /** + * Infer type name from various sources of information including Edm and context URL, if available. + * + * @param contextURL context URL + * @param metadataETag metadata ETag + * @return Edm type information + */ + private EdmEntityType findEntityType(final ContextURL contextURL, final String metadataETag) { + EdmEntityType entityType = null; + + if (client instanceof EdmEnabledODataClient && contextURL != null) { + final Edm edm = ((EdmEnabledODataClient) client).getEdm(metadataETag); + + if (contextURL.getDerivedEntity() == null) { + for (EdmSchema schema : edm.getSchemas()) { + final EdmEntityContainer container = schema.getEntityContainer(); + + EdmBindingTarget bindingTarget = + container.getEntitySet(contextURL.getEntitySetOrSingletonOrType()); + if (bindingTarget == null) { + bindingTarget = container.getSingleton(contextURL.getEntitySetOrSingletonOrType()); + } + if (bindingTarget != null) { + if (contextURL.getNavOrPropertyPath() == null) { + entityType = bindingTarget.getEntityType(); + } else { + final EdmNavigationProperty navProp = bindingTarget.getEntityType(). + getNavigationProperty(contextURL.getNavOrPropertyPath()); + + entityType = navProp == null + ? bindingTarget.getEntityType() + : navProp.getType(); + } + } + } + } else { + entityType = edm.getEntityType(new FullQualifiedName(contextURL.getDerivedEntity())); + } + } + + return entityType; + } @Override - public CommonODataEntity getODataEntity(final Entry resource, final URI defaultBaseURI) { + public CommonODataEntity getODataEntity(final ResWrap resource) { if (LOG.isDebugEnabled()) { final StringWriter writer = new StringWriter(); - client.getSerializer().entry(resource, writer); + client.getSerializer().entry(resource.getPayload(), writer); writer.flush(); LOG.debug("EntryResource -> ODataEntity:\n{}", writer.toString()); } - final URI base = defaultBaseURI == null ? resource.getBaseURI() : defaultBaseURI; + final URI base = resource.getContextURL() == null + ? resource.getPayload().getBaseURI() : resource.getContextURL().getServiceRoot(); - final FullQualifiedName entityTypeName = resource.getType() == null - ? null - : new FullQualifiedName(resource.getType()); - final CommonODataEntity entity = resource.getSelfLink() == null - ? client.getObjectFactory().newEntity(entityTypeName) - : client.getObjectFactory().newEntity(entityTypeName, - URIUtils.getURI(base, resource.getSelfLink().getHref())); - - if (StringUtils.isNotBlank(resource.getETag())) { - entity.setETag(resource.getETag()); + final EdmEntityType edmType = findEntityType(resource.getContextURL(), resource.getMetadataETag()); + FullQualifiedName typeName = null; + if (resource.getPayload().getType() == null) { + if (edmType != null) { + typeName = edmType.getFullQualifiedName(); + } + } else { + typeName = new FullQualifiedName(resource.getPayload().getType()); } - if (resource.getEditLink() != null) { - entity.setEditLink(URIUtils.getURI(base, resource.getEditLink().getHref())); + final CommonODataEntity entity = resource.getPayload().getSelfLink() == null + ? client.getObjectFactory().newEntity(typeName) + : client.getObjectFactory().newEntity(typeName, + URIUtils.getURI(base, resource.getPayload().getSelfLink().getHref())); + + if (StringUtils.isNotBlank(resource.getPayload().getETag())) { + entity.setETag(resource.getPayload().getETag()); } - for (Link link : resource.getAssociationLinks()) { + if (resource.getPayload().getEditLink() != null) { + entity.setEditLink(URIUtils.getURI(base, resource.getPayload().getEditLink().getHref())); + } + + for (Link link : resource.getPayload().getAssociationLinks()) { entity.addLink(new ODataLink.Builder().setVersion(client.getServiceVersion()). setURI(URIUtils.getURI(base, link.getHref())). setType(ODataLinkType.ASSOCIATION).setTitle(link.getTitle()).build()); } - odataLinks(resource, entity, base); + odataNavigationLinks( + edmType, resource.getPayload(), entity, resource.getMetadataETag(), base); - for (Link link : resource.getMediaEditLinks()) { + for (Link link : resource.getPayload().getMediaEditLinks()) { entity.addLink(new ODataLink.Builder().setVersion(client.getServiceVersion()). setURI(URIUtils.getURI(base, link.getHref())). setType(ODataLinkType.MEDIA_EDIT).setTitle(link.getTitle()).build()); } - for (ODataOperation operation : resource.getOperations()) { + for (ODataOperation operation : resource.getPayload().getOperations()) { operation.setTarget(URIUtils.getURI(base, operation.getTarget())); entity.getOperations().add(operation); } - if (resource.isMediaEntry()) { + if (resource.getPayload().isMediaEntry()) { entity.setMediaEntity(true); - entity.setMediaContentSource(resource.getMediaContentSource()); - entity.setMediaContentType(resource.getMediaContentType()); - entity.setMediaETag(resource.getMediaETag()); + entity.setMediaContentSource(resource.getPayload().getMediaContentSource()); + entity.setMediaContentType(resource.getPayload().getMediaContentType()); + entity.setMediaETag(resource.getPayload().getMediaETag()); } - copyProperties(resource.getProperties(), entity, base); + for (Property property : resource.getPayload().getProperties()) { + add(entity, getODataProperty( + new ResWrap(resource.getContextURL(), resource.getMetadataETag(), property))); + } return entity; } - protected ODataValue getODataValue(final Property resource, final URI base) { - ODataValue value = null; + protected EdmTypeInfo buildTypeInfo(final ResWrap resource) { + FullQualifiedName typeName = null; + final EdmType entityType = findEntityType(resource.getContextURL(), resource.getMetadataETag()); + if (entityType instanceof EdmStructuredType) { + final EdmProperty edmProperty = ((EdmStructuredType) entityType). + getStructuralProperty(resource.getPayload().getName()); + if (edmProperty != null) { + typeName = edmProperty.getType().getFullQualifiedName(); + } + } - final EdmTypeInfo typeInfo = resource.getType() == null - ? null - : new EdmTypeInfo.Builder().setTypeExpression(resource.getType()).build(); - if (resource.getValue().isPrimitive()) { + EdmTypeInfo typeInfo = null; + if (typeName == null) { + if (resource.getPayload().getType() != null) { + typeInfo = new EdmTypeInfo.Builder().setTypeExpression(resource.getPayload().getType()).build(); + } + } else { + typeInfo = new EdmTypeInfo.Builder().setTypeExpression(typeName.toString()).build(); + } + return typeInfo; + } + + protected ODataValue getODataValue(final ResWrap resource) { + final EdmTypeInfo typeInfo = buildTypeInfo(resource); + + ODataValue value = null; + if (resource.getPayload().getValue().isPrimitive()) { value = client.getObjectFactory().newPrimitiveValueBuilder(). - setText(resource.getValue().asPrimitive().get()). + setText(resource.getPayload().getValue().asPrimitive().get()). setType(typeInfo == null ? null : EdmPrimitiveTypeKind.valueOfFQN( client.getServiceVersion(), typeInfo.getFullQualifiedName().toString())).build(); - } else if (resource.getValue().isGeospatial()) { + } else if (resource.getPayload().getValue().isGeospatial()) { value = client.getObjectFactory().newPrimitiveValueBuilder(). - setValue(resource.getValue().asGeospatial().get()). + setValue(resource.getPayload().getValue().asGeospatial().get()). setType(typeInfo == null || EdmPrimitiveTypeKind.Geography.getFullQualifiedName().equals(typeInfo.getFullQualifiedName()) || EdmPrimitiveTypeKind.Geometry.getFullQualifiedName().equals(typeInfo.getFullQualifiedName()) - ? resource.getValue().asGeospatial().get().getEdmPrimitiveTypeKind() + ? resource.getPayload().getValue().asGeospatial().get().getEdmPrimitiveTypeKind() : EdmPrimitiveTypeKind.valueOfFQN( client.getServiceVersion(), typeInfo.getFullQualifiedName().toString())).build(); - } else if (resource.getValue().isComplex()) { + } else if (resource.getPayload().getValue().isComplex()) { value = client.getObjectFactory().newComplexValue(typeInfo == null ? null : typeInfo.getFullQualifiedName().toString()); - for (Property property : resource.getValue().asComplex().get()) { - value.asComplex().add(getODataProperty(property)); + for (Property property : resource.getPayload().getValue().asComplex().get()) { + value.asComplex().add(getODataProperty( + new ResWrap(resource.getContextURL(), resource.getMetadataETag(), property))); } - } else if (resource.getValue().isCollection()) { + } else if (resource.getPayload().getValue().isCollection()) { value = client.getObjectFactory().newCollectionValue(typeInfo == null ? null : "Collection(" + typeInfo.getFullQualifiedName().toString() + ")"); - for (Value _value : resource.getValue().asCollection().get()) { + for (Value _value : resource.getPayload().getValue().asCollection().get()) { final JSONPropertyImpl fake = new JSONPropertyImpl(); fake.setValue(_value); - value.asCollection().add(getODataValue(fake, base)); + value.asCollection().add(getODataValue( + new ResWrap(resource.getContextURL(), resource.getMetadataETag(), fake))); } } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataReader.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataReader.java index b7d29f77c..0df51a5ae 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataReader.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataReader.java @@ -19,6 +19,7 @@ package org.apache.olingo.client.core.op; import java.io.InputStream; +import java.net.URI; import java.util.List; import org.apache.commons.io.IOUtils; import org.apache.olingo.client.api.CommonODataClient; @@ -35,7 +36,7 @@ import org.apache.olingo.commons.api.domain.ODataValue; import org.apache.olingo.client.api.edm.xml.XMLMetadata; import org.apache.olingo.client.api.op.CommonODataReader; import org.apache.olingo.client.core.edm.EdmClientImpl; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.Entry; import org.apache.olingo.commons.api.data.Feed; import org.apache.olingo.commons.api.edm.Edm; @@ -74,7 +75,7 @@ public abstract class AbstractODataReader implements CommonODataReader { @Override public ODataServiceDocument readServiceDocument(final InputStream input, final ODataFormat format) { return client.getBinder().getODataServiceDocument( - client.getDeserializer().toServiceDocument(input, format).getObject()); + client.getDeserializer().toServiceDocument(input, format).getPayload()); } @Override @@ -84,48 +85,60 @@ public abstract class AbstractODataReader implements CommonODataReader { @Override @SuppressWarnings("unchecked") - public Container read(final InputStream src, final String format, final Class reference) { - Container res; + public ResWrap read(final InputStream src, final String format, final Class reference) { + ResWrap res; try { if (ODataEntitySetIterator.class.isAssignableFrom(reference)) { - res = new Container( - null, null, (T) new ODataEntitySetIterator(client, src, ODataPubFormat.fromString(format))); + res = new ResWrap( + (URI) null, + null, + reference.cast(new ODataEntitySetIterator( + client, src, ODataPubFormat.fromString(format)))); } else if (CommonODataEntitySet.class.isAssignableFrom(reference)) { - final Container container = client.getDeserializer().toFeed(src, ODataPubFormat.fromString(format)); - res = new Container( - container.getContextURL(), - container.getMetadataETag(), - (T) client.getBinder().getODataEntitySet(container.getObject())); + final ResWrap resource = client.getDeserializer().toFeed(src, ODataPubFormat.fromString(format)); + res = new ResWrap( + resource.getContextURL(), + resource.getMetadataETag(), + reference.cast(client.getBinder().getODataEntitySet(resource))); } else if (CommonODataEntity.class.isAssignableFrom(reference)) { - final Container container = client.getDeserializer().toEntry(src, ODataPubFormat.fromString(format)); - res = new Container( + final ResWrap container = client.getDeserializer().toEntry(src, ODataPubFormat.fromString(format)); + res = new ResWrap( container.getContextURL(), container.getMetadataETag(), - (T) client.getBinder().getODataEntity(container.getObject())); + reference.cast(client.getBinder().getODataEntity(container))); } else if (CommonODataProperty.class.isAssignableFrom(reference)) { - final Container container = client.getDeserializer().toProperty(src, ODataFormat.fromString(format)); - res = new Container( + final ResWrap container = client.getDeserializer().toProperty(src, ODataFormat.fromString(format)); + res = new ResWrap( container.getContextURL(), container.getMetadataETag(), - (T) client.getBinder().getODataProperty(container.getObject())); + reference.cast(client.getBinder().getODataProperty(container))); } else if (ODataValue.class.isAssignableFrom(reference)) { - res = new Container(null, null, (T) client.getObjectFactory().newPrimitiveValueBuilder(). - setType(ODataValueFormat.fromString(format) == ODataValueFormat.TEXT - ? EdmPrimitiveTypeKind.String : EdmPrimitiveTypeKind.Stream). - setText(IOUtils.toString(src)). - build()); + res = new ResWrap( + (URI) null, + null, + reference.cast(client.getObjectFactory().newPrimitiveValueBuilder(). + setType(ODataValueFormat.fromString(format) == ODataValueFormat.TEXT + ? EdmPrimitiveTypeKind.String : EdmPrimitiveTypeKind.Stream). + setText(IOUtils.toString(src)). + build())); } else if (XMLMetadata.class.isAssignableFrom(reference)) { - res = new Container(null, null, (T) readMetadata(src)); + res = new ResWrap( + (URI) null, + null, + reference.cast(readMetadata(src))); } else if (ODataServiceDocument.class.isAssignableFrom(reference)) { - final Container container = + final ResWrap resource = client.getDeserializer().toServiceDocument(src, ODataFormat.fromString(format)); - res = new Container( - container.getContextURL(), - container.getMetadataETag(), - (T) client.getBinder().getODataServiceDocument(container.getObject())); + res = new ResWrap( + resource.getContextURL(), + resource.getMetadataETag(), + reference.cast(client.getBinder().getODataServiceDocument(resource.getPayload()))); } else if (ODataError.class.isAssignableFrom(reference)) { - res = new Container(null, null, (T) readError(src, !format.toString().contains("json"))); + res = new ResWrap( + (URI) null, + null, + reference.cast(readError(src, !format.toString().contains("json")))); } else { throw new IllegalArgumentException("Invalid reference type " + reference); } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataBinderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataBinderImpl.java index c0ce3f384..75d3eaac8 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataBinderImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataBinderImpl.java @@ -18,9 +18,6 @@ */ package org.apache.olingo.client.core.op.impl.v3; -import java.net.URI; -import java.util.List; -import org.apache.olingo.commons.api.data.v3.LinkCollection; import org.apache.olingo.client.api.domain.v3.ODataLinkCollection; import org.apache.olingo.client.api.op.v3.ODataBinder; import org.apache.olingo.client.core.op.AbstractODataBinder; @@ -28,6 +25,8 @@ import org.apache.olingo.client.core.v3.ODataClientImpl; import org.apache.olingo.commons.api.data.Entry; import org.apache.olingo.commons.api.data.Feed; import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.data.ResWrap; +import org.apache.olingo.commons.api.data.v3.LinkCollection; import org.apache.olingo.commons.api.domain.CommonODataEntity; import org.apache.olingo.commons.api.domain.CommonODataEntitySet; import org.apache.olingo.commons.api.domain.CommonODataProperty; @@ -73,35 +72,18 @@ public class ODataBinderImpl extends AbstractODataBinder implements ODataBinder } @Override - public ODataEntitySet getODataEntitySet(final Feed resource) { + public ODataEntitySet getODataEntitySet(final ResWrap resource) { return (ODataEntitySet) super.getODataEntitySet(resource); } @Override - public ODataEntitySet getODataEntitySet(final Feed resource, final URI defaultBaseURI) { - return (ODataEntitySet) super.getODataEntitySet(resource, defaultBaseURI); - } - - @Override - protected void copyProperties(final List src, final CommonODataEntity dst, final URI base) { - for (Property property : src) { - add(dst, getODataProperty(property)); - } - } - - @Override - public ODataEntity getODataEntity(final Entry resource) { + public ODataEntity getODataEntity(final ResWrap resource) { return (ODataEntity) super.getODataEntity(resource); } @Override - public ODataEntity getODataEntity(final Entry resource, final URI defaultBaseURI) { - return (ODataEntity) super.getODataEntity(resource, defaultBaseURI); - } - - @Override - public ODataProperty getODataProperty(final Property property) { - return new ODataPropertyImpl(property.getName(), getODataValue(property, null)); + public ODataProperty getODataProperty(final ResWrap property) { + return new ODataPropertyImpl(property.getPayload().getName(), getODataValue(property)); } @Override diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataDeserializerImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataDeserializerImpl.java index 01bacbe01..2c5ae5946 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataDeserializerImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataDeserializerImpl.java @@ -31,7 +31,7 @@ import org.apache.olingo.client.core.data.v3.JSONServiceDocumentImpl; import org.apache.olingo.client.core.data.v4.XMLServiceDocumentImpl; import org.apache.olingo.client.core.edm.xml.v3.EdmxImpl; import org.apache.olingo.client.core.edm.xml.v3.XMLMetadataImpl; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.core.op.AbstractODataDeserializer; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; @@ -53,14 +53,14 @@ public class ODataDeserializerImpl extends AbstractODataDeserializer implements } @Override - public Container toServiceDocument(final InputStream input, final ODataFormat format) { + public ResWrap toServiceDocument(final InputStream input, final ODataFormat format) { return format == ODataFormat.XML ? this.xml(input, XMLServiceDocumentImpl.class) : this.json(input, JSONServiceDocumentImpl.class); } @Override - public Container toLinkCollection(final InputStream input, final ODataFormat format) { + public ResWrap toLinkCollection(final InputStream input, final ODataFormat format) { return format == ODataFormat.XML ? this.atom(input, XMLLinkCollectionImpl.class) : this.json(input, JSONLinkCollectionImpl.class); diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataReaderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataReaderImpl.java index 8663e79b8..2b8bc5d78 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataReaderImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataReaderImpl.java @@ -25,8 +25,7 @@ import org.apache.olingo.commons.api.format.ODataFormat; import org.apache.olingo.client.api.op.v3.ODataReader; import org.apache.olingo.client.api.v3.ODataClient; import org.apache.olingo.client.core.op.AbstractODataReader; -import org.apache.olingo.commons.api.data.Container; -import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.v3.LinkCollection; import org.apache.olingo.commons.api.domain.v3.ODataEntity; import org.apache.olingo.commons.api.domain.v3.ODataEntitySet; @@ -43,39 +42,36 @@ public class ODataReaderImpl extends AbstractODataReader implements ODataReader @Override public ODataEntitySet readEntitySet(final InputStream input, final ODataPubFormat format) { - return ((ODataClient) client).getBinder(). - getODataEntitySet(client.getDeserializer().toFeed(input, format).getObject()); + return ((ODataClient) client).getBinder().getODataEntitySet(client.getDeserializer().toFeed(input, format)); } @Override public ODataEntity readEntity(final InputStream input, final ODataPubFormat format) { - return ((ODataClient) client).getBinder(). - getODataEntity(client.getDeserializer().toEntry(input, format).getObject()); + return ((ODataClient) client).getBinder().getODataEntity(client.getDeserializer().toEntry(input, format)); } @Override public ODataProperty readProperty(final InputStream input, final ODataFormat format) { - final Property property = client.getDeserializer().toProperty(input, format).getObject(); - return ((ODataClient) client).getBinder().getODataProperty(property); + return ((ODataClient) client).getBinder().getODataProperty(client.getDeserializer().toProperty(input, format)); } @Override public ODataLinkCollection readLinks(final InputStream input, final ODataFormat format) { return ((ODataClient) client).getBinder().getLinkCollection( - ((ODataClient) client).getDeserializer().toLinkCollection(input, format).getObject()); + ((ODataClient) client).getDeserializer().toLinkCollection(input, format).getPayload()); } @Override @SuppressWarnings("unchecked") - public Container read(final InputStream src, final String format, final Class reference) { + public ResWrap read(final InputStream src, final String format, final Class reference) { if (ODataLinkCollection.class.isAssignableFrom(reference)) { - final Container container = + final ResWrap container = ((ODataClient) client).getDeserializer().toLinkCollection(src, ODataFormat.fromString(format)); - return new Container( + return new ResWrap( container.getContextURL(), container.getMetadataETag(), - (T) ((ODataClient) client).getBinder().getLinkCollection(container.getObject())); + (T) ((ODataClient) client).getBinder().getLinkCollection(container.getPayload())); } else { return super.read(src, format, reference); } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataBinderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataBinderImpl.java index 950ea532c..407ab1b52 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataBinderImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataBinderImpl.java @@ -18,11 +18,10 @@ */ package org.apache.olingo.client.core.op.impl.v4; -import java.net.URI; -import java.util.List; import org.apache.olingo.client.api.data.ServiceDocument; import org.apache.olingo.client.api.data.ServiceDocumentItem; import org.apache.olingo.client.api.op.v4.ODataBinder; +import org.apache.olingo.client.api.v4.EdmEnabledODataClient; import org.apache.olingo.client.api.v4.ODataClient; import org.apache.olingo.client.core.op.AbstractODataBinder; import org.apache.olingo.client.core.uri.URIUtils; @@ -30,6 +29,7 @@ import org.apache.olingo.commons.api.data.Entry; import org.apache.olingo.commons.api.data.Feed; import org.apache.olingo.commons.api.data.LinkedComplexValue; import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.Value; import org.apache.olingo.commons.api.domain.CommonODataEntity; import org.apache.olingo.commons.api.domain.CommonODataEntitySet; @@ -40,6 +40,7 @@ import org.apache.olingo.commons.api.domain.v4.ODataEntity; import org.apache.olingo.commons.api.domain.v4.ODataEntitySet; import org.apache.olingo.commons.api.domain.v4.ODataLinkedComplexValue; import org.apache.olingo.commons.api.domain.v4.ODataProperty; +import org.apache.olingo.commons.api.edm.EdmComplexType; import org.apache.olingo.commons.core.data.EnumValueImpl; import org.apache.olingo.commons.core.data.LinkedComplexValueImpl; import org.apache.olingo.commons.core.domain.v4.ODataPropertyImpl; @@ -143,68 +144,52 @@ public class ODataBinderImpl extends AbstractODataBinder implements ODataBinder } @Override - public ODataEntitySet getODataEntitySet(final Feed resource) { + public ODataEntitySet getODataEntitySet(final ResWrap resource) { return (ODataEntitySet) super.getODataEntitySet(resource); } @Override - public ODataEntitySet getODataEntitySet(final Feed resource, final URI defaultBaseURI) { - return (ODataEntitySet) super.getODataEntitySet(resource, defaultBaseURI); - } - - @Override - protected void copyProperties(final List src, final CommonODataEntity dst, final URI base) { - for (Property property : src) { - add(dst, getODataProperty(property, base)); - } - } - - @Override - public ODataEntity getODataEntity(final Entry resource) { - return (ODataEntity) super.getODataEntity(resource); - } - - @Override - public ODataEntity getODataEntity(final Entry resource, final URI defaultBaseURI) { - final ODataEntity entity = (ODataEntity) super.getODataEntity(resource, defaultBaseURI); - entity.setReference(resource.getId()); + public ODataEntity getODataEntity(final ResWrap resource) { + final ODataEntity entity = (ODataEntity) super.getODataEntity(resource); + entity.setReference(resource.getPayload().getId()); return entity; } @Override - public ODataProperty getODataProperty(final Property property) { - return getODataProperty(property, null); + public ODataProperty getODataProperty(final ResWrap property) { + return new ODataPropertyImpl(property.getPayload().getName(), getODataValue(property)); } @Override - public ODataProperty getODataProperty(final Property property, final URI base) { - return new ODataPropertyImpl(property.getName(), getODataValue(property, base)); - } - - @Override - protected ODataValue getODataValue(final Property resource, final URI base) { - final EdmTypeInfo typeInfo = resource.getType() == null - ? null - : new EdmTypeInfo.Builder().setTypeExpression(resource.getType()).build(); + protected ODataValue getODataValue(final ResWrap resource) { + final EdmTypeInfo typeInfo = buildTypeInfo(resource); ODataValue value; - if (resource.getValue().isEnum()) { + if (resource.getPayload().getValue().isEnum()) { value = ((ODataClient) client).getObjectFactory().newEnumValue( typeInfo == null ? null : typeInfo.getFullQualifiedName().toString(), - resource.getValue().asEnum().get()); - } else if (resource.getValue().isLinkedComplex()) { + resource.getPayload().getValue().asEnum().get()); + } else if (resource.getPayload().getValue().isLinkedComplex()) { final ODataLinkedComplexValue lcValue = ((ODataClient) client).getObjectFactory(). newLinkedComplexValue(typeInfo == null ? null : typeInfo.getFullQualifiedName().toString()); - for (Property property : resource.getValue().asComplex().get()) { - lcValue.add(getODataProperty(property)); + for (Property property : resource.getPayload().getValue().asComplex().get()) { + lcValue.add(getODataProperty( + new ResWrap(resource.getContextURL(), resource.getMetadataETag(), property))); } - odataLinks(resource.getValue().asLinkedComplex(), lcValue, base); + EdmComplexType edmType = null; + if (client instanceof EdmEnabledODataClient && typeInfo != null) { + edmType = ((EdmEnabledODataClient) client).getEdm(resource.getMetadataETag()). + getComplexType(typeInfo.getFullQualifiedName()); + } + + odataNavigationLinks(edmType, resource.getPayload().getValue().asLinkedComplex(), lcValue, + resource.getMetadataETag(), resource.getContextURL() == null ? null : resource.getContextURL().getURI()); value = lcValue; } else { - value = super.getODataValue(resource, base); + value = super.getODataValue(resource); } return value; diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataDeserializerImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataDeserializerImpl.java index 08d35568b..9bb6727f3 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataDeserializerImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataDeserializerImpl.java @@ -28,7 +28,7 @@ import org.apache.olingo.client.core.data.v4.JSONServiceDocumentImpl; import org.apache.olingo.client.core.data.v4.XMLServiceDocumentImpl; import org.apache.olingo.client.core.edm.xml.v4.EdmxImpl; import org.apache.olingo.client.core.edm.xml.v4.XMLMetadataImpl; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.core.op.AbstractODataDeserializer; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; @@ -50,7 +50,7 @@ public class ODataDeserializerImpl extends AbstractODataDeserializer implements } @Override - public Container toServiceDocument(final InputStream input, final ODataFormat format) { + public ResWrap toServiceDocument(final InputStream input, final ODataFormat format) { return format == ODataFormat.XML ? this.xml(input, XMLServiceDocumentImpl.class) : this.json(input, JSONServiceDocumentImpl.class); diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataReaderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataReaderImpl.java index 41f1e3b36..eb446d1d8 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataReaderImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataReaderImpl.java @@ -22,7 +22,6 @@ import java.io.InputStream; import org.apache.olingo.client.api.op.v4.ODataReader; import org.apache.olingo.client.api.v4.ODataClient; import org.apache.olingo.client.core.op.AbstractODataReader; -import org.apache.olingo.commons.api.data.Property; import org.apache.olingo.commons.api.domain.v4.ODataEntity; import org.apache.olingo.commons.api.domain.v4.ODataEntitySet; import org.apache.olingo.commons.api.domain.v4.ODataProperty; @@ -39,19 +38,16 @@ public class ODataReaderImpl extends AbstractODataReader implements ODataReader @Override public ODataEntitySet readEntitySet(final InputStream input, final ODataPubFormat format) { - return ((ODataClient) client).getBinder(). - getODataEntitySet(client.getDeserializer().toFeed(input, format).getObject()); + return ((ODataClient) client).getBinder().getODataEntitySet(client.getDeserializer().toFeed(input, format)); } @Override public ODataEntity readEntity(final InputStream input, final ODataPubFormat format) { - return ((ODataClient) client).getBinder(). - getODataEntity(client.getDeserializer().toEntry(input, format).getObject()); + return ((ODataClient) client).getBinder().getODataEntity(client.getDeserializer().toEntry(input, format)); } @Override public ODataProperty readProperty(final InputStream input, final ODataFormat format) { - final Property property = client.getDeserializer().toProperty(input, format).getObject(); - return ((ODataClient) client).getBinder().getODataProperty(property); + return ((ODataClient) client).getBinder().getODataProperty(client.getDeserializer().toProperty(input, format)); } } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/v3/EdmEnabledODataClientImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/v3/EdmEnabledODataClientImpl.java new file mode 100644 index 000000000..e0f6dda4e --- /dev/null +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/v3/EdmEnabledODataClientImpl.java @@ -0,0 +1,53 @@ +/* + * 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. + */ +package org.apache.olingo.client.core.v3; + +import org.apache.olingo.client.api.communication.request.retrieve.EdmMetadataRequest; +import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; +import org.apache.olingo.client.api.v3.EdmEnabledODataClient; +import org.apache.olingo.commons.api.edm.Edm; + +public class EdmEnabledODataClientImpl extends ODataClientImpl implements EdmEnabledODataClient { + + private final String serviceRoot; + + private Edm edm; + + public EdmEnabledODataClientImpl(final String serviceRoot) { + super(); + + this.serviceRoot = serviceRoot; + } + + @Override + public String getServiceRoot() { + return serviceRoot; + } + + @Override + public final Edm getEdm(final String metadataETag) { + synchronized (this) { + final EdmMetadataRequest metadataReq = getRetrieveRequestFactory().getMetadataRequest(serviceRoot); + final ODataRetrieveResponse metadataRes = metadataReq.execute(); + this.edm = metadataRes.getBody(); + } + return this.edm; + } + +} diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/EdmEnabledODataClientImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/EdmEnabledODataClientImpl.java new file mode 100644 index 000000000..238045f99 --- /dev/null +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/EdmEnabledODataClientImpl.java @@ -0,0 +1,59 @@ +/* + * 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. + */ +package org.apache.olingo.client.core.v4; + +import org.apache.commons.lang3.StringUtils; +import org.apache.olingo.client.api.communication.request.retrieve.EdmMetadataRequest; +import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; +import org.apache.olingo.client.api.v4.EdmEnabledODataClient; +import org.apache.olingo.commons.api.edm.Edm; + +public class EdmEnabledODataClientImpl extends ODataClientImpl implements EdmEnabledODataClient { + + private final String serviceRoot; + + private Edm edm; + + private String metadataETag; + + public EdmEnabledODataClientImpl(final String serviceRoot) { + super(); + + this.serviceRoot = serviceRoot; + this.metadataETag = StringUtils.EMPTY; + } + + @Override + public String getServiceRoot() { + return serviceRoot; + } + + @Override + public final Edm getEdm(final String metadataETag) { + synchronized (this) { + if (this.metadataETag != null && !this.metadataETag.equals(metadataETag)) { + final EdmMetadataRequest metadataReq = getRetrieveRequestFactory().getMetadataRequest(serviceRoot); + final ODataRetrieveResponse metadataRes = metadataReq.execute(); + this.metadataETag = metadataRes.getETag(); + this.edm = metadataRes.getBody(); + } + } + return this.edm; + } +} diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AbstractTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AbstractTestITCase.java index 22719afd2..9f06dc410 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AbstractTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AbstractTestITCase.java @@ -297,7 +297,7 @@ public abstract class AbstractTestITCase extends AbstractBaseTestITCase { final ODataRetrieveResponse res = getClient().getRetrieveRequestFactory(). getEntityRequest(uri).execute(); try { - return res.getEtag(); + return res.getETag(); } finally { res.close(); } diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AsyncTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AsyncTestITCase.java index 2868f8cb3..9b9ba9ca6 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AsyncTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AsyncTestITCase.java @@ -79,7 +79,7 @@ public class AsyncTestITCase extends AbstractTestITCase { final ODataEntityUpdateRequest updateReq = client.getCUDRequestFactory().getEntityUpdateRequest(uri, UpdateType.MERGE, entity); - updateReq.setIfMatch(entityRes.getEtag()); + updateReq.setIfMatch(entityRes.getETag()); final Future> futureRes = updateReq.asyncExecute(); while (!futureRes.isDone()) { diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityRetrieveTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityRetrieveTestITCase.java index 7c3bb1ddb..2693fb2c2 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityRetrieveTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityRetrieveTestITCase.java @@ -18,6 +18,11 @@ */ package org.apache.olingo.client.core.it.v3; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + import java.util.LinkedHashMap; import java.util.List; import org.apache.commons.lang3.StringUtils; @@ -26,6 +31,7 @@ import org.apache.olingo.client.api.communication.request.retrieve.ODataRawReque import org.apache.olingo.client.api.communication.response.ODataRawResponse; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; import org.apache.olingo.client.api.uri.CommonURIBuilder; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.domain.CommonODataEntity; import org.apache.olingo.commons.api.domain.CommonODataEntitySet; import org.apache.olingo.commons.api.domain.CommonODataProperty; @@ -33,14 +39,10 @@ import org.apache.olingo.commons.api.domain.ODataInlineEntity; import org.apache.olingo.commons.api.domain.ODataInlineEntitySet; import org.apache.olingo.commons.api.domain.ODataLink; import org.apache.olingo.commons.api.domain.v3.ODataEntity; +import org.apache.olingo.commons.api.domain.v3.ODataEntitySet; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.format.ODataPubFormat; import org.apache.olingo.commons.core.op.ResourceFactory; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - import org.junit.Test; /** @@ -154,11 +156,11 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase { final ODataRawResponse res = req.execute(); assertNotNull(res); - final CommonODataEntitySet entitySet = res.getBodyAs(CommonODataEntitySet.class); + final ResWrap entitySet = res.getBodyAs(ODataEntitySet.class); assertNull(entitySet); - final CommonODataEntity entity = res.getBodyAs(CommonODataEntity.class); - assertNotNull(entity); + final ResWrap entity = res.getBodyAs(ODataEntity.class); + assertNotNull(entity.getPayload()); } @Test @@ -219,7 +221,7 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase { final ODataRetrieveResponse res = req.execute(); assertEquals(200, res.getStatusCode()); - final String etag = res.getEtag(); + final String etag = res.getETag(); assertTrue(StringUtils.isNotBlank(etag)); final CommonODataEntity product = res.getBody(); diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntitySetTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntitySetTestITCase.java index a8b1c518c..abf0964e5 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntitySetTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntitySetTestITCase.java @@ -32,6 +32,7 @@ import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse import org.apache.olingo.client.api.domain.ODataEntitySetIterator; import org.apache.olingo.client.api.uri.v3.URIBuilder; import org.apache.olingo.client.core.uri.URIUtils; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.domain.v3.ODataEntity; import org.apache.olingo.commons.api.domain.v3.ODataEntitySet; import org.apache.olingo.commons.api.format.ODataPubFormat; @@ -155,8 +156,8 @@ public class EntitySetTestITCase extends AbstractTestITCase { final ODataRawResponse res = req.execute(); assertNotNull(res); - final ODataEntitySet entitySet = res.getBodyAs(ODataEntitySet.class); - assertEquals(10, entitySet.getCount()); + final ResWrap entitySet = res.getBodyAs(ODataEntitySet.class); + assertEquals(10, entitySet.getPayload().getCount()); } private void rawRequest(final ODataPubFormat format) { @@ -169,7 +170,7 @@ public class EntitySetTestITCase extends AbstractTestITCase { final ODataRawResponse res = req.execute(); assertNotNull(res); - final ODataEntitySet entitySet = res.getBodyAs(ODataEntitySet.class); - assertNotNull(entitySet); + final ResWrap entitySet = res.getBodyAs(ODataEntitySet.class); + assertNotNull(entitySet.getPayload()); } } diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/PropertyRetrieveTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/PropertyRetrieveTestITCase.java index a38b403f1..59eaef869 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/PropertyRetrieveTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/PropertyRetrieveTestITCase.java @@ -64,8 +64,7 @@ public class PropertyRetrieveTestITCase extends AbstractTestITCase { assertTrue(value.isCollection()); } } catch (ODataClientErrorException e) { - if (e.getStatusLine().getStatusCode() != 404 - && e.getStatusLine().getStatusCode() != 400) { + if (e.getStatusLine().getStatusCode() != 404 && e.getStatusLine().getStatusCode() != 400) { fail(e.getMessage()); } } diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/PropertyTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/PropertyTestITCase.java index c0ebc4c66..2bdc18f76 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/PropertyTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/PropertyTestITCase.java @@ -38,6 +38,7 @@ import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse import org.apache.olingo.client.api.communication.response.ODataValueUpdateResponse; import org.apache.olingo.client.api.http.HttpMethod; import org.apache.olingo.client.api.uri.v3.URIBuilder; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.domain.ODataCollectionValue; import org.apache.olingo.commons.api.domain.ODataPrimitiveValue; import org.apache.olingo.commons.api.domain.ODataValue; @@ -284,7 +285,7 @@ public class PropertyTestITCase extends AbstractTestITCase { } updateReq.setFormat(format); - ODataPropertyUpdateResponse updateRes = updateReq.execute(); + final ODataPropertyUpdateResponse updateRes = updateReq.execute(); assertEquals(204, updateRes.getStatusCode()); retrieveReq = client.getRetrieveRequestFactory().getPropertyRequest(uriBuilder.build()); @@ -353,7 +354,7 @@ public class PropertyTestITCase extends AbstractTestITCase { final ODataRawResponse res = req.execute(); assertNotNull(res); - final ODataProperty property = res.getBodyAs(ODataProperty.class); - assertNotNull(property); + final ResWrap property = res.getBodyAs(ODataProperty.class); + assertNotNull(property.getPayload()); } } diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/QueryOptionsTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/QueryOptionsTestITCase.java index 03884df8c..827ad2afe 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/QueryOptionsTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/QueryOptionsTestITCase.java @@ -195,7 +195,7 @@ public class QueryOptionsTestITCase extends AbstractTestITCase { req.setFormat(ODataPubFormat.ATOM); final Entry atomEntry = - client.getDeserializer().toEntry(req.execute().getRawResponse(), ODataPubFormat.ATOM).getObject(); + client.getDeserializer().toEntry(req.execute().getRawResponse(), ODataPubFormat.ATOM).getPayload(); assertEquals("remotingdestructorprinterswitcheschannelssatellitelanguageresolve", ((AtomEntryImpl) atomEntry).getSummary()); } diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/AbstractTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/AbstractTestITCase.java index ea5b5e017..c090ec838 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/AbstractTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/AbstractTestITCase.java @@ -25,6 +25,7 @@ import org.apache.olingo.client.api.communication.request.cud.ODataEntityCreateR import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest; import org.apache.olingo.client.api.communication.response.ODataDeleteResponse; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; +import org.apache.olingo.client.api.v4.EdmEnabledODataClient; import org.apache.olingo.client.api.v4.ODataClient; import org.apache.olingo.client.core.ODataClientFactory; import org.apache.olingo.client.core.it.AbstractBaseTestITCase; @@ -42,7 +43,9 @@ import org.junit.BeforeClass; public abstract class AbstractTestITCase extends AbstractBaseTestITCase { - protected static ODataClient client; + protected static final ODataClient client = ODataClientFactory.getV4(); + + protected static EdmEnabledODataClient edmClient; protected static String testStaticServiceRootURL; @@ -61,11 +64,8 @@ public abstract class AbstractTestITCase extends AbstractBaseTestITCase { testOpenTypeServiceRootURL = "http://localhost:9080/StaticService/V40/OpenType.svc"; testLargeModelServiceRootURL = "http://localhost:9080/StaticService/V40/Static.svc/large"; testAuthServiceRootURL = "http://localhost:9080/DefaultService.svc"; - } - @BeforeClass - public static void setClientInstance() { - client = ODataClientFactory.getV4(); + edmClient = ODataClientFactory.getEdmEnabledV4(testStaticServiceRootURL); } @Override diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityRetrieveTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityRetrieveTestITCase.java index db69cca20..4feea9692 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityRetrieveTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityRetrieveTestITCase.java @@ -32,12 +32,16 @@ import org.apache.olingo.client.api.communication.request.retrieve.ODataRawReque import org.apache.olingo.client.api.communication.response.ODataRawResponse; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; import org.apache.olingo.client.api.uri.v4.URIBuilder; +import org.apache.olingo.client.api.v4.EdmEnabledODataClient; +import org.apache.olingo.client.api.v4.ODataClient; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.domain.CommonODataEntity; import org.apache.olingo.commons.api.domain.CommonODataEntitySet; import org.apache.olingo.commons.api.domain.CommonODataProperty; import org.apache.olingo.commons.api.domain.ODataInlineEntity; import org.apache.olingo.commons.api.domain.ODataInlineEntitySet; import org.apache.olingo.commons.api.domain.ODataLink; +import org.apache.olingo.commons.api.domain.ODataLinkType; import org.apache.olingo.commons.api.domain.v4.ODataEntity; import org.apache.olingo.commons.api.domain.v4.ODataEntitySet; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; @@ -49,12 +53,8 @@ import org.junit.Test; */ public class EntityRetrieveTestITCase extends AbstractTestITCase { - protected String getServiceRoot() { - return testStaticServiceRootURL; - } - - private void withInlineEntry(final ODataPubFormat format) { - final URIBuilder uriBuilder = client.getURIBuilder(getServiceRoot()). + private void withInlineEntry(final ODataClient client, final ODataPubFormat format) { + final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL). appendEntitySetSegment("Customers").appendKeySegment(1).expand("Company"); final ODataEntityRequest req = client.getRetrieveRequestFactory(). @@ -66,56 +66,65 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase { assertNotNull(entity); assertEquals("Microsoft.Test.OData.Services.ODataWCFService.Customer", entity.getTypeName().toString()); - assertEquals(getServiceRoot() + "/Customers(1)", entity.getEditLink().toASCIIString()); + assertTrue(entity.getProperty("Home").hasPrimitiveValue()); + assertEquals("Edm.GeographyPoint", entity.getProperty("Home").getPrimitiveValue().getTypeName()); + assertEquals(testStaticServiceRootURL + "/Customers(1)", entity.getEditLink().toASCIIString()); - assertEquals(3, entity.getNavigationLinks().size()); + // In JSON with minimal metadata, links are not provided + if (format == ODataPubFormat.ATOM || format == ODataPubFormat.JSON_FULL_METADATA) { + assertEquals(3, entity.getNavigationLinks().size()); - if (ODataPubFormat.ATOM == format) { - assertTrue(entity.getAssociationLinks().isEmpty()); - // In JSON, association links for each $ref link will exist. - } - - boolean found = false; - - for (ODataLink link : entity.getNavigationLinks()) { - if (link instanceof ODataInlineEntity) { - final CommonODataEntity inline = ((ODataInlineEntity) link).getEntity(); - assertNotNull(inline); - - final List properties = inline.getProperties(); - assertEquals(5, properties.size()); - - assertTrue(properties.get(0).getName().equals("CompanyID") - || properties.get(1).getName().equals("CompanyID") - || properties.get(2).getName().equals("CompanyID") - || properties.get(3).getName().equals("CompanyID") - || properties.get(4).getName().equals("CompanyID")); - assertTrue(properties.get(0).getValue().toString().equals("0") - || properties.get(1).getValue().toString().equals("0") - || properties.get(2).getValue().toString().equals("0") - || properties.get(3).getValue().toString().equals("0") - || properties.get(4).getValue().toString().equals("0")); - - found = true; + if (ODataPubFormat.ATOM == format) { + assertTrue(entity.getAssociationLinks().isEmpty()); + // In JSON, association links for each $ref link will exist. } - } - assertTrue(found); + boolean found = false; + + for (ODataLink link : entity.getNavigationLinks()) { + if (link instanceof ODataInlineEntity) { + final CommonODataEntity inline = ((ODataInlineEntity) link).getEntity(); + assertNotNull(inline); + + final List properties = inline.getProperties(); + assertEquals(5, properties.size()); + + assertTrue(properties.get(0).getName().equals("CompanyID") + || properties.get(1).getName().equals("CompanyID") + || properties.get(2).getName().equals("CompanyID") + || properties.get(3).getName().equals("CompanyID") + || properties.get(4).getName().equals("CompanyID")); + assertTrue(properties.get(0).getValue().toString().equals("0") + || properties.get(1).getValue().toString().equals("0") + || properties.get(2).getValue().toString().equals("0") + || properties.get(3).getValue().toString().equals("0") + || properties.get(4).getValue().toString().equals("0")); + + found = true; + } + } + + assertTrue(found); + } } @Test public void withInlineEntryFromAtom() { - withInlineEntry(ODataPubFormat.ATOM); + withInlineEntry(client, ODataPubFormat.ATOM); + } + + @Test + public void withInlineEntryFromFullJSON() { + withInlineEntry(client, ODataPubFormat.JSON_FULL_METADATA); } @Test public void withInlineEntryFromJSON() { - // this needs to be full, otherwise there is no mean to recognize links - withInlineEntry(ODataPubFormat.JSON_FULL_METADATA); + withInlineEntry(edmClient, ODataPubFormat.JSON); } - private void withInlineFeed(final ODataPubFormat format) { - final URIBuilder uriBuilder = client.getURIBuilder(getServiceRoot()). + private void withInlineFeed(final ODataClient client, final ODataPubFormat format) { + final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL). appendEntitySetSegment("Customers").appendKeySegment(1).expand("Orders"); final ODataEntityRequest req = client.getRetrieveRequestFactory(). @@ -125,34 +134,40 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase { final ODataRetrieveResponse res = req.execute(); final ODataEntity entity = res.getBody(); assertNotNull(entity); + assertEquals("Microsoft.Test.OData.Services.ODataWCFService.Customer", entity.getTypeName().toString()); - boolean found = false; + // In JSON with minimal metadata, links are not provided + if (format == ODataPubFormat.ATOM || format == ODataPubFormat.JSON_FULL_METADATA) { + boolean found = false; + for (ODataLink link : entity.getNavigationLinks()) { + if (link instanceof ODataInlineEntitySet) { + final CommonODataEntitySet inline = ((ODataInlineEntitySet) link).getEntitySet(); + assertNotNull(inline); - for (ODataLink link : entity.getNavigationLinks()) { - if (link instanceof ODataInlineEntitySet) { - final CommonODataEntitySet inline = ((ODataInlineEntitySet) link).getEntitySet(); - assertNotNull(inline); - - found = true; + found = true; + } } + assertTrue(found); } - - assertTrue(found); } @Test public void withInlineFeedFromAtom() { - withInlineFeed(ODataPubFormat.ATOM); + withInlineFeed(client, ODataPubFormat.ATOM); + } + + @Test + public void withInlineFeedFromFullJSON() { + withInlineFeed(client, ODataPubFormat.JSON_FULL_METADATA); } @Test public void withInlineFeedFromJSON() { - // this needs to be full, otherwise there is no mean to recognize links - withInlineFeed(ODataPubFormat.JSON_FULL_METADATA); + withInlineFeed(edmClient, ODataPubFormat.JSON); } private void rawRequest(final ODataPubFormat format) { - final URIBuilder uriBuilder = client.getURIBuilder(getServiceRoot()). + final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL). appendEntitySetSegment("People").appendKeySegment(5); final ODataRawRequest req = client.getRetrieveRequestFactory().getRawRequest(uriBuilder.build()); @@ -161,11 +176,11 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase { final ODataRawResponse res = req.execute(); assertNotNull(res); - final ODataEntitySet entitySet = res.getBodyAs(ODataEntitySet.class); + final ResWrap entitySet = res.getBodyAs(ODataEntitySet.class); assertNull(entitySet); - final ODataEntity entity = res.getBodyAs(ODataEntity.class); - assertTrue(entity.getReference().endsWith("/StaticService/V40/Static.svc/People(5)")); + final ResWrap entity = res.getBodyAs(ODataEntity.class); + assertTrue(entity.getPayload().getReference().endsWith("/StaticService/V40/Static.svc/People(5)")); } @Test @@ -175,7 +190,7 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase { @Test public void rawRequestAsJSON() { - // this needs to be full, otherwise actions will not be provided + // this needs to be full, otherwise reference will not be provided rawRequest(ODataPubFormat.JSON_FULL_METADATA); } @@ -184,7 +199,7 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase { multiKey.put("ProductID", "6"); multiKey.put("ProductDetailID", 1); - final URIBuilder uriBuilder = client.getURIBuilder(getServiceRoot()). + final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL). appendEntitySetSegment("ProductDetails").appendKeySegment(multiKey); final ODataEntityRequest req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build()); @@ -207,19 +222,9 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase { multiKey(ODataPubFormat.JSON_FULL_METADATA); } - @Test - public void checkForETagAsATOM() { - checkForETag(ODataPubFormat.ATOM); - } - - @Test - public void checkForETagAsJSON() { - checkForETag(ODataPubFormat.JSON_FULL_METADATA); - } - - private void checkForETag(final ODataPubFormat format) { + private void checkForETag(final ODataClient client, final ODataPubFormat format) { final URIBuilder uriBuilder = - client.getURIBuilder(getServiceRoot()).appendEntitySetSegment("Orders").appendKeySegment(8); + client.getURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("Orders").appendKeySegment(8); final ODataEntityRequest req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build()); req.setFormat(format); @@ -227,16 +232,36 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase { final ODataRetrieveResponse res = req.execute(); assertEquals(200, res.getStatusCode()); - final String etag = res.getEtag(); + final String etag = res.getETag(); assertTrue(StringUtils.isNotBlank(etag)); final ODataEntity order = res.getBody(); assertEquals(etag, order.getETag()); + assertEquals("Microsoft.Test.OData.Services.ODataWCFService.Order", order.getTypeName().toString()); + assertEquals("Edm.Int32", order.getProperty("OrderID").getPrimitiveValue().getTypeName()); + assertEquals("Edm.DateTimeOffset", order.getProperty("OrderDate").getPrimitiveValue().getTypeName()); + assertEquals("Edm.Duration", order.getProperty("ShelfLife").getPrimitiveValue().getTypeName()); + assertEquals("Collection(Edm.Duration)", order.getProperty("OrderShelfLifes").getCollectionValue().getTypeName()); + } + + @Test + public void checkForETagAsATOM() { + checkForETag(client, ODataPubFormat.ATOM); + } + + @Test + public void checkForETagAsFullJSON() { + checkForETag(client, ODataPubFormat.JSON_FULL_METADATA); + } + + @Test + public void checkForETagAsJSON() { + checkForETag(edmClient, ODataPubFormat.JSON); } @Test(expected = IllegalArgumentException.class) public void issue99() { - final URIBuilder uriBuilder = client.getURIBuilder(getServiceRoot()).appendEntitySetSegment("Orders"); + final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("Orders"); final ODataEntityRequest req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build()); req.setFormat(ODataPubFormat.JSON); @@ -246,18 +271,8 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase { req.execute().getBody(); } - @Test - public void atomReference() { - reference(ODataPubFormat.ATOM); - } - - @Test - public void jsonReference() { - reference(ODataPubFormat.JSON_FULL_METADATA); - } - private void reference(final ODataPubFormat format) { - final URIBuilder uriBuilder = client.getURIBuilder(getServiceRoot()). + final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL). appendEntitySetSegment("Orders").appendKeySegment(8).appendNavigationSegment("CustomerForOrder"). appendRefSegment(); @@ -272,7 +287,7 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase { assertTrue(entity.getReference().endsWith("/StaticService/V40/Static.svc/Customers(PersonID=1)")); final URI referenceURI = - client.getURIBuilder(getServiceRoot()).appendEntityIdSegment(entity.getReference()).build(); + client.getURIBuilder(testStaticServiceRootURL).appendEntityIdSegment(entity.getReference()).build(); req = client.getRetrieveRequestFactory().getEntityRequest(referenceURI); req.setFormat(format); @@ -282,27 +297,71 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase { assertNotNull(res.getBody()); } - private void contained(final ODataPubFormat format) throws EdmPrimitiveTypeException { - final URI uri = getClient().getURIBuilder(getServiceRoot()). + @Test + public void atomReference() { + reference(ODataPubFormat.ATOM); + } + + @Test + public void jsonReference() { + reference(ODataPubFormat.JSON_FULL_METADATA); + } + + private void contained(final ODataClient client, final ODataPubFormat format) throws EdmPrimitiveTypeException { + final URI uri = client.getURIBuilder(testStaticServiceRootURL). appendEntitySetSegment("Accounts").appendKeySegment(101). appendNavigationSegment("MyPaymentInstruments").appendKeySegment(101901).build(); - - final ODataEntityRequest req = getClient().getRetrieveRequestFactory().getEntityRequest(uri); + final ODataEntityRequest req = client.getRetrieveRequestFactory().getEntityRequest(uri); req.setFormat(format); final ODataEntity contained = req.execute().getBody(); assertNotNull(contained); + assertEquals("Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument", contained.getTypeName().toString()); assertEquals(101901, contained.getProperty("PaymentInstrumentID").getPrimitiveValue().toCastValue(Integer.class), 0); + assertEquals("Edm.DateTimeOffset", contained.getProperty("CreatedDate").getPrimitiveValue().getTypeName()); } @Test - public void atomContained() throws EdmPrimitiveTypeException { - contained(ODataPubFormat.ATOM); + public void containedFromAtom() throws EdmPrimitiveTypeException { + contained(client, ODataPubFormat.ATOM); } @Test - public void jsonContained() throws EdmPrimitiveTypeException { - contained(ODataPubFormat.JSON); + public void containedFromFullJSON() throws EdmPrimitiveTypeException { + contained(client, ODataPubFormat.JSON_FULL_METADATA); } + + @Test + public void containedFromJSON() throws EdmPrimitiveTypeException { + contained(edmClient, ODataPubFormat.JSON); + } + + private void entitySetNavigationLink(final ODataClient client, final ODataPubFormat format) { + final URI uri = client.getURIBuilder(testStaticServiceRootURL). + appendEntitySetSegment("Accounts").appendKeySegment(101).build(); + final ODataEntityRequest req = client.getRetrieveRequestFactory().getEntityRequest(uri); + req.setFormat(format); + + final ODataEntity entity = req.execute().getBody(); + assertNotNull(entity); + + // With JSON, entity set navigation links are only recognizable via Edm + if (format == ODataPubFormat.ATOM || client instanceof EdmEnabledODataClient) { + assertEquals(ODataLinkType.ENTITY_SET_NAVIGATION, entity.getNavigationLink("MyPaymentInstruments").getType()); + assertEquals(ODataLinkType.ENTITY_SET_NAVIGATION, entity.getNavigationLink("ActiveSubscriptions").getType()); + } + } + + @Test + public void entitySetNavigationLinkFromAtom() { + entitySetNavigationLink(client, ODataPubFormat.ATOM); + } + + @Test + public void entitySetNavigationLinkFromJSON() { + // only JSON_FULL_METADATA has links, only Edm can recognize entity set navigation + entitySetNavigationLink(edmClient, ODataPubFormat.JSON_FULL_METADATA); + } + } diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java index 1c9e301cd..e4265fe66 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java @@ -31,7 +31,9 @@ import org.apache.olingo.client.api.communication.response.ODataRawResponse; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; import org.apache.olingo.client.api.domain.ODataEntitySetIterator; import org.apache.olingo.client.api.uri.v4.URIBuilder; +import org.apache.olingo.client.api.v4.ODataClient; import org.apache.olingo.client.core.uri.URIUtils; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.domain.v4.ODataEntity; import org.apache.olingo.commons.api.domain.v4.ODataEntitySet; import org.apache.olingo.commons.api.format.ODataPubFormat; @@ -42,8 +44,19 @@ import org.junit.Test; */ public class EntitySetTestITCase extends AbstractTestITCase { - protected String getServiceRoot() { - return testStaticServiceRootURL; + private void rawRequest(final ODataPubFormat format) { + final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL); + uriBuilder.appendEntitySetSegment("People"); + + final ODataRawRequest req = client.getRetrieveRequestFactory().getRawRequest(uriBuilder.build()); + req.setFormat(format.toString(client.getServiceVersion())); + + final ODataRawResponse res = req.execute(); + assertNotNull(res); + + final ResWrap entitySet = res.getBodyAs(ODataEntitySet.class); + assertNotNull(entitySet.getPayload()); + assertTrue(entitySet.getContextURL().getURI().toASCIIString().endsWith("$metadata#People")); } @Test @@ -56,72 +69,40 @@ public class EntitySetTestITCase extends AbstractTestITCase { rawRequest(ODataPubFormat.JSON); } + private void readWithInlineCount(final ODataClient client, final ODataPubFormat format) { + final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL); + uriBuilder.appendEntitySetSegment("People").count(true); + + final ODataRawRequest req = client.getRetrieveRequestFactory().getRawRequest(uriBuilder.build()); + req.setFormat(format.toString(client.getServiceVersion())); + + final ODataRawResponse res = req.execute(); + assertNotNull(res); + + final ResWrap entitySet = res.getBodyAs(ODataEntitySet.class); + assertEquals(5, entitySet.getPayload().getCount()); + + assertEquals("Microsoft.Test.OData.Services.ODataWCFService.Address", + entitySet.getPayload().getEntities().get(2).getProperty("HomeAddress").getComplexValue().getTypeName()); + } + @Test public void readWithInlineCountAsJSON() throws IOException { - readWithInlineCount(ODataPubFormat.JSON); + readWithInlineCount(edmClient, ODataPubFormat.JSON); + } + + @Test + public void readWithInlineCountAsFullJSON() throws IOException { + readWithInlineCount(client, ODataPubFormat.JSON_FULL_METADATA); } @Test public void readWithInlineCountAsAtom() throws IOException { - readWithInlineCount(ODataPubFormat.ATOM); - } - - @Test - public void readODataEntitySetIteratorFromAtom() { - readODataEntitySetIterator(ODataPubFormat.ATOM); - } - - @Test - public void readODataEntitySetIteratorFromJSON() { - readODataEntitySetIterator(ODataPubFormat.JSON); - } - - @Test - public void readODataEntitySetIteratorFromJSONFullMeta() { - readODataEntitySetIterator(ODataPubFormat.JSON_FULL_METADATA); - } - - @Test - public void readODataEntitySetIteratorFromJSONNoMeta() { - readODataEntitySetIterator(ODataPubFormat.JSON_NO_METADATA); - } - - @Test - public void readODataEntitySetWithNextFromAtom() { - readEntitySetWithNextLink(ODataPubFormat.ATOM); - } - - @Test - public void readODataEntitySetWithNextFromJSON() { - readEntitySetWithNextLink(ODataPubFormat.JSON_FULL_METADATA); - } - - private void readEntitySetWithNextLink(final ODataPubFormat format) { - final URIBuilder uriBuilder = client.getURIBuilder(getServiceRoot()); - uriBuilder.appendEntitySetSegment("People"); - - final ODataEntitySetRequest req = client.getRetrieveRequestFactory(). - getEntitySetRequest(uriBuilder.build()); - req.setFormat(format); - - final ODataRetrieveResponse res = req.execute(); - final ODataEntitySet feed = res.getBody(); - - assertNotNull(feed); - - assertTrue(res.getContextURL().toASCIIString().endsWith("$metadata#People")); - - assertEquals(5, feed.getEntities().size()); - assertNotNull(feed.getNext()); - - final URI expected = URI.create(getServiceRoot() + "/People?$skiptoken=5"); - final URI found = URIUtils.getURI(getServiceRoot(), feed.getNext().toASCIIString()); - - assertEquals(expected, found); + readWithInlineCount(client, ODataPubFormat.ATOM); } private void readODataEntitySetIterator(final ODataPubFormat format) { - final URIBuilder uriBuilder = client.getURIBuilder(getServiceRoot()); + final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL); uriBuilder.appendEntitySetSegment("People"); final ODataEntitySetIteratorRequest req = @@ -143,32 +124,56 @@ public class EntitySetTestITCase extends AbstractTestITCase { assertTrue(feedIterator.getNext().toASCIIString().endsWith("People?$skiptoken=5")); } - private void readWithInlineCount(final ODataPubFormat format) { - final URIBuilder uriBuilder = client.getURIBuilder(getServiceRoot()); - uriBuilder.appendEntitySetSegment("People").count(true); - - final ODataRawRequest req = client.getRetrieveRequestFactory().getRawRequest(uriBuilder.build()); - req.setFormat(format.toString(client.getServiceVersion())); - - final ODataRawResponse res = req.execute(); - assertNotNull(res); - - final ODataEntitySet entitySet = res.getBodyAs(ODataEntitySet.class); - assertEquals(5, entitySet.getCount()); + @Test + public void readODataEntitySetIteratorFromAtom() { + readODataEntitySetIterator(ODataPubFormat.ATOM); } - private void rawRequest(final ODataPubFormat format) { - final URIBuilder uriBuilder = client.getURIBuilder(getServiceRoot()); + @Test + public void readODataEntitySetIteratorFromJSON() { + readODataEntitySetIterator(ODataPubFormat.JSON); + } + + @Test + public void readODataEntitySetIteratorFromJSONFull() { + readODataEntitySetIterator(ODataPubFormat.JSON_FULL_METADATA); + } + + @Test + public void readODataEntitySetIteratorFromJSONNo() { + readODataEntitySetIterator(ODataPubFormat.JSON_NO_METADATA); + } + + private void readEntitySetWithNextLink(final ODataPubFormat format) { + final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL); uriBuilder.appendEntitySetSegment("People"); - final ODataRawRequest req = client.getRetrieveRequestFactory().getRawRequest(uriBuilder.build()); - req.setFormat(format.toString(client.getServiceVersion())); + final ODataEntitySetRequest req = client.getRetrieveRequestFactory(). + getEntitySetRequest(uriBuilder.build()); + req.setFormat(format); - final ODataRawResponse res = req.execute(); - assertNotNull(res); + final ODataRetrieveResponse res = req.execute(); + final ODataEntitySet feed = res.getBody(); - final ODataEntitySet entitySet = res.getBodyAs(ODataEntitySet.class); - assertNotNull(entitySet); - assertTrue(res.getContextURL().toASCIIString().endsWith("$metadata#People")); + assertNotNull(feed); + + assertEquals(5, feed.getEntities().size()); + assertNotNull(feed.getNext()); + + final URI expected = URI.create(testStaticServiceRootURL + "/People?$skiptoken=5"); + final URI found = URIUtils.getURI(testStaticServiceRootURL, feed.getNext().toASCIIString()); + + assertEquals(expected, found); } + + @Test + public void readODataEntitySetWithNextFromAtom() { + readEntitySetWithNextLink(ODataPubFormat.ATOM); + } + + @Test + public void readODataEntitySetWithNextFromJSON() { + readEntitySetWithNextLink(ODataPubFormat.JSON_FULL_METADATA); + } + } diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/FilterFactoryTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/FilterFactoryTestITCase.java index 595c6c666..4062de56a 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/FilterFactoryTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/FilterFactoryTestITCase.java @@ -18,14 +18,14 @@ */ package org.apache.olingo.client.core.it.v4; -import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest; import static org.junit.Assert.assertEquals; +import static org.apache.olingo.client.core.it.v4.AbstractTestITCase.client; +import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest; import org.apache.olingo.client.api.uri.URIFilter; import org.apache.olingo.client.api.uri.v4.FilterArgFactory; import org.apache.olingo.client.api.uri.v4.FilterFactory; import org.apache.olingo.client.api.uri.v4.URIBuilder; -import static org.apache.olingo.client.core.it.v4.AbstractTestITCase.client; import org.apache.olingo.commons.api.domain.v4.ODataEntity; import org.apache.olingo.commons.api.domain.v4.ODataEntitySet; import org.apache.olingo.commons.api.format.ODataPubFormat; @@ -43,7 +43,6 @@ public class FilterFactoryTestITCase extends AbstractTestITCase { @Test public void crossjoin() { - final URIFilter filter = getFilterFactory().eq( getFilterArgFactory().property("Orders/OrderID"), getFilterArgFactory().property("Customers/Order")); diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/KeyAsSegmentTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/KeyAsSegmentTestITCase.java index 4a0c3690f..91d4c8597 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/KeyAsSegmentTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/KeyAsSegmentTestITCase.java @@ -18,11 +18,13 @@ */ package org.apache.olingo.client.core.it.v4; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + import java.net.URI; import org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateRequest; import org.apache.olingo.client.api.communication.request.cud.v4.UpdateType; -import static org.junit.Assert.assertFalse; - import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest; import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; @@ -32,8 +34,6 @@ import org.apache.olingo.commons.api.domain.v4.ODataProperty; import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.format.ODataPubFormat; import org.junit.AfterClass; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; import org.junit.BeforeClass; import org.junit.Test; diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/MetadataTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/MetadataTestITCase.java index 887a46da3..4bac063bb 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/MetadataTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/MetadataTestITCase.java @@ -27,6 +27,8 @@ import org.apache.olingo.client.core.it.AbstractMetadataTestITCase; import org.apache.olingo.commons.api.edm.Edm; import org.apache.olingo.commons.api.edm.EdmEntityContainer; import org.apache.olingo.commons.api.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.apache.olingo.commons.api.edm.EdmProperty; import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.junit.Test; @@ -42,6 +44,14 @@ public class MetadataTestITCase extends AbstractMetadataTestITCase { final Edm metadata = getClient().getRetrieveRequestFactory(). getMetadataRequest(getTestServiceRoot()).execute().getBody(); assertNotNull(metadata); + + final EdmEntityType order = metadata.getEntityType( + new FullQualifiedName("Microsoft.Test.OData.Services.ODataWCFService", "Order")); + assertNotNull(order); + + final EdmProperty orderDate = order.getStructuralProperty("OrderDate"); + assertNotNull(orderDate); + assertEquals("Edm.DateTimeOffset", orderDate.getType().getFullQualifiedName().toString()); } @Test diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/PropertyTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/PropertyTestITCase.java new file mode 100644 index 000000000..00247ae7e --- /dev/null +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/PropertyTestITCase.java @@ -0,0 +1,113 @@ +/* + * 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. + */ +package org.apache.olingo.client.core.it.v4; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.apache.olingo.client.api.communication.request.retrieve.ODataPropertyRequest; +import org.apache.olingo.client.api.uri.v4.URIBuilder; +import org.apache.olingo.client.api.v4.ODataClient; +import org.apache.olingo.commons.api.domain.v4.ODataProperty; +import org.apache.olingo.commons.api.format.ODataFormat; +import org.junit.Test; + +public class PropertyTestITCase extends AbstractTestITCase { + + private void _enum(final ODataClient client, final ODataFormat format) { + final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL). + appendEntitySetSegment("Products").appendKeySegment(5).appendPropertySegment("CoverColors"); + final ODataPropertyRequest req = client.getRetrieveRequestFactory(). + getPropertyRequest(uriBuilder.build()); + req.setFormat(format); + + final ODataProperty prop = req.execute().getBody(); + assertNotNull(prop); + assertEquals("Collection(Microsoft.Test.OData.Services.ODataWCFService.Color)", prop.getValue().getTypeName()); + } + + @Test + public void enumFromXML() { + _enum(client, ODataFormat.XML); + } + + @Test + public void enumFromJSON() { + _enum(edmClient, ODataFormat.JSON); + } + + @Test + public void enumFromFullJSON() { + _enum(client, ODataFormat.JSON_FULL_METADATA); + } + + private void geospatial(final ODataClient client, final ODataFormat format) { + final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL). + appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("Home"); + final ODataPropertyRequest req = client.getRetrieveRequestFactory(). + getPropertyRequest(uriBuilder.build()); + req.setFormat(format); + + final ODataProperty prop = req.execute().getBody(); + assertNotNull(prop); + assertEquals("Edm.GeographyPoint", prop.getValue().getTypeName()); + } + + @Test + public void geospatialFromXML() { + geospatial(client, ODataFormat.XML); + } + + @Test + public void geospatialFromJSON() { + geospatial(edmClient, ODataFormat.JSON); + } + + @Test + public void geospatialFromFullJSON() { + geospatial(client, ODataFormat.JSON_FULL_METADATA); + } + + private void complex(final ODataClient client, final ODataFormat format) { + final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL). + appendEntitySetSegment("Customers").appendKeySegment(2).appendPropertySegment("HomeAddress"); + final ODataPropertyRequest req = client.getRetrieveRequestFactory(). + getPropertyRequest(uriBuilder.build()); + req.setFormat(format); + + final ODataProperty prop = req.execute().getBody(); + assertNotNull(prop); + assertEquals("Microsoft.Test.OData.Services.ODataWCFService.Address", prop.getValue().getTypeName()); + } + + @Test + public void complexFromXML() { + complex(client, ODataFormat.XML); + } + + @Test + public void complexFromJSON() { + complex(edmClient, ODataFormat.JSON); + } + + @Test + public void complexFromFullJSON() { + complex(client, ODataFormat.JSON_FULL_METADATA); + } +} diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/ServiceDocumentTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/ServiceDocumentTestITCase.java index 133c92902..3e7653daa 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/ServiceDocumentTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/ServiceDocumentTestITCase.java @@ -19,7 +19,6 @@ package org.apache.olingo.client.core.it.v4; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; import java.net.URI; import org.apache.olingo.client.api.communication.request.retrieve.ODataServiceDocumentRequest; @@ -43,7 +42,6 @@ public class ServiceDocumentTestITCase extends AbstractTestITCase { assertEquals(6, serviceDocument.getSingletons().size()); assertEquals(6, serviceDocument.getFunctionImports().size()); - assertTrue(res.getContextURL().toASCIIString().endsWith("/StaticService/V40/Static.svc/$metadata")); assertEquals(URI.create(testStaticServiceRootURL + "/ProductDetails"), serviceDocument.getEntitySetURI("ProductDetails")); assertEquals(URI.create(testStaticServiceRootURL + "/Boss"), diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/AtomTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/AtomTest.java index ce2ef71b4..1e6df49ed 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/AtomTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/AtomTest.java @@ -70,7 +70,7 @@ public class AtomTest extends AbstractTest { protected void feed(final String filename, final ODataPubFormat format) throws Exception { final StringWriter writer = new StringWriter(); getClient().getSerializer().feed(getClient().getDeserializer().toFeed( - getClass().getResourceAsStream("Customer." + getSuffix(format)), format).getObject(), writer); + getClass().getResourceAsStream("Customer." + getSuffix(format)), format).getPayload(), writer); assertSimilar("Customer." + getSuffix(format), writer.toString()); } @@ -83,7 +83,7 @@ public class AtomTest extends AbstractTest { protected void entry(final String filename, final ODataPubFormat format) throws Exception { final StringWriter writer = new StringWriter(); getClient().getSerializer().entry(getClient().getDeserializer().toEntry( - getClass().getResourceAsStream(filename + "." + getSuffix(format)), format).getObject(), writer); + getClass().getResourceAsStream(filename + "." + getSuffix(format)), format).getPayload(), writer); assertSimilar(filename + "." + getSuffix(format), writer.toString()); } @@ -103,7 +103,8 @@ public class AtomTest extends AbstractTest { protected void property(final String filename, final ODataFormat format) throws Exception { final StringWriter writer = new StringWriter(); getClient().getSerializer().property(getClient().getDeserializer(). - toProperty(getClass().getResourceAsStream(filename + "." + getSuffix(format)), format).getObject(), writer); + toProperty(getClass().getResourceAsStream(filename + "." + getSuffix(format)), format).getPayload(), + writer); assertSimilar(filename + "." + getSuffix(format), writer.toString()); } diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntitySetTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntitySetTest.java index 67edef370..f01a7f516 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntitySetTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntitySetTest.java @@ -23,9 +23,12 @@ import static org.junit.Assert.assertEquals; import java.io.IOException; import java.io.InputStream; +import java.net.URI; import org.apache.olingo.client.api.v3.ODataClient; import org.apache.olingo.commons.api.format.ODataPubFormat; import org.apache.olingo.client.core.AbstractTest; +import org.apache.olingo.commons.api.data.Feed; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.domain.v3.ODataEntitySet; import org.apache.olingo.commons.core.op.ResourceFactory; import org.junit.Test; @@ -40,14 +43,15 @@ public class EntitySetTest extends AbstractTest { private void read(final ODataPubFormat format) throws IOException { final InputStream input = getClass().getResourceAsStream("Customer." + getSuffix(format)); final ODataEntitySet entitySet = getClient().getBinder().getODataEntitySet( - getClient().getDeserializer().toFeed(input, format).getObject()); + getClient().getDeserializer().toFeed(input, format)); assertNotNull(entitySet); assertEquals(2, entitySet.getEntities().size()); assertNotNull(entitySet.getNext()); - final ODataEntitySet written = getClient().getBinder().getODataEntitySet(getClient(). - getBinder().getFeed(entitySet, ResourceFactory.feedClassForFormat(format == ODataPubFormat.ATOM))); + final ODataEntitySet written = getClient().getBinder().getODataEntitySet(new ResWrap((URI) null, null, + getClient().getBinder().getFeed( + entitySet, ResourceFactory.feedClassForFormat(format == ODataPubFormat.ATOM)))); assertEquals(entitySet, written); } diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntityTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntityTest.java index 631a45d6d..cbc804119 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntityTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntityTest.java @@ -23,10 +23,13 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.InputStream; +import java.net.URI; import org.apache.olingo.client.api.v3.ODataClient; import org.apache.olingo.commons.api.domain.ODataLink; import org.apache.olingo.commons.api.format.ODataPubFormat; import org.apache.olingo.client.core.AbstractTest; +import org.apache.olingo.commons.api.data.Entry; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.domain.v3.ODataEntity; import org.apache.olingo.commons.api.domain.v3.ODataProperty; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; @@ -46,7 +49,7 @@ public class EntityTest extends AbstractTest { private void readAndWrite(final ODataPubFormat format) { final InputStream input = getClass().getResourceAsStream("Customer_-10." + getSuffix(format)); final ODataEntity entity = getClient().getBinder().getODataEntity( - getClient().getDeserializer().toEntry(input, format).getObject()); + getClient().getDeserializer().toEntry(input, format)); assertNotNull(entity); assertEquals("Microsoft.Test.OData.Services.AstoriaDefaultService.Customer", entity.getTypeName().toString()); @@ -64,8 +67,8 @@ public class EntityTest extends AbstractTest { assertTrue(check); - final ODataEntity written = getClient().getBinder().getODataEntity(getClient().getBinder(). - getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM))); + final ODataEntity written = getClient().getBinder().getODataEntity(new ResWrap((URI) null, null, getClient(). + getBinder().getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM)))); assertEquals(entity, written); } @@ -82,7 +85,7 @@ public class EntityTest extends AbstractTest { private void readGeospatial(final ODataPubFormat format) { final InputStream input = getClass().getResourceAsStream("AllGeoTypesSet_-8." + getSuffix(format)); final ODataEntity entity = getClient().getBinder().getODataEntity( - getClient().getDeserializer().toEntry(input, format).getObject()); + getClient().getDeserializer().toEntry(input, format)); assertNotNull(entity); boolean found = false; @@ -95,8 +98,8 @@ public class EntityTest extends AbstractTest { } assertTrue(found); - final ODataEntity written = getClient().getBinder().getODataEntity(getClient().getBinder(). - getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM))); + final ODataEntity written = getClient().getBinder().getODataEntity(new ResWrap((URI) null, null, getClient(). + getBinder().getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM)))); assertEquals(entity, written); } @@ -114,14 +117,14 @@ public class EntityTest extends AbstractTest { private void withActions(final ODataPubFormat format) { final InputStream input = getClass().getResourceAsStream("ComputerDetail_-10." + getSuffix(format)); final ODataEntity entity = getClient().getBinder().getODataEntity( - getClient().getDeserializer().toEntry(input, format).getObject()); + getClient().getDeserializer().toEntry(input, format)); assertNotNull(entity); assertEquals(1, entity.getOperations().size()); assertEquals("ResetComputerDetailsSpecifications", entity.getOperations().get(0).getTitle()); - final ODataEntity written = getClient().getBinder().getODataEntity(getClient().getBinder(). - getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM))); + final ODataEntity written = getClient().getBinder().getODataEntity(new ResWrap((URI) null, null, getClient(). + getBinder().getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM)))); entity.getOperations().clear(); assertEquals(entity, written); } @@ -140,14 +143,14 @@ public class EntityTest extends AbstractTest { private void mediaEntity(final ODataPubFormat format) { final InputStream input = getClass().getResourceAsStream("Car_16." + getSuffix(format)); final ODataEntity entity = getClient().getBinder().getODataEntity( - getClient().getDeserializer().toEntry(input, format).getObject()); + getClient().getDeserializer().toEntry(input, format)); assertNotNull(entity); assertTrue(entity.isMediaEntity()); assertNotNull(entity.getMediaContentSource()); assertNotNull(entity.getMediaContentType()); - final ODataEntity written = getClient().getBinder().getODataEntity(getClient().getBinder(). - getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM))); + final ODataEntity written = getClient().getBinder().getODataEntity(new ResWrap((URI) null, null, getClient(). + getBinder().getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM)))); assertEquals(entity, written); } @@ -164,7 +167,7 @@ public class EntityTest extends AbstractTest { private void issue128(final ODataPubFormat format) throws EdmPrimitiveTypeException { final InputStream input = getClass().getResourceAsStream("AllGeoTypesSet_-5." + getSuffix(format)); final ODataEntity entity = getClient().getBinder().getODataEntity( - getClient().getDeserializer().toEntry(input, format).getObject()); + getClient().getDeserializer().toEntry(input, format)); assertNotNull(entity); final ODataProperty geogCollection = entity.getProperty("GeogCollection"); diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntitySetTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntitySetTest.java index cbca94254..88a0f07f3 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntitySetTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntitySetTest.java @@ -18,17 +18,20 @@ */ package org.apache.olingo.client.core.v4; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertEquals; import java.io.IOException; import java.io.InputStream; +import java.net.URI; import org.apache.olingo.client.api.v4.ODataClient; -import org.apache.olingo.commons.api.format.ODataPubFormat; import org.apache.olingo.client.core.AbstractTest; +import org.apache.olingo.commons.api.data.Feed; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.domain.v4.ODataEntity; import org.apache.olingo.commons.api.domain.v4.ODataEntitySet; +import org.apache.olingo.commons.api.format.ODataPubFormat; import org.apache.olingo.commons.core.op.ResourceFactory; import org.junit.Test; @@ -42,14 +45,15 @@ public class EntitySetTest extends AbstractTest { private void read(final ODataPubFormat format) throws IOException { final InputStream input = getClass().getResourceAsStream("Customers." + getSuffix(format)); final ODataEntitySet entitySet = getClient().getBinder().getODataEntitySet( - getClient().getDeserializer().toFeed(input, format).getObject()); + getClient().getDeserializer().toFeed(input, format)); assertNotNull(entitySet); assertEquals(2, entitySet.getEntities().size()); assertNull(entitySet.getNext()); - final ODataEntitySet written = getClient().getBinder().getODataEntitySet(getClient().getBinder(). - getFeed(entitySet, ResourceFactory.feedClassForFormat(format == ODataPubFormat.ATOM))); + final ODataEntitySet written = getClient().getBinder().getODataEntitySet(new ResWrap((URI) null, null, + getClient().getBinder().getFeed( + entitySet, ResourceFactory.feedClassForFormat(format == ODataPubFormat.ATOM)))); assertEquals(entitySet, written); } @@ -66,7 +70,7 @@ public class EntitySetTest extends AbstractTest { private void ref(final ODataPubFormat format) { final InputStream input = getClass().getResourceAsStream("collectionOfEntityReferences." + getSuffix(format)); final ODataEntitySet entitySet = getClient().getBinder().getODataEntitySet( - getClient().getDeserializer().toFeed(input, format).getObject()); + getClient().getDeserializer().toFeed(input, format)); assertNotNull(entitySet); for (ODataEntity entity : entitySet.getEntities()) { @@ -74,8 +78,9 @@ public class EntitySetTest extends AbstractTest { } entitySet.setCount(entitySet.getEntities().size()); - final ODataEntitySet written = getClient().getBinder().getODataEntitySet(getClient().getBinder(). - getFeed(entitySet, ResourceFactory.feedClassForFormat(format == ODataPubFormat.ATOM))); + final ODataEntitySet written = getClient().getBinder().getODataEntitySet(new ResWrap((URI) null, null, + getClient().getBinder().getFeed( + entitySet, ResourceFactory.feedClassForFormat(format == ODataPubFormat.ATOM)))); assertEquals(entitySet, written); } diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntityTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntityTest.java index 5707985ee..317f9160e 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntityTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntityTest.java @@ -24,9 +24,12 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.InputStream; +import java.net.URI; import java.util.Iterator; import org.apache.olingo.client.api.v4.ODataClient; import org.apache.olingo.client.core.AbstractTest; +import org.apache.olingo.commons.api.data.Entry; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.domain.ODataInlineEntitySet; import org.apache.olingo.commons.api.domain.ODataLink; import org.apache.olingo.commons.api.domain.ODataLinkType; @@ -50,7 +53,7 @@ public class EntityTest extends AbstractTest { private void singleton(final ODataPubFormat format) { final InputStream input = getClass().getResourceAsStream("VipCustomer." + getSuffix(format)); final ODataEntity entity = getClient().getBinder().getODataEntity( - getClient().getDeserializer().toEntry(input, format).getObject()); + getClient().getDeserializer().toEntry(input, format)); assertNotNull(entity); assertEquals("Microsoft.Test.OData.Services.ODataWCFService.Customer", entity.getTypeName().toString()); @@ -90,8 +93,8 @@ public class EntityTest extends AbstractTest { // operations won't get serialized entity.getOperations().clear(); - final ODataEntity written = getClient().getBinder().getODataEntity(getClient().getBinder(). - getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM))); + final ODataEntity written = getClient().getBinder().getODataEntity(new ResWrap((URI) null, null, getClient(). + getBinder().getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM)))); assertEquals(entity, written); } @@ -108,7 +111,7 @@ public class EntityTest extends AbstractTest { private void withEnums(final ODataPubFormat format) { final InputStream input = getClass().getResourceAsStream("Products_5." + getSuffix(format)); final ODataEntity entity = getClient().getBinder().getODataEntity( - getClient().getDeserializer().toEntry(input, format).getObject()); + getClient().getDeserializer().toEntry(input, format)); assertNotNull(entity); final ODataProperty skinColor = entity.getProperty("SkinColor"); @@ -125,8 +128,8 @@ public class EntityTest extends AbstractTest { // operations won't get serialized entity.getOperations().clear(); - final ODataEntity written = getClient().getBinder().getODataEntity(getClient().getBinder(). - getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM))); + final ODataEntity written = getClient().getBinder().getODataEntity(new ResWrap((URI) null, null, getClient(). + getBinder().getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM)))); assertEquals(entity, written); } @@ -144,7 +147,7 @@ public class EntityTest extends AbstractTest { final InputStream input = getClass().getResourceAsStream( "Accounts_101_expand_MyPaymentInstruments." + getSuffix(format)); final ODataEntity entity = getClient().getBinder().getODataEntity( - getClient().getDeserializer().toEntry(input, format).getObject()); + getClient().getDeserializer().toEntry(input, format)); assertNotNull(entity); final ODataLink instruments = entity.getNavigationLink("MyPaymentInstruments"); @@ -159,8 +162,8 @@ public class EntityTest extends AbstractTest { inline.getEntitySet().setCount(3); // operations won't get serialized entity.getOperations().clear(); - final ODataEntity written = getClient().getBinder().getODataEntity(getClient().getBinder(). - getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM))); + final ODataEntity written = getClient().getBinder().getODataEntity(new ResWrap((URI) null, null, getClient(). + getBinder().getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM)))); assertEquals(entity, written); } @@ -178,15 +181,15 @@ public class EntityTest extends AbstractTest { final InputStream input = getClass().getResourceAsStream( "Advertisements_f89dee73-af9f-4cd4-b330-db93c25ff3c7." + getSuffix(format)); final ODataEntity entity = getClient().getBinder().getODataEntity( - getClient().getDeserializer().toEntry(input, format).getObject()); + getClient().getDeserializer().toEntry(input, format)); assertNotNull(entity); assertTrue(entity.isMediaEntity()); assertNotNull(entity.getMediaContentSource()); assertEquals("\"8zOOKKvgOtptr4gt8IrnapX3jds=\"", entity.getMediaETag()); - final ODataEntity written = getClient().getBinder().getODataEntity(getClient().getBinder(). - getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM))); + final ODataEntity written = getClient().getBinder().getODataEntity(new ResWrap((URI) null, null, getClient(). + getBinder().getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM)))); assertEquals(entity, written); } @@ -203,7 +206,7 @@ public class EntityTest extends AbstractTest { private void withStream(final ODataPubFormat format) { final InputStream input = getClass().getResourceAsStream("PersonDetails_1." + getSuffix(format)); final ODataEntity entity = getClient().getBinder().getODataEntity( - getClient().getDeserializer().toEntry(input, format).getObject()); + getClient().getDeserializer().toEntry(input, format)); assertNotNull(entity); assertFalse(entity.isMediaEntity()); @@ -211,8 +214,8 @@ public class EntityTest extends AbstractTest { final ODataLink editMedia = entity.getEditMediaLink("Photo"); assertNotNull(editMedia); - final ODataEntity written = getClient().getBinder().getODataEntity(getClient().getBinder(). - getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM))); + final ODataEntity written = getClient().getBinder().getODataEntity(new ResWrap((URI) null, null, getClient(). + getBinder().getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM)))); assertEquals(entity, written); } @@ -229,13 +232,13 @@ public class EntityTest extends AbstractTest { private void ref(final ODataPubFormat format) { final InputStream input = getClass().getResourceAsStream("entityReference." + getSuffix(format)); final ODataEntity entity = getClient().getBinder().getODataEntity( - getClient().getDeserializer().toEntry(input, format).getObject()); + getClient().getDeserializer().toEntry(input, format)); assertNotNull(entity); assertNotNull(entity.getReference()); - final ODataEntity written = getClient().getBinder().getODataEntity(getClient().getBinder(). - getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM))); + final ODataEntity written = getClient().getBinder().getODataEntity(new ResWrap((URI) null, null, getClient(). + getBinder().getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM)))); assertEquals(entity, written); } @@ -252,7 +255,7 @@ public class EntityTest extends AbstractTest { private void complexNavigationProperties(final ODataPubFormat format) { final InputStream input = getClass().getResourceAsStream("entity.withcomplexnavigation." + getSuffix(format)); final ODataEntity entity = getClient().getBinder().getODataEntity( - getClient().getDeserializer().toEntry(input, format).getObject()); + getClient().getDeserializer().toEntry(input, format)); assertNotNull(entity); final ODataLinkedComplexValue addressValue = entity.getProperty("Address").getLinkedComplexValue(); @@ -261,8 +264,8 @@ public class EntityTest extends AbstractTest { // ETag is not serialized entity.setETag(null); - final ODataEntity written = getClient().getBinder().getODataEntity(getClient().getBinder(). - getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM))); + final ODataEntity written = getClient().getBinder().getODataEntity(new ResWrap((URI) null, null, getClient(). + getBinder().getEntry(entity, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM)))); assertEquals(entity, written); } diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/JSONTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/JSONTest.java index c2add6298..904e35ec4 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/JSONTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/JSONTest.java @@ -123,7 +123,7 @@ public class JSONTest extends AbstractTest { protected void feed(final String filename, final ODataPubFormat format) throws Exception { final StringWriter writer = new StringWriter(); getClient().getSerializer().feed(getClient().getDeserializer().toFeed( - getClass().getResourceAsStream(filename + "." + getSuffix(format)), format).getObject(), writer); + getClass().getResourceAsStream(filename + "." + getSuffix(format)), format).getPayload(), writer); assertSimilar(filename + "." + getSuffix(format), writer.toString()); } @@ -137,7 +137,7 @@ public class JSONTest extends AbstractTest { protected void entry(final String filename, final ODataPubFormat format) throws Exception { final StringWriter writer = new StringWriter(); getClient().getSerializer().entry(getClient().getDeserializer().toEntry( - getClass().getResourceAsStream(filename + "." + getSuffix(format)), format).getObject(), writer); + getClass().getResourceAsStream(filename + "." + getSuffix(format)), format).getPayload(), writer); assertSimilar(filename + "." + getSuffix(format), writer.toString()); } @@ -163,7 +163,8 @@ public class JSONTest extends AbstractTest { protected void property(final String filename, final ODataFormat format) throws Exception { final StringWriter writer = new StringWriter(); getClient().getSerializer().property(getClient().getDeserializer(). - toProperty(getClass().getResourceAsStream(filename + "." + getSuffix(format)), format).getObject(), writer); + toProperty(getClass().getResourceAsStream(filename + "." + getSuffix(format)), format).getPayload(), + writer); assertSimilar(filename + "." + getSuffix(format), writer.toString()); } diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ServiceDocumentTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ServiceDocumentTest.java index 08067abfe..c03619cde 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ServiceDocumentTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ServiceDocumentTest.java @@ -24,12 +24,11 @@ import static org.junit.Assert.assertTrue; import java.net.URI; import org.apache.olingo.client.api.data.ServiceDocument; - import org.apache.olingo.client.api.v4.ODataClient; import org.apache.olingo.commons.api.domain.ODataServiceDocument; import org.apache.olingo.commons.api.format.ODataFormat; import org.apache.olingo.client.core.AbstractTest; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.junit.Test; public class ServiceDocumentTest extends AbstractTest { @@ -44,13 +43,13 @@ public class ServiceDocumentTest extends AbstractTest { } private ODataServiceDocument parse(final ODataFormat format) { - Container service = getClient().getDeserializer().toServiceDocument( + ResWrap service = getClient().getDeserializer().toServiceDocument( getClass().getResourceAsStream("serviceDocument." + getFileExtension(format)), format); - assertEquals(URI.create("http://host/service/$metadata"), service.getContextURL()); + assertEquals(URI.create("http://host/service/$metadata"), service.getContextURL().getURI()); assertEquals("W/\"MjAxMy0wNS0xM1QxNDo1NFo=\"", service.getMetadataETag()); - final ODataServiceDocument serviceDocument = getClient().getBinder().getODataServiceDocument(service.getObject()); + final ODataServiceDocument serviceDocument = getClient().getBinder().getODataServiceDocument(service.getPayload()); assertNotNull(serviceDocument); assertTrue(serviceDocument.getEntitySetTitles().contains("Order Details")); @@ -69,6 +68,6 @@ public class ServiceDocumentTest extends AbstractTest { @Test public void xml() { - final ODataServiceDocument serviceDocument = parse(ODataFormat.XML); + parse(ODataFormat.XML); } } diff --git a/lib/commons-api/pom.xml b/lib/commons-api/pom.xml index 619703e0d..ce6849ae8 100644 --- a/lib/commons-api/pom.xml +++ b/lib/commons-api/pom.xml @@ -44,6 +44,12 @@ org.slf4j slf4j-api + + + junit + junit + test + diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ContextURL.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ContextURL.java new file mode 100644 index 000000000..c2d503e2c --- /dev/null +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ContextURL.java @@ -0,0 +1,152 @@ +/* + * 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. + */ +package org.apache.olingo.commons.api.data; + +import java.net.URI; +import org.apache.commons.lang3.StringUtils; +import org.apache.olingo.commons.api.Constants; + +/** + * High-level representation of a context URL, built from the string value returned by a service; provides access to the + * various components of the context URL, defined in the protocol specification. + * + * {@link http://docs.oasis-open.org/odata/odata/v4.0/os/part1-protocol/odata-v4.0-os-part1-protocol.html#_Toc372793655} + */ +public class ContextURL { + + private URI uri; + + private URI serviceRoot; + + private String entitySetOrSingletonOrType; + + private String derivedEntity; + + private String selectList; + + private String navOrPropertyPath; + + public static ContextURL getInstance(final URI contextURL) { + final ContextURL instance = new ContextURL(); + instance.uri = contextURL; + + final String contextURLasString = instance.uri.toASCIIString(). + replace("/$entity", StringUtils.EMPTY). + replace("/@Element", StringUtils.EMPTY); + + instance.serviceRoot = URI.create(StringUtils.substringBefore(contextURLasString, Constants.METADATA)); + + final String rest = StringUtils.substringAfter(contextURLasString, Constants.METADATA + "#"); + + String firstToken; + if (rest.startsWith("Collection(")) { + firstToken = rest.substring(0, rest.indexOf(')') + 1); + instance.entitySetOrSingletonOrType = firstToken; + } else { + final int openParIdx = rest.indexOf('('); + if (openParIdx == -1) { + firstToken = StringUtils.substringBefore(rest, "/"); + + instance.entitySetOrSingletonOrType = firstToken; + } else { + firstToken = StringUtils.substringBeforeLast(rest, ")") + ")"; + + instance.entitySetOrSingletonOrType = firstToken.substring(0, openParIdx); + final int commaIdx = firstToken.indexOf(','); + if (commaIdx != -1) { + instance.selectList = firstToken.substring(openParIdx + 1, firstToken.length() - 1); + } + } + } + + final int slashIdx = instance.entitySetOrSingletonOrType.indexOf('/'); + if (slashIdx != -1) { + final String clone = instance.entitySetOrSingletonOrType; + instance.entitySetOrSingletonOrType = clone.substring(0, slashIdx); + instance.derivedEntity = clone.substring(slashIdx + 1); + } + + if (!firstToken.equals(rest)) { + final String[] pathElems = StringUtils.substringAfter(rest, "/").split("/"); + if (pathElems.length > 0) { + if (pathElems[0].indexOf('.') == -1) { + instance.navOrPropertyPath = pathElems[0]; + } else { + instance.derivedEntity = pathElems[0]; + } + + if (pathElems.length > 1) { + instance.navOrPropertyPath = pathElems[1]; + } + } + } + + return instance; + } + + public URI getURI() { + return uri; + } + + public URI getServiceRoot() { + return serviceRoot; + } + + public String getEntitySetOrSingletonOrType() { + return entitySetOrSingletonOrType; + } + + public String getDerivedEntity() { + return derivedEntity; + } + + public String getSelectList() { + return selectList; + } + + public String getNavOrPropertyPath() { + return navOrPropertyPath; + } + + @Override + public boolean equals(final Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final ContextURL other = (ContextURL) obj; + if (this.uri != other.uri && (this.uri == null || !this.uri.equals(other.uri))) { + return false; + } + return true; + } + + @Override + public int hashCode() { + return this.uri.hashCode(); + } + + @Override + public String toString() { + return this.uri.toString(); + } + +} diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Container.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ResWrap.java similarity index 79% rename from lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Container.java rename to lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ResWrap.java index be3476b64..41c6c7b19 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Container.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ResWrap.java @@ -21,20 +21,26 @@ package org.apache.olingo.commons.api.data; import java.net.URI; /** - * Outermost response object container. + * Outermost response payload wrapper. + * + * @param the actual response payload */ -public class Container { +public class ResWrap { - private final URI contextURL; + private final ContextURL contextURL; private final String metadataETag; - private final T object; + private final T payload; - public Container(final URI contextURL, final String metadataETag, final T object) { + public ResWrap(final URI contextURL, final String metadataETag, final T payload) { + this(contextURL == null ? null : ContextURL.getInstance(contextURL), metadataETag, payload); + } + + public ResWrap(final ContextURL contextURL, final String metadataETag, final T payload) { this.contextURL = contextURL; this.metadataETag = metadataETag; - this.object = object; + this.payload = payload; } /** @@ -49,7 +55,7 @@ public class Container { * * @return context URL. */ - public URI getContextURL() { + public ContextURL getContextURL() { return contextURL; } @@ -70,7 +76,7 @@ public class Container { * * @return contained object. */ - public T getObject() { - return object; + public T getPayload() { + return payload; } } diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/AbstractODataValue.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/AbstractODataValue.java index 4fb9de956..29f651043 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/AbstractODataValue.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/AbstractODataValue.java @@ -79,7 +79,6 @@ public abstract class AbstractODataValue implements ODataValue { * * @return complex value. */ -// @SuppressWarnings("unchecked") @Override public ODataComplexValue asComplex() { return isComplex() ? (ODataComplexValue) this : null; @@ -100,7 +99,6 @@ public abstract class AbstractODataValue implements ODataValue { * * @return collection value. */ -// @SuppressWarnings("unchecked") @Override public ODataCollectionValue asCollection() { return isCollection() ? (ODataCollectionValue) this : null; diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataComplexValue.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataComplexValue.java index a0ad0c77f..77173b6e7 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataComplexValue.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataComplexValue.java @@ -31,6 +31,7 @@ public interface ODataComplexValue extends OData * Adds field to the complex type. * * @param field field to be added. + * @return this (for fluent-style calls) */ ODataComplexValue add(OP field); diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmNavigationProperty.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmNavigationProperty.java index 5f54154ea..b53e6170b 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmNavigationProperty.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmNavigationProperty.java @@ -27,11 +27,19 @@ import java.util.List; */ public interface EdmNavigationProperty extends EdmElement { + @Override + EdmEntityType getType(); + /** * @return true if nullable or null if not specified */ Boolean isNullable(); + /** + * @return true if containsTarget or null if not specified + */ + Boolean containsTarget(); + /** * @return the partner navigation property */ diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/op/CommonODataDeserializer.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/op/CommonODataDeserializer.java index 4b30ddd0c..52b010362 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/op/CommonODataDeserializer.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/op/CommonODataDeserializer.java @@ -20,7 +20,7 @@ package org.apache.olingo.commons.api.op; import java.io.InputStream; import java.io.Serializable; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.Entry; import org.apache.olingo.commons.api.domain.ODataError; import org.apache.olingo.commons.api.data.Feed; @@ -40,7 +40,7 @@ public interface CommonODataDeserializer extends Serializable { * @param format Atom or JSON * @return Feed instance. */ - Container toFeed(InputStream input, ODataPubFormat format); + ResWrap toFeed(InputStream input, ODataPubFormat format); /** * Gets an entry object from the given InputStream. @@ -49,7 +49,7 @@ public interface CommonODataDeserializer extends Serializable { * @param format Atom or JSON * @return Entry instance. */ - Container toEntry(InputStream input, ODataPubFormat format); + ResWrap toEntry(InputStream input, ODataPubFormat format); /** * Gets a property object from the given InputStream. @@ -58,7 +58,7 @@ public interface CommonODataDeserializer extends Serializable { * @param format XML or JSON * @return Property instance. */ - Container toProperty(InputStream input, ODataFormat format); + ResWrap toProperty(InputStream input, ODataFormat format); /** * Gets the ODataError object represented by the given InputStream. diff --git a/lib/commons-api/src/test/java/org/apache/olingo/commons/api/data/ContextURLTest.java b/lib/commons-api/src/test/java/org/apache/olingo/commons/api/data/ContextURLTest.java new file mode 100644 index 000000000..df7e6496f --- /dev/null +++ b/lib/commons-api/src/test/java/org/apache/olingo/commons/api/data/ContextURLTest.java @@ -0,0 +1,184 @@ +/* + * 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. + */ +package org.apache.olingo.commons.api.data; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.net.URI; +import org.junit.Test; + +public class ContextURLTest { + + @Test + public void collectionOfEntities() { + ContextURL contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#Customers")); + + assertEquals(URI.create("http://host/service/"), contextURL.getServiceRoot()); + assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + + contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#Orders(4711)/Items")); + + assertEquals("Orders", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertEquals("Items", contextURL.getNavOrPropertyPath()); + } + + @Test + public void entity() { + ContextURL contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#Customers/$entity")); + + assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + + contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#Orders(4711)/Items/$entity")); + + assertEquals("Orders", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertEquals("Items", contextURL.getNavOrPropertyPath()); + + // v3 + contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#Products/@Element")); + + assertEquals("Products", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + } + + @Test + public void singleton() { + ContextURL contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#Contoso")); + + assertEquals("Contoso", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + } + + @Test + public void collectionOfDerivedEntities() { + final ContextURL contextURL = ContextURL.getInstance( + URI.create("http://host/service/$metadata#Customers/Model.VipCustomer")); + + assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); + assertEquals("Model.VipCustomer", contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + } + + @Test + public void derivedEntity() { + final ContextURL contextURL = ContextURL.getInstance( + URI.create("http://host/service/$metadata#Customers/Model.VipCustomer/$entity")); + + assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); + assertEquals("Model.VipCustomer", contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + } + + @Test + public void collectionOfProjectedEntities() { + final ContextURL contextURL = ContextURL.getInstance( + URI.create("http://host/service/$metadata#Customers(Address,Orders)")); + + assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertEquals("Address,Orders", contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + } + + @Test + public void projectedEntity() { + ContextURL contextURL = ContextURL.getInstance( + URI.create("http://host/service/$metadata#Customers(Name,Rating)/$entity")); + + assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertEquals("Name,Rating", contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + + contextURL = ContextURL.getInstance( + URI.create("http://host/service/$metadata#Customers(Name,Address/Country)")); + + assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertEquals("Name,Address/Country", contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + } + + @Test + public void collectionOfProjectedExpandedEntities() { + final ContextURL contextURL = ContextURL.getInstance( + URI.create("http://host/service/$metadata#Employees/" + + "Sales.Manager(DirectReports,DirectReports+(FirstName,LastName))")); + + assertEquals("Employees", contextURL.getEntitySetOrSingletonOrType()); + assertEquals("Sales.Manager", contextURL.getDerivedEntity()); + assertEquals("DirectReports,DirectReports+(FirstName,LastName)", contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + } + + @Test + public void propertyValue() { + final ContextURL contextURL = ContextURL.getInstance( + URI.create("http://host/service/$metadata#Customers(1)/Addresses")); + + assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertEquals("Addresses", contextURL.getNavOrPropertyPath()); + } + + @Test + public void CollectionOfComplexOrPrimitiveTypes() { + final ContextURL contextURL = ContextURL.getInstance( + URI.create("http://host/service/$metadata#Collection(Edm.String)")); + + assertEquals("Collection(Edm.String)", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + } + + @Test + public void complexOrPrimitiveType() { + ContextURL contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#Edm.String")); + + assertEquals("Edm.String", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + + contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#ODataDemo.Address")); + + assertEquals("ODataDemo.Address", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + } +} diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonDeserializer.java index 7eaf66921..97be4eb66 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonDeserializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonDeserializer.java @@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import java.io.IOException; +import java.util.AbstractMap.SimpleEntry; import java.util.HashSet; import java.util.Iterator; import java.util.Map; @@ -32,7 +33,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.data.CollectionValue; import org.apache.olingo.commons.api.data.ComplexValue; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.Linked; import org.apache.olingo.commons.api.data.Value; import org.apache.olingo.commons.api.domain.ODataLinkType; @@ -41,7 +42,7 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.commons.core.edm.EdmTypeInfo; -abstract class AbstractJsonDeserializer extends ODataJacksonDeserializer> { +abstract class AbstractJsonDeserializer extends ODataJacksonDeserializer> { private JSONGeoValueDeserializer geoDeserializer; @@ -66,9 +67,9 @@ abstract class AbstractJsonDeserializer extends ODataJacksonDeserializer>readValueAs( + link.setInlineEntry(inline.traverse(codec).>readValueAs( new TypeReference() { - }).getObject()); + }).getPayload()); } if (inline instanceof ArrayNode) { @@ -77,9 +78,9 @@ abstract class AbstractJsonDeserializer extends ODataJacksonDeserializer entries = ((ArrayNode) inline).elements(); while (entries.hasNext()) { - feed.getEntries().add(entries.next().traverse(codec).>readValuesAs( + feed.getEntries().add(entries.next().traverse(codec).>readValuesAs( new TypeReference() { - }).next().getObject()); + }).next().getPayload()); } link.setInlineFeed(feed); @@ -144,8 +145,9 @@ abstract class AbstractJsonDeserializer extends ODataJacksonDeserializer itor = field.getValue().elements(); itor.hasNext();) { + for (final Iterator itor = field.getValue().elements(); itor.hasNext();) { final JsonNode node = itor.next(); + final LinkImpl link = new LinkImpl(); link.setTitle(getTitle(field)); link.setRel(version.getNamespaceMap().get(ODataServiceVersion.NAVIGATION_LINK_REL) + getTitle(field)); @@ -159,42 +161,46 @@ abstract class AbstractJsonDeserializer extends ODataJacksonDeserializer guessPropertyType(final JsonNode node) { + ODataPropertyType type; + EdmTypeInfo typeInfo = null; if (node.isValueNode() || node.isNull()) { type = ODataPropertyType.PRIMITIVE; + + EdmPrimitiveTypeKind kind = EdmPrimitiveTypeKind.String; + if (node.isShort()) { + kind = EdmPrimitiveTypeKind.Int16; + } else if (node.isIntegralNumber()) { + kind = EdmPrimitiveTypeKind.Int32; + } else if (node.isLong()) { + kind = EdmPrimitiveTypeKind.Int64; + } else if (node.isBigDecimal()) { + kind = EdmPrimitiveTypeKind.Decimal; + } else if (node.isBoolean()) { + kind = EdmPrimitiveTypeKind.Boolean; + } else if (node.isFloat()) { + kind = EdmPrimitiveTypeKind.Single; + } else if (node.isDouble()) { + kind = EdmPrimitiveTypeKind.Double; + } + typeInfo = new EdmTypeInfo.Builder(). + setTypeExpression(kind.getFullQualifiedName().toString()).build(); } else if (node.isArray()) { type = ODataPropertyType.COLLECTION; } else if (node.isObject()) { - type = ODataPropertyType.COMPLEX; + if (node.has(Constants.ATTR_TYPE) && node.has(Constants.JSON_CRS)) { + type = ODataPropertyType.PRIMITIVE; + typeInfo = new EdmTypeInfo.Builder(). + setTypeExpression("Edm.Geography" + node.get(Constants.ATTR_TYPE).asText()).build(); + } else { + type = ODataPropertyType.COMPLEX; + } } else { type = ODataPropertyType.EMPTY; } - return type; + return new SimpleEntry(type, typeInfo); } private Value fromPrimitive(final JsonNode node, final EdmTypeInfo typeInfo) { @@ -280,12 +286,17 @@ abstract class AbstractJsonDeserializer extends ODataJacksonDeserializer guessed = guessPropertyType(node); + if (typeInfo == null) { + typeInfo = guessed.getValue(); + } + final ODataPropertyType propType = typeInfo == null - ? guessPropertyType(node) + ? guessed.getKey() : typeInfo.isCollection() ? ODataPropertyType.COLLECTION : typeInfo.isPrimitiveType() @@ -312,8 +323,8 @@ abstract class AbstractJsonDeserializer extends ODataJacksonDeserializer property(final InputStream input) throws XMLStreamException { + private ResWrap property(final InputStream input) throws XMLStreamException { final XMLEventReader reader = getReader(input); final StartElement start = skipBeforeFirstStartElement(reader); return getContainer(start, property(reader, start)); @@ -366,7 +366,7 @@ public class AtomDeserializer extends AbstractAtomDealer { } } - private Container linkCollection(final InputStream input) throws XMLStreamException { + private ResWrap linkCollection(final InputStream input) throws XMLStreamException { final XMLEventReader reader = getReader(input); final StartElement start = skipBeforeFirstStartElement(reader); return getContainer(start, linkCollection(reader, start)); @@ -552,7 +552,7 @@ public class AtomDeserializer extends AbstractAtomDealer { return entry; } - private Container entry(final InputStream input) throws XMLStreamException { + private ResWrap entry(final InputStream input) throws XMLStreamException { final XMLEventReader reader = getReader(input); final StartElement start = skipBeforeFirstStartElement(reader); return getContainer(start, entry(reader, start)); @@ -622,7 +622,7 @@ public class AtomDeserializer extends AbstractAtomDealer { return feed; } - private Container feed(final InputStream input) throws XMLStreamException { + private ResWrap feed(final InputStream input) throws XMLStreamException { final XMLEventReader reader = getReader(input); final StartElement start = skipBeforeFirstStartElement(reader); return getContainer(start, feed(reader, start)); @@ -678,36 +678,36 @@ public class AtomDeserializer extends AbstractAtomDealer { return error; } - private Container error(final InputStream input) throws XMLStreamException { + private ResWrap error(final InputStream input) throws XMLStreamException { final XMLEventReader reader = getReader(input); final StartElement start = skipBeforeFirstStartElement(reader); return getContainer(start, error(reader, start)); } - private Container getContainer(final StartElement start, final T object) { + private ResWrap getContainer(final StartElement start, final T object) { final Attribute context = start.getAttributeByName(contextQName); final Attribute metadataETag = start.getAttributeByName(metadataEtagQName); - return new Container( + return new ResWrap( context == null ? null : URI.create(context.getValue()), metadataETag == null ? null : metadataETag.getValue(), object); } @SuppressWarnings("unchecked") - public Container read(final InputStream input, final Class reference) + public ResWrap read(final InputStream input, final Class reference) throws XMLStreamException { if (XMLODataErrorImpl.class.equals(reference)) { - return (Container) error(input); + return (ResWrap) error(input); } else if (AtomFeedImpl.class.equals(reference)) { - return (Container) feed(input); + return (ResWrap) feed(input); } else if (AtomEntryImpl.class.equals(reference)) { - return (Container) entry(input); + return (ResWrap) entry(input); } else if (AtomPropertyImpl.class.equals(reference)) { - return (Container) property(input); + return (ResWrap) property(input); } else if (XMLLinkCollectionImpl.class.equals(reference)) { - return (Container) linkCollection(input); + return (ResWrap) linkCollection(input); } return null; } 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 6b8746985..aba3d16d2 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 @@ -28,7 +28,7 @@ import javax.xml.stream.XMLStreamWriter; import org.apache.commons.lang3.StringUtils; import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.data.CollectionValue; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.Entry; import org.apache.olingo.commons.api.data.Feed; import org.apache.olingo.commons.api.data.Link; @@ -291,11 +291,11 @@ public class AtomSerializer extends AbstractAtomDealer { writer.writeAttribute(Constants.ATOM_ATTR_ID, entry.getId()); } - private void entryRef(final XMLStreamWriter writer, final Container container) throws XMLStreamException { + private void entryRef(final XMLStreamWriter writer, final ResWrap container) throws XMLStreamException { writer.writeStartElement(Constants.ATOM_ELEM_ENTRY_REF); writer.writeNamespace(StringUtils.EMPTY, version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA)); addContextInfo(writer, container); - writer.writeAttribute(Constants.ATOM_ATTR_ID, container.getObject().getId()); + writer.writeAttribute(Constants.ATOM_ATTR_ID, container.getPayload().getId()); } private void entry(final Writer outWriter, final Entry entry) throws XMLStreamException { @@ -317,8 +317,8 @@ public class AtomSerializer extends AbstractAtomDealer { writer.flush(); } - private void entry(final Writer outWriter, final Container container) throws XMLStreamException { - final Entry entry = container.getObject(); + private void entry(final Writer outWriter, final ResWrap container) throws XMLStreamException { + final Entry entry = container.getPayload(); final XMLStreamWriter writer = FACTORY.createXMLStreamWriter(outWriter); @@ -394,14 +394,14 @@ public class AtomSerializer extends AbstractAtomDealer { writer.flush(); } - private void feed(final Writer outWriter, final Container feed) throws XMLStreamException { + private void feed(final Writer outWriter, final ResWrap feed) throws XMLStreamException { final XMLStreamWriter writer = FACTORY.createXMLStreamWriter(outWriter); startDocument(writer, Constants.ATOM_ELEM_FEED); addContextInfo(writer, feed); - feed(writer, feed.getObject()); + feed(writer, feed.getPayload()); writer.writeEndElement(); writer.writeEndDocument(); @@ -439,13 +439,13 @@ public class AtomSerializer extends AbstractAtomDealer { } @SuppressWarnings("unchecked") - public void write(final Writer writer, final Container container) throws XMLStreamException { - final T obj = container == null ? null : container.getObject(); + public void write(final Writer writer, final ResWrap container) throws XMLStreamException { + final T obj = container == null ? null : container.getPayload(); if (obj instanceof Feed) { - this.feed(writer, (Container) container); + this.feed(writer, (ResWrap) container); } else if (obj instanceof Entry) { - entry(writer, (Container) container); + entry(writer, (ResWrap) container); } else if (obj instanceof Property) { property(writer, (Property) obj); } else if (obj instanceof Link) { @@ -454,21 +454,21 @@ public class AtomSerializer extends AbstractAtomDealer { } private void addContextInfo( - final XMLStreamWriter writer, final Container container) throws XMLStreamException { + final XMLStreamWriter writer, final ResWrap container) throws XMLStreamException { if (container.getContextURL() != null) { - final String base = StringUtils.substringBefore(container.getContextURL().toASCIIString(), Constants.METADATA); - if (container.getObject() instanceof AtomFeedImpl) { - ((AtomFeedImpl) container.getObject()).setBaseURI(base); + String base = container.getContextURL().getServiceRoot().toASCIIString(); + if (container.getPayload() instanceof AtomFeedImpl) { + ((AtomFeedImpl) container.getPayload()).setBaseURI(base); } - if (container.getObject() instanceof AtomEntryImpl) { - ((AtomEntryImpl) container.getObject()).setBaseURI(base); + if (container.getPayload() instanceof AtomEntryImpl) { + ((AtomEntryImpl) container.getPayload()).setBaseURI(base); } writer.writeAttribute( version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.CONTEXT, - container.getContextURL().toASCIIString()); + container.getContextURL().getURI().toASCIIString()); } if (StringUtils.isNotBlank(container.getMetadataETag())) { diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONEntryDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONEntryDeserializer.java index 34936484e..dce4b7407 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONEntryDeserializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONEntryDeserializer.java @@ -32,7 +32,7 @@ import java.util.Map; import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.apache.olingo.commons.api.Constants; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.Link; import org.apache.olingo.commons.api.domain.ODataLinkType; import org.apache.olingo.commons.api.domain.ODataOperation; @@ -47,7 +47,7 @@ import org.apache.olingo.commons.core.edm.EdmTypeInfo; public class JSONEntryDeserializer extends AbstractJsonDeserializer { @Override - protected Container doDeserialize(final JsonParser parser, final DeserializationContext ctxt) + protected ResWrap doDeserialize(final JsonParser parser, final DeserializationContext ctxt) throws IOException, JsonProcessingException { final ObjectNode tree = parser.getCodec().readTree(parser); @@ -195,6 +195,6 @@ public class JSONEntryDeserializer extends AbstractJsonDeserializer(contextURL, metadataETag, entry); + return new ResWrap(contextURL, metadataETag, entry); } } 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 b7dcf8d7d..a5c2c3361 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 @@ -25,7 +25,7 @@ import java.io.IOException; import java.net.URI; import org.apache.commons.lang3.StringUtils; import org.apache.olingo.commons.api.Constants; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.Entry; import org.apache.olingo.commons.api.data.Link; import org.apache.olingo.commons.api.data.Property; @@ -41,15 +41,16 @@ public class JSONEntrySerializer extends AbstractJsonSerializer { @Override protected void doSerialize(final JSONEntryImpl entry, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException { - doContainerSerialize(new Container(null, null, entry), jgen, provider); + + doContainerSerialize(new ResWrap((URI) null, null, entry), jgen, provider); } @Override protected void doContainerSerialize( - final Container container, final JsonGenerator jgen, final SerializerProvider provider) + final ResWrap container, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException { - final Entry entry = container.getObject(); + final Entry entry = container.getPayload(); jgen.writeStartObject(); @@ -57,7 +58,7 @@ public class JSONEntrySerializer extends AbstractJsonSerializer { if (container.getContextURL() != null) { jgen.writeStringField(version.compareTo(ODataServiceVersion.V40) >= 0 ? Constants.JSON_CONTEXT : Constants.JSON_METADATA, - container.getContextURL().toASCIIString()); + container.getContextURL().getURI().toASCIIString()); } if (version.compareTo(ODataServiceVersion.V40) >= 0 && StringUtils.isNotBlank(container.getMetadataETag())) { jgen.writeStringField(Constants.JSON_METADATA_ETAG, container.getMetadataETag()); diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONFeedDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONFeedDeserializer.java index 238e56b15..a9f80c446 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONFeedDeserializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONFeedDeserializer.java @@ -28,7 +28,7 @@ import java.io.IOException; import java.net.URI; import java.util.Iterator; import org.apache.olingo.commons.api.Constants; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; /** * Reads JSON string into a feed. @@ -38,7 +38,7 @@ import org.apache.olingo.commons.api.data.Container; public class JSONFeedDeserializer extends AbstractJsonDeserializer { @Override - protected Container doDeserialize(final JsonParser parser, final DeserializationContext ctxt) + protected ResWrap doDeserialize(final JsonParser parser, final DeserializationContext ctxt) throws IOException, JsonProcessingException { final ObjectNode tree = (ObjectNode) parser.getCodec().readTree(parser); @@ -79,12 +79,12 @@ public class JSONFeedDeserializer extends AbstractJsonDeserializer if (tree.hasNonNull(Constants.VALUE)) { for (final Iterator itor = tree.get(Constants.VALUE).iterator(); itor.hasNext();) { feed.getEntries().add( - itor.next().traverse(parser.getCodec()).>readValueAs( + itor.next().traverse(parser.getCodec()).>readValueAs( new TypeReference() { - }).getObject()); + }).getPayload()); } } - return new Container(contextURL, metadataETag, feed); + return new ResWrap(contextURL, metadataETag, feed); } } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONFeedSerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONFeedSerializer.java index 6a4728df2..457b34c98 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONFeedSerializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONFeedSerializer.java @@ -22,9 +22,10 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; +import java.net.URI; import org.apache.commons.lang3.StringUtils; import org.apache.olingo.commons.api.Constants; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.Entry; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; @@ -34,15 +35,16 @@ public class JSONFeedSerializer extends AbstractJsonSerializer { protected void doSerialize( final JSONFeedImpl feed, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException { - doContainerSerialize(new Container(null, null, feed), jgen, provider); + + doContainerSerialize(new ResWrap((URI) null, null, feed), jgen, provider); } @Override protected void doContainerSerialize( - final Container container, final JsonGenerator jgen, final SerializerProvider provider) + final ResWrap container, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException { - final JSONFeedImpl feed = container.getObject(); + final JSONFeedImpl feed = container.getPayload(); jgen.writeStartObject(); @@ -50,7 +52,7 @@ public class JSONFeedSerializer extends AbstractJsonSerializer { if (container.getContextURL() != null) { jgen.writeStringField(version.compareTo(ODataServiceVersion.V40) >= 0 ? Constants.JSON_CONTEXT : Constants.JSON_METADATA, - container.getContextURL().toASCIIString()); + container.getContextURL().getURI().toASCIIString()); } if (version.compareTo(ODataServiceVersion.V40) >= 0 && StringUtils.isNotBlank(container.getMetadataETag())) { diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorDeserializer.java index de3ffa113..43ee06cda 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorDeserializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorDeserializer.java @@ -24,13 +24,14 @@ import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import java.io.IOException; +import java.net.URI; import org.apache.olingo.commons.api.Constants; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; public class JSONODataErrorDeserializer extends AbstractJsonDeserializer { @Override - protected Container doDeserialize(final JsonParser parser, final DeserializationContext ctxt) + protected ResWrap doDeserialize(final JsonParser parser, final DeserializationContext ctxt) throws IOException, JsonProcessingException { final JSONODataErrorImpl error = new JSONODataErrorImpl(); @@ -55,6 +56,6 @@ public class JSONODataErrorDeserializer extends AbstractJsonDeserializer(null, null, error); + return new ResWrap((URI) null, null, error); } } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONPropertyDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONPropertyDeserializer.java index 6d8f0e268..74ae1d40c 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONPropertyDeserializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONPropertyDeserializer.java @@ -26,7 +26,7 @@ import java.io.IOException; import java.net.URI; import org.apache.commons.lang3.StringUtils; import org.apache.olingo.commons.api.Constants; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.core.edm.EdmTypeInfo; /** @@ -37,7 +37,7 @@ import org.apache.olingo.commons.core.edm.EdmTypeInfo; public class JSONPropertyDeserializer extends AbstractJsonDeserializer { @Override - protected Container doDeserialize(final JsonParser parser, final DeserializationContext ctxt) + protected ResWrap doDeserialize(final JsonParser parser, final DeserializationContext ctxt) throws IOException, JsonProcessingException { final ObjectNode tree = (ObjectNode) parser.getCodec().readTree(parser); @@ -78,6 +78,6 @@ public class JSONPropertyDeserializer extends AbstractJsonDeserializer(contextURL, metadataETag, property); + return new ResWrap(contextURL, metadataETag, property); } } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONPropertySerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONPropertySerializer.java index 4f20e69e0..74e8cf008 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONPropertySerializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONPropertySerializer.java @@ -22,9 +22,10 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; +import java.net.URI; import org.apache.commons.lang3.StringUtils; import org.apache.olingo.commons.api.Constants; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.Property; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.commons.core.edm.EdmTypeInfo; @@ -39,22 +40,23 @@ public class JSONPropertySerializer extends AbstractJsonSerializer(null, null, property), jgen, provider); + + doContainerSerialize(new ResWrap((URI) null, null, property), jgen, provider); } @Override protected void doContainerSerialize( - final Container container, final JsonGenerator jgen, final SerializerProvider provider) + final ResWrap container, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException { - final Property property = container.getObject(); + final Property property = container.getPayload(); jgen.writeStartObject(); if (serverMode && container.getContextURL() != null) { jgen.writeStringField(version.compareTo(ODataServiceVersion.V40) >= 0 ? Constants.JSON_CONTEXT : Constants.JSON_METADATA, - container.getContextURL().toASCIIString()); + container.getContextURL().getURI().toASCIIString()); } if (StringUtils.isNotBlank(property.getType())) { diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/ODataJacksonSerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/ODataJacksonSerializer.java index 1e331d43c..944fb5174 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/ODataJacksonSerializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/ODataJacksonSerializer.java @@ -24,7 +24,7 @@ import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; @@ -37,7 +37,7 @@ public abstract class ODataJacksonSerializer extends JsonSerializer { protected abstract void doSerialize(T value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException; - protected abstract void doContainerSerialize(Container value, JsonGenerator jgen, SerializerProvider provider) + protected abstract void doContainerSerialize(ResWrap value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException; @Override @@ -48,8 +48,8 @@ public abstract class ODataJacksonSerializer extends JsonSerializer { version = (ODataServiceVersion) provider.getAttribute(ODataServiceVersion.class); serverMode = (Boolean) provider.getAttribute(Boolean.class); - if (value instanceof Container) { - doContainerSerialize((Container) value, jgen, provider); + if (value instanceof ResWrap) { + doContainerSerialize((ResWrap) value, jgen, provider); } else { doSerialize(value, jgen, provider); } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmNavigationProperty.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmNavigationProperty.java index 0d97ba645..e14879e2f 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmNavigationProperty.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmNavigationProperty.java @@ -39,7 +39,7 @@ public abstract class AbstractEdmNavigationProperty extends EdmElementImpl imple protected abstract FullQualifiedName getTypeFQN(); @Override - public EdmType getType() { + public EdmEntityType getType() { if (typeImpl == null) { typeImpl = edm.getEntityType(getTypeFQN()); if (typeImpl == null) { diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/op/AbstractODataDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/op/AbstractODataDeserializer.java index ceb6b7e6b..29eed4a15 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/op/AbstractODataDeserializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/op/AbstractODataDeserializer.java @@ -21,6 +21,7 @@ package org.apache.olingo.commons.core.op; import com.fasterxml.jackson.core.type.TypeReference; import java.io.InputStream; import java.lang.reflect.Type; +import java.net.URI; import org.apache.olingo.commons.api.data.Entry; import org.apache.olingo.commons.api.domain.ODataError; import org.apache.olingo.commons.api.data.Feed; @@ -30,7 +31,7 @@ import org.apache.olingo.commons.api.format.ODataPubFormat; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.commons.api.op.CommonODataDeserializer; import org.apache.olingo.commons.core.data.AtomDeserializer; -import org.apache.olingo.commons.api.data.Container; +import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.core.data.AtomEntryImpl; import org.apache.olingo.commons.core.data.AtomFeedImpl; import org.apache.olingo.commons.core.data.AtomPropertyImpl; @@ -53,21 +54,21 @@ public abstract class AbstractODataDeserializer extends AbstractJacksonTool impl } @Override - public Container toFeed(final InputStream input, final ODataPubFormat format) { + public ResWrap toFeed(final InputStream input, final ODataPubFormat format) { return format == ODataPubFormat.ATOM ? this.atom(input, AtomFeedImpl.class) : this.json(input, JSONFeedImpl.class); } @Override - public Container toEntry(final InputStream input, final ODataPubFormat format) { + public ResWrap toEntry(final InputStream input, final ODataPubFormat format) { return format == ODataPubFormat.ATOM ? this.atom(input, AtomEntryImpl.class) : this.json(input, JSONEntryImpl.class); } @Override - public Container toProperty(final InputStream input, final ODataFormat format) { + public ResWrap toProperty(final InputStream input, final ODataFormat format) { return format == ODataFormat.XML ? this.atom(input, AtomPropertyImpl.class) : this.json(input, JSONPropertyImpl.class); @@ -76,14 +77,14 @@ public abstract class AbstractODataDeserializer extends AbstractJacksonTool impl @Override public ODataError toError(final InputStream input, final boolean isXML) { return isXML - ? this.atom(input, XMLODataErrorImpl.class).getObject() - : this.json(input, JSONODataErrorImpl.class).getObject(); + ? this.atom(input, XMLODataErrorImpl.class).getPayload() + : this.json(input, JSONODataErrorImpl.class).getPayload(); } /* * ------------------ Protected methods ------------------ */ - protected Container atom(final InputStream input, final Class reference) { + protected ResWrap atom(final InputStream input, final Class reference) { try { return atomDeserializer.read(input, reference); } catch (Exception e) { @@ -92,7 +93,7 @@ public abstract class AbstractODataDeserializer extends AbstractJacksonTool impl } @SuppressWarnings("unchecked") - protected Container xml(final InputStream input, final Class reference) { + protected ResWrap xml(final InputStream input, final Class reference) { try { final T obj = getXmlMapper().readValue(input, new TypeReference() { @Override @@ -101,14 +102,14 @@ public abstract class AbstractODataDeserializer extends AbstractJacksonTool impl } }); - return obj instanceof Container ? (Container) obj : new Container(null, null, obj); + return obj instanceof ResWrap ? (ResWrap) obj : new ResWrap((URI) null, null, obj); } catch (Exception e) { throw new IllegalArgumentException("While deserializing " + reference.getName(), e); } } @SuppressWarnings("unchecked") - protected Container json(final InputStream input, final Class reference) { + protected ResWrap json(final InputStream input, final Class reference) { try { final T obj = getObjectMapper().readValue(input, new TypeReference() { @Override @@ -117,7 +118,7 @@ public abstract class AbstractODataDeserializer extends AbstractJacksonTool impl } }); - return obj instanceof Container ? (Container) obj : new Container(null, null, obj); + return obj instanceof ResWrap ? (ResWrap) obj : new ResWrap((URI) null, null, obj); } catch (Exception e) { throw new IllegalArgumentException("While deserializing " + reference.getName(), e); } diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/edm/provider/EdmNavigationPropertyImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/edm/provider/EdmNavigationPropertyImpl.java index 4c7e0cb23..b5d17dee0 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/edm/provider/EdmNavigationPropertyImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/edm/provider/EdmNavigationPropertyImpl.java @@ -32,6 +32,7 @@ import org.apache.olingo.server.api.edm.provider.ReferentialConstraint; public class EdmNavigationPropertyImpl extends AbstractEdmNavigationProperty { private final NavigationProperty navigationProperty; + private List referentialConstraints; public EdmNavigationPropertyImpl(final Edm edm, final NavigationProperty navigationProperty) { @@ -54,6 +55,11 @@ public class EdmNavigationPropertyImpl extends AbstractEdmNavigationProperty { return navigationProperty.getNullable(); } + @Override + public Boolean containsTarget() { + return navigationProperty.isContainsTarget(); + } + @Override protected String internatGetPartner() { return navigationProperty.getPartner(); @@ -80,7 +86,7 @@ public class EdmNavigationPropertyImpl extends AbstractEdmNavigationProperty { if (providerConstraints != null) { for (ReferentialConstraint constraint : providerConstraints) { referentialConstraints.add(new EdmReferentialConstraintImpl(constraint.getProperty(), constraint - .getReferencedProperty())); + .getReferencedProperty())); } } }