You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by fm...@apache.org on 2014/03/24 10:38:52 UTC
[1/8] [OLINGO-205,
OLINGO-200] provided atom v4 deserialization for entity type/set +
entity set request
Repository: incubator-olingo-odata4
Updated Branches:
refs/heads/olingo200 a55ed62ac -> f0edb5081
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmStructuredType.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmStructuredType.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmStructuredType.java
index d48fda4..a807052 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmStructuredType.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmStructuredType.java
@@ -34,96 +34,99 @@ import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
public abstract class AbstractEdmStructuredType extends EdmTypeImpl implements EdmStructuredType {
- protected EdmStructuredType baseType;
+ protected EdmStructuredType baseType;
- private List<String> propertyNames;
+ private List<String> propertyNames;
- private List<String> navigationPropertyNames;
+ private List<String> navigationPropertyNames;
- public AbstractEdmStructuredType(final Edm edm, final FullQualifiedName fqn, final EdmTypeKind kind,
- final FullQualifiedName baseTypeName) {
+ public AbstractEdmStructuredType(
+ final Edm edm,
+ final FullQualifiedName fqn,
+ final EdmTypeKind kind,
+ final FullQualifiedName baseTypeName) {
- super(edm, fqn, kind);
- }
+ super(edm, fqn, kind);
+ }
- protected abstract EdmStructuredType buildBaseType(FullQualifiedName baseTypeName);
+ protected abstract EdmStructuredType buildBaseType(FullQualifiedName baseTypeName);
- protected abstract Map<String, EdmProperty> getProperties();
+ protected abstract Map<String, EdmProperty> getProperties();
- protected abstract Map<String, EdmNavigationProperty> getNavigationProperties();
+ protected abstract Map<String, EdmNavigationProperty> getNavigationProperties();
- @Override
- public List<String> getPropertyNames() {
- if (propertyNames == null) {
- propertyNames = new ArrayList<String>();
- if (baseType != null) {
- propertyNames.addAll(baseType.getPropertyNames());
- }
- propertyNames.addAll(getProperties().keySet());
- }
- return propertyNames;
- }
-
- @Override
- public List<String> getNavigationPropertyNames() {
- if (navigationPropertyNames == null) {
- navigationPropertyNames = new ArrayList<String>();
- if (baseType != null) {
- navigationPropertyNames.addAll(baseType.getNavigationPropertyNames());
- }
- navigationPropertyNames.addAll(getNavigationProperties().keySet());
- }
- return navigationPropertyNames;
- }
-
- @Override
- public EdmElement getProperty(final String name) {
- EdmElement property = getStructuralProperty(name);
- if (property == null) {
- property = getNavigationProperty(name);
- }
- return property;
- }
-
- @Override
- public EdmProperty getStructuralProperty(final String name) {
- EdmProperty property = null;
- if (baseType != null) {
- property = baseType.getStructuralProperty(name);
- }
- if (property == null) {
- property = getProperties().get(name);
+ @Override
+ public List<String> getPropertyNames() {
+ if (propertyNames == null) {
+ propertyNames = new ArrayList<String>();
+ if (baseType != null) {
+ propertyNames.addAll(baseType.getPropertyNames());
+ }
+ propertyNames.addAll(getProperties().keySet());
+ }
+ return propertyNames;
}
- return property;
- }
-
- @Override
- public EdmNavigationProperty getNavigationProperty(final String name) {
- EdmNavigationProperty property = null;
- if (baseType != null) {
- property = baseType.getNavigationProperty(name);
+
+ @Override
+ public List<String> getNavigationPropertyNames() {
+ if (navigationPropertyNames == null) {
+ navigationPropertyNames = new ArrayList<String>();
+ if (baseType != null) {
+ navigationPropertyNames.addAll(baseType.getNavigationPropertyNames());
+ }
+ navigationPropertyNames.addAll(getNavigationProperties().keySet());
+ }
+ return navigationPropertyNames;
}
- if (property == null) {
- property = getNavigationProperties().get(name);
+
+ @Override
+ public EdmElement getProperty(final String name) {
+ EdmElement property = getStructuralProperty(name);
+ if (property == null) {
+ property = getNavigationProperty(name);
+ }
+ return property;
}
- return property;
- }
-
- @Override
- public boolean compatibleTo(final EdmType targetType) {
- EdmStructuredType sourceType = this;
- if (targetType == null) {
- throw new EdmException("Target type must not be null");
+
+ @Override
+ public EdmProperty getStructuralProperty(final String name) {
+ EdmProperty property = null;
+ if (baseType != null) {
+ property = baseType.getStructuralProperty(name);
+ }
+ if (property == null) {
+ property = getProperties().get(name);
+ }
+ return property;
}
- while (!sourceType.getName().equals(targetType.getName())
- || !sourceType.getNamespace().equals(targetType.getNamespace())) {
-
- sourceType = sourceType.getBaseType();
- if (sourceType == null) {
- return false;
- }
+
+ @Override
+ public EdmNavigationProperty getNavigationProperty(final String name) {
+ EdmNavigationProperty property = null;
+ if (baseType != null) {
+ property = baseType.getNavigationProperty(name);
+ }
+ if (property == null) {
+ property = getNavigationProperties().get(name);
+ }
+ return property;
}
- return true;
- }
+ @Override
+ public boolean compatibleTo(final EdmType targetType) {
+ EdmStructuredType sourceType = this;
+ if (targetType == null) {
+ throw new EdmException("Target type must not be null");
+ }
+ while (!sourceType.getName().equals(targetType.getName())
+ || !sourceType.getNamespace().equals(targetType.getNamespace())) {
+
+ sourceType = sourceType.getBaseType();
+ if (sourceType == null) {
+ return false;
+ }
+ }
+
+ return true;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmNamedImpl.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmNamedImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmNamedImpl.java
index 8f82d56..0f0bd5d 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmNamedImpl.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmNamedImpl.java
@@ -23,18 +23,17 @@ import org.apache.olingo.commons.api.edm.EdmNamed;
public abstract class EdmNamedImpl implements EdmNamed {
- protected final Edm edm;
+ protected final Edm edm;
- private final String name;
+ private final String name;
- public EdmNamedImpl(final Edm edm, final String name) {
- this.edm = edm;
- this.name = name;
- }
-
- @Override
- public String getName() {
- return name;
- }
+ public EdmNamedImpl(final Edm edm, final String name) {
+ this.edm = edm;
+ this.name = name;
+ }
+ @Override
+ public String getName() {
+ return name;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeImpl.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeImpl.java
index 7fc2808..ed20afa 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeImpl.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeImpl.java
@@ -25,24 +25,23 @@ import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
public class EdmTypeImpl extends EdmNamedImpl implements EdmType {
- protected final FullQualifiedName fqn;
+ protected final FullQualifiedName fqn;
- protected final EdmTypeKind kind;
+ protected final EdmTypeKind kind;
- public EdmTypeImpl(final Edm edm, final FullQualifiedName fqn, final EdmTypeKind kind) {
- super(edm, fqn.getName());
- this.fqn = fqn;
- this.kind = kind;
- }
+ public EdmTypeImpl(final Edm edm, final FullQualifiedName fqn, final EdmTypeKind kind) {
+ super(edm, fqn.getName());
+ this.fqn = fqn;
+ this.kind = kind;
+ }
- @Override
- public String getNamespace() {
- return fqn.getNamespace();
- }
-
- @Override
- public EdmTypeKind getKind() {
- return kind;
- }
+ @Override
+ public String getNamespace() {
+ return fqn.getNamespace();
+ }
+ @Override
+ public EdmTypeKind getKind() {
+ return kind;
+ }
}
[5/8] git commit: [OLINGO-205,
OLINGO-200] provided atom v4 deserialization for entity type/set +
entity set request
Posted by fm...@apache.org.
[OLINGO-205, OLINGO-200] provided atom v4 deserialization for entity type/set + entity set request
Project: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/commit/9aefb959
Tree: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/tree/9aefb959
Diff: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/diff/9aefb959
Branch: refs/heads/olingo200
Commit: 9aefb95905edee86a6747c26afa40d6f57451008
Parents: 4780fc5
Author: fmartelli <fa...@gmail.com>
Authored: Mon Mar 24 09:50:23 2014 +0100
Committer: fmartelli <fa...@gmail.com>
Committed: Mon Mar 24 09:50:23 2014 +0100
----------------------------------------------------------------------
.../org/apache/olingo/fit/AbstractServices.java | 28 +-
.../olingo/fit/utils/AbstractJSONUtilities.java | 503 +++++++
.../olingo/fit/utils/AbstractUtilities.java | 3 +-
.../olingo/fit/utils/AbstractXMLUtilities.java | 1302 ++++++++++++++++
.../org/apache/olingo/fit/utils/Accept.java | 50 +-
.../org/apache/olingo/fit/utils/Commons.java | 6 +-
.../apache/olingo/fit/utils/JSONUtilities.java | 503 -------
.../apache/olingo/fit/utils/XMLUtilities.java | 1388 ------------------
.../olingo/fit/utils/v3/JSONUtilities.java | 28 +
.../olingo/fit/utils/v3/XMLUtilities.java | 191 +++
.../olingo/fit/utils/v4/JSONUtilities.java | 28 +
.../olingo/fit/utils/v4/XMLUtilities.java | 142 ++
fit/src/main/resources/v4/People/feed.full.json | 332 +++++
fit/src/main/resources/v4/People/feed.xml | 218 +++
fit/src/main/resources/v4/metadata.xml | 743 +++++-----
.../request/ODataBasicRequest.java | 3 +-
.../request/retrieve/ODataRetrieveRequest.java | 3 +-
.../olingo/client/api/domain/ODataLinkType.java | 8 +-
.../apache/olingo/client/api/format/Format.java | 26 +
.../olingo/client/api/format/ODataFormat.java | 8 +-
.../client/api/format/ODataMediaFormat.java | 8 +-
.../client/api/format/ODataPubFormat.java | 47 +-
.../client/api/format/ODataValueFormat.java | 8 +-
.../request/AbstractODataBasicRequest.java | 144 +-
.../communication/request/ODataRequestImpl.java | 12 +-
.../request/invoke/ODataInvokeRequestImpl.java | 4 +-
.../retrieve/AbstractODataRetrieveRequest.java | 3 +-
.../request/retrieve/ODataRawRequestImpl.java | 2 +-
.../AbstractODataStreamedEntityRequest.java | 4 +-
.../core/data/AbstractJsonDeserializer.java | 5 +-
.../client/core/data/AtomDeserializer.java | 2 -
.../core/data/AtomPropertyDeserializer.java | 16 +-
.../core/data/JSONGeoValueDeserializer.java | 11 +-
.../client/core/edm/EdmActionImportImpl.java | 1 -
.../client/core/edm/EdmOperationImpl.java | 8 +-
.../olingo/client/core/edm/EdmTypeInfo.java | 26 +-
.../core/op/impl/AbstractODataBinder.java | 8 +-
.../core/op/impl/AbstractODataDeserializer.java | 1 -
.../core/it/v3/EntityRetrieveTestITCase.java | 2 +-
.../client/core/it/v3/EntitySetTestITCase.java | 2 +-
.../core/it/v3/QueryOptionsTestITCase.java | 3 +-
.../client/core/it/v4/AbstractTestITCase.java | 4 +-
.../client/core/it/v4/EntitySetTestITCase.java | 152 ++
.../org/apache/olingo/commons/api/edm/Edm.java | 161 +-
.../olingo/commons/api/edm/EdmActionImport.java | 2 +-
.../api/edm/constants/ODataServiceVersion.java | 7 +-
.../core/edm/AbstractEdmComplexType.java | 39 +-
.../core/edm/AbstractEdmEntityContainer.java | 176 +--
.../commons/core/edm/AbstractEdmOperation.java | 131 +-
.../core/edm/AbstractEdmOperationImport.java | 65 +-
.../core/edm/AbstractEdmStructuredType.java | 159 +-
.../olingo/commons/core/edm/EdmNamedImpl.java | 21 +-
.../olingo/commons/core/edm/EdmTypeImpl.java | 31 +-
53 files changed, 3917 insertions(+), 2861 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
----------------------------------------------------------------------
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 12032c5..025e4fe 100644
--- a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
+++ b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
@@ -19,8 +19,8 @@
package org.apache.olingo.fit;
import org.apache.olingo.fit.utils.Accept;
-import org.apache.olingo.fit.utils.XMLUtilities;
-import org.apache.olingo.fit.utils.JSONUtilities;
+import org.apache.olingo.fit.utils.AbstractXMLUtilities;
+import org.apache.olingo.fit.utils.AbstractJSONUtilities;
import org.apache.olingo.fit.utils.ODataVersion;
import org.apache.olingo.fit.utils.FSManager;
@@ -70,13 +70,18 @@ public abstract class AbstractServices {
private static Set<ODataVersion> initialized = EnumSet.noneOf(ODataVersion.class);
protected abstract ODataVersion getVersion();
- protected final XMLUtilities xml;
+ protected final AbstractXMLUtilities xml;
- protected final JSONUtilities json;
+ protected final AbstractJSONUtilities json;
public AbstractServices() throws Exception {
- this.xml = new XMLUtilities(getVersion());
- this.json = new JSONUtilities(getVersion());
+ if (ODataVersion.v3 == getVersion()) {
+ 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();
+ }
if (!initialized.contains(getVersion())) {
xml.retrieveLinkInfoFromMetadata();
@@ -135,7 +140,7 @@ public abstract class AbstractServices {
return xml.
createResponse(FSManager.instance(getVersion()).readFile(filename, Accept.XML), null, Accept.XML);
} catch (Exception e) {
- return xml.createFaultResponse(Accept.XML.toString(), e);
+ return xml.createFaultResponse(Accept.XML.toString(getVersion()), e);
}
}
@@ -547,7 +552,7 @@ public abstract class AbstractServices {
return xml.createResponse(null, null, null, Response.Status.NO_CONTENT);
} catch (Exception e) {
- return xml.createFaultResponse(Accept.XML.toString(), e);
+ return xml.createFaultResponse(Accept.XML.toString(getVersion()), e);
}
}
@@ -749,7 +754,7 @@ public abstract class AbstractServices {
} catch (Exception e) {
LOG.error("Error retrieving entity", e);
- return xml.createFaultResponse(Accept.JSON.toString(), e);
+ return xml.createFaultResponse(Accept.JSON.toString(getVersion()), e);
}
}
@@ -775,7 +780,7 @@ public abstract class AbstractServices {
@QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format,
final String changes) {
if (xml.isMediaContent(entitySetName + "/" + path)) {
- return replaceMediaProperty(prefer, entitySetName, entityId, path, format, changes);
+ return replaceMediaProperty(prefer, entitySetName, entityId, path, changes);
} else {
return replaceProperty(accept, prefer, entitySetName, entityId, path, format, changes, false);
}
@@ -786,7 +791,6 @@ public abstract class AbstractServices {
final String entitySetName,
final String entityId,
final String path,
- final String format,
final String value) {
try {
final AbstractUtilities utils = getUtilities(null);
@@ -809,7 +813,7 @@ public abstract class AbstractServices {
} catch (Exception e) {
LOG.error("Error retrieving entity", e);
- return xml.createFaultResponse(Accept.JSON.toString(), e);
+ return xml.createFaultResponse(Accept.JSON.toString(getVersion()), e);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/AbstractJSONUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractJSONUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractJSONUtilities.java
new file mode 100644
index 0000000..c62d341
--- /dev/null
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractJSONUtilities.java
@@ -0,0 +1,503 @@
+/*
+ * 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;
+
+import static org.apache.olingo.fit.utils.Constants.*;
+
+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;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.NotFoundException;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+
+public abstract class AbstractJSONUtilities extends AbstractUtilities {
+
+ public AbstractJSONUtilities(final ODataVersion version) throws Exception {
+ super(version);
+ }
+
+ @Override
+ protected Accept getDefaultFormat() {
+ return Accept.JSON_FULLMETA;
+ }
+
+ @Override
+ protected InputStream addLinks(
+ final String entitySetName, final String entitykey, final InputStream is, final Set<String> links)
+ throws Exception {
+ final ObjectMapper mapper = new ObjectMapper();
+ final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
+ IOUtils.closeQuietly(is);
+
+ for (String link : links) {
+ srcNode.set(link + JSON_NAVIGATION_SUFFIX,
+ new TextNode(Commons.getLinksURI(version, entitySetName, entitykey, link)));
+ }
+
+ return IOUtils.toInputStream(srcNode.toString());
+ }
+
+ @Override
+ protected Set<String> retrieveAllLinkNames(InputStream is) throws Exception {
+ final ObjectMapper mapper = new ObjectMapper();
+ final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
+ IOUtils.closeQuietly(is);
+
+ final Set<String> links = new HashSet<String>();
+
+ final Iterator<String> fieldIter = srcNode.fieldNames();
+
+ while (fieldIter.hasNext()) {
+ final String field = fieldIter.next();
+
+ if (field.endsWith(JSON_NAVIGATION_BIND_SUFFIX)
+ || field.endsWith(JSON_NAVIGATION_SUFFIX)
+ || field.endsWith(JSON_MEDIA_SUFFIX)
+ || field.endsWith(JSON_EDITLINK_NAME)) {
+ if (field.indexOf('@') > 0) {
+ links.add(field.substring(0, field.indexOf('@')));
+ } else {
+ links.add(field);
+ }
+ }
+ }
+
+ return links;
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ protected NavigationLinks retrieveNavigationInfo(
+ final String entitySetName, final InputStream is)
+ throws Exception {
+ final ObjectMapper mapper = new ObjectMapper();
+ final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
+ IOUtils.closeQuietly(is);
+
+ final NavigationLinks links = new NavigationLinks();
+
+ final Iterator<Map.Entry<String, JsonNode>> fieldIter = srcNode.fields();
+
+ while (fieldIter.hasNext()) {
+ final Map.Entry<String, JsonNode> field = fieldIter.next();
+ if (field.getKey().endsWith(JSON_NAVIGATION_BIND_SUFFIX)) {
+ final String title = field.getKey().substring(0, field.getKey().indexOf('@'));
+ final List<String> hrefs = new ArrayList<String>();
+ if (field.getValue().isArray()) {
+ for (JsonNode href : ((ArrayNode) field.getValue())) {
+ final String uri = href.asText();
+ hrefs.add(uri.substring(uri.lastIndexOf('/') + 1));
+ }
+ } else {
+ final String uri = field.getValue().asText();
+ hrefs.add(uri.substring(uri.lastIndexOf('/') + 1));
+ }
+
+ links.addLinks(title, hrefs);
+ } else if (Commons.linkInfo.get(version).exists(entitySetName, field.getKey())) {
+ links.addInlines(field.getKey(), IOUtils.toInputStream(field.getValue().toString()));
+ }
+ }
+
+ return links;
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ protected InputStream normalizeLinks(
+ final String entitySetName, final String entityKey, final InputStream is, final NavigationLinks links)
+ throws Exception {
+ final ObjectMapper mapper = new ObjectMapper();
+ final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
+
+ if (links != null) {
+ for (String linkTitle : links.getLinkNames()) {
+ // normalize link
+ srcNode.remove(linkTitle + JSON_NAVIGATION_BIND_SUFFIX);
+ srcNode.set(
+ linkTitle + JSON_NAVIGATION_SUFFIX,
+ new TextNode(String.format("%s(%s)/%s", entitySetName, entityKey, linkTitle)));
+ }
+
+ for (String linkTitle : links.getInlineNames()) {
+ // normalize link if exist; declare a new one if missing
+ srcNode.remove(linkTitle + JSON_NAVIGATION_BIND_SUFFIX);
+ srcNode.set(
+ linkTitle + JSON_NAVIGATION_SUFFIX,
+ new TextNode(String.format("%s(%s)/%s", entitySetName, entityKey, linkTitle)));
+
+ // remove inline
+ srcNode.remove(linkTitle);
+
+ // remove from links
+ links.removeLink(linkTitle);
+ }
+ }
+
+ srcNode.set(
+ JSON_EDITLINK_NAME,
+ new TextNode(Constants.DEFAULT_SERVICE_URL + entitySetName + "(" + entityKey + ")"));
+
+ return IOUtils.toInputStream(srcNode.toString());
+ }
+
+ @Override
+ public InputStream getPropertyValue(final InputStream src, final List<String> path)
+ throws Exception {
+ final ObjectMapper mapper = new ObjectMapper();
+ final JsonNode srcNode = mapper.readTree(src);
+ JsonNode node = getProperty(srcNode, path);
+ return IOUtils.toInputStream(node.asText());
+ }
+
+ @Override
+ public InputStream getProperty(
+ final String entitySetName, final String entityId, final List<String> path, final String edmType)
+ throws Exception {
+
+ final InputStream src =
+ fsManager.readFile(Commons.getEntityBasePath(entitySetName, entityId) + ENTITY, Accept.JSON_FULLMETA);
+
+ final ObjectMapper mapper = new ObjectMapper();
+ final JsonNode srcNode = mapper.readTree(src);
+
+ final ObjectNode propertyNode = new ObjectNode(JsonNodeFactory.instance);
+
+ if (StringUtils.isNotBlank(edmType)) {
+ propertyNode.put(JSON_ODATAMETADATA_NAME, 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<String> 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 ObjectMapper mapper = new ObjectMapper();
+ final JsonNode srcNode = mapper.readTree(src);
+
+ ((ObjectNode) srcNode).put(ODATA_COUNT_NAME, count);
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ mapper.writeValue(bos, srcNode);
+
+ final InputStream res = new ByteArrayInputStream(bos.toByteArray());
+ IOUtils.closeQuietly(bos);
+
+ return res;
+ }
+
+ public InputStream wrapJsonEntities(final InputStream entities) throws Exception {
+ final ObjectMapper mapper = new ObjectMapper();
+ final JsonNode node = mapper.readTree(entities);
+
+ final ObjectNode res;
+
+ final JsonNode value = node.get(JSON_VALUE_NAME);
+
+ if (value.isArray()) {
+ res = mapper.createObjectNode();
+ res.set("value", value);
+ final JsonNode next = node.get(JSON_NEXTLINK_NAME);
+ if (next != null) {
+ res.set(JSON_NEXTLINK_NAME, next);
+ }
+ } else {
+ res = (ObjectNode) value;
+ }
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ mapper.writeValue(bos, res);
+
+ final InputStream is = new ByteArrayInputStream(bos.toByteArray());
+ IOUtils.closeQuietly(bos);
+
+ return is;
+ }
+
+ @Override
+ public InputStream selectEntity(final InputStream src, final String[] propertyNames) throws Exception {
+ final ObjectMapper mapper = new ObjectMapper();
+ final ObjectNode srcNode = (ObjectNode) mapper.readTree(src);
+
+ final Set<String> retain = new HashSet<String>();
+ retain.add(JSON_ID_NAME);
+ retain.add(JSON_TYPE_NAME);
+ retain.add(JSON_EDITLINK_NAME);
+ retain.add(JSON_NEXTLINK_NAME);
+ retain.add(JSON_ODATAMETADATA_NAME);
+ retain.add(JSON_VALUE_NAME);
+
+ for (String name : propertyNames) {
+ retain.add(name);
+ retain.add(name + JSON_NAVIGATION_SUFFIX);
+ retain.add(name + JSON_MEDIA_SUFFIX);
+ retain.add(name + JSON_TYPE_SUFFIX);
+ }
+
+ srcNode.retain(retain);
+
+ return IOUtils.toInputStream(srcNode.toString());
+ }
+
+ @Override
+ public InputStream readEntities(
+ final List<String> links, final String linkName, final String next, final boolean forceFeed)
+ throws Exception {
+
+ if (links.isEmpty()) {
+ throw new NotFoundException();
+ }
+
+ final ObjectMapper mapper = new ObjectMapper();
+ final ObjectNode node = mapper.createObjectNode();
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ if (forceFeed || links.size() > 1) {
+ bos.write("[".getBytes());
+ }
+
+ for (String link : links) {
+ try {
+ final Map.Entry<String, String> uri = Commons.parseEntityURI(link);
+ final Map.Entry<String, InputStream> entity =
+ readEntity(uri.getKey(), uri.getValue(), Accept.JSON_FULLMETA);
+
+ if (bos.size() > 1) {
+ bos.write(",".getBytes());
+ }
+
+ IOUtils.copy(entity.getValue(), bos);
+ } catch (Exception e) {
+ // log and ignore link
+ LOG.warn("Error parsing uri {}", link, e);
+ }
+ }
+
+ if (forceFeed || links.size() > 1) {
+ bos.write("]".getBytes());
+ }
+
+ node.set(JSON_VALUE_NAME, mapper.readTree(new ByteArrayInputStream(bos.toByteArray())));
+
+ if (StringUtils.isNotBlank(next)) {
+ node.set(JSON_NEXTLINK_NAME, new TextNode(next));
+ }
+
+ return IOUtils.toInputStream(node.toString());
+ }
+
+ @Override
+ protected InputStream replaceLink(
+ final InputStream toBeChanged, final String linkName, final InputStream replacement)
+ throws Exception {
+ final ObjectMapper mapper = new ObjectMapper();
+
+ final ObjectNode toBeChangedNode = (ObjectNode) mapper.readTree(toBeChanged);
+ final ObjectNode replacementNode = (ObjectNode) mapper.readTree(replacement);
+
+ if (toBeChangedNode.get(linkName + JSON_NAVIGATION_SUFFIX) == null) {
+ throw new NotFoundException();
+ }
+
+ toBeChangedNode.set(linkName, replacementNode.get(JSON_VALUE_NAME));
+
+ final JsonNode next = replacementNode.get(linkName + JSON_NEXTLINK_NAME);
+ if (next != null) {
+ toBeChangedNode.set(linkName + JSON_NEXTLINK_SUFFIX, next);
+ }
+
+ return IOUtils.toInputStream(toBeChangedNode.toString());
+ }
+
+ @Override
+ protected Map<String, InputStream> getChanges(final InputStream src) throws Exception {
+ final Map<String, InputStream> res = new HashMap<String, InputStream>();
+
+ final ObjectMapper mapper = new ObjectMapper();
+ final JsonNode srcObject = mapper.readTree(src);
+
+ final Iterator<Map.Entry<String, JsonNode>> fields = srcObject.fields();
+ while (fields.hasNext()) {
+ final Map.Entry<String, JsonNode> field = fields.next();
+ res.put(field.getKey(), IOUtils.toInputStream(field.getValue().toString()));
+ }
+
+ return res;
+ }
+
+ @Override
+ protected InputStream setChanges(
+ final InputStream toBeChanged, final Map<String, InputStream> properties) throws Exception {
+
+ final ObjectMapper mapper = new ObjectMapper();
+ final ObjectNode toBeChangedObject = (ObjectNode) mapper.readTree(toBeChanged);
+
+ for (Map.Entry<String, InputStream> property : properties.entrySet()) {
+ final JsonNode propertyNode = mapper.readTree(property.getValue());
+ toBeChangedObject.set(property.getKey(), propertyNode);
+ }
+
+ return IOUtils.toInputStream(toBeChangedObject.toString());
+ }
+
+ @Override
+ public Map.Entry<String, List<String>> extractLinkURIs(
+ final String entitySetName, final String entityId, final String linkName)
+ throws Exception {
+ final LinkInfo links = readLinks(entitySetName, entityId, linkName, Accept.JSON_FULLMETA);
+ return extractLinkURIs(links.getLinks());
+ }
+
+ @Override
+ public Map.Entry<String, List<String>> extractLinkURIs(final InputStream is)
+ throws Exception {
+ final ObjectMapper mapper = new ObjectMapper();
+ final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
+ IOUtils.closeQuietly(is);
+
+ final List<String> links = new ArrayList<String>();
+
+ JsonNode uris = srcNode.get("value");
+ if (uris == null) {
+ final JsonNode url = srcNode.get("url");
+ if (url != null) {
+ links.add(url.textValue());
+ }
+ } else {
+ final Iterator<JsonNode> iter = ((ArrayNode) uris).iterator();
+ while (iter.hasNext()) {
+ links.add(iter.next().get("url").textValue());
+ }
+ }
+
+ final JsonNode next = srcNode.get(JSON_NEXTLINK_NAME);
+
+ return new SimpleEntry<String, List<String>>(next == null ? null : next.asText(), links);
+ }
+
+ @Override
+ public InputStream addEditLink(
+ final InputStream content, final String title, final String href) throws Exception {
+ final ObjectMapper mapper = new ObjectMapper();
+ final ObjectNode srcNode = (ObjectNode) mapper.readTree(content);
+ IOUtils.closeQuietly(content);
+
+ srcNode.set(JSON_EDITLINK_NAME, new TextNode(href));
+ return IOUtils.toInputStream(srcNode.toString());
+ }
+
+ @Override
+ public InputStream replaceProperty(
+ final InputStream src, final InputStream replacement, final List<String> path, final boolean justValue)
+ throws Exception {
+ final ObjectMapper mapper = new ObjectMapper();
+ final ObjectNode srcNode = (ObjectNode) mapper.readTree(src);
+ IOUtils.closeQuietly(src);
+
+ final JsonNode replacementNode;
+ if (justValue) {
+ replacementNode = new TextNode(IOUtils.toString(replacement));
+ } else {
+ replacementNode = (ObjectNode) mapper.readTree(replacement);
+ }
+ IOUtils.closeQuietly(replacement);
+
+ JsonNode node = srcNode;
+ for (int i = 0; i < path.size() - 1; i++) {
+ node = node.get(path.get(i));
+ if (node == null) {
+ throw new NotFoundException();
+ }
+ }
+
+ ((ObjectNode) node).set(path.get(path.size() - 1), replacementNode);
+
+ return IOUtils.toInputStream(srcNode.toString());
+ }
+
+ @Override
+ public InputStream deleteProperty(final InputStream src, final List<String> path) throws Exception {
+ final ObjectMapper mapper = new ObjectMapper();
+ final ObjectNode srcNode = (ObjectNode) mapper.readTree(src);
+ IOUtils.closeQuietly(src);
+
+ JsonNode node = srcNode;
+ for (int i = 0; i < path.size() - 1; i++) {
+ node = node.get(path.get(i));
+ if (node == null) {
+ throw new NotFoundException();
+ }
+ }
+
+ ((ObjectNode) node).set(path.get(path.size() - 1), null);
+
+ return IOUtils.toInputStream(srcNode.toString());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
----------------------------------------------------------------------
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 74653a1..7b74b62 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
@@ -384,7 +384,7 @@ public abstract class AbstractUtilities {
}
if (accept != null) {
- builder.header("Content-Type", accept.toString());
+ builder.header("Content-Type", accept.toString(version));
} else {
builder.header("Content-Type", "*/*");
}
@@ -423,7 +423,6 @@ public abstract class AbstractUtilities {
public Response createFaultResponse(final String accept, final Exception e) {
LOG.debug("Create fault response about .... ", e);
- e.printStackTrace();
final Response.ResponseBuilder builder = Response.serverError();
if (version == ODataVersion.v3) {
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/AbstractXMLUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractXMLUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractXMLUtilities.java
new file mode 100644
index 0000000..d02e828
--- /dev/null
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractXMLUtilities.java
@@ -0,0 +1,1302 @@
+/*
+ * 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;
+
+import static org.apache.olingo.fit.utils.Constants.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.StringWriter;
+import java.util.AbstractMap;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.NotFoundException;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventFactory;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLEventWriter;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemException;
+
+public abstract class AbstractXMLUtilities extends AbstractUtilities {
+
+ protected static XMLInputFactory ifactory = null;
+
+ protected static XMLOutputFactory ofactory = null;
+
+ public AbstractXMLUtilities(final ODataVersion version) throws Exception {
+ super(version);
+ }
+
+ public abstract void retrieveLinkInfoFromMetadata() throws Exception;
+
+ @Override
+ protected Accept getDefaultFormat() {
+ return Accept.ATOM;
+ }
+
+ protected XMLEventReader getEventReader(final InputStream is) throws XMLStreamException {
+ if (ifactory == null) {
+ ifactory = XMLInputFactory.newInstance();
+ }
+ ifactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, false);
+ return ifactory.createXMLEventReader(is);
+ }
+
+ protected static XMLEventWriter getEventWriter(final OutputStream os) throws XMLStreamException {
+ if (ofactory == null) {
+ ofactory = XMLOutputFactory.newInstance();
+ }
+
+ return ofactory.createXMLEventWriter(os);
+ }
+
+ private void writeEvent(final XMLEvent event, final XMLEventWriter writer) {
+ if (writer != null) {
+ try {
+ writer.add(event);
+ } catch (XMLStreamException e) {
+ LOG.error("Error writing event {}", event, e);
+ }
+ }
+ }
+
+ private void skipElement(
+ final StartElement start,
+ final XMLEventReader reader,
+ final XMLEventWriter writer,
+ final boolean excludeStart)
+ throws Exception {
+
+ if (!excludeStart) {
+ writeEvent(start, writer);
+ }
+
+ int depth = 1;
+ boolean found = false;
+
+ while (reader.hasNext() && !found) {
+ final XMLEvent event = reader.nextEvent();
+
+ writeEvent(event, writer);
+
+ if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
+ depth++;
+ } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT) {
+ depth--;
+ found = depth == 0 && start.getName().equals(event.asEndElement().getName());
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ protected InputStream addLinks(
+ final String entitySetName, final String entitykey, final InputStream is, final Set<String> links)
+ throws Exception {
+
+ // -----------------------------------------
+ // 0. Build reader and writer
+ // -----------------------------------------
+ final XMLEventReader reader = getEventReader(is);
+ final XMLEventFactory eventFactory = XMLEventFactory.newInstance();
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final XMLEventWriter writer = getEventWriter(bos);
+ // -----------------------------------------
+ final Map.Entry<Integer, XmlElement> entry =
+ extractElement(reader, writer, Collections.singletonList("entry"), 0, 1, 1);
+
+ writer.add(entry.getValue().getStart());
+
+ // add for links
+ for (String link : links) {
+ final Set<Attribute> attributes = new HashSet<Attribute>();
+ attributes.add(eventFactory.createAttribute(new QName("title"), link));
+ attributes.add(eventFactory.createAttribute(new QName("href"),
+ Commons.getLinksURI(version, entitySetName, entitykey, link)));
+ attributes.add(eventFactory.createAttribute(new QName("rel"), Constants.ATOM_LINK_REL + link));
+ attributes.add(eventFactory.createAttribute(new QName("type"),
+ Commons.linkInfo.get(version).isFeed(entitySetName, link) ? Constants.ATOM_LINK_FEED
+ : Constants.ATOM_LINK_ENTRY));
+
+ writer.add(eventFactory.createStartElement(new QName(LINK), attributes.iterator(), null));
+ writer.add(eventFactory.createEndElement(new QName(LINK), null));
+ }
+
+ writer.add(entry.getValue().getContentReader());
+ writer.add(entry.getValue().getEnd());
+ writer.add(reader);
+ IOUtils.closeQuietly(is);
+
+ writer.flush();
+ writer.close();
+ reader.close();
+
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ protected Set<String> retrieveAllLinkNames(final InputStream is) throws Exception {
+ final Set<String> links = new HashSet<String>();
+
+ final XMLEventReader reader = getEventReader(is);
+
+ try {
+
+ int startDepth = 0;
+
+ while (true) {
+ final Map.Entry<Integer, XmlElement> linkInfo =
+ extractElement(reader, null, Collections.<String>singletonList(LINK), startDepth, 2, 2);
+
+ startDepth = linkInfo.getKey();
+
+ links.add(linkInfo.getValue().getStart().getAttributeByName(new QName("title")).getValue());
+ }
+ } catch (Exception ignore) {
+ // ignore
+ } finally {
+ reader.close();
+ IOUtils.closeQuietly(is);
+ }
+
+ return links;
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ protected NavigationLinks retrieveNavigationInfo(
+ final String entitySetName, final InputStream is)
+ throws Exception {
+
+ final NavigationLinks links = new NavigationLinks();
+
+ final XMLEventReader reader = getEventReader(is);
+
+ try {
+ final List<Map.Entry<String, String>> filter = new ArrayList<Map.Entry<String, String>>();
+ filter.add(new AbstractMap.SimpleEntry<String, String>("type", "application/atom+xml;type=entry"));
+ filter.add(new AbstractMap.SimpleEntry<String, String>("type", "application/atom+xml;type=feed"));
+
+ int startDepth = 0;
+
+ while (true) {
+ // a. search for link with type attribute equals to "application/atom+xml;type=entry/feed"
+ final Map.Entry<Integer, XmlElement> linkInfo = extractElement(
+ reader, null, Collections.<String>singletonList(LINK), filter, true, startDepth, 2, 2);
+ final XmlElement link = linkInfo.getValue();
+ startDepth = linkInfo.getKey();
+
+ final String title = link.getStart().getAttributeByName(new QName("title")).getValue();
+
+ final Attribute hrefAttr = link.getStart().getAttributeByName(new QName("href"));
+ final String href = hrefAttr == null ? null : hrefAttr.getValue();
+
+ try {
+ final XmlElement inlineElement =
+ extractElement(link.getContentReader(), null, Collections.<String>singletonList(INLINE), 0, -1, -1).
+ getValue();
+ final XMLEventReader inlineReader = inlineElement.getContentReader();
+
+ try {
+ while (true) {
+ final XmlElement entry =
+ extractElement(inlineReader, null, Collections.<String>singletonList("entry"), 0, -1, -1).
+ getValue();
+ links.addInlines(title, entry.toStream());
+ }
+ } catch (Exception e) {
+ // Reached the end of document
+ }
+
+ inlineReader.close();
+ } catch (Exception ignore) {
+ // inline element not found (inlines are not mondatory).
+ if (StringUtils.isNotBlank(href) && entityUriPattern.matcher(href).matches()) {
+ links.addLinks(title, href.substring(href.lastIndexOf('/') + 1));
+ }
+ }
+ }
+ } catch (Exception ignore) {
+ // ignore
+ } finally {
+ reader.close();
+ }
+
+ return links;
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ protected InputStream normalizeLinks(
+ final String entitySetName, final String entityKey, final InputStream is, final NavigationLinks links)
+ throws Exception {
+
+ // -----------------------------------------
+ // 0. Build reader and writer
+ // -----------------------------------------
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ IOUtils.copy(is, bos);
+ is.close();
+
+ final ByteArrayOutputStream tmpBos = new ByteArrayOutputStream();
+ final XMLEventWriter writer = getEventWriter(tmpBos);
+
+ final XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+ // -----------------------------------------
+
+ // -----------------------------------------
+ // 1. Normalize links
+ // -----------------------------------------
+ final Set<String> added = new HashSet<String>();
+
+ try {
+ final List<Map.Entry<String, String>> filter = new ArrayList<Map.Entry<String, String>>();
+ filter.add(new AbstractMap.SimpleEntry<String, String>("type", "application/atom+xml;type=entry"));
+ filter.add(new AbstractMap.SimpleEntry<String, String>("type", "application/atom+xml;type=feed"));
+
+ Map.Entry<Integer, XmlElement> linkInfo = null;
+
+ while (true) {
+ // a. search for link with type attribute equals to "application/atom+xml;type=entry/feed"
+ linkInfo = extractElement(
+ reader, writer, Collections.<String>singletonList(LINK), filter, true,
+ linkInfo == null ? 0 : linkInfo.getKey(), 2, 2);
+ final XmlElement link = linkInfo.getValue();
+
+ final String title = link.getStart().getAttributeByName(new QName("title")).getValue();
+
+ if (!added.contains(title)) {
+ added.add(title);
+
+ final String normalizedLink = String.format(
+ "<link href=\"%s(%s)/%s\" rel=\"%s\" title=\"%s\" type=\"%s\"/>",
+ entitySetName,
+ entityKey,
+ title,
+ link.getStart().getAttributeByName(new QName("rel")).getValue(),
+ title,
+ link.getStart().getAttributeByName(new QName("type")).getValue());
+
+ addAtomElement(IOUtils.toInputStream(normalizedLink), writer);
+ }
+ }
+ } catch (Exception ignore) {
+ // ignore
+ } finally {
+ writer.close();
+ reader.close();
+ }
+ // -----------------------------------------
+
+ // -----------------------------------------
+ // 2. Add edit link if missing
+ // -----------------------------------------
+ final InputStream content = addEditLink(
+ new ByteArrayInputStream(tmpBos.toByteArray()),
+ entitySetName,
+ Constants.DEFAULT_SERVICE_URL + entitySetName + "(" + entityKey + ")");
+ // -----------------------------------------
+
+ // -----------------------------------------
+ // 3. Add content element if missing
+ // -----------------------------------------
+ return addAtomContent(
+ content,
+ entitySetName,
+ Constants.DEFAULT_SERVICE_URL + entitySetName + "(" + entityKey + ")");
+ // -----------------------------------------
+
+ }
+
+ public XmlElement getXmlElement(
+ final StartElement start,
+ final XMLEventReader reader)
+ throws Exception {
+
+ final XmlElement res = new XmlElement();
+ res.setStart(start);
+
+ StringWriter content = new StringWriter();
+
+ int depth = 1;
+
+ while (reader.hasNext() && depth > 0) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
+ depth++;
+ } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT) {
+ depth--;
+ }
+
+ if (depth == 0) {
+ res.setEnd(event.asEndElement());
+ } else {
+ event.writeAsEncodedUnicode(content);
+ }
+ }
+
+ content.flush();
+ content.close();
+
+ res.setContent(new ByteArrayInputStream(content.toString().getBytes()));
+
+ return res;
+ }
+
+ private void addAtomElement(
+ final InputStream content,
+ final XMLEventWriter writer)
+ throws Exception {
+ final XMLEventReader reader = getEventReader(content);
+
+ final XMLEventFactory eventFactory = XMLEventFactory.newInstance();
+ XMLEvent newLine = eventFactory.createSpace("\n");
+
+ try {
+ writer.add(newLine);
+
+ while (reader.hasNext()) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.getEventType() != XMLStreamConstants.START_DOCUMENT
+ && event.getEventType() != XMLStreamConstants.END_DOCUMENT
+ && event.getEventType() != XMLStreamConstants.COMMENT) {
+ writer.add(event);
+ }
+ }
+ writer.add(newLine);
+ } finally {
+ reader.close();
+ IOUtils.closeQuietly(content);
+ }
+ }
+
+ @Override
+ public InputStream addEditLink(
+ final InputStream content, final String title, final String href)
+ throws Exception {
+
+ final ByteArrayOutputStream copy = new ByteArrayOutputStream();
+ IOUtils.copy(content, copy);
+
+ IOUtils.closeQuietly(content);
+
+ XMLEventReader reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ XMLEventWriter writer = getEventWriter(bos);
+
+ final String editLinkElement = String.format("<link rel=\"edit\" title=\"%s\" href=\"%s\" />", title, href);
+
+ try {
+ // check edit link existence
+ extractElement(reader, writer, Collections.<String>singletonList(LINK),
+ Collections.<Map.Entry<String, String>>singletonList(
+ new AbstractMap.SimpleEntry<String, String>("rel", "edit")), false, 0, -1, -1);
+
+ addAtomElement(IOUtils.toInputStream(editLinkElement), writer);
+ writer.add(reader);
+
+ } catch (Exception e) {
+ reader.close();
+ reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
+
+ bos = new ByteArrayOutputStream();
+ writer = getEventWriter(bos);
+
+ final XmlElement entryElement =
+ extractElement(reader, writer, Collections.<String>singletonList("entry"), 0, 1, 1).getValue();
+
+ writer.add(entryElement.getStart());
+
+ addAtomElement(IOUtils.toInputStream(editLinkElement), writer);
+
+ writer.add(entryElement.getContentReader());
+ writer.add(entryElement.getEnd());
+
+ writer.add(reader);
+
+ writer.flush();
+ writer.close();
+ } finally {
+ reader.close();
+ }
+
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+
+ public InputStream addAtomContent(
+ final InputStream content, final String title, final String href)
+ throws Exception {
+
+ final ByteArrayOutputStream copy = new ByteArrayOutputStream();
+ IOUtils.copy(content, copy);
+
+ IOUtils.closeQuietly(content);
+
+ XMLEventReader reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ XMLEventWriter writer = getEventWriter(bos);
+
+ try {
+ // check edit link existence
+ XmlElement contentElement =
+ extractElement(reader, writer, Collections.<String>singletonList("content"), 0, 2, 2).getValue();
+ writer.add(contentElement.getStart());
+ writer.add(contentElement.getContentReader());
+ writer.add(contentElement.getEnd());
+ writer.add(reader);
+ } catch (Exception e) {
+ reader.close();
+ reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
+
+ bos = new ByteArrayOutputStream();
+ writer = getEventWriter(bos);
+
+ if (isMediaContent(title)) {
+ final XmlElement entryElement =
+ extractElement(reader, writer, Collections.<String>singletonList("entry"), 0, 1, 1).getValue();
+
+ writer.add(entryElement.getStart());
+ writer.add(entryElement.getContentReader());
+
+ addAtomElement(
+ IOUtils.toInputStream(String.format("<content type=\"*/*\" src=\"%s/$value\" />", href)),
+ writer);
+
+ writer.add(entryElement.getEnd());
+ } else {
+ try {
+ final XmlElement entryElement =
+ extractElement(reader, writer, Collections.<String>singletonList(PROPERTIES), 0, 2, 3).getValue();
+
+ addAtomElement(
+ IOUtils.toInputStream("<content type=\"application/xml\">"),
+ writer);
+
+ writer.add(entryElement.getStart());
+ writer.add(entryElement.getContentReader());
+ writer.add(entryElement.getEnd());
+
+ addAtomElement(
+ IOUtils.toInputStream("</content>"),
+ writer);
+ } catch (Exception nf) {
+ reader.close();
+ reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
+
+ bos = new ByteArrayOutputStream();
+ writer = getEventWriter(bos);
+
+ final XmlElement entryElement =
+ extractElement(reader, writer, Collections.<String>singletonList("entry"), 0, 1, 1).getValue();
+ writer.add(entryElement.getStart());
+ writer.add(entryElement.getContentReader());
+
+ addAtomElement(
+ IOUtils.toInputStream("<content type=\"application/xml\"/>"),
+ writer);
+
+ writer.add(entryElement.getEnd());
+ }
+ }
+
+ writer.add(reader);
+
+ writer.flush();
+ writer.close();
+ } finally {
+ reader.close();
+ }
+
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+
+ public int countAllElements(final String entitySetName) throws Exception {
+ final String basePath = entitySetName + File.separatorChar;
+ int count = countFeedElements(fsManager.readFile(basePath + FEED, Accept.XML), "entry");
+
+ final String skipTokenDirPath = fsManager.getAbsolutePath(basePath + SKIP_TOKEN, null);
+
+
+ try {
+ final FileObject skipToken = fsManager.resolve(skipTokenDirPath);
+ final FileObject[] files = fsManager.findByExtension(skipToken, Accept.XML.getExtension().substring(1));
+
+ for (FileObject file : files) {
+ count += countFeedElements(fsManager.readFile(
+ basePath + SKIP_TOKEN + File.separatorChar + file.getName().getBaseName(), null), "entry");
+ }
+ } catch (FileSystemException fse) {
+ LOG.debug("Resource path '{}' not found", skipTokenDirPath);
+ }
+
+
+ return count;
+ }
+
+ private int countFeedElements(final InputStream is, final String elementName) throws XMLStreamException {
+ final XMLEventReader reader = getEventReader(is);
+
+ int count = 0;
+
+ while (reader.hasNext()) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.getEventType() == XMLStreamConstants.START_ELEMENT
+ && elementName.equals(event.asStartElement().getName().getLocalPart())) {
+ count++;
+ }
+ }
+
+ reader.close();
+ return count;
+ }
+
+ public Map.Entry<Integer, XmlElement> extractElement(
+ final XMLEventReader reader, final XMLEventWriter writer, final List<String> 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<Integer, XmlElement> extractElement(
+ final XMLEventReader reader, final XMLEventWriter writer, final List<String> path,
+ final Collection<Map.Entry<String, String>> filter,
+ final boolean filterInOr,
+ final int startPathPos, final int minPathPos, final int maxPathPos)
+ throws Exception {
+
+ StartElement start = null;
+ int searchFor = 0;
+ int depth = startPathPos;
+
+ // Current inspected element
+ String current = null;
+
+ // set defaults
+ final List<String> pathElementNames = path == null ? Collections.<String>emptyList() : path;
+ final Collection<Map.Entry<String, String>> filterAttrs =
+ filter == null ? Collections.<Map.Entry<String, String>>emptySet() : filter;
+
+ while (reader.hasNext() && start == null) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
+ depth++;
+
+ if (current != null || ((minPathPos < 0 || minPathPos <= depth) && (maxPathPos < 0 || depth <= maxPathPos))) {
+ if (pathElementNames.isEmpty()
+ || pathElementNames.get(searchFor).trim().equals(event.asStartElement().getName().getLocalPart())) {
+
+ if (searchFor < pathElementNames.size() - 1) {
+ // path exploring not completed
+ writeEvent(event, writer);
+ current = pathElementNames.get(searchFor).trim();
+ searchFor++;
+ } else {
+
+ // path exploring completed ... evaluate filter about path element name attribute
+ boolean match = filterAttrs.isEmpty() || !filterInOr;
+
+ for (Map.Entry<String, String> filterAttr : filterAttrs) {
+ final Attribute attr = event.asStartElement().getAttributeByName(new QName(filterAttr.getKey().trim()));
+
+ if (attr == null || !filterAttr.getValue().trim().equals(attr.getValue())) {
+ match = filterInOr ? match : false;
+ } else {
+ match = filterInOr ? true : match;
+ }
+ }
+
+ if (match) {
+ // found searched element
+ start = event.asStartElement();
+ } else {
+ skipElement(event.asStartElement(), reader, writer, false);
+ depth--;
+ }
+ }
+ } else if (current == null) {
+ writeEvent(event, writer);
+ } else {
+ // skip element
+ skipElement(event.asStartElement(), reader, writer, false);
+ depth--;
+ }
+ } else {
+ writeEvent(event, writer);
+ }
+
+ } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT) {
+ depth--;
+
+ writeEvent(event, writer);
+
+ if (event.asEndElement().getName().getLocalPart().equals(current)) {
+ // back step ....
+ searchFor--;
+ current = searchFor > 0 ? pathElementNames.get(searchFor - 1).trim() : null;
+ }
+ } else {
+ writeEvent(event, writer);
+ }
+ }
+
+ if (start == null) {
+ throw new NotFoundException();
+ }
+
+ return new SimpleEntry<Integer, XmlElement>(Integer.valueOf(depth - 1), getXmlElement(start, reader));
+ }
+
+ public InputStream addAtomInlinecount(
+ final InputStream feed, final int count, final Accept accept)
+ throws Exception {
+ final XMLEventReader reader = getEventReader(feed);
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final XMLEventWriter writer = getEventWriter(bos);
+
+ try {
+
+ final XmlElement feedElement =
+ extractElement(reader, writer, Collections.<String>singletonList("feed"), 0, 1, 1).getValue();
+
+ writer.add(feedElement.getStart());
+ addAtomElement(IOUtils.toInputStream(String.format("<m:count>%d</m:count>", count)), writer);
+ writer.add(feedElement.getContentReader());
+ writer.add(feedElement.getEnd());
+
+ while (reader.hasNext()) {
+ writer.add(reader.nextEvent());
+ }
+
+ } finally {
+ writer.flush();
+ writer.close();
+ reader.close();
+ IOUtils.closeQuietly(feed);
+ }
+
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+
+ @Override
+ public InputStream getPropertyValue(final InputStream is, final List<String> path)
+ throws Exception {
+
+ final List<String> pathElements = new ArrayList<String>();
+
+ for (String element : path) {
+ pathElements.add(ATOM_PROPERTY_PREFIX + element);
+ }
+
+ final XMLEventReader reader = getEventReader(is);
+ final Map.Entry<Integer, XmlElement> 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);
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final XMLEventWriter writer = getEventWriter(bos);
+
+ final List<String> found = new ArrayList<String>(Arrays.asList(propertyNames));
+
+ boolean inProperties = false;
+ boolean writeCurrent = true;
+ Boolean writeNext = null;
+ String currentName = null;
+
+ final List<String> fieldToBeSaved = new ArrayList<String>(Arrays.asList(propertyNames));
+
+ while (reader.hasNext()) {
+ final XMLEvent event = reader.nextEvent();
+ if (event.getEventType() == XMLStreamConstants.START_ELEMENT
+ && LINK.equals(event.asStartElement().getName().getLocalPart())
+ && !fieldToBeSaved.contains(
+ event.asStartElement().getAttributeByName(new QName("title")).getValue())
+ && !"edit".equals(event.asStartElement().getAttributeByName(new QName("rel")).getValue())) {
+ writeCurrent = false;
+ } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT
+ && LINK.equals(event.asEndElement().getName().getLocalPart())) {
+ writeNext = true;
+ } else if (event.getEventType() == XMLStreamConstants.START_ELEMENT
+ && (PROPERTIES).equals(event.asStartElement().getName().getLocalPart())) {
+ writeCurrent = true;
+ writeNext = false;
+ inProperties = true;
+ } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT
+ && (PROPERTIES).equals(event.asEndElement().getName().getLocalPart())) {
+ writeCurrent = true;
+ } else if (inProperties) {
+ if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
+ final String elementName = event.asStartElement().getName().getLocalPart();
+
+ for (String propertyName : propertyNames) {
+ if ((ATOM_PROPERTY_PREFIX + propertyName.trim()).equals(elementName)) {
+ writeCurrent = true;
+ found.remove(propertyName);
+ currentName = propertyName;
+ }
+ }
+
+ } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT
+ && StringUtils.isNotBlank(currentName)
+ && (ATOM_PROPERTY_PREFIX + currentName.trim()).equals(
+ event.asEndElement().getName().getLocalPart())) {
+ writeNext = false;
+ currentName = null;
+ }
+
+ }
+
+ if (writeCurrent) {
+ writer.add(event);
+ }
+
+ if (writeNext != null) {
+ writeCurrent = writeNext;
+ writeNext = null;
+ }
+ }
+
+ writer.flush();
+ writer.close();
+ reader.close();
+ IOUtils.closeQuietly(entity);
+
+ // Do not raise any exception in order to support FC properties as well
+ // if (!found.isEmpty()) {
+ // throw new Exception(String.format("Could not find a properties '%s'", found));
+ // }
+
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+
+ @Override
+ public InputStream readEntities(
+ final List<String> links, final String linkName, final String next, final boolean forceFeed)
+ throws Exception {
+
+ if (links.isEmpty()) {
+ throw new NotFoundException();
+ }
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ if (forceFeed || links.size() > 1) {
+ // build a feed
+ bos.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>".getBytes());
+
+ bos.write(("<feed xml:base=\"" + DEFAULT_SERVICE_URL + "\" "
+ + "xmlns=\"http://www.w3.org/2005/Atom\" "
+ + "xmlns:d=\"http://schemas.microsoft.com/ado/2007/08/dataservices\" "
+ + "xmlns:m=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">")
+ .getBytes());
+
+ bos.write(("<id>" + DEFAULT_SERVICE_URL + "entityset(entityid)/" + linkName + "</id>").getBytes());
+
+ bos.write(("<title type=\"text\">" + linkName + "</title>").getBytes());
+ bos.write("<updated>2014-03-03T13:40:49Z</updated>".getBytes());
+ bos.write(("<link rel=\"self\" title=\"" + linkName + "\" href=\"" + linkName + "\" />").getBytes());
+ }
+
+ for (String link : links) {
+ try {
+ final Map.Entry<String, String> uri = Commons.parseEntityURI(link);
+
+ final XmlElement entry =
+ extractElement(
+ getEventReader(readEntity(uri.getKey(), uri.getValue(), Accept.ATOM).getValue()),
+ null,
+ Collections.<String>singletonList("entry"),
+ 0, 1, 1).getValue();
+
+ IOUtils.copy(entry.toStream(), bos);
+ } catch (Exception e) {
+ // log and ignore link
+ LOG.warn("Error parsing uri {}", link, e);
+ }
+ }
+
+ if (forceFeed || links.size() > 1) {
+
+ if (StringUtils.isNotBlank(next)) {
+ bos.write(String.format("<link rel=\"next\" href=\"%s\" />", next).getBytes());
+ }
+
+ bos.write("</feed>".getBytes());
+ }
+
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+
+ @Override
+ public Map<String, InputStream> getChanges(final InputStream src) throws Exception {
+ final Map<String, InputStream> res = new HashMap<String, InputStream>();
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ IOUtils.copy(src, bos);
+ IOUtils.closeQuietly(src);
+
+ // retrieve properties ...
+ XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+ final Map.Entry<Integer, XmlElement> propertyElement =
+ extractElement(reader, null, Collections.<String>singletonList(PROPERTIES), 0, 2, 3);
+ reader.close();
+
+ reader = propertyElement.getValue().getContentReader();
+
+ try {
+ while (true) {
+ final XmlElement property = extractElement(reader, null, null, 0, -1, -1).getValue();
+ res.put(property.getStart().getName().getLocalPart(), property.toStream());
+ }
+ } catch (Exception ignore) {
+ // end
+ }
+
+ reader.close();
+
+ // retrieve links ...
+ reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+ try {
+ int pos = 0;
+ while (true) {
+ final Map.Entry<Integer, XmlElement> linkElement =
+ extractElement(reader, null, Collections.<String>singletonList(LINK), pos, 2, 2);
+
+ res.put("[LINK]" + linkElement.getValue().getStart().getAttributeByName(new QName("title")).getValue(),
+ linkElement.getValue().toStream());
+
+ pos = linkElement.getKey();
+ }
+ } catch (Exception ignore) {
+ // end
+ }
+
+ return res;
+ }
+
+ @Override
+ public InputStream setChanges(
+ final InputStream toBeChanged,
+ final Map<String, InputStream> properties)
+ throws Exception {
+ XMLEventReader reader = getEventReader(toBeChanged);
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ XMLEventWriter writer = getEventWriter(bos);
+
+ // ---------------------------------
+ // add property changes
+ // ---------------------------------
+ Map.Entry<Integer, XmlElement> propertyElement =
+ extractElement(reader, writer, Collections.<String>singletonList(PROPERTIES), 0, 2, 3);
+
+ writer.flush();
+
+ ByteArrayOutputStream pbos = new ByteArrayOutputStream();
+ OutputStreamWriter pwriter = new OutputStreamWriter(pbos);
+
+ final XMLEventReader propertyReader = propertyElement.getValue().getContentReader();
+
+ try {
+ while (true) {
+ final XmlElement property = extractElement(propertyReader, null, null, 0, -1, -1).getValue();
+ final String name = property.getStart().getName().getLocalPart();
+
+ if (properties.containsKey(name)) {
+ // replace
+ final InputStream replacement = properties.get(name);
+ properties.remove(property.getStart().getName().getLocalPart());
+ pwriter.append(IOUtils.toString(replacement));
+ IOUtils.closeQuietly(replacement);
+ } else {
+ pwriter.append(IOUtils.toString(property.toStream()));
+ }
+ }
+ } catch (Exception ignore) {
+ // end
+ }
+
+ for (Map.Entry<String, InputStream> remains : properties.entrySet()) {
+ if (!remains.getKey().startsWith("[LINK]")) {
+ pwriter.append(IOUtils.toString(remains.getValue()));
+ IOUtils.closeQuietly(remains.getValue());
+ }
+ }
+
+ pwriter.flush();
+ pwriter.close();
+
+ writer.add(propertyElement.getValue().getStart());
+ writer.add(new XMLEventReaderWrapper(new ByteArrayInputStream(pbos.toByteArray())));
+ writer.add(propertyElement.getValue().getEnd());
+
+ IOUtils.closeQuietly(pbos);
+
+ writer.add(reader);
+ reader.close();
+ writer.flush();
+ writer.close();
+ // ---------------------------------
+
+ // ---------------------------------
+ // add navigationm changes
+ // ---------------------------------
+
+ // remove existent links
+ for (Map.Entry<String, InputStream> remains : properties.entrySet()) {
+
+ if (remains.getKey().startsWith("[LINK]")) {
+ reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+ bos.reset();
+ writer = getEventWriter(bos);
+
+ try {
+ final String linkName = remains.getKey().substring(remains.getKey().indexOf("]") + 1);
+
+ extractElement(reader, writer, Collections.<String>singletonList(LINK),
+ Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>("title", linkName)),
+ false, 0, 2, 2);
+
+ writer.add(reader);
+
+ } catch (Exception ignore) {
+ // ignore
+ }
+
+ writer.flush();
+ writer.close();
+ }
+ }
+
+ reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+ bos.reset();
+ writer = getEventWriter(bos);
+
+ propertyElement = extractElement(reader, writer, Collections.<String>singletonList(CONTENT), 0, 2, 2);
+ writer.flush();
+
+ pbos.reset();
+ pwriter = new OutputStreamWriter(pbos);
+
+ for (Map.Entry<String, InputStream> remains : properties.entrySet()) {
+ if (remains.getKey().startsWith("[LINK]")) {
+ pwriter.append(IOUtils.toString(remains.getValue()));
+ IOUtils.closeQuietly(remains.getValue());
+ }
+ }
+
+ pwriter.flush();
+ pwriter.close();
+
+ writer.add(new XMLEventReaderWrapper(new ByteArrayInputStream(pbos.toByteArray())));
+ IOUtils.closeQuietly(pbos);
+
+ writer.add(propertyElement.getValue().getStart());
+ writer.add(propertyElement.getValue().getContentReader());
+ writer.add(propertyElement.getValue().getEnd());
+
+ writer.add(reader);
+ reader.close();
+ writer.flush();
+ writer.close();
+ // ---------------------------------
+
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+
+ @Override
+ protected InputStream replaceLink(
+ final InputStream toBeChanged, final String linkName, final InputStream replacement)
+ throws Exception {
+ final XMLEventReader reader = getEventReader(toBeChanged);
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final XMLEventWriter writer = getEventWriter(bos);
+
+ final XMLEventFactory eventFactory = XMLEventFactory.newInstance();
+ XMLEvent newLine = eventFactory.createSpace("\n");
+
+ try {
+ final XmlElement linkElement =
+ extractElement(reader, writer, Collections.<String>singletonList(LINK),
+ Collections.<Map.Entry<String, String>>singletonList(new SimpleEntry<String, String>("title", linkName)),
+ false, 0, -1, -1).getValue();
+ writer.add(linkElement.getStart());
+
+ // ------------------------------------------
+ // write inline ...
+ // ------------------------------------------
+ writer.add(newLine);
+ writer.add(eventFactory.createStartElement("m", null, "inline"));
+
+ addAtomElement(replacement, writer);
+
+ writer.add(eventFactory.createEndElement("m", null, "inline"));
+ writer.add(newLine);
+ // ------------------------------------------
+
+ writer.add(linkElement.getEnd());
+
+ writer.add(reader);
+ writer.flush();
+ writer.close();
+ } finally {
+ reader.close();
+ IOUtils.closeQuietly(toBeChanged);
+ }
+
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+
+ public String getEdmTypeFromAtom(final String entitySetName, final String entityId, final List<String> path)
+ throws Exception {
+ InputStream src = fsManager.readFile(Commons.getEntityBasePath(entitySetName, entityId) + ENTITY, Accept.XML);
+
+ final List<String> atomPathElements = new ArrayList<String>();
+
+ for (String element : path) {
+ atomPathElements.add(ATOM_PROPERTY_PREFIX + element);
+ }
+
+ final Map.Entry<Integer, XmlElement> prop = extractElement(getEventReader(src), null, atomPathElements, 0, 3, 4);
+ IOUtils.closeQuietly(src);
+
+ final Attribute type = prop.getValue().getStart().getAttributeByName(new QName(TYPE));
+
+ final String edmType;
+
+ if (type == null) {
+ edmType = Constants.ATOM_DEF_TYPE;
+ } else {
+ edmType = type.getValue();
+ }
+
+ return edmType;
+ }
+
+ @Override
+ public Map.Entry<String, List<String>> extractLinkURIs(
+ final String entitySetName, final String entityId, final String linkName)
+ throws Exception {
+ final LinkInfo links = readLinks(entitySetName, entityId, linkName, Accept.XML);
+ return extractLinkURIs(links.getLinks());
+ }
+
+ @Override
+ public Map.Entry<String, List<String>> extractLinkURIs(final InputStream is)
+ throws Exception {
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ IOUtils.copy(is, bos);
+ IOUtils.closeQuietly(is);
+
+ XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+ final List<String> links = new ArrayList<String>();
+ try {
+ while (true) {
+ links.add(IOUtils.toString(extractElement(reader, null, Collections.<String>singletonList("uri"), 0, -1, -1).
+ getValue().getContent()));
+ }
+ } catch (Exception ignore) {
+ // End document reached ...
+ }
+ reader.close();
+
+ String next;
+
+ reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+ try {
+ next = IOUtils.toString(extractElement(reader, null, Collections.<String>singletonList("next"), 0, -1, -1).
+ getValue().getContent());
+ } catch (Exception ignore) {
+ // next link is not mandatory
+ next = null;
+ }
+ reader.close();
+
+ return new AbstractMap.SimpleEntry<String, List<String>>(next, links);
+ }
+
+ @Override
+ public InputStream getProperty(
+ final String entitySetName, final String entityId, final List<String> path, final String edmType)
+ throws Exception {
+ final List<String> pathElements = new ArrayList<String>();
+
+ for (String element : path) {
+ pathElements.add(ATOM_PROPERTY_PREFIX + element);
+ }
+
+ final InputStream src =
+ fsManager.readFile(Commons.getEntityBasePath(entitySetName, entityId) + 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(ATOM_DATASERVICE_NS)) == null) {
+ writer.add(eventFactory.createNamespace(ATOM_PROPERTY_PREFIX.substring(0, 1), DATASERVICES_NS));
+ }
+ if (property.getStart().getAttributeByName(new QName(ATOM_METADATA_NS)) == null) {
+ writer.add(eventFactory.createNamespace(ATOM_METADATA_PREFIX.substring(0, 1), 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<String> path, final boolean justValue)
+ throws Exception {
+
+ final List<String> pathElements = new ArrayList<String>();
+
+ for (String element : path) {
+ pathElements.add(ATOM_PROPERTY_PREFIX + element);
+ }
+
+ final XMLEventReader reader = getEventReader(src);
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final XMLEventWriter writer = getEventWriter(bos);
+
+ final Map.Entry<Integer, XmlElement> element = extractElement(reader, writer, pathElements, 0, 3, 4);
+
+ if (justValue) {
+ writer.add(element.getValue().getStart());
+ }
+
+ final XMLEventReader changesReader = new XMLEventReaderWrapper(replacement);
+
+ writer.add(changesReader);
+ changesReader.close();
+ IOUtils.closeQuietly(replacement);
+
+ if (justValue) {
+ writer.add(element.getValue().getEnd());
+ }
+
+ writer.add(reader);
+
+ reader.close();
+ IOUtils.closeQuietly(src);
+
+ writer.flush();
+ writer.close();
+
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+
+ @Override
+ public InputStream deleteProperty(final InputStream src, final List<String> path) throws Exception {
+
+ final List<String> pathElements = new ArrayList<String>();
+
+ for (String element : path) {
+ pathElements.add(ATOM_PROPERTY_PREFIX + element);
+ }
+
+ final XMLEventReader reader = getEventReader(src);
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final XMLEventWriter writer = getEventWriter(bos);
+
+ final Map.Entry<Integer, XmlElement> 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))));
+
+ writer.add(changesReader);
+ changesReader.close();
+
+ writer.add(reader);
+
+ reader.close();
+ IOUtils.closeQuietly(src);
+
+ writer.flush();
+ writer.close();
+
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/Accept.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/Accept.java b/fit/src/main/java/org/apache/olingo/fit/utils/Accept.java
index 9fdf1da..2371843 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/Accept.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/Accept.java
@@ -28,24 +28,35 @@ public enum Accept {
TEXT(ContentType.TEXT_PLAIN.getMimeType(), ".txt"),
XML(ContentType.APPLICATION_XML.getMimeType(), ".xml"),
ATOM(ContentType.APPLICATION_ATOM_XML.getMimeType(), ".xml"),
- JSON(ContentType.APPLICATION_JSON.getMimeType() + ";odata=minimalmetadata", ".full.json"),
- JSON_NOMETA(ContentType.APPLICATION_JSON.getMimeType() + ";odata=nometadata", ".full.json"),
- JSON_FULLMETA(ContentType.APPLICATION_JSON.getMimeType() + ";odata=fullmetadata", ".full.json");
+ JSON(ContentType.APPLICATION_JSON.getMimeType() + ";odata=minimalmetadata",
+ ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=minimal", ".full.json"),
+ JSON_NOMETA(ContentType.APPLICATION_JSON.getMimeType() + ";odata=nometadata",
+ ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=none", ".full.json"),
+ JSON_FULLMETA(ContentType.APPLICATION_JSON.getMimeType() + ";odata=fullmetadata",
+ ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=full", ".full.json");
- private final String contentType;
+ private final String contentTypeV3;
+
+ private final String contentTypeV4;
private final String fileExtension;
private static Pattern allTypesPattern = Pattern.compile("(.*,)?\\*/\\*([,;].*)?");
- Accept(final String contentType, final String fileExtension) {
- this.contentType = contentType;
+ Accept(final String contentTypeV3, final String fileExtension) {
+ this.contentTypeV3 = contentTypeV3;
+ this.contentTypeV4 = contentTypeV3;
+ this.fileExtension = fileExtension;
+ }
+
+ Accept(final String contentTypeV3, final String contentTypeV4, final String fileExtension) {
+ this.contentTypeV3 = contentTypeV3;
+ this.contentTypeV4 = contentTypeV4;
this.fileExtension = fileExtension;
}
- @Override
- public String toString() {
- return contentType;
+ public String toString(final ODataVersion version) {
+ return ODataVersion.v3 == version ? contentTypeV3 : contentTypeV4;
}
public String getExtension() {
@@ -53,23 +64,30 @@ public enum Accept {
}
public static Accept parse(final String contentType, final ODataVersion version) {
- return parse(contentType, version, ODataVersion.v3 == version ? ATOM : JSON_NOMETA);
+ final Accept def;
+ if (ODataVersion.v3 == version) {
+ def = ATOM;
+ } else {
+ def = JSON_NOMETA;
+ }
+
+ return parse(contentType, version, def);
}
public static Accept parse(final String contentType, final ODataVersion version, final Accept def) {
if (StringUtils.isBlank(contentType) || allTypesPattern.matcher(contentType).matches()) {
return def;
- } else if (JSON_NOMETA.toString().equals(contentType)) {
+ } else if (JSON_NOMETA.toString(version).equals(contentType)) {
return JSON_NOMETA;
- } else if (JSON.toString().equals(contentType) || "application/json".equals(contentType)) {
+ } else if (JSON.toString(version).equals(contentType) || "application/json".equals(contentType)) {
return JSON;
- } else if (JSON_FULLMETA.toString().equals(contentType)) {
+ } else if (JSON_FULLMETA.toString(version).equals(contentType)) {
return JSON_FULLMETA;
- } else if (XML.toString().equals(contentType)) {
+ } else if (XML.toString(version).equals(contentType)) {
return XML;
- } else if (ATOM.toString().equals(contentType)) {
+ } else if (ATOM.toString(version).equals(contentType)) {
return ATOM;
- } else if (TEXT.toString().equals(contentType)) {
+ } else if (TEXT.toString(version).equals(contentType)) {
return TEXT;
} else {
throw new UnsupportedMediaTypeException("Unsupported media type");
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java b/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java
index 233e03d..dcc4807 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java
@@ -74,6 +74,10 @@ public abstract class Commons {
mediaContent.put("Car/Photo", null);
}
+ public static Map<ODataVersion, MetadataLinkInfo> getLinkInfo() {
+ return linkInfo;
+ }
+
public static String getEntityURI(final String entitySetName, final String entityKey) {
return entitySetName + "(" + entityKey + ")";
}
@@ -230,7 +234,7 @@ public abstract class Commons {
break;
default:
- throw new UnsupportedOperationException(target.toString());
+ throw new UnsupportedOperationException(target.name());
}
for (String field : toBeRemoved) {
[7/8] git commit: [OLINGO-205, OLINGO-200, OLINGO-65] merge
Posted by fm...@apache.org.
[OLINGO-205, OLINGO-200, OLINGO-65] merge
Project: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/commit/5b5576f8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/tree/5b5576f8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/diff/5b5576f8
Branch: refs/heads/olingo200
Commit: 5b5576f86cfa8d3fb07151ff774238ba2a87c0d9
Parents: 9aefb95 a55ed62
Author: fmartelli <fa...@gmail.com>
Authored: Mon Mar 24 10:05:44 2014 +0100
Committer: fmartelli <fa...@gmail.com>
Committed: Mon Mar 24 10:05:44 2014 +0100
----------------------------------------------------------------------
lib/client-api/pom.xml | 5 -
.../olingo/client/api/CommonConfiguration.java | 8 +-
.../olingo/client/api/CommonODataClient.java | 12 +-
.../org/apache/olingo/client/api/Constants.java | 258 ------------
.../ODataClientErrorException.java | 2 +-
.../request/ODataBasicRequest.java | 2 +-
.../request/cud/CommonCUDRequestFactory.java | 8 +-
.../request/cud/ODataDeleteRequest.java | 2 +-
.../request/cud/ODataEntityCreateRequest.java | 2 +-
.../request/cud/ODataEntityUpdateRequest.java | 2 +-
.../request/cud/ODataLinkCreateRequest.java | 2 +-
.../request/cud/ODataLinkUpdateRequest.java | 2 +-
.../request/cud/ODataPropertyUpdateRequest.java | 2 +-
.../request/cud/ODataValueUpdateRequest.java | 2 +-
.../invoke/CommonInvokeRequestFactory.java | 4 +-
.../request/invoke/ODataInvokeRequest.java | 6 +-
.../request/invoke/ODataNoContent.java | 2 +-
.../request/retrieve/ODataEntityRequest.java | 4 +-
.../retrieve/ODataEntitySetIteratorRequest.java | 2 +-
.../request/retrieve/ODataEntitySetRequest.java | 4 +-
.../request/retrieve/ODataMediaRequest.java | 2 +-
.../request/retrieve/ODataMetadataRequest.java | 2 +-
.../request/retrieve/ODataPropertyRequest.java | 4 +-
.../request/retrieve/ODataRetrieveRequest.java | 2 +-
.../retrieve/ODataServiceDocumentRequest.java | 4 +-
.../request/retrieve/ODataValueRequest.java | 4 +-
.../retrieve/v3/ODataLinkCollectionRequest.java | 2 +-
.../streamed/ODataStreamedEntityRequest.java | 2 +-
.../response/ODataEntityCreateResponse.java | 2 +-
.../response/ODataEntityUpdateResponse.java | 2 +-
.../response/ODataInvokeResponse.java | 2 +-
.../ODataMediaEntityCreateResponse.java | 2 +-
.../ODataMediaEntityUpdateResponse.java | 2 +-
.../response/ODataPropertyUpdateResponse.java | 2 +-
.../response/ODataValueUpdateResponse.java | 2 +-
.../olingo/client/api/data/CollectionValue.java | 27 --
.../olingo/client/api/data/ComplexValue.java | 27 --
.../apache/olingo/client/api/data/Entry.java | 167 --------
.../org/apache/olingo/client/api/data/Feed.java | 75 ----
.../apache/olingo/client/api/data/GeoUtils.java | 90 -----
.../olingo/client/api/data/GeospatialValue.java | 28 --
.../org/apache/olingo/client/api/data/Link.java | 121 ------
.../olingo/client/api/data/NullValue.java | 26 --
.../olingo/client/api/data/ODataError.java | 67 ---
.../olingo/client/api/data/PrimitiveValue.java | 25 --
.../apache/olingo/client/api/data/Property.java | 34 --
.../apache/olingo/client/api/data/Value.java | 44 --
.../client/api/data/v3/LinkCollection.java | 52 ---
.../client/api/domain/AbstractODataValue.java | 127 ------
.../client/api/domain/ODataCollectionValue.java | 98 -----
.../client/api/domain/ODataComplexValue.java | 97 -----
.../olingo/client/api/domain/ODataEntity.java | 316 ---------------
.../client/api/domain/ODataEntitySet.java | 120 ------
.../api/domain/ODataEntitySetIterator.java | 8 +-
.../client/api/domain/ODataGeospatialValue.java | 57 ---
.../client/api/domain/ODataInlineEntity.java | 74 ----
.../client/api/domain/ODataInlineEntitySet.java | 74 ----
.../client/api/domain/ODataInvokeResult.java | 30 --
.../olingo/client/api/domain/ODataItem.java | 111 -----
.../olingo/client/api/domain/ODataLink.java | 190 ---------
.../olingo/client/api/domain/ODataLinkType.java | 93 -----
.../client/api/domain/ODataObjectFactory.java | 218 ----------
.../client/api/domain/ODataOperation.java | 88 ----
.../client/api/domain/ODataPrimitiveValue.java | 67 ---
.../olingo/client/api/domain/ODataProperty.java | 186 ---------
.../client/api/domain/ODataPropertyType.java | 40 --
.../client/api/domain/ODataServiceDocument.java | 183 ---------
.../olingo/client/api/domain/ODataValue.java | 84 ----
.../apache/olingo/client/api/format/Format.java | 26 --
.../olingo/client/api/format/ODataFormat.java | 103 -----
.../client/api/format/ODataMediaFormat.java | 77 ----
.../client/api/format/ODataPubFormat.java | 122 ------
.../client/api/format/ODataValueFormat.java | 82 ----
.../client/api/op/ClientODataDeserializer.java | 39 ++
.../olingo/client/api/op/CommonODataBinder.java | 18 +-
.../client/api/op/CommonODataDeserializer.java | 84 ----
.../olingo/client/api/op/CommonODataReader.java | 14 +-
.../olingo/client/api/op/ODataSerializer.java | 100 -----
.../olingo/client/api/op/ODataWriter.java | 10 +-
.../olingo/client/api/op/v3/ODataBinder.java | 2 +-
.../client/api/op/v3/ODataDeserializer.java | 8 +-
.../olingo/client/api/op/v3/ODataReader.java | 2 +-
.../client/api/op/v4/ODataDeserializer.java | 4 +-
lib/client-core/pom.xml | 21 -
.../client/core/AbstractConfiguration.java | 8 +-
.../olingo/client/core/AbstractODataClient.java | 8 +-
.../request/AbstractODataBasicRequest.java | 2 +-
.../communication/request/ODataRequestImpl.java | 14 +-
.../request/batch/ODataBatchUtilities.java | 2 +-
.../request/cud/AbstractCUDRequestFactory.java | 8 +-
.../request/cud/ODataDeleteRequestImpl.java | 2 +-
.../cud/ODataEntityCreateRequestImpl.java | 4 +-
.../cud/ODataEntityUpdateRequestImpl.java | 4 +-
.../request/cud/ODataLinkCreateRequestImpl.java | 4 +-
.../request/cud/ODataLinkUpdateRequestImpl.java | 4 +-
.../cud/ODataPropertyUpdateRequestImpl.java | 4 +-
.../cud/ODataValueUpdateRequestImpl.java | 4 +-
.../invoke/AbstractInvokeRequestFactory.java | 2 +-
.../request/invoke/ODataInvokeRequestImpl.java | 14 +-
.../invoke/v3/InvokeRequestFactoryImpl.java | 10 +-
.../invoke/v4/InvokeRequestFactoryImpl.java | 4 +-
.../retrieve/AbstractODataRetrieveRequest.java | 2 +-
.../retrieve/ODataEntityRequestImpl.java | 4 +-
.../ODataEntitySetIteratorRequestImpl.java | 2 +-
.../retrieve/ODataEntitySetRequestImpl.java | 4 +-
.../request/retrieve/ODataMediaRequestImpl.java | 2 +-
.../retrieve/ODataMetadataRequestImpl.java | 2 +-
.../retrieve/ODataPropertyRequestImpl.java | 4 +-
.../request/retrieve/ODataRawRequestImpl.java | 2 +-
.../ODataServiceDocumentRequestImpl.java | 4 +-
.../request/retrieve/ODataValueRequestImpl.java | 4 +-
.../v3/ODataLinkCollectionRequestImpl.java | 2 +-
.../AbstractODataStreamedEntityRequest.java | 2 +-
.../streamed/AbstractODataStreamedRequest.java | 2 +-
.../ODataMediaEntityCreateRequestImpl.java | 2 +-
.../ODataMediaEntityUpdateRequestImpl.java | 2 +-
.../batch/ODataBatchResponseManager.java | 2 +-
.../client/core/data/AbstractAtomDealer.java | 87 ----
.../client/core/data/AbstractAtomObject.java | 78 ----
.../olingo/client/core/data/AbstractEntry.java | 159 --------
.../core/data/AbstractJsonDeserializer.java | 175 --------
.../core/data/AbstractJsonSerializer.java | 94 -----
.../client/core/data/AbstractPayloadObject.java | 48 ---
.../client/core/data/AbstractPropertyImpl.java | 80 ----
.../olingo/client/core/data/AbstractValue.java | 98 -----
.../client/core/data/AtomDeserializer.java | 368 -----------------
.../olingo/client/core/data/AtomEntryImpl.java | 25 --
.../olingo/client/core/data/AtomFeedImpl.java | 66 ---
.../core/data/AtomGeoValueDeserializer.java | 253 ------------
.../core/data/AtomGeoValueSerializer.java | 222 ----------
.../core/data/AtomPropertyDeserializer.java | 218 ----------
.../client/core/data/AtomPropertyImpl.java | 25 --
.../core/data/AtomPropertySerializer.java | 88 ----
.../olingo/client/core/data/AtomSerializer.java | 264 ------------
.../client/core/data/CollectionValueImpl.java | 40 --
.../client/core/data/ComplexValueImpl.java | 40 --
.../client/core/data/GeospatialValueImpl.java | 42 --
.../client/core/data/JSONEntryDeserializer.java | 244 -----------
.../olingo/client/core/data/JSONEntryImpl.java | 94 -----
.../client/core/data/JSONEntrySerializer.java | 120 ------
.../client/core/data/JSONErrorBundle.java | 50 ---
.../olingo/client/core/data/JSONErrorImpl.java | 237 -----------
.../client/core/data/JSONFeedDeserializer.java | 68 ----
.../olingo/client/core/data/JSONFeedImpl.java | 113 ------
.../client/core/data/JSONFeedSerializer.java | 57 ---
.../core/data/JSONGeoValueDeserializer.java | 265 ------------
.../core/data/JSONGeoValueSerializer.java | 175 --------
.../core/data/JSONPropertyDeserializer.java | 71 ----
.../client/core/data/JSONPropertyImpl.java | 53 ---
.../core/data/JSONPropertySerializer.java | 59 ---
.../data/JSONServiceDocumentDeserializer.java | 5 +-
.../olingo/client/core/data/LinkImpl.java | 112 -----
.../olingo/client/core/data/NullValueImpl.java | 35 --
.../core/data/ODataJacksonDeserializer.java | 45 ---
.../core/data/ODataJacksonSerializer.java | 45 ---
.../client/core/data/PrimitiveValueImpl.java | 41 --
.../olingo/client/core/data/XMLErrorImpl.java | 213 ----------
.../data/XMLServiceDocumentDeserializer.java | 3 +-
.../core/data/v3/JSONLinkCollectionImpl.java | 118 ------
.../core/data/v3/JSONServiceDocumentImpl.java | 4 +-
.../core/data/v3/XMLLinkCollectionImpl.java | 70 ----
.../core/data/v4/JSONServiceDocumentImpl.java | 4 +-
.../core/domain/ODataGeospatialValueImpl.java | 4 +-
.../core/domain/ODataPrimitiveValueImpl.java | 13 +-
.../client/core/edm/EdmActionImportImpl.java | 2 +-
.../olingo/client/core/edm/EdmClientImpl.java | 1 +
.../client/core/edm/EdmComplexTypeImpl.java | 1 +
.../client/core/edm/EdmEntityContainerImpl.java | 1 +
.../client/core/edm/EdmEntityTypeImpl.java | 1 +
.../client/core/edm/EdmFunctionImportImpl.java | 1 +
.../core/edm/EdmNavigationPropertyImpl.java | 1 +
.../client/core/edm/EdmParameterImpl.java | 1 +
.../olingo/client/core/edm/EdmPropertyImpl.java | 1 +
.../client/core/edm/EdmReturnTypeImpl.java | 1 +
.../olingo/client/core/edm/EdmTypeInfo.java | 184 ---------
.../core/edm/v3/EdmActionImportProxy.java | 2 +-
.../core/edm/v3/EdmFunctionImportProxy.java | 2 +-
.../core/edm/xml/AbstractComplexType.java | 1 -
.../core/edm/xml/AbstractEdmDeserializer.java | 71 ++++
.../core/edm/xml/AbstractEntityContainer.java | 1 -
.../client/core/edm/xml/AbstractEntitySet.java | 1 -
.../client/core/edm/xml/AbstractEntityType.java | 1 -
.../client/core/edm/xml/AbstractEnumType.java | 1 -
.../client/core/edm/xml/AbstractSchema.java | 1 -
.../core/edm/xml/ComplexTypeDeserializer.java | 82 ++++
.../core/edm/xml/DataServicesDeserializer.java | 3 +-
.../client/core/edm/xml/EdmxDeserializer.java | 3 +-
.../edm/xml/EntityContainerDeserializer.java | 101 +++++
.../core/edm/xml/EntityKeyDeserializer.java | 47 +++
.../client/core/edm/xml/EntityKeyImpl.java | 1 -
.../core/edm/xml/EntitySetDeserializer.java | 69 ++++
.../core/edm/xml/EntityTypeDeserializer.java | 90 +++++
.../core/edm/xml/EnumTypeDeserializer.java | 72 ++++
.../core/edm/xml/ParameterDeserializer.java | 3 +-
.../core/edm/xml/PropertyDeserializer.java | 3 +-
.../client/core/edm/xml/SchemaDeserializer.java | 148 +++++++
.../edm/xml/v3/AnnotationsDeserializer.java | 2 +-
.../edm/xml/v3/AssociationDeserializer.java | 2 +-
.../edm/xml/v3/AssociationSetDeserializer.java | 2 +-
.../edm/xml/v3/FunctionImportDeserializer.java | 2 +-
.../ReferentialConstraintRoleDeserializer.java | 2 +-
.../edm/xml/v3/TypeAnnotationDeserializer.java | 2 +-
.../core/edm/xml/v4/ActionDeserializer.java | 2 +-
.../core/edm/xml/v4/AnnotationDeserializer.java | 2 +-
.../edm/xml/v4/AnnotationsDeserializer.java | 2 +-
.../core/edm/xml/v4/FunctionDeserializer.java | 2 +-
.../xml/v4/NavigationPropertyDeserializer.java | 2 +-
.../core/edm/xml/v4/ReferenceDeserializer.java | 2 +-
.../core/edm/xml/v4/ReturnTypeDeserializer.java | 2 +-
.../core/edm/xml/v4/SingletonDeserializer.java | 2 +-
.../core/edm/xml/v4/TermDeserializer.java | 2 +-
.../edm/xml/v4/TypeDefinitionDeserializer.java | 2 +-
.../xml/v4/annotation/ApplyDeserializer.java | 2 +-
.../edm/xml/v4/annotation/CastDeserializer.java | 2 +-
.../v4/annotation/CollectionDeserializer.java | 2 +-
.../DynExprConstructDeserializer.java | 2 +-
.../edm/xml/v4/annotation/IsOfDeserializer.java | 2 +-
.../annotation/LabeledElementDeserializer.java | 2 +-
.../edm/xml/v4/annotation/NullDeserializer.java | 2 +-
.../annotation/PropertyValueDeserializer.java | 2 +-
.../xml/v4/annotation/RecordDeserializer.java | 2 +-
.../xml/v4/annotation/UrlRefDeserializer.java | 2 +-
.../client/core/op/AbstractODataBinder.java | 405 +++++++++++++++++++
.../client/core/op/AbstractODataReader.java | 117 ++++++
.../olingo/client/core/op/ODataWriterImpl.java | 102 +++++
.../core/op/impl/AbstractEdmDeserializer.java | 71 ----
.../core/op/impl/AbstractJacksonTool.java | 85 ----
.../core/op/impl/AbstractODataBinder.java | 404 ------------------
.../core/op/impl/AbstractODataDeserializer.java | 106 -----
.../core/op/impl/AbstractODataReader.java | 117 ------
.../core/op/impl/AbstractODataSerializer.java | 141 -------
.../core/op/impl/ComplexTypeDeserializer.java | 83 ----
.../op/impl/EntityContainerDeserializer.java | 102 -----
.../core/op/impl/EntityKeyDeserializer.java | 50 ---
.../core/op/impl/EntitySetDeserializer.java | 70 ----
.../core/op/impl/EntityTypeDeserializer.java | 92 -----
.../core/op/impl/EnumTypeDeserializer.java | 73 ----
.../op/impl/InjectableSerializerProvider.java | 43 --
.../core/op/impl/ODataObjectFactoryImpl.java | 165 --------
.../client/core/op/impl/ODataWriterImpl.java | 101 -----
.../client/core/op/impl/ResourceFactory.java | 125 ------
.../client/core/op/impl/SchemaDeserializer.java | 149 -------
.../client/core/op/impl/v3/ODataBinderImpl.java | 4 +-
.../core/op/impl/v3/ODataDeserializerImpl.java | 16 +-
.../client/core/op/impl/v3/ODataReaderImpl.java | 6 +-
.../core/op/impl/v3/ODataSerializerImpl.java | 8 +-
.../client/core/op/impl/v4/ODataBinderImpl.java | 4 +-
.../core/op/impl/v4/ODataDeserializerImpl.java | 10 +-
.../client/core/op/impl/v4/ODataReaderImpl.java | 6 +-
.../core/op/impl/v4/ODataSerializerImpl.java | 8 +-
.../apache/olingo/client/core/uri/URIUtils.java | 22 +-
.../olingo/client/core/v3/ODataClientImpl.java | 6 +-
.../olingo/client/core/v4/ODataClientImpl.java | 6 +-
.../client/core/AbstractPrimitiveTest.java | 10 +-
.../client/core/AbstractPropertyTest.java | 12 +-
.../apache/olingo/client/core/AbstractTest.java | 4 +-
.../olingo/client/core/AtomLinksQualifier.java | 2 +-
.../client/core/it/AbstractTestITCase.java | 28 +-
.../client/core/it/v3/AsyncTestITCase.java | 4 +-
.../client/core/it/v3/CountTestITCase.java | 4 +-
.../core/it/v3/EntityCreateTestITCase.java | 12 +-
.../core/it/v3/EntityRetrieveTestITCase.java | 16 +-
.../client/core/it/v3/EntitySetTestITCase.java | 6 +-
.../core/it/v3/EntityUpdateTestITCase.java | 4 +-
.../client/core/it/v3/ErrorTestITCase.java | 4 +-
.../core/it/v3/FilterFactoryTestITCase.java | 2 +-
.../client/core/it/v3/FilterTestITCase.java | 2 +-
.../core/it/v3/KeyAsSegmentTestITCase.java | 4 +-
.../client/core/it/v3/LinkTestITCase.java | 4 +-
.../core/it/v3/MediaEntityTestITCase.java | 8 +-
.../it/v3/NavigationLinkCreateTestITCase.java | 20 +-
.../client/core/it/v3/OpenTypeTestITCase.java | 6 +-
.../core/it/v3/PrimitiveKeysTestITCase.java | 4 +-
.../core/it/v3/PropertyRetrieveTestITCase.java | 14 +-
.../client/core/it/v3/PropertyTestITCase.java | 10 +-
.../core/it/v3/PropertyValueTestITCase.java | 6 +-
.../core/it/v3/QueryOptionsTestITCase.java | 12 +-
.../v3/ServiceDocumentRetrieveTestITCase.java | 4 +-
.../core/it/v3/ServiceDocumentTestITCase.java | 4 +-
.../client/core/it/v4/EntitySetTestITCase.java | 8 +-
.../apache/olingo/client/core/v3/AtomTest.java | 4 +-
.../olingo/client/core/v3/EntitySetTest.java | 6 +-
.../olingo/client/core/v3/EntityTest.java | 10 +-
.../apache/olingo/client/core/v3/ErrorTest.java | 4 +-
.../apache/olingo/client/core/v3/JSONTest.java | 6 +-
.../client/core/v3/PrimitiveValueTest.java | 2 +-
.../client/core/v3/ServiceDocumentTest.java | 4 +-
.../client/core/v4/PrimitiveValueTest.java | 2 +-
.../client/core/v4/ServiceDocumentTest.java | 4 +-
.../client/core/v3/AllGeoTypesSet_-10_Geom.xml | 13 +-
.../v3/AllGeoTypesSet_-3_GeomMultiPolygon.xml | 43 +-
.../olingo/client/core/v3/AllGeoTypesSet_-5.xml | 97 ++---
.../v3/AllGeoTypesSet_-5_GeogCollection.xml | 19 +-
.../core/v3/AllGeoTypesSet_-5_GeogPolygon.xml | 18 +-
.../core/v3/AllGeoTypesSet_-6_GeomMultiLine.xml | 24 +-
.../v3/AllGeoTypesSet_-7_GeomMultiPoint.xml | 14 +-
.../olingo/client/core/v3/AllGeoTypesSet_-8.xml | 81 ++--
.../v3/AllGeoTypesSet_-8_GeomCollection.xml | 18 +-
lib/commons-api/pom.xml | 5 +
.../apache/olingo/commons/api/Constants.java | 243 +++++++++++
.../commons/api/data/CollectionValue.java | 27 ++
.../olingo/commons/api/data/ComplexValue.java | 27 ++
.../apache/olingo/commons/api/data/Entry.java | 167 ++++++++
.../apache/olingo/commons/api/data/Feed.java | 75 ++++
.../olingo/commons/api/data/GeoUtils.java | 90 +++++
.../commons/api/data/GeospatialValue.java | 28 ++
.../apache/olingo/commons/api/data/Link.java | 121 ++++++
.../olingo/commons/api/data/NullValue.java | 26 ++
.../olingo/commons/api/data/PrimitiveValue.java | 25 ++
.../olingo/commons/api/data/Property.java | 34 ++
.../apache/olingo/commons/api/data/Value.java | 44 ++
.../commons/api/data/v3/LinkCollection.java | 52 +++
.../commons/api/domain/AbstractODataValue.java | 127 ++++++
.../api/domain/ODataCollectionValue.java | 98 +++++
.../commons/api/domain/ODataComplexValue.java | 97 +++++
.../olingo/commons/api/domain/ODataEntity.java | 316 +++++++++++++++
.../commons/api/domain/ODataEntitySet.java | 120 ++++++
.../olingo/commons/api/domain/ODataError.java | 67 +++
.../api/domain/ODataGeospatialValue.java | 57 +++
.../commons/api/domain/ODataInlineEntity.java | 74 ++++
.../api/domain/ODataInlineEntitySet.java | 74 ++++
.../commons/api/domain/ODataInvokeResult.java | 30 ++
.../olingo/commons/api/domain/ODataItem.java | 111 +++++
.../olingo/commons/api/domain/ODataLink.java | 190 +++++++++
.../commons/api/domain/ODataLinkType.java | 93 +++++
.../commons/api/domain/ODataObjectFactory.java | 218 ++++++++++
.../commons/api/domain/ODataOperation.java | 88 ++++
.../commons/api/domain/ODataPrimitiveValue.java | 67 +++
.../commons/api/domain/ODataProperty.java | 186 +++++++++
.../commons/api/domain/ODataPropertyType.java | 40 ++
.../api/domain/ODataServiceDocument.java | 183 +++++++++
.../olingo/commons/api/domain/ODataValue.java | 84 ++++
.../olingo/commons/api/format/ContentType.java | 47 +++
.../olingo/commons/api/format/Format.java | 26 ++
.../olingo/commons/api/format/ODataFormat.java | 102 +++++
.../commons/api/format/ODataMediaFormat.java | 76 ++++
.../commons/api/format/ODataPubFormat.java | 121 ++++++
.../commons/api/format/ODataValueFormat.java | 81 ++++
.../commons/api/op/CommonODataDeserializer.java | 71 ++++
.../olingo/commons/api/op/ODataSerializer.java | 100 +++++
lib/commons-core/pom.xml | 21 +
.../commons/core/data/AbstractAtomDealer.java | 87 ++++
.../commons/core/data/AbstractAtomObject.java | 78 ++++
.../olingo/commons/core/data/AbstractEntry.java | 159 ++++++++
.../core/data/AbstractJsonDeserializer.java | 175 ++++++++
.../core/data/AbstractJsonSerializer.java | 94 +++++
.../core/data/AbstractPayloadObject.java | 48 +++
.../commons/core/data/AbstractPropertyImpl.java | 80 ++++
.../olingo/commons/core/data/AbstractValue.java | 98 +++++
.../commons/core/data/AtomDeserializer.java | 368 +++++++++++++++++
.../olingo/commons/core/data/AtomEntryImpl.java | 25 ++
.../olingo/commons/core/data/AtomFeedImpl.java | 66 +++
.../core/data/AtomGeoValueDeserializer.java | 261 ++++++++++++
.../core/data/AtomGeoValueSerializer.java | 221 ++++++++++
.../core/data/AtomPropertyDeserializer.java | 218 ++++++++++
.../commons/core/data/AtomPropertyImpl.java | 25 ++
.../core/data/AtomPropertySerializer.java | 88 ++++
.../commons/core/data/AtomSerializer.java | 264 ++++++++++++
.../commons/core/data/CollectionValueImpl.java | 40 ++
.../commons/core/data/ComplexValueImpl.java | 40 ++
.../commons/core/data/GeospatialValueImpl.java | 42 ++
.../core/data/JSONEntryDeserializer.java | 241 +++++++++++
.../olingo/commons/core/data/JSONEntryImpl.java | 92 +++++
.../commons/core/data/JSONEntrySerializer.java | 120 ++++++
.../commons/core/data/JSONErrorBundle.java | 50 +++
.../olingo/commons/core/data/JSONErrorImpl.java | 237 +++++++++++
.../commons/core/data/JSONFeedDeserializer.java | 68 ++++
.../olingo/commons/core/data/JSONFeedImpl.java | 113 ++++++
.../commons/core/data/JSONFeedSerializer.java | 57 +++
.../core/data/JSONGeoValueDeserializer.java | 273 +++++++++++++
.../core/data/JSONGeoValueSerializer.java | 183 +++++++++
.../core/data/JSONPropertyDeserializer.java | 71 ++++
.../commons/core/data/JSONPropertyImpl.java | 53 +++
.../core/data/JSONPropertySerializer.java | 59 +++
.../olingo/commons/core/data/LinkImpl.java | 112 +++++
.../olingo/commons/core/data/NullValueImpl.java | 35 ++
.../core/data/ODataJacksonDeserializer.java | 44 ++
.../core/data/ODataJacksonSerializer.java | 45 +++
.../commons/core/data/PrimitiveValueImpl.java | 41 ++
.../olingo/commons/core/data/XMLErrorImpl.java | 213 ++++++++++
.../core/data/v3/JSONLinkCollectionImpl.java | 118 ++++++
.../core/data/v3/XMLLinkCollectionImpl.java | 70 ++++
.../olingo/commons/core/edm/EdmTypeInfo.java | 184 +++++++++
.../commons/core/op/AbstractJacksonTool.java | 83 ++++
.../core/op/AbstractODataDeserializer.java | 106 +++++
.../core/op/AbstractODataSerializer.java | 141 +++++++
.../core/op/InjectableSerializerProvider.java | 43 ++
.../commons/core/op/ODataObjectFactoryImpl.java | 162 ++++++++
.../olingo/commons/core/op/ResourceFactory.java | 125 ++++++
389 files changed, 11517 insertions(+), 11309 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonConfiguration.java
----------------------------------------------------------------------
diff --cc lib/client-api/src/main/java/org/apache/olingo/client/api/CommonConfiguration.java
index 48f2614,59786f3..af0ec21
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonConfiguration.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonConfiguration.java
@@@ -18,15 -18,15 +18,15 @@@
*/
package org.apache.olingo.client.api;
- import org.apache.olingo.client.api.format.ODataFormat;
- import org.apache.olingo.client.api.format.ODataMediaFormat;
- import org.apache.olingo.client.api.format.ODataPubFormat;
- import org.apache.olingo.client.api.format.ODataValueFormat;
-import org.apache.olingo.commons.api.format.ODataFormat;
-import org.apache.olingo.commons.api.format.ODataMediaFormat;
-import org.apache.olingo.commons.api.format.ODataPubFormat;
-import org.apache.olingo.commons.api.format.ODataValueFormat;
import org.apache.olingo.client.api.http.HttpClientFactory;
import org.apache.olingo.client.api.http.HttpUriRequestFactory;
import java.io.Serializable;
import java.util.concurrent.ExecutorService;
++import org.apache.olingo.commons.api.format.ODataFormat;
++import org.apache.olingo.commons.api.format.ODataMediaFormat;
++import org.apache.olingo.commons.api.format.ODataPubFormat;
++import org.apache.olingo.commons.api.format.ODataValueFormat;
/**
* Configuration wrapper.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java
----------------------------------------------------------------------
diff --cc lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java
index 7ba38f8,f64b233..1d97bcc
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java
@@@ -20,7 -20,6 +20,7 @@@ package org.apache.olingo.client.api.co
import java.util.concurrent.Future;
import org.apache.olingo.client.api.communication.response.ODataResponse;
- import org.apache.olingo.client.api.format.Format;
++import org.apache.olingo.commons.api.format.Format;
/**
* Basic OData request.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java
----------------------------------------------------------------------
diff --cc lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java
index 14f907e,edabb96..073f520
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java
@@@ -20,7 -20,6 +20,7 @@@ package org.apache.olingo.client.api.co
import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
- import org.apache.olingo.client.api.format.Format;
++import org.apache.olingo.commons.api.format.Format;
/**
* This is an abstract representation of an OData retrieve query request returning one or more result item.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
----------------------------------------------------------------------
diff --cc lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
index 8cd5819,307cdc9..80eadf1
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
@@@ -31,7 -31,6 +31,7 @@@ import org.apache.olingo.client.api.com
import org.apache.olingo.client.api.communication.request.ODataStreamer;
import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
import org.apache.olingo.client.api.communication.response.ODataResponse;
- import org.apache.olingo.client.api.format.Format;
++import org.apache.olingo.commons.api.format.Format;
import org.apache.olingo.client.api.http.HttpMethod;
/**
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
----------------------------------------------------------------------
diff --cc lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
index 2e60a7d,bec2f65..3e6c1bb
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
@@@ -42,22 -42,17 +42,22 @@@ import org.apache.olingo.client.api.com
import org.apache.olingo.client.api.communication.header.ODataHeaders;
import org.apache.olingo.client.api.communication.request.ODataRequest;
import org.apache.olingo.client.api.communication.request.ODataStreamer;
+import org.apache.olingo.client.api.communication.request.batch.v3.BatchRequestFactory;
+import org.apache.olingo.client.api.communication.request.cud.v3.CUDRequestFactory;
+import org.apache.olingo.client.api.communication.request.invoke.v3.InvokeRequestFactory;
+import org.apache.olingo.client.api.communication.request.streamed.v3.StreamedRequestFactory;
import org.apache.olingo.client.api.communication.response.ODataResponse;
- import org.apache.olingo.client.api.format.ODataMediaFormat;
- import org.apache.olingo.client.api.format.ODataPubFormat;
- import org.apache.olingo.client.api.format.ODataValueFormat;
++import org.apache.olingo.commons.api.format.Format;
+import org.apache.olingo.client.api.http.HttpClientException;
+import org.apache.olingo.client.api.http.HttpMethod;
- import org.apache.olingo.client.core.data.JSONErrorImpl;
- import org.apache.olingo.client.core.data.XMLErrorImpl;
- import org.apache.olingo.client.api.data.ODataError;
- import org.apache.olingo.client.api.format.Format;
+import org.apache.olingo.client.core.communication.header.ODataHeadersImpl;
++import org.apache.olingo.commons.api.domain.ODataError;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+ import org.apache.olingo.commons.api.format.ODataMediaFormat;
+ import org.apache.olingo.commons.api.format.ODataPubFormat;
+ import org.apache.olingo.commons.api.format.ODataValueFormat;
-import org.apache.olingo.client.api.http.HttpClientException;
-import org.apache.olingo.client.api.http.HttpMethod;
+ import org.apache.olingo.commons.core.data.JSONErrorImpl;
+ import org.apache.olingo.commons.core.data.XMLErrorImpl;
-import org.apache.olingo.commons.api.domain.ODataError;
-import org.apache.olingo.client.core.communication.header.ODataHeadersImpl;
-import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/ODataInvokeRequestImpl.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java
----------------------------------------------------------------------
diff --cc lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java
index 628e836,fe51722..7fd3966
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java
@@@ -26,7 -26,6 +26,7 @@@ import org.apache.olingo.client.api.Com
import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
import org.apache.olingo.client.api.communication.request.retrieve.ODataRetrieveRequest;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
- import org.apache.olingo.client.api.format.Format;
++import org.apache.olingo.commons.api.format.Format;
import org.apache.olingo.client.api.http.HttpMethod;
import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest;
import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedEntityRequest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmActionImportImpl.java
----------------------------------------------------------------------
diff --cc lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmActionImportImpl.java
index bf047af,ae64d31..ae6b8d4
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmActionImportImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmActionImportImpl.java
@@@ -40,5 -41,5 +41,4 @@@ public class EdmActionImportImpl extend
return edm.getAction(new EdmTypeInfo.Builder().setEdm(edm).setTypeExpression(actionImport.getAction()).
setDefaultNamespace(container.getNamespace()).build().getFullQualifiedName(), null, null);
}
--
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java
----------------------------------------------------------------------
diff --cc lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java
index 0000000,0524c13..44e7ad4
mode 000000,100644..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
@@@ -1,0 -1,405 +1,405 @@@
+ /*
+ * 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.op;
+
+ import org.apache.olingo.commons.core.op.ResourceFactory;
+ import java.io.StringWriter;
+ import java.net.URI;
+ import java.util.Iterator;
+ 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.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.client.api.data.ServiceDocumentItem;
+ 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.ODataEntity;
+ import org.apache.olingo.commons.api.domain.ODataEntitySet;
+ 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.ODataProperty;
+ import org.apache.olingo.commons.api.domain.ODataServiceDocument;
+ import org.apache.olingo.commons.api.domain.ODataValue;
+ import org.apache.olingo.commons.api.format.ODataPubFormat;
+ import org.apache.olingo.client.api.op.CommonODataBinder;
+ import org.apache.olingo.commons.core.data.CollectionValueImpl;
+ import org.apache.olingo.commons.core.data.ComplexValueImpl;
+ import org.apache.olingo.commons.core.data.GeospatialValueImpl;
+ import org.apache.olingo.commons.core.data.JSONPropertyImpl;
+ import org.apache.olingo.commons.core.data.LinkImpl;
+ import org.apache.olingo.commons.core.data.NullValueImpl;
+ import org.apache.olingo.commons.core.data.PrimitiveValueImpl;
+ import org.apache.olingo.client.core.uri.URIUtils;
+ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+
+ public abstract class AbstractODataBinder implements CommonODataBinder {
+
+ private static final long serialVersionUID = 454285889193689536L;
+
+ /**
+ * Logger.
+ */
+ protected final Logger LOG = LoggerFactory.getLogger(AbstractODataBinder.class);
+
+ protected final CommonODataClient client;
+
+ protected AbstractODataBinder(final CommonODataClient client) {
+ this.client = client;
+ }
+
+ @Override
+ public ODataServiceDocument getODataServiceDocument(final ServiceDocument resource) {
+ final ODataServiceDocument serviceDocument = new ODataServiceDocument();
+
+ for (ServiceDocumentItem entitySet : resource.getEntitySets()) {
+ // handles V3 JSON format oddities, where title is not contained
+ serviceDocument.getEntitySets().put(StringUtils.isBlank(entitySet.getTitle())
+ ? entitySet.getName() : entitySet.getTitle(),
+ URIUtils.getURI(resource.getBaseURI(), entitySet.getHref()));
+ }
+
+ return serviceDocument;
+ }
+
+ @Override
+ public Feed getFeed(final ODataEntitySet feed, final Class<? extends Feed> reference) {
+ final Feed feedResource = ResourceFactory.newFeed(reference);
+
+ feedResource.setCount(feed.getCount());
+
+ final URI next = feed.getNext();
+ if (next != null) {
+ feedResource.setNext(next);
+ }
+
+ for (ODataEntity entity : feed.getEntities()) {
+ feedResource.getEntries().add(getEntry(entity, ResourceFactory.entryClassForFeed(reference)));
+ }
+
+ return feedResource;
+ }
+
+ @Override
+ public Entry getEntry(final ODataEntity entity, final Class<? extends Entry> reference) {
+ return getEntry(entity, reference, true);
+ }
+
+ @Override
+ public Entry getEntry(final ODataEntity entity, final Class<? extends Entry> reference, final boolean setType) {
+ final Entry entry = ResourceFactory.newEntry(reference);
+ entry.setType(entity.getName());
+
+ // -------------------------------------------------------------
+ // Add edit and self link
+ // -------------------------------------------------------------
+ final URI editLink = entity.getEditLink();
+ if (editLink != null) {
+ final LinkImpl entryEditLink = new LinkImpl();
+ entryEditLink.setTitle(entity.getName());
+ entryEditLink.setHref(editLink.toASCIIString());
+ entryEditLink.setRel(Constants.EDIT_LINK_REL);
+ entry.setEditLink(entryEditLink);
+ }
+
+ if (entity.isReadOnly()) {
+ final LinkImpl entrySelfLink = new LinkImpl();
+ entrySelfLink.setTitle(entity.getName());
+ entrySelfLink.setHref(entity.getLink().toASCIIString());
+ entrySelfLink.setRel(Constants.SELF_LINK_REL);
+ entry.setSelfLink(entrySelfLink);
+ }
+ // -------------------------------------------------------------
+
+ // -------------------------------------------------------------
+ // Append navigation links (handling inline entry / feed as well)
+ // -------------------------------------------------------------
+ // handle navigation links
+ for (ODataLink link : entity.getNavigationLinks()) {
+ // append link
+ LOG.debug("Append navigation link\n{}", link);
+ entry.getNavigationLinks().add(getLink(link,
+ ResourceFactory.formatForEntryClass(reference) == ODataPubFormat.ATOM));
+ }
+ // -------------------------------------------------------------
+
+ // -------------------------------------------------------------
+ // Append edit-media links
+ // -------------------------------------------------------------
+ for (ODataLink link : entity.getEditMediaLinks()) {
+ LOG.debug("Append edit-media link\n{}", link);
+ entry.getMediaEditLinks().add(getLink(link,
+ ResourceFactory.formatForEntryClass(reference) == ODataPubFormat.ATOM));
+ }
+ // -------------------------------------------------------------
+
+ // -------------------------------------------------------------
+ // Append association links
+ // -------------------------------------------------------------
+ for (ODataLink link : entity.getAssociationLinks()) {
+ LOG.debug("Append association link\n{}", link);
+ entry.getAssociationLinks().add(getLink(link,
+ ResourceFactory.formatForEntryClass(reference) == ODataPubFormat.ATOM));
+ }
+ // -------------------------------------------------------------
+
+ if (entity.isMediaEntity()) {
+ entry.setMediaContentSource(entity.getMediaContentSource());
+ entry.setMediaContentType(entity.getMediaContentType());
+ }
+
+ for (ODataProperty property : entity.getProperties()) {
+ entry.getProperties().add(getProperty(property, reference, setType));
+ }
+
+ return entry;
+ }
+
+ @Override
+ public Link getLink(final ODataLink link, boolean isXML) {
+ final Link linkResource = new LinkImpl();
+ linkResource.setRel(link.getRel());
+ linkResource.setTitle(link.getName());
+ linkResource.setHref(link.getLink() == null ? null : link.getLink().toASCIIString());
+ linkResource.setType(link.getType().toString());
+ linkResource.setMediaETag(link.getMediaETag());
+
+ if (link instanceof ODataInlineEntity) {
+ // append inline entity
+ final ODataEntity inlineEntity = ((ODataInlineEntity) link).getEntity();
+ LOG.debug("Append in-line entity\n{}", inlineEntity);
+
+ linkResource.setInlineEntry(getEntry(inlineEntity, ResourceFactory.entryClassForFormat(isXML)));
+ } else if (link instanceof ODataInlineEntitySet) {
+ // append inline feed
+ final ODataEntitySet InlineFeed = ((ODataInlineEntitySet) link).getEntitySet();
+ LOG.debug("Append in-line feed\n{}", InlineFeed);
+
+ linkResource.setInlineFeed(getFeed(InlineFeed, ResourceFactory.feedClassForFormat(isXML)));
+ }
+
+ return linkResource;
+ }
+
+ @Override
+ public Property getProperty(final ODataProperty property, final Class<? extends Entry> reference,
+ final boolean setType) {
+
+ final Property propertyResource = ResourceFactory.newProperty(reference);
+ propertyResource.setName(property.getName());
+ propertyResource.setValue(getValue(property.getValue(), reference, setType));
+
+ if (setType) {
+ if (property.hasPrimitiveValue()) {
+ propertyResource.setType(property.getPrimitiveValue().getType().toString());
+ } else if (property.hasComplexValue()) {
+ propertyResource.setType(property.getComplexValue().getType());
+ } else if (property.hasCollectionValue()) {
+ propertyResource.setType(property.getCollectionValue().getType());
+ }
+ }
+
+ return propertyResource;
+ }
+
+ private Value getValue(final ODataValue value, final Class<? extends Entry> reference, final boolean setType) {
+ Value valueResource = null;
+
+ if (value == null) {
+ valueResource = new NullValueImpl();
+ } else if (value.isPrimitive()) {
+ valueResource = new PrimitiveValueImpl(value.asPrimitive().toString());
+ } else if (value.isGeospatial()) {
+ valueResource = new GeospatialValueImpl(value.asGeospatial().toValue());
+ } else if (value.isComplex()) {
+ final ODataComplexValue _value = value.asComplex();
+ valueResource = new ComplexValueImpl();
+
+ for (final Iterator<ODataProperty> itor = _value.iterator(); itor.hasNext();) {
+ valueResource.asComplex().get().add(getProperty(itor.next(), reference, setType));
+ }
+ } else if (value.isCollection()) {
+ final ODataCollectionValue _value = value.asCollection();
+ valueResource = new CollectionValueImpl();
+
+ for (final Iterator<ODataValue> itor = _value.iterator(); itor.hasNext();) {
+ valueResource.asCollection().get().add(getValue(itor.next(), reference, setType));
+ }
+ }
+
+ return valueResource;
+ }
+
+ @Override
+ public ODataEntitySet getODataEntitySet(final Feed resource) {
+ return getODataEntitySet(resource, null);
+ }
+
+ @Override
+ public ODataEntitySet getODataEntitySet(final Feed resource, final URI defaultBaseURI) {
+ if (LOG.isDebugEnabled()) {
+ final StringWriter writer = new StringWriter();
+ client.getSerializer().feed(resource, writer);
+ writer.flush();
+ LOG.debug("Feed -> ODataEntitySet:\n{}", writer.toString());
+ }
+
+ final URI base = defaultBaseURI == null ? resource.getBaseURI() : defaultBaseURI;
-
++
+ final URI next = resource.getNext();
+
+ final ODataEntitySet entitySet = next == null
+ ? client.getObjectFactory().newEntitySet()
+ : client.getObjectFactory().newEntitySet(URIUtils.getURI(base, next.toASCIIString()));
+
+ if (resource.getCount() != null) {
+ entitySet.setCount(resource.getCount());
+ }
+
+ for (Entry entryResource : resource.getEntries()) {
+ entitySet.addEntity(getODataEntity(entryResource));
+ }
-
++
+ return entitySet;
+ }
+
+ @Override
+ public ODataEntity getODataEntity(final Entry resource) {
+ return getODataEntity(resource, null);
+ }
+
+ @Override
+ public ODataEntity getODataEntity(final Entry resource, final URI defaultBaseURI) {
+ if (LOG.isDebugEnabled()) {
+ final StringWriter writer = new StringWriter();
+ client.getSerializer().entry(resource, writer);
+ writer.flush();
+ LOG.debug("EntryResource -> ODataEntity:\n{}", writer.toString());
+ }
+
+ final URI base = defaultBaseURI == null ? resource.getBaseURI() : defaultBaseURI;
+
+ final ODataEntity entity = resource.getSelfLink() == null
+ ? client.getObjectFactory().newEntity(resource.getType())
+ : client.getObjectFactory().newEntity(resource.getType(),
+ URIUtils.getURI(base, resource.getSelfLink().getHref()));
+
+ if (StringUtils.isNotBlank(resource.getETag())) {
+ entity.setETag(resource.getETag());
+ }
-
++
+ if (resource.getEditLink() != null) {
+ entity.setEditLink(URIUtils.getURI(base, resource.getEditLink().getHref()));
+ }
-
++
+ for (Link link : resource.getAssociationLinks()) {
+ entity.addLink(client.getObjectFactory().newAssociationLink(link.getTitle(), base, link.getHref()));
+ }
+
+ for (Link link : resource.getNavigationLinks()) {
+ final Entry inlineEntry = link.getInlineEntry();
+ final Feed inlineFeed = link.getInlineFeed();
+
+ if (inlineEntry == null && inlineFeed == null) {
+ entity.addLink(
+ client.getObjectFactory().newEntityNavigationLink(link.getTitle(), base, link.getHref()));
+ } else if (inlineFeed == null) {
+ entity.addLink(client.getObjectFactory().newInlineEntity(
+ link.getTitle(), base, link.getHref(),
+ getODataEntity(inlineEntry,
+ inlineEntry.getBaseURI() == null ? base : inlineEntry.getBaseURI())));
+ } else {
+ entity.addLink(client.getObjectFactory().newInlineEntitySet(
+ link.getTitle(), base, link.getHref(),
+ getODataEntitySet(inlineFeed,
+ inlineFeed.getBaseURI() == null ? base : inlineFeed.getBaseURI())));
+ }
+ }
+
+ for (Link link : resource.getMediaEditLinks()) {
+ entity.addLink(client.getObjectFactory().newMediaEditLink(link.getTitle(), base, link.getHref()));
+ }
+
+ for (ODataOperation operation : resource.getOperations()) {
+ operation.setTarget(URIUtils.getURI(base, operation.getTarget()));
+ entity.getOperations().add(operation);
+ }
+
+ if (resource.isMediaEntry()) {
+ entity.setMediaEntity(true);
+ entity.setMediaContentSource(resource.getMediaContentSource());
+ entity.setMediaContentType(resource.getMediaContentType());
+ }
+
+ for (Property property : resource.getProperties()) {
+ entity.getProperties().add(getODataProperty(property));
+ }
+
+ return entity;
+ }
+
+ @Override
+ public ODataProperty getODataProperty(final Property property) {
+ return new ODataProperty(property.getName(), getODataValue(property));
+ }
+
+ private ODataValue getODataValue(final Property resource) {
+ ODataValue value = null;
+
+ if (resource.getValue().isSimple()) {
+ value = client.getPrimitiveValueBuilder().
+ setText(resource.getValue().asSimple().get()).
+ setType(resource.getType() == null
+ ? null
+ : EdmPrimitiveTypeKind.valueOfFQN(client.getServiceVersion(), resource.getType())).build();
+ } else if (resource.getValue().isGeospatial()) {
+ value = client.getGeospatialValueBuilder().
+ setValue(resource.getValue().asGeospatial().get()).
+ setType(resource.getType() == null
+ || EdmPrimitiveTypeKind.Geography.getFullQualifiedName().toString().equals(resource.getType())
+ || EdmPrimitiveTypeKind.Geometry.getFullQualifiedName().toString().equals(resource.getType())
+ ? null
+ : EdmPrimitiveTypeKind.valueOfFQN(client.getServiceVersion(), resource.getType())).build();
+ } else if (resource.getValue().isComplex()) {
+ value = new ODataComplexValue(resource.getType());
+
+ for (Property property : resource.getValue().asComplex().get()) {
+ value.asComplex().add(getODataProperty(property));
+ }
+ } else if (resource.getValue().isCollection()) {
+ value = new ODataCollectionValue(resource.getType());
+
+ for (Value _value : resource.getValue().asCollection().get()) {
+ final JSONPropertyImpl fake = new JSONPropertyImpl();
+ fake.setValue(_value);
+ value.asCollection().add(getODataValue(fake));
+ }
+ }
+
+ return value;
+ }
+ }
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityRetrieveTestITCase.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntitySetTestITCase.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/QueryOptionsTestITCase.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
----------------------------------------------------------------------
diff --cc lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
index 9e2527a,0000000..e3e8a1e
mode 100644,000000..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
@@@ -1,152 -1,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.client.core.it.v4;
+
++import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetIteratorRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataRawRequest;
+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.ODataEntitySet;
+import org.apache.olingo.client.api.domain.ODataEntitySetIterator;
- import org.apache.olingo.client.api.format.ODataPubFormat;
+import org.apache.olingo.client.api.uri.CommonURIBuilder;
- import org.apache.olingo.client.core.op.impl.ResourceFactory;
- import static org.junit.Assert.assertNotNull;
++import org.apache.olingo.commons.api.domain.ODataEntitySet;
++import org.apache.olingo.commons.api.format.ODataPubFormat;
++import org.apache.olingo.commons.core.op.ResourceFactory;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * This is the unit test class to check basic feed operations.
+ */
+public class EntitySetTestITCase extends AbstractTestITCase {
+
+ protected String getServiceRoot() {
+ return testStaticServiceRootURL;
+ }
+
+ @Test
+ public void rawRequestAsAtom() throws IOException {
+ rawRequest(ODataPubFormat.ATOM);
+ }
+
+ @Test
+ @Ignore
+ public void rawRequestAsJSON() throws IOException {
+ rawRequest(ODataPubFormat.JSON);
+ }
+
+ @Test
+ public void readODataEntitySetIteratorFromAtom() {
+ readODataEntitySetIterator(ODataPubFormat.ATOM);
+ }
+
+ @Test
+ @Ignore
+ public void readODataEntitySetIteratorFromJSON() {
+ readODataEntitySetIterator(ODataPubFormat.JSON);
+ }
+
+ @Test
+ @Ignore
+ public void readODataEntitySetIteratorFromJSONFullMeta() {
+ readODataEntitySetIterator(ODataPubFormat.JSON_FULL_METADATA);
+ }
+
+ @Test
+ @Ignore
+ public void readODataEntitySetIteratorFromJSONNoMeta() {
+ readODataEntitySetIterator(ODataPubFormat.JSON_NO_METADATA);
+ }
+
+ @Test
+ public void readODataEntitySetWithNextFromAtom() {
+ readEntitySetWithNextLink(ODataPubFormat.ATOM);
+ }
+
+ @Test
+ @Ignore
+ public void readODataEntitySetWithNextFromJSON() {
+ readEntitySetWithNextLink(ODataPubFormat.JSON_FULL_METADATA);
+ }
+
+ private void readEntitySetWithNextLink(final ODataPubFormat format) {
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot());
+ uriBuilder.appendEntitySetSegment("People");
+
+ final ODataEntitySetRequest req = client.getRetrieveRequestFactory().getEntitySetRequest(uriBuilder.build());
+ req.setFormat(format);
+
+ final ODataRetrieveResponse<ODataEntitySet> res = req.execute();
+ final ODataEntitySet feed = res.getBody();
+
+ assertNotNull(feed);
+
+ debugFeed(client.getBinder().getFeed(feed, ResourceFactory.feedClassForFormat(
+ ODataPubFormat.ATOM == format)), "Just retrieved feed");
+
+ assertEquals(5, feed.getEntities().size());
+// assertNotNull(feed.getNext());
+
+// final URI expected = URI.create(getServiceRoot() + "/Customer?$skiptoken=-9");
+// final URI found = URIUtils.getURI(getServiceRoot(), feed.getNext().toASCIIString());
+
+// assertEquals(expected, found);
+ }
+
+ private void readODataEntitySetIterator(final ODataPubFormat format) {
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot());
+ uriBuilder.appendEntitySetSegment("People");
+
+ final ODataEntitySetIteratorRequest req =
+ client.getRetrieveRequestFactory().getEntitySetIteratorRequest(uriBuilder.build());
+ req.setFormat(format);
+
+ final ODataRetrieveResponse<ODataEntitySetIterator> res = req.execute();
+ final ODataEntitySetIterator feedIterator = res.getBody();
+
+ assertNotNull(feedIterator);
+
+ int count = 0;
+
+ while (feedIterator.hasNext()) {
+ assertNotNull(feedIterator.next());
+ count++;
+ }
+ assertEquals(5, count);
+// assertTrue(feedIterator.getNext().toASCIIString().endsWith("Customer?$skiptoken=-9"));
+ }
+
+ private void rawRequest(final ODataPubFormat format) {
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot());
+ 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 ODataEntitySet entitySet = res.getBodyAs(ODataEntitySet.class);
+ assertNotNull(entitySet);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataLinkType.java
----------------------------------------------------------------------
diff --cc lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataLinkType.java
index 0000000,59dc834..28727ea
mode 000000,100644..100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataLinkType.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataLinkType.java
@@@ -1,0 -1,93 +1,93 @@@
+ /*
+ * 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.domain;
+
+ import org.apache.commons.lang3.StringUtils;
+ import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+ import org.apache.olingo.commons.api.format.ContentType;
-import org.apache.olingo.commons.api.format.ODataPubFormat;
+
+ /**
+ * OData link types.
+ */
+ public enum ODataLinkType {
+
+ /**
+ * Entity navigation link.
+ */
- ENTITY_NAVIGATION(ODataPubFormat.ATOM + ";type=entry"),
++ ENTITY_NAVIGATION(ContentType.APPLICATION_ATOM_XML + ";type=entry"),
+ /**
+ * Entity set navigation link.
+ */
- ENTITY_SET_NAVIGATION(ODataPubFormat.ATOM + ";type=feed"),
++ ENTITY_SET_NAVIGATION(ContentType.APPLICATION_ATOM_XML + ";type=feed"),
+ /**
+ * Association link.
+ */
+ ASSOCIATION(ContentType.APPLICATION_XML),
+ /**
+ * Media-edit link.
+ */
+ MEDIA_EDIT("*/*");
+
+ private String type;
+
+ private ODataLinkType(final String type) {
+ this.type = type;
+ }
+
+ private ODataLinkType setType(final String type) {
+ this.type = type;
+ return this;
+ }
+
+ /**
- * Gets <code>LinkType</code> instance from the given rel and type.
++ * Gets
++ * <code>LinkType</code> instance from the given rel and type.
+ *
+ * @param version OData protocol version.
+ * @param rel rel.
+ * @param type type.
+ * @return <code>ODataLinkType</code> object.
+ */
+ public static ODataLinkType fromString(final ODataServiceVersion version, final String rel, final String type) {
+ if (StringUtils.isNotBlank(rel)
+ && rel.startsWith(version.getNamespaceMap().get(ODataServiceVersion.MEDIA_EDIT_LINK_REL))) {
+
+ return MEDIA_EDIT.setType(StringUtils.isBlank(type) ? "*/*" : type);
+ }
+
+ if (ODataLinkType.ENTITY_NAVIGATION.type.equals(type)) {
+ return ENTITY_NAVIGATION;
+ }
+
+ if (ODataLinkType.ENTITY_SET_NAVIGATION.type.equals(type)) {
+ return ENTITY_SET_NAVIGATION;
+ }
+
+ if (ODataLinkType.ASSOCIATION.type.equals(type)) {
+ return ASSOCIATION;
+ }
+
+ throw new IllegalArgumentException("Invalid link type: " + type);
+ }
+
+ @Override
+ public String toString() {
+ return type;
+ }
+ }
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/Format.java
----------------------------------------------------------------------
diff --cc lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/Format.java
index 0000000,0000000..f031018
new file mode 100644
--- /dev/null
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/Format.java
@@@ -1,0 -1,0 +1,26 @@@
++/*
++ * 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.format;
++
++import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
++
++public interface Format {
++
++ String toString(ODataServiceVersion version);
++}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataFormat.java
----------------------------------------------------------------------
diff --cc lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataFormat.java
index 0000000,30d9e09..7401e0b
mode 000000,100644..100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataFormat.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataFormat.java
@@@ -1,0 -1,95 +1,102 @@@
+ /*
+ * 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.format;
+
++import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
++
+ /**
+ * Available formats to be used in various contexts.
+ */
-public enum ODataFormat {
++public enum ODataFormat implements Format{
+
+ /**
+ * JSON format with no metadata.
+ */
+ JSON_NO_METADATA(ContentType.APPLICATION_JSON + ";odata=nometadata"),
+ /**
+ * JSON format with minimal metadata (default).
+ */
+ JSON(ContentType.APPLICATION_JSON + ";odata=minimalmetadata"),
+ /**
+ * JSON format with no metadata.
+ */
+ JSON_FULL_METADATA(ContentType.APPLICATION_JSON + ";odata=fullmetadata"),
+ /**
+ * XML format.
+ */
+ XML(ContentType.APPLICATION_XML);
+
+ private final String format;
+
+ ODataFormat(final String format) {
+ this.format = format;
+ }
+
+ /**
+ * Gets format as a string.
+ *
+ * @return format as a string.
+ */
+ @Override
+ public String toString() {
+ return format;
+ }
+
+ /**
+ * Gets OData format from its string representation.
+ *
+ * @param format string representation of the format.
+ * @return OData format.
+ */
+ public static ODataFormat fromString(final String format) {
+ ODataFormat result = null;
+
+ final StringBuffer _format = new StringBuffer();
+
+ final String[] parts = format.split(";");
+ _format.append(parts[0].trim());
+ if (ContentType.APPLICATION_JSON.equals(parts[0].trim())) {
+ if (parts.length > 1) {
+ _format.append(';').append(parts[1].trim());
+ } else {
+ result = ODataFormat.JSON;
+ }
+ }
+
+ if (result == null) {
+ final String candidate = _format.toString();
+ for (ODataFormat value : values()) {
+ if (candidate.equals(value.toString())) {
+ result = value;
+ }
+ }
+ }
+
+ if (result == null) {
+ throw new IllegalArgumentException("Unsupported format: " + format);
+ }
+
+ return result;
+ }
++
++ @Override
++ public String toString(final ODataServiceVersion version) {
++ return this.toString();
++ }
+ }
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataMediaFormat.java
----------------------------------------------------------------------
diff --cc lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataMediaFormat.java
index 0000000,c479de4..a9410d5
mode 000000,100644..100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataMediaFormat.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataMediaFormat.java
@@@ -1,0 -1,69 +1,76 @@@
+ /*
+ * 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.format;
+
++import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
++
+ /**
+ * Available formats for media.
+ */
-public enum ODataMediaFormat {
++public enum ODataMediaFormat implements Format{
+
+ CHARSET_PARAMETER("charset"),
+ MEDIA_TYPE_WILDCARD("*"),
+ WILDCARD(ContentType.WILDCARD),
+ APPLICATION_XML(ContentType.APPLICATION_XML),
+ APPLICATION_ATOM_XML(ContentType.APPLICATION_ATOM_XML),
+ APPLICATION_XHTML_XML(ContentType.APPLICATION_XHTML_XML),
+ APPLICATION_SVG_XML(ContentType.APPLICATION_SVG_XML),
+ APPLICATION_JSON(ContentType.APPLICATION_JSON),
+ APPLICATION_FORM_URLENCODED(ContentType.APPLICATION_FORM_URLENCODED),
+ MULTIPART_FORM_DATA(ContentType.MULTIPART_FORM_DATA),
+ APPLICATION_OCTET_STREAM(ContentType.APPLICATION_OCTET_STREAM),
+ TEXT_PLAIN(ContentType.TEXT_PLAIN),
+ TEXT_XML(ContentType.TEXT_XML),
+ TEXT_HTML(ContentType.TEXT_HTML);
+
+ private final String format;
+
+ private ODataMediaFormat(final String format) {
+ this.format = format;
+ }
+
+ @Override
+ public String toString() {
+ return format;
+ }
+
+ public static ODataMediaFormat fromFormat(final String format) {
+ final String _format = format.split(";")[0];
+
+ ODataMediaFormat result = null;
+
+ for (ODataMediaFormat value : values()) {
+ if (_format.equals(value.toString())) {
+ result = value;
+ }
+ }
+
+ if (result == null) {
+ throw new IllegalArgumentException("Unsupported format: " + format);
+ }
+
+ return result;
+ }
++
++ @Override
++ public String toString(final ODataServiceVersion version) {
++ return this.toString();
++ }
+ }
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataPubFormat.java
----------------------------------------------------------------------
diff --cc lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataPubFormat.java
index 0000000,6cd6a05..62dc61b
mode 000000,100644..100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataPubFormat.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataPubFormat.java
@@@ -1,0 -1,95 +1,121 @@@
+ /*
+ * 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.format;
+
++import java.util.EnumMap;
++import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
++
+ /**
+ * Available formats for AtomPub exchange.
+ */
-public enum ODataPubFormat {
++public enum ODataPubFormat implements Format {
+
+ /**
+ * JSON format with no metadata.
+ */
- JSON_NO_METADATA(ContentType.APPLICATION_JSON + ";odata=nometadata"),
++ JSON_NO_METADATA(),
+ /**
+ * JSON format with minimal metadata (default).
+ */
- JSON(ContentType.APPLICATION_JSON + ";odata=minimalmetadata"),
++ JSON(),
+ /**
+ * JSON format with no metadata.
+ */
- JSON_FULL_METADATA(ContentType.APPLICATION_JSON + ";odata=fullmetadata"),
++ JSON_FULL_METADATA(),
+ /**
+ * Atom format.
+ */
- ATOM(ContentType.APPLICATION_ATOM_XML);
++ ATOM();
++
++ final static EnumMap<ODataServiceVersion, EnumMap<ODataPubFormat, String>> formatPerVersion =
++ new EnumMap<ODataServiceVersion, EnumMap<ODataPubFormat, String>>(ODataServiceVersion.class);
+
- private final String format;
++ static {
++ final EnumMap<ODataPubFormat, String> v3 = new EnumMap<ODataPubFormat, String>(ODataPubFormat.class);
++ v3.put(JSON_NO_METADATA, ContentType.APPLICATION_JSON + ";odata=nometadata");
++ v3.put(JSON, ContentType.APPLICATION_JSON + ";odata=minimalmetadata");
++ v3.put(JSON_FULL_METADATA, ContentType.APPLICATION_JSON + ";odata=fullmetadata");
++ v3.put(ATOM, ContentType.APPLICATION_ATOM_XML);
++ formatPerVersion.put(ODataServiceVersion.V30, v3);
+
- ODataPubFormat(final String format) {
- this.format = format;
++ final EnumMap<ODataPubFormat, String> v4 = new EnumMap<ODataPubFormat, String>(ODataPubFormat.class);
++ v4.put(JSON_NO_METADATA, ContentType.APPLICATION_JSON + ";odata.metadata=none");
++ v4.put(JSON, ContentType.APPLICATION_JSON + ";odata.metadata=minimal");
++ v4.put(JSON_FULL_METADATA, ContentType.APPLICATION_JSON + ";odata.metadata=full");
++ v4.put(ATOM, ContentType.APPLICATION_ATOM_XML);
++ formatPerVersion.put(ODataServiceVersion.V40, v4);
+ }
+
+ /**
+ * Gets format as a string.
+ *
+ * @return format as a string.
+ */
+ @Override
++ public String toString(final ODataServiceVersion version) {
++ if (version.ordinal() < ODataServiceVersion.V30.ordinal()) {
++ throw new IllegalArgumentException("Unsupported version " + version);
++ }
++
++ return ODataPubFormat.formatPerVersion.get(version).get(this);
++ }
++
++ @Override
+ public String toString() {
- return format;
++ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Gets OData format from its string representation.
+ *
+ * @param format string representation of the format.
+ * @return OData format.
+ */
+ public static ODataPubFormat fromString(final String format) {
+ ODataPubFormat result = null;
+
+ final StringBuffer _format = new StringBuffer();
+
+ final String[] parts = format.split(";");
+ _format.append(parts[0].trim());
+ if (ContentType.APPLICATION_JSON.equals(parts[0].trim())) {
- if (parts.length > 1 && parts[1].startsWith("odata=")) {
++ if (parts.length > 1 && parts[1].startsWith("odata")) {
+ _format.append(';').append(parts[1].trim());
+ } else {
+ result = ODataPubFormat.JSON;
+ }
+ }
+
+ if (result == null) {
+ final String candidate = _format.toString();
+ for (ODataPubFormat value : values()) {
- if (candidate.equals(value.toString())) {
++ if (candidate.equals(value.toString(ODataServiceVersion.V30))
++ || candidate.equals(value.toString(ODataServiceVersion.V40))) {
+ result = value;
+ }
+ }
+ }
+
+ if (result == null) {
+ throw new IllegalArgumentException("Unsupported format: " + format);
+ }
+
+ return result;
+ }
+ }
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataValueFormat.java
----------------------------------------------------------------------
diff --cc lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataValueFormat.java
index 0000000,1b290bf..28ce108
mode 000000,100644..100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataValueFormat.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataValueFormat.java
@@@ -1,0 -1,74 +1,81 @@@
+ /*
+ * 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.format;
+
++import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
++
+ /**
+ * Available formats for property values.
+ */
-public enum ODataValueFormat {
++public enum ODataValueFormat implements Format {
+
+ /**
+ * Application octet stream.
+ */
+ STREAM(ContentType.APPLICATION_OCTET_STREAM),
+ /**
+ * Plain text format.
+ */
+ TEXT(ContentType.TEXT_PLAIN);
+
+ private final String format;
+
+ ODataValueFormat(final String format) {
+ this.format = format;
+ }
+
+ /**
+ * Gets format as a string.
+ *
+ * @return format as a string.
+ */
+ @Override
+ public String toString() {
+ return format;
+ }
+
+ /**
+ * Gets format from its string representation.
+ *
+ * @param format string representation of the format.
+ * @return OData format.
+ */
+ public static ODataValueFormat fromString(final String format) {
+ final String _format = format.split(";")[0];
+
+ ODataValueFormat result = null;
+
+ for (ODataValueFormat value : values()) {
+ if (_format.equals(value.toString())) {
+ result = value;
+ }
+ }
+
+ if (result == null) {
+ throw new IllegalArgumentException("Unsupported format: " + format);
+ }
+
+ return result;
+ }
++
++ @Override
++ public String toString(final ODataServiceVersion version) {
++ return this.toString();
++ }
+ }
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonDeserializer.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonDeserializer.java
index 0000000,2d865ce..4c92ae6
mode 000000,100644..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
@@@ -1,0 -1,176 +1,175 @@@
+ /*
+ * 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.core.data;
+
+ import com.fasterxml.jackson.databind.JsonNode;
+ import com.fasterxml.jackson.databind.node.ObjectNode;
+ import java.util.Iterator;
+ import java.util.Map;
+ 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.Value;
+ import org.apache.olingo.commons.api.domain.ODataPropertyType;
+ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+ import org.apache.olingo.commons.core.edm.EdmTypeInfo;
+
+ abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<T> {
+
+ private JSONGeoValueDeserializer geoDeserializer;
+
+ private JSONGeoValueDeserializer getGeoDeserializer() {
+ if (geoDeserializer == null) {
+ geoDeserializer = new JSONGeoValueDeserializer(version);
+ }
+ return geoDeserializer;
+ }
+
+ protected EdmPrimitiveTypeKind getPrimitiveType(final JsonNode node) {
+ EdmPrimitiveTypeKind result = EdmPrimitiveTypeKind.String;
+
+ if (node.isIntegralNumber()) {
+ result = EdmPrimitiveTypeKind.Int32;
+ } else if (node.isBoolean()) {
+ result = EdmPrimitiveTypeKind.Boolean;
+ } else if (node.isFloatingPointNumber()) {
+ result = EdmPrimitiveTypeKind.Double;
+ }
+
+ return result;
+ }
+
+ private ODataPropertyType guessPropertyType(final JsonNode node) {
- ODataPropertyType type = null;
++ final ODataPropertyType type;
+
+ if (node.isValueNode() || node.isNull()) {
+ type = ODataPropertyType.PRIMITIVE;
+ } else if (node.isArray()) {
+ type = ODataPropertyType.COLLECTION;
+ } else if (node.isObject()) {
+ type = ODataPropertyType.COMPLEX;
+ } else {
+ type = ODataPropertyType.EMPTY;
+ }
+
+ return type;
+ }
+
+ private Value fromPrimitive(final JsonNode node, final EdmTypeInfo typeInfo) {
- Value value = null;
++ final Value value;
+
+ if (node.isNull()) {
+ value = new NullValueImpl();
+ } else {
+ if (typeInfo != null && typeInfo.getPrimitiveTypeKind().isGeospatial()) {
+ value = new GeospatialValueImpl(getGeoDeserializer().deserialize(node, typeInfo));
+ } else {
+ value = new PrimitiveValueImpl(node.asText());
+ }
+ }
+
+ return value;
+ }
+
+ private ComplexValue fromComplex(final JsonNode node) {
+ final ComplexValue value = new ComplexValueImpl();
+
+ String type = null;
+ for (final Iterator<Map.Entry<String, JsonNode>> itor = node.fields(); itor.hasNext();) {
+ final Map.Entry<String, JsonNode> field = itor.next();
+
+ if (type == null && field.getKey().endsWith(Constants.JSON_TYPE_SUFFIX)) {
+ type = field.getValue().asText();
+ } else {
+ final JSONPropertyImpl property = new JSONPropertyImpl();
+ property.setName(field.getKey());
+ property.setType(type);
+ type = null;
+
+ value(property, field.getValue());
+ value.get().add(property);
+ }
+ }
+
+ return value;
+ }
+
+ private CollectionValue fromCollection(final Iterator<JsonNode> nodeItor, final EdmTypeInfo typeInfo) {
+ final CollectionValueImpl value = new CollectionValueImpl();
+
+ final EdmTypeInfo type = typeInfo == null
+ ? null
+ : new EdmTypeInfo.Builder().setTypeExpression(typeInfo.getFullQualifiedName().toString()).build();
+
+ while (nodeItor.hasNext()) {
+ final JsonNode child = nodeItor.next();
+
+ if (child.isValueNode()) {
+ value.get().add(fromPrimitive(child, type));
+ } else if (child.isContainerNode()) {
+ if (child.has(Constants.JSON_TYPE)) {
+ ((ObjectNode) child).remove(Constants.JSON_TYPE);
+ }
+ value.get().add(fromComplex(child));
+ }
+ }
+
+ return value;
+ }
+
+ protected void value(final JSONPropertyImpl property, final JsonNode node) {
+ final EdmTypeInfo typeInfo = StringUtils.isBlank(property.getType())
+ ? null
+ : new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build();
+
+ final ODataPropertyType propType = typeInfo == null
+ ? guessPropertyType(node)
+ : typeInfo.isCollection()
+ ? ODataPropertyType.COLLECTION
+ : typeInfo.isPrimitiveType()
+ ? ODataPropertyType.PRIMITIVE
+ : ODataPropertyType.COMPLEX;
+
+ switch (propType) {
+ case COLLECTION:
+ property.setValue(fromCollection(node.elements(), typeInfo));
+ break;
+
+ case COMPLEX:
+ if (node.has(Constants.JSON_TYPE)) {
+ property.setType(node.get(Constants.JSON_TYPE).asText());
+ ((ObjectNode) node).remove(Constants.JSON_TYPE);
+ }
+ property.setValue(fromComplex(node));
+ break;
+
+ case PRIMITIVE:
+ if (property.getType() == null) {
+ property.setType(getPrimitiveType(node).getFullQualifiedName().toString());
+ }
+ property.setValue(fromPrimitive(node, typeInfo));
+ break;
+
+ case EMPTY:
+ default:
+ property.setValue(new PrimitiveValueImpl(StringUtils.EMPTY));
+ }
+ }
-
+ }
[6/8] [OLINGO-205, OLINGO-200, OLINGO-65] merge
Posted by fm...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java
index 0000000,f42fe00..b8775d5
mode 000000,100644..100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java
@@@ -1,0 -1,370 +1,368 @@@
+ /*
+ * 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.core.data;
+
+ import java.io.InputStream;
+ import java.net.URI;
+ import java.text.ParseException;
+ import javax.xml.namespace.QName;
+ import javax.xml.stream.XMLEventReader;
+ import javax.xml.stream.XMLInputFactory;
+ import javax.xml.stream.XMLStreamException;
+ import javax.xml.stream.events.Attribute;
+ import javax.xml.stream.events.StartElement;
+ import javax.xml.stream.events.XMLEvent;
+ import org.apache.olingo.commons.api.Constants;
+ import org.apache.olingo.commons.api.domain.ODataOperation;
+ import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+ import org.apache.olingo.commons.api.format.ContentType;
+ import org.apache.olingo.commons.core.data.v3.XMLLinkCollectionImpl;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+
+ public class AtomDeserializer extends AbstractAtomDealer {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AtomDeserializer.class);
+
+ private static final XMLInputFactory FACTORY = XMLInputFactory.newInstance();
+
+ private final AtomPropertyDeserializer propDeserializer;
+
+ public AtomDeserializer(final ODataServiceVersion version) {
+ super(version);
+ this.propDeserializer = new AtomPropertyDeserializer(version);
+ }
+
+ private AtomPropertyImpl property(final InputStream input) throws XMLStreamException {
+ final XMLEventReader reader = FACTORY.createXMLEventReader(input);
+ return propDeserializer.deserialize(reader, skipBeforeFirstStartElement(reader));
+ }
+
+ private StartElement skipBeforeFirstStartElement(final XMLEventReader reader) throws XMLStreamException {
+ StartElement startEvent = null;
+ while (reader.hasNext() && startEvent == null) {
+ final XMLEvent event = reader.nextEvent();
+ if (event.isStartElement()) {
+ startEvent = event.asStartElement();
+ }
+ }
+ if (startEvent == null) {
+ throw new IllegalArgumentException("Cannot find any XML start element");
+ }
+
+ return startEvent;
+ }
+
+ private void common(final XMLEventReader reader, final StartElement start,
+ final AbstractAtomObject object, final String key) throws XMLStreamException {
+
+ boolean foundEndElement = false;
+ while (reader.hasNext() && !foundEndElement) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.isCharacters() && !event.asCharacters().isWhiteSpace()) {
+ try {
+ object.setCommonProperty(key, event.asCharacters().getData());
+ } catch (ParseException e) {
+ throw new XMLStreamException("While parsing Atom entry or feed common elements", e);
+ }
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndElement = true;
+ }
+ }
+ }
+
+ private void inline(final XMLEventReader reader, final StartElement start, final LinkImpl link)
+ throws XMLStreamException {
+
+ boolean foundEndElement = false;
+ while (reader.hasNext() && !foundEndElement) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.isStartElement() && inlineQName.equals(event.asStartElement().getName())) {
+ StartElement inline = null;
+ while (reader.hasNext() && inline == null) {
+ final XMLEvent innerEvent = reader.peek();
+ if (innerEvent.isCharacters() && innerEvent.asCharacters().isWhiteSpace()) {
+ reader.nextEvent();
+ } else if (innerEvent.isStartElement()) {
+ inline = innerEvent.asStartElement();
+ }
+ }
+ if (inline != null) {
+ if (Constants.QNAME_ATOM_ELEM_ENTRY.equals(inline.getName())) {
+ link.setInlineEntry(entry(reader, inline));
+ }
+ if (Constants.QNAME_ATOM_ELEM_FEED.equals(inline.getName())) {
+ link.setInlineFeed(feed(reader, inline));
+ }
+ }
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndElement = true;
+ }
+ }
+ }
+
+ private XMLLinkCollectionImpl linkCollection(final InputStream input) throws XMLStreamException {
+ final XMLEventReader reader = FACTORY.createXMLEventReader(input);
+
+ final XMLLinkCollectionImpl linkCollection = new XMLLinkCollectionImpl();
+
+ boolean isURI = false;
+ boolean isNext = false;
+ while (reader.hasNext()) {
+ final XMLEvent event = reader.nextEvent();
+ if (event.isStartElement()) {
+ isURI = uriQName.equals(event.asStartElement().getName());
+ isNext = nextQName.equals(event.asStartElement().getName());
+ }
+
+ if (event.isCharacters() && !event.asCharacters().isWhiteSpace()) {
+ if (isURI) {
+ linkCollection.getLinks().add(URI.create(event.asCharacters().getData()));
+ isURI = false;
+ } else if (isNext) {
+ linkCollection.setNext(URI.create(event.asCharacters().getData()));
+ isNext = false;
+ }
+ }
+ }
+
+ return linkCollection;
+ }
+
+ private void properties(final XMLEventReader reader, final StartElement start, final AtomEntryImpl entry)
+ throws XMLStreamException {
-
+ boolean foundEndProperties = false;
+ while (reader.hasNext() && !foundEndProperties) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.isStartElement()) {
+ entry.getProperties().add(propDeserializer.deserialize(reader, event.asStartElement()));
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndProperties = true;
+ }
+ }
+ }
+
+ private AtomEntryImpl entry(final XMLEventReader reader, final StartElement start) throws XMLStreamException {
+ if (!Constants.QNAME_ATOM_ELEM_ENTRY.equals(start.getName())) {
+ return null;
+ }
+
+ final AtomEntryImpl entry = new AtomEntryImpl();
+ final Attribute xmlBase = start.getAttributeByName(Constants.QNAME_ATTR_XML_BASE);
+ if (xmlBase != null) {
+ entry.setBaseURI(xmlBase.getValue());
+ }
+ final Attribute etag = start.getAttributeByName(etagQName);
+ if (etag != null) {
+ entry.setETag(etag.getValue());
+ }
+
+ boolean foundEndEntry = false;
+ while (reader.hasNext() && !foundEndEntry) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.isStartElement()) {
+ if (Constants.QNAME_ATOM_ELEM_ID.equals(event.asStartElement().getName())) {
+ common(reader, event.asStartElement(), entry, "id");
+ } else if (Constants.QNAME_ATOM_ELEM_TITLE.equals(event.asStartElement().getName())) {
+ common(reader, event.asStartElement(), entry, "title");
+ } else if (Constants.QNAME_ATOM_ELEM_SUMMARY.equals(event.asStartElement().getName())) {
+ common(reader, event.asStartElement(), entry, "summary");
+ } else if (Constants.QNAME_ATOM_ELEM_UPDATED.equals(event.asStartElement().getName())) {
+ common(reader, event.asStartElement(), entry, "updated");
+ } else if (Constants.QNAME_ATOM_ELEM_CATEGORY.equals(event.asStartElement().getName())) {
+ final Attribute term = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATOM_ATTR_TERM));
+ if (term != null) {
+ entry.setType(term.getValue());
+ }
+ } else if (Constants.QNAME_ATOM_ELEM_LINK.equals(event.asStartElement().getName())) {
+ final LinkImpl link = new LinkImpl();
+ final Attribute rel = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_REL));
+ if (rel != null) {
+ link.setRel(rel.getValue());
+ }
+ final Attribute title = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TITLE));
+ if (title != null) {
+ link.setTitle(title.getValue());
+ }
+ final Attribute href = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_HREF));
+ if (href != null) {
+ link.setHref(href.getValue());
+ }
+ final Attribute type = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TYPE));
+ if (type != null) {
+ link.setType(type.getValue());
+ }
+
+ if (Constants.SELF_LINK_REL.equals(link.getRel())) {
+ entry.setSelfLink(link);
+ } else if (Constants.EDIT_LINK_REL.equals(link.getRel())) {
+ entry.setEditLink(link);
+ } else if (link.getRel().startsWith(version.getNamespaceMap().get(ODataServiceVersion.NAVIGATION_LINK_REL))) {
+ entry.getNavigationLinks().add(link);
+ inline(reader, event.asStartElement(), link);
+ } else if (link.getRel().startsWith(
+ version.getNamespaceMap().get(ODataServiceVersion.ASSOCIATION_LINK_REL))) {
+
+ entry.getAssociationLinks().add(link);
+ } else if (link.getRel().startsWith(
+ version.getNamespaceMap().get(ODataServiceVersion.MEDIA_EDIT_LINK_REL))) {
+
+ final Attribute metag = event.asStartElement().getAttributeByName(etagQName);
+ if (metag != null) {
+ link.setMediaETag(metag.getValue());
+ }
+ entry.getMediaEditLinks().add(link);
+ }
+ } else if (actionQName.equals(event.asStartElement().getName())) {
+ final ODataOperation operation = new ODataOperation();
+ final Attribute metadata = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_METADATA));
+ if (metadata != null) {
+ operation.setMetadataAnchor(metadata.getValue());
+ }
+ final Attribute title = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TITLE));
+ if (title != null) {
+ operation.setTitle(title.getValue());
+ }
+ final Attribute target = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TARGET));
+ if (target != null) {
+ operation.setTarget(URI.create(target.getValue()));
+ }
+
+ entry.getOperations().add(operation);
+ } else if (Constants.QNAME_ATOM_ELEM_CONTENT.equals(event.asStartElement().getName())) {
+ final Attribute type = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TYPE));
+ if (type == null || ContentType.APPLICATION_XML.equals(type.getValue())) {
+ properties(reader, skipBeforeFirstStartElement(reader), entry);
+ } else {
+ entry.setMediaContentType(type.getValue());
+ final Attribute src = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATOM_ATTR_SRC));
+ if (src != null) {
+ entry.setMediaContentSource(src.getValue());
+ }
+ }
+ } else if (propertiesQName.equals(event.asStartElement().getName())) {
+ properties(reader, event.asStartElement(), entry);
+ }
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndEntry = true;
+ }
+ }
+
+ return entry;
+ }
+
+ private AtomEntryImpl entry(final InputStream input) throws XMLStreamException {
+ final XMLEventReader reader = FACTORY.createXMLEventReader(input);
+ return entry(reader, skipBeforeFirstStartElement(reader));
+ }
+
+ private void count(final XMLEventReader reader, final StartElement start, final AtomFeedImpl feed)
+ throws XMLStreamException {
+
+ boolean foundEndElement = false;
+ while (reader.hasNext() && !foundEndElement) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.isCharacters() && !event.asCharacters().isWhiteSpace()) {
+ feed.setCount(Integer.valueOf(event.asCharacters().getData()));
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndElement = true;
+ }
+ }
+ }
+
+ private AtomFeedImpl feed(final XMLEventReader reader, final StartElement start) throws XMLStreamException {
+ if (!Constants.QNAME_ATOM_ELEM_FEED.equals(start.getName())) {
+ return null;
+ }
+
+ final AtomFeedImpl feed = new AtomFeedImpl();
+ final Attribute xmlBase = start.getAttributeByName(Constants.QNAME_ATTR_XML_BASE);
+ if (xmlBase != null) {
+ feed.setBaseURI(xmlBase.getValue());
+ }
+
+ boolean foundEndFeed = false;
+ while (reader.hasNext() && !foundEndFeed) {
+ final XMLEvent event = reader.nextEvent();
-
+ if (event.isStartElement()) {
+ if (countQName.equals(event.asStartElement().getName())) {
+ count(reader, event.asStartElement(), feed);
+ } else if (Constants.QNAME_ATOM_ELEM_ID.equals(event.asStartElement().getName())) {
+ common(reader, event.asStartElement(), feed, "id");
+ } else if (Constants.QNAME_ATOM_ELEM_TITLE.equals(event.asStartElement().getName())) {
+ common(reader, event.asStartElement(), feed, "title");
+ } else if (Constants.QNAME_ATOM_ELEM_SUMMARY.equals(event.asStartElement().getName())) {
+ common(reader, event.asStartElement(), feed, "summary");
+ } else if (Constants.QNAME_ATOM_ELEM_UPDATED.equals(event.asStartElement().getName())) {
+ common(reader, event.asStartElement(), feed, "updated");
+ } else if (Constants.QNAME_ATOM_ELEM_LINK.equals(event.asStartElement().getName())) {
+ final Attribute rel = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_REL));
+ if (rel != null && Constants.NEXT_LINK_REL.equals(rel.getValue())) {
+ final Attribute href = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_HREF));
+ if (href != null) {
+ feed.setNext(URI.create(href.getValue()));
+ }
+ }
+ } else if (Constants.QNAME_ATOM_ELEM_ENTRY.equals(event.asStartElement().getName())) {
+ feed.getEntries().add(entry(reader, event.asStartElement()));
+ }
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndFeed = true;
+ }
+ }
+
+ return feed;
+ }
+
+ private AtomFeedImpl feed(final InputStream input) throws XMLStreamException {
+ final XMLEventReader reader = FACTORY.createXMLEventReader(input);
+ return feed(reader, skipBeforeFirstStartElement(reader));
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> T read(final InputStream input, final Class<T> reference) throws XMLStreamException {
+ if (AtomFeedImpl.class.equals(reference)) {
+ return (T) feed(input);
+ } else if (AtomEntryImpl.class.equals(reference)) {
+ return (T) entry(input);
+ } else if (AtomPropertyImpl.class.equals(reference)) {
+ return (T) property(input);
+ } else if (XMLLinkCollectionImpl.class.equals(reference)) {
+ return (T) linkCollection(input);
+ }
+ return null;
+ }
+ }
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomPropertyDeserializer.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomPropertyDeserializer.java
index 0000000,99231b4..91ad49a
mode 000000,100644..100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomPropertyDeserializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomPropertyDeserializer.java
@@@ -1,0 -1,214 +1,218 @@@
+ /*
+ * 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.core.data;
+
+ import javax.xml.stream.XMLEventReader;
+ import javax.xml.stream.XMLStreamException;
+ import javax.xml.stream.events.Attribute;
+ import javax.xml.stream.events.StartElement;
+ import javax.xml.stream.events.XMLEvent;
+ 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.Value;
+ import org.apache.olingo.commons.api.domain.ODataPropertyType;
+ 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;
+
+ class AtomPropertyDeserializer extends AbstractAtomDealer {
+
+ private final AtomGeoValueDeserializer geoDeserializer;
+
+ public AtomPropertyDeserializer(final ODataServiceVersion version) {
+ super(version);
+ this.geoDeserializer = new AtomGeoValueDeserializer();
+ }
+
+ private Value fromPrimitive(final XMLEventReader reader, final StartElement start,
+ final EdmTypeInfo typeInfo) throws XMLStreamException {
+
+ Value value = null;
+
+ boolean foundEndProperty = false;
+ while (reader.hasNext() && !foundEndProperty) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.isStartElement() && typeInfo != null && typeInfo.getPrimitiveTypeKind().isGeospatial()) {
+ final EdmPrimitiveTypeKind geoType = EdmPrimitiveTypeKind.valueOfFQN(
+ version, typeInfo.getFullQualifiedName().toString());
+ value = new GeospatialValueImpl(this.geoDeserializer.deserialize(reader, event.asStartElement(), geoType));
+ }
+
+ if (event.isCharacters() && !event.asCharacters().isWhiteSpace()
+ && (typeInfo == null || !typeInfo.getPrimitiveTypeKind().isGeospatial())) {
+
+ value = new PrimitiveValueImpl(event.asCharacters().getData());
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndProperty = true;
+ }
+ }
+
+ return value;
+ }
+
+ private ComplexValue fromComplex(final XMLEventReader reader, final StartElement start)
+ throws XMLStreamException {
+
+ final ComplexValue value = new ComplexValueImpl();
+
+ boolean foundEndProperty = false;
+ while (reader.hasNext() && !foundEndProperty) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.isStartElement()) {
+ value.get().add(deserialize(reader, event.asStartElement()));
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndProperty = true;
+ }
+ }
+
+ return value;
+ }
+
+ private CollectionValue fromCollection(final XMLEventReader reader, final StartElement start,
+ final EdmTypeInfo typeInfo) throws XMLStreamException {
+
+ final CollectionValueImpl value = new CollectionValueImpl();
+
+ final EdmTypeInfo type = typeInfo == null
+ ? null
+ : new EdmTypeInfo.Builder().setTypeExpression(typeInfo.getFullQualifiedName().toString()).build();
+
+ boolean foundEndProperty = false;
+ while (reader.hasNext() && !foundEndProperty) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.isStartElement()) {
+ switch (guessPropertyType(reader)) {
+ case COMPLEX:
+ value.get().add(fromComplex(reader, event.asStartElement()));
+ break;
+
+ case PRIMITIVE:
+ value.get().add(fromPrimitive(reader, event.asStartElement(), type));
+ break;
+
+ default:
+ // do not add null or empty values
+ }
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndProperty = true;
+ }
+ }
+
+ return value;
+ }
+
+ private ODataPropertyType guessPropertyType(final XMLEventReader reader) throws XMLStreamException {
+ XMLEvent child = null;
+ while (reader.hasNext() && child == null) {
+ final XMLEvent event = reader.peek();
+ if (event.isCharacters() && event.asCharacters().isWhiteSpace()) {
+ reader.nextEvent();
+ } else {
+ child = event;
+ }
+ }
+
- ODataPropertyType type = null;
++ final ODataPropertyType type;
+ if (child == null) {
+ type = ODataPropertyType.PRIMITIVE;
+ } else {
+ if (child.isStartElement()) {
+ if (Constants.NS_GML.equals(child.asStartElement().getName().getNamespaceURI())) {
+ type = ODataPropertyType.PRIMITIVE;
+ } else if (elementQName.equals(child.asStartElement().getName())) {
+ type = ODataPropertyType.COLLECTION;
+ } else {
+ type = ODataPropertyType.COMPLEX;
+ }
+ } else if (child.isCharacters()) {
+ type = ODataPropertyType.PRIMITIVE;
+ } else {
+ type = ODataPropertyType.EMPTY;
+ }
+ }
+
+ return type;
+ }
+
+ public AtomPropertyImpl deserialize(final XMLEventReader reader, final StartElement start)
+ throws XMLStreamException {
+
+ final AtomPropertyImpl property = new AtomPropertyImpl();
+ property.setName(start.getName().getLocalPart());
+
+ final Attribute typeAttr = start.getAttributeByName(this.typeQName);
- if (typeAttr != null) {
- property.setType(typeAttr.getValue());
- }
+
+ Value value;
+ final Attribute nullAttr = start.getAttributeByName(this.nullQName);
++ final String typeAttrValue = typeAttr == null ? null : typeAttr.getValue();
++
+ if (nullAttr == null) {
- final EdmTypeInfo typeInfo = StringUtils.isBlank(property.getType())
++ final EdmTypeInfo typeInfo = StringUtils.isBlank(typeAttrValue)
+ ? null
- : new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build();
++ : new EdmTypeInfo.Builder().setTypeExpression(typeAttrValue).build();
++
++ if (typeInfo != null) {
++ property.setType(typeInfo.getTypeExpression());
++ }
+
+ final ODataPropertyType propType = typeInfo == null
+ ? guessPropertyType(reader)
+ : typeInfo.isCollection()
+ ? ODataPropertyType.COLLECTION
+ : typeInfo.isPrimitiveType()
+ ? ODataPropertyType.PRIMITIVE
+ : ODataPropertyType.COMPLEX;
+
+ switch (propType) {
+ case COLLECTION:
+ value = fromCollection(reader, start, typeInfo);
+ break;
+
+ case COMPLEX:
+ value = fromComplex(reader, start);
+ break;
+
+ case PRIMITIVE:
+ value = fromPrimitive(reader, start, typeInfo);
+ break;
+
+ case EMPTY:
+ default:
+ value = new PrimitiveValueImpl(StringUtils.EMPTY);
+ }
+ } else {
+ value = new NullValueImpl();
+ }
++
+ property.setValue(value);
+
+ return property;
+ }
+ }
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONGeoValueDeserializer.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONGeoValueDeserializer.java
index 0000000,f1863a7..c544f73
mode 000000,100644..100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONGeoValueDeserializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONGeoValueDeserializer.java
@@@ -1,0 -1,274 +1,273 @@@
+ /*
+ * 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.core.data;
+
+ import com.fasterxml.jackson.databind.JsonNode;
+ import java.util.ArrayList;
+ import java.util.Collections;
+ import java.util.Iterator;
+ import java.util.List;
+ import org.apache.olingo.commons.api.Constants;
+ import org.apache.olingo.commons.api.data.GeoUtils;
+ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+ import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+ import org.apache.olingo.commons.api.edm.geo.Geospatial;
+ import org.apache.olingo.commons.api.edm.geo.GeospatialCollection;
+ import org.apache.olingo.commons.api.edm.geo.LineString;
+ import org.apache.olingo.commons.api.edm.geo.MultiLineString;
+ import org.apache.olingo.commons.api.edm.geo.MultiPoint;
+ import org.apache.olingo.commons.api.edm.geo.MultiPolygon;
+ import org.apache.olingo.commons.api.edm.geo.Point;
+ import org.apache.olingo.commons.api.edm.geo.Polygon;
+ import org.apache.olingo.commons.core.edm.EdmTypeInfo;
+ import org.apache.olingo.commons.core.edm.primitivetype.EdmDouble;
+
+ class JSONGeoValueDeserializer {
+
+ private final ODataServiceVersion version;
+
+ public JSONGeoValueDeserializer(final ODataServiceVersion version) {
+ this.version = version;
+ }
+
+ private Point point(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type, final String crs) {
+ Point point = null;
+
+ if (itor.hasNext()) {
+ point = new Point(GeoUtils.getDimension(type), crs);
+ try {
+ point.setX(EdmDouble.getInstance().valueOfString(itor.next().asText(), null, null,
+ Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, null, Double.class));
+ point.setY(EdmDouble.getInstance().valueOfString(itor.next().asText(), null, null,
+ Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, null, Double.class));
+ } catch (EdmPrimitiveTypeException e) {
+ throw new IllegalArgumentException("While deserializing point coordinates as double", e);
+ }
+ }
+
+ return point;
+ }
+
+ private MultiPoint multipoint(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
+ final String crs) {
+
- MultiPoint multiPoint = null;
++ final MultiPoint multiPoint;
+
+ if (itor.hasNext()) {
+ final List<Point> points = new ArrayList<Point>();
+ while (itor.hasNext()) {
+ final Iterator<JsonNode> mpItor = itor.next().elements();
+ points.add(point(mpItor, type, crs));
+ }
+ multiPoint = new MultiPoint(GeoUtils.getDimension(type), crs, points);
+ } else {
+ multiPoint = new MultiPoint(GeoUtils.getDimension(type), crs, Collections.<Point>emptyList());
+ }
+
+ return multiPoint;
+ }
+
+ private LineString lineString(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
+ final String crs) {
+
- LineString lineString = null;
++ final LineString lineString;
+
+ if (itor.hasNext()) {
+ final List<Point> points = new ArrayList<Point>();
+ while (itor.hasNext()) {
+ final Iterator<JsonNode> mpItor = itor.next().elements();
+ points.add(point(mpItor, type, crs));
+ }
+ lineString = new LineString(GeoUtils.getDimension(type), crs, points);
+ } else {
+ lineString = new LineString(GeoUtils.getDimension(type), crs, Collections.<Point>emptyList());
+ }
+
+ return lineString;
+ }
+
+ private MultiLineString multiLineString(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
+ final String crs) {
+
- MultiLineString multiLineString = null;
++ final MultiLineString multiLineString;
+
+ if (itor.hasNext()) {
+ final List<LineString> lineStrings = new ArrayList<LineString>();
+ while (itor.hasNext()) {
+ final Iterator<JsonNode> mlsItor = itor.next().elements();
+ lineStrings.add(lineString(mlsItor, type, crs));
+ }
+ multiLineString = new MultiLineString(GeoUtils.getDimension(type), crs, lineStrings);
+ } else {
+ multiLineString = new MultiLineString(GeoUtils.getDimension(type), crs, Collections.<LineString>emptyList());
+ }
+
+ return multiLineString;
+ }
+
+ private Polygon polygon(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
+ final String crs) {
+
+ List<Point> extPoints = null;
+ if (itor.hasNext()) {
+ final Iterator<JsonNode> extItor = itor.next().elements();
+ if (extItor.hasNext()) {
+ extPoints = new ArrayList<Point>();
+ while (extItor.hasNext()) {
+ final Iterator<JsonNode> mpItor = extItor.next().elements();
+ extPoints.add(point(mpItor, type, crs));
+ }
+ }
+ }
+
+ List<Point> intPoints = null;
+ if (itor.hasNext()) {
+ final Iterator<JsonNode> intItor = itor.next().elements();
+ if (intItor.hasNext()) {
+ intPoints = new ArrayList<Point>();
+ while (intItor.hasNext()) {
+ final Iterator<JsonNode> mpItor = intItor.next().elements();
+ intPoints.add(point(mpItor, type, crs));
+ }
+ }
+ }
+
+ return new Polygon(GeoUtils.getDimension(type), crs, intPoints, extPoints);
+ }
+
+ private MultiPolygon multiPolygon(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
+ final String crs) {
+
- MultiPolygon multiPolygon = null;
++ final MultiPolygon multiPolygon;
+
+ if (itor.hasNext()) {
+ final List<Polygon> polygons = new ArrayList<Polygon>();
+ while (itor.hasNext()) {
+ final Iterator<JsonNode> mpItor = itor.next().elements();
+ polygons.add(polygon(mpItor, type, crs));
+ }
+ multiPolygon = new MultiPolygon(GeoUtils.getDimension(type), crs, polygons);
+ } else {
+ multiPolygon = new MultiPolygon(GeoUtils.getDimension(type), crs, Collections.<Polygon>emptyList());
+ }
+
+ return multiPolygon;
+ }
+
+ private GeospatialCollection collection(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
+ final String crs) {
+
- GeospatialCollection collection = null;
++ final GeospatialCollection collection;
+
+ if (itor.hasNext()) {
+ final List<Geospatial> geospatials = new ArrayList<Geospatial>();
+
+ while (itor.hasNext()) {
+ final JsonNode geo = itor.next();
+ final String collItemType = geo.get(Constants.ATTR_TYPE).asText();
+ final String callAsType;
+ if (EdmPrimitiveTypeKind.GeographyCollection.name().equals(collItemType)
+ || EdmPrimitiveTypeKind.GeometryCollection.name().equals(collItemType)) {
+
+ callAsType = collItemType;
+ } else {
+ callAsType = (type == EdmPrimitiveTypeKind.GeographyCollection ? "Geography" : "Geometry")
+ + collItemType;
+ }
+
+ geospatials.add(deserialize(geo, new EdmTypeInfo.Builder().setTypeExpression(callAsType).build()));
+ }
+
+ collection = new GeospatialCollection(GeoUtils.getDimension(type), crs, geospatials);
+ } else {
+ collection = new GeospatialCollection(GeoUtils.getDimension(type), crs, Collections.<Geospatial>emptyList());
+ }
+
+ return collection;
+ }
+
+ public Geospatial deserialize(final JsonNode node, final EdmTypeInfo typeInfo) {
+ final EdmPrimitiveTypeKind actualType;
+ if ((typeInfo.getPrimitiveTypeKind() == EdmPrimitiveTypeKind.Geography
+ || typeInfo.getPrimitiveTypeKind() == EdmPrimitiveTypeKind.Geometry)
+ && node.has(Constants.ATTR_TYPE)) {
+
+ String nodeType = node.get(Constants.ATTR_TYPE).asText();
+ if (nodeType.startsWith("Geo")) {
+ final int yIdx = nodeType.indexOf('y');
+ nodeType = nodeType.substring(yIdx + 1);
+ }
+ actualType = EdmPrimitiveTypeKind.valueOfFQN(version, typeInfo.getFullQualifiedName().toString() + nodeType);
+ } else {
+ actualType = typeInfo.getPrimitiveTypeKind();
+ }
+
+ final Iterator<JsonNode> cooItor = node.has(Constants.JSON_COORDINATES)
+ ? node.get(Constants.JSON_COORDINATES).elements()
+ : Collections.<JsonNode>emptyList().iterator();
+
+ String crs = null;
+ if (node.has(Constants.JSON_CRS)) {
+ crs = node.get(Constants.JSON_CRS).get(Constants.PROPERTIES).get(Constants.JSON_NAME).asText().split(":")[1];
+ }
+
+ Geospatial value = null;
+ switch (actualType) {
+ case GeographyPoint:
+ case GeometryPoint:
+ value = point(cooItor, actualType, crs);
+ break;
+
+ case GeographyMultiPoint:
+ case GeometryMultiPoint:
+ value = multipoint(cooItor, actualType, crs);
+ break;
+
+ case GeographyLineString:
+ case GeometryLineString:
+ value = lineString(cooItor, actualType, crs);
+ break;
+
+ case GeographyMultiLineString:
+ case GeometryMultiLineString:
+ value = multiLineString(cooItor, actualType, crs);
+ break;
+
+ case GeographyPolygon:
+ case GeometryPolygon:
+ value = polygon(cooItor, actualType, crs);
+ break;
+
+ case GeographyMultiPolygon:
+ case GeometryMultiPolygon:
+ value = multiPolygon(cooItor, actualType, crs);
+ break;
+
+ case GeographyCollection:
+ case GeometryCollection:
+ value = collection(node.get(Constants.JSON_GEOMETRIES).elements(), actualType, crs);
+ break;
+
+ default:
+ }
+
+ return value;
+ }
-
+ }
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeInfo.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeInfo.java
index 0000000,567950d..09e70cb
mode 000000,100644..100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeInfo.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeInfo.java
@@@ -1,0 -1,172 +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.core.edm;
+
+ import org.apache.commons.lang3.StringUtils;
+ import org.apache.olingo.commons.api.edm.Edm;
+ import org.apache.olingo.commons.api.edm.EdmComplexType;
+ import org.apache.olingo.commons.api.edm.EdmEntityType;
+ import org.apache.olingo.commons.api.edm.EdmEnumType;
++import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
+ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+ import org.apache.olingo.commons.api.edm.FullQualifiedName;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+
+ public class EdmTypeInfo {
+
+ private static final Logger LOG = LoggerFactory.getLogger(EdmTypeInfo.class);
+
+ public static class Builder {
+
+ private String typeExpression;
+
+ private String defaultNamespace;
+
+ private Edm edm;
+
+ public Builder setTypeExpression(final String typeExpression) {
+ this.typeExpression = typeExpression;
+ return this;
+ }
+
+ public Builder setDefaultNamespace(final String defaultNamespace) {
+ this.defaultNamespace = defaultNamespace;
+ return this;
+ }
+
+ public Builder setEdm(final Edm edm) {
+ this.edm = edm;
+ return this;
+ }
+
+ public EdmTypeInfo build() {
- return new EdmTypeInfo(edm, typeExpression.indexOf('.') == -1
++ return new EdmTypeInfo(edm, typeExpression.indexOf('.') == -1 && StringUtils.isNotBlank(defaultNamespace)
+ ? defaultNamespace + "." + typeExpression
+ : typeExpression);
+ }
+ }
-
+ private final Edm edm;
+
+ private final String typeExpression;
+
+ private final boolean collection;
+
+ private final FullQualifiedName fullQualifiedName;
+
+ private EdmPrimitiveTypeKind primitiveType;
+
+ private EdmEnumType enumType;
+
+ private EdmComplexType complexType;
+
+ private EdmEntityType entityType;
+
+ private EdmTypeInfo(final Edm edm, final String typeExpression) {
+ this.edm = edm;
- this.typeExpression = typeExpression;
+
+ String baseType;
+ final int collStartIdx = typeExpression.indexOf("Collection(");
+ final int collEndIdx = typeExpression.lastIndexOf(')');
+ if (collStartIdx == -1) {
+ baseType = typeExpression;
+ this.collection = false;
+ } else {
+ if (collEndIdx == -1) {
+ throw new IllegalArgumentException("Malformed type: " + typeExpression);
+ }
+
+ this.collection = true;
+ baseType = typeExpression.substring(collStartIdx + 11, collEndIdx);
+ }
+
++
++ baseType = baseType.replaceAll("^#", "");
++
++ final String typeName;
++ final String namespace;
++
+ final int lastDotIdx = baseType.lastIndexOf('.');
+ if (lastDotIdx == -1) {
- throw new IllegalArgumentException("Cannot find namespace or alias in " + typeExpression);
++ namespace = EdmPrimitiveType.EDM_NAMESPACE;
++ typeName = baseType;
++ baseType = new FullQualifiedName(EdmPrimitiveType.EDM_NAMESPACE, baseType).toString();
++ } else {
++ namespace = baseType.substring(0, lastDotIdx);
++ typeName = baseType.substring(lastDotIdx + 1);
+ }
- final String namespace = baseType.substring(0, lastDotIdx);
- final String typeName = baseType.substring(lastDotIdx + 1);
++
+ if (StringUtils.isBlank(typeName)) {
+ throw new IllegalArgumentException("Null or empty type name in " + typeExpression);
+ }
+
++ final StringBuilder exp = new StringBuilder();
++ exp.append(baseType);
++
++ this.typeExpression = (this.collection ? exp.insert(0, "Collection(").append(")") : exp).toString();
+ this.fullQualifiedName = new FullQualifiedName(namespace, typeName);
+
+ try {
+ this.primitiveType = EdmPrimitiveTypeKind.valueOf(this.fullQualifiedName.getName());
+ } catch (IllegalArgumentException e) {
+ LOG.debug("{} does not appear to refer to an Edm primitive type", this.fullQualifiedName);
+ }
+ if (this.primitiveType == null && this.edm != null) {
+ this.enumType = this.edm.getEnumType(this.fullQualifiedName);
+ if (this.enumType == null) {
+ this.complexType = this.edm.getComplexType(this.fullQualifiedName);
+ if (this.complexType == null) {
+ this.entityType = this.edm.getEntityType(this.fullQualifiedName);
+ }
+ }
+ }
+ }
+
+ public String getTypeExpression() {
+ return typeExpression;
+ }
+
+ public boolean isCollection() {
+ return collection;
+ }
+
+ public FullQualifiedName getFullQualifiedName() {
+ return fullQualifiedName;
+ }
+
+ public boolean isPrimitiveType() {
+ return this.primitiveType != null;
+ }
+
+ public EdmPrimitiveTypeKind getPrimitiveTypeKind() {
+ return primitiveType;
+ }
+
+ public boolean isEnumType() {
+ return this.enumType != null;
+ }
+
+ public EdmEnumType getEnumType() {
+ return enumType;
+ }
+
+ public boolean isComplexType() {
+ return this.complexType != null;
+ }
+
+ public EdmComplexType getComplexType() {
+ return complexType;
+ }
+
+ public boolean isEntityType() {
+ return this.entityType != null;
+ }
+
+ public EdmEntityType getEntityType() {
+ return entityType;
+ }
-
+ }
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-core/src/main/java/org/apache/olingo/commons/core/op/AbstractODataDeserializer.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/op/AbstractODataDeserializer.java
index 0000000,94c43da..991e723
mode 000000,100644..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
@@@ -1,0 -1,107 +1,106 @@@
+ /*
+ * 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.core.op;
+
+ import java.io.InputStream;
+ import org.apache.olingo.commons.api.data.Entry;
+ import org.apache.olingo.commons.api.domain.ODataError;
+ import org.apache.olingo.commons.api.data.Feed;
+ import org.apache.olingo.commons.api.data.Property;
+ import org.apache.olingo.commons.api.format.ODataFormat;
+ 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.core.data.AtomEntryImpl;
+ import org.apache.olingo.commons.core.data.AtomFeedImpl;
+ import org.apache.olingo.commons.core.data.AtomPropertyImpl;
+ import org.apache.olingo.commons.core.data.JSONEntryImpl;
+ import org.apache.olingo.commons.core.data.JSONErrorBundle;
+ import org.apache.olingo.commons.core.data.JSONFeedImpl;
+ import org.apache.olingo.commons.core.data.JSONPropertyImpl;
+ import org.apache.olingo.commons.core.data.XMLErrorImpl;
+
+ public abstract class AbstractODataDeserializer extends AbstractJacksonTool implements CommonODataDeserializer {
+
+ private static final long serialVersionUID = -4244158979195609909L;
+
+ private final AtomDeserializer atomDeserializer;
+
+ public AbstractODataDeserializer(final ODataServiceVersion version) {
+ super(version);
+
+ this.atomDeserializer = new AtomDeserializer(version);
+ }
+
+ @Override
+ public Feed toFeed(final InputStream input, final ODataPubFormat format) {
+ return format == ODataPubFormat.ATOM
+ ? atom(input, AtomFeedImpl.class)
+ : json(input, JSONFeedImpl.class);
+ }
+
+ @Override
+ public Entry toEntry(final InputStream input, final ODataPubFormat format) {
+ return format == ODataPubFormat.ATOM
+ ? atom(input, AtomEntryImpl.class)
+ : json(input, JSONEntryImpl.class);
+ }
+
+ @Override
+ public Property toProperty(final InputStream input, final ODataFormat format) {
+ return format == ODataFormat.XML
+ ? atom(input, AtomPropertyImpl.class)
+ : json(input, JSONPropertyImpl.class);
+ }
+
+ @Override
+ public ODataError toError(final InputStream input, final boolean isXML) {
+ return isXML
+ ? xml(input, XMLErrorImpl.class)
+ : json(input, JSONErrorBundle.class).getError();
+ }
+
+ /*
+ * ------------------ Protected methods ------------------
+ */
+ protected <T> T xml(final InputStream input, final Class<T> reference) {
+ try {
+ return getXmlMapper().readValue(input, reference);
+ } catch (Exception e) {
+ throw new IllegalArgumentException("While deserializing " + reference.getName(), e);
+ }
+ }
+
+ protected <T> T atom(final InputStream input, final Class<T> reference) {
+ try {
+ return atomDeserializer.read(input, reference);
+ } catch (Exception e) {
+ throw new IllegalArgumentException("While deserializing " + reference.getName(), e);
+ }
+ }
+
+ protected <T> T json(final InputStream input, final Class<T> reference) {
+ try {
+ return getObjectMapper().readValue(input, reference);
+ } catch (Exception e) {
+ throw new IllegalArgumentException("While deserializing " + reference.getName(), e);
+ }
+ }
-
+ }
[4/8] [OLINGO-205,
OLINGO-200] provided atom v4 deserialization for entity type/set +
entity set request
Posted by fm...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java
deleted file mode 100644
index 79d2d8f..0000000
--- a/fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java
+++ /dev/null
@@ -1,503 +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;
-
-import static org.apache.olingo.fit.utils.Constants.*;
-
-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;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.util.AbstractMap.SimpleEntry;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.ws.rs.NotFoundException;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-
-public class JSONUtilities extends AbstractUtilities {
-
- public JSONUtilities(final ODataVersion version) throws Exception {
- super(version);
- }
-
- @Override
- protected Accept getDefaultFormat() {
- return Accept.JSON_FULLMETA;
- }
-
- @Override
- protected InputStream addLinks(
- final String entitySetName, final String entitykey, final InputStream is, final Set<String> links)
- throws Exception {
- final ObjectMapper mapper = new ObjectMapper();
- final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
- IOUtils.closeQuietly(is);
-
- for (String link : links) {
- srcNode.set(link + JSON_NAVIGATION_SUFFIX,
- new TextNode(Commons.getLinksURI(version, entitySetName, entitykey, link)));
- }
-
- return IOUtils.toInputStream(srcNode.toString());
- }
-
- @Override
- protected Set<String> retrieveAllLinkNames(InputStream is) throws Exception {
- final ObjectMapper mapper = new ObjectMapper();
- final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
- IOUtils.closeQuietly(is);
-
- final Set<String> links = new HashSet<String>();
-
- final Iterator<String> fieldIter = srcNode.fieldNames();
-
- while (fieldIter.hasNext()) {
- final String field = fieldIter.next();
-
- if (field.endsWith(JSON_NAVIGATION_BIND_SUFFIX)
- || field.endsWith(JSON_NAVIGATION_SUFFIX)
- || field.endsWith(JSON_MEDIA_SUFFIX)
- || field.endsWith(JSON_EDITLINK_NAME)) {
- if (field.indexOf('@') > 0) {
- links.add(field.substring(0, field.indexOf('@')));
- } else {
- links.add(field);
- }
- }
- }
-
- return links;
- }
-
- /**
- * {@inheritDoc }
- */
- @Override
- protected NavigationLinks retrieveNavigationInfo(
- final String entitySetName, final InputStream is)
- throws Exception {
- final ObjectMapper mapper = new ObjectMapper();
- final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
- IOUtils.closeQuietly(is);
-
- final NavigationLinks links = new NavigationLinks();
-
- final Iterator<Map.Entry<String, JsonNode>> fieldIter = srcNode.fields();
-
- while (fieldIter.hasNext()) {
- final Map.Entry<String, JsonNode> field = fieldIter.next();
- if (field.getKey().endsWith(JSON_NAVIGATION_BIND_SUFFIX)) {
- final String title = field.getKey().substring(0, field.getKey().indexOf('@'));
- final List<String> hrefs = new ArrayList<String>();
- if (field.getValue().isArray()) {
- for (JsonNode href : ((ArrayNode) field.getValue())) {
- final String uri = href.asText();
- hrefs.add(uri.substring(uri.lastIndexOf('/') + 1));
- }
- } else {
- final String uri = field.getValue().asText();
- hrefs.add(uri.substring(uri.lastIndexOf('/') + 1));
- }
-
- links.addLinks(title, hrefs);
- } else if (Commons.linkInfo.get(version).exists(entitySetName, field.getKey())) {
- links.addInlines(field.getKey(), IOUtils.toInputStream(field.getValue().toString()));
- }
- }
-
- return links;
- }
-
- /**
- * {@inheritDoc }
- */
- @Override
- protected InputStream normalizeLinks(
- final String entitySetName, final String entityKey, final InputStream is, final NavigationLinks links)
- throws Exception {
- final ObjectMapper mapper = new ObjectMapper();
- final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
-
- if (links != null) {
- for (String linkTitle : links.getLinkNames()) {
- // normalize link
- srcNode.remove(linkTitle + JSON_NAVIGATION_BIND_SUFFIX);
- srcNode.set(
- linkTitle + JSON_NAVIGATION_SUFFIX,
- new TextNode(String.format("%s(%s)/%s", entitySetName, entityKey, linkTitle)));
- }
-
- for (String linkTitle : links.getInlineNames()) {
- // normalize link if exist; declare a new one if missing
- srcNode.remove(linkTitle + JSON_NAVIGATION_BIND_SUFFIX);
- srcNode.set(
- linkTitle + JSON_NAVIGATION_SUFFIX,
- new TextNode(String.format("%s(%s)/%s", entitySetName, entityKey, linkTitle)));
-
- // remove inline
- srcNode.remove(linkTitle);
-
- // remove from links
- links.removeLink(linkTitle);
- }
- }
-
- srcNode.set(
- JSON_EDITLINK_NAME,
- new TextNode(Constants.DEFAULT_SERVICE_URL + entitySetName + "(" + entityKey + ")"));
-
- return IOUtils.toInputStream(srcNode.toString());
- }
-
- @Override
- public InputStream getPropertyValue(final InputStream src, final List<String> path)
- throws Exception {
- final ObjectMapper mapper = new ObjectMapper();
- final JsonNode srcNode = mapper.readTree(src);
- JsonNode node = getProperty(srcNode, path);
- return IOUtils.toInputStream(node.asText());
- }
-
- @Override
- public InputStream getProperty(
- final String entitySetName, final String entityId, final List<String> path, final String edmType)
- throws Exception {
-
- final InputStream src =
- fsManager.readFile(Commons.getEntityBasePath(entitySetName, entityId) + ENTITY, Accept.JSON_FULLMETA);
-
- final ObjectMapper mapper = new ObjectMapper();
- final JsonNode srcNode = mapper.readTree(src);
-
- final ObjectNode propertyNode = new ObjectNode(JsonNodeFactory.instance);
-
- if (StringUtils.isNotBlank(edmType)) {
- propertyNode.put(JSON_ODATAMETADATA_NAME, 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<String> 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 ObjectMapper mapper = new ObjectMapper();
- final JsonNode srcNode = mapper.readTree(src);
-
- ((ObjectNode) srcNode).put(ODATA_COUNT_NAME, count);
-
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- mapper.writeValue(bos, srcNode);
-
- final InputStream res = new ByteArrayInputStream(bos.toByteArray());
- IOUtils.closeQuietly(bos);
-
- return res;
- }
-
- public InputStream wrapJsonEntities(final InputStream entities) throws Exception {
- final ObjectMapper mapper = new ObjectMapper();
- final JsonNode node = mapper.readTree(entities);
-
- final ObjectNode res;
-
- final JsonNode value = node.get(JSON_VALUE_NAME);
-
- if (value.isArray()) {
- res = mapper.createObjectNode();
- res.set("value", value);
- final JsonNode next = node.get(JSON_NEXTLINK_NAME);
- if (next != null) {
- res.set(JSON_NEXTLINK_NAME, next);
- }
- } else {
- res = (ObjectNode) value;
- }
-
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- mapper.writeValue(bos, res);
-
- final InputStream is = new ByteArrayInputStream(bos.toByteArray());
- IOUtils.closeQuietly(bos);
-
- return is;
- }
-
- @Override
- public InputStream selectEntity(final InputStream src, final String[] propertyNames) throws Exception {
- final ObjectMapper mapper = new ObjectMapper();
- final ObjectNode srcNode = (ObjectNode) mapper.readTree(src);
-
- final Set<String> retain = new HashSet<String>();
- retain.add(JSON_ID_NAME);
- retain.add(JSON_TYPE_NAME);
- retain.add(JSON_EDITLINK_NAME);
- retain.add(JSON_NEXTLINK_NAME);
- retain.add(JSON_ODATAMETADATA_NAME);
- retain.add(JSON_VALUE_NAME);
-
- for (String name : propertyNames) {
- retain.add(name);
- retain.add(name + JSON_NAVIGATION_SUFFIX);
- retain.add(name + JSON_MEDIA_SUFFIX);
- retain.add(name + JSON_TYPE_SUFFIX);
- }
-
- srcNode.retain(retain);
-
- return IOUtils.toInputStream(srcNode.toString());
- }
-
- @Override
- public InputStream readEntities(
- final List<String> links, final String linkName, final String next, final boolean forceFeed)
- throws Exception {
-
- if (links.isEmpty()) {
- throw new NotFoundException();
- }
-
- final ObjectMapper mapper = new ObjectMapper();
- final ObjectNode node = mapper.createObjectNode();
-
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-
- if (forceFeed || links.size() > 1) {
- bos.write("[".getBytes());
- }
-
- for (String link : links) {
- try {
- final Map.Entry<String, String> uri = Commons.parseEntityURI(link);
- final Map.Entry<String, InputStream> entity =
- readEntity(uri.getKey(), uri.getValue(), Accept.JSON_FULLMETA);
-
- if (bos.size() > 1) {
- bos.write(",".getBytes());
- }
-
- IOUtils.copy(entity.getValue(), bos);
- } catch (Exception e) {
- // log and ignore link
- LOG.warn("Error parsing uri {}", link, e);
- }
- }
-
- if (forceFeed || links.size() > 1) {
- bos.write("]".getBytes());
- }
-
- node.set(JSON_VALUE_NAME, mapper.readTree(new ByteArrayInputStream(bos.toByteArray())));
-
- if (StringUtils.isNotBlank(next)) {
- node.set(JSON_NEXTLINK_NAME, new TextNode(next));
- }
-
- return IOUtils.toInputStream(node.toString());
- }
-
- @Override
- protected InputStream replaceLink(
- final InputStream toBeChanged, final String linkName, final InputStream replacement)
- throws Exception {
- final ObjectMapper mapper = new ObjectMapper();
-
- final ObjectNode toBeChangedNode = (ObjectNode) mapper.readTree(toBeChanged);
- final ObjectNode replacementNode = (ObjectNode) mapper.readTree(replacement);
-
- if (toBeChangedNode.get(linkName + JSON_NAVIGATION_SUFFIX) == null) {
- throw new NotFoundException();
- }
-
- toBeChangedNode.set(linkName, replacementNode.get(JSON_VALUE_NAME));
-
- final JsonNode next = replacementNode.get(linkName + JSON_NEXTLINK_NAME);
- if (next != null) {
- toBeChangedNode.set(linkName + JSON_NEXTLINK_SUFFIX, next);
- }
-
- return IOUtils.toInputStream(toBeChangedNode.toString());
- }
-
- @Override
- protected Map<String, InputStream> getChanges(final InputStream src) throws Exception {
- final Map<String, InputStream> res = new HashMap<String, InputStream>();
-
- final ObjectMapper mapper = new ObjectMapper();
- final JsonNode srcObject = mapper.readTree(src);
-
- final Iterator<Map.Entry<String, JsonNode>> fields = srcObject.fields();
- while (fields.hasNext()) {
- final Map.Entry<String, JsonNode> field = fields.next();
- res.put(field.getKey(), IOUtils.toInputStream(field.getValue().toString()));
- }
-
- return res;
- }
-
- @Override
- protected InputStream setChanges(
- final InputStream toBeChanged, final Map<String, InputStream> properties) throws Exception {
-
- final ObjectMapper mapper = new ObjectMapper();
- final ObjectNode toBeChangedObject = (ObjectNode) mapper.readTree(toBeChanged);
-
- for (Map.Entry<String, InputStream> property : properties.entrySet()) {
- final JsonNode propertyNode = mapper.readTree(property.getValue());
- toBeChangedObject.set(property.getKey(), propertyNode);
- }
-
- return IOUtils.toInputStream(toBeChangedObject.toString());
- }
-
- @Override
- public Map.Entry<String, List<String>> extractLinkURIs(
- final String entitySetName, final String entityId, final String linkName)
- throws Exception {
- final LinkInfo links = readLinks(entitySetName, entityId, linkName, Accept.JSON_FULLMETA);
- return extractLinkURIs(links.getLinks());
- }
-
- @Override
- public Map.Entry<String, List<String>> extractLinkURIs(final InputStream is)
- throws Exception {
- final ObjectMapper mapper = new ObjectMapper();
- final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
- IOUtils.closeQuietly(is);
-
- final List<String> links = new ArrayList<String>();
-
- JsonNode uris = srcNode.get("value");
- if (uris == null) {
- final JsonNode url = srcNode.get("url");
- if (url != null) {
- links.add(url.textValue());
- }
- } else {
- final Iterator<JsonNode> iter = ((ArrayNode) uris).iterator();
- while (iter.hasNext()) {
- links.add(iter.next().get("url").textValue());
- }
- }
-
- final JsonNode next = srcNode.get(JSON_NEXTLINK_NAME);
-
- return new SimpleEntry<String, List<String>>(next == null ? null : next.asText(), links);
- }
-
- @Override
- public InputStream addEditLink(
- final InputStream content, final String title, final String href) throws Exception {
- final ObjectMapper mapper = new ObjectMapper();
- final ObjectNode srcNode = (ObjectNode) mapper.readTree(content);
- IOUtils.closeQuietly(content);
-
- srcNode.set(JSON_EDITLINK_NAME, new TextNode(href));
- return IOUtils.toInputStream(srcNode.toString());
- }
-
- @Override
- public InputStream replaceProperty(
- final InputStream src, final InputStream replacement, final List<String> path, final boolean justValue)
- throws Exception {
- final ObjectMapper mapper = new ObjectMapper();
- final ObjectNode srcNode = (ObjectNode) mapper.readTree(src);
- IOUtils.closeQuietly(src);
-
- final JsonNode replacementNode;
- if (justValue) {
- replacementNode = new TextNode(IOUtils.toString(replacement));
- } else {
- replacementNode = (ObjectNode) mapper.readTree(replacement);
- }
- IOUtils.closeQuietly(replacement);
-
- JsonNode node = srcNode;
- for (int i = 0; i < path.size() - 1; i++) {
- node = node.get(path.get(i));
- if (node == null) {
- throw new NotFoundException();
- }
- }
-
- ((ObjectNode) node).set(path.get(path.size() - 1), replacementNode);
-
- return IOUtils.toInputStream(srcNode.toString());
- }
-
- @Override
- public InputStream deleteProperty(final InputStream src, final List<String> path) throws Exception {
- final ObjectMapper mapper = new ObjectMapper();
- final ObjectNode srcNode = (ObjectNode) mapper.readTree(src);
- IOUtils.closeQuietly(src);
-
- JsonNode node = srcNode;
- for (int i = 0; i < path.size() - 1; i++) {
- node = node.get(path.get(i));
- if (node == null) {
- throw new NotFoundException();
- }
- }
-
- ((ObjectNode) node).set(path.get(path.size() - 1), null);
-
- return IOUtils.toInputStream(srcNode.toString());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java
deleted file mode 100644
index 0009eea..0000000
--- a/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java
+++ /dev/null
@@ -1,1388 +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;
-
-import static org.apache.olingo.fit.utils.Constants.*;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.StringWriter;
-import java.util.AbstractMap;
-import java.util.AbstractMap.SimpleEntry;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.ws.rs.NotFoundException;
-import javax.xml.namespace.QName;
-import javax.xml.stream.XMLEventFactory;
-import javax.xml.stream.XMLEventReader;
-import javax.xml.stream.XMLEventWriter;
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamConstants;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.events.Attribute;
-import javax.xml.stream.events.StartElement;
-import javax.xml.stream.events.XMLEvent;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.vfs2.FileObject;
-import org.apache.commons.vfs2.FileSystemException;
-
-public class XMLUtilities extends AbstractUtilities {
-
- protected static XMLInputFactory ifactory = null;
-
- protected static XMLOutputFactory ofactory = null;
-
- public XMLUtilities(final ODataVersion version) throws Exception {
- super(version);
- }
-
- public void retrieveLinkInfoFromMetadata() throws Exception {
-
- final MetadataLinkInfo metadataLinkInfo = new MetadataLinkInfo();
- Commons.linkInfo.put(version, metadataLinkInfo);
-
- final InputStream metadata = fsManager.readFile(Constants.METADATA, Accept.XML);
- final XMLEventReader reader = getEventReader(metadata);
-
- int initialDepth = 0;
- try {
- while (true) {
- Map.Entry<Integer, XmlElement> entityType =
- extractElement(reader, null, Collections.<String>singletonList("EntityType"),
- null, false, initialDepth, 4, 4);
- initialDepth = entityType.getKey();
-
- final String entitySetName =
- entityType.getValue().getStart().getAttributeByName(new QName("Name")).getValue();
-
- final XMLEventReader entityReader = getEventReader(entityType.getValue().toStream());
- int size = 0;
-
- try {
- while (true) {
- final XmlElement navProperty =
- extractElement(entityReader, null, Collections.<String>singletonList("NavigationProperty"),
- null, false, 0, -1, -1).getValue();
-
- final String linkName = navProperty.getStart().getAttributeByName(new QName("Name")).getValue();
- final Map.Entry<String, Boolean> target = getTargetInfo(navProperty.getStart(), linkName);
-
- metadataLinkInfo.addLink(
- entitySetName,
- linkName,
- target.getKey(),
- target.getValue());
-
- size++;
- }
- } catch (Exception e) {
- } finally {
- entityReader.close();
- }
-
- if (size == 0) {
- metadataLinkInfo.addEntitySet(entitySetName);
- }
- }
- } catch (Exception e) {
- } finally {
- reader.close();
- }
- }
-
- private Map.Entry<String, Boolean> getTargetInfo(final StartElement element, final String linkName)
- throws Exception {
- final InputStream metadata = fsManager.readFile(Constants.METADATA, Accept.XML);
- XMLEventReader reader = getEventReader(metadata);
-
- final String associationName = element.getAttributeByName(new QName("Relationship")).getValue();
-
- final Map.Entry<Integer, XmlElement> association = extractElement(
- reader, null, Collections.<String>singletonList("Association"),
- Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>(
- "Name", associationName.substring(associationName.lastIndexOf(".") + 1))), false,
- 0, 4, 4);
-
- reader.close();
- IOUtils.closeQuietly(metadata);
-
- final InputStream associationContent = association.getValue().toStream();
- reader = getEventReader(associationContent);
-
- final Map.Entry<Integer, XmlElement> associationEnd = extractElement(
- reader, null, Collections.<String>singletonList("End"),
- Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>("Role", linkName)),
- false, 0, -1, -1);
-
- reader.close();
- IOUtils.closeQuietly(associationContent);
-
- final String target = associationEnd.getValue().getStart().getAttributeByName(new QName("Type")).getValue();
- final boolean feed = associationEnd.getValue().getStart().getAttributeByName(
- new QName("Multiplicity")).getValue().equals("*");
-
- return new SimpleEntry<String, Boolean>(target, feed);
- }
-
- @Override
- protected Accept getDefaultFormat() {
- return Accept.ATOM;
- }
-
- protected XMLEventReader getEventReader(final InputStream is) throws XMLStreamException {
- if (ifactory == null) {
- ifactory = XMLInputFactory.newInstance();
- }
- ifactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, false);
- return ifactory.createXMLEventReader(is);
- }
-
- protected static XMLEventWriter getEventWriter(final OutputStream os) throws XMLStreamException {
- if (ofactory == null) {
- ofactory = XMLOutputFactory.newInstance();
- }
-
- return ofactory.createXMLEventWriter(os);
- }
-
- private void writeEvent(final XMLEvent event, final XMLEventWriter writer) {
- if (writer != null) {
- try {
- writer.add(event);
- } catch (XMLStreamException e) {
- LOG.error("Error writing event {}", event, e);
- }
- }
- }
-
- private void skipElement(
- final StartElement start,
- final XMLEventReader reader,
- final XMLEventWriter writer,
- final boolean excludeStart)
- throws Exception {
-
- if (!excludeStart) {
- writeEvent(start, writer);
- }
-
- int depth = 1;
- boolean found = false;
-
- while (reader.hasNext() && !found) {
- final XMLEvent event = reader.nextEvent();
-
- writeEvent(event, writer);
-
- if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
- depth++;
- } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT) {
- depth--;
- found = depth == 0 && start.getName().equals(event.asEndElement().getName());
- }
- }
- }
-
- /**
- * {@inheritDoc }
- */
- @Override
- protected InputStream addLinks(
- final String entitySetName, final String entitykey, final InputStream is, final Set<String> links)
- throws Exception {
-
- // -----------------------------------------
- // 0. Build reader and writer
- // -----------------------------------------
- final XMLEventReader reader = getEventReader(is);
- final XMLEventFactory eventFactory = XMLEventFactory.newInstance();
-
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- final XMLEventWriter writer = getEventWriter(bos);
- // -----------------------------------------
- final Map.Entry<Integer, XmlElement> entry =
- extractElement(reader, writer, Collections.singletonList("entry"), 0, 1, 1);
-
- writer.add(entry.getValue().getStart());
-
- // add for links
- for (String link : links) {
- final Set<Attribute> attributes = new HashSet<Attribute>();
- attributes.add(eventFactory.createAttribute(new QName("title"), link));
- attributes.add(eventFactory.createAttribute(new QName("href"),
- Commons.getLinksURI(version, entitySetName, entitykey, link)));
- attributes.add(eventFactory.createAttribute(new QName("rel"), Constants.ATOM_LINK_REL + link));
- attributes.add(eventFactory.createAttribute(new QName("type"),
- Commons.linkInfo.get(version).isFeed(entitySetName, link) ? Constants.ATOM_LINK_FEED
- : Constants.ATOM_LINK_ENTRY));
-
- writer.add(eventFactory.createStartElement(new QName(LINK), attributes.iterator(), null));
- writer.add(eventFactory.createEndElement(new QName(LINK), null));
- }
-
- writer.add(entry.getValue().getContentReader());
- writer.add(entry.getValue().getEnd());
- writer.add(reader);
- IOUtils.closeQuietly(is);
-
- writer.flush();
- writer.close();
- reader.close();
-
- return new ByteArrayInputStream(bos.toByteArray());
- }
-
- /**
- * {@inheritDoc }
- */
- @Override
- protected Set<String> retrieveAllLinkNames(final InputStream is) throws Exception {
- final Set<String> links = new HashSet<String>();
-
- final XMLEventReader reader = getEventReader(is);
-
- try {
-
- int startDepth = 0;
-
- while (true) {
- final Map.Entry<Integer, XmlElement> linkInfo =
- extractElement(reader, null, Collections.<String>singletonList(LINK), startDepth, 2, 2);
-
- startDepth = linkInfo.getKey();
-
- links.add(linkInfo.getValue().getStart().getAttributeByName(new QName("title")).getValue());
- }
- } catch (Exception ignore) {
- // ignore
- } finally {
- reader.close();
- IOUtils.closeQuietly(is);
- }
-
- return links;
- }
-
- /**
- * {@inheritDoc }
- */
- @Override
- protected NavigationLinks retrieveNavigationInfo(
- final String entitySetName, final InputStream is)
- throws Exception {
-
- final NavigationLinks links = new NavigationLinks();
-
- final XMLEventReader reader = getEventReader(is);
-
- try {
- final List<Map.Entry<String, String>> filter = new ArrayList<Map.Entry<String, String>>();
- filter.add(new AbstractMap.SimpleEntry<String, String>("type", "application/atom+xml;type=entry"));
- filter.add(new AbstractMap.SimpleEntry<String, String>("type", "application/atom+xml;type=feed"));
-
- int startDepth = 0;
-
- while (true) {
- // a. search for link with type attribute equals to "application/atom+xml;type=entry/feed"
- final Map.Entry<Integer, XmlElement> linkInfo = extractElement(
- reader, null, Collections.<String>singletonList(LINK), filter, true, startDepth, 2, 2);
- final XmlElement link = linkInfo.getValue();
- startDepth = linkInfo.getKey();
-
- final String title = link.getStart().getAttributeByName(new QName("title")).getValue();
-
- final Attribute hrefAttr = link.getStart().getAttributeByName(new QName("href"));
- final String href = hrefAttr == null ? null : hrefAttr.getValue();
-
- try {
- final XmlElement inlineElement =
- extractElement(link.getContentReader(), null, Collections.<String>singletonList(INLINE), 0, -1, -1).
- getValue();
- final XMLEventReader inlineReader = inlineElement.getContentReader();
-
- try {
- while (true) {
- final XmlElement entry =
- extractElement(inlineReader, null, Collections.<String>singletonList("entry"), 0, -1, -1).
- getValue();
- links.addInlines(title, entry.toStream());
- }
- } catch (Exception e) {
- // Reached the end of document
- }
-
- inlineReader.close();
- } catch (Exception ignore) {
- // inline element not found (inlines are not mondatory).
- if (StringUtils.isNotBlank(href) && entityUriPattern.matcher(href).matches()) {
- links.addLinks(title, href.substring(href.lastIndexOf('/') + 1));
- }
- }
- }
- } catch (Exception ignore) {
- // ignore
- } finally {
- reader.close();
- }
-
- return links;
- }
-
- /**
- * {@inheritDoc }
- */
- @Override
- protected InputStream normalizeLinks(
- final String entitySetName, final String entityKey, final InputStream is, final NavigationLinks links)
- throws Exception {
-
- // -----------------------------------------
- // 0. Build reader and writer
- // -----------------------------------------
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- IOUtils.copy(is, bos);
- is.close();
-
- final ByteArrayOutputStream tmpBos = new ByteArrayOutputStream();
- final XMLEventWriter writer = getEventWriter(tmpBos);
-
- final XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
- // -----------------------------------------
-
- // -----------------------------------------
- // 1. Normalize links
- // -----------------------------------------
- final Set<String> added = new HashSet<String>();
-
- try {
- final List<Map.Entry<String, String>> filter = new ArrayList<Map.Entry<String, String>>();
- filter.add(new AbstractMap.SimpleEntry<String, String>("type", "application/atom+xml;type=entry"));
- filter.add(new AbstractMap.SimpleEntry<String, String>("type", "application/atom+xml;type=feed"));
-
- Map.Entry<Integer, XmlElement> linkInfo = null;
-
- while (true) {
- // a. search for link with type attribute equals to "application/atom+xml;type=entry/feed"
- linkInfo = extractElement(
- reader, writer, Collections.<String>singletonList(LINK), filter, true,
- linkInfo == null ? 0 : linkInfo.getKey(), 2, 2);
- final XmlElement link = linkInfo.getValue();
-
- final String title = link.getStart().getAttributeByName(new QName("title")).getValue();
-
- if (!added.contains(title)) {
- added.add(title);
-
- final String normalizedLink = String.format(
- "<link href=\"%s(%s)/%s\" rel=\"%s\" title=\"%s\" type=\"%s\"/>",
- entitySetName,
- entityKey,
- title,
- link.getStart().getAttributeByName(new QName("rel")).getValue(),
- title,
- link.getStart().getAttributeByName(new QName("type")).getValue());
-
- addAtomElement(IOUtils.toInputStream(normalizedLink), writer);
- }
- }
- } catch (Exception ignore) {
- // ignore
- } finally {
- writer.close();
- reader.close();
- }
- // -----------------------------------------
-
- // -----------------------------------------
- // 2. Add edit link if missing
- // -----------------------------------------
- final InputStream content = addEditLink(
- new ByteArrayInputStream(tmpBos.toByteArray()),
- entitySetName,
- Constants.DEFAULT_SERVICE_URL + entitySetName + "(" + entityKey + ")");
- // -----------------------------------------
-
- // -----------------------------------------
- // 3. Add content element if missing
- // -----------------------------------------
- return addAtomContent(
- content,
- entitySetName,
- Constants.DEFAULT_SERVICE_URL + entitySetName + "(" + entityKey + ")");
- // -----------------------------------------
-
- }
-
- public XmlElement getXmlElement(
- final StartElement start,
- final XMLEventReader reader)
- throws Exception {
-
- final XmlElement res = new XmlElement();
- res.setStart(start);
-
- StringWriter content = new StringWriter();
-
- int depth = 1;
-
- while (reader.hasNext() && depth > 0) {
- final XMLEvent event = reader.nextEvent();
-
- if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
- depth++;
- } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT) {
- depth--;
- }
-
- if (depth == 0) {
- res.setEnd(event.asEndElement());
- } else {
- event.writeAsEncodedUnicode(content);
- }
- }
-
- content.flush();
- content.close();
-
- res.setContent(new ByteArrayInputStream(content.toString().getBytes()));
-
- return res;
- }
-
- private void addAtomElement(
- final InputStream content,
- final XMLEventWriter writer)
- throws Exception {
- final XMLEventReader reader = getEventReader(content);
-
- final XMLEventFactory eventFactory = XMLEventFactory.newInstance();
- XMLEvent newLine = eventFactory.createSpace("\n");
-
- try {
- writer.add(newLine);
-
- while (reader.hasNext()) {
- final XMLEvent event = reader.nextEvent();
-
- if (event.getEventType() != XMLStreamConstants.START_DOCUMENT
- && event.getEventType() != XMLStreamConstants.END_DOCUMENT
- && event.getEventType() != XMLStreamConstants.COMMENT) {
- writer.add(event);
- }
- }
- writer.add(newLine);
- } finally {
- reader.close();
- IOUtils.closeQuietly(content);
- }
- }
-
- @Override
- public InputStream addEditLink(
- final InputStream content, final String title, final String href)
- throws Exception {
-
- final ByteArrayOutputStream copy = new ByteArrayOutputStream();
- IOUtils.copy(content, copy);
-
- IOUtils.closeQuietly(content);
-
- XMLEventReader reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
-
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- XMLEventWriter writer = getEventWriter(bos);
-
- final String editLinkElement = String.format("<link rel=\"edit\" title=\"%s\" href=\"%s\" />", title, href);
-
- try {
- // check edit link existence
- extractElement(reader, writer, Collections.<String>singletonList(LINK),
- Collections.<Map.Entry<String, String>>singletonList(
- new AbstractMap.SimpleEntry<String, String>("rel", "edit")), false, 0, -1, -1);
-
- addAtomElement(IOUtils.toInputStream(editLinkElement), writer);
- writer.add(reader);
-
- } catch (Exception e) {
- reader.close();
- reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
-
- bos = new ByteArrayOutputStream();
- writer = getEventWriter(bos);
-
- final XmlElement entryElement =
- extractElement(reader, writer, Collections.<String>singletonList("entry"), 0, 1, 1).getValue();
-
- writer.add(entryElement.getStart());
-
- addAtomElement(IOUtils.toInputStream(editLinkElement), writer);
-
- writer.add(entryElement.getContentReader());
- writer.add(entryElement.getEnd());
-
- writer.add(reader);
-
- writer.flush();
- writer.close();
- } finally {
- reader.close();
- }
-
- return new ByteArrayInputStream(bos.toByteArray());
- }
-
- public InputStream addAtomContent(
- final InputStream content, final String title, final String href)
- throws Exception {
-
- final ByteArrayOutputStream copy = new ByteArrayOutputStream();
- IOUtils.copy(content, copy);
-
- IOUtils.closeQuietly(content);
-
- XMLEventReader reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
-
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- XMLEventWriter writer = getEventWriter(bos);
-
- try {
- // check edit link existence
- XmlElement contentElement =
- extractElement(reader, writer, Collections.<String>singletonList("content"), 0, 2, 2).getValue();
- writer.add(contentElement.getStart());
- writer.add(contentElement.getContentReader());
- writer.add(contentElement.getEnd());
- writer.add(reader);
- } catch (Exception e) {
- reader.close();
- reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
-
- bos = new ByteArrayOutputStream();
- writer = getEventWriter(bos);
-
- if (isMediaContent(title)) {
- final XmlElement entryElement =
- extractElement(reader, writer, Collections.<String>singletonList("entry"), 0, 1, 1).getValue();
-
- writer.add(entryElement.getStart());
- writer.add(entryElement.getContentReader());
-
- addAtomElement(
- IOUtils.toInputStream(String.format("<content type=\"*/*\" src=\"%s/$value\" />", href)),
- writer);
-
- writer.add(entryElement.getEnd());
- } else {
- try {
- final XmlElement entryElement =
- extractElement(reader, writer, Collections.<String>singletonList(PROPERTIES), 0, 2, 3).getValue();
-
- addAtomElement(
- IOUtils.toInputStream("<content type=\"application/xml\">"),
- writer);
-
- writer.add(entryElement.getStart());
- writer.add(entryElement.getContentReader());
- writer.add(entryElement.getEnd());
-
- addAtomElement(
- IOUtils.toInputStream("</content>"),
- writer);
- } catch (Exception nf) {
- reader.close();
- reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
-
- bos = new ByteArrayOutputStream();
- writer = getEventWriter(bos);
-
- final XmlElement entryElement =
- extractElement(reader, writer, Collections.<String>singletonList("entry"), 0, 1, 1).getValue();
- writer.add(entryElement.getStart());
- writer.add(entryElement.getContentReader());
-
- addAtomElement(
- IOUtils.toInputStream("<content type=\"application/xml\"/>"),
- writer);
-
- writer.add(entryElement.getEnd());
- }
- }
-
- writer.add(reader);
-
- writer.flush();
- writer.close();
- } finally {
- reader.close();
- }
-
- return new ByteArrayInputStream(bos.toByteArray());
- }
-
- public int countAllElements(final String entitySetName) throws Exception {
- final String basePath = entitySetName + File.separatorChar;
- int count = countFeedElements(fsManager.readFile(basePath + FEED, Accept.XML), "entry");
-
- final String skipTokenDirPath = fsManager.getAbsolutePath(basePath + SKIP_TOKEN, null);
-
-
- try {
- final FileObject skipToken = fsManager.resolve(skipTokenDirPath);
- final FileObject[] files = fsManager.findByExtension(skipToken, Accept.XML.getExtension().substring(1));
-
- for (FileObject file : files) {
- count += countFeedElements(fsManager.readFile(
- basePath + SKIP_TOKEN + File.separatorChar + file.getName().getBaseName(), null), "entry");
- }
- } catch (FileSystemException fse) {
- LOG.debug("Resource path '{}' not found", skipTokenDirPath);
- }
-
-
- return count;
- }
-
- private int countFeedElements(final InputStream is, final String elementName) throws XMLStreamException {
- final XMLEventReader reader = getEventReader(is);
-
- int count = 0;
-
- while (reader.hasNext()) {
- final XMLEvent event = reader.nextEvent();
-
- if (event.getEventType() == XMLStreamConstants.START_ELEMENT
- && elementName.equals(event.asStartElement().getName().getLocalPart())) {
- count++;
- }
- }
-
- reader.close();
- return count;
- }
-
- public Map.Entry<Integer, XmlElement> extractElement(
- final XMLEventReader reader, final XMLEventWriter writer, final List<String> 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<Integer, XmlElement> extractElement(
- final XMLEventReader reader, final XMLEventWriter writer, final List<String> path,
- final Collection<Map.Entry<String, String>> filter,
- final boolean filterInOr,
- final int startPathPos, final int minPathPos, final int maxPathPos)
- throws Exception {
-
- StartElement start = null;
- int searchFor = 0;
- int depth = startPathPos;
-
- // Current inspected element
- String current = null;
-
- // set defaults
- final List<String> pathElementNames = path == null ? Collections.<String>emptyList() : path;
- final Collection<Map.Entry<String, String>> filterAttrs =
- filter == null ? Collections.<Map.Entry<String, String>>emptySet() : filter;
-
- while (reader.hasNext() && start == null) {
- final XMLEvent event = reader.nextEvent();
-
- if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
- depth++;
-
- if (current != null || ((minPathPos < 0 || minPathPos <= depth) && (maxPathPos < 0 || depth <= maxPathPos))) {
- if (pathElementNames.isEmpty()
- || pathElementNames.get(searchFor).trim().equals(event.asStartElement().getName().getLocalPart())) {
-
- if (searchFor < pathElementNames.size() - 1) {
- // path exploring not completed
- writeEvent(event, writer);
- current = pathElementNames.get(searchFor).trim();
- searchFor++;
- } else {
-
- // path exploring completed ... evaluate filter about path element name attribute
- boolean match = filterAttrs.isEmpty() || !filterInOr;
-
- for (Map.Entry<String, String> filterAttr : filterAttrs) {
- final Attribute attr = event.asStartElement().getAttributeByName(new QName(filterAttr.getKey().trim()));
-
- if (attr == null || !filterAttr.getValue().trim().equals(attr.getValue())) {
- match = filterInOr ? match : false;
- } else {
- match = filterInOr ? true : match;
- }
- }
-
- if (match) {
- // found searched element
- start = event.asStartElement();
- } else {
- skipElement(event.asStartElement(), reader, writer, false);
- depth--;
- }
- }
- } else if (current == null) {
- writeEvent(event, writer);
- } else {
- // skip element
- skipElement(event.asStartElement(), reader, writer, false);
- depth--;
- }
- } else {
- writeEvent(event, writer);
- }
-
- } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT) {
- depth--;
-
- writeEvent(event, writer);
-
- if (event.asEndElement().getName().getLocalPart().equals(current)) {
- // back step ....
- searchFor--;
- current = searchFor > 0 ? pathElementNames.get(searchFor - 1).trim() : null;
- }
- } else {
- writeEvent(event, writer);
- }
- }
-
- if (start == null) {
- throw new NotFoundException();
- }
-
- return new SimpleEntry<Integer, XmlElement>(Integer.valueOf(depth - 1), getXmlElement(start, reader));
- }
-
- public InputStream addAtomInlinecount(
- final InputStream feed, final int count, final Accept accept)
- throws Exception {
- final XMLEventReader reader = getEventReader(feed);
-
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- final XMLEventWriter writer = getEventWriter(bos);
-
- try {
-
- final XmlElement feedElement =
- extractElement(reader, writer, Collections.<String>singletonList("feed"), 0, 1, 1).getValue();
-
- writer.add(feedElement.getStart());
- addAtomElement(IOUtils.toInputStream(String.format("<m:count>%d</m:count>", count)), writer);
- writer.add(feedElement.getContentReader());
- writer.add(feedElement.getEnd());
-
- while (reader.hasNext()) {
- writer.add(reader.nextEvent());
- }
-
- } finally {
- writer.flush();
- writer.close();
- reader.close();
- IOUtils.closeQuietly(feed);
- }
-
- return new ByteArrayInputStream(bos.toByteArray());
- }
-
- @Override
- public InputStream getPropertyValue(final InputStream is, final List<String> path)
- throws Exception {
-
- final List<String> pathElements = new ArrayList<String>();
-
- for (String element : path) {
- pathElements.add(ATOM_PROPERTY_PREFIX + element);
- }
-
- final XMLEventReader reader = getEventReader(is);
- final Map.Entry<Integer, XmlElement> 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);
-
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- final XMLEventWriter writer = getEventWriter(bos);
-
- final List<String> found = new ArrayList<String>(Arrays.asList(propertyNames));
-
- boolean inProperties = false;
- boolean writeCurrent = true;
- Boolean writeNext = null;
- String currentName = null;
-
- final List<String> fieldToBeSaved = new ArrayList<String>(Arrays.asList(propertyNames));
-
- while (reader.hasNext()) {
- final XMLEvent event = reader.nextEvent();
- if (event.getEventType() == XMLStreamConstants.START_ELEMENT
- && LINK.equals(event.asStartElement().getName().getLocalPart())
- && !fieldToBeSaved.contains(
- event.asStartElement().getAttributeByName(new QName("title")).getValue())
- && !"edit".equals(event.asStartElement().getAttributeByName(new QName("rel")).getValue())) {
- writeCurrent = false;
- } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT
- && LINK.equals(event.asEndElement().getName().getLocalPart())) {
- writeNext = true;
- } else if (event.getEventType() == XMLStreamConstants.START_ELEMENT
- && (PROPERTIES).equals(event.asStartElement().getName().getLocalPart())) {
- writeCurrent = true;
- writeNext = false;
- inProperties = true;
- } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT
- && (PROPERTIES).equals(event.asEndElement().getName().getLocalPart())) {
- writeCurrent = true;
- } else if (inProperties) {
- if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
- final String elementName = event.asStartElement().getName().getLocalPart();
-
- for (String propertyName : propertyNames) {
- if ((ATOM_PROPERTY_PREFIX + propertyName.trim()).equals(elementName)) {
- writeCurrent = true;
- found.remove(propertyName);
- currentName = propertyName;
- }
- }
-
- } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT
- && StringUtils.isNotBlank(currentName)
- && (ATOM_PROPERTY_PREFIX + currentName.trim()).equals(
- event.asEndElement().getName().getLocalPart())) {
- writeNext = false;
- currentName = null;
- }
-
- }
-
- if (writeCurrent) {
- writer.add(event);
- }
-
- if (writeNext != null) {
- writeCurrent = writeNext;
- writeNext = null;
- }
- }
-
- writer.flush();
- writer.close();
- reader.close();
- IOUtils.closeQuietly(entity);
-
- // Do not raise any exception in order to support FC properties as well
- // if (!found.isEmpty()) {
- // throw new Exception(String.format("Could not find a properties '%s'", found));
- // }
-
- return new ByteArrayInputStream(bos.toByteArray());
- }
-
- @Override
- public InputStream readEntities(
- final List<String> links, final String linkName, final String next, final boolean forceFeed)
- throws Exception {
-
- if (links.isEmpty()) {
- throw new NotFoundException();
- }
-
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-
- if (forceFeed || links.size() > 1) {
- // build a feed
- bos.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>".getBytes());
-
- bos.write(("<feed xml:base=\"" + DEFAULT_SERVICE_URL + "\" "
- + "xmlns=\"http://www.w3.org/2005/Atom\" "
- + "xmlns:d=\"http://schemas.microsoft.com/ado/2007/08/dataservices\" "
- + "xmlns:m=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">")
- .getBytes());
-
- bos.write(("<id>" + DEFAULT_SERVICE_URL + "entityset(entityid)/" + linkName + "</id>").getBytes());
-
- bos.write(("<title type=\"text\">" + linkName + "</title>").getBytes());
- bos.write("<updated>2014-03-03T13:40:49Z</updated>".getBytes());
- bos.write(("<link rel=\"self\" title=\"" + linkName + "\" href=\"" + linkName + "\" />").getBytes());
- }
-
- for (String link : links) {
- try {
- final Map.Entry<String, String> uri = Commons.parseEntityURI(link);
-
- final XmlElement entry =
- extractElement(
- getEventReader(readEntity(uri.getKey(), uri.getValue(), Accept.ATOM).getValue()),
- null,
- Collections.<String>singletonList("entry"),
- 0, 1, 1).getValue();
-
- IOUtils.copy(entry.toStream(), bos);
- } catch (Exception e) {
- // log and ignore link
- LOG.warn("Error parsing uri {}", link, e);
- }
- }
-
- if (forceFeed || links.size() > 1) {
-
- if (StringUtils.isNotBlank(next)) {
- bos.write(String.format("<link rel=\"next\" href=\"%s\" />", next).getBytes());
- }
-
- bos.write("</feed>".getBytes());
- }
-
- return new ByteArrayInputStream(bos.toByteArray());
- }
-
- @Override
- public Map<String, InputStream> getChanges(final InputStream src) throws Exception {
- final Map<String, InputStream> res = new HashMap<String, InputStream>();
-
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- IOUtils.copy(src, bos);
- IOUtils.closeQuietly(src);
-
- // retrieve properties ...
- XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
-
- final Map.Entry<Integer, XmlElement> propertyElement =
- extractElement(reader, null, Collections.<String>singletonList(PROPERTIES), 0, 2, 3);
- reader.close();
-
- reader = propertyElement.getValue().getContentReader();
-
- try {
- while (true) {
- final XmlElement property = extractElement(reader, null, null, 0, -1, -1).getValue();
- res.put(property.getStart().getName().getLocalPart(), property.toStream());
- }
- } catch (Exception ignore) {
- // end
- }
-
- reader.close();
-
- // retrieve links ...
- reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
-
- try {
- int pos = 0;
- while (true) {
- final Map.Entry<Integer, XmlElement> linkElement =
- extractElement(reader, null, Collections.<String>singletonList(LINK), pos, 2, 2);
-
- res.put("[LINK]" + linkElement.getValue().getStart().getAttributeByName(new QName("title")).getValue(),
- linkElement.getValue().toStream());
-
- pos = linkElement.getKey();
- }
- } catch (Exception ignore) {
- // end
- }
-
- return res;
- }
-
- @Override
- public InputStream setChanges(
- final InputStream toBeChanged,
- final Map<String, InputStream> properties)
- throws Exception {
- XMLEventReader reader = getEventReader(toBeChanged);
-
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- XMLEventWriter writer = getEventWriter(bos);
-
- // ---------------------------------
- // add property changes
- // ---------------------------------
- Map.Entry<Integer, XmlElement> propertyElement =
- extractElement(reader, writer, Collections.<String>singletonList(PROPERTIES), 0, 2, 3);
-
- writer.flush();
-
- ByteArrayOutputStream pbos = new ByteArrayOutputStream();
- OutputStreamWriter pwriter = new OutputStreamWriter(pbos);
-
- final XMLEventReader propertyReader = propertyElement.getValue().getContentReader();
-
- try {
- while (true) {
- final XmlElement property = extractElement(propertyReader, null, null, 0, -1, -1).getValue();
- final String name = property.getStart().getName().getLocalPart();
-
- if (properties.containsKey(name)) {
- // replace
- final InputStream replacement = properties.get(name);
- properties.remove(property.getStart().getName().getLocalPart());
- pwriter.append(IOUtils.toString(replacement));
- IOUtils.closeQuietly(replacement);
- } else {
- pwriter.append(IOUtils.toString(property.toStream()));
- }
- }
- } catch (Exception ignore) {
- // end
- }
-
- for (Map.Entry<String, InputStream> remains : properties.entrySet()) {
- if (!remains.getKey().startsWith("[LINK]")) {
- pwriter.append(IOUtils.toString(remains.getValue()));
- IOUtils.closeQuietly(remains.getValue());
- }
- }
-
- pwriter.flush();
- pwriter.close();
-
- writer.add(propertyElement.getValue().getStart());
- writer.add(new XMLEventReaderWrapper(new ByteArrayInputStream(pbos.toByteArray())));
- writer.add(propertyElement.getValue().getEnd());
-
- IOUtils.closeQuietly(pbos);
-
- writer.add(reader);
- reader.close();
- writer.flush();
- writer.close();
- // ---------------------------------
-
- // ---------------------------------
- // add navigationm changes
- // ---------------------------------
-
- // remove existent links
- for (Map.Entry<String, InputStream> remains : properties.entrySet()) {
-
- if (remains.getKey().startsWith("[LINK]")) {
- reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
-
- bos.reset();
- writer = getEventWriter(bos);
-
- try {
- final String linkName = remains.getKey().substring(remains.getKey().indexOf("]") + 1);
-
- extractElement(reader, writer, Collections.<String>singletonList(LINK),
- Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>("title", linkName)),
- false, 0, 2, 2);
-
- writer.add(reader);
-
- } catch (Exception ignore) {
- // ignore
- }
-
- writer.flush();
- writer.close();
- }
- }
-
- reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
-
- bos.reset();
- writer = getEventWriter(bos);
-
- propertyElement = extractElement(reader, writer, Collections.<String>singletonList(CONTENT), 0, 2, 2);
- writer.flush();
-
- pbos.reset();
- pwriter = new OutputStreamWriter(pbos);
-
- for (Map.Entry<String, InputStream> remains : properties.entrySet()) {
- if (remains.getKey().startsWith("[LINK]")) {
- pwriter.append(IOUtils.toString(remains.getValue()));
- IOUtils.closeQuietly(remains.getValue());
- }
- }
-
- pwriter.flush();
- pwriter.close();
-
- writer.add(new XMLEventReaderWrapper(new ByteArrayInputStream(pbos.toByteArray())));
- IOUtils.closeQuietly(pbos);
-
- writer.add(propertyElement.getValue().getStart());
- writer.add(propertyElement.getValue().getContentReader());
- writer.add(propertyElement.getValue().getEnd());
-
- writer.add(reader);
- reader.close();
- writer.flush();
- writer.close();
- // ---------------------------------
-
- return new ByteArrayInputStream(bos.toByteArray());
- }
-
- @Override
- protected InputStream replaceLink(
- final InputStream toBeChanged, final String linkName, final InputStream replacement)
- throws Exception {
- final XMLEventReader reader = getEventReader(toBeChanged);
-
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- final XMLEventWriter writer = getEventWriter(bos);
-
- final XMLEventFactory eventFactory = XMLEventFactory.newInstance();
- XMLEvent newLine = eventFactory.createSpace("\n");
-
- try {
- final XmlElement linkElement =
- extractElement(reader, writer, Collections.<String>singletonList(LINK),
- Collections.<Map.Entry<String, String>>singletonList(new SimpleEntry<String, String>("title", linkName)),
- false, 0, -1, -1).getValue();
- writer.add(linkElement.getStart());
-
- // ------------------------------------------
- // write inline ...
- // ------------------------------------------
- writer.add(newLine);
- writer.add(eventFactory.createStartElement("m", null, "inline"));
-
- addAtomElement(replacement, writer);
-
- writer.add(eventFactory.createEndElement("m", null, "inline"));
- writer.add(newLine);
- // ------------------------------------------
-
- writer.add(linkElement.getEnd());
-
- writer.add(reader);
- writer.flush();
- writer.close();
- } finally {
- reader.close();
- IOUtils.closeQuietly(toBeChanged);
- }
-
- return new ByteArrayInputStream(bos.toByteArray());
- }
-
- public String getEdmTypeFromAtom(final String entitySetName, final String entityId, final List<String> path)
- throws Exception {
- InputStream src = fsManager.readFile(Commons.getEntityBasePath(entitySetName, entityId) + ENTITY, Accept.XML);
-
- final List<String> atomPathElements = new ArrayList<String>();
-
- for (String element : path) {
- atomPathElements.add(ATOM_PROPERTY_PREFIX + element);
- }
-
- final Map.Entry<Integer, XmlElement> prop = extractElement(getEventReader(src), null, atomPathElements, 0, 3, 4);
- IOUtils.closeQuietly(src);
-
- final Attribute type = prop.getValue().getStart().getAttributeByName(new QName(TYPE));
-
- final String edmType;
-
- if (type == null) {
- edmType = Constants.ATOM_DEF_TYPE;
- } else {
- edmType = type.getValue();
- }
-
- return edmType;
- }
-
- @Override
- public Map.Entry<String, List<String>> extractLinkURIs(
- final String entitySetName, final String entityId, final String linkName)
- throws Exception {
- final LinkInfo links = readLinks(entitySetName, entityId, linkName, Accept.XML);
- return extractLinkURIs(links.getLinks());
- }
-
- @Override
- public Map.Entry<String, List<String>> extractLinkURIs(final InputStream is)
- throws Exception {
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- IOUtils.copy(is, bos);
- IOUtils.closeQuietly(is);
-
- XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
- final List<String> links = new ArrayList<String>();
- try {
- while (true) {
- links.add(IOUtils.toString(extractElement(reader, null, Collections.<String>singletonList("uri"), 0, -1, -1).
- getValue().getContent()));
- }
- } catch (Exception ignore) {
- // End document reached ...
- }
- reader.close();
-
- String next;
-
- reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
- try {
- next = IOUtils.toString(extractElement(reader, null, Collections.<String>singletonList("next"), 0, -1, -1).
- getValue().getContent());
- } catch (Exception ignore) {
- // next link is not mandatory
- next = null;
- }
- reader.close();
-
- return new AbstractMap.SimpleEntry<String, List<String>>(next, links);
- }
-
- @Override
- public InputStream getProperty(
- final String entitySetName, final String entityId, final List<String> path, final String edmType)
- throws Exception {
- final List<String> pathElements = new ArrayList<String>();
-
- for (String element : path) {
- pathElements.add(ATOM_PROPERTY_PREFIX + element);
- }
-
- final InputStream src =
- fsManager.readFile(Commons.getEntityBasePath(entitySetName, entityId) + 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(ATOM_DATASERVICE_NS)) == null) {
- writer.add(eventFactory.createNamespace(ATOM_PROPERTY_PREFIX.substring(0, 1), DATASERVICES_NS));
- }
- if (property.getStart().getAttributeByName(new QName(ATOM_METADATA_NS)) == null) {
- writer.add(eventFactory.createNamespace(ATOM_METADATA_PREFIX.substring(0, 1), 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<String> path, final boolean justValue)
- throws Exception {
-
- final List<String> pathElements = new ArrayList<String>();
-
- for (String element : path) {
- pathElements.add(ATOM_PROPERTY_PREFIX + element);
- }
-
- final XMLEventReader reader = getEventReader(src);
-
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- final XMLEventWriter writer = getEventWriter(bos);
-
- final Map.Entry<Integer, XmlElement> element = extractElement(reader, writer, pathElements, 0, 3, 4);
-
- if (justValue) {
- writer.add(element.getValue().getStart());
- }
-
- final XMLEventReader changesReader = new XMLEventReaderWrapper(replacement);
-
- writer.add(changesReader);
- changesReader.close();
- IOUtils.closeQuietly(replacement);
-
- if (justValue) {
- writer.add(element.getValue().getEnd());
- }
-
- writer.add(reader);
-
- reader.close();
- IOUtils.closeQuietly(src);
-
- writer.flush();
- writer.close();
-
- return new ByteArrayInputStream(bos.toByteArray());
- }
-
- @Override
- public InputStream deleteProperty(final InputStream src, final List<String> path) throws Exception {
-
- final List<String> pathElements = new ArrayList<String>();
-
- for (String element : path) {
- pathElements.add(ATOM_PROPERTY_PREFIX + element);
- }
-
- final XMLEventReader reader = getEventReader(src);
-
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- final XMLEventWriter writer = getEventWriter(bos);
-
- final Map.Entry<Integer, XmlElement> 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))));
-
- writer.add(changesReader);
- changesReader.close();
-
- writer.add(reader);
-
- reader.close();
- IOUtils.closeQuietly(src);
-
- writer.flush();
- writer.close();
-
- return new ByteArrayInputStream(bos.toByteArray());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/v3/JSONUtilities.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..0f2a3f2
--- /dev/null
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/v3/JSONUtilities.java
@@ -0,0 +1,28 @@
+/*
+ * 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.fit.utils.ODataVersion;
+
+public class JSONUtilities extends org.apache.olingo.fit.utils.AbstractJSONUtilities {
+
+ public JSONUtilities() throws Exception {
+ super(ODataVersion.v3);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/v3/XMLUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/v3/XMLUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/v3/XMLUtilities.java
new file mode 100644
index 0000000..c1a58bf
--- /dev/null
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/v3/XMLUtilities.java
@@ -0,0 +1,191 @@
+/*
+ * 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 java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.StartElement;
+import org.apache.commons.io.IOUtils;
+import org.apache.olingo.fit.utils.Accept;
+import org.apache.olingo.fit.utils.Commons;
+import org.apache.olingo.fit.utils.Constants;
+import org.apache.olingo.fit.utils.MetadataLinkInfo;
+import org.apache.olingo.fit.utils.ODataVersion;
+import org.apache.olingo.fit.utils.XmlElement;
+
+public class XMLUtilities extends org.apache.olingo.fit.utils.AbstractXMLUtilities {
+
+ public XMLUtilities() throws Exception {
+ super(ODataVersion.v3);
+ }
+
+ @Override
+ public void retrieveLinkInfoFromMetadata() throws Exception {
+
+ final MetadataLinkInfo metadataLinkInfo = new MetadataLinkInfo();
+ Commons.getLinkInfo().put(version, metadataLinkInfo);
+
+ final InputStream metadata = fsManager.readFile(Constants.METADATA, Accept.XML);
+ final XMLEventReader reader = getEventReader(metadata);
+
+ try {
+ while (true) {
+ final Map.Entry<Integer, XmlElement> entitySetElement =
+ extractElement(reader, null, Collections.<String>singletonList("EntitySet"),
+ null, false, 0, -1, -1);
+
+ retrieveLinks(entitySetElement.getValue(), metadataLinkInfo);
+ }
+ } catch (Exception e) {
+ } finally {
+ reader.close();
+ }
+ }
+
+ private void retrieveLinks(final XmlElement entitySetElement, final MetadataLinkInfo metadataLinkInfo)
+ throws Exception {
+
+ final InputStream metadata = fsManager.readFile(Constants.METADATA, Accept.XML);
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ IOUtils.copy(metadata, bos);
+ IOUtils.closeQuietly(metadata);
+
+ final String entitySetName = entitySetElement.getStart().getAttributeByName(new QName("Name")).getValue().trim();
+ final String entityType = entitySetElement.getStart().getAttributeByName(new QName("EntityType")).getValue().trim();
+
+ final Collection<Map.Entry<String, String>> filter = new HashSet<Map.Entry<String, String>>();
+ filter.add(new SimpleEntry<String, String>(
+ "Name", entityType.substring(entityType.lastIndexOf(".") + 1, entityType.length())));
+ filter.add(new SimpleEntry<String, String>("BaseType", entityType));
+
+ final XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+ final Map.Entry<Integer, XmlElement> entityTypeElement = extractElement(
+ reader, null, Collections.<String>singletonList("EntityType"), filter, true, 0, -1, -1);
+
+ final XMLEventReader entityReader = entityTypeElement.getValue().getContentReader();
+ int size = 0;
+
+ try {
+ while (true) {
+ final XmlElement navProperty =
+ extractElement(entityReader, null, Collections.<String>singletonList("NavigationProperty"),
+ null, false, 0, -1, -1).getValue();
+
+ final String linkName = navProperty.getStart().getAttributeByName(new QName("Name")).getValue();
+ final Map.Entry<String, Boolean> target = getTargetInfo(navProperty.getStart(), linkName);
+
+ metadataLinkInfo.addLink(
+ entitySetName,
+ linkName,
+ target.getKey(),
+ target.getValue());
+
+ size++;
+ }
+ } catch (Exception e) {
+ } finally {
+ entityReader.close();
+ }
+
+ if (size == 0) {
+ metadataLinkInfo.addEntitySet(entitySetName);
+ }
+ }
+
+ private Map.Entry<String, Boolean> getTargetInfo(final StartElement element, final String linkName)
+ throws Exception {
+ final InputStream metadata = fsManager.readFile(Constants.METADATA, Accept.XML);
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ IOUtils.copy(metadata, bos);
+ IOUtils.closeQuietly(metadata);
+
+ // ------------------------------------
+ // Retrieve association
+ // ------------------------------------
+ XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+ final String associationName = element.getAttributeByName(new QName("Relationship")).getValue();
+
+ final Map.Entry<Integer, XmlElement> association = extractElement(
+ reader, null, Collections.<String>singletonList("Association"),
+ Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>(
+ "Name", associationName.substring(associationName.lastIndexOf(".") + 1))), false,
+ 0, 4, 4);
+
+ reader.close();
+ // ------------------------------------
+
+ // ------------------------------------
+ // check for feed or not from Association role
+ // ------------------------------------
+ InputStream associationContent = association.getValue().toStream();
+ reader = getEventReader(associationContent);
+
+ Map.Entry<Integer, XmlElement> associationEnd = extractElement(
+ reader, null, Collections.<String>singletonList("End"),
+ Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>("Role", linkName)),
+ false, 0, -1, -1);
+
+ reader.close();
+ IOUtils.closeQuietly(associationContent);
+
+ final boolean feed = associationEnd.getValue().getStart().getAttributeByName(
+ new QName("Multiplicity")).getValue().equals("*");
+ // ------------------------------------
+
+ // ------------------------------------
+ // Retrieve target association set name
+ // ------------------------------------
+ reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+ final Map.Entry<Integer, XmlElement> associationSet = extractElement(
+ reader, null, Collections.<String>singletonList("AssociationSet"),
+ Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>(
+ "Association", associationName)), false, 0, -1, -1);
+
+ reader.close();
+
+ associationContent = associationSet.getValue().toStream();
+ reader = getEventReader(associationContent);
+
+ associationEnd = extractElement(
+ reader, null, Collections.<String>singletonList("End"),
+ Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>("Role", linkName)),
+ false, 0, -1, -1);
+
+ reader.close();
+ IOUtils.closeQuietly(associationContent);
+
+ final String target = associationEnd.getValue().getStart().getAttributeByName(new QName("EntitySet")).getValue();
+ // ------------------------------------
+
+ return new SimpleEntry<String, Boolean>(target, feed);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/v4/JSONUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/v4/JSONUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/v4/JSONUtilities.java
new file mode 100644
index 0000000..daf75f4
--- /dev/null
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/v4/JSONUtilities.java
@@ -0,0 +1,28 @@
+/*
+ * 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.fit.utils.ODataVersion;
+
+public class JSONUtilities extends org.apache.olingo.fit.utils.AbstractJSONUtilities {
+
+ public JSONUtilities() throws Exception {
+ super(ODataVersion.v4);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/v4/XMLUtilities.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..c61d272
--- /dev/null
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/v4/XMLUtilities.java
@@ -0,0 +1,142 @@
+/*
+ * 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 java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import org.apache.commons.io.IOUtils;
+import org.apache.olingo.fit.utils.Accept;
+import org.apache.olingo.fit.utils.Commons;
+import org.apache.olingo.fit.utils.Constants;
+import org.apache.olingo.fit.utils.MetadataLinkInfo;
+import org.apache.olingo.fit.utils.ODataVersion;
+import org.apache.olingo.fit.utils.XmlElement;
+
+public class XMLUtilities extends org.apache.olingo.fit.utils.AbstractXMLUtilities {
+
+ public XMLUtilities() throws Exception {
+ super(ODataVersion.v4);
+ }
+
+ @Override
+ public void retrieveLinkInfoFromMetadata() throws Exception {
+
+ final MetadataLinkInfo metadataLinkInfo = new MetadataLinkInfo();
+ Commons.getLinkInfo().put(version, metadataLinkInfo);
+
+ final InputStream metadata = fsManager.readFile(Constants.METADATA, Accept.XML);
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ IOUtils.copy(metadata, bos);
+ IOUtils.closeQuietly(metadata);
+
+ XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+ final Set<String> singletons = new HashSet<String>();
+
+ try {
+ while (true) {
+ final Map.Entry<Integer, XmlElement> entitySetElement =
+ extractElement(reader, null, Collections.<String>singletonList("Singleton"),
+ null, false, 0, -1, -1);
+
+ final String entitySetName =
+ entitySetElement.getValue().getStart().getAttributeByName(new QName("Name")).getValue().trim();
+ singletons.add(entitySetName);
+ }
+ } catch (Exception e) {
+ } finally {
+ reader.close();
+ }
+
+ reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+ try {
+ while (true) {
+ final Map.Entry<Integer, XmlElement> entitySetElement =
+ extractElement(reader, null, Collections.<String>singletonList("EntitySet"),
+ null, false, 0, -1, -1);
+
+ retrieveLinks(entitySetElement.getValue(), metadataLinkInfo, singletons);
+ }
+ } catch (Exception e) {
+ } finally {
+ reader.close();
+ }
+
+ reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+ try {
+ while (true) {
+ final Map.Entry<Integer, XmlElement> entitySetElement =
+ extractElement(reader, null, Collections.<String>singletonList("Singleton"),
+ null, false, 0, -1, -1);
+
+ retrieveLinks(entitySetElement.getValue(), metadataLinkInfo, singletons);
+ }
+ } catch (Exception e) {
+ } finally {
+ reader.close();
+ }
+ }
+
+ private void retrieveLinks(
+ final XmlElement entitySetElement, final MetadataLinkInfo metadataLinkInfo, final Set<String> singletons)
+ throws Exception {
+
+ final String entitySetName = entitySetElement.getStart().getAttributeByName(new QName("Name")).getValue().trim();
+
+ final XMLEventReader entityReader = entitySetElement.getContentReader();
+ int size = 0;
+
+ try {
+ while (true) {
+ final XmlElement navProperty =
+ extractElement(entityReader, null, Collections.<String>singletonList("NavigationPropertyBinding"),
+ null, false, 0, -1, -1).getValue();
+
+ final String linkName = navProperty.getStart().getAttributeByName(new QName("Path")).getValue();
+ final String target = navProperty.getStart().getAttributeByName(new QName("Target")).getValue();
+ final boolean feed = !singletons.contains(target);
+
+ metadataLinkInfo.addLink(
+ entitySetName,
+ linkName,
+ target,
+ feed);
+
+ size++;
+ }
+ } catch (Exception e) {
+ } finally {
+ entityReader.close();
+ }
+
+ if (size == 0) {
+ metadataLinkInfo.addEntitySet(entitySetName);
+ }
+ }
+}
[2/8] [OLINGO-205,
OLINGO-200] provided atom v4 deserialization for entity type/set +
entity set request
Posted by fm...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java
index f64b233..7ba38f8 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java
@@ -20,6 +20,7 @@ package org.apache.olingo.client.api.communication.request;
import java.util.concurrent.Future;
import org.apache.olingo.client.api.communication.response.ODataResponse;
+import org.apache.olingo.client.api.format.Format;
/**
* Basic OData request.
@@ -27,7 +28,7 @@ import org.apache.olingo.client.api.communication.response.ODataResponse;
* @param <V> OData response type corresponding to the request implementation.
* @param <T> Accepted content-type formats by the request in object.
*/
-public interface ODataBasicRequest<V extends ODataResponse, T extends Enum<T>> extends ODataRequest {
+public interface ODataBasicRequest<V extends ODataResponse, T extends Format> extends ODataRequest {
/**
* Request execute.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java
index edabb96..14f907e 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java
@@ -20,9 +20,10 @@ package org.apache.olingo.client.api.communication.request.retrieve;
import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.format.Format;
/**
* This is an abstract representation of an OData retrieve query request returning one or more result item.
*/
-public interface ODataRetrieveRequest<V, T extends Enum<T>> extends ODataBasicRequest<ODataRetrieveResponse<V>, T> {
+public interface ODataRetrieveRequest<V, T extends Format> extends ODataBasicRequest<ODataRetrieveResponse<V>, T> {
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataLinkType.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataLinkType.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataLinkType.java
index 6702c00..179f9cc 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataLinkType.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataLinkType.java
@@ -20,7 +20,6 @@ package org.apache.olingo.client.api.domain;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.entity.ContentType;
-import org.apache.olingo.client.api.format.ODataPubFormat;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
/**
@@ -31,11 +30,11 @@ public enum ODataLinkType {
/**
* Entity navigation link.
*/
- ENTITY_NAVIGATION(ODataPubFormat.ATOM + ";type=entry"),
+ ENTITY_NAVIGATION(ContentType.APPLICATION_ATOM_XML.getMimeType() + ";type=entry"),
/**
* Entity set navigation link.
*/
- ENTITY_SET_NAVIGATION(ODataPubFormat.ATOM + ";type=feed"),
+ ENTITY_SET_NAVIGATION(ContentType.APPLICATION_ATOM_XML.getMimeType() + ";type=feed"),
/**
* Association link.
*/
@@ -57,7 +56,8 @@ public enum ODataLinkType {
}
/**
- * Gets <code>LinkType</code> instance from the given rel and type.
+ * Gets
+ * <code>LinkType</code> instance from the given rel and type.
*
* @param client OData client.
* @param rel rel.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-api/src/main/java/org/apache/olingo/client/api/format/Format.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/format/Format.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/format/Format.java
new file mode 100644
index 0000000..1d52664
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/format/Format.java
@@ -0,0 +1,26 @@
+/*
+ * 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.format;
+
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+
+public interface Format {
+
+ String toString(ODataServiceVersion version);
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataFormat.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataFormat.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataFormat.java
index 2ee704b..8f52ea3 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataFormat.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataFormat.java
@@ -19,11 +19,12 @@
package org.apache.olingo.client.api.format;
import org.apache.http.entity.ContentType;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
/**
* Available formats to be used in various contexts.
*/
-public enum ODataFormat {
+public enum ODataFormat implements Format{
/**
* JSON format with no metadata.
@@ -94,4 +95,9 @@ public enum ODataFormat {
return result;
}
+
+ @Override
+ public String toString(final ODataServiceVersion version) {
+ return this.toString();
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataMediaFormat.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataMediaFormat.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataMediaFormat.java
index 353edc4..5d49ddb 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataMediaFormat.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataMediaFormat.java
@@ -19,11 +19,12 @@
package org.apache.olingo.client.api.format;
import org.apache.http.entity.ContentType;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
/**
* Available formats for media.
*/
-public enum ODataMediaFormat {
+public enum ODataMediaFormat implements Format{
CHARSET_PARAMETER("charset"),
MEDIA_TYPE_WILDCARD("*"),
@@ -68,4 +69,9 @@ public enum ODataMediaFormat {
return result;
}
+
+ @Override
+ public String toString(final ODataServiceVersion version) {
+ return this.toString();
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataPubFormat.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataPubFormat.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataPubFormat.java
index 62e5322..aea294f 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataPubFormat.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataPubFormat.java
@@ -18,34 +18,49 @@
*/
package org.apache.olingo.client.api.format;
+import java.util.EnumMap;
import org.apache.http.entity.ContentType;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
/**
* Available formats for AtomPub exchange.
*/
-public enum ODataPubFormat {
+public enum ODataPubFormat implements Format {
/**
* JSON format with no metadata.
*/
- JSON_NO_METADATA(ContentType.APPLICATION_JSON.getMimeType() + ";odata=nometadata"),
+ JSON_NO_METADATA(),
/**
* JSON format with minimal metadata (default).
*/
- JSON(ContentType.APPLICATION_JSON.getMimeType() + ";odata=minimalmetadata"),
+ JSON(),
/**
* JSON format with no metadata.
*/
- JSON_FULL_METADATA(ContentType.APPLICATION_JSON.getMimeType() + ";odata=fullmetadata"),
+ JSON_FULL_METADATA(),
/**
* Atom format.
*/
- ATOM(ContentType.APPLICATION_ATOM_XML.getMimeType());
+ ATOM();
- private final String format;
+ final static EnumMap<ODataServiceVersion, EnumMap<ODataPubFormat, String>> formatPerVersion =
+ new EnumMap<ODataServiceVersion, EnumMap<ODataPubFormat, String>>(ODataServiceVersion.class);
- ODataPubFormat(final String format) {
- this.format = format;
+ static {
+ final EnumMap<ODataPubFormat, String> v3 = new EnumMap<ODataPubFormat, String>(ODataPubFormat.class);
+ v3.put(JSON_NO_METADATA, ContentType.APPLICATION_JSON.getMimeType() + ";odata=nometadata");
+ v3.put(JSON, ContentType.APPLICATION_JSON.getMimeType() + ";odata=minimalmetadata");
+ v3.put(JSON_FULL_METADATA, ContentType.APPLICATION_JSON.getMimeType() + ";odata=fullmetadata");
+ v3.put(ATOM, ContentType.APPLICATION_ATOM_XML.getMimeType());
+ formatPerVersion.put(ODataServiceVersion.V30, v3);
+
+ final EnumMap<ODataPubFormat, String> v4 = new EnumMap<ODataPubFormat, String>(ODataPubFormat.class);
+ v4.put(JSON_NO_METADATA, ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=none");
+ v4.put(JSON, ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=minimal");
+ v4.put(JSON_FULL_METADATA, ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=full");
+ v4.put(ATOM, ContentType.APPLICATION_ATOM_XML.getMimeType());
+ formatPerVersion.put(ODataServiceVersion.V40, v4);
}
/**
@@ -54,8 +69,17 @@ public enum ODataPubFormat {
* @return format as a string.
*/
@Override
+ public String toString(final ODataServiceVersion version) {
+ if (version.ordinal() < ODataServiceVersion.V30.ordinal()) {
+ throw new IllegalArgumentException("Unsupported version " + version);
+ }
+
+ return ODataPubFormat.formatPerVersion.get(version).get(this);
+ }
+
+ @Override
public String toString() {
- return format;
+ throw new UnsupportedOperationException();
}
/**
@@ -72,7 +96,7 @@ public enum ODataPubFormat {
final String[] parts = format.split(";");
_format.append(parts[0].trim());
if (ContentType.APPLICATION_JSON.getMimeType().equals(parts[0].trim())) {
- if (parts.length > 1 && parts[1].startsWith("odata=")) {
+ if (parts.length > 1 && parts[1].startsWith("odata")) {
_format.append(';').append(parts[1].trim());
} else {
result = ODataPubFormat.JSON;
@@ -82,7 +106,8 @@ public enum ODataPubFormat {
if (result == null) {
final String candidate = _format.toString();
for (ODataPubFormat value : values()) {
- if (candidate.equals(value.toString())) {
+ if (candidate.equals(value.toString(ODataServiceVersion.V30))
+ || candidate.equals(value.toString(ODataServiceVersion.V40))) {
result = value;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataValueFormat.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataValueFormat.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataValueFormat.java
index b04ce7d..818b104 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataValueFormat.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataValueFormat.java
@@ -19,11 +19,12 @@
package org.apache.olingo.client.api.format;
import org.apache.http.entity.ContentType;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
/**
* Available formats for property values.
*/
-public enum ODataValueFormat {
+public enum ODataValueFormat implements Format{
/**
* Application octet stream.
@@ -73,4 +74,9 @@ public enum ODataValueFormat {
return result;
}
+
+ @Override
+ public String toString(final ODataServiceVersion version) {
+ return this.toString();
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
index 307cdc9..8cd5819 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
@@ -31,6 +31,7 @@ import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
import org.apache.olingo.client.api.communication.request.ODataStreamer;
import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
import org.apache.olingo.client.api.communication.response.ODataResponse;
+import org.apache.olingo.client.api.format.Format;
import org.apache.olingo.client.api.http.HttpMethod;
/**
@@ -39,88 +40,87 @@ import org.apache.olingo.client.api.http.HttpMethod;
* @param <V> OData response type corresponding to the request implementation.
* @param <T> OData format being used.
*/
-public abstract class AbstractODataBasicRequest<V extends ODataResponse, T extends Enum<T>>
+public abstract class AbstractODataBasicRequest<V extends ODataResponse, T extends Format>
extends ODataRequestImpl<T>
implements ODataBasicRequest<V, T> {
- /**
- * Constructor.
- *
- * @param odataClient client instance getting this request
- * @param formatRef reference class for the format being used
- * @param method request method.
- * @param uri OData request URI.
- */
- public AbstractODataBasicRequest(final CommonODataClient odataClient,
- final Class<T> formatRef, final HttpMethod method, final URI uri) {
+ /**
+ * Constructor.
+ *
+ * @param odataClient client instance getting this request
+ * @param formatRef reference class for the format being used
+ * @param method request method.
+ * @param uri OData request URI.
+ */
+ public AbstractODataBasicRequest(final CommonODataClient odataClient,
+ final Class<T> formatRef, final HttpMethod method, final URI uri) {
- super(odataClient, formatRef, method, uri);
- }
+ super(odataClient, formatRef, method, uri);
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public void setFormat(final T format) {
- if (format != null) {
- setAccept(format.toString());
- setContentType(format.toString());
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setFormat(final T format) {
+ if (format != null) {
+ setAccept(format.toString(odataClient.getServiceVersion()));
+ setContentType(format.toString(odataClient.getServiceVersion()));
}
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public final Future<V> asyncExecute() {
- return odataClient.getConfiguration().getExecutor().submit(new Callable<V>() {
-
- @Override
- public V call() throws Exception {
- return execute();
- }
- });
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final Future<V> asyncExecute() {
+ return odataClient.getConfiguration().getExecutor().submit(new Callable<V>() {
+ @Override
+ public V call() throws Exception {
+ return execute();
+ }
+ });
+ }
- /**
- * Gets payload as an InputStream.
- *
- * @return InputStream for entire payload.
- */
- protected abstract InputStream getPayload();
+ /**
+ * Gets payload as an InputStream.
+ *
+ * @return InputStream for entire payload.
+ */
+ protected abstract InputStream getPayload();
- /**
- * Serializes the full request into the given batch request.
- *
- * @param req destination batch request.
- */
- public void batch(final ODataBatchRequest req) {
- batch(req, null);
- }
+ /**
+ * Serializes the full request into the given batch request.
+ *
+ * @param req destination batch request.
+ */
+ public void batch(final ODataBatchRequest req) {
+ batch(req, null);
+ }
- /**
- * Serializes the full request into the given batch request.
- * <p>
- * This method have to be used to serialize a changeset item with the specified contentId.
- *
- * @param req destination batch request.
- * @param contentId contentId of the changeset item.
- */
- public void batch(final ODataBatchRequest req, final String contentId) {
- try {
- req.rawAppend(toByteArray());
- if (StringUtils.isNotBlank(contentId)) {
- req.rawAppend((ODataBatchConstants.CHANGESET_CONTENT_ID_NAME + ": " + contentId).getBytes());
- req.rawAppend(ODataStreamer.CRLF);
- }
- req.rawAppend(ODataStreamer.CRLF);
+ /**
+ * Serializes the full request into the given batch request.
+ * <p>
+ * This method have to be used to serialize a changeset item with the specified contentId.
+ *
+ * @param req destination batch request.
+ * @param contentId contentId of the changeset item.
+ */
+ public void batch(final ODataBatchRequest req, final String contentId) {
+ try {
+ req.rawAppend(toByteArray());
+ if (StringUtils.isNotBlank(contentId)) {
+ req.rawAppend((ODataBatchConstants.CHANGESET_CONTENT_ID_NAME + ": " + contentId).getBytes());
+ req.rawAppend(ODataStreamer.CRLF);
+ }
+ req.rawAppend(ODataStreamer.CRLF);
- final InputStream payload = getPayload();
- if (payload != null) {
- req.rawAppend(IOUtils.toByteArray(getPayload()));
- }
- } catch (IOException e) {
- throw new IllegalStateException(e);
- }
+ final InputStream payload = getPayload();
+ if (payload != null) {
+ req.rawAppend(IOUtils.toByteArray(getPayload()));
+ }
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
}
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
index d088e97..2e60a7d 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
@@ -42,6 +42,10 @@ import org.apache.olingo.client.api.communication.header.ODataHeaderValues;
import org.apache.olingo.client.api.communication.header.ODataHeaders;
import org.apache.olingo.client.api.communication.request.ODataRequest;
import org.apache.olingo.client.api.communication.request.ODataStreamer;
+import org.apache.olingo.client.api.communication.request.batch.v3.BatchRequestFactory;
+import org.apache.olingo.client.api.communication.request.cud.v3.CUDRequestFactory;
+import org.apache.olingo.client.api.communication.request.invoke.v3.InvokeRequestFactory;
+import org.apache.olingo.client.api.communication.request.streamed.v3.StreamedRequestFactory;
import org.apache.olingo.client.api.communication.response.ODataResponse;
import org.apache.olingo.client.api.format.ODataMediaFormat;
import org.apache.olingo.client.api.format.ODataPubFormat;
@@ -51,6 +55,7 @@ import org.apache.olingo.client.api.http.HttpMethod;
import org.apache.olingo.client.core.data.JSONErrorImpl;
import org.apache.olingo.client.core.data.XMLErrorImpl;
import org.apache.olingo.client.api.data.ODataError;
+import org.apache.olingo.client.api.format.Format;
import org.apache.olingo.client.core.communication.header.ODataHeadersImpl;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.slf4j.Logger;
@@ -66,7 +71,7 @@ import org.slf4j.LoggerFactory;
* @see InvokeRequestFactory
* @see StreamedRequestFactory
*/
-public class ODataRequestImpl<T extends Enum<T>> implements ODataRequest {
+public class ODataRequestImpl<T extends Format> implements ODataRequest {
/**
* Logger.
@@ -251,7 +256,7 @@ public class ODataRequestImpl<T extends Enum<T>> implements ODataRequest {
@Override
public String getAccept() {
final String acceptHead = odataHeaders.getHeader(HeaderName.accept);
- return StringUtils.isBlank(acceptHead) ? getDefaultFormat().toString() : acceptHead;
+ return StringUtils.isBlank(acceptHead) ? getDefaultFormat().toString(odataClient.getServiceVersion()) : acceptHead;
}
/**
@@ -284,7 +289,8 @@ public class ODataRequestImpl<T extends Enum<T>> implements ODataRequest {
@Override
public String getContentType() {
final String contentTypeHead = odataHeaders.getHeader(HeaderName.contentType);
- return StringUtils.isBlank(contentTypeHead) ? getDefaultFormat().toString() : contentTypeHead;
+ return StringUtils.isBlank(contentTypeHead)
+ ? getDefaultFormat().toString(odataClient.getServiceVersion()) : contentTypeHead;
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/ODataInvokeRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/ODataInvokeRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/ODataInvokeRequestImpl.java
index c6355e4..abef76c 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/ODataInvokeRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/ODataInvokeRequestImpl.java
@@ -100,7 +100,7 @@ public class ODataInvokeRequestImpl<T extends ODataInvokeResult>
public void setFormat(final ODataPubFormat format) {
final String _format = (reference.isAssignableFrom(ODataProperty.class) && format == ODataPubFormat.ATOM)
? ODataFormat.XML.toString()
- : format.toString();
+ : format.toString(odataClient.getServiceVersion());
setAccept(_format);
setContentType(_format);
}
@@ -163,7 +163,7 @@ public class ODataInvokeRequestImpl<T extends ODataInvokeResult>
} else if (this.method == HttpMethod.POST) {
((HttpPost) request).setEntity(URIUtils.buildInputStreamEntity(odataClient, input));
- setContentType(ODataPubFormat.JSON.toString());
+ setContentType(ODataPubFormat.JSON.toString(odataClient.getServiceVersion()));
}
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java
index fe51722..628e836 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java
@@ -26,6 +26,7 @@ import org.apache.olingo.client.api.CommonODataClient;
import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
import org.apache.olingo.client.api.communication.request.retrieve.ODataRetrieveRequest;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.format.Format;
import org.apache.olingo.client.api.http.HttpMethod;
import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest;
import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
@@ -33,7 +34,7 @@ import org.apache.olingo.client.core.communication.response.AbstractODataRespons
/**
* This is an abstract representation of an OData retrieve query request returning one or more result item.
*/
-public abstract class AbstractODataRetrieveRequest<V, T extends Enum<T>>
+public abstract class AbstractODataRetrieveRequest<V, T extends Format>
extends AbstractODataBasicRequest<ODataRetrieveResponse<V>, T>
implements ODataRetrieveRequest<V, T>, ODataBatchableRequest {
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java
----------------------------------------------------------------------
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 4226cc2..777d86a 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
@@ -92,7 +92,7 @@ public class ODataRawRequestImpl extends ODataRequestImpl<ODataPubFormat>
this.close();
}
}
-
+
return odataClient.getReader().read(new ByteArrayInputStream(obj), getContentType(), reference);
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedEntityRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedEntityRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedEntityRequest.java
index d19d0d5..c7f7c52 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedEntityRequest.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedEntityRequest.java
@@ -48,7 +48,7 @@ public abstract class AbstractODataStreamedEntityRequest<V extends ODataResponse
public AbstractODataStreamedEntityRequest(final CommonODataClient odataClient, final HttpMethod method,
URI uri) {
super(odataClient, method, uri);
- setAccept(getFormat().toString());
+ setAccept(getFormat().toString(odataClient.getServiceVersion()));
}
/**
@@ -65,6 +65,6 @@ public abstract class AbstractODataStreamedEntityRequest<V extends ODataResponse
@Override
public final void setFormat(final ODataPubFormat format) {
this.format = format;
- setAccept(format.toString());
+ setAccept(format.toString(odataClient.getServiceVersion()));
}
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonDeserializer.java
index 74b29fb..3aca585 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonDeserializer.java
@@ -57,7 +57,7 @@ abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<T> {
}
private ODataPropertyType guessPropertyType(final JsonNode node) {
- ODataPropertyType type = null;
+ final ODataPropertyType type;
if (node.isValueNode() || node.isNull()) {
type = ODataPropertyType.PRIMITIVE;
@@ -73,7 +73,7 @@ abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<T> {
}
private Value fromPrimitive(final JsonNode node, final EdmTypeInfo typeInfo) {
- Value value = null;
+ final Value value;
if (node.isNull()) {
value = new NullValueImpl();
@@ -172,5 +172,4 @@ abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<T> {
property.setValue(new PrimitiveValueImpl(StringUtils.EMPTY));
}
}
-
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java
index 8893b91..835d174 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java
@@ -153,7 +153,6 @@ public class AtomDeserializer extends AbstractAtomDealer {
private void properties(final XMLEventReader reader, final StartElement start, final AtomEntryImpl entry)
throws XMLStreamException {
-
boolean foundEndProperties = false;
while (reader.hasNext() && !foundEndProperties) {
final XMLEvent event = reader.nextEvent();
@@ -316,7 +315,6 @@ public class AtomDeserializer extends AbstractAtomDealer {
boolean foundEndFeed = false;
while (reader.hasNext() && !foundEndFeed) {
final XMLEvent event = reader.nextEvent();
-
if (event.isStartElement()) {
if (countQName.equals(event.asStartElement().getName())) {
count(reader, event.asStartElement(), feed);
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomPropertyDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomPropertyDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomPropertyDeserializer.java
index 884d815..42d2504 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomPropertyDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomPropertyDeserializer.java
@@ -139,7 +139,7 @@ class AtomPropertyDeserializer extends AbstractAtomDealer {
}
}
- ODataPropertyType type = null;
+ final ODataPropertyType type;
if (child == null) {
type = ODataPropertyType.PRIMITIVE;
} else {
@@ -168,16 +168,19 @@ class AtomPropertyDeserializer extends AbstractAtomDealer {
property.setName(start.getName().getLocalPart());
final Attribute typeAttr = start.getAttributeByName(this.typeQName);
- if (typeAttr != null) {
- property.setType(typeAttr.getValue());
- }
Value value;
final Attribute nullAttr = start.getAttributeByName(this.nullQName);
+ final String typeAttrValue = typeAttr == null ? null : typeAttr.getValue();
+
if (nullAttr == null) {
- final EdmTypeInfo typeInfo = StringUtils.isBlank(property.getType())
+ final EdmTypeInfo typeInfo = StringUtils.isBlank(typeAttrValue)
? null
- : new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build();
+ : new EdmTypeInfo.Builder().setTypeExpression(typeAttrValue).build();
+
+ if (typeInfo != null) {
+ property.setType(typeInfo.getTypeExpression());
+ }
final ODataPropertyType propType = typeInfo == null
? guessPropertyType(reader)
@@ -207,6 +210,7 @@ class AtomPropertyDeserializer extends AbstractAtomDealer {
} else {
value = new NullValueImpl();
}
+
property.setValue(value);
return property;
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONGeoValueDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONGeoValueDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONGeoValueDeserializer.java
index eebfef3..c77369a 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONGeoValueDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONGeoValueDeserializer.java
@@ -60,7 +60,7 @@ class JSONGeoValueDeserializer {
private MultiPoint multipoint(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
final String crs) {
- MultiPoint multiPoint = null;
+ final MultiPoint multiPoint;
if (itor.hasNext()) {
final List<Point> points = new ArrayList<Point>();
@@ -79,7 +79,7 @@ class JSONGeoValueDeserializer {
private LineString lineString(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
final String crs) {
- LineString lineString = null;
+ final LineString lineString;
if (itor.hasNext()) {
final List<Point> points = new ArrayList<Point>();
@@ -98,7 +98,7 @@ class JSONGeoValueDeserializer {
private MultiLineString multiLineString(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
final String crs) {
- MultiLineString multiLineString = null;
+ final MultiLineString multiLineString;
if (itor.hasNext()) {
final List<LineString> lineStrings = new ArrayList<LineString>();
@@ -147,7 +147,7 @@ class JSONGeoValueDeserializer {
private MultiPolygon multiPolygon(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
final String crs) {
- MultiPolygon multiPolygon = null;
+ final MultiPolygon multiPolygon;
if (itor.hasNext()) {
final List<Polygon> polygons = new ArrayList<Polygon>();
@@ -166,7 +166,7 @@ class JSONGeoValueDeserializer {
private GeospatialCollection collection(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
final String crs) {
- GeospatialCollection collection = null;
+ final GeospatialCollection collection;
if (itor.hasNext()) {
final List<Geospatial> geospatials = new ArrayList<Geospatial>();
@@ -262,5 +262,4 @@ class JSONGeoValueDeserializer {
return value;
}
-
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmActionImportImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmActionImportImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmActionImportImpl.java
index 3827418..bf047af 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmActionImportImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmActionImportImpl.java
@@ -19,7 +19,6 @@
package org.apache.olingo.client.core.edm;
import org.apache.olingo.client.api.edm.xml.v4.ActionImport;
-import org.apache.olingo.client.core.edm.EdmTypeInfo;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmAction;
import org.apache.olingo.commons.api.edm.EdmActionImport;
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmOperationImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmOperationImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmOperationImpl.java
index f54d6c1..da29a68 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmOperationImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmOperationImpl.java
@@ -70,12 +70,12 @@ public abstract class EdmOperationImpl extends AbstractEdmOperation {
@Override
public FullQualifiedName getBindingParameterTypeFqn() {
- FullQualifiedName fqn = null;
+ FullQualifiedName bpfqn = null;
final EdmParameter bindingParam = getBindingParameter();
if (bindingParam != null) {
- fqn = new FullQualifiedName(bindingParam.getType().getNamespace(), bindingParam.getType().getName());
+ bpfqn = new FullQualifiedName(bindingParam.getType().getNamespace(), bindingParam.getType().getName());
}
- return fqn;
+ return bpfqn;
}
@Override
@@ -85,6 +85,6 @@ public abstract class EdmOperationImpl extends AbstractEdmOperation {
if (bindingParam != null) {
result = bindingParam.isCollection();
}
- return null;
+ return result;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmTypeInfo.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmTypeInfo.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmTypeInfo.java
index 461e829..abf1a54 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmTypeInfo.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmTypeInfo.java
@@ -23,6 +23,7 @@ import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmEnumType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.slf4j.Logger;
@@ -56,12 +57,11 @@ public class EdmTypeInfo {
}
public EdmTypeInfo build() {
- return new EdmTypeInfo(edm, typeExpression.indexOf('.') == -1
+ return new EdmTypeInfo(edm, typeExpression.indexOf('.') == -1 && StringUtils.isNotBlank(defaultNamespace)
? defaultNamespace + "." + typeExpression
: typeExpression);
}
}
-
private final Edm edm;
private final String typeExpression;
@@ -80,7 +80,6 @@ public class EdmTypeInfo {
private EdmTypeInfo(final Edm edm, final String typeExpression) {
this.edm = edm;
- this.typeExpression = typeExpression;
String baseType;
final int collStartIdx = typeExpression.indexOf("Collection(");
@@ -97,16 +96,30 @@ public class EdmTypeInfo {
baseType = typeExpression.substring(collStartIdx + 11, collEndIdx);
}
+
+ baseType = baseType.replaceAll("^#", "");
+
+ final String typeName;
+ final String namespace;
+
final int lastDotIdx = baseType.lastIndexOf('.');
if (lastDotIdx == -1) {
- throw new IllegalArgumentException("Cannot find namespace or alias in " + typeExpression);
+ namespace = EdmPrimitiveType.EDM_NAMESPACE;
+ typeName = baseType;
+ baseType = new FullQualifiedName(EdmPrimitiveType.EDM_NAMESPACE, baseType).toString();
+ } else {
+ namespace = baseType.substring(0, lastDotIdx);
+ typeName = baseType.substring(lastDotIdx + 1);
}
- final String namespace = baseType.substring(0, lastDotIdx);
- final String typeName = baseType.substring(lastDotIdx + 1);
+
if (StringUtils.isBlank(typeName)) {
throw new IllegalArgumentException("Null or empty type name in " + typeExpression);
}
+ final StringBuilder exp = new StringBuilder();
+ exp.append(baseType);
+
+ this.typeExpression = (this.collection ? exp.insert(0, "Collection(").append(")") : exp).toString();
this.fullQualifiedName = new FullQualifiedName(namespace, typeName);
try {
@@ -168,5 +181,4 @@ public class EdmTypeInfo {
public EdmEntityType getEntityType() {
return entityType;
}
-
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataBinder.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataBinder.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataBinder.java
index 2c2cdea..09c39ef 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataBinder.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataBinder.java
@@ -268,7 +268,7 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
}
final URI base = defaultBaseURI == null ? resource.getBaseURI() : defaultBaseURI;
-
+
final URI next = resource.getNext();
final ODataEntitySet entitySet = next == null
@@ -282,7 +282,7 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
for (Entry entryResource : resource.getEntries()) {
entitySet.addEntity(getODataEntity(entryResource));
}
-
+
return entitySet;
}
@@ -310,11 +310,11 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
if (StringUtils.isNotBlank(resource.getETag())) {
entity.setETag(resource.getETag());
}
-
+
if (resource.getEditLink() != null) {
entity.setEditLink(URIUtils.getURI(base, resource.getEditLink().getHref()));
}
-
+
for (Link link : resource.getAssociationLinks()) {
entity.addLink(client.getObjectFactory().newAssociationLink(link.getTitle(), base, link.getHref()));
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataDeserializer.java
index 67acc09..103f81d 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataDeserializer.java
@@ -103,5 +103,4 @@ public abstract class AbstractODataDeserializer extends AbstractJacksonTool impl
throw new IllegalArgumentException("While deserializing " + reference.getName(), e);
}
}
-
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityRetrieveTestITCase.java
----------------------------------------------------------------------
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 6637346..c69b469 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
@@ -148,7 +148,7 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase {
appendEntitySetSegment("Car").appendKeySegment(16);
final ODataRawRequest req = client.getRetrieveRequestFactory().getRawRequest(uriBuilder.build());
- req.setFormat(format.toString());
+ req.setFormat(format.toString(client.getServiceVersion()));
final ODataRawResponse res = req.execute();
assertNotNull(res);
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntitySetTestITCase.java
----------------------------------------------------------------------
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 35cc3d6..3e69aff 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
@@ -138,7 +138,7 @@ public class EntitySetTestITCase extends AbstractTestITCase {
uriBuilder.appendEntitySetSegment("Car");
final ODataRawRequest req = client.getRetrieveRequestFactory().getRawRequest(uriBuilder.build());
- req.setFormat(format.toString());
+ req.setFormat(format.toString(client.getServiceVersion()));
final ODataRawResponse res = req.execute();
assertNotNull(res);
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/QueryOptionsTestITCase.java
----------------------------------------------------------------------
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 3501482..21cf9ae 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
@@ -107,7 +107,8 @@ public class QueryOptionsTestITCase extends AbstractTestITCase {
final ODataRetrieveResponse<ODataEntity> res = req.execute();
assertNotNull(res);
- assertTrue(res.getContentType().replaceAll(" ", "").startsWith(ODataPubFormat.JSON.toString()));
+ assertTrue(res.getContentType().replaceAll(" ", "").
+ startsWith(ODataPubFormat.JSON.toString(client.getServiceVersion())));
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/AbstractTestITCase.java
----------------------------------------------------------------------
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 46a59bd..a745380 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
@@ -35,8 +35,8 @@ public abstract class AbstractTestITCase extends org.apache.olingo.client.core.i
@BeforeClass
public static void setUpODataServiceRoot() throws IOException {
- testStaticServiceRootURL = "http://localhost:9080/StaticService/V30/Static.svc";
- testLargeModelServiceRootURL = "http://localhost:9080/StaticService/V30/Static.svc/large";
+ testStaticServiceRootURL = "http://localhost:9080/StaticService/V40/Static.svc";
+ testLargeModelServiceRootURL = "http://localhost:9080/StaticService/V40/Static.svc/large";
testAuthServiceRootURL = "http://localhost:9080/DefaultService.svc";
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..9e2527a
--- /dev/null
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.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.client.core.it.v4;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetIteratorRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataRawRequest;
+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.ODataEntitySet;
+import org.apache.olingo.client.api.domain.ODataEntitySetIterator;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+import org.apache.olingo.client.api.uri.CommonURIBuilder;
+import org.apache.olingo.client.core.op.impl.ResourceFactory;
+import static org.junit.Assert.assertNotNull;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * This is the unit test class to check basic feed operations.
+ */
+public class EntitySetTestITCase extends AbstractTestITCase {
+
+ protected String getServiceRoot() {
+ return testStaticServiceRootURL;
+ }
+
+ @Test
+ public void rawRequestAsAtom() throws IOException {
+ rawRequest(ODataPubFormat.ATOM);
+ }
+
+ @Test
+ @Ignore
+ public void rawRequestAsJSON() throws IOException {
+ rawRequest(ODataPubFormat.JSON);
+ }
+
+ @Test
+ public void readODataEntitySetIteratorFromAtom() {
+ readODataEntitySetIterator(ODataPubFormat.ATOM);
+ }
+
+ @Test
+ @Ignore
+ public void readODataEntitySetIteratorFromJSON() {
+ readODataEntitySetIterator(ODataPubFormat.JSON);
+ }
+
+ @Test
+ @Ignore
+ public void readODataEntitySetIteratorFromJSONFullMeta() {
+ readODataEntitySetIterator(ODataPubFormat.JSON_FULL_METADATA);
+ }
+
+ @Test
+ @Ignore
+ public void readODataEntitySetIteratorFromJSONNoMeta() {
+ readODataEntitySetIterator(ODataPubFormat.JSON_NO_METADATA);
+ }
+
+ @Test
+ public void readODataEntitySetWithNextFromAtom() {
+ readEntitySetWithNextLink(ODataPubFormat.ATOM);
+ }
+
+ @Test
+ @Ignore
+ public void readODataEntitySetWithNextFromJSON() {
+ readEntitySetWithNextLink(ODataPubFormat.JSON_FULL_METADATA);
+ }
+
+ private void readEntitySetWithNextLink(final ODataPubFormat format) {
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot());
+ uriBuilder.appendEntitySetSegment("People");
+
+ final ODataEntitySetRequest req = client.getRetrieveRequestFactory().getEntitySetRequest(uriBuilder.build());
+ req.setFormat(format);
+
+ final ODataRetrieveResponse<ODataEntitySet> res = req.execute();
+ final ODataEntitySet feed = res.getBody();
+
+ assertNotNull(feed);
+
+ debugFeed(client.getBinder().getFeed(feed, ResourceFactory.feedClassForFormat(
+ ODataPubFormat.ATOM == format)), "Just retrieved feed");
+
+ assertEquals(5, feed.getEntities().size());
+// assertNotNull(feed.getNext());
+
+// final URI expected = URI.create(getServiceRoot() + "/Customer?$skiptoken=-9");
+// final URI found = URIUtils.getURI(getServiceRoot(), feed.getNext().toASCIIString());
+
+// assertEquals(expected, found);
+ }
+
+ private void readODataEntitySetIterator(final ODataPubFormat format) {
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot());
+ uriBuilder.appendEntitySetSegment("People");
+
+ final ODataEntitySetIteratorRequest req =
+ client.getRetrieveRequestFactory().getEntitySetIteratorRequest(uriBuilder.build());
+ req.setFormat(format);
+
+ final ODataRetrieveResponse<ODataEntitySetIterator> res = req.execute();
+ final ODataEntitySetIterator feedIterator = res.getBody();
+
+ assertNotNull(feedIterator);
+
+ int count = 0;
+
+ while (feedIterator.hasNext()) {
+ assertNotNull(feedIterator.next());
+ count++;
+ }
+ assertEquals(5, count);
+// assertTrue(feedIterator.getNext().toASCIIString().endsWith("Customer?$skiptoken=-9"));
+ }
+
+ private void rawRequest(final ODataPubFormat format) {
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot());
+ 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 ODataEntitySet entitySet = res.getBodyAs(ODataEntitySet.class);
+ assertNotNull(entitySet);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/Edm.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/Edm.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/Edm.java
index c7aeff0..32e6fc8 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/Edm.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/Edm.java
@@ -26,92 +26,93 @@ import java.util.List;
* Interface representing a Entity Data Model as described in the Conceptual Schema Definition.
*/
public interface Edm {
-
- /**
- * This method DOES NOT support lazy loading. All schemas are loaded completely!
- * @return all schemas defined for this EDM
- */
- List<EdmSchema> getSchemas();
- /**
- * Get entity container by full qualified name.
- * <br/>
- * See {@link EdmEntityContainer} for more information.
- *
- * @param name
- * @return {@link EdmEntityContainer}
- */
- EdmEntityContainer getEntityContainer(FullQualifiedName name);
+ /**
+ * This method DOES NOT support lazy loading. All schemas are loaded completely!
+ *
+ * @return all schemas defined for this EDM
+ */
+ List<EdmSchema> getSchemas();
- /**
- * Get enum type by full qualified name.
- * <br/>
- * See {@link EdmEnumType} for more information
- *
- * @param name
- * @return {@link EdmEnumType}
- */
- EdmEnumType getEnumType(FullQualifiedName name);
+ /**
+ * Get entity container by full qualified name.
+ * <br/>
+ * See {@link EdmEntityContainer} for more information.
+ *
+ * @param name
+ * @return {@link EdmEntityContainer}
+ */
+ EdmEntityContainer getEntityContainer(FullQualifiedName name);
- /**
- * Get a type definition by full qualified name.
- * <br/>
- * See {@link EdmTypeDefinition} for more information
- *
- * @param name
- * @return {@link EdmTypeDefinition}
- */
- EdmTypeDefinition getTypeDefinition(FullQualifiedName name);
+ /**
+ * Get enum type by full qualified name.
+ * <br/>
+ * See {@link EdmEnumType} for more information
+ *
+ * @param name
+ * @return {@link EdmEnumType}
+ */
+ EdmEnumType getEnumType(FullQualifiedName name);
- /**
- * Get entity type by full qualified name.
- * <br/>
- * See {@link EdmEntityType} for more information.
- *
- * @param name
- * @return {@link EdmEntityType}
- */
- EdmEntityType getEntityType(FullQualifiedName name);
+ /**
+ * Get a type definition by full qualified name.
+ * <br/>
+ * See {@link EdmTypeDefinition} for more information
+ *
+ * @param name
+ * @return {@link EdmTypeDefinition}
+ */
+ EdmTypeDefinition getTypeDefinition(FullQualifiedName name);
- /**
- * Get complex type by full qualified name..
- * <br/>
- * See {@link EdmComplexType} for more information.
- *
- * @param name
- * @return {@link EdmComplexType}
- */
- EdmComplexType getComplexType(FullQualifiedName name);
+ /**
+ * Get entity type by full qualified name.
+ * <br/>
+ * See {@link EdmEntityType} for more information.
+ *
+ * @param name
+ * @return {@link EdmEntityType}
+ */
+ EdmEntityType getEntityType(FullQualifiedName name);
- /**
- * Get Action by full qualified name and binding parameter type.
- *
- * @param actionName must not be null
- * @param bindingParameterTypeName may be null if it is an unbound action
- * @param isBindingParameterCollection may be null if it is an unbound action
- * @return {@link EdmAction}
- */
- EdmAction getAction(FullQualifiedName actionName, FullQualifiedName bindingParameterTypeName,
- Boolean isBindingParameterCollection);
+ /**
+ * Get complex type by full qualified name..
+ * <br/>
+ * See {@link EdmComplexType} for more information.
+ *
+ * @param name
+ * @return {@link EdmComplexType}
+ */
+ EdmComplexType getComplexType(FullQualifiedName name);
- /**
- * Get Function by full qualified name and binding parameter type and binding parameter names.
- *
- * @param functionName
- * @param bindingParameterTypeName may be null if it is an unbound function
- * @param isBindingParameterCollection may be null if it is an unbound function
- * @param parameterNames may be null if it is an unbound function
- * @return {@link EdmFunction}
- */
- EdmFunction getFunction(FullQualifiedName functionName, FullQualifiedName bindingParameterTypeName,
- Boolean isBindingParameterCollection, List<String> parameterNames);
+ /**
+ * Get Action by full qualified name and binding parameter type.
+ *
+ * @param actionName must not be null
+ * @param bindingParameterTypeName may be null if it is an unbound action
+ * @param isBindingParameterCollection may be null if it is an unbound action
+ * @return {@link EdmAction}
+ */
+ EdmAction getAction(FullQualifiedName actionName, FullQualifiedName bindingParameterTypeName,
+ Boolean isBindingParameterCollection);
- /**
- * Get service metadata.
- * <br/>
- * See {@link EdmServiceMetadata} for more information.
- *
- * @return {@link EdmServiceMetadata}
- */
- EdmServiceMetadata getServiceMetadata();
+ /**
+ * Get Function by full qualified name and binding parameter type and binding parameter names.
+ *
+ * @param functionName
+ * @param bindingParameterTypeName may be null if it is an unbound function
+ * @param isBindingParameterCollection may be null if it is an unbound function
+ * @param parameterNames may be null if it is an unbound function
+ * @return {@link EdmFunction}
+ */
+ EdmFunction getFunction(FullQualifiedName functionName, FullQualifiedName bindingParameterTypeName,
+ Boolean isBindingParameterCollection, List<String> parameterNames);
+
+ /**
+ * Get service metadata.
+ * <br/>
+ * See {@link EdmServiceMetadata} for more information.
+ *
+ * @return {@link EdmServiceMetadata}
+ */
+ EdmServiceMetadata getServiceMetadata();
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmActionImport.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmActionImport.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmActionImport.java
index 428fbdf..a302b9e 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmActionImport.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmActionImport.java
@@ -23,5 +23,5 @@ package org.apache.olingo.commons.api.edm;
*/
public interface EdmActionImport extends EdmOperationImport {
- EdmAction getAction();
+ EdmAction getAction();
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java
index f50d400..d637814 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java
@@ -40,8 +40,6 @@ public enum ODataServiceVersion {
public static final String NS_METADATA = "metadata";
- public static final String NS_DATA = "data";
-
public static final String NS_SCHEME = "scheme";
public static final String NAVIGATION_LINK_REL = "navigationLinkRel";
@@ -70,8 +68,11 @@ public enum ODataServiceVersion {
{
put(NS_METADATA, "http://docs.oasis-open.org/odata/ns/metadata");
- put(NS_DATA, "http://docs.oasis-open.org/odata/ns/data");
+ put(NS_DATASERVICES, "http://docs.oasis-open.org/odata/ns/data");
put(NS_SCHEME, "http://docs.oasis-open.org/odata/ns/scheme");
+ put(NAVIGATION_LINK_REL, "http://docs.oasis-open.org/odata/ns/related/");
+ put(ASSOCIATION_LINK_REL, "http://docs.oasis-open.org/odata/ns/relatedlinks/");
+ put(MEDIA_EDIT_LINK_REL, "http://docs.oasis-open.org/odata/ns/edit-media/");
}
});
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmComplexType.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmComplexType.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmComplexType.java
index 346eb2e..732f29f 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmComplexType.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmComplexType.java
@@ -27,24 +27,29 @@ import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
public abstract class AbstractEdmComplexType extends AbstractEdmStructuredType implements EdmComplexType {
- public AbstractEdmComplexType(final Edm edm, final FullQualifiedName fqn, final FullQualifiedName baseTypeName) {
- super(edm, fqn, EdmTypeKind.COMPLEX, baseTypeName);
- }
+ public AbstractEdmComplexType(
+ final Edm edm,
+ final FullQualifiedName fqn,
+ final FullQualifiedName baseTypeName) {
+ super(edm, fqn, EdmTypeKind.COMPLEX, baseTypeName);
+ }
- @Override
- protected EdmStructuredType buildBaseType(final FullQualifiedName baseTypeName) {
- EdmComplexType baseType = null;
- if (baseTypeName != null) {
- baseType = edm.getComplexType(baseTypeName);
- if (baseType == null) {
- throw new EdmException("Can't find base type with name: " + baseTypeName + " for complex type: " + getName());
- }
+ @Override
+ protected EdmStructuredType buildBaseType(final FullQualifiedName baseTypeName) {
+ // TODO: check for comment
+ EdmComplexType baseType = null;
+ if (baseTypeName != null) {
+ baseType = edm.getComplexType(baseTypeName);
+ if (baseType == null) {
+ throw new EdmException("Can't find base type with name: " + baseTypeName + " for complex type: "
+ + getName());
+ }
+ }
+ return baseType;
}
- return baseType;
- }
- @Override
- public EdmComplexType getBaseType() {
- return (EdmComplexType) baseType;
- }
+ @Override
+ public EdmComplexType getBaseType() {
+ return (EdmComplexType) baseType;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmEntityContainer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmEntityContainer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmEntityContainer.java
index aba62ba..41eb368 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmEntityContainer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmEntityContainer.java
@@ -33,119 +33,123 @@ import org.apache.olingo.commons.api.edm.FullQualifiedName;
public abstract class AbstractEdmEntityContainer extends EdmNamedImpl implements EdmEntityContainer {
- protected final FullQualifiedName entityContainerName;
+ protected final FullQualifiedName entityContainerName;
- protected final Map<String, EdmSingleton> singletons = new HashMap<String, EdmSingleton>();
- private boolean allSingletonsLoaded = false;
+ protected final Map<String, EdmSingleton> singletons = new HashMap<String, EdmSingleton>();
- protected final Map<String, EdmEntitySet> entitySets = new HashMap<String, EdmEntitySet>();
- private boolean allEntitySetsLoaded = false;
+ private boolean allSingletonsLoaded = false;
- protected final Map<String, EdmActionImport> actionImports = new HashMap<String, EdmActionImport>();
- private boolean allActionImportsLoaded = false;
+ protected final Map<String, EdmEntitySet> entitySets = new HashMap<String, EdmEntitySet>();
- protected final Map<String, EdmFunctionImport> functionImports = new HashMap<String, EdmFunctionImport>();
- private boolean allFunctionImportsLoaded = false;
+ private boolean allEntitySetsLoaded = false;
- public AbstractEdmEntityContainer(final Edm edm, final FullQualifiedName entityContainerName) {
- super(edm, entityContainerName.getName());
- this.entityContainerName = entityContainerName;
- }
+ protected final Map<String, EdmActionImport> actionImports = new HashMap<String, EdmActionImport>();
- @Override
- public String getNamespace() {
- return entityContainerName.getNamespace();
- }
+ private boolean allActionImportsLoaded = false;
- protected abstract EdmSingleton createSingleton(String singletonName);
+ protected final Map<String, EdmFunctionImport> functionImports = new HashMap<String, EdmFunctionImport>();
- @Override
- public EdmSingleton getSingleton(final String singletonName) {
- EdmSingleton singleton = singletons.get(singletonName);
- if (singleton == null) {
- singleton = createSingleton(singletonName);
- singletons.put(singletonName, singleton);
+ private boolean allFunctionImportsLoaded = false;
+
+ public AbstractEdmEntityContainer(final Edm edm, final FullQualifiedName entityContainerName) {
+ super(edm, entityContainerName.getName());
+ this.entityContainerName = entityContainerName;
+ }
+
+ @Override
+ public String getNamespace() {
+ return entityContainerName.getNamespace();
}
- return singleton;
- }
- protected abstract EdmEntitySet createEntitySet(String entitySetName);
+ protected abstract EdmSingleton createSingleton(String singletonName);
- @Override
- public EdmEntitySet getEntitySet(final String entitySetName) {
- EdmEntitySet entitySet = entitySets.get(entitySetName);
- if (entitySet == null) {
- entitySet = createEntitySet(entitySetName);
- entitySets.put(entitySetName, entitySet);
+ @Override
+ public EdmSingleton getSingleton(final String singletonName) {
+ EdmSingleton singleton = singletons.get(singletonName);
+ if (singleton == null) {
+ singleton = createSingleton(singletonName);
+ singletons.put(singletonName, singleton);
+ }
+ return singleton;
}
- return entitySet;
- }
- protected abstract EdmActionImport createActionImport(String actionImportName);
+ protected abstract EdmEntitySet createEntitySet(String entitySetName);
- @Override
- public EdmActionImport getActionImport(final String actionImportName) {
- EdmActionImport actionImport = actionImports.get(actionImportName);
- if (actionImport == null) {
- actionImport = createActionImport(actionImportName);
- actionImports.put(actionImportName, actionImport);
+ @Override
+ public EdmEntitySet getEntitySet(final String entitySetName) {
+ EdmEntitySet entitySet = entitySets.get(entitySetName);
+ if (entitySet == null) {
+ entitySet = createEntitySet(entitySetName);
+ entitySets.put(entitySetName, entitySet);
+ }
+ return entitySet;
}
- return actionImport;
- }
- protected abstract EdmFunctionImport createFunctionImport(String functionImportName);
+ protected abstract EdmActionImport createActionImport(String actionImportName);
- @Override
- public EdmFunctionImport getFunctionImport(final String functionImportName) {
- EdmFunctionImport functionImport = functionImports.get(functionImportName);
- if (functionImport == null) {
- functionImport = createFunctionImport(functionImportName);
- functionImports.put(functionImportName, functionImport);
+ @Override
+ public EdmActionImport getActionImport(final String actionImportName) {
+ EdmActionImport actionImport = actionImports.get(actionImportName);
+ if (actionImport == null) {
+ actionImport = createActionImport(actionImportName);
+ actionImports.put(actionImportName, actionImport);
+ }
+ return actionImport;
}
- return functionImport;
- }
-
- @Override
- public List<EdmEntitySet> getEntitySets() {
- if (!allEntitySetsLoaded) {
- loadAllEntitySets();
- allEntitySetsLoaded = true;
+
+ protected abstract EdmFunctionImport createFunctionImport(String functionImportName);
+
+ @Override
+ public EdmFunctionImport getFunctionImport(final String functionImportName) {
+ EdmFunctionImport functionImport = functionImports.get(functionImportName);
+ if (functionImport == null) {
+ functionImport = createFunctionImport(functionImportName);
+ functionImports.put(functionImportName, functionImport);
+ }
+ return functionImport;
+ }
+
+ @Override
+ public List<EdmEntitySet> getEntitySets() {
+ if (!allEntitySetsLoaded) {
+ loadAllEntitySets();
+ allEntitySetsLoaded = true;
+ }
+ return new ArrayList<EdmEntitySet>(entitySets.values());
}
- return new ArrayList<EdmEntitySet>(entitySets.values());
- }
- protected abstract void loadAllEntitySets();
+ protected abstract void loadAllEntitySets();
- @Override
- public List<EdmFunctionImport> getFunctionImports() {
- if (!allFunctionImportsLoaded) {
- loadAllFunctionImports();
- allFunctionImportsLoaded = true;
+ @Override
+ public List<EdmFunctionImport> getFunctionImports() {
+ if (!allFunctionImportsLoaded) {
+ loadAllFunctionImports();
+ allFunctionImportsLoaded = true;
+ }
+ return new ArrayList<EdmFunctionImport>(functionImports.values());
}
- return new ArrayList<EdmFunctionImport>(functionImports.values());
- }
- protected abstract void loadAllFunctionImports();
+ protected abstract void loadAllFunctionImports();
- @Override
- public List<EdmSingleton> getSingletons() {
- if (!allSingletonsLoaded) {
- loadAllSingletons();
- allSingletonsLoaded = true;
+ @Override
+ public List<EdmSingleton> getSingletons() {
+ if (!allSingletonsLoaded) {
+ loadAllSingletons();
+ allSingletonsLoaded = true;
+ }
+ return new ArrayList<EdmSingleton>(singletons.values());
}
- return new ArrayList<EdmSingleton>(singletons.values());
- }
- protected abstract void loadAllSingletons();
+ protected abstract void loadAllSingletons();
- @Override
- public List<EdmActionImport> getActionImports() {
- if (!allActionImportsLoaded) {
- loadAllActionImports();
- allActionImportsLoaded = true;
+ @Override
+ public List<EdmActionImport> getActionImports() {
+ if (!allActionImportsLoaded) {
+ loadAllActionImports();
+ allActionImportsLoaded = true;
+ }
+ return new ArrayList<EdmActionImport>(actionImports.values());
}
- return new ArrayList<EdmActionImport>(actionImports.values());
- }
- protected abstract void loadAllActionImports();
+ protected abstract void loadAllActionImports();
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmOperation.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmOperation.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmOperation.java
index b848540..3c2f894 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmOperation.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmOperation.java
@@ -35,80 +35,83 @@ import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
public abstract class AbstractEdmOperation extends EdmTypeImpl implements EdmOperation {
- private final Map<String, EdmParameter> parameters = new LinkedHashMap<String, EdmParameter>();
+ private final Map<String, EdmParameter> parameters = new LinkedHashMap<String, EdmParameter>();
- private String entitySetPath;
+ private String entitySetPath;
- private boolean isBound;
+ private boolean isBound;
- private EdmReturnType returnType;
+ private EdmReturnType returnType;
- private List<String> parameterNames;
+ private List<String> parameterNames;
- protected AbstractEdmOperation(final Edm edm, final FullQualifiedName fqn, final EdmTypeKind kind) {
- super(edm, fqn, kind);
- }
+ protected AbstractEdmOperation(
+ final Edm edm,
+ final FullQualifiedName fqn,
+ final EdmTypeKind kind) {
+ super(edm, fqn, kind);
+ }
+
+ protected void setParameters(final List<EdmParameter> _parameters) {
+ for (EdmParameter parameter : _parameters) {
+ parameters.put(parameter.getName(), parameter);
+ }
+ }
+
+ protected void setEntitySetPath(final String entitySetPath) {
+ this.entitySetPath = entitySetPath;
+ }
+
+ protected void setIsBound(final boolean isBound) {
+ this.isBound = isBound;
+ }
- protected void setParameters(final List<EdmParameter> _parameters) {
- for (EdmParameter parameter : _parameters) {
- parameters.put(parameter.getName(), parameter);
+ protected void setReturnType(final EdmReturnType returnType) {
+ this.returnType = returnType;
}
- }
-
- protected void setEntitySetPath(final String entitySetPath) {
- this.entitySetPath = entitySetPath;
- }
-
- protected void setIsBound(final boolean isBound) {
- this.isBound = isBound;
- }
-
- protected void setReturnType(final EdmReturnType returnType) {
- this.returnType = returnType;
- }
-
- @Override
- public EdmParameter getParameter(final String name) {
- return parameters.get(name);
- }
-
- @Override
- public List<String> getParameterNames() {
- if (parameterNames == null) {
- parameterNames = new ArrayList<String>(parameters.size());
- for (String parameterName : parameters.keySet()) {
- parameterNames.add(parameterName);
- }
+
+ @Override
+ public EdmParameter getParameter(final String name) {
+ return parameters.get(name);
}
- return parameterNames;
- }
-
- @Override
- public EdmEntitySet getReturnedEntitySet(final EdmEntitySet bindingParameterEntitySet) {
- EdmEntitySet returnedEntitySet = null;
- if (bindingParameterEntitySet != null && entitySetPath != null) {
- final EdmBindingTarget relatedBindingTarget = bindingParameterEntitySet.
- getRelatedBindingTarget(entitySetPath);
- if (relatedBindingTarget == null) {
- throw new EdmException("Cannot find entity set with path: " + entitySetPath);
- }
- if (relatedBindingTarget instanceof EdmEntitySet) {
- returnedEntitySet = (EdmEntitySet) relatedBindingTarget;
- } else {
- throw new EdmException("BindingTarget with name: " + relatedBindingTarget.getName() + " must be an entity set");
- }
+
+ @Override
+ public List<String> getParameterNames() {
+ if (parameterNames == null) {
+ parameterNames = new ArrayList<String>(parameters.size());
+ for (String parameterName : parameters.keySet()) {
+ parameterNames.add(parameterName);
+ }
+ }
+ return parameterNames;
}
- return returnedEntitySet;
- }
- @Override
- public EdmReturnType getReturnType() {
- return returnType;
- }
+ @Override
+ public EdmEntitySet getReturnedEntitySet(final EdmEntitySet bindingParameterEntitySet) {
+ EdmEntitySet returnedEntitySet = null;
+ if (bindingParameterEntitySet != null && entitySetPath != null) {
+ final EdmBindingTarget relatedBindingTarget = bindingParameterEntitySet.
+ getRelatedBindingTarget(entitySetPath);
+ if (relatedBindingTarget == null) {
+ throw new EdmException("Cannot find entity set with path: " + entitySetPath);
+ }
+ if (relatedBindingTarget instanceof EdmEntitySet) {
+ returnedEntitySet = (EdmEntitySet) relatedBindingTarget;
+ } else {
+ throw new EdmException("BindingTarget with name: " + relatedBindingTarget.getName()
+ + " must be an entity set");
+ }
+ }
+ return returnedEntitySet;
+ }
- @Override
- public boolean isBound() {
- return isBound;
- }
+ @Override
+ public EdmReturnType getReturnType() {
+ return returnType;
+ }
+ @Override
+ public boolean isBound() {
+ return isBound;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmOperationImport.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmOperationImport.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmOperationImport.java
index 96aa49f..fe81533 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmOperationImport.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmOperationImport.java
@@ -27,37 +27,40 @@ import org.apache.olingo.commons.api.edm.Target;
public abstract class AbstractEdmOperationImport extends EdmNamedImpl implements EdmOperationImport {
- protected final EdmEntityContainer container;
-
- private final Target entitySet;
-
- private EdmEntitySet returnedEntitySet;
-
- public AbstractEdmOperationImport(final Edm edm, final EdmEntityContainer container, final String name,
- final Target entitySet) {
-
- super(edm, name);
- this.container = container;
- this.entitySet = entitySet;
- }
-
- @Override
- public EdmEntitySet getReturnedEntitySet() {
- if (entitySet != null && returnedEntitySet == null) {
- EdmEntityContainer entityContainer = edm.getEntityContainer(entitySet.getEntityContainer());
- if (entityContainer == null) {
- throw new EdmException("Can´t find entity container with name: " + entitySet.getEntityContainer());
- }
- returnedEntitySet = entityContainer.getEntitySet(entitySet.getTargetName());
- if (returnedEntitySet == null) {
- throw new EdmException("Can´t find entity set with name: " + entitySet.getTargetName());
- }
+ protected final EdmEntityContainer container;
+
+ private final Target entitySet;
+
+ private EdmEntitySet returnedEntitySet;
+
+ public AbstractEdmOperationImport(
+ final Edm edm,
+ final EdmEntityContainer container,
+ final String name,
+ final Target entitySet) {
+
+ super(edm, name);
+ this.container = container;
+ this.entitySet = entitySet;
}
- return returnedEntitySet;
- }
- @Override
- public EdmEntityContainer getEntityContainer() {
- return container;
- }
+ @Override
+ public EdmEntitySet getReturnedEntitySet() {
+ if (entitySet != null && returnedEntitySet == null) {
+ EdmEntityContainer entityContainer = edm.getEntityContainer(entitySet.getEntityContainer());
+ if (entityContainer == null) {
+ throw new EdmException("Can´t find entity container with name: " + entitySet.getEntityContainer());
+ }
+ returnedEntitySet = entityContainer.getEntitySet(entitySet.getTargetName());
+ if (returnedEntitySet == null) {
+ throw new EdmException("Can´t find entity set with name: " + entitySet.getTargetName());
+ }
+ }
+ return returnedEntitySet;
+ }
+
+ @Override
+ public EdmEntityContainer getEntityContainer() {
+ return container;
+ }
}
[8/8] git commit: [OLINGO-175,
OLINGO-205] provided (V4) next link check
Posted by fm...@apache.org.
[OLINGO-175, OLINGO-205] provided (V4) next link check
Project: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/commit/f0edb508
Tree: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/tree/f0edb508
Diff: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/diff/f0edb508
Branch: refs/heads/olingo200
Commit: f0edb5081363d9e9f9ab0192541a943325e12dbb
Parents: 5b5576f
Author: fmartelli <fa...@gmail.com>
Authored: Mon Mar 24 10:38:32 2014 +0100
Committer: fmartelli <fa...@gmail.com>
Committed: Mon Mar 24 10:38:32 2014 +0100
----------------------------------------------------------------------
fit/src/main/resources/v4/People/feed.full.json | 3 ++-
fit/src/main/resources/v4/People/feed.xml | 1 +
.../olingo/client/core/it/v4/EntitySetTestITCase.java | 13 ++++++++-----
3 files changed, 11 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/f0edb508/fit/src/main/resources/v4/People/feed.full.json
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/v4/People/feed.full.json b/fit/src/main/resources/v4/People/feed.full.json
index 0c998f6..a0e3db0 100644
--- a/fit/src/main/resources/v4/People/feed.full.json
+++ b/fit/src/main/resources/v4/People/feed.full.json
@@ -328,5 +328,6 @@
"target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
}
}
- ]
+ ],
+ "odata.nextLink": "People?$skiptoken=5"
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/f0edb508/fit/src/main/resources/v4/People/feed.xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/v4/People/feed.xml b/fit/src/main/resources/v4/People/feed.xml
index f79bb49..609c669 100644
--- a/fit/src/main/resources/v4/People/feed.xml
+++ b/fit/src/main/resources/v4/People/feed.xml
@@ -215,4 +215,5 @@
</m:properties>
</content>
</entry>
+ <link rel="next" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People?$skiptoken=5"/>
</feed>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/f0edb508/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
----------------------------------------------------------------------
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 e3e8a1e..8455ecd 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
@@ -20,8 +20,10 @@ package org.apache.olingo.client.core.it.v4;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import java.io.IOException;
+import java.net.URI;
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetIteratorRequest;
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
import org.apache.olingo.client.api.communication.request.retrieve.ODataRawRequest;
@@ -29,6 +31,7 @@ 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.CommonURIBuilder;
+import org.apache.olingo.client.core.uri.URIUtils;
import org.apache.olingo.commons.api.domain.ODataEntitySet;
import org.apache.olingo.commons.api.format.ODataPubFormat;
import org.apache.olingo.commons.core.op.ResourceFactory;
@@ -105,12 +108,12 @@ public class EntitySetTestITCase extends AbstractTestITCase {
ODataPubFormat.ATOM == format)), "Just retrieved feed");
assertEquals(5, feed.getEntities().size());
-// assertNotNull(feed.getNext());
+ assertNotNull(feed.getNext());
-// final URI expected = URI.create(getServiceRoot() + "/Customer?$skiptoken=-9");
-// final URI found = URIUtils.getURI(getServiceRoot(), feed.getNext().toASCIIString());
+ final URI expected = URI.create(getServiceRoot() + "/People?$skiptoken=5");
+ final URI found = URIUtils.getURI(getServiceRoot(), feed.getNext().toASCIIString());
-// assertEquals(expected, found);
+ assertEquals(expected, found);
}
private void readODataEntitySetIterator(final ODataPubFormat format) {
@@ -133,7 +136,7 @@ public class EntitySetTestITCase extends AbstractTestITCase {
count++;
}
assertEquals(5, count);
-// assertTrue(feedIterator.getNext().toASCIIString().endsWith("Customer?$skiptoken=-9"));
+ assertTrue(feedIterator.getNext().toASCIIString().endsWith("People?$skiptoken=5"));
}
private void rawRequest(final ODataPubFormat format) {
[3/8] [OLINGO-205,
OLINGO-200] provided atom v4 deserialization for entity type/set +
entity set request
Posted by fm...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/resources/v4/People/feed.full.json
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/v4/People/feed.full.json b/fit/src/main/resources/v4/People/feed.full.json
new file mode 100644
index 0000000..0c998f6
--- /dev/null
+++ b/fit/src/main/resources/v4/People/feed.full.json
@@ -0,0 +1,332 @@
+{
+ "@odata.context": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#People",
+ "value":
+ [
+ {
+ "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Customer",
+ "@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)",
+ "@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer",
+ "PersonID": 1,
+ "FirstName": "Bob",
+ "LastName": "Cat",
+ "MiddleName": null,
+ "HomeAddress":
+ {
+ "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.HomeAddress",
+ "Street": "1 Microsoft Way",
+ "City": "London",
+ "PostalCode": "98052",
+ "FamilyName": "Cats"
+ },
+ "Home@odata.type": "#GeographyPoint",
+ "Home":
+ {
+ "type": "Point",
+ "coordinates":
+ [
+ 23.1,
+ 32.1
+ ],
+ "crs":
+ {
+ "type": "name",
+ "properties":
+ {
+ "name": "EPSG:4326"
+ }
+ }
+ },
+ "Numbers@odata.type": "#Collection(String)",
+ "Numbers":
+ [
+ "111-111-1111"
+ ],
+ "Emails@odata.type": "#Collection(String)",
+ "Emails":
+ [
+ "abc@abc.com"
+ ],
+ "City": "London",
+ "Birthday@odata.type": "#DateTimeOffset",
+ "Birthday": "1957-04-03T00:00:00Z",
+ "TimeBetweenLastTwoOrders@odata.type": "#Duration",
+ "TimeBetweenLastTwoOrders": "PT0.0000001S",
+ "Parent@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Parent/$ref",
+ "Parent@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Parent",
+ "Orders@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders/$ref",
+ "Orders@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders",
+ "Company@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company/$ref",
+ "Company@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company",
+ "#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress":
+ {
+ "title": "Microsoft.Test.OData.Services.ODataWCFService.ResetAddress",
+ "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress"
+ },
+ "#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress":
+ {
+ "title": "Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress",
+ "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
+ }
+ },
+ {
+ "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Customer",
+ "@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)",
+ "@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer",
+ "PersonID": 2,
+ "FirstName": "Jill",
+ "LastName": "Jones",
+ "MiddleName": null,
+ "HomeAddress": null,
+ "Home@odata.type": "#GeographyPoint",
+ "Home":
+ {
+ "type": "Point",
+ "coordinates":
+ [
+ 161.8,
+ 15
+ ],
+ "crs":
+ {
+ "type": "name",
+ "properties":
+ {
+ "name": "EPSG:4326"
+ }
+ }
+ },
+ "Numbers@odata.type": "#Collection(String)",
+ "Numbers":
+ [
+ ],
+ "Emails@odata.type": "#Collection(String)",
+ "Emails":
+ [
+ ],
+ "City": "Sydney",
+ "Birthday@odata.type": "#DateTimeOffset",
+ "Birthday": "1983-01-15T00:00:00Z",
+ "TimeBetweenLastTwoOrders@odata.type": "#Duration",
+ "TimeBetweenLastTwoOrders": "PT0.0000002S",
+ "Parent@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Parent/$ref",
+ "Parent@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Parent",
+ "Orders@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders/$ref",
+ "Orders@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders",
+ "Company@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company/$ref",
+ "Company@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company",
+ "#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress":
+ {
+ "title": "Microsoft.Test.OData.Services.ODataWCFService.ResetAddress",
+ "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress"
+ },
+ "#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress":
+ {
+ "title": "Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress",
+ "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
+ }
+ },
+ {
+ "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Employee",
+ "@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)",
+ "@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee",
+ "PersonID": 3,
+ "FirstName": "Jacob",
+ "LastName": "Zip",
+ "MiddleName": null,
+ "HomeAddress":
+ {
+ "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Address",
+ "Street": "1 Microsoft Way",
+ "City": "Sydney",
+ "PostalCode": "98052"
+ },
+ "Home@odata.type": "#GeographyPoint",
+ "Home":
+ {
+ "type": "Point",
+ "coordinates":
+ [
+ 161.8,
+ 15
+ ],
+ "crs":
+ {
+ "type": "name",
+ "properties":
+ {
+ "name": "EPSG:4326"
+ }
+ }
+ },
+ "Numbers@odata.type": "#Collection(String)",
+ "Numbers":
+ [
+ "333-333-3333"
+ ],
+ "Emails@odata.type": "#Collection(String)",
+ "Emails":
+ [
+ null
+ ],
+ "DateHired@odata.type": "#DateTimeOffset",
+ "DateHired": "2010-12-13T00:00:00Z",
+ "Office@odata.type": "#GeographyPoint",
+ "Office":
+ {
+ "type": "Point",
+ "coordinates":
+ [
+ 162,
+ 15
+ ],
+ "crs":
+ {
+ "type": "name",
+ "properties":
+ {
+ "name": "EPSG:4326"
+ }
+ }
+ },
+ "Parent@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Parent/$ref",
+ "Parent@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Parent",
+ "Company@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Company/$ref",
+ "Company@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Company",
+ "#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress":
+ {
+ "title": "Microsoft.Test.OData.Services.ODataWCFService.ResetAddress",
+ "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress"
+ },
+ "#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress":
+ {
+ "title": "Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress",
+ "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
+ }
+ },
+ {
+ "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Employee",
+ "@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)",
+ "@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee",
+ "PersonID": 4,
+ "FirstName": "Elmo",
+ "LastName": "Rogers",
+ "MiddleName": null,
+ "HomeAddress": null,
+ "Home@odata.type": "#GeographyPoint",
+ "Home":
+ {
+ "type": "Point",
+ "coordinates":
+ [
+ -61.8,
+ -15
+ ],
+ "crs":
+ {
+ "type": "name",
+ "properties":
+ {
+ "name": "EPSG:4326"
+ }
+ }
+ },
+ "Numbers@odata.type": "#Collection(String)",
+ "Numbers":
+ [
+ "444-444-4444",
+ "555-555-5555",
+ "666-666-6666"
+ ],
+ "Emails@odata.type": "#Collection(String)",
+ "Emails":
+ [
+ "def@def.org",
+ "lmn@lmn.com"
+ ],
+ "DateHired@odata.type": "#DateTimeOffset",
+ "DateHired": "2008-03-27T00:00:00Z",
+ "Office@odata.type": "#GeographyPoint",
+ "Office":
+ {
+ "type": "Point",
+ "coordinates":
+ [
+ -62,
+ -15
+ ],
+ "crs":
+ {
+ "type": "name",
+ "properties":
+ {
+ "name": "EPSG:4326"
+ }
+ }
+ },
+ "Parent@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Parent/$ref",
+ "Parent@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Parent",
+ "Company@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Company/$ref",
+ "Company@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Company",
+ "#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress":
+ {
+ "title": "Microsoft.Test.OData.Services.ODataWCFService.ResetAddress",
+ "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress"
+ },
+ "#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress":
+ {
+ "title": "Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress",
+ "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
+ }
+ },
+ {
+ "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Person",
+ "@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)",
+ "@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)",
+ "PersonID": 5,
+ "FirstName": "Peter",
+ "LastName": "Bee",
+ "MiddleName": null,
+ "HomeAddress": null,
+ "Home@odata.type": "#GeographyPoint",
+ "Home":
+ {
+ "type": "Point",
+ "coordinates":
+ [
+ -261.8,
+ -16
+ ],
+ "crs":
+ {
+ "type": "name",
+ "properties":
+ {
+ "name": "EPSG:4326"
+ }
+ }
+ },
+ "Numbers@odata.type": "#Collection(String)",
+ "Numbers":
+ [
+ "555-555-5555"
+ ],
+ "Emails@odata.type": "#Collection(String)",
+ "Emails":
+ [
+ "def@test.msn"
+ ],
+ "Parent@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Parent/$ref",
+ "Parent@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Parent",
+ "#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress":
+ {
+ "title": "Microsoft.Test.OData.Services.ODataWCFService.ResetAddress",
+ "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress"
+ },
+ "#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress":
+ {
+ "title": "Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress",
+ "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
+ }
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/resources/v4/People/feed.xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/v4/People/feed.xml b/fit/src/main/resources/v4/People/feed.xml
new file mode 100644
index 0000000..f79bb49
--- /dev/null
+++ b/fit/src/main/resources/v4/People/feed.xml
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+<feed xml:base="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/"
+ xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://docs.oasis-open.org/odata/ns/data"
+ xmlns:m="http://docs.oasis-open.org/odata/ns/metadata"
+ xmlns:georss="http://www.georss.org/georss"
+ xmlns:gml="http://www.opengis.net/gml"
+ m:context="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#People">
+ <id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People</id>
+ <title />
+ <updated>2014-03-20T14:31:00Z</updated>
+ <entry>
+ <id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)</id>
+ <category term="#Microsoft.Test.OData.Services.ODataWCFService.Customer" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
+ <link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer" />
+ <link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Parent" />
+ <link rel="http://docs.oasis-open.org/odata/ns/related/Orders" type="application/atom+xml;type=feed" title="Orders" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders" />
+ <link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company" />
+ <title />
+ <updated>2014-03-20T14:31:00Z</updated>
+ <author>
+ <name />
+ </author>
+ <content type="application/xml">
+ <m:properties>
+ <d:PersonID m:type="Int32">1</d:PersonID>
+ <d:FirstName>Bob</d:FirstName>
+ <d:LastName>Cat</d:LastName>
+ <d:MiddleName m:null="true" />
+ <d:HomeAddress m:type="#Microsoft.Test.OData.Services.ODataWCFService.HomeAddress">
+ <d:Street>1 Microsoft Way</d:Street>
+ <d:City>London</d:City>
+ <d:PostalCode>98052</d:PostalCode>
+ <d:FamilyName>Cats</d:FamilyName>
+ </d:HomeAddress>
+ <d:Home m:type="GeographyPoint">
+ <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+ <gml:pos>32.1 23.1</gml:pos>
+ </gml:Point>
+ </d:Home>
+ <d:Numbers m:type="#Collection(String)">
+ <m:element>111-111-1111</m:element>
+ </d:Numbers>
+ <d:Emails m:type="#Collection(String)">
+ <m:element>abc@abc.com</m:element>
+ </d:Emails>
+ <d:City>London</d:City>
+ <d:Birthday m:type="DateTimeOffset">1957-04-03T00:00:00Z</d:Birthday>
+ <d:TimeBetweenLastTwoOrders m:type="Duration">PT0.0000001S</d:TimeBetweenLastTwoOrders>
+ </m:properties>
+ </content>
+ </entry>
+ <entry>
+ <id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)</id>
+ <category term="#Microsoft.Test.OData.Services.ODataWCFService.Customer" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
+ <link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer" />
+ <link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Parent" />
+ <link rel="http://docs.oasis-open.org/odata/ns/related/Orders" type="application/atom+xml;type=feed" title="Orders" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders" />
+ <link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company" />
+ <title />
+ <updated>2014-03-20T14:31:00Z</updated>
+ <author>
+ <name />
+ </author>
+ <content type="application/xml">
+ <m:properties>
+ <d:PersonID m:type="Int32">2</d:PersonID>
+ <d:FirstName>Jill</d:FirstName>
+ <d:LastName>Jones</d:LastName>
+ <d:MiddleName m:null="true" />
+ <d:HomeAddress m:null="true" />
+ <d:Home m:type="GeographyPoint">
+ <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+ <gml:pos>15 161.8</gml:pos>
+ </gml:Point>
+ </d:Home>
+ <d:Numbers m:type="#Collection(String)" />
+ <d:Emails m:type="#Collection(String)" />
+ <d:City>Sydney</d:City>
+ <d:Birthday m:type="DateTimeOffset">1983-01-15T00:00:00Z</d:Birthday>
+ <d:TimeBetweenLastTwoOrders m:type="Duration">PT0.0000002S</d:TimeBetweenLastTwoOrders>
+ </m:properties>
+ </content>
+ </entry>
+ <entry>
+ <id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)</id>
+ <category term="#Microsoft.Test.OData.Services.ODataWCFService.Employee" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
+ <link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee" />
+ <link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Parent" />
+ <link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Company" />
+ <title />
+ <updated>2014-03-20T14:31:00Z</updated>
+ <author>
+ <name />
+ </author>
+ <content type="application/xml">
+ <m:properties>
+ <d:PersonID m:type="Int32">3</d:PersonID>
+ <d:FirstName>Jacob</d:FirstName>
+ <d:LastName>Zip</d:LastName>
+ <d:MiddleName m:null="true" />
+ <d:HomeAddress m:type="#Microsoft.Test.OData.Services.ODataWCFService.Address">
+ <d:Street>1 Microsoft Way</d:Street>
+ <d:City>Sydney</d:City>
+ <d:PostalCode>98052</d:PostalCode>
+ </d:HomeAddress>
+ <d:Home m:type="GeographyPoint">
+ <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+ <gml:pos>15 161.8</gml:pos>
+ </gml:Point>
+ </d:Home>
+ <d:Numbers m:type="#Collection(String)">
+ <m:element>333-333-3333</m:element>
+ </d:Numbers>
+ <d:Emails m:type="#Collection(String)">
+ <m:element m:null="true" />
+ </d:Emails>
+ <d:DateHired m:type="DateTimeOffset">2010-12-13T00:00:00Z</d:DateHired>
+ <d:Office m:type="GeographyPoint">
+ <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+ <gml:pos>15 162</gml:pos>
+ </gml:Point>
+ </d:Office>
+ </m:properties>
+ </content>
+ </entry>
+ <entry>
+ <id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)</id>
+ <category term="#Microsoft.Test.OData.Services.ODataWCFService.Employee" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
+ <link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee" />
+ <link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Parent" />
+ <link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Company" />
+ <title />
+ <updated>2014-03-20T14:31:00Z</updated>
+ <author>
+ <name />
+ </author>
+ <content type="application/xml">
+ <m:properties>
+ <d:PersonID m:type="Int32">4</d:PersonID>
+ <d:FirstName>Elmo</d:FirstName>
+ <d:LastName>Rogers</d:LastName>
+ <d:MiddleName m:null="true" />
+ <d:HomeAddress m:null="true" />
+ <d:Home m:type="GeographyPoint">
+ <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+ <gml:pos>-15 -61.8</gml:pos>
+ </gml:Point>
+ </d:Home>
+ <d:Numbers m:type="#Collection(String)">
+ <m:element>444-444-4444</m:element>
+ <m:element>555-555-5555</m:element>
+ <m:element>666-666-6666</m:element>
+ </d:Numbers>
+ <d:Emails m:type="#Collection(String)">
+ <m:element>def@def.org</m:element>
+ <m:element>lmn@lmn.com</m:element>
+ </d:Emails>
+ <d:DateHired m:type="DateTimeOffset">2008-03-27T00:00:00Z</d:DateHired>
+ <d:Office m:type="GeographyPoint">
+ <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+ <gml:pos>-15 -62</gml:pos>
+ </gml:Point>
+ </d:Office>
+ </m:properties>
+ </content>
+ </entry>
+ <entry>
+ <id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)</id>
+ <category term="#Microsoft.Test.OData.Services.ODataWCFService.Person" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
+ <link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)" />
+ <link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Parent" />
+ <title />
+ <updated>2014-03-20T14:31:00Z</updated>
+ <author>
+ <name />
+ </author>
+ <content type="application/xml">
+ <m:properties>
+ <d:PersonID m:type="Int32">5</d:PersonID>
+ <d:FirstName>Peter</d:FirstName>
+ <d:LastName>Bee</d:LastName>
+ <d:MiddleName m:null="true" />
+ <d:HomeAddress m:null="true" />
+ <d:Home m:type="GeographyPoint">
+ <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+ <gml:pos>-16 -261.8</gml:pos>
+ </gml:Point>
+ </d:Home>
+ <d:Numbers m:type="#Collection(String)">
+ <m:element>555-555-5555</m:element>
+ </d:Numbers>
+ <d:Emails m:type="#Collection(String)">
+ <m:element>def@test.msn</m:element>
+ </d:Emails>
+ </m:properties>
+ </content>
+ </entry>
+</feed>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/resources/v4/metadata.xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/v4/metadata.xml b/fit/src/main/resources/v4/metadata.xml
index ae13a4e..b51bf0f 100644
--- a/fit/src/main/resources/v4/metadata.xml
+++ b/fit/src/main/resources/v4/metadata.xml
@@ -21,499 +21,418 @@
-->
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
<edmx:DataServices>
- <Schema Namespace="NorthwindModel" xmlns="http://docs.oasis-open.org/odata/ns/edm">
- <!-- EnumType with values -->
- <EnumType Name="FileAccess" UnderlyingType="Edm.Int32" IsFlags="true">
- <Member Name="Read" Value="1" />
- <Member Name="Write" Value="2" />
- <Member Name="Create" Value="4" />
- <Member Name="Delete" Value="8" />
- </EnumType>
- <!-- EnumType without any values -->
- <EnumType Name="ShippingMethod">
- <Member Name="FirstClass" />
- <Member Name="TwoDay" />
- <Member Name="Overnight" />
- </EnumType>
- <!-- ComplexType -->
- <ComplexType Name="Dimensions">
- <Property Name="Height" Nullable="false" Type="Edm.Decimal" />
- <Property Name="Weight" Nullable="false" Type="Edm.Decimal" />
- <Property Name="Length" Nullable="false" Type="Edm.Decimal" />
+ <Schema Namespace="Microsoft.Test.OData.Services.ODataWCFService" xmlns="http://docs.oasis-open.org/odata/ns/edm">
+ <ComplexType Name="Address">
+ <Property Name="Street" Type="Edm.String" Nullable="false" />
+ <Property Name="City" Type="Edm.String" Nullable="false" />
+ <Property Name="PostalCode" Type="Edm.String" Nullable="false" />
</ComplexType>
- <!-- ComplexType with enum property -->
- <ComplexType Name="ACL">
- <Property Name="Filename" Nullable="false" Type="Edm.String" />
- <Property Name="Access" Nullable="false" Type="NorthwindModel.FileAccess" />
+ <ComplexType Name="HomeAddress" BaseType="Microsoft.Test.OData.Services.ODataWCFService.Address">
+ <Property Name="FamilyName" Type="Edm.String" />
</ComplexType>
- <EntityType Name="Category">
- <Key>
- <PropertyRef Name="CategoryID" />
- </Key>
- <Property Name="CategoryID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
- <Property Name="CategoryName" Type="Edm.String" Nullable="false" MaxLength="15" />
- <Property Name="Description" Type="Edm.String" MaxLength="max" />
- <Property Name="Picture" Type="Edm.Binary" MaxLength="max" />
- <NavigationProperty Name="Products" Type="Collection(NorthwindModel.Product)" Partner="Category" />
- </EntityType>
- <EntityType Name="CustomerDemographic">
+ <ComplexType Name="CompanyAddress" BaseType="Microsoft.Test.OData.Services.ODataWCFService.Address">
+ <Property Name="CompanyName" Type="Edm.String" Nullable="false" />
+ </ComplexType>
+ <EnumType Name="AccessLevel" IsFlags="true">
+ <Member Name="None" Value="0" />
+ <Member Name="Read" Value="1" />
+ <Member Name="Write" Value="2" />
+ <Member Name="Execute" Value="4" />
+ <Member Name="ReadWrite" Value="3" />
+ </EnumType>
+ <EnumType Name="Color">
+ <Member Name="Red" Value="1" />
+ <Member Name="Green" Value="2" />
+ <Member Name="Blue" Value="4" />
+ </EnumType>
+ <EnumType Name="CompanyCategory">
+ <Member Name="IT" Value="0" />
+ <Member Name="Communication" Value="1" />
+ <Member Name="Electronics" Value="2" />
+ <Member Name="Others" Value="4" />
+ </EnumType>
+ <EntityType Name="Person">
<Key>
- <PropertyRef Name="CustomerTypeID" />
+ <PropertyRef Name="PersonID" />
</Key>
- <Property Name="CustomerTypeID" Type="Edm.String" Nullable="false" MaxLength="10" />
- <Property Name="CustomerDesc" Type="Edm.String" MaxLength="max" />
- <NavigationProperty Name="Customers" Type="Collection(NorthwindModel.Customer)" Partner="CustomerDemographics" />
+ <Property Name="PersonID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="FirstName" Type="Edm.String" Nullable="false" />
+ <Property Name="LastName" Type="Edm.String" Nullable="false" />
+ <Property Name="MiddleName" Type="Edm.String" />
+ <Property Name="HomeAddress" Type="Microsoft.Test.OData.Services.ODataWCFService.Address" />
+ <Property Name="Home" Type="Edm.GeographyPoint" SRID="4326" />
+ <Property Name="Numbers" Type="Collection(Edm.String)" Nullable="false" />
+ <Property Name="Emails" Type="Collection(Edm.String)" />
+ <NavigationProperty Name="Parent" Type="Microsoft.Test.OData.Services.ODataWCFService.Person" Nullable="false" />
</EntityType>
- <EntityType Name="Customer">
- <Key>
- <PropertyRef Name="CustomerID" />
- </Key>
- <Property Name="CustomerID" Type="Edm.String" Nullable="false" MaxLength="5" />
- <Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" />
- <Property Name="ContactName" Type="Edm.String" MaxLength="30" />
- <Property Name="ContactTitle" Type="Edm.String" MaxLength="30" />
- <Property Name="Address" Type="Edm.String" MaxLength="60" />
- <Property Name="City" Type="Edm.String" MaxLength="15" />
- <Property Name="Region" Type="Edm.String" MaxLength="15" />
- <Property Name="PostalCode" Type="Edm.String" MaxLength="10" />
- <Property Name="Country" Type="Edm.String" MaxLength="15" />
- <Property Name="Phone" Type="Edm.String" MaxLength="24" />
- <Property Name="Fax" Type="Edm.String" MaxLength="24" />
- <!-- EnumType attribute -->
- <Property Name="FileAccess" Type="NorthwindModel.FileAccess" />
- <NavigationProperty Name="Orders" Type="Collection(NorthwindModel.Order)" Partner="Customer" />
- <NavigationProperty Name="CustomerDemographics" Type="Collection(NorthwindModel.CustomerDemographic)" Partner="Customers" />
+ <EntityType Name="Customer" BaseType="Microsoft.Test.OData.Services.ODataWCFService.Person">
+ <Property Name="City" Type="Edm.String" Nullable="false" />
+ <Property Name="Birthday" Type="Edm.DateTimeOffset" Nullable="false" />
+ <Property Name="TimeBetweenLastTwoOrders" Type="Edm.Duration" Nullable="false" />
+ <NavigationProperty Name="Orders" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Order)" />
+ <NavigationProperty Name="Company" Type="Microsoft.Test.OData.Services.ODataWCFService.Company" Nullable="false" Partner="VipCustomer" />
</EntityType>
- <EntityType Name="Employee">
- <Key>
- <PropertyRef Name="EmployeeID" />
- </Key>
- <Property Name="EmployeeID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
- <Property Name="LastName" Type="Edm.String" Nullable="false" MaxLength="20" />
- <Property Name="FirstName" Type="Edm.String" Nullable="false" MaxLength="10" />
- <Property Name="Title" Type="Edm.String" MaxLength="30" />
- <Property Name="TitleOfCourtesy" Type="Edm.String" MaxLength="25" />
- <Property Name="BirthDate" Type="Edm.DateTimeOffset" />
- <Property Name="HireDate" Type="Edm.DateTimeOffset" />
- <Property Name="Address" Type="Edm.String" MaxLength="60" />
- <Property Name="City" Type="Edm.String" MaxLength="15" />
- <Property Name="Region" Type="Edm.String" MaxLength="15" />
- <Property Name="PostalCode" Type="Edm.String" MaxLength="10" />
- <Property Name="Country" Type="Edm.String" MaxLength="15" />
- <Property Name="HomePhone" Type="Edm.String" MaxLength="24" />
- <Property Name="Extension" Type="Edm.String" MaxLength="4" />
- <Property Name="Photo" Type="Edm.Binary" MaxLength="max" />
- <Property Name="Notes" Type="Edm.String" MaxLength="max" />
- <Property Name="ReportsTo" Type="Edm.Int32" />
- <Property Name="PhotoPath" Type="Edm.String" MaxLength="255" />
- <NavigationProperty Name="Employees1" Type="Collection(NorthwindModel.Employee)" Partner="Employee1" />
- <NavigationProperty Name="Employee1" Type="NorthwindModel.Employee" Partner="Employees1">
- <ReferentialConstraint Property="ReportsTo" ReferencedProperty="EmployeeID" />
- </NavigationProperty>
- <NavigationProperty Name="Orders" Type="Collection(NorthwindModel.Order)" Partner="Employee" />
- <NavigationProperty Name="Territories" Type="Collection(NorthwindModel.Territory)" Partner="Employees" />
+ <EntityType Name="Employee" BaseType="Microsoft.Test.OData.Services.ODataWCFService.Person">
+ <Property Name="DateHired" Type="Edm.DateTimeOffset" Nullable="false" />
+ <Property Name="Office" Type="Edm.GeographyPoint" SRID="4326" />
+ <NavigationProperty Name="Company" Type="Microsoft.Test.OData.Services.ODataWCFService.Company" Nullable="false" Partner="Employees" />
</EntityType>
- <EntityType Name="Order_Detail">
+ <EntityType Name="Product">
<Key>
- <PropertyRef Name="OrderID" />
<PropertyRef Name="ProductID" />
</Key>
- <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
<Property Name="ProductID" Type="Edm.Int32" Nullable="false" />
- <Property Name="UnitPrice" Type="Edm.Decimal" Nullable="false" Precision="19" Scale="4" />
- <Property Name="Quantity" Type="Edm.Int16" Nullable="false" />
- <Property Name="Discount" Type="Edm.Single" Nullable="false" />
- <NavigationProperty Name="Order" Type="NorthwindModel.Order" Nullable="false" Partner="Order_Details">
- <ReferentialConstraint Property="OrderID" ReferencedProperty="OrderID" />
- </NavigationProperty>
- <NavigationProperty Name="Product" Type="NorthwindModel.Product" Nullable="false" Partner="Order_Details">
+ <Property Name="Name" Type="Edm.String" Nullable="false" />
+ <Property Name="QuantityPerUnit" Type="Edm.String" Nullable="false" />
+ <Property Name="UnitPrice" Type="Edm.Single" Nullable="false" />
+ <Property Name="QuantityInStock" Type="Edm.Int32" Nullable="false" />
+ <Property Name="Discontinued" Type="Edm.Boolean" Nullable="false" />
+ <Property Name="UserAccess" Type="Microsoft.Test.OData.Services.ODataWCFService.AccessLevel" />
+ <Property Name="SkinColor" Type="Microsoft.Test.OData.Services.ODataWCFService.Color" />
+ <Property Name="CoverColors" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Color)" Nullable="false" />
+ <NavigationProperty Name="Details" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.ProductDetail)">
<ReferentialConstraint Property="ProductID" ReferencedProperty="ProductID" />
</NavigationProperty>
</EntityType>
- <EntityType Name="Order">
- <Key>
- <PropertyRef Name="OrderID" />
- </Key>
- <Property Name="OrderID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
- <Property Name="CustomerID" Type="Edm.String" MaxLength="5" />
- <Property Name="EmployeeID" Type="Edm.Int32" />
- <Property Name="OrderDate" Type="Edm.DateTimeOffset" />
- <Property Name="RequiredDate" Type="Edm.DateTimeOffset" />
- <Property Name="ShippedDate" Type="Edm.DateTimeOffset" />
- <Property Name="ShipVia" Type="Edm.Int32" />
- <Property Name="Freight" Type="Edm.Decimal" Precision="19" Scale="4" />
- <Property Name="ShipName" Type="Edm.String" MaxLength="40" />
- <Property Name="ShipAddress" Type="Edm.String" MaxLength="60" />
- <Property Name="ShipCity" Type="Edm.String" MaxLength="15" />
- <Property Name="ShipRegion" Type="Edm.String" MaxLength="15" />
- <Property Name="ShipPostalCode" Type="Edm.String" MaxLength="10" />
- <Property Name="ShipCountry" Type="Edm.String" MaxLength="15" />
- <NavigationProperty Name="Customer" Type="NorthwindModel.Customer" Partner="Orders">
- <ReferentialConstraint Property="CustomerID" ReferencedProperty="CustomerID" />
- </NavigationProperty>
- <NavigationProperty Name="Employee" Type="NorthwindModel.Employee" Partner="Orders">
- <ReferentialConstraint Property="EmployeeID" ReferencedProperty="EmployeeID" />
- </NavigationProperty>
- <NavigationProperty Name="Order_Details" Type="Collection(NorthwindModel.Order_Detail)" Partner="Order" />
- <NavigationProperty Name="Shipper" Type="NorthwindModel.Shipper" Partner="Orders">
- <ReferentialConstraint Property="ShipVia" ReferencedProperty="ShipperID" />
- </NavigationProperty>
- </EntityType>
- <EntityType Name="Product">
+ <EntityType Name="ProductDetail">
<Key>
<PropertyRef Name="ProductID" />
+ <PropertyRef Name="ProductDetailID" />
</Key>
- <Property Name="ProductID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
- <Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
- <Property Name="SupplierID" Type="Edm.Int32" />
- <Property Name="CategoryID" Type="Edm.Int32" />
- <Property Name="QuantityPerUnit" Type="Edm.String" MaxLength="20" />
- <Property Name="UnitPrice" Type="Edm.Decimal" Precision="19" Scale="4" />
- <Property Name="UnitsInStock" Type="Edm.Int16" />
- <Property Name="UnitsOnOrder" Type="Edm.Int16" />
- <Property Name="ReorderLevel" Type="Edm.Int16" />
- <Property Name="Discontinued" Type="Edm.Boolean" Nullable="false" />
- <!-- ComplexType attributes -->
- <Property Name="ProductDimensions" Type="NorthwindModel.Dimensions" />
- <Property Name="ShippingDimensions" Type="NorthwindModel.Dimensions" />
- <NavigationProperty Name="Category" Type="NorthwindModel.Category" Partner="Products">
- <ReferentialConstraint Property="CategoryID" ReferencedProperty="CategoryID" />
- </NavigationProperty>
- <NavigationProperty Name="Order_Details" Type="Collection(NorthwindModel.Order_Detail)" Partner="Product" />
- <NavigationProperty Name="Supplier" Type="NorthwindModel.Supplier" Partner="Products">
- <ReferentialConstraint Property="SupplierID" ReferencedProperty="SupplierID" />
+ <Property Name="ProductID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="ProductDetailID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="ProductName" Type="Edm.String" Nullable="false" />
+ <Property Name="Description" Type="Edm.String" Nullable="false" />
+ <NavigationProperty Name="RelatedProduct" Type="Microsoft.Test.OData.Services.ODataWCFService.Product" />
+ <NavigationProperty Name="Reviews" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.ProductReview)">
+ <ReferentialConstraint Property="ProductID" ReferencedProperty="ProductID" />
+ <ReferentialConstraint Property="ProductDetailID" ReferencedProperty="ProductDetailID" />
</NavigationProperty>
</EntityType>
- <EntityType Name="Region">
+ <EntityType Name="ProductReview">
<Key>
- <PropertyRef Name="RegionID" />
- </Key>
- <Property Name="RegionID" Type="Edm.Int32" Nullable="false" />
- <Property Name="RegionDescription" Type="Edm.String" Nullable="false" MaxLength="50" />
- <NavigationProperty Name="Territories" Type="Collection(NorthwindModel.Territory)" Partner="Region" />
- </EntityType>
- <EntityType Name="Shipper">
- <Key>
- <PropertyRef Name="ShipperID" />
- </Key>
- <Property Name="ShipperID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
- <Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" />
- <Property Name="Phone" Type="Edm.String" MaxLength="24" />
- <NavigationProperty Name="Orders" Type="Collection(NorthwindModel.Order)" Partner="Shipper" />
- </EntityType>
- <EntityType Name="Supplier">
- <Key>
- <PropertyRef Name="SupplierID" />
+ <PropertyRef Name="ProductID" />
+ <PropertyRef Name="ProductDetailID" />
+ <PropertyRef Name="ReviewTitle" />
+ <PropertyRef Name="RevisionID" />
</Key>
- <Property Name="SupplierID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
- <Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" />
- <Property Name="ContactName" Type="Edm.String" MaxLength="30" />
- <Property Name="ContactTitle" Type="Edm.String" MaxLength="30" />
- <Property Name="Address" Type="Edm.String" MaxLength="60" />
- <Property Name="City" Type="Edm.String" MaxLength="15" />
- <Property Name="Region" Type="Edm.String" MaxLength="15" />
- <Property Name="PostalCode" Type="Edm.String" MaxLength="10" />
- <Property Name="Country" Type="Edm.String" MaxLength="15" />
- <Property Name="Phone" Type="Edm.String" MaxLength="24" />
- <Property Name="Fax" Type="Edm.String" MaxLength="24" />
- <Property Name="HomePage" Type="Edm.String" MaxLength="max" />
- <NavigationProperty Name="Products" Type="Collection(NorthwindModel.Product)" Partner="Supplier" />
+ <Property Name="ProductID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="ProductDetailID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="ReviewTitle" Type="Edm.String" Nullable="false" />
+ <Property Name="RevisionID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="Comment" Type="Edm.String" Nullable="false" />
+ <Property Name="Author" Type="Edm.String" Nullable="false" />
</EntityType>
- <EntityType Name="Territory">
+ <EntityType Name="Order">
<Key>
- <PropertyRef Name="TerritoryID" />
+ <PropertyRef Name="OrderID" />
</Key>
- <Property Name="TerritoryID" Type="Edm.String" Nullable="false" MaxLength="20" />
- <Property Name="TerritoryDescription" Type="Edm.String" Nullable="false" MaxLength="50" />
- <Property Name="RegionID" Type="Edm.Int32" Nullable="false" />
- <NavigationProperty Name="Region" Type="NorthwindModel.Region" Nullable="false" Partner="Territories">
- <ReferentialConstraint Property="RegionID" ReferencedProperty="RegionID" />
- </NavigationProperty>
- <NavigationProperty Name="Employees" Type="Collection(NorthwindModel.Employee)" Partner="Territories" />
+ <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="OrderDate" Type="Edm.DateTimeOffset" Nullable="false" />
+ <Property Name="ShelfLife" Type="Edm.Duration" />
+ <Property Name="OrderShelfLifes" Type="Collection(Edm.Duration)" />
+ <NavigationProperty Name="LoggedInEmployee" Type="Microsoft.Test.OData.Services.ODataWCFService.Employee" Nullable="false" />
+ <NavigationProperty Name="CustomerForOrder" Type="Microsoft.Test.OData.Services.ODataWCFService.Customer" Nullable="false" />
+ <NavigationProperty Name="OrderDetails" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.OrderDetail)" />
</EntityType>
- <EntityType Name="Alphabetical_list_of_product">
+ <EntityType Name="OrderDetail">
<Key>
- <PropertyRef Name="CategoryName" />
- <PropertyRef Name="Discontinued" />
+ <PropertyRef Name="OrderID" />
<PropertyRef Name="ProductID" />
- <PropertyRef Name="ProductName" />
</Key>
+ <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
<Property Name="ProductID" Type="Edm.Int32" Nullable="false" />
- <Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
- <Property Name="SupplierID" Type="Edm.Int32" />
- <Property Name="CategoryID" Type="Edm.Int32" />
- <Property Name="QuantityPerUnit" Type="Edm.String" MaxLength="20" />
- <Property Name="UnitPrice" Type="Edm.Decimal" Precision="19" Scale="4" />
- <Property Name="UnitsInStock" Type="Edm.Int16" />
- <Property Name="UnitsOnOrder" Type="Edm.Int16" />
- <Property Name="ReorderLevel" Type="Edm.Int16" />
- <Property Name="Discontinued" Type="Edm.Boolean" Nullable="false" />
- <Property Name="CategoryName" Type="Edm.String" Nullable="false" MaxLength="15" />
+ <Property Name="OrderPlaced" Type="Edm.DateTimeOffset" Nullable="false" />
+ <Property Name="Quantity" Type="Edm.Int32" Nullable="false" />
+ <Property Name="UnitPrice" Type="Edm.Single" Nullable="false" />
+ <NavigationProperty Name="ProductOrdered" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Product)" />
+ <NavigationProperty Name="AssociatedOrder" Type="Microsoft.Test.OData.Services.ODataWCFService.Order" Nullable="false" />
</EntityType>
- <EntityType Name="Category_Sales_for_1997">
+ <EntityType Name="Department">
<Key>
- <PropertyRef Name="CategoryName" />
+ <PropertyRef Name="DepartmentID" />
</Key>
- <Property Name="CategoryName" Type="Edm.String" Nullable="false" MaxLength="15" />
- <Property Name="CategorySales" Type="Edm.Decimal" Precision="19" Scale="4" />
+ <Property Name="DepartmentID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="Name" Type="Edm.String" Nullable="false" />
+ <NavigationProperty Name="Company" Type="Microsoft.Test.OData.Services.ODataWCFService.Company" Nullable="false" Partner="Departments" />
</EntityType>
- <EntityType Name="Current_Product_List">
+ <EntityType Name="Company">
<Key>
- <PropertyRef Name="ProductID" />
- <PropertyRef Name="ProductName" />
+ <PropertyRef Name="CompanyID" />
</Key>
- <Property Name="ProductID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
- <Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
+ <Property Name="CompanyID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="CompanyCategory" Type="Microsoft.Test.OData.Services.ODataWCFService.CompanyCategory" />
+ <Property Name="Revenue" Type="Edm.Int64" Nullable="false" />
+ <Property Name="Name" Type="Edm.String" />
+ <Property Name="Address" Type="Microsoft.Test.OData.Services.ODataWCFService.Address" />
+ <NavigationProperty Name="Employees" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Employee)" Partner="Company" />
+ <NavigationProperty Name="VipCustomer" Type="Microsoft.Test.OData.Services.ODataWCFService.Customer" Nullable="false" Partner="Company" />
+ <NavigationProperty Name="Departments" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Department)" Partner="Company" />
+ <NavigationProperty Name="CoreDepartment" Type="Microsoft.Test.OData.Services.ODataWCFService.Department" Nullable="false" />
</EntityType>
- <EntityType Name="Customer_and_Suppliers_by_City">
- <Key>
- <PropertyRef Name="CompanyName" />
- <PropertyRef Name="Relationship" />
- </Key>
- <Property Name="City" Type="Edm.String" MaxLength="15" />
- <Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" />
- <Property Name="ContactName" Type="Edm.String" MaxLength="30" />
- <Property Name="Relationship" Type="Edm.String" Nullable="false" MaxLength="9" Unicode="false" />
+ <EntityType Name="PublicCompany" BaseType="Microsoft.Test.OData.Services.ODataWCFService.Company">
+ <Property Name="StockExchange" Type="Edm.String" />
+ <NavigationProperty Name="Assets" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Asset)" ContainsTarget="true" />
+ <NavigationProperty Name="Club" Type="Microsoft.Test.OData.Services.ODataWCFService.Club" Nullable="false" ContainsTarget="true" />
+ <NavigationProperty Name="LabourUnion" Type="Microsoft.Test.OData.Services.ODataWCFService.LabourUnion" Nullable="false" />
</EntityType>
- <EntityType Name="Invoice">
+ <EntityType Name="Asset">
<Key>
- <PropertyRef Name="CustomerName" />
- <PropertyRef Name="Discount" />
- <PropertyRef Name="OrderID" />
- <PropertyRef Name="ProductID" />
- <PropertyRef Name="ProductName" />
- <PropertyRef Name="Quantity" />
- <PropertyRef Name="Salesperson" />
- <PropertyRef Name="ShipperName" />
- <PropertyRef Name="UnitPrice" />
+ <PropertyRef Name="AssetID" />
</Key>
- <Property Name="ShipName" Type="Edm.String" MaxLength="40" />
- <Property Name="ShipAddress" Type="Edm.String" MaxLength="60" />
- <Property Name="ShipCity" Type="Edm.String" MaxLength="15" />
- <Property Name="ShipRegion" Type="Edm.String" MaxLength="15" />
- <Property Name="ShipPostalCode" Type="Edm.String" MaxLength="10" />
- <Property Name="ShipCountry" Type="Edm.String" MaxLength="15" />
- <Property Name="CustomerID" Type="Edm.String" MaxLength="5" />
- <Property Name="CustomerName" Type="Edm.String" Nullable="false" MaxLength="40" />
- <Property Name="Address" Type="Edm.String" MaxLength="60" />
- <Property Name="City" Type="Edm.String" MaxLength="15" />
- <Property Name="Region" Type="Edm.String" MaxLength="15" />
- <Property Name="PostalCode" Type="Edm.String" MaxLength="10" />
- <Property Name="Country" Type="Edm.String" MaxLength="15" />
- <Property Name="Salesperson" Type="Edm.String" Nullable="false" MaxLength="31" />
- <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
- <Property Name="OrderDate" Type="Edm.DateTimeOffset" />
- <Property Name="RequiredDate" Type="Edm.DateTimeOffset" />
- <Property Name="ShippedDate" Type="Edm.DateTimeOffset" />
- <Property Name="ShipperName" Type="Edm.String" Nullable="false" MaxLength="40" />
- <Property Name="ProductID" Type="Edm.Int32" Nullable="false" />
- <Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
- <Property Name="UnitPrice" Type="Edm.Decimal" Nullable="false" Precision="19" Scale="4" />
- <Property Name="Quantity" Type="Edm.Int16" Nullable="false" />
- <Property Name="Discount" Type="Edm.Single" Nullable="false" />
- <Property Name="ExtendedPrice" Type="Edm.Decimal" Precision="19" Scale="4" />
- <Property Name="Freight" Type="Edm.Decimal" Precision="19" Scale="4" />
+ <Property Name="AssetID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="Name" Type="Edm.String" />
+ <Property Name="Number" Type="Edm.Int32" Nullable="false" />
</EntityType>
- <EntityType Name="Order_Details_Extended">
+ <EntityType Name="Club">
<Key>
- <PropertyRef Name="Discount" />
- <PropertyRef Name="OrderID" />
- <PropertyRef Name="ProductID" />
- <PropertyRef Name="ProductName" />
- <PropertyRef Name="Quantity" />
- <PropertyRef Name="UnitPrice" />
+ <PropertyRef Name="ClubID" />
</Key>
- <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
- <Property Name="ProductID" Type="Edm.Int32" Nullable="false" />
- <Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
- <Property Name="UnitPrice" Type="Edm.Decimal" Nullable="false" Precision="19" Scale="4" />
- <Property Name="Quantity" Type="Edm.Int16" Nullable="false" />
- <Property Name="Discount" Type="Edm.Single" Nullable="false" />
- <Property Name="ExtendedPrice" Type="Edm.Decimal" Precision="19" Scale="4" />
+ <Property Name="ClubID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="Name" Type="Edm.String" />
</EntityType>
- <EntityType Name="Order_Subtotal">
+ <EntityType Name="LabourUnion">
<Key>
- <PropertyRef Name="OrderID" />
+ <PropertyRef Name="LabourUnionID" />
</Key>
- <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
- <Property Name="Subtotal" Type="Edm.Decimal" Precision="19" Scale="4" />
+ <Property Name="LabourUnionID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="Name" Type="Edm.String" />
</EntityType>
- <EntityType Name="Orders_Qry">
+ <Action Name="AddAccessRight" IsBound="true">
+ <Parameter Name="product" Type="Microsoft.Test.OData.Services.ODataWCFService.Product" Nullable="false" />
+ <Parameter Name="accessRight" Type="Microsoft.Test.OData.Services.ODataWCFService.AccessLevel" />
+ <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.AccessLevel" />
+ </Action>
+ <Action Name="IncreaseRevenue" IsBound="true">
+ <Parameter Name="p" Type="Microsoft.Test.OData.Services.ODataWCFService.Company" Nullable="false" />
+ <Parameter Name="IncreaseValue" Type="Edm.Int64" />
+ <ReturnType Type="Edm.Int64" Nullable="false" />
+ </Action>
+ <Action Name="ResetAddress" IsBound="true" EntitySetPath="person">
+ <Parameter Name="person" Type="Microsoft.Test.OData.Services.ODataWCFService.Person" Nullable="false" />
+ <Parameter Name="addresses" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Address)" Nullable="false" />
+ <Parameter Name="index" Type="Edm.Int32" Nullable="false" />
+ <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.Person" Nullable="false" />
+ </Action>
+ <Action Name="Discount" IsBound="true" EntitySetPath="products">
+ <Parameter Name="products" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Product)" Nullable="false" />
+ <Parameter Name="percentage" Type="Edm.Int32" Nullable="false" />
+ <ReturnType Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Product)" Nullable="false" />
+ </Action>
+ <Action Name="Discount">
+ <Parameter Name="percentage" Type="Edm.Int32" Nullable="false" />
+ </Action>
+ <Action Name="ResetBossEmail">
+ <Parameter Name="emails" Type="Collection(Edm.String)" Nullable="false" />
+ <ReturnType Type="Collection(Edm.String)" Nullable="false" />
+ </Action>
+ <Action Name="ResetBossAddress">
+ <Parameter Name="address" Type="Microsoft.Test.OData.Services.ODataWCFService.Address" Nullable="false" />
+ <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.Address" Nullable="false" />
+ </Action>
+ <Function Name="GetEmployeesCount" IsBound="true">
+ <Parameter Name="p" Type="Microsoft.Test.OData.Services.ODataWCFService.Company" Nullable="false" />
+ <ReturnType Type="Edm.Int32" Nullable="false" />
+ </Function>
+ <Function Name="GetProductDetails" IsBound="true" EntitySetPath="product/Details" IsComposable="true">
+ <Parameter Name="product" Type="Microsoft.Test.OData.Services.ODataWCFService.Product" Nullable="false" />
+ <Parameter Name="count" Type="Edm.Int32" />
+ <ReturnType Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.ProductDetail)" Nullable="false" />
+ </Function>
+ <Function Name="GetRelatedProduct" IsBound="true" EntitySetPath="productDetail/Products" IsComposable="true">
+ <Parameter Name="productDetail" Type="Microsoft.Test.OData.Services.ODataWCFService.ProductDetail" Nullable="false" />
+ <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.Product" Nullable="false" />
+ </Function>
+ <Function Name="GetDefaultColor" IsComposable="true">
+ <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.Color" />
+ </Function>
+ <Function Name="GetPerson" IsComposable="true">
+ <Parameter Name="address" Type="Microsoft.Test.OData.Services.ODataWCFService.Address" Nullable="false" />
+ <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.Person" Nullable="false" />
+ </Function>
+ <Function Name="GetPerson2" IsComposable="true">
+ <Parameter Name="city" Type="Edm.String" Nullable="false" />
+ <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.Person" Nullable="false" />
+ </Function>
+ <Function Name="GetAllProducts" IsComposable="true">
+ <ReturnType Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Product)" Nullable="false" />
+ </Function>
+ <Function Name="GetBossEmails">
+ <Parameter Name="start" Type="Edm.Int32" Nullable="false" />
+ <Parameter Name="count" Type="Edm.Int32" Nullable="false" />
+ <ReturnType Type="Collection(Edm.String)" Nullable="false" />
+ </Function>
+ <Function Name="GetProductsByAccessLevel">
+ <Parameter Name="accessLevel" Type="Microsoft.Test.OData.Services.ODataWCFService.AccessLevel" />
+ <ReturnType Type="Collection(Edm.String)" Nullable="false" />
+ </Function>
+ <Function Name="GetActualAmount" IsBound="true">
+ <Parameter Name="giftcard" Type="Microsoft.Test.OData.Services.ODataWCFService.GiftCard" Nullable="false" />
+ <Parameter Name="bonusRate" Type="Edm.Double" />
+ <ReturnType Type="Edm.Double" Nullable="false" />
+ </Function>
+ <Function Name="GetDefaultPI" IsBound="true" EntitySetPath="account/MyPaymentInstruments">
+ <Parameter Name="account" Type="Microsoft.Test.OData.Services.ODataWCFService.Account" Nullable="false" />
+ <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument" />
+ </Function>
+ <Action Name="RefreshDefaultPI" IsBound="true" EntitySetPath="account/MyPaymentInstruments">
+ <Parameter Name="account" Type="Microsoft.Test.OData.Services.ODataWCFService.Account" Nullable="false" />
+ <Parameter Name="newDate" Type="Edm.DateTimeOffset" />
+ <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument" />
+ </Action>
+ <Function Name="GetHomeAddress" IsBound="true" IsComposable="true">
+ <Parameter Name="person" Type="Microsoft.Test.OData.Services.ODataWCFService.Person" Nullable="false" />
+ <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.HomeAddress" Nullable="false" />
+ </Function>
+ <Function Name="GetAccountInfo" IsBound="true" IsComposable="true">
+ <Parameter Name="account" Type="Microsoft.Test.OData.Services.ODataWCFService.Account" Nullable="false" />
+ <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.AccountInfo" Nullable="false" />
+ </Function>
+ <ComplexType Name="AccountInfo" OpenType="true">
+ <Property Name="FirstName" Type="Edm.String" Nullable="false" />
+ <Property Name="LastName" Type="Edm.String" Nullable="false" />
+ </ComplexType>
+ <EntityType Name="Account">
<Key>
- <PropertyRef Name="CompanyName" />
- <PropertyRef Name="OrderID" />
+ <PropertyRef Name="AccountID" />
</Key>
- <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
- <Property Name="CustomerID" Type="Edm.String" MaxLength="5" />
- <Property Name="EmployeeID" Type="Edm.Int32" />
- <Property Name="OrderDate" Type="Edm.DateTimeOffset" />
- <Property Name="RequiredDate" Type="Edm.DateTimeOffset" />
- <Property Name="ShippedDate" Type="Edm.DateTimeOffset" />
- <Property Name="ShipVia" Type="Edm.Int32" />
- <Property Name="Freight" Type="Edm.Decimal" Precision="19" Scale="4" />
- <Property Name="ShipName" Type="Edm.String" MaxLength="40" />
- <Property Name="ShipAddress" Type="Edm.String" MaxLength="60" />
- <Property Name="ShipCity" Type="Edm.String" MaxLength="15" />
- <Property Name="ShipRegion" Type="Edm.String" MaxLength="15" />
- <Property Name="ShipPostalCode" Type="Edm.String" MaxLength="10" />
- <Property Name="ShipCountry" Type="Edm.String" MaxLength="15" />
- <Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" />
- <Property Name="Address" Type="Edm.String" MaxLength="60" />
- <Property Name="City" Type="Edm.String" MaxLength="15" />
- <Property Name="Region" Type="Edm.String" MaxLength="15" />
- <Property Name="PostalCode" Type="Edm.String" MaxLength="10" />
- <Property Name="Country" Type="Edm.String" MaxLength="15" />
+ <Property Name="AccountID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="Country" Type="Edm.String" Nullable="false" />
+ <Property Name="AccountInfo" Type="Microsoft.Test.OData.Services.ODataWCFService.AccountInfo" />
+ <NavigationProperty Name="MyGiftCard" Type="Microsoft.Test.OData.Services.ODataWCFService.GiftCard" ContainsTarget="true" />
+ <NavigationProperty Name="MyPaymentInstruments" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument)" ContainsTarget="true" />
+ <NavigationProperty Name="ActiveSubscriptions" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Subscription)" ContainsTarget="true" />
+ <NavigationProperty Name="AvailableSubscriptionTemplatess" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Subscription)" />
</EntityType>
- <EntityType Name="Product_Sales_for_1997">
+ <EntityType Name="GiftCard">
<Key>
- <PropertyRef Name="CategoryName" />
- <PropertyRef Name="ProductName" />
+ <PropertyRef Name="GiftCardID" />
</Key>
- <Property Name="CategoryName" Type="Edm.String" Nullable="false" MaxLength="15" />
- <Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
- <Property Name="ProductSales" Type="Edm.Decimal" Precision="19" Scale="4" />
+ <Property Name="GiftCardID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="GiftCardNO" Type="Edm.String" Nullable="false" />
+ <Property Name="Amount" Type="Edm.Double" Nullable="false" />
+ <Property Name="ExperationDate" Type="Edm.DateTimeOffset" Nullable="false" />
</EntityType>
- <EntityType Name="Products_Above_Average_Price">
+ <EntityType Name="PaymentInstrument">
<Key>
- <PropertyRef Name="ProductName" />
+ <PropertyRef Name="PaymentInstrumentID" />
</Key>
- <Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
- <Property Name="UnitPrice" Type="Edm.Decimal" Precision="19" Scale="4" />
+ <Property Name="PaymentInstrumentID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="FriendlyName" Type="Edm.String" Nullable="false" />
+ <Property Name="CreatedDate" Type="Edm.DateTimeOffset" Nullable="false" />
+ <NavigationProperty Name="TheStoredPI" Type="Microsoft.Test.OData.Services.ODataWCFService.StoredPI" Nullable="false" />
+ <NavigationProperty Name="BillingStatements" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Statement)" ContainsTarget="true" />
+ <NavigationProperty Name="BackupStoredPI" Type="Microsoft.Test.OData.Services.ODataWCFService.StoredPI" Nullable="false" />
</EntityType>
- <EntityType Name="Products_by_Category">
- <Key>
- <PropertyRef Name="CategoryName" />
- <PropertyRef Name="Discontinued" />
- <PropertyRef Name="ProductName" />
- </Key>
- <Property Name="CategoryName" Type="Edm.String" Nullable="false" MaxLength="15" />
- <Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
- <Property Name="QuantityPerUnit" Type="Edm.String" MaxLength="20" />
- <Property Name="UnitsInStock" Type="Edm.Int16" />
- <Property Name="Discontinued" Type="Edm.Boolean" Nullable="false" />
+ <EntityType Name="CreditCardPI" BaseType="Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument">
+ <Property Name="CardNumber" Type="Edm.String" Nullable="false" />
+ <Property Name="CVV" Type="Edm.String" Nullable="false" />
+ <Property Name="HolderName" Type="Edm.String" Nullable="false" />
+ <Property Name="Balance" Type="Edm.Double" Nullable="false" />
+ <Property Name="ExperationDate" Type="Edm.DateTimeOffset" Nullable="false" />
+ <NavigationProperty Name="CreditRecords" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.CreditRecord)" ContainsTarget="true" />
</EntityType>
- <EntityType Name="Sales_by_Category">
+ <EntityType Name="StoredPI">
<Key>
- <PropertyRef Name="CategoryID" />
- <PropertyRef Name="CategoryName" />
- <PropertyRef Name="ProductName" />
+ <PropertyRef Name="StoredPIID" />
</Key>
- <Property Name="CategoryID" Type="Edm.Int32" Nullable="false" />
- <Property Name="CategoryName" Type="Edm.String" Nullable="false" MaxLength="15" />
- <Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
- <Property Name="ProductSales" Type="Edm.Decimal" Precision="19" Scale="4" />
+ <Property Name="StoredPIID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="PIName" Type="Edm.String" Nullable="false" />
+ <Property Name="PIType" Type="Edm.String" Nullable="false" />
+ <Property Name="CreatedDate" Type="Edm.DateTimeOffset" Nullable="false" />
</EntityType>
- <EntityType Name="Sales_Totals_by_Amount">
+ <EntityType Name="Statement">
<Key>
- <PropertyRef Name="CompanyName" />
- <PropertyRef Name="OrderID" />
+ <PropertyRef Name="StatementID" />
</Key>
- <Property Name="SaleAmount" Type="Edm.Decimal" Precision="19" Scale="4" />
- <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
- <Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" />
- <Property Name="ShippedDate" Type="Edm.DateTimeOffset" />
+ <Property Name="StatementID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="TransactionType" Type="Edm.String" Nullable="false" />
+ <Property Name="TransactionDescription" Type="Edm.String" Nullable="false" />
+ <Property Name="Amount" Type="Edm.Double" Nullable="false" />
</EntityType>
- <EntityType Name="Summary_of_Sales_by_Quarter">
+ <EntityType Name="CreditRecord">
<Key>
- <PropertyRef Name="OrderID" />
+ <PropertyRef Name="CreditRecordID" />
</Key>
- <Property Name="ShippedDate" Type="Edm.DateTimeOffset" />
- <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
- <Property Name="Subtotal" Type="Edm.Decimal" Precision="19" Scale="4" />
+ <Property Name="CreditRecordID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="IsGood" Type="Edm.Boolean" Nullable="false" />
+ <Property Name="Reason" Type="Edm.String" Nullable="false" />
+ <Property Name="CreatedDate" Type="Edm.DateTimeOffset" Nullable="false" />
</EntityType>
- <EntityType Name="Summary_of_Sales_by_Year">
+ <EntityType Name="Subscription">
<Key>
- <PropertyRef Name="OrderID" />
+ <PropertyRef Name="SubscriptionID" />
</Key>
- <Property Name="ShippedDate" Type="Edm.DateTimeOffset" />
- <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
- <Property Name="Subtotal" Type="Edm.Decimal" Precision="19" Scale="4" />
+ <Property Name="SubscriptionID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="TemplateGuid" Type="Edm.String" Nullable="false" />
+ <Property Name="Title" Type="Edm.String" Nullable="false" />
+ <Property Name="Category" Type="Edm.String" Nullable="false" />
+ <Property Name="CreatedDate" Type="Edm.DateTimeOffset" Nullable="false" />
</EntityType>
- <Annotations Target="ODataWebExperimental.Northwind.Model.NorthwindEntities">
- <Annotation Term="Com.Microsoft.OData.Service.Conventions.V1.UrlConventions" String="KeyAsSegment" />
- </Annotations>
- <!-- Function -->
- <Function Name="TopSellingProducts" ReturnType="Collection(NorthwindModel.Product)" IsComposable="true" EntitySetPath="ODataWebExperimental.Northwind.Model.Products">
- <Parameter Name="Year" Type="Edm.Decimal" Precision="4" Scale="0" />
- </Function>
- <Function Name="TopSellingProducts2" ReturnType="Collection(NorthwindModel.Product)" IsComposable="true" EntitySetPath="ODataWebExperimental.Northwind.Model.Products" IsBound="true">
- <Parameter Name="Product" Type="NorthwindModel.Product" />
- <Parameter Name="Year" Type="Edm.Decimal" Precision="4" Scale="0" />
- </Function>
- <!-- Action -->
- <Action Name="TopSellingProducts" EntitySetPath="ODataWebExperimental.Northwind.Model.Products" IsBound="true">
- <Parameter Name="Product" Type="NorthwindModel.Product" />
- <Parameter Name="Year" Type="Edm.Decimal" Precision="4" Scale="0" />
- </Action>
- </Schema>
- <Schema Namespace="ODataWebExperimental.Northwind.Model" xmlns="http://docs.oasis-open.org/odata/ns/edm">
- <EntityContainer Name="NorthwindEntities" p4:LazyLoadingEnabled="true" xmlns:p4="http://schemas.microsoft.com/ado/2009/02/edm/annotation">
- <EntitySet Name="Categories" EntityType="NorthwindModel.Category">
- <NavigationPropertyBinding Path="Products" Target="Products" />
- </EntitySet>
- <EntitySet Name="CustomerDemographics" EntityType="NorthwindModel.CustomerDemographic">
- <NavigationPropertyBinding Path="Customers" Target="Customers" />
+ <EntityContainer Name="InMemoryEntities">
+ <EntitySet Name="People" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Person">
+ <NavigationPropertyBinding Path="Parent" Target="People" />
</EntitySet>
- <EntitySet Name="Customers" EntityType="NorthwindModel.Customer">
- <NavigationPropertyBinding Path="CustomerDemographics" Target="CustomerDemographics" />
+ <Singleton Name="Boss" Type="Microsoft.Test.OData.Services.ODataWCFService.Person" />
+ <EntitySet Name="Customers" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Customer">
<NavigationPropertyBinding Path="Orders" Target="Orders" />
</EntitySet>
- <EntitySet Name="Employees" EntityType="NorthwindModel.Employee">
- <NavigationPropertyBinding Path="Employees1" Target="Employees" />
- <NavigationPropertyBinding Path="Employee1" Target="Employees" />
+ <Singleton Name="VipCustomer" Type="Microsoft.Test.OData.Services.ODataWCFService.Customer">
<NavigationPropertyBinding Path="Orders" Target="Orders" />
- <NavigationPropertyBinding Path="Territories" Target="Territories" />
- </EntitySet>
- <EntitySet Name="Order_Details" EntityType="NorthwindModel.Order_Detail">
- <NavigationPropertyBinding Path="Order" Target="Orders" />
- <NavigationPropertyBinding Path="Product" Target="Products" />
+ <NavigationPropertyBinding Path="Company" Target="Company" />
+ </Singleton>
+ <EntitySet Name="Employees" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Employee">
+ <NavigationPropertyBinding Path="Company" Target="Company" />
</EntitySet>
- <EntitySet Name="Orders" EntityType="NorthwindModel.Order">
- <NavigationPropertyBinding Path="Customer" Target="Customers" />
- <NavigationPropertyBinding Path="Employee" Target="Employees" />
- <NavigationPropertyBinding Path="Order_Details" Target="Order_Details" />
- <NavigationPropertyBinding Path="Shipper" Target="Shippers" />
+ <EntitySet Name="Products" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Product">
+ <NavigationPropertyBinding Path="Details" Target="ProductDetails" />
</EntitySet>
- <EntitySet Name="Products" EntityType="NorthwindModel.Product">
- <NavigationPropertyBinding Path="Category" Target="Categories" />
- <NavigationPropertyBinding Path="Order_Details" Target="Order_Details" />
- <NavigationPropertyBinding Path="Supplier" Target="Suppliers" />
+ <EntitySet Name="ProductDetails" EntityType="Microsoft.Test.OData.Services.ODataWCFService.ProductDetail">
+ <NavigationPropertyBinding Path="RelatedProduct" Target="Products" />
+ <NavigationPropertyBinding Path="Reviews" Target="ProductReviews" />
</EntitySet>
- <EntitySet Name="Regions" EntityType="NorthwindModel.Region">
- <NavigationPropertyBinding Path="Territories" Target="Territories" />
+ <EntitySet Name="ProductReviews" EntityType="Microsoft.Test.OData.Services.ODataWCFService.ProductReview" />
+ <EntitySet Name="Orders" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Order">
+ <NavigationPropertyBinding Path="LoggedInEmployee" Target="Employees" />
+ <NavigationPropertyBinding Path="CustomerForOrder" Target="Customers" />
+ <NavigationPropertyBinding Path="OrderDetails" Target="OrderDetails" />
</EntitySet>
- <EntitySet Name="Shippers" EntityType="NorthwindModel.Shipper">
- <NavigationPropertyBinding Path="Orders" Target="Orders" />
+ <EntitySet Name="OrderDetails" EntityType="Microsoft.Test.OData.Services.ODataWCFService.OrderDetail">
+ <NavigationPropertyBinding Path="AssociatedOrder" Target="Orders" />
+ <NavigationPropertyBinding Path="ProductOrdered" Target="Products" />
</EntitySet>
- <EntitySet Name="Suppliers" EntityType="NorthwindModel.Supplier">
- <NavigationPropertyBinding Path="Products" Target="Products" />
+ <EntitySet Name="Departments" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Department">
+ <NavigationPropertyBinding Path="Company" Target="Company" />
</EntitySet>
- <EntitySet Name="Territories" EntityType="NorthwindModel.Territory">
+ <Singleton Name="Company" Type="Microsoft.Test.OData.Services.ODataWCFService.Company">
<NavigationPropertyBinding Path="Employees" Target="Employees" />
- <NavigationPropertyBinding Path="Region" Target="Regions" />
- </EntitySet>
- <EntitySet Name="Alphabetical_list_of_products" EntityType="NorthwindModel.Alphabetical_list_of_product" />
- <EntitySet Name="Category_Sales_for_1997" EntityType="NorthwindModel.Category_Sales_for_1997" />
- <EntitySet Name="Current_Product_Lists" EntityType="NorthwindModel.Current_Product_List" />
- <EntitySet Name="Customer_and_Suppliers_by_Cities" EntityType="NorthwindModel.Customer_and_Suppliers_by_City" />
- <EntitySet Name="Invoices" EntityType="NorthwindModel.Invoice" />
- <EntitySet Name="Order_Details_Extendeds" EntityType="NorthwindModel.Order_Details_Extended" />
- <EntitySet Name="Order_Subtotals" EntityType="NorthwindModel.Order_Subtotal" />
- <EntitySet Name="Orders_Qries" EntityType="NorthwindModel.Orders_Qry" />
- <EntitySet Name="Product_Sales_for_1997" EntityType="NorthwindModel.Product_Sales_for_1997" />
- <EntitySet Name="Products_Above_Average_Prices" EntityType="NorthwindModel.Products_Above_Average_Price" />
- <EntitySet Name="Products_by_Categories" EntityType="NorthwindModel.Products_by_Category" />
- <EntitySet Name="Sales_by_Categories" EntityType="NorthwindModel.Sales_by_Category" />
- <EntitySet Name="Sales_Totals_by_Amounts" EntityType="NorthwindModel.Sales_Totals_by_Amount" />
- <EntitySet Name="Summary_of_Sales_by_Quarters" EntityType="NorthwindModel.Summary_of_Sales_by_Quarter" />
- <EntitySet Name="Summary_of_Sales_by_Years" EntityType="NorthwindModel.Summary_of_Sales_by_Year" />
- <!-- Singleton -->
- <Singleton Name="Contoso" Type="NorthwindModel.Supplier">
- <NavigationPropertyBinding Path="Products" Target="Products"/>
+ <NavigationPropertyBinding Path="VipCustomer" Target="VipCustomer" />
+ <NavigationPropertyBinding Path="Departments" Target="Departments" />
+ <NavigationPropertyBinding Path="CoreDepartment" Target="Departments" />
</Singleton>
- <!-- FunctionImport -->
- <FunctionImport Name="TopSellingProducts" EntitySet="Products" Function="NorthwindModel.TopSellingProducts"/>
+ <Singleton Name="PublicCompany" Type="Microsoft.Test.OData.Services.ODataWCFService.Company">
+ <NavigationPropertyBinding Path="Microsoft.Test.OData.Services.ODataWCFService.PublicCompany/LabourUnion" Target="LabourUnion" />
+ </Singleton>
+ <Singleton Name="LabourUnion" Type="Microsoft.Test.OData.Services.ODataWCFService.LabourUnion" />
+ <ActionImport Name="Discount" Action="Microsoft.Test.OData.Services.ODataWCFService.Discount" />
+ <ActionImport Name="ResetBossEmail" Action="Microsoft.Test.OData.Services.ODataWCFService.ResetBossEmail" />
+ <ActionImport Name="ResetBossAddress" Action="Microsoft.Test.OData.Services.ODataWCFService.ResetBossAddress" />
+ <FunctionImport Name="GetDefaultColor" Function="Microsoft.Test.OData.Services.ODataWCFService.GetDefaultColor" />
+ <FunctionImport Name="GetPerson" Function="Microsoft.Test.OData.Services.ODataWCFService.GetPerson" EntitySet="People" />
+ <FunctionImport Name="GetPerson2" Function="Microsoft.Test.OData.Services.ODataWCFService.GetPerson2" EntitySet="People" />
+ <FunctionImport Name="GetAllProducts" Function="Microsoft.Test.OData.Services.ODataWCFService.GetAllProducts" EntitySet="Products" />
+ <FunctionImport Name="GetBossEmails" Function="Microsoft.Test.OData.Services.ODataWCFService.GetBossEmails" />
+ <FunctionImport Name="GetProductsByAccessLevel" Function="Microsoft.Test.OData.Services.ODataWCFService.GetProductsByAccessLevel" />
+ <EntitySet Name="Accounts" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Account">
+ <NavigationPropertyBinding Path="Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument/TheStoredPI" Target="StoredPIs" />
+ <NavigationPropertyBinding Path="AvailableSubscriptionTemplatess" Target="SubscriptionTemplates" />
+ <NavigationPropertyBinding Path="Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument/BackupStoredPI" Target="DefaultStoredPI" />
+ </EntitySet>
+ <EntitySet Name="StoredPIs" EntityType="Microsoft.Test.OData.Services.ODataWCFService.StoredPI" />
+ <EntitySet Name="SubscriptionTemplates" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Subscription" />
+ <Singleton Name="DefaultStoredPI" Type="Microsoft.Test.OData.Services.ODataWCFService.StoredPI" />
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
+